Index: tools/gn/runtime_deps.cc |
diff --git a/tools/gn/runtime_deps.cc b/tools/gn/runtime_deps.cc |
index 078bebeee2c822dddda0cc4a7f199ca3e3946560..17b9c07522718d61bc906e8ed0f13cb78f717304 100644 |
--- a/tools/gn/runtime_deps.cc |
+++ b/tools/gn/runtime_deps.cc |
@@ -17,6 +17,7 @@ |
#include "tools/gn/filesystem_utils.h" |
#include "tools/gn/loader.h" |
#include "tools/gn/output_file.h" |
+#include "tools/gn/scheduler.h" |
#include "tools/gn/settings.h" |
#include "tools/gn/switches.h" |
#include "tools/gn/target.h" |
@@ -118,25 +119,72 @@ void RecursiveCollectRuntimeDeps(const Target* target, |
} |
} |
-bool WriteRuntimeDepsFile(const Target* target) { |
- SourceFile target_output_as_source = |
- GetMainOutput(target).AsSourceFile(target->settings()->build_settings()); |
- std::string data_deps_file_as_str = target_output_as_source.value(); |
- data_deps_file_as_str.append(".runtime_deps"); |
+bool CollectRuntimeDepsFromFlag(const Builder& builder, |
+ RuntimeDepsVector* files_to_write, |
+ Err* err) { |
+ std::string deps_target_list_file = |
+ base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
+ switches::kRuntimeDepsListFile); |
+ |
+ if (deps_target_list_file.empty()) |
+ return true; |
+ |
+ std::string list_contents; |
+ ScopedTrace load_trace(TraceItem::TRACE_FILE_LOAD, deps_target_list_file); |
+ if (!base::ReadFileToString(UTF8ToFilePath(deps_target_list_file), |
+ &list_contents)) { |
+ *err = Err(Location(), |
+ std::string("File for --") + switches::kRuntimeDepsListFile + |
+ " doesn't exist.", |
+ "The file given was \"" + deps_target_list_file + "\""); |
+ return false; |
+ } |
+ load_trace.Done(); |
+ |
+ SourceDir root_dir("//"); |
+ Label default_toolchain_label = builder.loader()->GetDefaultToolchain(); |
+ for (const auto& line : |
+ base::SplitString(list_contents, "\n", base::TRIM_WHITESPACE, |
+ base::SPLIT_WANT_ALL)) { |
+ if (line.empty()) |
+ continue; |
+ Label label = Label::Resolve(root_dir, default_toolchain_label, |
+ Value(nullptr, line), err); |
+ if (err->has_error()) |
+ return false; |
+ |
+ const Item* item = builder.GetItem(label); |
+ const Target* target = item ? item->AsTarget() : nullptr; |
+ if (!target) { |
+ *err = Err(Location(), "The label \"" + label.GetUserVisibleName(true) + |
+ "\" isn't a target.", |
+ "When reading the line:\n " + line + "\n" |
+ "from the --" + switches::kRuntimeDepsListFile + "=" + |
+ deps_target_list_file); |
+ return false; |
+ } |
+ |
+ OutputFile output_file = |
+ OutputFile(GetMainOutput(target).value() + ".runtime_deps"); |
+ files_to_write->push_back(std::make_pair(output_file, target)); |
+ } |
+ return true; |
+} |
+ |
+bool WriteRuntimeDepsFile(const OutputFile& output_file, |
+ const Target* target, |
+ Err* err) { |
+ SourceFile output_as_source = |
+ output_file.AsSourceFile(target->settings()->build_settings()); |
base::FilePath data_deps_file = |
- target->settings()->build_settings()->GetFullPath( |
- SourceFile(SourceFile::SwapIn(), &data_deps_file_as_str)); |
+ target->settings()->build_settings()->GetFullPath(output_as_source); |
std::stringstream contents; |
for (const auto& pair : ComputeRuntimeDeps(target)) |
contents << pair.first.value() << std::endl; |
- ScopedTrace trace(TraceItem::TRACE_FILE_WRITE, data_deps_file_as_str); |
- base::CreateDirectory(data_deps_file.DirName()); |
- |
- std::string contents_str = contents.str(); |
- return base::WriteFile(data_deps_file, contents_str.c_str(), |
- static_cast<int>(contents_str.size())) > -1; |
+ ScopedTrace trace(TraceItem::TRACE_FILE_WRITE, output_as_source.value()); |
+ return WriteFileIfChanged(data_deps_file, contents.str(), err); |
} |
} // namespace |
@@ -146,8 +194,8 @@ const char kRuntimeDeps_Help[] = |
"\n" |
" Runtime dependencies of a target are exposed via the \"runtime_deps\"\n" |
" category of \"gn desc\" (see \"gn help desc\") or they can be written\n" |
- " at build generation time via \"--runtime-deps-list-file\"\n" |
- " (see \"gn help --runtime-deps-list-file\").\n" |
+ " at build generation time via write_runtime_deps(), or\n" |
+ " --runtime-deps-list-file (see \"gn help --runtime-deps-list-file\").\n" |
"\n" |
" To a first approximation, the runtime dependencies of a target are\n" |
" the set of \"data\" files, data directories, and the shared libraries\n" |
@@ -225,50 +273,22 @@ RuntimeDepsVector ComputeRuntimeDeps(const Target* target) { |
} |
bool WriteRuntimeDepsFilesIfNecessary(const Builder& builder, Err* err) { |
- std::string deps_target_list_file = |
- base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
- switches::kRuntimeDepsListFile); |
- if (deps_target_list_file.empty()) |
- return true; // Nothing to do. |
- |
- std::string list_contents; |
- ScopedTrace load_trace(TraceItem::TRACE_FILE_LOAD, deps_target_list_file); |
- if (!base::ReadFileToString(UTF8ToFilePath(deps_target_list_file), |
- &list_contents)) { |
- *err = Err(Location(), |
- std::string("File for --") + switches::kRuntimeDepsListFile + |
- " doesn't exist.", |
- "The file given was \"" + deps_target_list_file + "\""); |
+ RuntimeDepsVector files_to_write; |
+ if (!CollectRuntimeDepsFromFlag(builder, &files_to_write, err)) |
return false; |
- } |
- load_trace.Done(); |
- SourceDir root_dir("//"); |
- Label default_toolchain_label = builder.loader()->GetDefaultToolchain(); |
- for (const auto& line : base::SplitString( |
- list_contents, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) { |
- if (line.empty()) |
- continue; |
- Label label = Label::Resolve(root_dir, default_toolchain_label, |
- Value(nullptr, line), err); |
- if (err->has_error()) |
- return false; |
- |
- const Item* item = builder.GetItem(label); |
- const Target* target = item ? item->AsTarget() : nullptr; |
- if (!target) { |
- *err = Err(Location(), "The label \"" + label.GetUserVisibleName(true) + |
- "\" isn't a target.", |
- "When reading the line:\n " + line + "\n" |
- "from the --" + switches::kRuntimeDepsListFile + "=" + |
- deps_target_list_file); |
- return false; |
- } |
+ // Files scheduled by write_runtime_deps. |
+ for (const Target* target : g_scheduler->GetWriteRuntimeDepsTargets()) { |
+ files_to_write.push_back( |
+ std::make_pair(target->write_runtime_deps_output(), target)); |
+ } |
+ for (const auto& entry : files_to_write) { |
// Currently this writes all runtime deps files sequentially. We generally |
// expect few of these. We can run this on the worker pool if it looks |
// like it's talking a long time. |
- WriteRuntimeDepsFile(target); |
+ if (!WriteRuntimeDepsFile(entry.first, entry.second, err)) |
+ return false; |
} |
return true; |
} |