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) {