1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/base_paths.h" 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <ostream> 8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <string> 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "build/build_config.h" 113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/environment.h" 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/file_path.h" 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/file_util.h" 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h" 15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/path_service.h" 17731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/nix/xdg_util.h" 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(OS_FREEBSD) 20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <sys/param.h> 21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <sys/sysctl.h> 22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif 23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace base { 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_LINUX) 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst char kSelfExe[] = "/proc/self/exe"; 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_SOLARIS) 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kSelfExe[] = getexecname(); 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 32731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// The name of this file relative to the source root. This is used for checking 33731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// that the source checkout is in the correct place. 34731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstatic const char kThisSourceFile[] = "base/base_paths_linux.cc"; 35731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool PathProviderPosix(int key, FilePath* result) { 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath path; 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott switch (key) { 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case base::FILE_EXE: 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case base::FILE_MODULE: { // TODO(evanm): is this correct? 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_LINUX) 4221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen FilePath bin_dir; 4321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!file_util::ReadSymbolicLink(FilePath(kSelfExe), &bin_dir)) { 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NOTREACHED() << "Unable to resolve " << kSelfExe << "."; 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 4721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen *result = bin_dir; 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_FREEBSD) 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 }; 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch char bin_dir[PATH_MAX + 1]; 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t length = sizeof(bin_dir); 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int error = sysctl(name, 4, bin_dir, &length, NULL, 0); 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (error < 0 || length == 0 || strlen(bin_dir) == 0) { 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED() << "Unable to resolve path."; 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bin_dir[strlen(bin_dir)] = 0; 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *result = FilePath(bin_dir); 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case base::DIR_SOURCE_ROOT: { 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Allow passing this in the environment, for more flexibility in build 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // tree configurations (sub-project builds, gyp --output_dir, etc.) 663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<base::Environment> env(base::Environment::Create()); 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string cr_source_root; 683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (env->GetVar("CR_SOURCE_ROOT", &cr_source_root)) { 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch path = FilePath(cr_source_root); 70731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (file_util::PathExists(path.Append(kThisSourceFile))) { 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *result = path; 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(WARNING) << "CR_SOURCE_ROOT is set, but it appears to not " 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << "point to the correct source root directory."; 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // On POSIX, unit tests execute two levels deep from the source root. 7921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // For example: out/{Debug|Release}/net_unittest 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (PathService::Get(base::DIR_EXE, &path)) { 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott path = path.DirName().DirName(); 82731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (file_util::PathExists(path.Append(kThisSourceFile))) { 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *result = path; 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // In a case of WebKit-only checkout, executable files are put into 8872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // <root of checkout>/out/{Debug|Release}, and we should return 8972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // <root of checkout>/Source/WebKit/chromium for DIR_SOURCE_ROOT. 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (PathService::Get(base::DIR_EXE, &path)) { 9172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen path = path.DirName().DirName().Append("Source/WebKit/chromium"); 92731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (file_util::PathExists(path.Append(kThisSourceFile))) { 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *result = path; 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If that failed (maybe the build output is symlinked to a different 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // drive) try assuming the current directory is the source root. 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (file_util::GetCurrentDirectory(&path) && 100731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick file_util::PathExists(path.Append(kThisSourceFile))) { 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *result = path; 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(ERROR) << "Couldn't find your source root. " 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott << "Try running from your chromium/src directory."; 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 10878494470aa829a52d6709093dd00e7704053e806Ben Murdoch case base::DIR_CACHE: 1097d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch#ifdef ANDROID 1107d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch NOTREACHED(); 1117d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch return false; 1127d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch#else 1133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<base::Environment> env(base::Environment::Create()); 114731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick FilePath cache_dir(base::nix::GetXDGDirectory(env.get(), "XDG_CACHE_HOME", 115731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ".cache")); 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *result = cache_dir; 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 1187d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch#endif 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace base 124