Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(208)

Side by Side Diff: tools/gn/runtime_deps.cc

Issue 1804303004: 🚙 GN: Add write_runtime_deps variable (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: remove {}s Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/gn/group_target_generator_unittest.cc ('k') | tools/gn/scheduler.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "tools/gn/runtime_deps.h" 5 #include "tools/gn/runtime_deps.h"
6 6
7 #include <map> 7 #include <map>
8 #include <set> 8 #include <set>
9 #include <sstream> 9 #include <sstream>
10 10
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/files/file_util.h" 12 #include "base/files/file_util.h"
13 #include "base/strings/string_split.h" 13 #include "base/strings/string_split.h"
14 #include "tools/gn/build_settings.h" 14 #include "tools/gn/build_settings.h"
15 #include "tools/gn/builder.h" 15 #include "tools/gn/builder.h"
16 #include "tools/gn/deps_iterator.h" 16 #include "tools/gn/deps_iterator.h"
17 #include "tools/gn/filesystem_utils.h" 17 #include "tools/gn/filesystem_utils.h"
18 #include "tools/gn/loader.h" 18 #include "tools/gn/loader.h"
19 #include "tools/gn/output_file.h" 19 #include "tools/gn/output_file.h"
20 #include "tools/gn/scheduler.h"
20 #include "tools/gn/settings.h" 21 #include "tools/gn/settings.h"
21 #include "tools/gn/switches.h" 22 #include "tools/gn/switches.h"
22 #include "tools/gn/target.h" 23 #include "tools/gn/target.h"
23 #include "tools/gn/trace.h" 24 #include "tools/gn/trace.h"
24 25
25 namespace { 26 namespace {
26 27
27 using RuntimeDepsVector = std::vector<std::pair<OutputFile, const Target*>>; 28 using RuntimeDepsVector = std::vector<std::pair<OutputFile, const Target*>>;
28 29
29 // Adds the given file to the deps list if it hasn't already been listed in 30 // Adds the given file to the deps list if it hasn't already been listed in
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 deps, seen_targets, found_files); 112 deps, seen_targets, found_files);
112 } 113 }
113 114
114 // Data dependencies. 115 // Data dependencies.
115 for (const auto& dep_pair : target->data_deps()) { 116 for (const auto& dep_pair : target->data_deps()) {
116 RecursiveCollectRuntimeDeps(dep_pair.ptr, true, 117 RecursiveCollectRuntimeDeps(dep_pair.ptr, true,
117 deps, seen_targets, found_files); 118 deps, seen_targets, found_files);
118 } 119 }
119 } 120 }
120 121
121 bool WriteRuntimeDepsFile(const Target* target) { 122 bool CollectRuntimeDepsFromFlag(const Builder& builder,
122 SourceFile target_output_as_source = 123 RuntimeDepsVector* files_to_write,
123 GetMainOutput(target).AsSourceFile(target->settings()->build_settings()); 124 Err* err) {
124 std::string data_deps_file_as_str = target_output_as_source.value(); 125 std::string deps_target_list_file =
125 data_deps_file_as_str.append(".runtime_deps"); 126 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
127 switches::kRuntimeDepsListFile);
128
129 if (deps_target_list_file.empty())
130 return true;
131
132 std::string list_contents;
133 ScopedTrace load_trace(TraceItem::TRACE_FILE_LOAD, deps_target_list_file);
134 if (!base::ReadFileToString(UTF8ToFilePath(deps_target_list_file),
135 &list_contents)) {
136 *err = Err(Location(),
137 std::string("File for --") + switches::kRuntimeDepsListFile +
138 " doesn't exist.",
139 "The file given was \"" + deps_target_list_file + "\"");
140 return false;
141 }
142 load_trace.Done();
143
144 SourceDir root_dir("//");
145 Label default_toolchain_label = builder.loader()->GetDefaultToolchain();
146 for (const auto& line :
147 base::SplitString(list_contents, "\n", base::TRIM_WHITESPACE,
148 base::SPLIT_WANT_ALL)) {
149 if (line.empty())
150 continue;
151 Label label = Label::Resolve(root_dir, default_toolchain_label,
152 Value(nullptr, line), err);
153 if (err->has_error())
154 return false;
155
156 const Item* item = builder.GetItem(label);
157 const Target* target = item ? item->AsTarget() : nullptr;
158 if (!target) {
159 *err = Err(Location(), "The label \"" + label.GetUserVisibleName(true) +
160 "\" isn't a target.",
161 "When reading the line:\n " + line + "\n"
162 "from the --" + switches::kRuntimeDepsListFile + "=" +
163 deps_target_list_file);
164 return false;
165 }
166
167 OutputFile output_file =
168 OutputFile(GetMainOutput(target).value() + ".runtime_deps");
169 files_to_write->push_back(std::make_pair(output_file, target));
170 }
171 return true;
172 }
173
174 bool WriteRuntimeDepsFile(const OutputFile& output_file,
175 const Target* target,
176 Err* err) {
177 SourceFile output_as_source =
178 output_file.AsSourceFile(target->settings()->build_settings());
126 base::FilePath data_deps_file = 179 base::FilePath data_deps_file =
127 target->settings()->build_settings()->GetFullPath( 180 target->settings()->build_settings()->GetFullPath(output_as_source);
128 SourceFile(SourceFile::SwapIn(), &data_deps_file_as_str));
129 181
130 std::stringstream contents; 182 std::stringstream contents;
131 for (const auto& pair : ComputeRuntimeDeps(target)) 183 for (const auto& pair : ComputeRuntimeDeps(target))
132 contents << pair.first.value() << std::endl; 184 contents << pair.first.value() << std::endl;
133 185
134 ScopedTrace trace(TraceItem::TRACE_FILE_WRITE, data_deps_file_as_str); 186 ScopedTrace trace(TraceItem::TRACE_FILE_WRITE, output_as_source.value());
135 base::CreateDirectory(data_deps_file.DirName()); 187 return WriteFileIfChanged(data_deps_file, contents.str(), err);
136
137 std::string contents_str = contents.str();
138 return base::WriteFile(data_deps_file, contents_str.c_str(),
139 static_cast<int>(contents_str.size())) > -1;
140 } 188 }
141 189
142 } // namespace 190 } // namespace
143 191
144 const char kRuntimeDeps_Help[] = 192 const char kRuntimeDeps_Help[] =
145 "Runtime dependencies\n" 193 "Runtime dependencies\n"
146 "\n" 194 "\n"
147 " Runtime dependencies of a target are exposed via the \"runtime_deps\"\n" 195 " Runtime dependencies of a target are exposed via the \"runtime_deps\"\n"
148 " category of \"gn desc\" (see \"gn help desc\") or they can be written\n" 196 " category of \"gn desc\" (see \"gn help desc\") or they can be written\n"
149 " at build generation time via \"--runtime-deps-list-file\"\n" 197 " at build generation time via write_runtime_deps(), or\n"
150 " (see \"gn help --runtime-deps-list-file\").\n" 198 " --runtime-deps-list-file (see \"gn help --runtime-deps-list-file\").\n"
151 "\n" 199 "\n"
152 " To a first approximation, the runtime dependencies of a target are\n" 200 " To a first approximation, the runtime dependencies of a target are\n"
153 " the set of \"data\" files, data directories, and the shared libraries\n" 201 " the set of \"data\" files, data directories, and the shared libraries\n"
154 " from all transitive dependencies. Executables, shared libraries, and\n" 202 " from all transitive dependencies. Executables, shared libraries, and\n"
155 " loadable modules are considered runtime dependencies of themselves.\n" 203 " loadable modules are considered runtime dependencies of themselves.\n"
156 "\n" 204 "\n"
157 "Executables\n" 205 "Executables\n"
158 "\n" 206 "\n"
159 " Executable targets and those executable targets' transitive\n" 207 " Executable targets and those executable targets' transitive\n"
160 " dependencies are not considered unless that executable is listed in\n" 208 " dependencies are not considered unless that executable is listed in\n"
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 266
219 // The initial target is not considered a data dependency so that actions's 267 // The initial target is not considered a data dependency so that actions's
220 // outputs (if the current target is an action) are not automatically 268 // outputs (if the current target is an action) are not automatically
221 // considered data deps. 269 // considered data deps.
222 RecursiveCollectRuntimeDeps(target, false, 270 RecursiveCollectRuntimeDeps(target, false,
223 &result, &seen_targets, &found_files); 271 &result, &seen_targets, &found_files);
224 return result; 272 return result;
225 } 273 }
226 274
227 bool WriteRuntimeDepsFilesIfNecessary(const Builder& builder, Err* err) { 275 bool WriteRuntimeDepsFilesIfNecessary(const Builder& builder, Err* err) {
228 std::string deps_target_list_file = 276 RuntimeDepsVector files_to_write;
229 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 277 if (!CollectRuntimeDepsFromFlag(builder, &files_to_write, err))
230 switches::kRuntimeDepsListFile); 278 return false;
231 if (deps_target_list_file.empty())
232 return true; // Nothing to do.
233 279
234 std::string list_contents; 280 // Files scheduled by write_runtime_deps.
235 ScopedTrace load_trace(TraceItem::TRACE_FILE_LOAD, deps_target_list_file); 281 for (const Target* target : g_scheduler->GetWriteRuntimeDepsTargets()) {
236 if (!base::ReadFileToString(UTF8ToFilePath(deps_target_list_file), 282 files_to_write.push_back(
237 &list_contents)) { 283 std::make_pair(target->write_runtime_deps_output(), target));
238 *err = Err(Location(),
239 std::string("File for --") + switches::kRuntimeDepsListFile +
240 " doesn't exist.",
241 "The file given was \"" + deps_target_list_file + "\"");
242 return false;
243 } 284 }
244 load_trace.Done();
245 285
246 SourceDir root_dir("//"); 286 for (const auto& entry : files_to_write) {
247 Label default_toolchain_label = builder.loader()->GetDefaultToolchain();
248 for (const auto& line : base::SplitString(
249 list_contents, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
250 if (line.empty())
251 continue;
252 Label label = Label::Resolve(root_dir, default_toolchain_label,
253 Value(nullptr, line), err);
254 if (err->has_error())
255 return false;
256
257 const Item* item = builder.GetItem(label);
258 const Target* target = item ? item->AsTarget() : nullptr;
259 if (!target) {
260 *err = Err(Location(), "The label \"" + label.GetUserVisibleName(true) +
261 "\" isn't a target.",
262 "When reading the line:\n " + line + "\n"
263 "from the --" + switches::kRuntimeDepsListFile + "=" +
264 deps_target_list_file);
265 return false;
266 }
267
268 // Currently this writes all runtime deps files sequentially. We generally 287 // Currently this writes all runtime deps files sequentially. We generally
269 // expect few of these. We can run this on the worker pool if it looks 288 // expect few of these. We can run this on the worker pool if it looks
270 // like it's talking a long time. 289 // like it's talking a long time.
271 WriteRuntimeDepsFile(target); 290 if (!WriteRuntimeDepsFile(entry.first, entry.second, err))
291 return false;
272 } 292 }
273 return true; 293 return true;
274 } 294 }
OLDNEW
« no previous file with comments | « tools/gn/group_target_generator_unittest.cc ('k') | tools/gn/scheduler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698