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

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

Issue 1207903002: Windows precompiled header support in GN (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Scott's grammar nits Created 5 years, 5 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/target.h ('k') | tools/gn/target_unittest.cc » ('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 (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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/target.h" 5 #include "tools/gn/target.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/strings/string_util.h" 8 #include "base/strings/string_util.h"
9 #include "base/strings/stringprintf.h" 9 #include "base/strings/stringprintf.h"
10 #include "tools/gn/config_values_extractors.h" 10 #include "tools/gn/config_values_extractors.h"
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 // inherited through the dependency tree (other flags don't work this way). 163 // inherited through the dependency tree (other flags don't work this way).
164 for (ConfigValuesIterator iter(this); !iter.done(); iter.Next()) { 164 for (ConfigValuesIterator iter(this); !iter.done(); iter.Next()) {
165 const ConfigValues& cur = iter.cur(); 165 const ConfigValues& cur = iter.cur();
166 all_lib_dirs_.append(cur.lib_dirs().begin(), cur.lib_dirs().end()); 166 all_lib_dirs_.append(cur.lib_dirs().begin(), cur.lib_dirs().end());
167 all_libs_.append(cur.libs().begin(), cur.libs().end()); 167 all_libs_.append(cur.libs().begin(), cur.libs().end());
168 } 168 }
169 169
170 PullDependentTargets(); 170 PullDependentTargets();
171 PullForwardedDependentConfigs(); 171 PullForwardedDependentConfigs();
172 PullRecursiveHardDeps(); 172 PullRecursiveHardDeps();
173 if (!ResolvePrecompiledHeaders(err))
174 return false;
173 175
174 FillOutputFiles(); 176 FillOutputFiles();
175 177
176 if (settings()->build_settings()->check_for_bad_items()) { 178 if (settings()->build_settings()->check_for_bad_items()) {
177 if (!CheckVisibility(err)) 179 if (!CheckVisibility(err))
178 return false; 180 return false;
179 if (!CheckTestonly(err)) 181 if (!CheckTestonly(err))
180 return false; 182 return false;
181 if (!CheckNoNestedStaticLibs(err)) 183 if (!CheckNoNestedStaticLibs(err))
182 return false; 184 return false;
(...skipping 25 matching lines...) Expand all
208 std::string Target::GetComputedOutputName(bool include_prefix) const { 210 std::string Target::GetComputedOutputName(bool include_prefix) const {
209 DCHECK(toolchain_) 211 DCHECK(toolchain_)
210 << "Toolchain must be specified before getting the computed output name."; 212 << "Toolchain must be specified before getting the computed output name.";
211 213
212 const std::string& name = output_name_.empty() ? label().name() 214 const std::string& name = output_name_.empty() ? label().name()
213 : output_name_; 215 : output_name_;
214 216
215 std::string result; 217 std::string result;
216 if (include_prefix) { 218 if (include_prefix) {
217 const Tool* tool = toolchain_->GetToolForTargetFinalOutput(this); 219 const Tool* tool = toolchain_->GetToolForTargetFinalOutput(this);
218 const std::string& prefix = tool->output_prefix(); 220 if (tool) {
219 // Only add the prefix if the name doesn't already have it. 221 // Only add the prefix if the name doesn't already have it.
220 if (!base::StartsWithASCII(name, prefix, true)) 222 if (!base::StartsWithASCII(name, tool->output_prefix(), true))
221 result = prefix; 223 result = tool->output_prefix();
224 }
222 } 225 }
223
224 result.append(name); 226 result.append(name);
225 return result; 227 return result;
226 } 228 }
227 229
228 bool Target::SetToolchain(const Toolchain* toolchain, Err* err) { 230 bool Target::SetToolchain(const Toolchain* toolchain, Err* err) {
229 DCHECK(!toolchain_); 231 DCHECK(!toolchain_);
230 DCHECK_NE(UNKNOWN, output_type_); 232 DCHECK_NE(UNKNOWN, output_type_);
231 toolchain_ = toolchain; 233 toolchain_ = toolchain;
232 234
233 const Tool* tool = toolchain->GetToolForTargetFinalOutput(this); 235 const Tool* tool = toolchain->GetToolForTargetFinalOutput(this);
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 NormalizePath(&out.value()); 424 NormalizePath(&out.value());
423 } 425 }
424 426
425 // Also count anything the target has declared to be an output. 427 // Also count anything the target has declared to be an output.
426 std::vector<SourceFile> outputs_as_sources; 428 std::vector<SourceFile> outputs_as_sources;
427 action_values_.GetOutputsAsSourceFiles(this, &outputs_as_sources); 429 action_values_.GetOutputsAsSourceFiles(this, &outputs_as_sources);
428 for (const SourceFile& out : outputs_as_sources) 430 for (const SourceFile& out : outputs_as_sources)
429 computed_outputs_.push_back(OutputFile(settings()->build_settings(), out)); 431 computed_outputs_.push_back(OutputFile(settings()->build_settings(), out));
430 } 432 }
431 433
434 bool Target::ResolvePrecompiledHeaders(Err* err) {
435 // Precompiled headers are stored on a ConfigValues struct. This way, the
436 // build can set all the precompiled header settings in a config and apply
437 // it to many targets. Likewise, the precompiled header values may be
438 // specified directly on a target.
439 //
440 // Unlike other values on configs which are lists that just get concatenated,
441 // the precompiled header settings are unique values. We allow them to be
442 // specified anywhere, but if they are specified in more than one place all
443 // places must match.
444
445 // Track where the current settings came from for issuing errors.
446 const Label* pch_header_settings_from = NULL;
447 if (config_values_.has_precompiled_headers())
448 pch_header_settings_from = &label();
449
450 for (ConfigValuesIterator iter(this); !iter.done(); iter.Next()) {
451 if (!iter.GetCurrentConfig())
452 continue; // Skip the one on the target itself.
453
454 const Config* config = iter.GetCurrentConfig();
455 const ConfigValues& cur = config->config_values();
456 if (!cur.has_precompiled_headers())
457 continue; // This one has no precompiled header info, skip.
458
459 if (config_values_.has_precompiled_headers()) {
460 // Already have a precompiled header values, the settings must match.
461 if (config_values_.precompiled_header() != cur.precompiled_header() ||
462 config_values_.precompiled_source() != cur.precompiled_source()) {
463 *err = Err(defined_from(),
464 "Precompiled header setting conflict.",
465 "The target " + label().GetUserVisibleName(false) + "\n"
466 "has conflicting precompiled header settings.\n"
467 "\n"
468 "From " + pch_header_settings_from->GetUserVisibleName(false) +
469 "\n header: " + config_values_.precompiled_header() +
470 "\n source: " + config_values_.precompiled_source().value() +
471 "\n\n"
472 "From " + config->label().GetUserVisibleName(false) +
473 "\n header: " + cur.precompiled_header() +
474 "\n source: " + cur.precompiled_source().value());
475 return false;
476 }
477 } else {
478 // Have settings from a config, apply them to ourselves.
479 pch_header_settings_from = &config->label();
480 config_values_.set_precompiled_header(cur.precompiled_header());
481 config_values_.set_precompiled_source(cur.precompiled_source());
482 }
483 }
484
485 return true;
486 }
487
432 bool Target::CheckVisibility(Err* err) const { 488 bool Target::CheckVisibility(Err* err) const {
433 for (const auto& pair : GetDeps(DEPS_ALL)) { 489 for (const auto& pair : GetDeps(DEPS_ALL)) {
434 if (!Visibility::CheckItemVisibility(this, pair.ptr, err)) 490 if (!Visibility::CheckItemVisibility(this, pair.ptr, err))
435 return false; 491 return false;
436 } 492 }
437 return true; 493 return true;
438 } 494 }
439 495
440 bool Target::CheckTestonly(Err* err) const { 496 bool Target::CheckTestonly(Err* err) const {
441 // If the current target is marked testonly, it can include both testonly 497 // If the current target is marked testonly, it can include both testonly
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 return; // Not in output dir, this is OK. 553 return; // Not in output dir, this is OK.
498 554
499 // Tell the scheduler about unknown files. This will be noted for later so 555 // Tell the scheduler about unknown files. This will be noted for later so
500 // the list of files written by the GN build itself (often response files) 556 // the list of files written by the GN build itself (often response files)
501 // can be filtered out of this list. 557 // can be filtered out of this list.
502 OutputFile out_file(settings()->build_settings(), source); 558 OutputFile out_file(settings()->build_settings(), source);
503 std::set<const Target*> seen_targets; 559 std::set<const Target*> seen_targets;
504 if (!EnsureFileIsGeneratedByDependency(this, out_file, true, &seen_targets)) 560 if (!EnsureFileIsGeneratedByDependency(this, out_file, true, &seen_targets))
505 g_scheduler->AddUnknownGeneratedInput(this, source); 561 g_scheduler->AddUnknownGeneratedInput(this, source);
506 } 562 }
OLDNEW
« no previous file with comments | « tools/gn/target.h ('k') | tools/gn/target_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698