From 29699d629eb5345caf6138e4e1dc8d3ec6e154e8 Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Mon, 17 Feb 2003 09:10:57 +0000 Subject: [PATCH] Bugfix: virtual target with per-main-target properties can be confused with ordinary virtual target. * new/virtual-target.jam (abstract-file-target.specific-main-target): New overridable rule. (abstract-file-target.actual-name): Use the above. (file-target.specific-main-target): Override, using code from 'compute-extra-path'. (file-target.compute-extra-path): Remove (file-target.path): Use 'specific-main-target' directly. * test/main_properties.py: More tests. [SVN r17480] --- src/build/virtual-target.jam | 77 ++++++++++++++++++++---------------- test/main_properties.py | 16 ++++++++ 2 files changed, 60 insertions(+), 33 deletions(-) diff --git a/src/build/virtual-target.jam b/src/build/virtual-target.jam index ec63fde8d..9e6d681d3 100644 --- a/src/build/virtual-target.jam +++ b/src/build/virtual-target.jam @@ -298,7 +298,17 @@ rule abstract-file-target ( name common.Clean clean : $(name) ; } } - + + # Returns the name of main target this virtual target is specific too. + # Ordinary, it's assumed that grist of the actual Jam target and target path + # is determined by project, base properties, target name and type. + # Derived classes may return non-empty string to indicate that the target is + # specific to the given main target. + rule specific-main-target ( ) + { + return "" ; + } + rule str ( ) { local action = [ action ] ; @@ -367,7 +377,12 @@ rule abstract-file-target ( name { grist = $(grist)/$(self.extra-grist) ; } - + local smt = [ specific-main-target ] ; + if $(smt) + { + grist = $(grist)/main-target-$(smt) ; + } + if $(self.suffix) { self.actual-name = [ sequence.join <$(grist)>$(self.name) @@ -415,7 +430,6 @@ rule file-target ( rule actualize-location ( target ) { - compute-extra-path ; if $(self.path) { LOCATE on $(target) = $(self.path) ; @@ -442,55 +456,52 @@ rule file-target ( # This is a source file. SEARCH on $(target) = [ path.native [ project.attribute $(self.project) source-location ] ] ; - } + } } - rule compute-extra-path ( ) - { - if $(self.action) - { - local ps = [ $(self.action).properties-ps ] ; - - local main-target = [ $(self.dg).main-target ] ; - local project = [ $(main-target).project ] ; - local plocation = [ project.attribute $(project) location ] ; - local ptarget = [ project.target $(plocation) ] ; - local ref-ps = [ $(ptarget).reference-properties [ $(self.dg).properties-ps ] ] ; - - - if [ $(ps).free ] != [ $(ref-ps).free ] - { - self.extra-path = [ sequence.join main-target- [ $(main-target).name ] ] ; - } - } - } + rule specific-main-target ( ) + { + if $(self.action) + { + local ps = [ $(self.action).properties-ps ] ; + + local main-target = [ $(self.dg).main-target ] ; + local project = [ $(main-target).project ] ; + local plocation = [ project.attribute $(project) location ] ; + local ptarget = [ project.target $(plocation) ] ; + local ref-ps = [ $(ptarget).reference-properties [ $(self.dg).properties-ps ] ] ; + if [ $(ps).free ] != [ $(ref-ps).free ] + { + return [ $(main-target).name ] ; + } + } + } + # Returns the directory for this target rule path ( ) { - if $(self.path) + if ! $(self.path) { - return $(self.path) ; - } - else - { - compute-extra-path ; - local build-dir = [ project.attribute $(self.project) build-dir ] ; if ! $(build-dir) { build-dir = [ project.attribute $(self.project) location ] ; } + local smt = [ specific-main-target ] ; local path = [ path.join $(build-dir) bin [ $(self.action).path ] - $(self.extra-path) + main-target-$(smt) ] ; - - return [ path.native $(path) ] ; + + # Store the computed path, so that it's not recomputed + # any more + self.path = [ path.native $(path) ] ; } + return $(self.path) ; } } diff --git a/test/main_properties.py b/test/main_properties.py index deae70fbb..dd1f1dc13 100644 --- a/test/main_properties.py +++ b/test/main_properties.py @@ -22,5 +22,21 @@ t.write("b.cpp", "void foo() {}\n") t.run_build_system() t.expect_addition("bin/gcc/debug/main-target-b/b.o") +# This tests another bug: when source file was used by two main targets, +# one without any requirements and another with free requirements, it +# was compiled twice with to the same locaiton. + +t.write("Jamfile", """ +exe a : a.cpp ; +exe b : a.cpp : FOO ; +""") +t.write("a.cpp", """ +int main() {} +""") + +t.rm("bin") +t.run_build_system() +t.expect_addition(["bin/gcc/debug/a.o", "bin/gcc/debug/main-target-b/a.o"]) + t.cleanup()