]> git.tdb.fi Git - builder.git/blobdiff - source/tool.h
Remove the now obsolete SubTool class
[builder.git] / source / tool.h
index 73be90d30a34a92f18235d9f9ece3d29f623318d..ca19c6f17b522cda1565371c60cbc0e97304f3df 100644 (file)
@@ -1,9 +1,13 @@
 #ifndef TOOL_H_
 #define TOOL_H_
 
-#include <list>
+#include <functional>
 #include <string>
+#include <vector>
 #include <msp/fs/path.h>
+#include "buildinfo.h"
+#include "internaltask.h"
+#include "virtualfilesystem.h"
 
 class Architecture;
 class Builder;
@@ -11,7 +15,6 @@ class BuildInfo;
 class Component;
 class FileTarget;
 class Target;
-class Task;
 
 /**
 Base class for tools.  Tools are used to turn targets into other targets.
@@ -20,43 +23,84 @@ Examples include compilers and linkers.
 class Tool
 {
 public:
-       typedef std::list<Msp::FS::Path> SearchPath;
-       typedef std::list<std::string> SuffixList;
+       enum ProcessingUnit
+       {
+               ONE_FILE,
+               DIRECTORY,
+               COMPONENT
+       };
 
 protected:
        Builder &builder;
-       const Architecture *architecture;
+       const Architecture *architecture = 0;
        std::string tag;
-       FileTarget *executable;
-       SuffixList input_suffixes;
-       SuffixList aux_suffixes;
-       SearchPath system_path;
-       bool prepared;
-
-       Tool(Builder &, const std::string &);
-       Tool(Builder &, const Architecture &, const std::string &);
+       std::string command;
+       FileTarget *executable = 0;
+       std::vector<std::string> input_suffixes;
+       std::vector<std::string> aux_suffixes;
+       ProcessingUnit processing_unit = ONE_FILE;
+       VirtualFileSystem::SearchPath system_path;
+       BuildInfo build_info;
+       std::function<Task *(const Target &)> run_func;
+       bool prepared = false;
+       std::vector<std::string> problems;
+
+       Tool(Builder &b, const std::string &t): Tool(b, 0, t) { }
+       Tool(Builder &b, const Architecture &a, const std::string &t): Tool(b, &a, t) { }
+private:
+       Tool(Builder &b, const Architecture *a, const std::string &t): builder(b), architecture(a), tag(t) { }
 public:
        virtual ~Tool() { }
 
+       Builder &get_builder() const { return builder; }
+
        const std::string &get_tag() const { return tag; }
 
+       /** Returns the architecture this tool builds for.  May return null if the
+       tool is architecture-agnostic. */
+       const Architecture *get_architecture() const { return architecture; }
+
+protected:
+       void set_run(std::function<Task *(const Target &)>);
+
+       template<typename T>
+       void set_run(Task *(*)(const T &));
+
+       template<typename T>
+       void set_run_internal(bool (*)(const T &));
+
+public:
+       /** 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.
-       const SuffixList &get_input_suffixes() const { return input_suffixes; }
+       const std::vector<std::string> &get_input_suffixes() const { return input_suffixes; }
 
        /** Returns a list of suffixes that are associated with this tool, but can't
        be processed directly.  For example C and C++ headers. */
-       const SuffixList &get_auxiliary_suffixes() const { return aux_suffixes; }
+       const std::vector<std::string> &get_auxiliary_suffixes() const { return aux_suffixes; }
 
        /** Indicates whether the tool can accept a suffix.  If aux is true,
        auxiliary suffixes are considered as well */
        bool accepts_suffix(const std::string &, bool aux = false) const;
 
+       /** Returns the grouping unit this tool prefers to process. */
+       ProcessingUnit get_processing_unit() const { return processing_unit; }
+
        /// Returns the systemwide search path for source files.
-       const SearchPath &get_system_path() const { return system_path; }
+       const VirtualFileSystem::SearchPath &get_system_path() const { return system_path; }
+
+       /** Returns tool-specific build info.  This can be used by other tools down
+       the chain. */
+       const BuildInfo &get_build_info() const { return build_info; }
 
        /// Creates a source file appropriate for this tool.
        virtual Target *create_source(const Component &, const Msp::FS::Path &) const { return 0; }
@@ -72,13 +116,13 @@ public:
        /** 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()) = 0;
+       virtual Target *create_target(const std::vector<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 Target *create_install(Target &) const { return 0; }
 
-       virtual std::string create_build_signature(const BuildInfo &) const { return std::string(); }
+       virtual std::string create_build_signature(const BuildInfo &) const;
 
        void prepare();
 
@@ -86,22 +130,30 @@ protected:
        virtual void do_prepare() { }
 
 public:
+       const std::vector<std::string> &get_problems() const { return problems; }
+
        /** Invokes the tool to build a target.  This should not be called directly;
        use Target::build() instead. */
-       virtual Task *run(const Target &) const = 0;
+       Task *run(const Target &t) const { return run_func(t); }
 };
 
-/**
-Intermediate base class for tool facets.  For example, a linker may need to
-use different commands depending on whether C++ source files are present or
-not, but their presence can't be directly determined from the object files.
-*/
-class SubTool: public Tool
+
+template<typename T>
+void Tool::set_run(Task *(*f)(const T &))
 {
-protected:
-       Tool &parent;
+       set_run([f](const Target &t){ return f(dynamic_cast<const T &>(t)); });
+}
 
-       SubTool(Tool &);
-};
+template<typename T>
+void Tool::set_run_internal(bool (*f)(const T &))
+{
+       set_run([f](const Target &t){
+               const T &ct = dynamic_cast<const T &>(t);
+               return new InternalTask([f, &ct]{ return f(ct); });
+       });
+}
+
+
+void operator>>(const Msp::LexicalConverter &, Tool::ProcessingUnit &);
 
 #endif