diff --git a/new/targets.jam b/new/targets.jam index 6ddd77c67..5270772cb 100644 --- a/new/targets.jam +++ b/new/targets.jam @@ -569,7 +569,9 @@ rule basic-target ( name : project local source-targets = [ generate-sources $(rproperties) ] ; self.generated.$(property-set) = - [ construct $(source-targets) : $(rproperties) ] ; + [ construct $(source-targets) : $(rproperties) ] ; + check-for-unused-sources + $(self.generated.$(property-set)) : $(source-targets) ; # Apply use requirement of this target to all generated # virtual targets. @@ -591,6 +593,27 @@ rule basic-target ( name : project } return $(self.generated.$(property-set)) ; } + + # Check that 'result' makes use of all the 'sources'. If not, + # issues a warning. + local rule check-for-unused-sources ( result + : sources * ) + { + local used-sources ; + for local r in $(result) + { + used-sources += [ virtual-target.traverse $(r) : include-roots : 1 ] ; #: includes-sources ] ; + } + + for local s in $(sources) + { + if ! $(s) in $(used-sources) + { + errors.warning "Unused source target" [ $(s).str ] + : "Main target is " [ full-name ] ; + } + } + } + # Constructs the virtual targets for this abstract targets and # the dependecy graph. Returns the list of virtual targets. diff --git a/new/virtual-target.jam b/new/virtual-target.jam index c896acde0..78fa8511b 100644 --- a/new/virtual-target.jam +++ b/new/virtual-target.jam @@ -729,8 +729,10 @@ rule register ( target ) } # Traverses the dependency graph of 'target' and return all targets that will -# be created before this one is created. -rule traverse ( target ) +# be created before this one is created. If root of some dependency graph is +# found during traversal, it's either included or not, dependencing of the +# value of 'include-roots'. In either case, sources of root are not traversed. +rule traverse ( target : include-roots ? : include-sources ? ) { local result ; if [ $(target).action ] @@ -743,10 +745,18 @@ rule traverse ( target ) { if ! [ $(t).root ] { - result += [ traverse $(t) ] ; + result += [ traverse $(t) : $(include-roots) : $(include-sources) ] ; } + else if $(include-roots) + { + result += $(t) ; + } } } + else if $(include-sources) + { + result = $(target) ; + } return $(result) ; } diff --git a/test/test_all.py b/test/test_all.py index d8a67a605..834662f7d 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -83,6 +83,7 @@ tests = [ "project_test1", "make_rule", "alias", "alternatives", + "unused", ] if os.name == 'posix': diff --git a/test/unused.py b/test/unused.py new file mode 100644 index 000000000..59199ffca --- /dev/null +++ b/test/unused.py @@ -0,0 +1,30 @@ +#!/usr/bin/python + +# Test that unused sources are at least reported. + +from BoostBuild import Tester +from string import find +t = Tester() + +t.write("a.h", """ +""") + +t.write("a.cpp", """ +int main() +{ + return 0; +} +""") + +t.write("Jamfile", """ +exe a : a.cpp a.h ; +""") + +t.write("project-root.jam", """ +""") + +t.run_build_system() +t.fail_test(find(t.stdout(), "warning: Unused source target { a.H }") == -1) + +t.cleanup() + diff --git a/v2/build/targets.jam b/v2/build/targets.jam index 6ddd77c67..5270772cb 100644 --- a/v2/build/targets.jam +++ b/v2/build/targets.jam @@ -569,7 +569,9 @@ rule basic-target ( name : project local source-targets = [ generate-sources $(rproperties) ] ; self.generated.$(property-set) = - [ construct $(source-targets) : $(rproperties) ] ; + [ construct $(source-targets) : $(rproperties) ] ; + check-for-unused-sources + $(self.generated.$(property-set)) : $(source-targets) ; # Apply use requirement of this target to all generated # virtual targets. @@ -591,6 +593,27 @@ rule basic-target ( name : project } return $(self.generated.$(property-set)) ; } + + # Check that 'result' makes use of all the 'sources'. If not, + # issues a warning. + local rule check-for-unused-sources ( result + : sources * ) + { + local used-sources ; + for local r in $(result) + { + used-sources += [ virtual-target.traverse $(r) : include-roots : 1 ] ; #: includes-sources ] ; + } + + for local s in $(sources) + { + if ! $(s) in $(used-sources) + { + errors.warning "Unused source target" [ $(s).str ] + : "Main target is " [ full-name ] ; + } + } + } + # Constructs the virtual targets for this abstract targets and # the dependecy graph. Returns the list of virtual targets. diff --git a/v2/build/virtual-target.jam b/v2/build/virtual-target.jam index c896acde0..78fa8511b 100644 --- a/v2/build/virtual-target.jam +++ b/v2/build/virtual-target.jam @@ -729,8 +729,10 @@ rule register ( target ) } # Traverses the dependency graph of 'target' and return all targets that will -# be created before this one is created. -rule traverse ( target ) +# be created before this one is created. If root of some dependency graph is +# found during traversal, it's either included or not, dependencing of the +# value of 'include-roots'. In either case, sources of root are not traversed. +rule traverse ( target : include-roots ? : include-sources ? ) { local result ; if [ $(target).action ] @@ -743,10 +745,18 @@ rule traverse ( target ) { if ! [ $(t).root ] { - result += [ traverse $(t) ] ; + result += [ traverse $(t) : $(include-roots) : $(include-sources) ] ; } + else if $(include-roots) + { + result += $(t) ; + } } } + else if $(include-sources) + { + result = $(target) ; + } return $(result) ; } diff --git a/v2/test/test_all.py b/v2/test/test_all.py index d8a67a605..834662f7d 100644 --- a/v2/test/test_all.py +++ b/v2/test/test_all.py @@ -83,6 +83,7 @@ tests = [ "project_test1", "make_rule", "alias", "alternatives", + "unused", ] if os.name == 'posix': diff --git a/v2/test/unused.py b/v2/test/unused.py new file mode 100644 index 000000000..59199ffca --- /dev/null +++ b/v2/test/unused.py @@ -0,0 +1,30 @@ +#!/usr/bin/python + +# Test that unused sources are at least reported. + +from BoostBuild import Tester +from string import find +t = Tester() + +t.write("a.h", """ +""") + +t.write("a.cpp", """ +int main() +{ + return 0; +} +""") + +t.write("Jamfile", """ +exe a : a.cpp a.h ; +""") + +t.write("project-root.jam", """ +""") + +t.run_build_system() +t.fail_test(find(t.stdout(), "warning: Unused source target { a.H }") == -1) + +t.cleanup() +