diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-04 19:19:59 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-04 19:19:59 +0000 |
commit | 132715e1e82b1f69fc5a67d3acedb24c12d02e2a (patch) | |
tree | d439dd489e8f11e40e9161c5e45188f62ff2d1e6 | |
parent | 21bb906f7ce89a54bf8ecdb951771bb25069e43c (diff) | |
download | chromium_src-132715e1e82b1f69fc5a67d3acedb24c12d02e2a.zip chromium_src-132715e1e82b1f69fc5a67d3acedb24c12d02e2a.tar.gz chromium_src-132715e1e82b1f69fc5a67d3acedb24c12d02e2a.tar.bz2 |
GN: toolchain threading cleanup
Remove the thread-unsafe toolchain pointer on the otherwise-threadsafe Settings object. I replaced it with the toolchain label, and moved the is_default flag from the toolchain to the Settings object.
This required that I pass the toolchain around in a few more places, but also simplifies some other cases.
I removed the toolchain prefix from Ninja rules for the default toolchain since that's not necessary any more for GYP compat.
This fixes an annoying double-free in the toolchain manager. I think my current refactor will clean this up in a later phase.
R=scottmg@chromium.org
Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=232657
Review URL: https://codereview.chromium.org/51693002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@232755 0039d316-1c4b-4281-b951-d872f2087c98
40 files changed, 175 insertions, 157 deletions
diff --git a/tools/gn/config.cc b/tools/gn/config.cc index 850d596..5b89e2b 100644 --- a/tools/gn/config.cc +++ b/tools/gn/config.cc @@ -10,7 +10,8 @@ #include "tools/gn/item_tree.h" #include "tools/gn/scheduler.h" -Config::Config(const Label& label) : Item(label) { +Config::Config(const Settings* settings, const Label& label) + : Item(settings, label) { } Config::~Config() { @@ -38,7 +39,7 @@ Config* Config::GetConfig(const Settings* settings, ItemNode* node = tree->GetExistingNodeLocked(label); Config* config = NULL; if (!node) { - config = new Config(label); + config = new Config(settings, label); node = new ItemNode(config); node->set_originally_referenced_from_here(specified_from_here); tree->AddNodeLocked(node); diff --git a/tools/gn/config.h b/tools/gn/config.h index 0ee9b7b..e5a1df6 100644 --- a/tools/gn/config.h +++ b/tools/gn/config.h @@ -17,7 +17,7 @@ class Settings; // Represents a named config in the dependency graph. class Config : public Item { public: - Config(const Label& label); + Config(const Settings* settings, const Label& label); virtual ~Config(); virtual Config* AsConfig() OVERRIDE; diff --git a/tools/gn/function_exec_script.cc b/tools/gn/function_exec_script.cc index bf55165..b382575 100644 --- a/tools/gn/function_exec_script.cc +++ b/tools/gn/function_exec_script.cc @@ -301,7 +301,7 @@ Value RunExecScript(Scope* scope, } ScopedTrace trace(TraceItem::TRACE_SCRIPT_EXECUTE, script_source.value()); - trace.SetToolchain(settings->toolchain()->label()); + trace.SetToolchain(settings->toolchain_label()); // Add all dependencies of this script, including the script itself, to the // build deps. diff --git a/tools/gn/function_toolchain.cc b/tools/gn/function_toolchain.cc index 933d55e..dde0306 100644 --- a/tools/gn/function_toolchain.cc +++ b/tools/gn/function_toolchain.cc @@ -102,7 +102,7 @@ Value RunToolchain(Scope* scope, // This object will actually be copied into the one owned by the toolchain // manager, but that has to be done in the lock. - Toolchain toolchain(label); + Toolchain toolchain(scope->settings(), label); Scope block_scope(scope); block_scope.SetProperty(&kToolchainPropertyKey, &toolchain); diff --git a/tools/gn/functions.cc b/tools/gn/functions.cc index acc8fe9..0e27297 100644 --- a/tools/gn/functions.cc +++ b/tools/gn/functions.cc @@ -134,7 +134,7 @@ bool EnsureSingleStringArg(const FunctionCallNode* function, } const Label& ToolchainLabelForScope(const Scope* scope) { - return scope->settings()->toolchain()->label(); + return scope->settings()->toolchain_label(); } Label MakeLabelForScope(const Scope* scope, diff --git a/tools/gn/gyp_helper.cc b/tools/gn/gyp_helper.cc index f69ed8f..fb669af 100644 --- a/tools/gn/gyp_helper.cc +++ b/tools/gn/gyp_helper.cc @@ -45,10 +45,10 @@ SourceFile GypHelper::GetGypFileForTarget(const Target* target, } std::string GypHelper::GetNameForTarget(const Target* target) const { - const Toolchain* toolchain = target->settings()->toolchain(); - if (toolchain->is_default()) + if (target->settings()->is_default()) return target->label().name(); // Default toolchain has no suffix. - return target->label().name() + "_" + toolchain->label().name(); + return target->label().name() + "_" + + target->settings()->toolchain_label().name(); } std::string GypHelper::GetFullRefForTarget(const Target* target) const { diff --git a/tools/gn/input_conversion.cc b/tools/gn/input_conversion.cc index 19a8047..c40bdba 100644 --- a/tools/gn/input_conversion.cc +++ b/tools/gn/input_conversion.cc @@ -117,9 +117,7 @@ Value ParseString(const std::string& input, } BuildSettings build_settings; - Label empty_label; - Toolchain toolchain(empty_label); - Settings settings(&build_settings, &toolchain, std::string()); + Settings settings(&build_settings, std::string()); Scope scope(&settings); Err nested_err; diff --git a/tools/gn/item.cc b/tools/gn/item.cc index 747183cb..fa16975 100644 --- a/tools/gn/item.cc +++ b/tools/gn/item.cc @@ -6,7 +6,9 @@ #include "base/logging.h" -Item::Item(const Label& label) : label_(label) { +Item::Item(const Settings* settings, const Label& label) + : settings_(settings), + label_(label) { } Item::~Item() { diff --git a/tools/gn/item.h b/tools/gn/item.h index 2538c50..69115bd 100644 --- a/tools/gn/item.h +++ b/tools/gn/item.h @@ -11,6 +11,7 @@ class Config; class ItemNode; +class Settings; class Target; class Toolchain; @@ -18,9 +19,11 @@ class Toolchain; // graph. class Item { public: - Item(const Label& label); + Item(const Settings* settings, const Label& label); virtual ~Item(); + const Settings* settings() const { return settings_; } + // This is guaranteed to never change after construction so this can be // accessed from any thread with no locking once the item is constructed. const Label& label() const { return label_; } @@ -49,6 +52,7 @@ class Item { virtual void OnResolved() {} private: + const Settings* settings_; Label label_; ItemNode* item_node_; diff --git a/tools/gn/ninja_binary_target_writer.cc b/tools/gn/ninja_binary_target_writer.cc index 3a1d620..c404006 100644 --- a/tools/gn/ninja_binary_target_writer.cc +++ b/tools/gn/ninja_binary_target_writer.cc @@ -86,8 +86,9 @@ Toolchain::ToolType GetToolTypeForTarget(const Target* target) { } // namespace NinjaBinaryTargetWriter::NinjaBinaryTargetWriter(const Target* target, + const Toolchain* toolchain, std::ostream& out) - : NinjaTargetWriter(target, out), + : NinjaTargetWriter(target, toolchain, out), tool_type_(GetToolTypeForTarget(target)){ } @@ -145,7 +146,6 @@ void NinjaBinaryTargetWriter::WriteSources( const Target::FileList& sources = target_->sources(); object_files->reserve(sources.size()); - const Toolchain* toolchain = GetToolchain(); std::string implicit_deps = GetSourcesImplicitDeps(); for (size_t i = 0; i < sources.size(); i++) { @@ -156,7 +156,7 @@ void NinjaBinaryTargetWriter::WriteSources( if (input_file_type == SOURCE_UNKNOWN) continue; // Skip unknown file types. std::string command = - helper_.GetRuleForSourceType(settings_, toolchain, input_file_type); + helper_.GetRuleForSourceType(settings_, input_file_type); if (command.empty()) continue; // Skip files not needing compilation. @@ -265,8 +265,7 @@ void NinjaBinaryTargetWriter::WriteLinkerFlags() { RecursiveTargetConfigStringsToStream(target_, &ConfigValues::ldflags, flag_options, out_); - const Toolchain* toolchain = GetToolchain(); - const Toolchain::Tool& tool = toolchain->GetTool(tool_type_); + const Toolchain::Tool& tool = toolchain_->GetTool(tool_type_); // Followed by library search paths that have been recursively pushed // through the dependency tree. @@ -306,7 +305,7 @@ void NinjaBinaryTargetWriter::WriteLinkCommand( path_output_.WriteFile(out_, external_output_file); } out_ << ": " - << helper_.GetRulePrefix(GetToolchain()) + << helper_.GetRulePrefix(target_->settings()) << Toolchain::ToolTypeToName(tool_type_); std::set<OutputFile> extra_object_files; @@ -346,7 +345,7 @@ void NinjaBinaryTargetWriter::WriteSourceSetStamp( out_ << "build "; path_output_.WriteFile(out_, helper_.GetTargetOutputFile(target_)); out_ << ": " - << helper_.GetRulePrefix(target_->settings()->toolchain()) + << helper_.GetRulePrefix(target_->settings()) << "stamp"; std::set<OutputFile> extra_object_files; diff --git a/tools/gn/ninja_binary_target_writer.h b/tools/gn/ninja_binary_target_writer.h index 8c57ffb..c188335 100644 --- a/tools/gn/ninja_binary_target_writer.h +++ b/tools/gn/ninja_binary_target_writer.h @@ -13,7 +13,9 @@ // library, or a static library). class NinjaBinaryTargetWriter : public NinjaTargetWriter { public: - NinjaBinaryTargetWriter(const Target* target, std::ostream& out); + NinjaBinaryTargetWriter(const Target* target, + const Toolchain* toolchain, + std::ostream& out); virtual ~NinjaBinaryTargetWriter(); virtual void Run() OVERRIDE; diff --git a/tools/gn/ninja_binary_target_writer_unittest.cc b/tools/gn/ninja_binary_target_writer_unittest.cc index a7de4a1..96a7448 100644 --- a/tools/gn/ninja_binary_target_writer_unittest.cc +++ b/tools/gn/ninja_binary_target_writer_unittest.cc @@ -22,7 +22,7 @@ TEST(NinjaBinaryTargetWriter, SourceSet) { // Source set itself. { std::ostringstream out; - NinjaBinaryTargetWriter writer(&target, out); + NinjaBinaryTargetWriter writer(&target, setup.toolchain(), out); writer.Run(); // TODO(brettw) I think we'll need to worry about backslashes here @@ -36,10 +36,10 @@ TEST(NinjaBinaryTargetWriter, SourceSet) { "cflags_objc =\n" "cflags_objcc =\n" "\n" - "build obj/foo/bar.input1.obj: tc_cxx ../../foo/input1.cc\n" - "build obj/foo/bar.input2.obj: tc_cxx ../../foo/input2.cc\n" + "build obj/foo/bar.input1.obj: cxx ../../foo/input1.cc\n" + "build obj/foo/bar.input2.obj: cxx ../../foo/input2.cc\n" "\n" - "build obj/foo/bar.stamp: tc_stamp obj/foo/bar.input1.obj obj/foo/bar.input2.obj\n"; + "build obj/foo/bar.stamp: stamp obj/foo/bar.input1.obj obj/foo/bar.input2.obj\n"; std::string out_str = out.str(); #if defined(OS_WIN) std::replace(out_str.begin(), out_str.end(), '\\', '/'); @@ -55,7 +55,7 @@ TEST(NinjaBinaryTargetWriter, SourceSet) { { std::ostringstream out; - NinjaBinaryTargetWriter writer(&shlib_target, out); + NinjaBinaryTargetWriter writer(&shlib_target, setup.toolchain(), out); writer.Run(); // TODO(brettw) I think we'll need to worry about backslashes here @@ -73,7 +73,7 @@ TEST(NinjaBinaryTargetWriter, SourceSet) { "manifests = obj/foo/shlib.intermediate.manifest\n" "ldflags = /MANIFEST /ManifestFile:obj/foo/shlib.intermediate.manifest\n" "libs =\n" - "build shlib.dll shlib.dll.lib: tc_solink obj/foo/bar.input1.obj obj/foo/bar.input2.obj\n" + "build shlib.dll shlib.dll.lib: solink obj/foo/bar.input1.obj obj/foo/bar.input2.obj\n" " soname = shlib.dll\n" " lib = shlib.dll\n" " dll = shlib.dll\n" diff --git a/tools/gn/ninja_copy_target_writer.cc b/tools/gn/ninja_copy_target_writer.cc index 5de249f..89b3e3f 100644 --- a/tools/gn/ninja_copy_target_writer.cc +++ b/tools/gn/ninja_copy_target_writer.cc @@ -9,8 +9,9 @@ #include "tools/gn/string_utils.h" NinjaCopyTargetWriter::NinjaCopyTargetWriter(const Target* target, + const Toolchain* toolchain, std::ostream& out) - : NinjaTargetWriter(target, out) { + : NinjaTargetWriter(target, toolchain, out) { } NinjaCopyTargetWriter::~NinjaCopyTargetWriter() { @@ -22,8 +23,7 @@ void NinjaCopyTargetWriter::Run() { std::vector<OutputFile> output_files; - std::string rule_prefix = - helper_.GetRulePrefix(target_->settings()->toolchain()); + std::string rule_prefix = helper_.GetRulePrefix(target_->settings()); for (size_t i = 0; i < target_->sources().size(); i++) { const SourceFile& input_file = target_->sources()[i]; diff --git a/tools/gn/ninja_copy_target_writer.h b/tools/gn/ninja_copy_target_writer.h index 99bbaff..cadbc38 100644 --- a/tools/gn/ninja_copy_target_writer.h +++ b/tools/gn/ninja_copy_target_writer.h @@ -11,7 +11,9 @@ // Writes a .ninja file for a copy target type. class NinjaCopyTargetWriter : public NinjaTargetWriter { public: - NinjaCopyTargetWriter(const Target* target, std::ostream& out); + NinjaCopyTargetWriter(const Target* target, + const Toolchain* toolchain, + std::ostream& out); virtual ~NinjaCopyTargetWriter(); virtual void Run() OVERRIDE; diff --git a/tools/gn/ninja_copy_target_writer_unittest.cc b/tools/gn/ninja_copy_target_writer_unittest.cc index c31cbd2..5642d9d 100644 --- a/tools/gn/ninja_copy_target_writer_unittest.cc +++ b/tools/gn/ninja_copy_target_writer_unittest.cc @@ -27,14 +27,14 @@ TEST(NinjaCopyTargetWriter, Run) { setup.settings()->set_target_os(Settings::LINUX); std::ostringstream out; - NinjaCopyTargetWriter writer(&target, out); + NinjaCopyTargetWriter writer(&target, setup.toolchain(), out); writer.Run(); const char expected_linux[] = - "build input1.out: tc_copy ../../foo/input1.txt\n" - "build input2.out: tc_copy ../../foo/input2.txt\n" + "build input1.out: copy ../../foo/input1.txt\n" + "build input2.out: copy ../../foo/input2.txt\n" "\n" - "build obj/foo/bar.stamp: tc_stamp input1.out input2.out\n"; + "build obj/foo/bar.stamp: stamp input1.out input2.out\n"; std::string out_str = out.str(); #if defined(OS_WIN) std::replace(out_str.begin(), out_str.end(), '\\', '/'); @@ -47,16 +47,16 @@ TEST(NinjaCopyTargetWriter, Run) { setup.settings()->set_target_os(Settings::WIN); std::ostringstream out; - NinjaCopyTargetWriter writer(&target, out); + NinjaCopyTargetWriter writer(&target, setup.toolchain(), out); writer.Run(); // TODO(brettw) I think we'll need to worry about backslashes here // depending if we're on actual Windows or Linux pretending to be Windows. const char expected_win[] = - "build input1.out: tc_copy ../../foo/input1.txt\n" - "build input2.out: tc_copy ../../foo/input2.txt\n" + "build input1.out: copy ../../foo/input1.txt\n" + "build input2.out: copy ../../foo/input2.txt\n" "\n" - "build obj/foo/bar.stamp: tc_stamp input1.out input2.out\n"; + "build obj/foo/bar.stamp: stamp input1.out input2.out\n"; std::string out_str = out.str(); #if defined(OS_WIN) std::replace(out_str.begin(), out_str.end(), '\\', '/'); diff --git a/tools/gn/ninja_group_target_writer.cc b/tools/gn/ninja_group_target_writer.cc index 606f916..d29f917 100644 --- a/tools/gn/ninja_group_target_writer.cc +++ b/tools/gn/ninja_group_target_writer.cc @@ -8,8 +8,9 @@ #include "tools/gn/string_utils.h" NinjaGroupTargetWriter::NinjaGroupTargetWriter(const Target* target, + const Toolchain* toolchain, std::ostream& out) - : NinjaTargetWriter(target, out) { + : NinjaTargetWriter(target, toolchain, out) { } NinjaGroupTargetWriter::~NinjaGroupTargetWriter() { @@ -21,7 +22,7 @@ void NinjaGroupTargetWriter::Run() { out_ << std::endl << "build "; path_output_.WriteFile(out_, helper_.GetTargetOutputFile(target_)); out_ << ": " - << helper_.GetRulePrefix(target_->settings()->toolchain()) + << helper_.GetRulePrefix(target_->settings()) << "stamp"; const LabelTargetVector& deps = target_->deps(); diff --git a/tools/gn/ninja_group_target_writer.h b/tools/gn/ninja_group_target_writer.h index 31625f8..862b920 100644 --- a/tools/gn/ninja_group_target_writer.h +++ b/tools/gn/ninja_group_target_writer.h @@ -11,7 +11,9 @@ // Writes a .ninja file for a group target type. class NinjaGroupTargetWriter : public NinjaTargetWriter { public: - NinjaGroupTargetWriter(const Target* target, std::ostream& out); + NinjaGroupTargetWriter(const Target* target, + const Toolchain* toolchain, + std::ostream& out); virtual ~NinjaGroupTargetWriter(); virtual void Run() OVERRIDE; diff --git a/tools/gn/ninja_helper.cc b/tools/gn/ninja_helper.cc index d90b698..e872c24 100644 --- a/tools/gn/ninja_helper.cc +++ b/tools/gn/ninja_helper.cc @@ -189,23 +189,20 @@ OutputFile NinjaHelper::GetTargetOutputFile(const Target* target) const { return ret; } -std::string NinjaHelper::GetRulePrefix(const Toolchain* toolchain) const { - // This code doesn't prefix the default toolchain commands. This is disabled - // so we can coexist with GYP's commands (which aren't prefixed). If we don't - // need to coexist with GYP anymore, we can uncomment this to make things a - // bit prettier. - //if (toolchain->is_default()) - // return std::string(); // Default toolchain has no prefix. - return toolchain->label().name() + "_"; +std::string NinjaHelper::GetRulePrefix(const Settings* settings) const { + // Don't prefix the default toolchain so it looks prettier, prefix everything + // else. + if (settings->is_default()) + return std::string(); // Default toolchain has no prefix. + return settings->toolchain_label().name() + "_"; } std::string NinjaHelper::GetRuleForSourceType(const Settings* settings, - const Toolchain* toolchain, SourceFileType type) const { // This function may be hot since it will be called for every source file // in the tree. We could cache the results to avoid making a string for // every invocation. - std::string prefix = GetRulePrefix(toolchain); + std::string prefix = GetRulePrefix(settings); if (type == SOURCE_C) return prefix + "cc"; diff --git a/tools/gn/ninja_helper.h b/tools/gn/ninja_helper.h index bef2fcd..84a2c89 100644 --- a/tools/gn/ninja_helper.h +++ b/tools/gn/ninja_helper.h @@ -52,12 +52,11 @@ class NinjaHelper { // Returns the prefix for rules on the given toolchain. We need this to // disambiguate a given rule for each toolchain. - std::string GetRulePrefix(const Toolchain* toolchain) const; + std::string GetRulePrefix(const Settings* settings) const; // Returns the name of the rule name for the given toolchain and file/target // type. Returns the empty string for source files with no command. std::string GetRuleForSourceType(const Settings* settings, - const Toolchain* toolchain, SourceFileType type) const; // Returns the relative directory in either slashes or the system separator diff --git a/tools/gn/ninja_helper_unittest.cc b/tools/gn/ninja_helper_unittest.cc index 6e3b25c..81f3669 100644 --- a/tools/gn/ninja_helper_unittest.cc +++ b/tools/gn/ninja_helper_unittest.cc @@ -17,9 +17,10 @@ class HelperSetterUpper { public: HelperSetterUpper() : build_settings(), - toolchain(Label(SourceDir("//"), "tc")), - settings(&build_settings, &toolchain, std::string()), + settings(&build_settings, std::string()), + toolchain(&settings, Label(SourceDir("//"), "tc")), target(&settings, Label(SourceDir("//tools/gn/"), "name")) { + settings.set_toolchain_label(toolchain.label()); settings.set_target_os(Settings::WIN); // Output going to "out/Debug". @@ -30,8 +31,8 @@ class HelperSetterUpper { } BuildSettings build_settings; - Toolchain toolchain; Settings settings; + Toolchain toolchain; Target target; }; diff --git a/tools/gn/ninja_script_target_writer.cc b/tools/gn/ninja_script_target_writer.cc index 1b8358c..e8cdef4 100644 --- a/tools/gn/ninja_script_target_writer.cc +++ b/tools/gn/ninja_script_target_writer.cc @@ -11,8 +11,9 @@ #include "tools/gn/target.h" NinjaScriptTargetWriter::NinjaScriptTargetWriter(const Target* target, + const Toolchain* toolchain, std::ostream& out) - : NinjaTargetWriter(target, out), + : NinjaTargetWriter(target, toolchain, out), path_output_no_escaping_( target->settings()->build_settings()->build_dir(), ESCAPE_NONE, false) { @@ -152,7 +153,7 @@ void NinjaScriptTargetWriter::WriteStamp( out_ << "build "; path_output_.WriteFile(out_, helper_.GetTargetOutputFile(target_)); out_ << ": " - << helper_.GetRulePrefix(target_->settings()->toolchain()) + << helper_.GetRulePrefix(target_->settings()) << "stamp"; for (size_t i = 0; i < output_files.size(); i++) { out_ << " "; diff --git a/tools/gn/ninja_script_target_writer.h b/tools/gn/ninja_script_target_writer.h index e84d618..9c51a6a 100644 --- a/tools/gn/ninja_script_target_writer.h +++ b/tools/gn/ninja_script_target_writer.h @@ -17,7 +17,9 @@ class OutputFile; // Writes a .ninja file for a custom script target type. class NinjaScriptTargetWriter : public NinjaTargetWriter { public: - NinjaScriptTargetWriter(const Target* target, std::ostream& out); + NinjaScriptTargetWriter(const Target* target, + const Toolchain* toolchain, + std::ostream& out); virtual ~NinjaScriptTargetWriter(); virtual void Run() OVERRIDE; diff --git a/tools/gn/ninja_script_target_writer_unittest.cc b/tools/gn/ninja_script_target_writer_unittest.cc index 1394717..f2c8a93 100644 --- a/tools/gn/ninja_script_target_writer_unittest.cc +++ b/tools/gn/ninja_script_target_writer_unittest.cc @@ -21,7 +21,7 @@ TEST(NinjaScriptTargetWriter, WriteOutputFilesForBuildLine) { SourceFile("//out/Debug/gen/{{source_name_part}}.cc")); std::ostringstream out; - NinjaScriptTargetWriter writer(&target, out); + NinjaScriptTargetWriter writer(&target, setup.toolchain(), out); FileTemplate output_template = writer.GetOutputTemplate(); @@ -42,7 +42,7 @@ TEST(NinjaScriptTargetWriter, WriteArgsSubstitutions) { Target target(setup.settings(), Label(SourceDir("//foo/"), "bar")); std::ostringstream out; - NinjaScriptTargetWriter writer(&target, out); + NinjaScriptTargetWriter writer(&target, setup.toolchain(), out); std::vector<std::string> args; args.push_back("-i"); @@ -88,7 +88,7 @@ TEST(NinjaScriptTargetWriter, InvokeOverSources) { "/usr/bin/python"))); std::ostringstream out; - NinjaScriptTargetWriter writer(&target, out); + NinjaScriptTargetWriter writer(&target, setup.toolchain(), out); writer.Run(); const char expected_linux[] = @@ -107,7 +107,7 @@ TEST(NinjaScriptTargetWriter, InvokeOverSources) { " source = ../../foo/input2.txt\n" " source_name_part = input2\n" "\n" - "build obj/foo/bar.stamp: tc_stamp input1.out input2.out\n"; + "build obj/foo/bar.stamp: stamp input1.out input2.out\n"; std::string out_str = out.str(); #if defined(OS_WIN) @@ -125,7 +125,7 @@ TEST(NinjaScriptTargetWriter, InvokeOverSources) { setup.settings()->set_target_os(Settings::WIN); std::ostringstream out; - NinjaScriptTargetWriter writer(&target, out); + NinjaScriptTargetWriter writer(&target, setup.toolchain(), out); writer.Run(); // TODO(brettw) I think we'll need to worry about backslashes here @@ -151,7 +151,7 @@ TEST(NinjaScriptTargetWriter, InvokeOverSources) { " source = ../../foo/input2.txt\n" " source_name_part = input2\n" "\n" - "build obj/foo/bar.stamp: tc_stamp input1.out input2.out\n"; + "build obj/foo/bar.stamp: stamp input1.out input2.out\n"; std::string out_str = out.str(); #if defined(OS_WIN) std::replace(out_str.begin(), out_str.end(), '\\', '/'); diff --git a/tools/gn/ninja_target_writer.cc b/tools/gn/ninja_target_writer.cc index d73c873..bdc0472 100644 --- a/tools/gn/ninja_target_writer.cc +++ b/tools/gn/ninja_target_writer.cc @@ -19,9 +19,12 @@ #include "tools/gn/target.h" #include "tools/gn/trace.h" -NinjaTargetWriter::NinjaTargetWriter(const Target* target, std::ostream& out) +NinjaTargetWriter::NinjaTargetWriter(const Target* target, + const Toolchain* toolchain, + std::ostream& out) : settings_(target->settings()), target_(target), + toolchain_(toolchain), out_(out), path_output_(settings_->build_settings()->build_dir(), ESCAPE_NINJA, true), @@ -45,7 +48,7 @@ void NinjaTargetWriter::RunAndWriteFile(const Target* target) { ScopedTrace trace(TraceItem::TRACE_FILE_WRITE, target->label().GetUserVisibleName(false)); - trace.SetToolchain(settings->toolchain()->label()); + trace.SetToolchain(settings->toolchain_label()); base::FilePath ninja_file(settings->build_settings()->GetFullPath( helper.GetNinjaFileForTarget(target).GetSourceFile( @@ -54,6 +57,10 @@ void NinjaTargetWriter::RunAndWriteFile(const Target* target) { if (g_scheduler->verbose_logging()) g_scheduler->Log("Writing", FilePathToUTF8(ninja_file)); + const Toolchain* tc = settings->build_settings()->toolchain_manager() + .GetToolchainDefinitionUnlocked(settings->toolchain_label()); + CHECK(tc); + file_util::CreateDirectory(ninja_file.DirName()); // It's rediculously faster to write to a string and then write that to @@ -62,19 +69,19 @@ void NinjaTargetWriter::RunAndWriteFile(const Target* target) { // Call out to the correct sub-type of writer. if (target->output_type() == Target::COPY_FILES) { - NinjaCopyTargetWriter writer(target, file); + NinjaCopyTargetWriter writer(target, tc, file); writer.Run(); } else if (target->output_type() == Target::CUSTOM) { - NinjaScriptTargetWriter writer(target, file); + NinjaScriptTargetWriter writer(target, tc, file); writer.Run(); } else if (target->output_type() == Target::GROUP) { - NinjaGroupTargetWriter writer(target, file); + NinjaGroupTargetWriter writer(target, tc, file); writer.Run(); } else if (target->output_type() == Target::EXECUTABLE || target->output_type() == Target::STATIC_LIBRARY || target->output_type() == Target::SHARED_LIBRARY || target->output_type() == Target::SOURCE_SET) { - NinjaBinaryTargetWriter writer(target, file); + NinjaBinaryTargetWriter writer(target, tc, file); writer.Run(); } else { CHECK(0); @@ -85,10 +92,6 @@ void NinjaTargetWriter::RunAndWriteFile(const Target* target) { static_cast<int>(contents.size())); } -const Toolchain* NinjaTargetWriter::GetToolchain() const { - return target_->settings()->toolchain(); -} - std::string NinjaTargetWriter::GetSourcesImplicitDeps() const { std::ostringstream ret; ret << " |"; diff --git a/tools/gn/ninja_target_writer.h b/tools/gn/ninja_target_writer.h index c9c72a7..e1c3bf8 100644 --- a/tools/gn/ninja_target_writer.h +++ b/tools/gn/ninja_target_writer.h @@ -19,7 +19,9 @@ class Target; // generated by the NinjaBuildWriter. class NinjaTargetWriter { public: - NinjaTargetWriter(const Target* target, std::ostream& out); + NinjaTargetWriter(const Target* target, + const Toolchain* toolchain, + std::ostream& out); virtual ~NinjaTargetWriter(); static void RunAndWriteFile(const Target* target); @@ -27,9 +29,6 @@ class NinjaTargetWriter { virtual void Run() = 0; protected: - // Returns the toolchain associated with the target. - const Toolchain* GetToolchain() const; - // Returns the string to be appended to source rules that encodes the // order-only dependencies for the current target. This will include the // "|" character so can just be appended to the source rules. If there are no @@ -41,6 +40,7 @@ class NinjaTargetWriter { const Settings* settings_; // Non-owning. const Target* target_; // Non-owning. + const Toolchain* toolchain_; // Non-owning. std::ostream& out_; PathOutput path_output_; diff --git a/tools/gn/ninja_toolchain_writer.cc b/tools/gn/ninja_toolchain_writer.cc index 310caba..5f33e69 100644 --- a/tools/gn/ninja_toolchain_writer.cc +++ b/tools/gn/ninja_toolchain_writer.cc @@ -13,6 +13,7 @@ #include "tools/gn/settings.h" #include "tools/gn/target.h" #include "tools/gn/toolchain.h" +#include "tools/gn/toolchain_manager.h" #include "tools/gn/trace.h" NinjaToolchainWriter::NinjaToolchainWriter( @@ -62,11 +63,14 @@ bool NinjaToolchainWriter::RunAndWriteFile( } void NinjaToolchainWriter::WriteRules() { - const Toolchain* tc = settings_->toolchain(); + const Toolchain* tc = settings_->build_settings()->toolchain_manager() + .GetToolchainDefinitionUnlocked(settings_->toolchain_label()); + CHECK(tc); + std::string indent(" "); NinjaHelper helper(settings_->build_settings()); - std::string rule_prefix = helper.GetRulePrefix(tc); + std::string rule_prefix = helper.GetRulePrefix(settings_); for (int i = Toolchain::TYPE_NONE + 1; i < Toolchain::TYPE_NUMTYPES; i++) { Toolchain::ToolType tool_type = static_cast<Toolchain::ToolType>(i); diff --git a/tools/gn/scope_per_file_provider.cc b/tools/gn/scope_per_file_provider.cc index 525aab6..1f4bc25 100644 --- a/tools/gn/scope_per_file_provider.cc +++ b/tools/gn/scope_per_file_provider.cc @@ -43,7 +43,7 @@ const Value* ScopePerFileProvider::GetProgrammaticValue( const Value* ScopePerFileProvider::GetCurrentToolchain() { if (!current_toolchain_) { current_toolchain_.reset(new Value(NULL, - scope_->settings()->toolchain()->label().GetUserVisibleName(false))); + scope_->settings()->toolchain_label().GetUserVisibleName(false))); } return current_toolchain_.get(); } diff --git a/tools/gn/scope_per_file_provider_unittest.cc b/tools/gn/scope_per_file_provider_unittest.cc index 1137d3b..776a0aa 100644 --- a/tools/gn/scope_per_file_provider_unittest.cc +++ b/tools/gn/scope_per_file_provider_unittest.cc @@ -6,34 +6,26 @@ #include "tools/gn/build_settings.h" #include "tools/gn/scope_per_file_provider.h" #include "tools/gn/settings.h" +#include "tools/gn/test_with_scope.h" #include "tools/gn/toolchain.h" #include "tools/gn/variables.h" TEST(ScopePerFileProvider, Expected) { - Err err; - - BuildSettings build_settings; - build_settings.toolchain_manager().SetDefaultToolchainUnlocked( - Label(SourceDir("//toolchain/"), "default", SourceDir(), ""), - LocationRange(), &err); - EXPECT_FALSE(err.has_error()); - - build_settings.SetBuildDir(SourceDir("//out/Debug/")); + TestWithScope test; // Prevent horrible wrapping of calls below. #define GPV(val) provider.GetProgrammaticValue(val)->string_value() // Test the default toolchain. { - Toolchain toolchain(Label(SourceDir("//toolchain/"), "tc")); - Settings settings(&build_settings, &toolchain, std::string()); - - Scope scope(&settings); + Scope scope(test.settings()); scope.set_source_dir(SourceDir("//source/")); ScopePerFileProvider provider(&scope); - EXPECT_EQ("//toolchain:tc", GPV(variables::kCurrentToolchain)); - EXPECT_EQ("//toolchain:default", GPV(variables::kDefaultToolchain)); + EXPECT_EQ("//toolchain:default", GPV(variables::kCurrentToolchain)); + // TODO(brettw) this test harness does not set up the Toolchain manager + // which is the source of this value, so we can't test this yet. + //EXPECT_EQ("//toolchain:default", GPV(variables::kDefaultToolchain)); EXPECT_EQ("//out/Debug", GPV(variables::kRootBuildDir)); EXPECT_EQ("//out/Debug/gen", GPV(variables::kRootGenDir)); EXPECT_EQ("//out/Debug", GPV(variables::kRootOutDir)); @@ -43,13 +35,17 @@ TEST(ScopePerFileProvider, Expected) { // Test some with an alternate toolchain. { - Toolchain toolchain(Label(SourceDir("//toolchain/"), "tc")); - Settings settings(&build_settings, &toolchain, "tc"); + Settings settings(test.build_settings(), "tc"); + Toolchain toolchain(&settings, Label(SourceDir("//toolchain/"), "tc")); + settings.set_toolchain_label(toolchain.label()); Scope scope(&settings); scope.set_source_dir(SourceDir("//source/")); ScopePerFileProvider provider(&scope); + EXPECT_EQ("//toolchain:tc", GPV(variables::kCurrentToolchain)); + // See above. + //EXPECT_EQ("//toolchain:default", GPV(variables::kDefaultToolchain)); EXPECT_EQ("//out/Debug", GPV(variables::kRootBuildDir)); EXPECT_EQ("//out/Debug/tc/gen", GPV(variables::kRootGenDir)); EXPECT_EQ("//out/Debug/tc", GPV(variables::kRootOutDir)); diff --git a/tools/gn/settings.cc b/tools/gn/settings.cc index bfab85d..b8de976 100644 --- a/tools/gn/settings.cc +++ b/tools/gn/settings.cc @@ -9,10 +9,9 @@ #include "tools/gn/filesystem_utils.h" Settings::Settings(const BuildSettings* build_settings, - const Toolchain* toolchain, const std::string& output_subdir_name) : build_settings_(build_settings), - toolchain_(toolchain), + is_default_(false), import_manager_(), base_config_(this), greedy_target_generation_(false) { diff --git a/tools/gn/settings.h b/tools/gn/settings.h index 1305c58..df6a3d6 100644 --- a/tools/gn/settings.h +++ b/tools/gn/settings.h @@ -38,18 +38,17 @@ class Settings { // toolchain's outputs. It should have no slashes in it. The default // toolchain should use an empty string. Settings(const BuildSettings* build_settings, - const Toolchain* toolchain, const std::string& output_subdir_name); ~Settings(); const BuildSettings* build_settings() const { return build_settings_; } - // Danger: this must only be used for getting the toolchain label until the - // toolchain has been resolved. Otherwise, it will be modified on an - // arbitrary thread when the toolchain invocation is found. Generally, you - // will only read this from the target generation where we know everything - // has been resolved and won't change. - const Toolchain* toolchain() const { return toolchain_; } + const Label& toolchain_label() const { return toolchain_label_; } + void set_toolchain_label(const Label& l) { toolchain_label_ = l; } + + // Indicates if this corresponds to the default toolchain. + bool is_default() const { return is_default_; } + void set_is_default(bool id) { is_default_ = id; } bool IsMac() const { return target_os_ == MAC; } bool IsLinux() const { return target_os_ == LINUX; } @@ -94,7 +93,8 @@ class Settings { private: const BuildSettings* build_settings_; - const Toolchain* toolchain_; + Label toolchain_label_; + bool is_default_; TargetOS target_os_; diff --git a/tools/gn/setup.cc b/tools/gn/setup.cc index 8bce9b5..47a243a 100644 --- a/tools/gn/setup.cc +++ b/tools/gn/setup.cc @@ -202,9 +202,9 @@ bool CommonSetup::RunPostMessageLoop() { Setup::Setup() : CommonSetup(), - empty_toolchain_(Label()), - empty_settings_(&empty_build_settings_, &empty_toolchain_, std::string()), + empty_settings_(&empty_build_settings_, std::string()), dotfile_scope_(&empty_settings_) { + empty_settings_.set_toolchain_label(Label()); } Setup::~Setup() { diff --git a/tools/gn/setup.h b/tools/gn/setup.h index c2b3d82..8b6d714 100644 --- a/tools/gn/setup.h +++ b/tools/gn/setup.h @@ -91,7 +91,6 @@ class Setup : public CommonSetup { // These empty settings and toolchain are used to interpret the command line // and dot file. BuildSettings empty_build_settings_; - Toolchain empty_toolchain_; Settings empty_settings_; Scope dotfile_scope_; diff --git a/tools/gn/target.cc b/tools/gn/target.cc index 291d579..28dcf91 100644 --- a/tools/gn/target.cc +++ b/tools/gn/target.cc @@ -57,8 +57,7 @@ void MergeAllDependentConfigsFrom(const Target* from_target, } // namespace Target::Target(const Settings* settings, const Label& label) - : Item(label), - settings_(settings), + : Item(settings, label), output_type_(UNKNOWN), hard_dep_(false), external_(false), @@ -155,9 +154,9 @@ void Target::OnResolved() { } // Mark as resolved. - if (!settings_->build_settings()->target_resolved_callback().is_null()) { + if (!settings()->build_settings()->target_resolved_callback().is_null()) { g_scheduler->ScheduleWork(base::Bind(&TargetResolvedThunk, - settings_->build_settings()->target_resolved_callback(), + settings()->build_settings()->target_resolved_callback(), this)); } } diff --git a/tools/gn/target.h b/tools/gn/target.h index d5c1af3..13b278c 100644 --- a/tools/gn/target.h +++ b/tools/gn/target.h @@ -58,8 +58,6 @@ class Target : public Item { bool HasBeenGenerated() const; void SetGenerated(const Token* token); - const Settings* settings() const { return settings_; } - OutputType output_type() const { return output_type_; } void set_output_type(OutputType t) { output_type_ = t; } @@ -149,7 +147,6 @@ class Target : public Item { // dependencies have been resolved. void PullDependentTargetInfo(std::set<const Config*>* unique_configs); - const Settings* settings_; OutputType output_type_; std::string output_name_; diff --git a/tools/gn/target_unittest.cc b/tools/gn/target_unittest.cc index ea1700f..ef213b5 100644 --- a/tools/gn/target_unittest.cc +++ b/tools/gn/target_unittest.cc @@ -15,16 +15,17 @@ class TargetTest : public testing::Test { public: TargetTest() : build_settings_(), - toolchain_(Label(SourceDir("//tc/"), "tc")), - settings_(&build_settings_, &toolchain_, std::string()) { + settings_(&build_settings_, std::string()), + toolchain_(&settings_, Label(SourceDir("//tc/"), "tc")) { + settings_.set_toolchain_label(toolchain_.label()); } virtual ~TargetTest() { } protected: BuildSettings build_settings_; - Toolchain toolchain_; Settings settings_; + Toolchain toolchain_; }; } // namespace @@ -122,15 +123,15 @@ TEST_F(TargetTest, DependentConfigs) { b.deps().push_back(LabelTargetPair(&c)); // Normal non-inherited config. - Config config(Label(SourceDir("//foo/"), "config")); + Config config(&settings_, Label(SourceDir("//foo/"), "config")); c.configs().push_back(LabelConfigPair(&config)); // All dependent config. - Config all(Label(SourceDir("//foo/"), "all")); + Config all(&settings_, Label(SourceDir("//foo/"), "all")); c.all_dependent_configs().push_back(LabelConfigPair(&all)); // Direct dependent config. - Config direct(Label(SourceDir("//foo/"), "direct")); + Config direct(&settings_, Label(SourceDir("//foo/"), "direct")); c.direct_dependent_configs().push_back(LabelConfigPair(&direct)); c.OnResolved(); diff --git a/tools/gn/test_with_scope.cc b/tools/gn/test_with_scope.cc index e83c99c..e149e92 100644 --- a/tools/gn/test_with_scope.cc +++ b/tools/gn/test_with_scope.cc @@ -6,9 +6,13 @@ TestWithScope::TestWithScope() : build_settings_(), - toolchain_(Label(SourceDir("//toolchain/"), "tc")), - settings_(&build_settings_, &toolchain_, std::string()), + settings_(&build_settings_, std::string()), + toolchain_(&settings_, Label(SourceDir("//toolchain/"), "default")), scope_(&settings_) { + build_settings_.SetBuildDir(SourceDir("//out/Debug/")); + + settings_.set_toolchain_label(toolchain_.label()); + settings_.set_is_default(true); } TestWithScope::~TestWithScope() { diff --git a/tools/gn/test_with_scope.h b/tools/gn/test_with_scope.h index 7d512c4..df2c93e 100644 --- a/tools/gn/test_with_scope.h +++ b/tools/gn/test_with_scope.h @@ -20,12 +20,13 @@ class TestWithScope { BuildSettings* build_settings() { return &build_settings_; } Settings* settings() { return &settings_; } + Toolchain* toolchain() { return &toolchain_; } Scope* scope() { return &scope_; } private: BuildSettings build_settings_; - Toolchain toolchain_; Settings settings_; + Toolchain toolchain_; Scope scope_; DISALLOW_COPY_AND_ASSIGN(TestWithScope); diff --git a/tools/gn/toolchain.cc b/tools/gn/toolchain.cc index 887fba2..eee458a 100644 --- a/tools/gn/toolchain.cc +++ b/tools/gn/toolchain.cc @@ -25,7 +25,8 @@ Toolchain::Tool::Tool() { Toolchain::Tool::~Tool() { } -Toolchain::Toolchain(const Label& label) : Item(label), is_default_(false) { +Toolchain::Toolchain(const Settings* settings, const Label& label) + : Item(settings, label) { } Toolchain::~Toolchain() { diff --git a/tools/gn/toolchain.h b/tools/gn/toolchain.h index 106f2f4..210c2c0 100644 --- a/tools/gn/toolchain.h +++ b/tools/gn/toolchain.h @@ -70,7 +70,7 @@ class Toolchain : public Item { std::string rspfile_content; }; - Toolchain(const Label& label); + Toolchain(const Settings* settings, const Label& label); virtual ~Toolchain(); // Item overrides. @@ -87,9 +87,6 @@ class Toolchain : public Item { const std::string& environment() const { return environment_; } void set_environment(const std::string& env) { environment_ = env; } - bool is_default() const { return is_default_; } - void set_is_default(bool id) { is_default_ = id; } - // Specifies build argument overrides that will be set on the base scope. It // will be as if these arguments were passed in on the command line. This // allows a toolchain to override the OS type of the default toolchain or @@ -100,7 +97,6 @@ class Toolchain : public Item { private: Tool tools_[TYPE_NUMTYPES]; - bool is_default_; Scope::KeyValueMap args_; std::string environment_; diff --git a/tools/gn/toolchain_manager.cc b/tools/gn/toolchain_manager.cc index affdec9..4edf212 100644 --- a/tools/gn/toolchain_manager.cc +++ b/tools/gn/toolchain_manager.cc @@ -78,11 +78,17 @@ struct ToolchainManager::Info { const Label& toolchain_name, const std::string& output_subdir_name) : state(TOOLCHAIN_NOT_LOADED), - toolchain(toolchain_name), + settings(build_settings, output_subdir_name), + toolchain(new Toolchain(&settings, toolchain_name)), toolchain_set(false), - settings(build_settings, &toolchain, output_subdir_name), toolchain_file_loaded(false), item_node(NULL) { + settings.set_toolchain_label(toolchain_name); + } + + ~Info() { + if (!item_node) // See toolchain definition for more. + delete toolchain; } // Makes sure that an ItemNode is created for the toolchain, which lets @@ -95,17 +101,13 @@ struct ToolchainManager::Info { void EnsureItemNode() { if (!item_node) { ItemTree& tree = settings.build_settings()->item_tree(); - item_node = new ItemNode(&toolchain); + item_node = new ItemNode(toolchain); tree.AddNodeLocked(item_node); } } ToolchainState state; - Toolchain toolchain; - bool toolchain_set; - LocationRange toolchain_definition_location; - // The first place in the build that we saw a reference for this toolchain. // This allows us to report errors if it can't be loaded and blame some // reasonable place of the code. This will be empty for the default toolchain. @@ -118,6 +120,13 @@ struct ToolchainManager::Info { // is only ever read or written inside the lock. Settings settings; + // When we create an item node, this pointer will be owned by that node + // so it's lifetime is managed by the dependency graph. Before we've created + // the ItemNode, this class has to takre responsibility for this pointer. + Toolchain* toolchain; + bool toolchain_set; + LocationRange toolchain_definition_location; + // Set when the file corresponding to the toolchain definition is loaded. // This will normally be set right after "toolchain_set". However, if the // toolchain definition is missing, the file might be marked loaded but the @@ -202,7 +211,7 @@ const Toolchain* ToolchainManager::GetToolchainDefinitionUnlocked( // Since we don't allow defining a toolchain more than once, we know that // once it's set it won't be mutated, so we can safely return this pointer // for reading outside the lock. - return &found->second->toolchain; + return found->second->toolchain; } bool ToolchainManager::SetDefaultToolchainUnlocked( @@ -261,13 +270,10 @@ bool ToolchainManager::SetToolchainDefinitionLocked( } // The labels should match or else we're setting the wrong one! - CHECK(info->toolchain.label() == tc.label()); + CHECK(info->toolchain->label() == tc.label()); - // Save the toolchain. We can just overwrite our definition, but we need to - // be careful to preserve the is_default flag. - bool is_default = info->toolchain.is_default(); - info->toolchain = tc; - info->toolchain.set_is_default(is_default); + // Save the toolchain. We can just overwrite our definition. + *info->toolchain = tc; if (info->toolchain_set) { *err = Err(defined_from, "Duplicate toolchain definition."); @@ -423,8 +429,9 @@ void ToolchainManager::FixupDefaultToolchainLocked() { // to set the label, but we can assign the toolchain to a new one. Loading // the build config can not change the toolchain, so we won't be overwriting // anything useful. - info->toolchain = Toolchain(default_toolchain_); - info->toolchain.set_is_default(true); + *info->toolchain = Toolchain(&info->settings, default_toolchain_); + info->settings.set_is_default(true); + info->settings.set_toolchain_label(default_toolchain_); info->EnsureItemNode(); // The default toolchain is loaded in greedy mode so all targets we @@ -486,8 +493,8 @@ void ToolchainManager::BackgroundLoadBuildConfig(Info* info, Scope* base_config = info->settings.base_config(); base_config->set_source_dir(SourceDir("//")); - info->settings.build_settings()->build_args().SetupRootScope(base_config, - info->settings.toolchain()->args()); + info->settings.build_settings()->build_args().SetupRootScope( + base_config, info->toolchain->args()); base_config->SetProcessingBuildConfig(); if (is_default) @@ -495,7 +502,7 @@ void ToolchainManager::BackgroundLoadBuildConfig(Info* info, ScopedTrace trace(TraceItem::TRACE_FILE_EXECUTE, info->settings.build_settings()->build_config_file().value()); - trace.SetToolchain(info->settings.toolchain()->label()); + trace.SetToolchain(info->settings.toolchain_label()); const BlockNode* root_block = root->AsBlock(); Err err; @@ -540,7 +547,7 @@ void ToolchainManager::BackgroundInvoke(const Info* info, if (root && !g_scheduler->is_failed()) { if (g_scheduler->verbose_logging()) { g_scheduler->Log("Running", file_name.value() + " with toolchain " + - info->toolchain.label().GetUserVisibleName(false)); + info->toolchain->label().GetUserVisibleName(false)); } Scope our_scope(info->settings.base_config()); @@ -548,7 +555,7 @@ void ToolchainManager::BackgroundInvoke(const Info* info, our_scope.set_source_dir(file_name.GetDir()); ScopedTrace trace(TraceItem::TRACE_FILE_EXECUTE, file_name.value()); - trace.SetToolchain(info->settings.toolchain()->label()); + trace.SetToolchain(info->settings.toolchain_label()); Err err; root->Execute(&our_scope, &err); |