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