From 07188495957d6ada793b5669cbc63ad771fc38b6 Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Thu, 24 Jun 2004 07:26:29 +0000 Subject: [PATCH] * build/virtual-target.jam (from-file): Use full file name as search key, to avoid creating two different targets from two different project, which actually correspond to the same file. (register): Use actual name of the target as key. This again avoid the problem with two equivalent targets in two different projects. [SVN r23173] --- v2/build/virtual-target.jam | 35 +++++++++++++++++++++-------- v2/test/duplicate.py | 44 +++++++++++++++++++++++++++++++++++++ v2/test/test_all.py | 1 + 3 files changed, 71 insertions(+), 9 deletions(-) create mode 100644 v2/test/duplicate.py diff --git a/v2/build/virtual-target.jam b/v2/build/virtual-target.jam index 6866c24c9..f0aa2fea2 100644 --- a/v2/build/virtual-target.jam +++ b/v2/build/virtual-target.jam @@ -716,10 +716,15 @@ class null-action : action rule from-file ( file : project ) { import type ; # had to do this here to break a circular dependency - - if $(.files.$(file).$(project)) + + # Check if we've created a target corresponding to this file. + local source-location = [ $(project).get source-location ] ; + local path = [ path.root [ path.root [ path.make $(file) ] $(source-location) ] + [ path.pwd ] ] ; + + if $(.files.$(path)) { - return $(.files.$(file).$(project)) ; + return $(.files.$(path)) ; } else { @@ -737,7 +742,7 @@ rule from-file ( file : project ) $(v).suffix [ MATCH ^.(.*)$ : $(file:S) ] ; result = $(v) ; } - .files.$(file).$(project) = $(result) ; + .files.$(path) = $(result) ; return $(result) ; } } @@ -749,7 +754,8 @@ rule from-file ( file : project ) rule register ( target ) { local signature = [ sequence.join - [ $(target).project ] [ $(target).name ] [ $(target).type ] : - ] ; + [ $(target).actual-name ] : - ] ; + local result ; for local t in $(.cache.$(signature)) { @@ -779,9 +785,10 @@ rule register ( target ) } } } + if ! $(result) { - .cache.$(signature) += $(target) ; + .cache.$(signature) += $(target) ; result = $(target) ; } @@ -924,7 +931,7 @@ rule clone-action ( action : new-project : new-action-name ? : new-properties ? # # The 'new-project' parameter tells what project should be assigned # for newly created non-source targets. -rule clone-template ( target dont-recurse ? : new-source : new-project ) +rule clone-template ( target dont-recurse ? : new-source : new-project : dont-register ? ) { local name = [ $(new-source).name ] ; local old-name = [ $(target).name ] ; @@ -963,7 +970,13 @@ rule clone-template ( target dont-recurse ? : new-source : new-project ) if $(t) != $(target) { cloned-targets += - [ clone-template $(t) dont-recurse : $(new-source) : $(new-project) ] ; + [ clone-template $(t) dont-recurse : $(new-source) : $(new-project) + # We don't want to pass new targets vis 'register' util we've + # finished building them -- i.e. until we assign the action. + # It might seem registering this not-yet ready target is + # harmless, but in fact the 'register' logic expects than + # registered target is never changed later. + : dont-register ] ; } } local cloned-targets2 ; @@ -974,12 +987,16 @@ rule clone-template ( target dont-recurse ? : new-source : new-project ) cloned-targets2 += [ register $(t) ] ; } + $(cloned-action).set-targets $(cloned-targets2) ; cloned = $(cloned-targets2[1]) ; } else { - cloned = [ register $(cloned) ] ; + if ! $(dont-register) + { + cloned = [ register $(cloned) ] ; + } } return $(cloned) ; } diff --git a/v2/test/duplicate.py b/v2/test/duplicate.py new file mode 100644 index 000000000..f26de455a --- /dev/null +++ b/v2/test/duplicate.py @@ -0,0 +1,44 @@ +#!/usr/bin/python + +# Copyright (C) Vladimir Prus 2004. Permission to copy, use, modify, sell and +# distribute this software is granted provided this copyright notice appears in +# all copies. This software is provided "as is" without express or implied +# warranty, and with no claim as to its suitability for any purpose. + +# This test tries to stage the same file to the same location by *two* +# different stage rules, in two different projects. This is not exactly +# good thing to do, but still, V2 should handle this. We had two bugs: +# - since the file is referred from two projects, we created to different +# virtual targets +# - we also failed to figure out that the two target corresponding to the +# copied files (created in two projects) are actually equivivalent. + +from BoostBuild import Tester, List + + +t = Tester() + +t.write("a.cpp", """ +""") + +t.write("Jamfile", """ +build-project a ; +build-project b ; +""") + +t.write("project-root.jam", """ +""") + +t.write("a/Jamfile", """ +stage bin : ../a.cpp : ../dist ; +""") + +t.write("b/Jamfile", """ +stage bin : ../a.cpp : ../dist ; +""") + +t.run_build_system() +t.expect_addition("dist/a.cpp") + + +t.cleanup() diff --git a/v2/test/test_all.py b/v2/test/test_all.py index 48ecebad7..c0dca9f82 100644 --- a/v2/test/test_all.py +++ b/v2/test/test_all.py @@ -122,6 +122,7 @@ tests = [ "project_test1", "standalone", "expansion", "wrapper", + "duplicate", #"ordered_properties", ]