diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2014-12-10 10:20:26 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2014-12-10 10:20:26 +0200 |
commit | 5e9eb843f6ccadfb47fa603260783425da9e7805 (patch) | |
tree | 3778f76de37f5258a07a8fae0e58a843b8a49f1d /build/target | |
parent | 20e3aedeb7df742c38276fb41cae8f3eb027b6dd (diff) |
Add rules
g++-4.9 -std=c++11 -g -I.. -o bd bd.cxx target.cxx native.cxx rule.cxx cxx/rule.cxx cxx/target.cxx process.cxx timestamp.cxx path.cxx
Diffstat (limited to 'build/target')
-rw-r--r-- | build/target | 110 |
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_; }; } |