Make analyze handle targets from all toolchains This is necessary for Fuchsia to correctly detect the need to run host tests, which use a non-default toolchain. Test: cases added to analyzer_unittest.cc Bug: fuchsia:53604 Bug: gn:178 Bug: chromium:667989 Change-Id: I3e944be6fffda811ca65438f3861df19c4aef409 Reviewed-on: https://gn-review.googlesource.com/c/gn/+/9060 Reviewed-by: Dirk Pranke <dpranke@google.com> Commit-Queue: Scott Graham <scottmg@chromium.org>
diff --git a/src/gn/analyzer.cc b/src/gn/analyzer.cc index b3db365..47b0a6d 100644 --- a/src/gn/analyzer.cc +++ b/src/gn/analyzer.cc
@@ -299,11 +299,7 @@ GetAllAffectedItems(inputs.source_files); std::set<const Target*> affected_targets; for (const Item* affected_item : affected_items) { - // Only handles targets in the default toolchain. - // TODO(crbug.com/667989): Expand analyzer to non-default toolchains when - // the bug is fixed. - if (affected_item->AsTarget() && - affected_item->label().GetToolchainLabel() == default_toolchain_) + if (affected_item->AsTarget()) affected_targets.insert(affected_item->AsTarget()); }
diff --git a/src/gn/analyzer_unittest.cc b/src/gn/analyzer_unittest.cc index d2e89a9..9f7d897 100644 --- a/src/gn/analyzer_unittest.cc +++ b/src/gn/analyzer_unittest.cc
@@ -48,12 +48,20 @@ AnalyzerTest() : loader_(new MockLoader), builder_(loader_.get()), - settings_(&build_settings_, std::string()) { + settings_(&build_settings_, std::string()), + other_settings_(&build_settings_, std::string()) { build_settings_.SetBuildDir(SourceDir("//out/")); + settings_.set_toolchain_label(Label(SourceDir("//tc/"), "default")); settings_.set_default_toolchain_label(settings_.toolchain_label()); tc_dir_ = settings_.toolchain_label().dir(); tc_name_ = settings_.toolchain_label().name(); + + other_settings_.set_toolchain_label(Label(SourceDir("//other/"), "tc")); + other_settings_.set_default_toolchain_label( + other_settings_.toolchain_label()); + tc_other_dir_ = other_settings_.toolchain_label().dir(); + tc_other_name_ = other_settings_.toolchain_label().name(); } std::unique_ptr<Target> MakeTarget(const std::string& dir, @@ -62,6 +70,12 @@ return std::make_unique<Target>(&settings_, label); } + std::unique_ptr<Target> MakeTargetOtherToolchain(const std::string& dir, + const std::string& name) { + Label label(SourceDir(dir), name, tc_other_dir_, tc_other_name_); + return std::make_unique<Target>(&other_settings_, label); + } + std::unique_ptr<Config> MakeConfig(const std::string& dir, const std::string& name) { Label label(SourceDir(dir), name, tc_dir_, tc_name_); @@ -90,9 +104,14 @@ scoped_refptr<MockLoader> loader_; Builder builder_; BuildSettings build_settings_; + Settings settings_; SourceDir tc_dir_; std::string tc_name_; + + Settings other_settings_; + SourceDir tc_other_dir_; + std::string tc_other_name_; }; // Tests that a target is marked as affected if its sources are modified. @@ -601,4 +620,102 @@ "}"); } +// Tests that targets in explicitly labelled with the default toolchain are +// included when their sources change. +// change. +TEST_F(AnalyzerTest, TargetToolchainSpecifiedRefersToSources) { + std::unique_ptr<Target> t = MakeTarget("//dir", "target_name"); + Target* t_raw = t.get(); + builder_.ItemDefined(std::move(t)); + + RunAnalyzerTest( + R"/({ + "files": [ "//dir/file_name.cc" ], + "additional_compile_targets": ["all"], + "test_targets": [ "//dir:target_name(//tc:default)" ] + })/", + "{" + R"("compile_targets":[],)" + R"/("status":"No dependency",)/" + R"("test_targets":[])" + "}"); + + t_raw->sources().push_back(SourceFile("//dir/file_name.cc")); + + RunAnalyzerTest( + R"*({ + "files": [ "//dir/file_name.cc" ], + "additional_compile_targets": [], + "test_targets": [ "//dir:target_name(//tc:default)" ] + })*", + "{" + R"("compile_targets":[],)" + R"/("status":"Found dependency",)/" + R"/("test_targets":["//dir:target_name"])/" + "}"); +} + +// Tests that targets in alternate toolchains are affected when their sources +// change. +TEST_F(AnalyzerTest, TargetAlternateToolchainRefersToSources) { + std::unique_ptr<Target> t = MakeTarget("//dir", "target_name"); + std::unique_ptr<Target> t_alt = + MakeTargetOtherToolchain("//dir", "target_name"); + Target* t_raw = t.get(); + Target* t_alt_raw = t_alt.get(); + builder_.ItemDefined(std::move(t)); + builder_.ItemDefined(std::move(t_alt)); + + RunAnalyzerTest( + R"/({ + "files": [ "//dir/file_name.cc" ], + "additional_compile_targets": ["all"], + "test_targets": [ "//dir:target_name", "//dir:target_name(//other:tc)" ] + })/", + "{" + R"("compile_targets":[],)" + R"/("status":"No dependency",)/" + R"("test_targets":[])" + "}"); + + t_raw->sources().push_back(SourceFile("//dir/file_name.cc")); + t_alt_raw->sources().push_back(SourceFile("//dir/alt_file_name.cc")); + + RunAnalyzerTest( + R"*({ + "files": [ "//dir/file_name.cc" ], + "additional_compile_targets": [], + "test_targets": [ "//dir:target_name", "//dir:target_name(//other:tc)" ] + })*", + "{" + R"("compile_targets":[],)" + R"/("status":"Found dependency",)/" + R"("test_targets":["//dir:target_name"])" + "}"); + + RunAnalyzerTest( + R"*({ + "files": [ "//dir/alt_file_name.cc" ], + "additional_compile_targets": [], + "test_targets": [ "//dir:target_name", "//dir:target_name(//other:tc)" ] + })*", + "{" + R"("compile_targets":[],)" + R"/("status":"Found dependency",)/" + R"/("test_targets":["//dir:target_name(//other:tc)"])/" + "}"); + + RunAnalyzerTest( + R"*({ + "files": [ "//dir/file_name.cc", "//dir/alt_file_name.cc" ], + "additional_compile_targets": [], + "test_targets": [ "//dir:target_name", "//dir:target_name(//other:tc)" ] + })*", + "{" + R"("compile_targets":[],)" + R"/("status":"Found dependency",)/" + R"/("test_targets":["//dir:target_name","//dir:target_name(//other:tc)"])/" + "}"); +} + } // namespace gn_analyzer_unittest
diff --git a/src/gn/command_analyze.cc b/src/gn/command_analyze.cc index 3000b34..5119b14 100644 --- a/src/gn/command_analyze.cc +++ b/src/gn/command_analyze.cc
@@ -23,7 +23,7 @@ const char kAnalyze_HelpShort[] = "analyze: Analyze which targets are affected by a list of files."; const char kAnalyze_Help[] = - R"DOC(gn analyze <out_dir> <input_path> <output_path> + R"*(gn analyze <out_dir> <input_path> <output_path> Analyze which targets are affected by a list of files. @@ -95,7 +95,7 @@ "error" key is non-empty and a non-fatal error occurred. In other words, it tries really hard to always write something to the output JSON and convey errors that way rather than via return codes. -)DOC"; +)*"; int RunAnalyze(const std::vector<std::string>& args) { if (args.size() != 3) {