]> git.tdb.fi Git - builder.git/commitdiff
Add transitive dependencies for source files
authorMikko Rasa <tdb@tdb.fi>
Thu, 22 Aug 2013 12:03:03 +0000 (15:03 +0300)
committerMikko Rasa <tdb@tdb.fi>
Thu, 22 Aug 2013 12:03:03 +0000 (15:03 +0300)
This eliminates a problem where includes in C source files would cause
generates sources to be rebuilt if any of the included files changed.
Includes should only affect the object file built from the source file,
not the source file itself.

source/analyzer.cpp
source/csourcefile.cpp
source/objectfile.cpp
source/target.cpp
source/target.h

index d15a7477984886db2e4c22262869f019275f9454..2c9cf058d7a565d3849acca028e150d878f4e85c 100644 (file)
@@ -30,6 +30,9 @@ void Analyzer::analyze()
                        const Target::Dependencies &depends = i->second->get_dependencies();
                        for(Target::Dependencies::const_iterator j=depends.begin(); j!=depends.end(); ++j)
                                rdepends[*j].insert(i->second);
+                       const Target::Dependencies &tdepends = i->second->get_transitive_dependencies();
+                       for(Target::Dependencies::const_iterator j=tdepends.begin(); j!=tdepends.end(); ++j)
+                               rdepends[*j].insert(i->second);
                }
        }
 
@@ -109,7 +112,11 @@ void Analyzer::build_depend_table(Target &tgt, unsigned depth)
                        depends.assign(rdeps.begin(), rdeps.end());
                }
                else
+               {
                        depends = tgt.get_dependencies();
+                       const Target::Dependencies &tdeps = tgt.get_transitive_dependencies();
+                       depends.insert(depends.end(), tdeps.begin(), tdeps.end());
+               }
 
                depends.sort(full_paths ? target_order_full : target_order);
 
index e34ff279cc4c98d199b491c075e17bc4c689a449..d4f6d79df9e0a0e2116d4d3ed6548d00c58b6337 100644 (file)
@@ -62,13 +62,13 @@ void CSourceFile::find_dependencies()
        {
                Target *hdr = builder.get_vfs().find_header(i->substr(1), ((*i)[0]=='"' ? local_incpath : incpath));
                if(hdr)
-                       add_dependency(*hdr);
+                       add_transitive_dependency(*hdr);
        }
 }
 
 void CSourceFile::modified()
 {
        includes.clear();
-       depends.clear();
+       trans_depends.clear();
        find_dependencies();
 }
index cee8c87d2d6078b90210aa81615d48bd0db0aaf9..97b5c75a523b34b0cfeff3d0c48413781a109834 100644 (file)
@@ -44,7 +44,7 @@ void ObjectFile::find_dependencies()
 void ObjectFile::find_dependencies(FileTarget *tgt)
 {
        FileTarget *rtgt = dynamic_cast<FileTarget *>(tgt->get_real_target());
-       const Dependencies &tdeps = rtgt->get_dependencies();
+       const Dependencies &tdeps = rtgt->get_transitive_dependencies();
        Dependencies deps_to_add;
        if(rtgt==tgt)
        {
index 72a369ad0d4a15332116ee0527e75d88030b4ebf..55f73a09cfe725dd2978f6c7d199992c61da9cba 100644 (file)
@@ -33,6 +33,13 @@ void Target::add_dependency(Target &dep)
                dep.signal_bubble_rebuild.connect(sigc::mem_fun(this, &Target::check_rebuild));
 }
 
+void Target::add_transitive_dependency(Target &dep)
+{
+       if(&dep==this)
+               throw invalid_argument("Target::add_transitive_dependency");
+       trans_depends.push_back(&dep);
+}
+
 void Target::add_side_effect(Target &se)
 {
        side_effects.push_back(&se);
index 6b9cc90a0842de77c845982a1f6462d7c107caf6..64a132c9f13a0460f8608695cb632b88f3ed5522 100644 (file)
@@ -17,6 +17,11 @@ class Tool;
 /**
 Targets make up the build graph.  This class is a base for all target types and
 handles many common tasks.  See also FileTarget and VirtualTarget.
+
+Targets can depend on other targets.  There are two kinds of dependencies:
+normal and transitive.  Normal dependencies will need to be built before the
+target itself, and will cause the target to be rebuilt if modified.  Transitive
+dependencies can be used by other targets further down the chain.
 */
 class Target
 {
@@ -49,6 +54,7 @@ protected:
        std::list<std::string> problems;
 
        Dependencies depends;
+       Dependencies trans_depends;
        Dependencies side_effects;
        Target *primary_target;
 
@@ -66,6 +72,8 @@ public:
        this won't be detected until the targets are prepared. */
        void add_dependency(Target &);
 
+       void add_transitive_dependency(Target &);
+
        /** Adds a side effect for the target.  Side effects are not built on their
        own, but together with their primary target. */
        void add_side_effect(Target &);
@@ -80,6 +88,8 @@ public:
        /// Returns the dependencies of the target, in the order they were added.
        const Dependencies &get_dependencies() const { return depends; }
 
+       const Dependencies &get_transitive_dependencies() const { return trans_depends; }
+
        /// Returns the side effects of the target.
        const Dependencies &get_side_effects() const { return side_effects; }