From: Mikko Rasa Date: Wed, 18 Jul 2012 20:27:44 +0000 (+0300) Subject: Track build options to rebuild primary targets when build type changes X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=03227882aef8b448065e6ca9cda9b7722b7a9753;p=builder.git Track build options to rebuild primary targets when build type changes --- diff --git a/source/binary.cpp b/source/binary.cpp index 6fd6161..d56ab17 100644 --- a/source/binary.cpp +++ b/source/binary.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "binary.h" #include "builder.h" #include "component.h" @@ -7,6 +8,7 @@ #include "sharedlibrary.h" #include "sourcepackage.h" #include "staticlibrary.h" +#include "tool.h" using namespace std; using namespace Msp; @@ -16,10 +18,11 @@ Binary::Binary(Builder &b, const FS::Path &p): { } Binary::Binary(Builder &b, const Component &c, const string &p, const list &objs): - FileTarget(b, c.get_package(), c.get_package().get_out_dir()/p) + FileTarget(b, c.get_package(), c.get_package().get_out_dir()/p), + objects(objs) { component = &c; - for(list::const_iterator i=objs.begin(); i!=objs.end(); ++i) + for(list::const_iterator i=objects.begin(); i!=objects.end(); ++i) add_dependency(**i); } @@ -67,3 +70,18 @@ void Binary::find_dependencies() add_dependency(**i); } } + +string Binary::create_build_signature() const +{ + set object_tools; + for(list::const_iterator i=objects.begin(); i!=objects.end(); ++i) + object_tools.insert((*i)->get_tool()); + + list sigs; + sigs.push_back(tool->create_build_signature(component->get_build_info())); + for(set::const_iterator i=object_tools.begin(); i!=object_tools.end(); ++i) + sigs.push_back((*i)->create_build_signature(component->get_build_info())); + sigs.sort(); + + return join(sigs.begin(), sigs.end(), ";"); +} diff --git a/source/binary.h b/source/binary.h index 8e6761f..b689a1d 100644 --- a/source/binary.h +++ b/source/binary.h @@ -13,11 +13,14 @@ library. class Binary: public FileTarget { protected: + std::list objects; + Binary(Builder &, const Msp::FS::Path &); Binary(Builder &, const Component &, const std::string &, const std::list &); -public: virtual void find_dependencies(); + + virtual std::string create_build_signature() const; }; #endif diff --git a/source/filetarget.cpp b/source/filetarget.cpp index 7de9b79..1f25cd1 100644 --- a/source/filetarget.cpp +++ b/source/filetarget.cpp @@ -1,10 +1,12 @@ #include #include #include +#include #include #include "builder.h" #include "filetarget.h" #include "sourcepackage.h" +#include "tool.h" using namespace std; using namespace Msp; @@ -84,8 +86,27 @@ void FileTarget::check_rebuild() } } - if(!needs_rebuild() && package && package->get_config().get_mtime()>mtime) - mark_rebuild("Package options changed"); + if(!needs_rebuild() && package) + { + if(package->get_config().get_mtime()>mtime) + mark_rebuild("Package options changed"); + + string build_sig = create_build_signature(); + if(package->get_cache().has_key(this, "build_sig")) + { + if(package->get_cache().get_value(this, "build_sig")!=build_sig) + mark_rebuild("Build signature changed"); + } + } +} + +string FileTarget::create_build_signature() const +{ + if(!package) + return string(); + + const BuildInfo &binfo = (component ? component->get_build_info() : package->get_build_info()); + return tool->create_build_signature(binfo); } Task *FileTarget::build() @@ -99,7 +120,15 @@ Task *FileTarget::build() void FileTarget::build_finished(bool success) { if(success) + { stat(); + if(package) + { + string build_sig = create_build_signature(); + if(!build_sig.empty()) + package->get_cache().set_value(this, "build_sig", build_sig); + } + } Target::build_finished(success); } diff --git a/source/filetarget.h b/source/filetarget.h index 30cd3df..6c12a5d 100644 --- a/source/filetarget.h +++ b/source/filetarget.h @@ -39,6 +39,8 @@ public: protected: virtual void check_rebuild(); + virtual std::string create_build_signature() const; + public: virtual Task *build(); diff --git a/source/gnucompiler.cpp b/source/gnucompiler.cpp index e2c5c0e..0bd1b33 100644 --- a/source/gnucompiler.cpp +++ b/source/gnucompiler.cpp @@ -37,6 +37,20 @@ Target *GnuCompiler::create_target(const list &sources, const string & return obj; } +string GnuCompiler::create_build_signature(const BuildInfo &binfo) const +{ + string result = FS::basename(executable->get_path()); + result += ','; + if(binfo.debug) + result += 'g'; + if(binfo.optimize) + { + result += 'O'; + result += (binfo.optimize>0 ? '0'+binfo.optimize : 's'); + } + return result; +} + Task *GnuCompiler::run(const Target &target) const { const ObjectFile &object = dynamic_cast(target); diff --git a/source/gnucompiler.h b/source/gnucompiler.h index d953e47..5992876 100644 --- a/source/gnucompiler.h +++ b/source/gnucompiler.h @@ -17,6 +17,7 @@ protected: public: virtual Target *create_target(const std::list &, const std::string &) const; + virtual std::string create_build_signature(const BuildInfo &) const; virtual Task *run(const Target &) const; }; diff --git a/source/gnulinker.cpp b/source/gnulinker.cpp index f7982f7..6ea8871 100644 --- a/source/gnulinker.cpp +++ b/source/gnulinker.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "builder.h" #include "component.h" #include "executable.h" @@ -105,6 +106,21 @@ Target *GnuLinker::Linker::create_target(const list &sources, const st return parent.create_target(sources, arg); } +string GnuLinker::Linker::create_build_signature(const BuildInfo &binfo) const +{ + string result = FS::basename(executable->get_path()); + result += ','; + if(binfo.libmode<=BuildInfo::STATIC) + result += 't'; + else + result += 'd'; + if(binfo.strip) + result += 's'; + result += ",l"; + result += join(binfo.libs.begin(), binfo.libs.end(), ",l"); + return result; +} + Task *GnuLinker::Linker::run(const Target &target) const { const Binary &bin = dynamic_cast(target); diff --git a/source/gnulinker.h b/source/gnulinker.h index 6bd11ca..8c380c8 100644 --- a/source/gnulinker.h +++ b/source/gnulinker.h @@ -19,6 +19,7 @@ private: Linker(GnuLinker &, const std::string &); virtual Target *create_target(const std::list &, const std::string &) const; + virtual std::string create_build_signature(const BuildInfo &) const; virtual Task *run(const Target &) const; }; diff --git a/source/tool.h b/source/tool.h index 3c3757f..6aee38b 100644 --- a/source/tool.h +++ b/source/tool.h @@ -7,6 +7,7 @@ class Architecture; class Builder; +class BuildInfo; class Component; class FileTarget; class Target; @@ -73,6 +74,8 @@ public: alternative target type for tools that can create multiple kinds of targets. */ virtual Target *create_target(const std::list &, const std::string & = std::string()) const = 0; + virtual std::string create_build_signature(const BuildInfo &) const { return std::string(); } + /** Invokes the tool to build a target. This should not be called directly; use Target::build() instead. */ virtual Task *run(const Target &) const = 0;