]> git.tdb.fi Git - builder.git/blobdiff - source/tool.h
Redesign how tools are run
[builder.git] / source / tool.h
index fa18ba8dca338d57c5e37c2c8fe42269f61ef1b1..ec5bf02b37d9fbf29b94eac121c82f0131f7fca8 100644 (file)
@@ -1,10 +1,12 @@
 #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;
@@ -13,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.
@@ -31,29 +32,44 @@ public:
 
 protected:
        Builder &builder;
-       const Architecture *architecture;
+       const Architecture *architecture = 0;
        std::string tag;
        std::string command;
-       FileTarget *executable;
-       std::list<std::string> input_suffixes;
-       std::list<std::string> aux_suffixes;
-       ProcessingUnit processing_unit;
+       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;
-       bool prepared;
-       std::list<std::string> problems;
-
-       Tool(Builder &, const std::string &);
-       Tool(Builder &, const Architecture &, const std::string &);
+       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 build for.  May return null if the
+       /** 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
@@ -66,11 +82,11 @@ public:
        FileTarget *get_executable() const { return executable; }
 
        /// Returns a list of suffixes that can be processed with this tool.
-       const std::list<std::string> &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 std::list<std::string> &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 */
@@ -100,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();
 
@@ -114,11 +130,11 @@ protected:
        virtual void do_prepare() { }
 
 public:
-       const std::list<std::string> &get_problems() const { return problems; }
+       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); }
 };
 
 /**
@@ -131,17 +147,33 @@ class SubTool: public Tool
 protected:
        Tool &parent;
 
-       SubTool(Tool &);
+       SubTool(Tool &t): Tool(t), parent(t) { }
 
 public:
        Target *create_source(const Component &, const Msp::FS::Path &) const override;
        Target *create_source(const Msp::FS::Path &) const override;
-       Target *create_target(const std::list<Target *> &, const std::string & = std::string()) override;
+       Target *create_target(const std::vector<Target *> &, const std::string & = std::string()) override;
        Target *create_install(Target &) const override;
        std::string create_build_signature(const BuildInfo &) const override;
 };
 
 
+template<typename T>
+void Tool::set_run(Task *(*f)(const T &))
+{
+       set_run([f](const Target &t){ return f(dynamic_cast<const T &>(t)); });
+}
+
+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