aboutsummaryrefslogtreecommitdiff
path: root/build/target
diff options
context:
space:
mode:
Diffstat (limited to 'build/target')
-rw-r--r--build/target93
1 files changed, 64 insertions, 29 deletions
diff --git a/build/target b/build/target
index 01cddc4..a381fd0 100644
--- a/build/target
+++ b/build/target
@@ -5,8 +5,11 @@
#ifndef BUILD_TARGET
#define BUILD_TARGET
+#include <set>
+#include <map>
#include <string>
#include <vector>
+#include <memory> // unique_ptr
#include <functional> // function, reference_wrapper
#include <typeindex>
#include <iosfwd>
@@ -15,6 +18,8 @@
#include <build/path>
#include <build/timestamp>
+#include <build/prerequisite>
+#include <build/utility> // compare_c_string, compare_pointer_target
namespace build
{
@@ -23,24 +28,29 @@ namespace build
enum class target_state {unknown, uptodate, updated, failed};
typedef std::function<target_state (target&)> recipe;
- typedef std::vector<std::reference_wrapper<target>> targets;
+ struct target_type
+ {
+ std::type_index id;
+ const char* name;
+ const target_type* base;
+ target* (*const factory) (std::string, path);
+ };
class target
{
public:
- target (std::string n): name_ (std::move (n)) {}
-
- const std::string&
- name () const {return name_;}
+ target (std::string n, path d)
+ : name (std::move (n)), directory (std::move (d)) {}
- const targets&
- prerequisites () const {return prerequisites_;}
+ const std::string name;
+ const path directory; // Absolute and normalized.
- targets&
- prerequisites () {return prerequisites_;}
+ public:
+ typedef
+ std::vector<std::reference_wrapper<prerequisite>>
+ prerequisites_type;
- void
- prerequisite (target& t) {prerequisites_.push_back (t);}
+ prerequisites_type prerequisites;
public:
typedef build::recipe recipe_type;
@@ -63,22 +73,10 @@ namespace build
target& operator= (const target&) = delete;
public:
- struct type_info
- {
- std::type_index id;
- const char* name;
- const type_info* base;
- };
-
- virtual const type_info&
- type_id () const = 0;
-
- protected:
- static const type_info ti_;
+ virtual const target_type& type () const = 0;
+ static const target_type static_type;
private:
- std::string name_;
- targets prerequisites_;
recipe_type recipe_;
target_state state_ {target_state::unknown};
};
@@ -86,6 +84,40 @@ namespace build
std::ostream&
operator<< (std::ostream&, const target&);
+ inline bool
+ operator< (const target& x, const target& y)
+ {
+ std::type_index tx (typeid (x)), ty (typeid (y));
+
+ return
+ (tx < ty) ||
+ (tx == ty && x.name < y.name) ||
+ (tx == ty && x.name == y.name && x.directory < y.directory);
+ }
+
+ typedef std::set<std::unique_ptr<target>, compare_pointer_target> target_set;
+ extern target_set targets;
+ extern target* default_target;
+
+ class target_type_map: public std::map<
+ const char*,
+ std::reference_wrapper<const target_type>,
+ compare_c_string>
+ {
+ public:
+ void
+ insert (const target_type& tt) {emplace (tt.name, tt);}
+ };
+
+ extern target_type_map target_types;
+
+ template <typename T>
+ target*
+ target_factory (std::string n, path d)
+ {
+ return new T (std::move (n), std::move (d));
+ }
+
// Modification time-based target.
//
class mtime_target: public target
@@ -109,7 +141,8 @@ namespace build
virtual timestamp
load_mtime () const = 0;
- protected: static const type_info ti_;
+ public:
+ static const target_type static_type;
private:
mutable timestamp mtime_ {timestamp_unknown};
@@ -134,7 +167,8 @@ namespace build
virtual timestamp
load_mtime () const;
- protected: static const type_info ti_;
+ public:
+ static const target_type static_type;
private:
path_type path_;
@@ -147,8 +181,9 @@ namespace build
public:
using path_target::path_target;
- public: virtual const type_info& type_id () const {return ti_;}
- protected: static const type_info ti_;
+ public:
+ virtual const target_type& type () const {return static_type;}
+ static const target_type static_type;
};
}