From bdc732fbd6bdff7636bcbc4dd8a4662e4f50dc44 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Sat, 6 Oct 2001 18:19:15 +0000 Subject: [PATCH] regex, threads, and python will all build from the top level. If you build the 'test' target from the top level, it will run all regressions. Jamfile: subincludes for thread, python libs, and status for regression tests Jamrules: Use the new path-global rule to establish BOOST_ROOT correctly for all subprojects libs/regex/build/Jamfile Take advantage of correct BOOST_ROOT setting libs/python/build/Jamfile Search for python executable; don't try to build anything if it can't be found. don't build tests by default improved comments, organization, and naming. status/Jamfile Fixed references to config test files Failed tests now leave their stdout results in .error instead of removing it No test targets are dependencies of 'all' anymore Added comments Reorganized tools/build/Jambase Meant to check this in long ago. tools/build/allyourbase.jam Fixed SHELL_EXPORT setting, added SHELL_SET removed 'test' from the dependencies of 'all'; tests no longer run by default. Fixed the direction of slashes for Windows when ALL_LOCATE_TARGET is used. Added path-global rule for declaring path variables which may be relative rule in-invocation-subdir returns true if the current subproject is the one from which Jam was invoked rule protect-subdir is now used to protect subproject variables rule tokens-to-simple-path converts path tokens to a simplified path. tools/build/boost-base.jam Fixed bugs tools/build/jam_src/makedebugjam.bat Fixed a bug which prevented a final debug build tools/build/jam_src/search.c Fixed a bug of mine which caused LOCATE to be ignored (!). [SVN r11348] --- Jambase | 26 +++++++- allyourbase.jam | 159 +++++++++++++++++++++++++++++++++++++-------- boost-base.jam | 15 ++--- v1/Jambase | 26 +++++++- v1/allyourbase.jam | 159 +++++++++++++++++++++++++++++++++++++-------- v1/boost-base.jam | 15 ++--- 6 files changed, 328 insertions(+), 72 deletions(-) diff --git a/Jambase b/Jambase index 22b558186..c9505818d 100644 --- a/Jambase +++ b/Jambase @@ -98,14 +98,31 @@ rule report-argument-error # rule-name length argnum : $(1) : $(2) : $(3) : $(4) ") instead." ; } -rule check-arguments # rule-name max-lengths... : $(1) : $(2) : $(3) : $(4)... +# check-arguments rule-name lengths... : $(1) : $(2) : $(3) : $(4)... +# + +# Check that arguments of the correct size are supplied to a rule +# invocation. Each element of lengths should either be a single nonnegative +# integer or a range of nonnegative integers (e.g. 2-4), which specifies the +# allowed length of each argument. The following arguments to check-arguments +# should be the arguments passed to the invoking rule, in order. It is useful to +# pass one more argument than the invoking rule expects, so that extra arguments +# may be detected. +rule check-arguments # { + # The name of the invoking rule, for error reporting local rule-name = $(<[1]) ; + + # The allowed lengths of each argument list local lengths = $(<[2-]) ; + + # Keeps track of which argument we're looking at. local argnums = 1 2 3 4 5 6 7 8 ; + # Iterate through each allowed length for length in $(lengths) { + # set maximum and minimum local maximum minimum = $($(argnums[2])[$(length)-]) ; switch $(length) { @@ -321,4 +338,11 @@ rule project-root if $(JAMFILE) { include $(JAMFILE) ; + + # Call any post-jamfile hooks + local hook ; + for hook in $(gPOST_JAMFILE_HOOKS) + { + local ignored = [ $(hook) ] ; + } } diff --git a/allyourbase.jam b/allyourbase.jam index 93e806672..29c193760 100644 --- a/allyourbase.jam +++ b/allyourbase.jam @@ -180,15 +180,16 @@ if $(NT) SUFDLL ?= .dll .lib ; gLINKABLE_PRODUCT_INDEX(DLL) = 2 ; # (the .lib is the ones to link) NOARSCAN ?= true ; - SHELL_EXPORT ?= "set " ; + SHELL_EXPORT ?= ; + SHELL_SET ?= "set " ; # dwa 6/4/01 - removed compiler determination for boost # added some yacc/lex stuff, assuming cygwin for now. - LEX = flex ; - YACC = bison -t -d -l -v ; - YACCFILES = y.tab ; - YACC_OUTPUT = --output= ; - LEX_OUTPUT = -o ; + LEX ?= flex ; + YACC ?= bison -t -d -l -v ; + YACCFILES ?= y.tab ; + YACC_OUTPUT ?= --output= ; + LEX_OUTPUT ?= -o ; # YACC_FIX_LINES = sed '/simple/d ; # fix up #line directives for metrowerks } else if $(OS2) @@ -395,6 +396,7 @@ else if $(UNIX) YACCFILES ?= y.tab ; YACCFLAGS ?= -d ; SHELL_EXPORT ?= "export " ; + SHELL_SET ?= "" ; } # @@ -431,7 +433,8 @@ RSH ?= rsh ; SED ?= sed ; SHELLHEADER ?= "#!/bin/sh" ; SHELLMODE ?= 755 ; -SHELL_EXPORT ?= "" ; +SHELL_EXPORT ?= ; +SHELL_SET ?= "" ; SLASH ?= / ; SPLITPATH ?= ":" ; # dwa -- added missing SPLITPATH STDHDRS ?= /usr/include ; @@ -453,7 +456,7 @@ OSFULL = $(OS)$(OSVER)$(OSPLAT) $(OS)$(OSPLAT) $(OS)$(OSVER) $(OS) ; # # dwa 6/17/01 - added test -DEPENDS all : shell files lib dll exe obj test ; +DEPENDS all : shell files lib dll exe obj ; DEPENDS all shell files lib dll exe obj test : first ; NOTFILE all first shell files lib dll exe obj dirs clean uninstall test ; ALWAYS clean uninstall ; @@ -888,19 +891,26 @@ rule MakeLocate # We add directory-grist here so that implicitly-created directory # target names don't collide with user-specified targets. - Depends $(<) : $(>[1]:G=directory-grist) ; - MkDir $(>[1]:G=directory-grist) ; + Depends $(<) : [ MkDir $(>[1]:G=directory-grist) ] ; } } +# now returns the created directory target -- dwa rule MkDir { # If dir exists, don't update it # Do this even for $(DOT). - NOUPDATE $(<) ; + local dir = $(<) ; + if $(NT) + { + # make sure slashes all go the right way + dir = [ FDirName [ split-path $(dir) ] ] ; + } + + NOUPDATE $(dir) ; - if $(<) != $(DOT) && ! $($(<)-mkdir) + if $(dir) != $(DOT) && ! $($(dir)-mkdir) { local s ; @@ -908,14 +918,14 @@ rule MkDir # MkDir1 has the actions # Arrange for jam dirs - $(<)-mkdir = true ; - MkDir1 $(<) ; - Depends dirs : $(<) ; + $(dir)-mkdir = true ; + MkDir1 $(dir) ; + Depends dirs : $(dir) ; # Recursively make parent directories. - # $(<:P) = $(<)'s parent, & we recurse until root + # $(dir:P) = $(dir)'s parent, & we recurse until root - s = $(<:P) ; + s = $(dir:P) ; if $(NT) { @@ -926,9 +936,9 @@ rule MkDir } } - if $(s) && $(s) != $(<) + if $(s) && $(s) != $(dir) { - Depends $(<) : $(s) ; + Depends $(dir) : $(s) ; MkDir $(s) ; } else if $(s) @@ -937,6 +947,7 @@ rule MkDir } } + return $(dir) ; } # dwa 6/4/01 - modified for boost @@ -1118,6 +1129,23 @@ rule subinclude } } +# dwa 10/6/01 - added for boost +# +# path-global variable-name : path... ; +# +# if $(variable-name) is unset, sets variable-name to path... +# variable-name will be adjusted on a per-subproject basis to refer to the same path. +rule path-global +{ + $(<) ?= $(>) ; + gPATH_GLOBAL_VALUE($(<)) = $($(<)) ; + + if ! ( $(<) in $(gPATH_GLOBALS) ) + { + gPATH_GLOBALS += $(<) ; + } +} + # dwa 6/4/01 - modified for boost rule SubDir { @@ -1155,19 +1183,19 @@ rule SubDir # If $(TOP)/Jamrules hasn't been included, do so. # - if ! $(gINCLUDED($(<[1]))) + if ! $(gINCLUDED($(gTOP))) { # Gated entry. - gINCLUDED($(<[1])) = TRUE ; + gINCLUDED($(gTOP)) = TRUE ; # File is $(TOPRULES) or $(TOP)/Jamrules. - _r = $($(<[1])RULES) ; + _r = $($(gTOP)RULES) ; if ! $(_r) { - _r = $(JAMRULES:R=$($(<[1]))) ; + _r = $(JAMRULES:R=$($(gTOP))) ; } # Include it. @@ -1175,7 +1203,7 @@ rule SubDir include $(_r) ; # determine where toolset specifications and boost-base can be found. - BOOST_BUILD_INSTALLATION ?= $($(<[1])) ; + BOOST_BUILD_INSTALLATION ?= $($(gTOP)) ; # and include boost-base include [ join-path $(BOOST_BUILD_INSTALLATION) boost-base.jam ] ; @@ -1188,17 +1216,18 @@ rule SubDir # This allows us to determine whether we're in the directory where jam was # invoked from so that we can make locally named targets gINVOCATION_SUBDIR_TOKENS ?= $(SUBDIR_TOKENS) ; + gINVOCATION_SUBDIR_TOKENS ?= $(DOT) ; # SUBDIR is the path from the invocation directory to the subproject # directory. - SUBDIR = [ FDirName [ simplify-path-tokens $($(<[1])_TOKENS) $(SUBDIR_TOKENS) ] ] ; + SUBDIR = [ tokens-to-simple-path $($(gTOP)_TOKENS) $(SUBDIR_TOKENS) ] ; SEARCH_SOURCE = $(SUBDIR) ; # This will strip off any leading dot on SUBDIR_TOKENS local nodot_subdir = [ simplify-path-tokens $(SUBDIR_TOKENS) ] ; - ALL_LOCATE_TARGET ?= $($(<[1])) ; + ALL_LOCATE_TARGET ?= $($(gTOP)) ; LOCATE_SOURCE = [ FDirName $(ALL_LOCATE_TARGET) $(nodot_subdir) ] ; LOCATE_TARGET = $(LOCATE_SOURCE) ; @@ -1211,9 +1240,22 @@ rule SubDir # This variable holds the path from the directory of Jam's invocation to the # directory of the current subproject. - RELATIVE_SUBDIR_TOKENS = [ simplify-path-tokens $($(<[1])_TOKENS) $(SUBDIR_TOKENS) : $(DOT) ] ; + RELATIVE_SUBDIR_TOKENS = [ simplify-path-tokens $($(gTOP)_TOKENS) $(SUBDIR_TOKENS) : $(DOT) ] ; RELATIVE_SUBDIR = [ join-path $(RELATIVE_SUBDIR_TOKENS) ] ; + + adjust-path-globals ; } + +rule in-invocation-subdir +{ + local subdir-tokens = $(SUBDIR-TOKENS) ; + subdir-tokens ?= $(DOT) ; + if $(subdir-tokens) = $(gINVOCATION_SUBDIR_TOKENS) + { + return true ; + } +} + # These are the global variables that get set up by SubDir. If you need to # invoke SubDir temporarily and then restore them, declare # local $(gSUBDIR_GLOBALS) ; @@ -1221,6 +1263,62 @@ gSUBDIR_GLOBALS = SUBDIR SUBDIR_TOKENS SEARCH_SOURCE LOCATE_SOURCE LOCATE_TARGET SOURCE_GRIST RELATIVE_SUBDIR RELATIVE_SUBDIR_TOKENS ; +rule protect-subdir +{ + return $(gSUBDIR_GLOBALS) $(gPATH_GLOBALS) ; +} + +# prepends root to any unrooted elements of paths, and simplifies +rule root-paths # paths... : root +{ + local path result ; + for path in $(<) + { + local rooted = $(path:R=$(>)) ; + if $(rooted) != $(path) + { + path = [ tokens-to-simple-path [ split-path $(rooted) ] ] ; + path = $(path:G=$(rooted:G)) ; + } + result += $(path) ; + } + return $(result) ; +} + +# Adjust all path globals so that they are relative to the current subproject. +rule adjust-path-globals +{ + # compute path tokens from current subproject to root + local tokens-to-root = [ split-path [ FSubDir $(SUBDIR_TOKENS) ] ] ; + + # compute path tokens from current subproject to invocation + # directory. $(DOT) is added just in case we're building from the project + # root + local tokens-to-invocation + = $(tokens-to-root) $(gINVOCATION_SUBDIR_TOKENS) ; + + local variable ; + for variable in $(gPATH_GLOBALS) + { + local paths = $(gPATH_GLOBAL_VALUE($(variable))) ; + $(variable) = ; + local path ; + for path in $(paths) + { + # is path already rooted? + if $(path:R=x) = $(path) + { + $(variable) += $(path) ; + } + else + { + local tokens = $(tokens-to-invocation) [ split-path $(path) ] ; + $(variable) += [ tokens-to-simple-path $(tokens) ] ; + } + } + } +} + # dwa 6/4/01 - added for boost # strip-grist value # @@ -1388,6 +1486,10 @@ rule simplify-path-tokens return $(result) ; } +rule tokens-to-simple-path +{ + return [ FDirName [ simplify-path-tokens $(<) ] ] ; +} rule SubDirCcFlags { @@ -1420,6 +1522,9 @@ rule SubInclude _s = [ FDirName $(<[2-]) ] ; + # protect variables from being permanently set by SubDir invocations + # in included files. + local [ protect-subdir ] ; include $(JAMFILE:D=$(_s):R=$($(<[1]))) ; } diff --git a/boost-base.jam b/boost-base.jam index 9ea4988e2..c51d1198d 100644 --- a/boost-base.jam +++ b/boost-base.jam @@ -723,9 +723,9 @@ rule fixup-path-properties { local path-properties = [ get-properties $(gPATH_FEATURES) : $(<) ] ; local non-path = [ difference $(<) : $(path-properties) ] ; - if $(RELATIVE_SUBDIR) && ! $(path-properties:R) + if $(RELATIVE_SUBDIR) { - path-properties = $(path-properties:R=$(RELATIVE_SUBDIR)) ; + path-properties = [ root-paths $(path-properties) : $(RELATIVE_SUBDIR) ] ; } return $(path-properties) $(non-path) ; } @@ -1001,15 +1001,14 @@ rule dependent-include # rule to find it. local jamfile-path - = [ join-path - [ simplify-path-tokens - $(RELATIVE_SUBDIR_TOKENS) [ directory-of $(target) ] $(JAMFILE) ] ] ; + = [ tokens-to-simple-path + $(RELATIVE_SUBDIR_TOKENS) [ directory-of $(target) ] $(JAMFILE) ] ; if ! $(gINCLUDED($(jamfile-path))) { # protect variables from being permanently set by SubDir invocations # in included files. - local $(gSUBDIR_GLOBALS) ; + local [ protect-subdir ] ; # this stack allows us to avoid making dependee libraries part of # the "type" targets, e.g. all, exe, obj. See rule type-DEPENDS. @@ -1107,7 +1106,7 @@ rule link-libraries local new-subdir = TOP [ top-relative-tokens [ directory-of $(lib-path) ] ] ; # protect global variables from being permanently set by SubDir - local $(gSUBDIR_GLOBALS) ; + local [ protect-subdir ] ; # Enter the dependee subproject SubDir $(new-subdir) ; @@ -1166,7 +1165,7 @@ rule declare-fake-targets # The following checks that we're in the subdirectory of Jam's invocation # so that we can arrange for ungristed target names to be built from the # command-line. - if ( $(SUBDIR_TOKENS) = $(gINVOCATION_SUBDIR_TOKENS) ) + if [ in-invocation-subdir ] { DEPENDS $(<:G=) : $(<) ; # allows $(<:G=) to be used to build all variants NOTFILE $(<:G=) ; diff --git a/v1/Jambase b/v1/Jambase index 22b558186..c9505818d 100644 --- a/v1/Jambase +++ b/v1/Jambase @@ -98,14 +98,31 @@ rule report-argument-error # rule-name length argnum : $(1) : $(2) : $(3) : $(4) ") instead." ; } -rule check-arguments # rule-name max-lengths... : $(1) : $(2) : $(3) : $(4)... +# check-arguments rule-name lengths... : $(1) : $(2) : $(3) : $(4)... +# + +# Check that arguments of the correct size are supplied to a rule +# invocation. Each element of lengths should either be a single nonnegative +# integer or a range of nonnegative integers (e.g. 2-4), which specifies the +# allowed length of each argument. The following arguments to check-arguments +# should be the arguments passed to the invoking rule, in order. It is useful to +# pass one more argument than the invoking rule expects, so that extra arguments +# may be detected. +rule check-arguments # { + # The name of the invoking rule, for error reporting local rule-name = $(<[1]) ; + + # The allowed lengths of each argument list local lengths = $(<[2-]) ; + + # Keeps track of which argument we're looking at. local argnums = 1 2 3 4 5 6 7 8 ; + # Iterate through each allowed length for length in $(lengths) { + # set maximum and minimum local maximum minimum = $($(argnums[2])[$(length)-]) ; switch $(length) { @@ -321,4 +338,11 @@ rule project-root if $(JAMFILE) { include $(JAMFILE) ; + + # Call any post-jamfile hooks + local hook ; + for hook in $(gPOST_JAMFILE_HOOKS) + { + local ignored = [ $(hook) ] ; + } } diff --git a/v1/allyourbase.jam b/v1/allyourbase.jam index 93e806672..29c193760 100644 --- a/v1/allyourbase.jam +++ b/v1/allyourbase.jam @@ -180,15 +180,16 @@ if $(NT) SUFDLL ?= .dll .lib ; gLINKABLE_PRODUCT_INDEX(DLL) = 2 ; # (the .lib is the ones to link) NOARSCAN ?= true ; - SHELL_EXPORT ?= "set " ; + SHELL_EXPORT ?= ; + SHELL_SET ?= "set " ; # dwa 6/4/01 - removed compiler determination for boost # added some yacc/lex stuff, assuming cygwin for now. - LEX = flex ; - YACC = bison -t -d -l -v ; - YACCFILES = y.tab ; - YACC_OUTPUT = --output= ; - LEX_OUTPUT = -o ; + LEX ?= flex ; + YACC ?= bison -t -d -l -v ; + YACCFILES ?= y.tab ; + YACC_OUTPUT ?= --output= ; + LEX_OUTPUT ?= -o ; # YACC_FIX_LINES = sed '/simple/d ; # fix up #line directives for metrowerks } else if $(OS2) @@ -395,6 +396,7 @@ else if $(UNIX) YACCFILES ?= y.tab ; YACCFLAGS ?= -d ; SHELL_EXPORT ?= "export " ; + SHELL_SET ?= "" ; } # @@ -431,7 +433,8 @@ RSH ?= rsh ; SED ?= sed ; SHELLHEADER ?= "#!/bin/sh" ; SHELLMODE ?= 755 ; -SHELL_EXPORT ?= "" ; +SHELL_EXPORT ?= ; +SHELL_SET ?= "" ; SLASH ?= / ; SPLITPATH ?= ":" ; # dwa -- added missing SPLITPATH STDHDRS ?= /usr/include ; @@ -453,7 +456,7 @@ OSFULL = $(OS)$(OSVER)$(OSPLAT) $(OS)$(OSPLAT) $(OS)$(OSVER) $(OS) ; # # dwa 6/17/01 - added test -DEPENDS all : shell files lib dll exe obj test ; +DEPENDS all : shell files lib dll exe obj ; DEPENDS all shell files lib dll exe obj test : first ; NOTFILE all first shell files lib dll exe obj dirs clean uninstall test ; ALWAYS clean uninstall ; @@ -888,19 +891,26 @@ rule MakeLocate # We add directory-grist here so that implicitly-created directory # target names don't collide with user-specified targets. - Depends $(<) : $(>[1]:G=directory-grist) ; - MkDir $(>[1]:G=directory-grist) ; + Depends $(<) : [ MkDir $(>[1]:G=directory-grist) ] ; } } +# now returns the created directory target -- dwa rule MkDir { # If dir exists, don't update it # Do this even for $(DOT). - NOUPDATE $(<) ; + local dir = $(<) ; + if $(NT) + { + # make sure slashes all go the right way + dir = [ FDirName [ split-path $(dir) ] ] ; + } + + NOUPDATE $(dir) ; - if $(<) != $(DOT) && ! $($(<)-mkdir) + if $(dir) != $(DOT) && ! $($(dir)-mkdir) { local s ; @@ -908,14 +918,14 @@ rule MkDir # MkDir1 has the actions # Arrange for jam dirs - $(<)-mkdir = true ; - MkDir1 $(<) ; - Depends dirs : $(<) ; + $(dir)-mkdir = true ; + MkDir1 $(dir) ; + Depends dirs : $(dir) ; # Recursively make parent directories. - # $(<:P) = $(<)'s parent, & we recurse until root + # $(dir:P) = $(dir)'s parent, & we recurse until root - s = $(<:P) ; + s = $(dir:P) ; if $(NT) { @@ -926,9 +936,9 @@ rule MkDir } } - if $(s) && $(s) != $(<) + if $(s) && $(s) != $(dir) { - Depends $(<) : $(s) ; + Depends $(dir) : $(s) ; MkDir $(s) ; } else if $(s) @@ -937,6 +947,7 @@ rule MkDir } } + return $(dir) ; } # dwa 6/4/01 - modified for boost @@ -1118,6 +1129,23 @@ rule subinclude } } +# dwa 10/6/01 - added for boost +# +# path-global variable-name : path... ; +# +# if $(variable-name) is unset, sets variable-name to path... +# variable-name will be adjusted on a per-subproject basis to refer to the same path. +rule path-global +{ + $(<) ?= $(>) ; + gPATH_GLOBAL_VALUE($(<)) = $($(<)) ; + + if ! ( $(<) in $(gPATH_GLOBALS) ) + { + gPATH_GLOBALS += $(<) ; + } +} + # dwa 6/4/01 - modified for boost rule SubDir { @@ -1155,19 +1183,19 @@ rule SubDir # If $(TOP)/Jamrules hasn't been included, do so. # - if ! $(gINCLUDED($(<[1]))) + if ! $(gINCLUDED($(gTOP))) { # Gated entry. - gINCLUDED($(<[1])) = TRUE ; + gINCLUDED($(gTOP)) = TRUE ; # File is $(TOPRULES) or $(TOP)/Jamrules. - _r = $($(<[1])RULES) ; + _r = $($(gTOP)RULES) ; if ! $(_r) { - _r = $(JAMRULES:R=$($(<[1]))) ; + _r = $(JAMRULES:R=$($(gTOP))) ; } # Include it. @@ -1175,7 +1203,7 @@ rule SubDir include $(_r) ; # determine where toolset specifications and boost-base can be found. - BOOST_BUILD_INSTALLATION ?= $($(<[1])) ; + BOOST_BUILD_INSTALLATION ?= $($(gTOP)) ; # and include boost-base include [ join-path $(BOOST_BUILD_INSTALLATION) boost-base.jam ] ; @@ -1188,17 +1216,18 @@ rule SubDir # This allows us to determine whether we're in the directory where jam was # invoked from so that we can make locally named targets gINVOCATION_SUBDIR_TOKENS ?= $(SUBDIR_TOKENS) ; + gINVOCATION_SUBDIR_TOKENS ?= $(DOT) ; # SUBDIR is the path from the invocation directory to the subproject # directory. - SUBDIR = [ FDirName [ simplify-path-tokens $($(<[1])_TOKENS) $(SUBDIR_TOKENS) ] ] ; + SUBDIR = [ tokens-to-simple-path $($(gTOP)_TOKENS) $(SUBDIR_TOKENS) ] ; SEARCH_SOURCE = $(SUBDIR) ; # This will strip off any leading dot on SUBDIR_TOKENS local nodot_subdir = [ simplify-path-tokens $(SUBDIR_TOKENS) ] ; - ALL_LOCATE_TARGET ?= $($(<[1])) ; + ALL_LOCATE_TARGET ?= $($(gTOP)) ; LOCATE_SOURCE = [ FDirName $(ALL_LOCATE_TARGET) $(nodot_subdir) ] ; LOCATE_TARGET = $(LOCATE_SOURCE) ; @@ -1211,9 +1240,22 @@ rule SubDir # This variable holds the path from the directory of Jam's invocation to the # directory of the current subproject. - RELATIVE_SUBDIR_TOKENS = [ simplify-path-tokens $($(<[1])_TOKENS) $(SUBDIR_TOKENS) : $(DOT) ] ; + RELATIVE_SUBDIR_TOKENS = [ simplify-path-tokens $($(gTOP)_TOKENS) $(SUBDIR_TOKENS) : $(DOT) ] ; RELATIVE_SUBDIR = [ join-path $(RELATIVE_SUBDIR_TOKENS) ] ; + + adjust-path-globals ; } + +rule in-invocation-subdir +{ + local subdir-tokens = $(SUBDIR-TOKENS) ; + subdir-tokens ?= $(DOT) ; + if $(subdir-tokens) = $(gINVOCATION_SUBDIR_TOKENS) + { + return true ; + } +} + # These are the global variables that get set up by SubDir. If you need to # invoke SubDir temporarily and then restore them, declare # local $(gSUBDIR_GLOBALS) ; @@ -1221,6 +1263,62 @@ gSUBDIR_GLOBALS = SUBDIR SUBDIR_TOKENS SEARCH_SOURCE LOCATE_SOURCE LOCATE_TARGET SOURCE_GRIST RELATIVE_SUBDIR RELATIVE_SUBDIR_TOKENS ; +rule protect-subdir +{ + return $(gSUBDIR_GLOBALS) $(gPATH_GLOBALS) ; +} + +# prepends root to any unrooted elements of paths, and simplifies +rule root-paths # paths... : root +{ + local path result ; + for path in $(<) + { + local rooted = $(path:R=$(>)) ; + if $(rooted) != $(path) + { + path = [ tokens-to-simple-path [ split-path $(rooted) ] ] ; + path = $(path:G=$(rooted:G)) ; + } + result += $(path) ; + } + return $(result) ; +} + +# Adjust all path globals so that they are relative to the current subproject. +rule adjust-path-globals +{ + # compute path tokens from current subproject to root + local tokens-to-root = [ split-path [ FSubDir $(SUBDIR_TOKENS) ] ] ; + + # compute path tokens from current subproject to invocation + # directory. $(DOT) is added just in case we're building from the project + # root + local tokens-to-invocation + = $(tokens-to-root) $(gINVOCATION_SUBDIR_TOKENS) ; + + local variable ; + for variable in $(gPATH_GLOBALS) + { + local paths = $(gPATH_GLOBAL_VALUE($(variable))) ; + $(variable) = ; + local path ; + for path in $(paths) + { + # is path already rooted? + if $(path:R=x) = $(path) + { + $(variable) += $(path) ; + } + else + { + local tokens = $(tokens-to-invocation) [ split-path $(path) ] ; + $(variable) += [ tokens-to-simple-path $(tokens) ] ; + } + } + } +} + # dwa 6/4/01 - added for boost # strip-grist value # @@ -1388,6 +1486,10 @@ rule simplify-path-tokens return $(result) ; } +rule tokens-to-simple-path +{ + return [ FDirName [ simplify-path-tokens $(<) ] ] ; +} rule SubDirCcFlags { @@ -1420,6 +1522,9 @@ rule SubInclude _s = [ FDirName $(<[2-]) ] ; + # protect variables from being permanently set by SubDir invocations + # in included files. + local [ protect-subdir ] ; include $(JAMFILE:D=$(_s):R=$($(<[1]))) ; } diff --git a/v1/boost-base.jam b/v1/boost-base.jam index 9ea4988e2..c51d1198d 100644 --- a/v1/boost-base.jam +++ b/v1/boost-base.jam @@ -723,9 +723,9 @@ rule fixup-path-properties { local path-properties = [ get-properties $(gPATH_FEATURES) : $(<) ] ; local non-path = [ difference $(<) : $(path-properties) ] ; - if $(RELATIVE_SUBDIR) && ! $(path-properties:R) + if $(RELATIVE_SUBDIR) { - path-properties = $(path-properties:R=$(RELATIVE_SUBDIR)) ; + path-properties = [ root-paths $(path-properties) : $(RELATIVE_SUBDIR) ] ; } return $(path-properties) $(non-path) ; } @@ -1001,15 +1001,14 @@ rule dependent-include # rule to find it. local jamfile-path - = [ join-path - [ simplify-path-tokens - $(RELATIVE_SUBDIR_TOKENS) [ directory-of $(target) ] $(JAMFILE) ] ] ; + = [ tokens-to-simple-path + $(RELATIVE_SUBDIR_TOKENS) [ directory-of $(target) ] $(JAMFILE) ] ; if ! $(gINCLUDED($(jamfile-path))) { # protect variables from being permanently set by SubDir invocations # in included files. - local $(gSUBDIR_GLOBALS) ; + local [ protect-subdir ] ; # this stack allows us to avoid making dependee libraries part of # the "type" targets, e.g. all, exe, obj. See rule type-DEPENDS. @@ -1107,7 +1106,7 @@ rule link-libraries local new-subdir = TOP [ top-relative-tokens [ directory-of $(lib-path) ] ] ; # protect global variables from being permanently set by SubDir - local $(gSUBDIR_GLOBALS) ; + local [ protect-subdir ] ; # Enter the dependee subproject SubDir $(new-subdir) ; @@ -1166,7 +1165,7 @@ rule declare-fake-targets # The following checks that we're in the subdirectory of Jam's invocation # so that we can arrange for ungristed target names to be built from the # command-line. - if ( $(SUBDIR_TOKENS) = $(gINVOCATION_SUBDIR_TOKENS) ) + if [ in-invocation-subdir ] { DEPENDS $(<:G=) : $(<) ; # allows $(<:G=) to be used to build all variants NOTFILE $(<:G=) ;