Write input files to json project This information is useful for IDEs to monitor the gn project files in order to know when to re-run gn to update the .json file. Change-Id: I68eb3b13cfb6a468d2d4adfc88db3599f18e6d46 Reviewed-on: https://gn-review.googlesource.com/c/gn/+/7080 Commit-Queue: Brett Wilson <brettw@chromium.org> Reviewed-by: Brett Wilson <brettw@chromium.org>
diff --git a/src/gn/json_project_writer.cc b/src/gn/json_project_writer.cc index 6509839..7c04ea1 100644 --- a/src/gn/json_project_writer.cc +++ b/src/gn/json_project_writer.cc
@@ -15,6 +15,7 @@ #include "gn/desc_builder.h" #include "gn/exec_process.h" #include "gn/filesystem_utils.h" +#include "gn/scheduler.h" #include "gn/settings.h" // Structure of JSON output file @@ -208,6 +209,28 @@ "default_toolchain", base::Value(default_toolchain_label.GetUserVisibleName(false))); + std::vector<base::FilePath> input_files; + g_scheduler->input_file_manager()->GetAllPhysicalInputFileNames(&input_files); + + // Other files read by the build. + std::vector<base::FilePath> other_files = g_scheduler->GetGenDependencies(); + + // Sort the input files to order them deterministically. + // Additionally, remove duplicate filepaths that seem to creep in. + std::set<base::FilePath> fileset(input_files.begin(), input_files.end()); + fileset.insert(other_files.begin(), other_files.end()); + + base::ListValue inputs; + const auto &build_path = build_settings->root_path(); + for (const auto& other_file : fileset) { + std::string file; + if (MakeAbsolutePathRelativeIfPossible(FilePathToUTF8(build_path), + FilePathToUTF8(other_file), &file)) { + inputs.Append(std::make_unique<base::Value>(std::move(file))); + } + } + settings->SetKey("gen_input_files", std::move(inputs)); + auto output = std::make_unique<base::DictionaryValue>(); output->SetWithoutPathExpansion("targets", std::move(targets)); output->SetWithoutPathExpansion("build_settings", std::move(settings));
diff --git a/src/gn/json_project_writer.h b/src/gn/json_project_writer.h index ee2e7b9..9d396d3 100644 --- a/src/gn/json_project_writer.h +++ b/src/gn/json_project_writer.h
@@ -23,9 +23,9 @@ Err* err); private: - FRIEND_TEST_ALL_PREFIXES(JSONProjectWriter, ActionWithResponseFile); - FRIEND_TEST_ALL_PREFIXES(JSONProjectWriter, ForEachWithResponseFile); - FRIEND_TEST_ALL_PREFIXES(JSONProjectWriter, RustTarget); + FRIEND_TEST_ALL_PREFIXES(JSONWriter, ActionWithResponseFile); + FRIEND_TEST_ALL_PREFIXES(JSONWriter, ForEachWithResponseFile); + FRIEND_TEST_ALL_PREFIXES(JSONWriter, RustTarget); static std::string RenderJSON(const BuildSettings* build_settings, std::vector<const Target*>& all_targets);
diff --git a/src/gn/json_project_writer_unittest.cc b/src/gn/json_project_writer_unittest.cc index 709d7c1..8a29425 100644 --- a/src/gn/json_project_writer_unittest.cc +++ b/src/gn/json_project_writer_unittest.cc
@@ -7,10 +7,13 @@ #include "gn/substitution_list.h" #include "gn/target.h" #include "gn/test_with_scope.h" +#include "gn/test_with_scheduler.h" #include "util/build_config.h" #include "util/test/test.h" -TEST(JSONProjectWriter, ActionWithResponseFile) { +using JSONWriter = TestWithScheduler; + +TEST_F(JSONWriter, ActionWithResponseFile) { Err err; TestWithScope setup; @@ -37,6 +40,15 @@ base::FilePath(FILE_PATH_LITERAL("/usr/bin/python"))); std::vector<const Target*> targets; targets.push_back(&target); +#if defined(OS_WIN) + base::FilePath root_path = base::FilePath(FILE_PATH_LITERAL("c:/path/to/src")); +#else + base::FilePath root_path = base::FilePath(FILE_PATH_LITERAL("/path/to/src")); +#endif + setup.build_settings()->SetRootPath(root_path); + g_scheduler->AddGenDependency(root_path.Append(FILE_PATH_LITERAL(".gn"))); + g_scheduler->AddGenDependency(root_path.Append(FILE_PATH_LITERAL("BUILD.gn"))); + g_scheduler->AddGenDependency(root_path.Append(FILE_PATH_LITERAL("build/BUILD.gn"))); std::string out = JSONProjectWriter::RenderJSON(setup.build_settings(), targets); #if defined(OS_WIN) @@ -47,7 +59,12 @@ " \"build_settings\": {\n" " \"build_dir\": \"//out/Debug/\",\n" " \"default_toolchain\": \"//toolchain:default\",\n" - " \"root_path\": \"\"\n" + " \"gen_input_files\": [ \"//.gn\", \"//BUILD.gn\", \"//build/BUILD.gn\" ],\n" +#if defined(OS_WIN) + " \"root_path\": \"c:/path/to/src\"\n" +#else + " \"root_path\": \"/path/to/src\"\n" +#endif " },\n" " \"targets\": {\n" " \"//foo:bar()\": {\n" @@ -72,7 +89,7 @@ EXPECT_EQ(expected_json, out); } -TEST(JSONProjectWriter, RustTarget) { +TEST_F(JSONWriter, RustTarget) { Err err; TestWithScope setup; @@ -99,6 +116,7 @@ " \"build_settings\": {\n" " \"build_dir\": \"//out/Debug/\",\n" " \"default_toolchain\": \"//toolchain:default\",\n" + " \"gen_input_files\": [ ],\n" " \"root_path\": \"\"\n" " },\n" " \"targets\": {\n" @@ -127,7 +145,7 @@ EXPECT_EQ(expected_json, out); } -TEST(JSONProjectWriter, ForEachWithResponseFile) { +TEST_F(JSONWriter, ForEachWithResponseFile) { Err err; TestWithScope setup; @@ -153,6 +171,14 @@ base::FilePath(FILE_PATH_LITERAL("/usr/bin/python"))); std::vector<const Target*> targets; targets.push_back(&target); +#if defined(OS_WIN) + base::FilePath root_path = base::FilePath(FILE_PATH_LITERAL("c:/path/to/src")); +#else + base::FilePath root_path = base::FilePath(FILE_PATH_LITERAL("/path/to/src")); +#endif + setup.build_settings()->SetRootPath(root_path); + g_scheduler->AddGenDependency(root_path.Append(FILE_PATH_LITERAL(".gn"))); + g_scheduler->AddGenDependency(root_path.Append(FILE_PATH_LITERAL("BUILD.gn"))); std::string out = JSONProjectWriter::RenderJSON(setup.build_settings(), targets); #if defined(OS_WIN) @@ -163,7 +189,12 @@ " \"build_settings\": {\n" " \"build_dir\": \"//out/Debug/\",\n" " \"default_toolchain\": \"//toolchain:default\",\n" - " \"root_path\": \"\"\n" + " \"gen_input_files\": [ \"//.gn\", \"//BUILD.gn\" ],\n" +#if defined(OS_WIN) + " \"root_path\": \"c:/path/to/src\"\n" +#else + " \"root_path\": \"/path/to/src\"\n" +#endif " },\n" " \"targets\": {\n" " \"//foo:bar()\": {\n"