This is necessary for some future developments.
DataTool::DataTool(Builder &b):
Tool(b, "DATA")
{
+ set_command("mspdatatool");
input_suffixes.push_back(".mdt");
}
throw invalid_argument("DataTool::create_target");
}
-void DataTool::do_prepare()
-{
- set_executable("mspdatatool");
-}
-
Task *DataTool::run(const Target &tgt) const
{
const Component &comp = *tgt.get_component();
virtual Target *create_source(const Component &, const Msp::FS::Path &) 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")
{
+ set_command("ar", true);
input_suffixes.push_back(".o");
}
return lib;
}
-void GnuArchiver::do_prepare()
-{
- set_executable("ar", true);
-}
-
Task *GnuArchiver::run(const Target &target) const
{
const StaticLibrary &lib = dynamic_cast<const StaticLibrary &>(target);
GnuArchiver(Builder &, const Architecture &);
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;
GnuCCompiler::GnuCCompiler(Builder &b, const Architecture &a):
- GnuCompiler(b, a, "CC", "gcc")
+ GnuCompiler(b, a, "CC")
{
+ set_command("gcc", true);
input_suffixes.push_back(".c");
aux_suffixes.push_back(".h");
}
using namespace std;
using namespace Msp;
-GnuCompiler::GnuCompiler(Builder &b, const Architecture &a, const string &t, const string &c):
- Tool(b, a, t),
- command(c)
+GnuCompiler::GnuCompiler(Builder &b, const Architecture &a, const string &t):
+ Tool(b, a, t)
{
if(architecture->is_native())
system_path.push_back("/usr/include");
return result;
}
-void GnuCompiler::do_prepare()
-{
- set_executable(command, true);
-}
-
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 &);
+ GnuCompiler(Builder &, const Architecture &, const std::string &);
public:
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;
};
using namespace Msp;
GnuCxxCompiler::GnuCxxCompiler(Builder &b, const Architecture &a):
- GnuCompiler(b, a, "CXX", "g++")
+ GnuCompiler(b, a, "CXX")
{
+ set_command("g++", true);
input_suffixes.push_back(".cpp");
input_suffixes.push_back(".cc");
aux_suffixes.push_back(".hpp");
GnuLinker::Linker::Linker(GnuLinker &p, const string &ct):
SubTool(p),
compiler_tag(ct)
-{ }
+{
+ if(compiler_tag=="CC")
+ set_command("gcc", true);
+ else if(compiler_tag=="CXX")
+ set_command("g++", true);
+ else
+ throw invalid_argument("GnuLinker::Linker::Linker");
+}
Target *GnuLinker::Linker::create_target(const list<Target *> &sources, const string &arg)
{
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");
-
- set_executable(command, true);
- }
}
Task *GnuLinker::Linker::run(const Target &target) const
MingwDllTool::MingwDllTool(Builder &b, const Architecture &a):
Tool(b, a, "DLL")
-{ }
+{
+ set_command("dlltool", true);
+}
Target *MingwDllTool::create_target(const list<Target *> &sources, const string &)
{
return 0;
}
-void MingwDllTool::do_prepare()
-{
- set_executable("dlltool", true);
-}
-
Task *MingwDllTool::run(const Target &target) const
{
const ImportLibrary *imp = dynamic_cast<const ImportLibrary *>(&target);
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;
};
prepared(false)
{ }
+void Tool::set_command(const string &cmd, bool cross)
+{
+ if(cmd.empty())
+ throw invalid_argument("Tool::set_command");
+
+ if(cross && architecture->is_cross())
+ command = format("%s-%s", architecture->get_cross_prefix(), cmd);
+ else
+ command = cmd;
+}
+
bool Tool::accepts_suffix(const string &suffix, bool aux) const
{
if(find(input_suffixes.begin(), input_suffixes.end(), suffix)!=input_suffixes.end())
prepared = true;
do_prepare();
-}
-
-void Tool::set_executable(const string &command, bool cross)
-{
- if(cross && architecture->is_cross())
- return set_executable(format("%s-%s", architecture->get_cross_prefix(), command), false);
-
- executable = builder.get_vfs().find_binary(command);
- if(!executable)
- problems.push_back(format("Can't find executable %s", command));
+ if(!executable && !command.empty())
+ {
+ executable = builder.get_vfs().find_binary(command);
+ if(!executable)
+ problems.push_back(format("Can't find executable %s", command));
+ }
}
Builder &builder;
const Architecture *architecture;
std::string tag;
+ std::string command;
FileTarget *executable;
SuffixList input_suffixes;
SuffixList aux_suffixes;
tool is architecture-agnostic. */
const Architecture *get_architecture() const { return architecture; }
+ /** Overrides the command used by the tool. The new command should accept
+ the same command line arguments. Only works on tools that use an external
+ command. If cross is true and the architecture is not native, a cross
+ prefix is added to the command. May have no effect after prepare() has been
+ called. */
+ void set_command(const std::string &cmd, bool cross = false);
+
/** Returns a target for the tool's own executable. If the tool does not
- use an external program, returns null. */
+ use an external program, returns null. The tool must be prepared first. */
FileTarget *get_executable() const { return executable; }
/// Returns a list of suffixes that can be processed with this tool.
protected:
virtual void do_prepare() { }
- /** Locates an executable for the tool from the VFS. If it isn't found, a
- problem is reported. If cross is true and the architecture is not native,
- a cross prefix is added to the command. */
- void set_executable(const std::string &command, bool cross = false);
-
public:
const std::list<std::string> &get_problems() const { return problems; }