blob: bdf540ce8046c3de4ea5125986984b1882eaa182 [file] [log] [blame]
[email protected]9bc8cff2010-04-03 01:05:391// Copyright (c) 2010 The Chromium Authors. All rights reserved.
[email protected]b2e97292008-09-02 18:20:342// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]5d1937bb2009-11-21 01:29:005#include "base/base_paths.h"
[email protected]b2e97292008-09-02 18:20:346
7#include <unistd.h>
[email protected]99aae102010-05-10 16:30:278#if defined(OS_FREEBSD)
9#include <sys/param.h>
10#include <sys/sysctl.h>
11#endif
[email protected]b2e97292008-09-02 18:20:3412
[email protected]76b90d312010-08-03 03:00:5013#include "base/environment.h"
[email protected]640517f2008-10-30 23:54:0414#include "base/file_path.h"
[email protected]b2e97292008-09-02 18:20:3415#include "base/file_util.h"
16#include "base/logging.h"
17#include "base/path_service.h"
[email protected]9e9b6e8e2009-12-02 08:45:0118#include "base/scoped_ptr.h"
[email protected]b2e97292008-09-02 18:20:3419#include "base/sys_string_conversions.h"
[email protected]6b0349ef2010-10-16 04:56:0620#include "base/nix/xdg_util.h"
[email protected]b2e97292008-09-02 18:20:3421
22namespace base {
23
[email protected]4a34ce02009-08-31 22:25:0024#if defined(OS_LINUX)
25const char kSelfExe[] = "/proc/self/exe";
[email protected]a1208912010-02-17 14:15:0826#elif defined(OS_SOLARIS)
27const char kSelfExe[] = getexecname();
[email protected]4a34ce02009-08-31 22:25:0028#endif
29
[email protected]6b0349ef2010-10-16 04:56:0630// The name of this file relative to the source root. This is used for checking
31// that the source checkout is in the correct place.
32static const char kThisSourceFile[] = "base/base_paths_linux.cc";
33
[email protected]5d1937bb2009-11-21 01:29:0034bool PathProviderPosix(int key, FilePath* result) {
[email protected]640517f2008-10-30 23:54:0435 FilePath path;
[email protected]b2e97292008-09-02 18:20:3436 switch (key) {
37 case base::FILE_EXE:
[email protected]4a34ce02009-08-31 22:25:0038 case base::FILE_MODULE: { // TODO(evanm): is this correct?
[email protected]99aae102010-05-10 16:30:2739#if defined(OS_LINUX)
[email protected]723571a2010-12-03 17:37:5440 FilePath bin_dir;
41 if (!file_util::ReadSymbolicLink(FilePath(kSelfExe), &bin_dir)) {
[email protected]4a34ce02009-08-31 22:25:0042 NOTREACHED() << "Unable to resolve " << kSelfExe << ".";
[email protected]b2e97292008-09-02 18:20:3443 return false;
44 }
[email protected]723571a2010-12-03 17:37:5445 *result = bin_dir;
[email protected]b2e97292008-09-02 18:20:3446 return true;
[email protected]99aae102010-05-10 16:30:2747#elif defined(OS_FREEBSD)
48 int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
49 char bin_dir[PATH_MAX + 1];
50 size_t length = sizeof(bin_dir);
51 int error = sysctl(name, 4, bin_dir, &length, NULL, 0);
52 if (error < 0 || length == 0 || strlen(bin_dir) == 0) {
53 NOTREACHED() << "Unable to resolve path.";
54 return false;
55 }
56 bin_dir[strlen(bin_dir)] = 0;
57 *result = FilePath(bin_dir);
58 return true;
59#endif
[email protected]b2e97292008-09-02 18:20:3460 }
[email protected]632be2f2010-04-21 23:28:4361 case base::DIR_SOURCE_ROOT: {
62 // Allow passing this in the environment, for more flexibility in build
63 // tree configurations (sub-project builds, gyp --output_dir, etc.)
[email protected]76b90d312010-08-03 03:00:5064 scoped_ptr<base::Environment> env(base::Environment::Create());
[email protected]632be2f2010-04-21 23:28:4365 std::string cr_source_root;
[email protected]3ba7e082010-08-07 02:57:5966 if (env->GetVar("CR_SOURCE_ROOT", &cr_source_root)) {
[email protected]632be2f2010-04-21 23:28:4367 path = FilePath(cr_source_root);
[email protected]6b0349ef2010-10-16 04:56:0668 if (file_util::PathExists(path.Append(kThisSourceFile))) {
[email protected]632be2f2010-04-21 23:28:4369 *result = path;
70 return true;
71 } else {
72 LOG(WARNING) << "CR_SOURCE_ROOT is set, but it appears to not "
73 << "point to the correct source root directory.";
74 }
75 }
[email protected]5d1937bb2009-11-21 01:29:0076 // On POSIX, unit tests execute two levels deep from the source root.
[email protected]016498e2010-12-03 00:59:2377 // For example: out/{Debug|Release}/net_unittest
[email protected]95d050e2009-09-10 19:30:4678 if (PathService::Get(base::DIR_EXE, &path)) {
79 path = path.DirName().DirName();
[email protected]6b0349ef2010-10-16 04:56:0680 if (file_util::PathExists(path.Append(kThisSourceFile))) {
[email protected]95d050e2009-09-10 19:30:4681 *result = path;
82 return true;
83 }
84 }
[email protected]14a25e502010-06-15 06:53:5285 // In a case of WebKit-only checkout, executable files are put into
86 // WebKit/out/{Debug|Release}, and we should return WebKit/WebKit/chromium
87 // for DIR_SOURCE_ROOT.
88 if (PathService::Get(base::DIR_EXE, &path)) {
89 path = path.DirName().DirName().Append("WebKit/chromium");
[email protected]6b0349ef2010-10-16 04:56:0690 if (file_util::PathExists(path.Append(kThisSourceFile))) {
[email protected]14a25e502010-06-15 06:53:5291 *result = path;
92 return true;
93 }
94 }
[email protected]95d050e2009-09-10 19:30:4695 // If that failed (maybe the build output is symlinked to a different
96 // drive) try assuming the current directory is the source root.
97 if (file_util::GetCurrentDirectory(&path) &&
[email protected]6b0349ef2010-10-16 04:56:0698 file_util::PathExists(path.Append(kThisSourceFile))) {
[email protected]95d050e2009-09-10 19:30:4699 *result = path;
100 return true;
101 }
102 LOG(ERROR) << "Couldn't find your source root. "
103 << "Try running from your chromium/src directory.";
104 return false;
[email protected]632be2f2010-04-21 23:28:43105 }
[email protected]b411da32010-11-24 02:23:15106 case base::DIR_CACHE:
[email protected]76b90d312010-08-03 03:00:50107 scoped_ptr<base::Environment> env(base::Environment::Create());
[email protected]6b0349ef2010-10-16 04:56:06108 FilePath cache_dir(base::nix::GetXDGDirectory(env.get(), "XDG_CACHE_HOME",
109 ".cache"));
[email protected]9e9b6e8e2009-12-02 08:45:01110 *result = cache_dir;
111 return true;
[email protected]b2e97292008-09-02 18:20:34112 }
113 return false;
114}
115
116} // namespace base