From c0c85b67516653c181fbce7c61c2df3e31e4edd8 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 18 Dec 2014 07:14:53 +0200 Subject: Initial support for loading dependency info from buildfiles Also a new iteration on the overall architecture. Now, for the first time, build can read the buildfile and build itself. g++-4.9 -std=c++14 -g -I.. -o bd bd.cxx algorithm.cxx scope.cxx parser.cxx lexer.cxx target.cxx prerequisite.cxx rule.cxx native.cxx cxx/target.cxx cxx/rule.cxx process.cxx timestamp.cxx path.cxx g++-4.9 -std=c++14 -g -I../../.. -o driver driver.cxx ../../../build/lexer.cxx g++-4.9 -std=c++14 -g -I../../.. -o driver driver.cxx ../../../build/lexer.cxx ../../../build/parser.cxx ../../../build/scope.cxx ../../../build/target.cxx ../../../build/native.cxx ../../../build/prerequisite.cxx ../../../build/path.cxx ../../../build/timestamp.cxx --- build/target | 93 +++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 64 insertions(+), 29 deletions(-) (limited to 'build/target') 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 +#include #include #include +#include // unique_ptr #include // function, reference_wrapper #include #include @@ -15,6 +18,8 @@ #include #include +#include +#include // 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 recipe; - typedef std::vector> 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> + 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, 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, + compare_c_string> + { + public: + void + insert (const target_type& tt) {emplace (tt.name, tt);} + }; + + extern target_type_map target_types; + + template + 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; }; } -- cgit v1.1