aboutsummaryrefslogtreecommitdiff
path: root/build/target
diff options
context:
space:
mode:
Diffstat (limited to 'build/target')
-rw-r--r--build/target110
1 files changed, 95 insertions, 15 deletions
diff --git a/build/target b/build/target
index 4319ccb..3ef3192 100644
--- a/build/target
+++ b/build/target
@@ -7,11 +7,21 @@
#include <string>
#include <vector>
-#include <functional> // std::reference_wrapper
+#include <functional> // function, reference_wrapper
+#include <typeindex>
+#include <iosfwd>
+#include <cassert>
+
+#include <build/path>
+#include <build/timestamp>
namespace build
{
class target;
+
+ enum class target_state {unknown, uptodate, updated, failed};
+ typedef std::function<target_state (target&)> recipe;
+
typedef std::vector<std::reference_wrapper<target>> targets;
class target
@@ -32,42 +42,112 @@ namespace build
prerequisite (target& t) {prerequisites_.push_back (t);}
public:
- typedef bool (*rule_type) (target&);
+ typedef build::recipe recipe_type;
- rule_type
- rule () const {return rule_;}
+ const recipe_type&
+ recipe () const {return recipe_;}
void
- rule (rule_type r) {rule_ = r;}
+ recipe (recipe_type r) {assert (!recipe_); recipe_ = r;}
+
+ public:
+ target_state
+ state () const {return state_;}
+
+ void
+ state (target_state s) {state_ = s;}
private:
target (const target&) = delete;
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_;
+
private:
std::string name_;
targets prerequisites_;
- rule_type rule_ {0};
+ recipe_type recipe_;
+ target_state state_ {target_state::unknown};
};
- class exe: public target
- {
- using target::target;
- };
+ std::ostream&
+ operator<< (std::ostream&, const target&);
- class obj: public target
+ // Modification time-based target.
+ //
+ class mtime_target: public target
{
+ public:
using target::target;
+
+ timestamp
+ mtime () const
+ {
+ if (mtime_ == timestamp_unknown)
+ mtime_ = load_mtime ();
+
+ return mtime_;
+ }
+
+ void
+ mtime (timestamp mt) {mtime_ = mt;}
+
+ protected:
+ virtual timestamp
+ load_mtime () const = 0;
+
+ protected: static const type_info ti_;
+
+ private:
+ mutable timestamp mtime_ {timestamp_unknown};
};
- class hxx: public target
+ // Filesystem path-bases target.
+ //
+ class path_target: public mtime_target
{
- using target::target;
+ public:
+ using mtime_target::mtime_target;
+
+ typedef build::path path_type;
+
+ const path_type&
+ path () const {return path_;}
+
+ void
+ path (path_type p) {assert (path_.empty ()); path_ = p;}
+
+ protected:
+ virtual timestamp
+ load_mtime () const;
+
+ protected: static const type_info ti_;
+
+ private:
+ path_type path_;
};
- class cxx: public target
+ // File target.
+ //
+ class file: public path_target
{
- using target::target;
+ public:
+ using path_target::path_target;
+
+ public: virtual const type_info& type_id () const {return ti_;}
+ protected: static const type_info ti_;
};
}