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"