]> git.tdb.fi Git - builder.git/commitdiff
Track build options to rebuild primary targets when build type changes
authorMikko Rasa <tdb@tdb.fi>
Wed, 18 Jul 2012 20:27:44 +0000 (23:27 +0300)
committerMikko Rasa <tdb@tdb.fi>
Wed, 18 Jul 2012 20:27:44 +0000 (23:27 +0300)
source/binary.cpp
source/binary.h
source/filetarget.cpp
source/filetarget.h
source/gnucompiler.cpp
source/gnucompiler.h
source/gnulinker.cpp
source/gnulinker.h
source/tool.h

index 6fd6161989f24450ca4352b60126f474d545f366..d56ab17b0b59020ae30dc2825654d6c186b485b9 100644 (file)
@@ -1,5 +1,6 @@
 #include <msp/fs/utils.h>
 #include <msp/strings/format.h>
+#include <msp/strings/utils.h>
 #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<ObjectFile *> &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<ObjectFile *>::const_iterator i=objs.begin(); i!=objs.end(); ++i)
+       for(list<ObjectFile *>::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<const Tool *> object_tools;
+       for(list<ObjectFile *>::const_iterator i=objects.begin(); i!=objects.end(); ++i)
+               object_tools.insert((*i)->get_tool());
+
+       list<string> sigs;
+       sigs.push_back(tool->create_build_signature(component->get_build_info()));
+       for(set<const Tool *>::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(), ";");
+}
index 8e6761f6c434ea7fa4dbfd8fafb47658071859eb..b689a1d4fab8368f2ccd45a23dd7e57129a1a889 100644 (file)
@@ -13,11 +13,14 @@ library.
 class Binary: public FileTarget
 {
 protected:
+       std::list<ObjectFile *> objects;
+
        Binary(Builder &, const Msp::FS::Path &);
        Binary(Builder &, const Component &, const std::string &, const std::list<ObjectFile *> &);
 
-public:
        virtual void find_dependencies();
+
+       virtual std::string create_build_signature() const;
 };
 
 #endif
index 7de9b797761717ce968649931e29ea6a32b8920c..1f25cd1a9818a283c9e74ba4705d3df2dafd9faa 100644 (file)
@@ -1,10 +1,12 @@
 #include <msp/fs/stat.h>
 #include <msp/fs/utils.h>
 #include <msp/strings/format.h>
+#include <msp/strings/utils.h>
 #include <msp/time/utils.h>
 #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);
 }
index 30cd3df3ec3fae9486761e8cf403c8df582dc9ce..6c12a5df22e38fb54e7ff7433f6f26c6c4cc668c 100644 (file)
@@ -39,6 +39,8 @@ public:
 protected:
        virtual void check_rebuild();
 
+       virtual std::string create_build_signature() const;
+
 public:
        virtual Task *build();
 
index e2c5c0e71a494e7bb11079a5be0f76725f135b93..0bd1b33274028384fbfb6fd5127ead017493f67f 100644 (file)
@@ -37,6 +37,20 @@ Target *GnuCompiler::create_target(const list<Target *> &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<const ObjectFile &>(target);
index d953e47f3c847a64cc794906dfaa186f7ead52d9..59928766fb1a8d93fd548251e1f23e72b70a895b 100644 (file)
@@ -17,6 +17,7 @@ protected:
 
 public:
        virtual Target *create_target(const std::list<Target *> &, const std::string &) const;
+       virtual std::string create_build_signature(const BuildInfo &) const;
        virtual Task *run(const Target &) const;
 };
 
index f7982f7a626c9ac927c2e20b7db42794a72416ff..6ea88718fa4d8c3af4f3c2d91863eabefbe74531 100644 (file)
@@ -3,6 +3,7 @@
 #include <msp/fs/dir.h>
 #include <msp/fs/utils.h>
 #include <msp/strings/format.h>
+#include <msp/strings/utils.h>
 #include "builder.h"
 #include "component.h"
 #include "executable.h"
@@ -105,6 +106,21 @@ Target *GnuLinker::Linker::create_target(const list<Target *> &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<const Binary &>(target);
index 6bd11ca441afda7f4be2e275d4ce80862894de2e..8c380c85ae9beb95c02c1c68645a1b580458c85d 100644 (file)
@@ -19,6 +19,7 @@ private:
                Linker(GnuLinker &, const std::string &);
 
                virtual Target *create_target(const std::list<Target *> &, const std::string &) const;
+               virtual std::string create_build_signature(const BuildInfo &) const;
                virtual Task *run(const Target &) const;
        };
 
index 3c3757fe794549365851170b6b1e461a1998fd74..6aee38b2ee6a59b62206c0f8617dd7e5df6cf590 100644 (file)
@@ -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<Target *> &, 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;