]> git.tdb.fi Git - builder.git/commitdiff
Delay locating tool executables until the tool is needed
authorMikko Rasa <tdb@tdb.fi>
Wed, 8 May 2013 07:24:45 +0000 (10:24 +0300)
committerMikko Rasa <tdb@tdb.fi>
Wed, 8 May 2013 07:37:23 +0000 (10:37 +0300)
This solves a problem where the mspdatatool executable is not detected as
built by the mspdatafile package.

25 files changed:
source/component.cpp
source/copy.cpp
source/copy.h
source/datatool.cpp
source/datatool.h
source/gnuarchiver.cpp
source/gnuarchiver.h
source/gnucompiler.cpp
source/gnucompiler.h
source/gnucxxcompiler.cpp
source/gnucxxcompiler.h
source/gnulinker.cpp
source/gnulinker.h
source/mingwdlltool.cpp
source/mingwdlltool.h
source/pkgconfiggenerator.cpp
source/pkgconfiggenerator.h
source/tar.cpp
source/tar.h
source/target.cpp
source/target.h
source/tool.cpp
source/tool.h
source/toolchain.cpp
source/toolchain.h

index 371e145a0369ab7f3a37a48131033d8446e567af..d0cc1e9822922726f5a5cce8f2af3c5fa0a7b7af 100644 (file)
@@ -138,7 +138,7 @@ void Component::create_targets() const
        string inst_loc;
        if(type==TARBALL)
        {
-               const Tool &tar = toolchain.get_tool("TAR");
+               Tool &tar = toolchain.get_tool("TAR");
 
                list<Target *> files;
                for(SourceList::const_iterator i=source_filenames.begin(); i!=source_filenames.end(); ++i)
@@ -171,7 +171,7 @@ void Component::create_targets() const
        else if(type==INSTALL)
        {
                Target *inst = build_graph.get_target("install");
-               const Tool &copy = toolchain.get_tool("CP");
+               Tool &copy = toolchain.get_tool("CP");
                for(SourceList::const_iterator i=source_filenames.begin(); i!=source_filenames.end(); ++i)
                {
                        FileTarget *ft;
@@ -184,7 +184,7 @@ void Component::create_targets() const
        }
        else if(type==DATAPACK)
        {
-               const Tool &dcomp = toolchain.get_tool("DATA");
+               Tool &dcomp = toolchain.get_tool("DATA");
 
                list<Target *> files;
                for(SourceList::const_iterator i=source_filenames.begin(); i!=source_filenames.end(); ++i)
@@ -214,7 +214,7 @@ void Component::create_targets() const
                for(SourceList::const_iterator i=source_filenames.begin(); i!=source_filenames.end(); ++i)
                {
                        string ext = FS::extpart(FS::basename(*i));
-                       const Tool *tool = toolchain.get_tool_for_suffix(ext, true);
+                       Tool *tool = toolchain.get_tool_for_suffix(ext, true);
                        if(tool)
                        {
                                Target *src = tool->create_source(*this, *i);
@@ -232,12 +232,12 @@ void Component::create_targets() const
                        }
                }
 
-               const Tool &linker = toolchain.get_tool("LINK");
+               Tool &linker = toolchain.get_tool("LINK");
 
                list<Target *> results;
                if(type==LIBRARY)
                {
-                       const Tool &archiver = toolchain.get_tool("AR");
+                       Tool &archiver = toolchain.get_tool("AR");
                        results.push_back(linker.create_target(objs, "shared"));
                        results.push_back(archiver.create_target(objs));
                }
index 75d047df7ef50c6371835f456a747f2c34b6121a..24be942532b83ab52a0dcfdeb8446ad29d708edf 100644 (file)
@@ -16,7 +16,7 @@ Copy::Copy(Builder &b):
        Tool(b, "CP")
 { }
 
-Target *Copy::create_target(const list<Target *> &sources, const string &arg) const
+Target *Copy::create_target(const list<Target *> &sources, const string &arg)
 {
        FileTarget &file_tgt = dynamic_cast<FileTarget &>(*sources.front());
        InstalledFile *inst = new InstalledFile(builder, *file_tgt.get_package(), file_tgt, arg);
index 3aa10a9a94ef42674d7acd83e8c27dcef71a6a23..dedd0f57a0e3aa41607d67b0f6d16c10c6fa799a 100644 (file)
@@ -31,7 +31,7 @@ private:
 public:
        Copy(Builder &);
 
-       virtual Target *create_target(const std::list<Target *> &, const std::string &) const;
+       virtual Target *create_target(const std::list<Target *> &, const std::string &);
        virtual Task *run(const Target &) const;
 };
 
index a956984a35deb6e9aa8b19eeca274fab4513db37..4a4fc8a0cd89360d875bc7682de8c8b02afc6cd5 100644 (file)
@@ -16,10 +16,6 @@ using namespace Msp;
 DataTool::DataTool(Builder &b):
        Tool(b, "DATA")
 {
-       executable = builder.get_vfs().find_binary("mspdatatool");
-       if(!executable)
-               builder.problem(string(), format("Can't find executable mspdatatool for tool %s", tag));
-
        input_suffixes.push_back(".mdt");
 }
 
@@ -28,7 +24,7 @@ Target *DataTool::create_source(const Component &comp, const FS::Path &path) con
        return new DataTransform(builder, comp, path);
 }
 
-Target *DataTool::create_target(const list<Target *> &sources, const string &arg) const
+Target *DataTool::create_target(const list<Target *> &sources, const string &arg)
 {
        if(arg=="collection")
        {
@@ -52,6 +48,13 @@ Target *DataTool::create_target(const list<Target *> &sources, const string &arg
                throw invalid_argument("DataTool::create_target");
 }
 
+void DataTool::do_prepare()
+{
+       executable = builder.get_vfs().find_binary("mspdatatool");
+       if(!executable)
+               builder.problem(string(), format("Can't find executable mspdatatool for tool %s", tag));
+}
+
 Task *DataTool::run(const Target &tgt) const
 {
        const Component &comp = *tgt.get_component();
index b6c4f5b67de060f315da6f51239d2ea8f942c19a..f2720c005b3622e657a8309e17c8e58ca6e308b8 100644 (file)
@@ -9,7 +9,10 @@ public:
        DataTool(Builder &);
 
        virtual Target *create_source(const Component &, const Msp::FS::Path &) const;
-       virtual Target *create_target(const std::list<Target *> &, const std::string &) const;
+       virtual Target *create_target(const std::list<Target *> &, const std::string &);
+private:
+       virtual void do_prepare();
+public:
        virtual Task *run(const Target &) const;
 };
 
index 3499204954593db5587280e5d1679b514f2e2215..7482b0d17caf004d66125f4a82c8c098d0bb2331 100644 (file)
@@ -17,15 +17,10 @@ using namespace Msp;
 GnuArchiver::GnuArchiver(Builder &b, const Architecture &a):
        Tool(b, a, "AR")
 {
-       string command = "ar";
-       if(architecture->is_cross())
-               command = format("%s-%s", architecture->get_cross_prefix(), command);
-       executable = builder.get_vfs().find_binary(command);
-
        input_suffixes.push_back(".o");
 }
 
-Target *GnuArchiver::create_target(const list<Target *> &sources, const string &) const
+Target *GnuArchiver::create_target(const list<Target *> &sources, const string &)
 {
        if(sources.empty())
                throw invalid_argument("GnuArchiver::create_target");
@@ -45,6 +40,14 @@ Target *GnuArchiver::create_target(const list<Target *> &sources, const string &
        return lib;
 }
 
+void GnuArchiver::do_prepare()
+{
+       string command = "ar";
+       if(architecture->is_cross())
+               command = format("%s-%s", architecture->get_cross_prefix(), command);
+       executable = builder.get_vfs().find_binary(command);
+}
+
 Task *GnuArchiver::run(const Target &target) const
 {
        const StaticLibrary &lib = dynamic_cast<const StaticLibrary &>(target);
index 41386f645f212b4f2e3cf8945086ca4fef4bc0ff..2c625b6c82265257148bfb4d7950a98163f88b01 100644 (file)
@@ -8,7 +8,10 @@ class GnuArchiver: public Tool
 public:
        GnuArchiver(Builder &, const Architecture &);
 
-       virtual Target *create_target(const std::list<Target *> &, const std::string &) const;
+       virtual Target *create_target(const std::list<Target *> &, const std::string &);
+private:
+       virtual void do_prepare();
+public:
        virtual Task *run(const Target &) const;
 };
 
index 06ad5a9d7e0037735cbc89c18bb2709bd7053070..7d1d166579467f4213735f0975d354a2690c55d4 100644 (file)
@@ -14,22 +14,16 @@ using namespace std;
 using namespace Msp;
 
 GnuCompiler::GnuCompiler(Builder &b, const Architecture &a, const string &t, const string &c):
-       Tool(b, a, t)
+       Tool(b, a, t),
+       command(c)
 {
-       string command = c;
-       if(architecture->is_cross())
-               command = format("%s-%s", architecture->get_cross_prefix(), command);
-       executable = builder.get_vfs().find_binary(command);
-       if(!executable)
-               builder.problem(string(), format("Can't find executable %s for tool %s", command, tag));
-
        if(architecture->is_native())
                system_path.push_back("/usr/include");
        else
                system_path.push_back("/usr/"+architecture->get_cross_prefix()+"/include");
 }
 
-Target *GnuCompiler::create_target(const list<Target *> &sources, const string &) const
+Target *GnuCompiler::create_target(const list<Target *> &sources, const string &)
 {
        if(sources.size()!=1)
                throw invalid_argument("GnuCCompiler::create_target");
@@ -58,6 +52,15 @@ string GnuCompiler::create_build_signature(const BuildInfo &binfo) const
        return result;
 }
 
+void GnuCompiler::do_prepare()
+{
+       if(architecture->is_cross())
+               command = format("%s-%s", architecture->get_cross_prefix(), command);
+       executable = builder.get_vfs().find_binary(command);
+       if(!executable)
+               builder.problem(string(), format("Can't find executable %s for tool %s", command, tag));
+}
+
 Task *GnuCompiler::run(const Target &target) const
 {
        const ObjectFile &object = dynamic_cast<const ObjectFile &>(target);
index 59928766fb1a8d93fd548251e1f23e72b70a895b..0c283e22827ac3f1afa05bdd4f6302bb032bd99d 100644 (file)
@@ -12,12 +12,18 @@ appropriate type.
 */
 class GnuCompiler: public Tool
 {
+private:
+       std::string command;
+
 protected:
        GnuCompiler(Builder &, const Architecture &, const std::string &, const std::string &);
 
 public:
-       virtual Target *create_target(const std::list<Target *> &, const std::string &) const;
+       virtual Target *create_target(const std::list<Target *> &, const std::string &);
        virtual std::string create_build_signature(const BuildInfo &) const;
+protected:
+       virtual void do_prepare();
+public:
        virtual Task *run(const Target &) const;
 };
 
index 9e206cc6b525edca08587ec43e966eba37afdf76..1926a5ed14bcc3e74a17fab214152c3ce87ca2a4 100644 (file)
@@ -16,9 +16,6 @@ GnuCxxCompiler::GnuCxxCompiler(Builder &b, const Architecture &a):
        input_suffixes.push_back(".cpp");
        input_suffixes.push_back(".cc");
        aux_suffixes.push_back(".hpp");
-
-       if(executable)
-               query_version();
 }
 
 void GnuCxxCompiler::query_version()
@@ -50,3 +47,10 @@ Target *GnuCxxCompiler::create_source(const FS::Path &path) const
 {
        return new CSourceFile(builder, path);
 }
+
+void GnuCxxCompiler::do_prepare()
+{
+       GnuCompiler::do_prepare();
+       if(executable)
+               query_version();
+}
index 314bb510e9ceb233d97fb91d3c7536b194f7acfb..5cdc34bd8a214d575cd8b5ed520354fcb237dbbc 100644 (file)
@@ -16,6 +16,9 @@ private:
 public:
        virtual Target *create_source(const Component &, const Msp::FS::Path &) const;
        virtual Target *create_source(const Msp::FS::Path &) const;
+
+private:
+       virtual void do_prepare();
 };
 
 #endif
index 21b765bd25f4ef41b139beaa06f3c58671252581..cfdee8daffc3570e572006d85093733bbe35c75f 100644 (file)
@@ -49,7 +49,7 @@ GnuLinker::~GnuLinker()
        delete cxx_linker;
 }
 
-Target *GnuLinker::create_target(const list<Target *> &sources, const string &arg) const
+Target *GnuLinker::create_target(const list<Target *> &sources, const string &arg)
 {
        if(sources.empty())
                throw invalid_argument("GnuLinker::create_target");
@@ -74,7 +74,7 @@ Target *GnuLinker::create_target(const list<Target *> &sources, const string &ar
                SharedLibrary *shlib = new SharedLibrary(builder, comp, objs);
                if(architecture->get_system()=="windows")
                {
-                       const Tool &dlltool = builder.get_toolchain().get_tool("DLL");
+                       Tool &dlltool = builder.get_toolchain().get_tool("DLL");
                        dlltool.create_target(*shlib);
                }
                bin = shlib;
@@ -89,7 +89,7 @@ Target *GnuLinker::create_install(Target &target) const
 {
        if(SharedLibrary *shlib = dynamic_cast<SharedLibrary *>(&target))
        {
-               const Tool &copy = builder.get_toolchain().get_tool("CP");
+               Tool &copy = builder.get_toolchain().get_tool("CP");
                InstalledFile *inst_tgt = dynamic_cast<InstalledFile *>(copy.create_target(target));
                if(architecture->get_system()=="windows")
                        builder.get_build_graph().add_installed_target(*shlib->get_import_library());
@@ -112,28 +112,12 @@ Task *GnuLinker::run(const Target &) const
 }
 
 
-GnuLinker::Linker::Linker(GnuLinker &p, const string &compiler_tag):
-       SubTool(p)
-{
-       const Tool &compiler = builder.get_toolchain().get_tool(compiler_tag);
-       if(dynamic_cast<const GnuCompiler *>(&compiler))
-               executable = compiler.get_executable();
-       else
-       {
-               string command;
-               if(compiler_tag=="CC")
-                       command = "gcc";
-               else if(compiler_tag=="CXX")
-                       command = "g++";
-               else
-                       throw invalid_argument("GnuLinker::Linker::Linker");
-               if(architecture->is_cross())
-                       command = format("%s-%s", architecture->get_cross_prefix(), command);
-               executable = builder.get_vfs().find_binary(command);
-       }
-}
+GnuLinker::Linker::Linker(GnuLinker &p, const string &ct):
+       SubTool(p),
+       compiler_tag(ct)
+{ }
 
-Target *GnuLinker::Linker::create_target(const list<Target *> &sources, const string &arg) const
+Target *GnuLinker::Linker::create_target(const list<Target *> &sources, const string &arg)
 {
        return parent.create_target(sources, arg);
 }
@@ -158,6 +142,29 @@ string GnuLinker::Linker::create_build_signature(const BuildInfo &binfo) const
        return result;
 }
 
+void GnuLinker::Linker::do_prepare()
+{
+       Tool &compiler = builder.get_toolchain().get_tool(compiler_tag);
+       if(dynamic_cast<GnuCompiler *>(&compiler))
+       {
+               compiler.prepare();
+               executable = compiler.get_executable();
+       }
+       else
+       {
+               string command;
+               if(compiler_tag=="CC")
+                       command = "gcc";
+               else if(compiler_tag=="CXX")
+                       command = "g++";
+               else
+                       throw invalid_argument("GnuLinker::Linker::Linker");
+               if(architecture->is_cross())
+                       command = format("%s-%s", architecture->get_cross_prefix(), command);
+               executable = builder.get_vfs().find_binary(command);
+       }
+}
+
 Task *GnuLinker::Linker::run(const Target &target) const
 {
        const Binary &bin = dynamic_cast<const Binary &>(target);
index 07e6a0ca0c322fb3ee6deb711b968cffbc019c2a..4673c070f2f725e007510201925b65b9ceea49c4 100644 (file)
@@ -15,12 +15,18 @@ class GnuLinker: public Tool
 private:
        class Linker: public SubTool
        {
+       private:
+               std::string compiler_tag;
+
        public:
                Linker(GnuLinker &, const std::string &);
 
-               virtual Target *create_target(const std::list<Target *> &, const std::string &) const;
+               virtual Target *create_target(const std::list<Target *> &, const std::string &);
                virtual Target *create_install(Target &) const;
                virtual std::string create_build_signature(const BuildInfo &) const;
+       private:
+               virtual void do_prepare();
+       public:
                virtual Task *run(const Target &) const;
        };
 
@@ -31,7 +37,7 @@ public:
        GnuLinker(Builder &, const Architecture &);
        ~GnuLinker();
 
-       virtual Target *create_target(const std::list<Target *> &, const std::string &) const;
+       virtual Target *create_target(const std::list<Target *> &, const std::string &);
        virtual Target *create_install(Target &) const;
        virtual Task *run(const Target &) const;
 };
index 5f62a02c954dadbcbc808b15b37d55938d90d812..f44f5754a1ef4f8d45ec639ff045716a9f7b830a 100644 (file)
@@ -18,14 +18,9 @@ using namespace Msp;
 
 MingwDllTool::MingwDllTool(Builder &b, const Architecture &a):
        Tool(b, a, "DLL")
-{
-       string command = "dlltool";
-       if(architecture->is_cross())
-               command = format("%s-%s", architecture->get_cross_prefix(), command);
-       executable = builder.get_vfs().find_binary(command);
-}
+{ }
 
-Target *MingwDllTool::create_target(const list<Target *> &sources, const string &) const
+Target *MingwDllTool::create_target(const list<Target *> &sources, const string &)
 {
        if(sources.size()!=1)
                throw invalid_argument("MingwDllTool::create_target");
@@ -50,7 +45,7 @@ Target *MingwDllTool::create_install(Target &target) const
 {
        if(ImportLibrary *imp = dynamic_cast<ImportLibrary *>(&target))
        {
-               const Tool &copy = builder.get_toolchain().get_tool("CP");
+               Tool &copy = builder.get_toolchain().get_tool("CP");
                InstalledFile *inst_tgt = dynamic_cast<InstalledFile *>(copy.create_target(target));
                string link_name = format("lib%s.dll.a", imp->get_shared_library()->get_libname());
                if(link_name!=FS::basename(inst_tgt->get_path()))
@@ -61,6 +56,14 @@ Target *MingwDllTool::create_install(Target &target) const
                return 0;
 }
 
+void MingwDllTool::do_prepare()
+{
+       string command = "dlltool";
+       if(architecture->is_cross())
+               command = format("%s-%s", architecture->get_cross_prefix(), command);
+       executable = builder.get_vfs().find_binary(command);
+}
+
 Task *MingwDllTool::run(const Target &target) const
 {
        const ImportLibrary *imp = dynamic_cast<const ImportLibrary *>(&target);
index 25a1e10377af8ec6d0291433ab263b1dcee31127..796da75024f6876cce0657522d0f1610bed5156e 100644 (file)
@@ -8,9 +8,13 @@ class MingwDllTool: public Tool
 public:
        MingwDllTool(Builder &, const Architecture &);
 
-       virtual Target *create_target(const std::list<Target *> &, const std::string &) const;
+       virtual Target *create_target(const std::list<Target *> &, const std::string &);
        virtual Target *create_install(Target &) const;
 
+private:
+       virtual void do_prepare();
+
+public:
        virtual Task *run(const Target &) const;
 };
 
index b4ba545249110d1340bf0bb99460bb07cea51458..677ef9bed27032cae00389f38a0e57b9db2559eb 100644 (file)
@@ -13,7 +13,7 @@ PkgConfigGenerator::PkgConfigGenerator(Builder &b):
 {
 }
 
-Target *PkgConfigGenerator::create_target(const list<Target *> &, const string &) const
+Target *PkgConfigGenerator::create_target(const list<Target *> &, const string &)
 {
        throw logic_error("Not implemented");
 }
index 14ba317df9c6a31e12f120c911c81ed53c3b9c36..a9adbc6fe2a86100a26d9c032375b47e48442a72 100644 (file)
@@ -26,7 +26,7 @@ private:
 public:
        PkgConfigGenerator(Builder &);
 
-       virtual Target *create_target(const std::list<Target *> &, const std::string &) const;
+       virtual Target *create_target(const std::list<Target *> &, const std::string &);
        virtual Task *run(const Target &) const;
 };
 
index ac2f9e800788513947335dc8a70d326a6830261e..bcaa85272c5a7e6c24c97249e65fa29162a6a426 100644 (file)
@@ -15,7 +15,7 @@ Tar::Tar(Builder &b):
        Tool(b, "TAR")
 { }
 
-Target *Tar::create_target(const list<Target *> &sources, const string &arg) const
+Target *Tar::create_target(const list<Target *> &sources, const string &arg)
 {
        if(!sources.front()->get_package())
                throw invalid_argument("Tar::create_target");
index c11587ecbf1ba17cfe35e5928dc47720c01c21fd..9be26d9debcac1303259c766575d06e2e9ad96bf 100644 (file)
@@ -26,7 +26,7 @@ private:
 public:
        Tar(Builder &);
 
-       virtual Target *create_target(const std::list<Target *> &, const std::string &) const;
+       virtual Target *create_target(const std::list<Target *> &, const std::string &);
        virtual Task *run(const Target &) const;
 };
 
index a9ad8e7063931006a3a6b3ba5de961a6d1f33fdf..87b0d0078e16bcb565898c55ba6923e807b328c1 100644 (file)
@@ -64,7 +64,7 @@ Target *Target::get_buildable_target()
        return 0;
 }
 
-void Target::set_tool(const Tool &t)
+void Target::set_tool(Tool &t)
 {
        tool = &t;
        for(Dependencies::const_iterator i=side_effects.begin(); i!=side_effects.end(); ++i)
@@ -102,12 +102,12 @@ void Target::prepare()
        }
 
        state = PREPARING;
+       if(tool)
+               tool->prepare();
        find_dependencies();
        if(tool)
-       {
                if(FileTarget *tool_exe = tool->get_executable())
                        add_dependency(*tool_exe);
-       }
 
        for(Dependencies::iterator i=depends.begin(); i!=depends.end(); ++i)
                (*i)->prepare();
index 0b9d2306fde33f6b35209c5d94dcf08d3af2101b..eda77d00dcd126b1c587768f04af4b8e7b162b2b 100644 (file)
@@ -42,7 +42,7 @@ protected:
        const Component *component;
        std::string name;
 
-       const Tool *tool;
+       Tool *tool;
        State state;
        std::string rebuild_reason;
 
@@ -95,7 +95,7 @@ public:
        the function recursively to find the final target. */
        virtual Target *get_real_target() { return this; }
 
-       void set_tool(const Tool &);
+       void set_tool(Tool &);
 
        /** Returns the tool used to build the target.  To actually build it, call
        the build() function. */
index cefbb8c3b0188c58d525b87def1a5b694f3a40df..a23de6322e8ad3fef1422531d8577944b18000de 100644 (file)
@@ -7,14 +7,16 @@ Tool::Tool(Builder &b, const string &t):
        builder(b),
        architecture(0),
        tag(t),
-       executable(0)
+       executable(0),
+       prepared(false)
 { }
 
 Tool::Tool(Builder &b, const Architecture &a, const string &t):
        builder(b),
        architecture(&a),
        tag(t),
-       executable(0)
+       executable(0),
+       prepared(false)
 { }
 
 bool Tool::accepts_suffix(const string &suffix, bool aux) const
@@ -27,13 +29,22 @@ bool Tool::accepts_suffix(const string &suffix, bool aux) const
                return false;
 }
 
-Target *Tool::create_target(Target &source, const string &arg) const
+Target *Tool::create_target(Target &source, const string &arg)
 {
        list<Target *> sources;
        sources.push_back(&source);
        return create_target(sources, arg);
 }
 
+void Tool::prepare()
+{
+       if(prepared)
+               return;
+
+       prepared = true;
+       do_prepare();
+}
+
 
 SubTool::SubTool(Tool &p):
        Tool(p),
index 294805359e43dc7f2096cfc9650ca7afb5bf1379..73be90d30a34a92f18235d9f9ece3d29f623318d 100644 (file)
@@ -31,6 +31,7 @@ protected:
        SuffixList input_suffixes;
        SuffixList aux_suffixes;
        SearchPath system_path;
+       bool prepared;
 
        Tool(Builder &, const std::string &);
        Tool(Builder &, const Architecture &, const std::string &);
@@ -41,7 +42,6 @@ public:
 
        /** Returns a target for the tool's own executable.  If the tool does not
        use an external program, returns null. */
-       // XXX The executable target should be retrieved when first needed
        FileTarget *get_executable() const { return executable; }
 
        /// Returns a list of suffixes that can be processed with this tool.
@@ -67,12 +67,12 @@ public:
        virtual Target *create_source(const Msp::FS::Path &) const { return 0; }
 
        /// Convenience function to create a target from a single source.
-       Target *create_target(Target &, const std::string & = std::string()) const;
+       Target *create_target(Target &, const std::string & = std::string());
 
        /** Creates a target from sources.  The exact types of accepted sources
        depends on the tool.  The optional second argument can be used to select an
        alternative target type for tools that can create multiple kinds of targets. */ 
-       virtual Target *create_target(const std::list<Target *> &, const std::string & = std::string()) const = 0;
+       virtual Target *create_target(const std::list<Target *> &, const std::string & = std::string()) = 0;
 
        /** Creates an install target for a target created by this tool.  Can return
        null if the tool does not want to handle installing in a special way. */
@@ -80,6 +80,12 @@ public:
 
        virtual std::string create_build_signature(const BuildInfo &) const { return std::string(); }
 
+       void prepare();
+
+protected:
+       virtual void do_prepare() { }
+
+public:
        /** Invokes the tool to build a target.  This should not be called directly;
        use Target::build() instead. */
        virtual Task *run(const Target &) const = 0;
index cdbc7aa0ae4e4e55ebfe76b28b8efc85df59b510..9d234038279d07d4ce41232c63e7ab5acec63f40 100644 (file)
@@ -16,12 +16,12 @@ void Toolchain::add_tool(Tool *tool)
        insert_unique(tools, tool->get_tag(), tool);
 }
 
-const Tool &Toolchain::get_tool(const string &tag) const
+Tool &Toolchain::get_tool(const string &tag) const
 {
        return *get_item(tools, tag);
 }
 
-const Tool *Toolchain::get_tool_for_suffix(const string &suffix, bool aux) const
+Tool *Toolchain::get_tool_for_suffix(const string &suffix, bool aux) const
 {
        for(ToolMap::const_iterator i=tools.begin(); i!=tools.end(); ++i)
                if(i->second->accepts_suffix(suffix, aux))
index 2c0e3d2a84977933113c0447b00a5a5daae50c60..572e42f58dcdc9e718a036c11dee5f433d61c8d6 100644 (file)
@@ -20,8 +20,8 @@ public:
        ~Toolchain();
 
        void add_tool(Tool *);
-       const Tool &get_tool(const std::string &) const;
-       const Tool *get_tool_for_suffix(const std::string &, bool = false) const;
+       Tool &get_tool(const std::string &) const;
+       Tool *get_tool_for_suffix(const std::string &, bool = false) const;
 };
 
 #endif