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)
else if(type==INSTALL)
{
Target *inst = build_graph.get_target("install");
- const Tool © = toolchain.get_tool("CP");
+ Tool © = toolchain.get_tool("CP");
for(SourceList::const_iterator i=source_filenames.begin(); i!=source_filenames.end(); ++i)
{
FileTarget *ft;
}
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)
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);
}
}
- 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));
}
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);
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;
};
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");
}
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")
{
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();
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;
};
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");
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);
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;
};
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");
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);
*/
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;
};
input_suffixes.push_back(".cpp");
input_suffixes.push_back(".cc");
aux_suffixes.push_back(".hpp");
-
- if(executable)
- query_version();
}
void GnuCxxCompiler::query_version()
{
return new CSourceFile(builder, path);
}
+
+void GnuCxxCompiler::do_prepare()
+{
+ GnuCompiler::do_prepare();
+ if(executable)
+ query_version();
+}
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
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");
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;
{
if(SharedLibrary *shlib = dynamic_cast<SharedLibrary *>(&target))
{
- const Tool © = builder.get_toolchain().get_tool("CP");
+ Tool © = 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());
}
-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);
}
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);
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;
};
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;
};
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");
{
if(ImportLibrary *imp = dynamic_cast<ImportLibrary *>(&target))
{
- const Tool © = builder.get_toolchain().get_tool("CP");
+ Tool © = 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()))
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);
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;
};
{
}
-Target *PkgConfigGenerator::create_target(const list<Target *> &, const string &) const
+Target *PkgConfigGenerator::create_target(const list<Target *> &, const string &)
{
throw logic_error("Not implemented");
}
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;
};
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");
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;
};
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)
}
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();
const Component *component;
std::string name;
- const Tool *tool;
+ Tool *tool;
State state;
std::string rebuild_reason;
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. */
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
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),
SuffixList input_suffixes;
SuffixList aux_suffixes;
SearchPath system_path;
+ bool prepared;
Tool(Builder &, const std::string &);
Tool(Builder &, const Architecture &, const std::string &);
/** 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.
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. */
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;
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))
~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