Make sure abs-path gn labels have separate target_gen_dirs
Use gen/ABS_PATH/... for target_gen_dir of build files outside of the
source tree, to mimic obj/ABS_PATH that's used for object directories
for such build files.
Previously, all build files outside of the source tree would use
root_gen_dir (e.g. out/Default/gen) as target_gen_dir. This broke the
"target_gen_dir is unique between different BUILD.gn files" assumption,
causing strange behavior and "ninja: multiple targets generate ..."
warnings for users of absolute path BUILD.gn files outside of //.
BUG=445454
R=brettw@chromium.org
Review URL: https://codereview.chromium.org/1420973003
Cr-Original-Commit-Position: refs/heads/master@{#356011}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 5b6813c06deae18ca309fba9913ee18e28150122
diff --git a/tools/gn/filesystem_utils.cc b/tools/gn/filesystem_utils.cc
index 44de5ad..a3455fd 100644
--- a/tools/gn/filesystem_utils.cc
+++ b/tools/gn/filesystem_utils.cc
@@ -686,6 +686,32 @@
settings->toolchain_label(), settings->is_default());
}
+void AppendFixedAbsolutePathSuffix(const BuildSettings* build_settings,
+ const SourceDir& source_dir,
+ OutputFile* result) {
+ const std::string& build_dir = build_settings->build_dir().value();
+
+ if (base::StartsWith(source_dir.value(), build_dir,
+ base::CompareCase::SENSITIVE)) {
+ size_t build_dir_size = build_dir.size();
+ result->value().append(&source_dir.value()[build_dir_size],
+ source_dir.value().size() - build_dir_size);
+ } else {
+ result->value().append("ABS_PATH");
+#if defined(OS_WIN)
+ // Windows absolute path contains ':' after drive letter. Remove it to
+ // avoid inserting ':' in the middle of path (eg. "ABS_PATH/C:/").
+ std::string src_dir_value = source_dir.value();
+ const auto colon_pos = src_dir_value.find(':');
+ if (colon_pos != std::string::npos)
+ src_dir_value.erase(src_dir_value.begin() + colon_pos);
+#else
+ const std::string& src_dir_value = source_dir.value();
+#endif
+ result->value().append(src_dir_value);
+ }
+}
+
SourceDir GetOutputDirForSourceDir(
const BuildSettings* build_settings,
const SourceDir& source_dir,
@@ -711,27 +737,7 @@
source_dir.value().size() - 2);
} else {
// System-absolute.
- const std::string& build_dir = build_settings->build_dir().value();
-
- if (base::StartsWith(source_dir.value(), build_dir,
- base::CompareCase::SENSITIVE)) {
- size_t build_dir_size = build_dir.size();
- result.value().append(&source_dir.value()[build_dir_size],
- source_dir.value().size() - build_dir_size);
- } else {
- result.value().append("ABS_PATH");
-#if defined(OS_WIN)
- // Windows absolute path contains ':' after drive letter. Remove it to
- // avoid inserting ':' in the middle of path (eg. "ABS_PATH/C:/").
- std::string src_dir_value = source_dir.value();
- const auto colon_pos = src_dir_value.find(':');
- if (colon_pos != std::string::npos)
- src_dir_value.erase(src_dir_value.begin() + colon_pos);
-#else
- const std::string& src_dir_value = source_dir.value();
-#endif
- result.value().append(src_dir_value);
- }
+ AppendFixedAbsolutePathSuffix(build_settings, source_dir, &result);
}
return result;
}
@@ -759,6 +765,10 @@
DCHECK(source_dir.is_source_absolute());
result.value().append(&source_dir.value()[2],
source_dir.value().size() - 2);
+ } else {
+ // System-absolute.
+ AppendFixedAbsolutePathSuffix(settings->build_settings(), source_dir,
+ &result);
}
return result;
}
diff --git a/tools/gn/function_get_path_info_unittest.cc b/tools/gn/function_get_path_info_unittest.cc
index 306c57e..5a8c455 100644
--- a/tools/gn/function_get_path_info_unittest.cc
+++ b/tools/gn/function_get_path_info_unittest.cc
@@ -110,6 +110,10 @@
EXPECT_EQ("//out/Debug/gen/src/foo", Call(".", "gen_dir"));
EXPECT_EQ("//out/Debug/gen/src/foo", Call("bar", "gen_dir"));
EXPECT_EQ("//out/Debug/gen/foo", Call("//foo/bar.txt", "gen_dir"));
- // System paths go into the root obj directory.
- EXPECT_EQ("//out/Debug/gen", Call("/foo/bar.txt", "gen_dir"));
+ // System paths go into the ABS_PATH gen directory
+ EXPECT_EQ("//out/Debug/gen/ABS_PATH/foo", Call("/foo/bar.txt", "gen_dir"));
+#if defined(OS_WIN)
+ EXPECT_EQ("//out/Debug/gen/ABS_PATH/C/foo",
+ Call("/C:/foo/bar.txt", "out_dir"));
+#endif
}
diff --git a/tools/gn/substitution_writer_unittest.cc b/tools/gn/substitution_writer_unittest.cc
index f5dcb78..6ae28ec 100644
--- a/tools/gn/substitution_writer_unittest.cc
+++ b/tools/gn/substitution_writer_unittest.cc
@@ -160,10 +160,13 @@
// Operations on an absolute path.
EXPECT_EQ("/baz.txt", GetRelSubst("/baz.txt", SUBSTITUTION_SOURCE));
EXPECT_EQ("/.", GetRelSubst("/baz.txt", SUBSTITUTION_SOURCE_DIR));
- EXPECT_EQ("gen", GetRelSubst("/baz.txt", SUBSTITUTION_SOURCE_GEN_DIR));
+ EXPECT_EQ("gen/ABS_PATH",
+ GetRelSubst("/baz.txt", SUBSTITUTION_SOURCE_GEN_DIR));
EXPECT_EQ("obj/ABS_PATH",
GetRelSubst("/baz.txt", SUBSTITUTION_SOURCE_OUT_DIR));
#if defined(OS_WIN)
+ EXPECT_EQ("gen/ABS_PATH/C",
+ GetRelSubst("/C:/baz.txt", SUBSTITUTION_SOURCE_GEN_DIR));
EXPECT_EQ("obj/ABS_PATH/C",
GetRelSubst("/C:/baz.txt", SUBSTITUTION_SOURCE_OUT_DIR));
#endif