Fix gn reference in build.ninja after bootstrapping
After bootstrapping gn, build.ninja has a reference that looks something like:
command = ../../../../../../../../../../tmp/tmp9Pn0sv/gn --root=../.. -q gen .
This reference will be broken when the OS removes the temporary directory. This
CL regenerates the build files using the gn executable from the build directory.
This on its own will update the reference to plain "gn", however we need the
reference to be "./gn", because "gn" might not exist in the PATH, or would point
to an old one from depot_tools.
BUG=808829
R=dpranke
Change-Id: I1b156a6af081a35ded152946af13a117563b8c1a
Reviewed-on: https://chromium-review.googlesource.com/905793
Commit-Queue: Thomas Anderson <thomasanderson@chromium.org>
Reviewed-by: Brett Wilson <brettw@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#535892}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 00eba186828272462f318ee7ff4ed2106a6388a7diff --git a/tools/gn/bootstrap/bootstrap.py b/tools/gn/bootstrap/bootstrap.py
index 61146e0..35c0945 100755
--- a/tools/gn/bootstrap/bootstrap.py
+++ b/tools/gn/bootstrap/bootstrap.py
@@ -936,6 +936,13 @@
cmd.append('gn')
check_call(cmd)
+ # build.ninja currently refers back to gn from the temporary directory.
+ # Regenerate the build files using the gn we just built so that the reference
+ # gets updated to "./gn".
+ cmd = [os.path.join(build_dir, 'gn'), 'gen', build_dir,
+ '--args=%s' % gn_gen_args]
+ check_call(cmd)
+
if not options.debug and not is_win:
check_call(['strip', os.path.join(build_dir, 'gn')])
diff --git a/tools/gn/filesystem_utils.cc b/tools/gn/filesystem_utils.cc
index b1370e8..6cce895 100644
--- a/tools/gn/filesystem_utils.cc
+++ b/tools/gn/filesystem_utils.cc
@@ -441,10 +441,20 @@
relative_components.push_back(base::FilePath::kParentDirectory);
for (size_t j = i; j < target_components.size(); j++)
relative_components.push_back(target_components[j]);
- base::FilePath relative(base::FilePath::kCurrentDirectory);
- for (const auto& component : relative_components)
- relative = relative.Append(component);
- return relative;
+ if (relative_components.size() <= 1) {
+ // In case the file pointed-to is an executable, prepend the current
+ // directory to the path -- if the path was "gn", use "./gn" instead. If
+ // the file path is used in a command, this prevents issues where "gn" might
+ // not be in the PATH (or it is in the path, and the wrong gn is used).
+ relative_components.insert(relative_components.begin(),
+ base::FilePath::kCurrentDirectory);
+ }
+ // base::FilePath::Append(component) replaces the file path with |component|
+ // if the path is base::Filepath::kCurrentDirectory. We want to preserve the
+ // leading "./", so we build the path ourselves and use that to construct the
+ // base::FilePath.
+ base::FilePath::StringType separator(&base::FilePath::kSeparators[0], 1);
+ return base::FilePath(base::JoinString(relative_components, separator));
}
void NormalizePath(std::string* path, const base::StringPiece& source_root) {
diff --git a/tools/gn/filesystem_utils_unittest.cc b/tools/gn/filesystem_utils_unittest.cc
index 03ec780..dc2e512 100644
--- a/tools/gn/filesystem_utils_unittest.cc
+++ b/tools/gn/filesystem_utils_unittest.cc
@@ -179,6 +179,10 @@
base::FilePath(L"out\\Debug"),
MakeAbsoluteFilePathRelativeIfPossible(
base::FilePath(L"C:\\src"), base::FilePath(L"C:\\src\\out\\Debug")));
+ EXPECT_EQ(base::FilePath(L".\\gn"),
+ MakeAbsoluteFilePathRelativeIfPossible(
+ base::FilePath(L"C:\\src\\out\\Debug"),
+ base::FilePath(L"C:\\src\\out\\Debug\\gn")));
EXPECT_EQ(
base::FilePath(L"..\\.."),
MakeAbsoluteFilePathRelativeIfPossible(
@@ -197,6 +201,9 @@
EXPECT_EQ(base::FilePath("out/Debug"),
MakeAbsoluteFilePathRelativeIfPossible(
base::FilePath("/src"), base::FilePath("/src/out/Debug")));
+ EXPECT_EQ(base::FilePath("./gn"), MakeAbsoluteFilePathRelativeIfPossible(
+ base::FilePath("/src/out/Debug"),
+ base::FilePath("/src/out/Debug/gn")));
EXPECT_EQ(base::FilePath("../.."),
MakeAbsoluteFilePathRelativeIfPossible(
base::FilePath("/src/out/Debug"), base::FilePath("/src")));