diff --git a/.travis.yml b/.travis.yml index 8ecfd7418..9413d7206 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,21 +11,18 @@ matrix: include: - os: linux dist: trusty - env: TOOLSET=gcc TEST_ALL_EXTRAS= + env: TOOLSET=gcc - os: linux dist: trusty - env: TOOLSET=clang TEST_ALL_EXTRAS= + env: TOOLSET=clang - os: osx osx_image: xcode8.3 - env: TOOLSET=clang TEST_ALL_EXTRAS= - allow_failures: - - os: osx - osx_image: xcode8.3 - env: TOOLSET=clang TEST_ALL_EXTRAS= + env: TOOLSET=clang language: cpp script: + - cd src/engine + - ./build.sh + - cd ../.. - ./bootstrap.sh --with-toolset=${TOOLSET} - cd test - - DO_DIFF=diff python test_all.py ${TOOLSET} ${TEST_ALL_EXTRAS} - - DO_DIFF=diff python library_chain.py --verbose ${TOOLSET} ${TEST_ALL_EXTRAS} - - DO_DIFF=diff python searched_lib.py --verbose ${TOOLSET} ${TEST_ALL_EXTRAS} + - python test_all.py ${TOOLSET} diff --git a/appveyor.yml b/appveyor.yml index 72880b9df..4b0b6a4c2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -22,5 +22,4 @@ build_script: test_script: - cd test - - set DO_DIFF=1 - - python test_all.py msvc %TEST_ALL_EXTRAS% --preserve + - python test_all.py msvc diff --git a/src/build/configure.jam b/src/build/configure.jam index a177e78e6..78683d6a0 100644 --- a/src/build/configure.jam +++ b/src/build/configure.jam @@ -37,7 +37,7 @@ feature.feature configure : : composite optional ; # relevant features are also considered relevant. # feature.compose : - ; + ; rule log-summary ( ) diff --git a/src/build/virtual-target.jam b/src/build/virtual-target.jam index 264616db6..2d139bd7f 100644 --- a/src/build/virtual-target.jam +++ b/src/build/virtual-target.jam @@ -794,7 +794,9 @@ class action # rules. .action on $(actual-targets) = $(__name__) ; - indirect.call $(self.action-name) $(actual-targets) + #indirect.call $(self.action-name) $(actual-targets) + # : $(self.actual-sources) : [ $(properties).raw ] ; + execute $(self.action-name) $(actual-targets) : $(self.actual-sources) : [ $(properties).raw ] ; # Since we set up the creating action here, we set up the action for @@ -865,6 +867,19 @@ class action { return $(property-set) ; } + + # Execute the action rule on the given targets, sources, and properties. + # Since this does the final call to the engine action rule this takes + # engine level targets and raw properties. One could override this, for + # example, to set additional variables on hte target that might be + # difficult to determine just using toolset flags. + # Note, you must call this base rule when overriding as otherwise the + # actions will not execute and the engine will not run commands. + # + rule execute ( action-name targets + : sources * : properties * ) + { + indirect.call $(action-name) $(targets) : $(sources) : $(properties) ; + } } diff --git a/src/tools/builtin.jam b/src/tools/builtin.jam index 7fdc691e0..1c1614e2c 100644 --- a/src/tools/builtin.jam +++ b/src/tools/builtin.jam @@ -13,7 +13,7 @@ import alias ; import "class" : new ; import errors ; import feature ; -import features/__init__ ; +import features/__init_features__ ; import generators ; import numbers ; import os ; @@ -35,6 +35,10 @@ import virtual-target ; import message ; import convert ; +# Generators need the target types registered first. So this import needs +# to be after that. +import generators/__init_generators__ ; + # FIXME: the following generate module import is not needed here but removing it # too hastily will break using code (e.g. the main Boost library Jamroot file) # that forgot to import the generate module before calling the generate rule. @@ -48,221 +52,6 @@ variant release : speed off full variant profile : release : on on ; -class searched-lib-target : abstract-file-target -{ - rule __init__ ( name - : project - : shared ? - : search * - : action - ) - { - abstract-file-target.__init__ $(name) : SEARCHED_LIB : $(project) - : $(action) : ; - - self.shared = $(shared) ; - self.search = $(search) ; - } - - rule shared ( ) - { - return $(self.shared) ; - } - - rule search ( ) - { - return $(self.search) ; - } - - rule actualize-location ( target ) - { - NOTFILE $(target) ; - } - - rule path ( ) - { - } -} - - -# The generator class for libraries (target type LIB). Depending on properties -# it will request building of the appropriate specific library type -- -# -- SHARED_LIB, STATIC_LIB or SHARED_LIB. -# -class lib-generator : generator -{ - rule __init__ ( * : * ) - { - generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) - : $(9) : $(10) : $(11) : $(12) : $(13) : $(14) : $(15) : $(16) : - $(17) : $(18) : $(19) ; - } - - rule run ( project name ? : property-set : sources * ) - { - # The lib generator is composing, and can be only invoked with an - # explicit name. This check is present in generator.run (and so in - # builtin.linking-generator) but duplicated here to avoid doing extra - # work. - if $(name) - { - local properties = [ $(property-set).raw ] ; - # Determine the needed target type. - local actual-type ; - # files can be generated by @rule feature - # in which case we do not consider it a SEARCHED_LIB type. - if ! in $(properties:G) && - ( in $(properties:G) || in $(properties:G) ) - { - actual-type = SEARCHED_LIB ; - } - else if in $(properties:G) - { - actual-type = LIB ; - } - else if shared in $(properties) - { - actual-type = SHARED_LIB ; - } - else - { - actual-type = STATIC_LIB ; - } - property-set = [ $(property-set).add-raw LIB ] ; - # Construct the target. - return [ generators.construct $(project) $(name) : $(actual-type) - : $(property-set) : $(sources) ] ; - } - } - - rule viable-source-types ( ) - { - return * ; - } -} - - -generators.register [ new lib-generator builtin.lib-generator : : LIB ] ; - - -# The implementation of the 'lib' rule. Beyond standard syntax that rule allows -# simplified: "lib a b c ;". -# -rule lib ( names + : sources * : requirements * : default-build * : - usage-requirements * ) -{ - if $(names[2]) - { - if in $(requirements:G) - { - errors.user-error "When several names are given to the 'lib' rule" : - "it is not allowed to specify the feature." ; - } - if $(sources) - { - errors.user-error "When several names are given to the 'lib' rule" : - "it is not allowed to specify sources." ; - } - } - - # This is a circular module dependency so it must be imported here. - import targets ; - - local project = [ project.current ] ; - local result ; - - for local name in $(names) - { - local r = $(requirements) ; - # Support " lib a ; " and " lib a b c ; " syntax. - if ! $(sources) && ! in $(requirements:G) - && ! in $(requirements:G) - { - r += $(name) ; - } - result += [ targets.main-target-alternative - [ new typed-target $(name) : $(project) : LIB - : [ targets.main-target-sources $(sources) : $(name) ] - : [ targets.main-target-requirements $(r) : $(project) ] - : [ targets.main-target-default-build $(default-build) : $(project) ] - : [ targets.main-target-usage-requirements $(usage-requirements) : $(project) ] - ] ] ; - } - return $(result) ; -} -IMPORT $(__name__) : lib : : lib ; - - -class searched-lib-generator : generator -{ - import property-set ; - - rule __init__ ( ) - { - # The requirements cause the generators to be tried *only* when we are - # building a lib target with a 'search' feature. This seems ugly --- all - # we want is to make sure searched-lib-generator is not invoked deep - # inside transformation search to produce intermediate targets. - generator.__init__ searched-lib-generator : : SEARCHED_LIB ; - } - - rule run ( project name ? : property-set : sources * ) - { - if $(name) - { - # If 'name' is empty, it means we have not been called to build a - # top-level target. In this case, we just fail immediately, because - # searched-lib-generator cannot be used to produce intermediate - # targets. - - local properties = [ $(property-set).raw ] ; - local shared ; - if shared in $(properties) - { - shared = true ; - } - - local search = [ feature.get-values : $(properties) ] ; - - local a = [ new null-action $(property-set) ] ; - local lib-name = [ feature.get-values : $(properties) ] ; - lib-name ?= $(name) ; - local t = [ new searched-lib-target $(lib-name) : $(project) - : $(shared) : $(search) : $(a) ] ; - # We return sources for a simple reason. If there is - # lib png : z : png ; - # the 'z' target should be returned, so that apps linking to 'png' - # will link to 'z', too. - return [ property-set.create $(search) ] - [ virtual-target.register $(t) ] $(sources) ; - } - } -} - -generators.register [ new searched-lib-generator ] ; - - -class prebuilt-lib-generator : generator -{ - rule __init__ ( * : * ) - { - generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) - : $(9) : $(10) : $(11) : $(12) : $(13) : $(14) : $(15) : $(16) : - $(17) : $(18) : $(19) ; - } - - rule run ( project name ? : property-set : sources * ) - { - local f = [ $(property-set).get ] ; - return $(f) $(sources) ; - } -} - -generators.register - [ new prebuilt-lib-generator builtin.prebuilt : : LIB : ] ; - -generators.override builtin.prebuilt : builtin.lib-generator ; - class preprocessed-target-class : basic-target { import generators ; @@ -305,322 +94,3 @@ rule preprocessed ( name : sources * : requirements * : default-build * : } IMPORT $(__name__) : preprocessed : : preprocessed ; - -class compile-action : action -{ - import sequence ; - - rule __init__ ( targets * : sources * : action-name : properties * ) - { - action.__init__ $(targets) : $(sources) : $(action-name) : $(properties) ; - } - - # For all virtual targets for the same dependency graph as self, i.e. which - # belong to the same main target, add their directories to the include path. - # - rule adjust-properties ( property-set ) - { - local s = [ $(self.targets[1]).creating-subvariant ] ; - if $(s) - { - return [ $(property-set).add-raw - [ $(s).implicit-includes "include" : H ] ] ; - } - else - { - return $(property-set) ; - } - } -} - - -# Declare a special compiler generator. The only thing it does is changing the -# type used to represent 'action' in the constructed dependency graph to -# 'compile-action'. That class in turn adds additional include paths to handle -# cases when a source file includes headers which are generated themselves. -# -class C-compiling-generator : generator -{ - rule __init__ ( id : source-types + : target-types + : requirements * - : optional-properties * ) - { - generator.__init__ $(id) : $(source-types) : $(target-types) : - $(requirements) : $(optional-properties) ; - } - - rule action-class ( ) - { - return compile-action ; - } -} - - -rule register-c-compiler ( id : source-types + : target-types + : requirements * - : optional-properties * ) -{ - generators.register [ new C-compiling-generator $(id) : $(source-types) : - $(target-types) : $(requirements) : $(optional-properties) ] ; -} - -# FIXME: this is ugly, should find a better way (we would like client code to -# register all generators as "generators.some-rule" instead of -# "some-module.some-rule".) -# -IMPORT $(__name__) : register-c-compiler : : generators.register-c-compiler ; - - -# The generator class for handling EXE and SHARED_LIB creation. -# -class linking-generator : generator -{ - import path ; - import project ; - import property-set ; - import type ; - - rule __init__ ( id - composing ? : # The generator will be composing if a non-empty - # string is passed or the parameter is not given. To - # make the generator non-composing, pass an empty - # string (""). - source-types + : - target-types + : - requirements * ) - { - composing ?= true ; - generator.__init__ $(id) $(composing) : $(source-types) - : $(target-types) : $(requirements) ; - } - - rule run ( project name ? : property-set : sources + ) - { - sources += [ $(property-set).get ] ; - - # Add properties for all searched libraries. - local extra ; - for local s in $(sources) - { - if [ $(s).type ] = SEARCHED_LIB - { - local search = [ $(s).search ] ; - extra += $(search) ; - } - } - - # It is possible that sources include shared libraries that did not came - # from 'lib' targets, e.g. .so files specified as sources. In this case - # we have to add extra dll-path properties and propagate extra xdll-path - # properties so that application linking to us will get xdll-path to - # those libraries. - local extra-xdll-paths ; - for local s in $(sources) - { - if [ type.is-derived [ $(s).type ] SHARED_LIB ] && ! [ $(s).action ] - { - # Unfortunately, we do not have a good way to find the path to a - # file, so use this nasty approach. - # - # TODO: This needs to be done better. One thing that is really - # broken with this is that it does not work correctly with - # projects having multiple source locations. - local p = [ $(s).project ] ; - local location = [ path.root [ $(s).name ] - [ $(p).get source-location ] ] ; - extra-xdll-paths += [ path.parent $(location) ] ; - } - } - - # Hardcode DLL paths only when linking executables. - # Pros: do not need to relink libraries when installing. - # Cons: "standalone" libraries (plugins, python extensions) can not - # hardcode paths to dependent libraries. - if [ $(property-set).get ] = true - && [ type.is-derived $(self.target-types[1]) EXE ] - { - local xdll-path = [ $(property-set).get ] ; - extra += $(xdll-path) $(extra-xdll-paths) ; - } - - if $(extra) - { - property-set = [ $(property-set).add-raw $(extra) ] ; - } - - local result = [ generator.run $(project) $(name) : $(property-set) - : $(sources) ] ; - - local ur ; - if $(result) - { - ur = [ extra-usage-requirements $(result) : $(property-set) ] ; - ur = [ $(ur).add - [ property-set.create $(extra-xdll-paths) ] ] ; - } - return $(ur) $(result) ; - } - - rule extra-usage-requirements ( created-targets * : property-set ) - { - local result = [ property-set.empty ] ; - local extra ; - - # Add appropriate usage requirements. - local raw = [ $(property-set).raw ] ; - if shared in $(raw) - { - local paths ; - local pwd = [ path.pwd ] ; - for local t in $(created-targets) - { - if [ type.is-derived [ $(t).type ] SHARED_LIB ] - { - paths += [ path.root [ path.make [ $(t).path ] ] $(pwd) ] ; - } - } - extra += $(paths:G=) ; - } - - # We need to pass features that we've got from sources, - # because if a shared library is built, exe using it needs to know paths - # to other shared libraries this one depends on in order to be able to - # find them all at runtime. - - # Just pass all features in property-set, it is theoretically possible - # that we will propagate features explicitly specified by - # the user, but then the user is to blame for using an internal feature. - local values = [ $(property-set).get ] ; - extra += $(values:G=) ; - - if $(extra) - { - result = [ property-set.create $(extra) ] ; - } - return $(result) ; - } - - rule generated-targets ( sources + : property-set : project name ? ) - { - local sources2 ; # Sources to pass to inherited rule. - local properties2 ; # Properties to pass to inherited rule. - local libraries ; # Library sources. - - # Searched libraries are not passed as arguments to the linker but via - # some option. So, we pass them to the action using a property. - properties2 = [ $(property-set).raw ] ; - local fsa ; - local fst ; - for local s in $(sources) - { - if [ type.is-derived [ $(s).type ] SEARCHED_LIB ] - { - local name = [ $(s).name ] ; - if [ $(s).shared ] - { - fsa += $(name) ; - } - else - { - fst += $(name) ; - } - } - else - { - sources2 += $(s) ; - } - } - properties2 += $(fsa:J=&&) - $(fst:J=&&) ; - - return [ generator.generated-targets $(sources2) - : [ property-set.create $(properties2) ] : $(project) $(name) ] ; - } -} - - -rule register-linker ( id composing ? : source-types + : target-types + - : requirements * ) -{ - generators.register [ new linking-generator $(id) $(composing) - : $(source-types) : $(target-types) : $(requirements) ] ; -} - - -# The generator class for handling STATIC_LIB creation. -# -class archive-generator : generator -{ - import property-set ; - - rule __init__ ( id composing ? : source-types + : target-types + - : requirements * ) - { - composing ?= true ; - generator.__init__ $(id) $(composing) : $(source-types) - : $(target-types) : $(requirements) ; - } - - rule run ( project name ? : property-set : sources + ) - { - sources += [ $(property-set).get ] ; - - local result = [ generator.run $(project) $(name) : $(property-set) - : $(sources) ] ; - - # For static linking, if we get a library in source, we can not directly - # link to it so we need to cause our dependencies to link to that - # library. There are two approaches: - # - adding the library to the list of returned targets. - # - using the usage requirements. - # The problem with the first is: - # - # lib a1 : : liba1.a ; - # lib a2 : a2.cpp a1 : static ; - # install dist : a2 ; - # - # here we will try to install 'a1', even though it is not necessary in - # the general case. With the second approach, even indirect dependants - # will link to the library, but it should not cause any harm. So, return - # all LIB sources together with created targets, so that dependants link - # to them. - local usage-requirements ; - if [ $(property-set).get ] = static - { - for local t in $(sources) - { - if [ type.is-derived [ $(t).type ] LIB ] - { - usage-requirements += $(t) ; - } - } - } - - usage-requirements = [ property-set.create $(usage-requirements) ] ; - - return $(usage-requirements) $(result) ; - } -} - - -rule register-archiver ( id composing ? : source-types + : target-types + - : requirements * ) -{ - generators.register [ new archive-generator $(id) $(composing) - : $(source-types) : $(target-types) : $(requirements) ] ; -} - - -# Generator that accepts everything and produces nothing. Useful as a general -# fallback for toolset-specific actions like PCH generation. -# -class dummy-generator : generator -{ - import property-set ; - - rule run ( project name ? : property-set : sources + ) - { - return [ property-set.empty ] ; - } -} - -IMPORT $(__name__) : register-linker register-archiver - : : generators.register-linker generators.register-archiver ; diff --git a/src/tools/clang-darwin.jam b/src/tools/clang-darwin.jam index 8d41916b8..a11b98398 100644 --- a/src/tools/clang-darwin.jam +++ b/src/tools/clang-darwin.jam @@ -66,8 +66,15 @@ rule init ( version ? : command * : options * ) common.handle-options clang-darwin : $(condition) : $(command) : $(options) ; - gcc.init-link-flags clang-darwin darwin $(condition) ; + gcc.init-link-flags clang darwin $(condition) ; + # - Ranlib. + local ranlib = [ feature.get-values : $(options) ] ; + toolset.flags clang-darwin.archive .RANLIB $(condition) : $(ranlib[1]) ; + + # - Archive builder. + local archiver = [ feature.get-values : $(options) ] ; + toolset.flags clang-darwin.archive .AR $(condition) : $(archiver[1]) ; } SPACE = " " ; @@ -128,6 +135,7 @@ flags clang-darwin ARFLAGS ; # logic in clang-linux, but that's hardly worth the trouble # as on Linux, 'ar' is always available. .AR = ar ; +.RANLIB = ranlib -cs ; rule archive ( targets * : sources * : properties * ) { @@ -161,7 +169,7 @@ rule archive ( targets * : sources * : properties * ) actions piecemeal archive { "$(.AR)" $(AROPTIONS) rc "$(<)" "$(>)" - "ranlib" -cs "$(<)" + "$(.RANLIB)" "$(<)" } flags clang-darwin.link USER_OPTIONS ; diff --git a/src/tools/clang-linux.jam b/src/tools/clang-linux.jam index f977c8c72..7bf112ae2 100644 --- a/src/tools/clang-linux.jam +++ b/src/tools/clang-linux.jam @@ -60,7 +60,15 @@ rule init ( version ? : command * : options * ) { common.handle-options clang-linux : $(condition) : $(command) : $(options) ; - gcc.init-link-flags clang-linux gnu $(condition) ; + gcc.init-link-flags clang linux $(condition) ; + + # - Ranlib. + local ranlib = [ feature.get-values : $(options) ] ; + toolset.flags clang-linux.archive .RANLIB $(condition) : $(ranlib[1]) ; + + # - Archive builder. + local archiver = [ feature.get-values : $(options) ] ; + toolset.flags clang-linux.archive .AR $(condition) : $(archiver[1]) ; } ############################################################################### @@ -92,10 +100,6 @@ toolset.flags clang-linux.compile OPTIONS off : -fno-rtti ; # C and C++ compilation rule compile.c++ ( targets * : sources * : properties * ) { - setup-threading $(targets) : $(sources) : $(properties) ; - gcc.setup-fpic $(targets) : $(sources) : $(properties) ; - gcc.setup-address-model $(targets) : $(sources) : $(properties) ; - local pth-file = [ on $(<) return $(PCH_FILE) ] ; if $(pth-file) { @@ -118,10 +122,6 @@ actions compile.c++.with-pch bind PCH_FILE rule compile.c ( targets * : sources * : properties * ) { - setup-threading $(targets) : $(sources) : $(properties) ; - gcc.setup-fpic $(targets) : $(sources) : $(properties) ; - gcc.setup-address-model $(targets) : $(sources) : $(properties) ; - local pth-file = [ on $(<) return $(PCH_FILE) ] ; if $(pth-file) { @@ -147,9 +147,6 @@ actions compile.c.with-pch bind PCH_FILE # PCH emission rule compile.c++.pch ( targets * : sources * : properties * ) { - setup-threading $(targets) : $(sources) : $(properties) ; - gcc.setup-fpic $(targets) : $(sources) : $(properties) ; - gcc.setup-address-model $(targets) : $(sources) : $(properties) ; } actions compile.c++.pch { @@ -157,9 +154,6 @@ actions compile.c++.pch { } rule compile.c.pch ( targets * : sources * : properties * ) { - setup-threading $(targets) : $(sources) : $(properties) ; - gcc.setup-fpic $(targets) : $(sources) : $(properties) ; - gcc.setup-address-model $(targets) : $(sources) : $(properties) ; } actions compile.c.pch @@ -173,8 +167,6 @@ actions compile.c.pch SPACE = " " ; rule link ( targets * : sources * : properties * ) { - setup-threading $(targets) : $(sources) : $(properties) ; - gcc.setup-address-model $(targets) : $(sources) : $(properties) ; SPACE on $(targets) = " " ; JAM_SEMAPHORE on $(targets) = clang-linux-link-semaphore ; } @@ -184,29 +176,10 @@ actions link bind LIBRARIES { } rule link.dll ( targets * : sources * : properties * ) { - setup-threading $(targets) : $(sources) : $(properties) ; - gcc.setup-address-model $(targets) : $(sources) : $(properties) ; SPACE on $(targets) = " " ; JAM_SEMAPHORE on $(targets) = clang-linux-link-semaphore ; } -rule setup-threading ( targets * : sources * : properties * ) -{ - - local target = [ feature.get-values target-os : $(properties) ] ; - - switch $(target) - { - case windows : - local threading = [ feature.get-values threading : $(properties) ] ; - if $(threading) = multi - { - OPTIONS on $(targets) += -pthread ; - } - case * : gcc.setup-threading $(targets) : $(sources) : $(properties) ; - } -} - # Differ from 'link' above only by -shared. actions link.dll bind LIBRARIES { "$(CONFIG_COMMAND)" -L"$(LINKPATH)" -Wl,-R$(SPACE)-Wl,"$(RPATH)" -o "$(<)" -Wl,-soname$(SPACE)-Wl,$(<[1]:D=) -shared $(START-GROUP) "$(>)" "$(LIBRARIES)" $(FINDLIBS-ST-PFX) -l$(FINDLIBS-ST) $(FINDLIBS-SA-PFX) -l$(FINDLIBS-SA) $(END-GROUP) $(OPTIONS) $(USER_OPTIONS) diff --git a/src/tools/common.jam b/src/tools/common.jam index e1af5f0b0..94aacbc23 100644 --- a/src/tools/common.jam +++ b/src/tools/common.jam @@ -208,6 +208,13 @@ rule check-init-parameters ( toolset requirement * : * ) } sig = $(sig)$(value:E="")- ; } + # We also need to consider requirements on the toolset as we can + # configure the same toolset multiple times with different options that + # are selected with the requirements. + if $(requirement) + { + sig = $(sig)$(requirement:J=,) ; + } if $(sig) in $(.all-signatures) { local message = diff --git a/src/tools/darwin.jam b/src/tools/darwin.jam index a610603f0..1760a1986 100644 --- a/src/tools/darwin.jam +++ b/src/tools/darwin.jam @@ -516,20 +516,10 @@ rule setup-address-model ( targets * : sources * : properties * ) } } -rule setup-threading ( targets * : sources * : properties * ) -{ - gcc.setup-threading $(targets) : $(sources) : $(properties) ; -} - -rule setup-fpic ( targets * : sources * : properties * ) -{ - gcc.setup-fpic $(targets) : $(sources) : $(properties) ; -} - rule compile.m ( targets * : sources * : properties * ) { LANG on $(<) = "-x objective-c" ; - gcc.setup-fpic $(targets) : $(sources) : $(properties) ; + gcc.set-fpic-options $(targets) : $(sources) : $(properties) ; setup-address-model $(targets) : $(sources) : $(properties) ; } @@ -541,7 +531,7 @@ actions compile.m rule compile.mm ( targets * : sources * : properties * ) { LANG on $(<) = "-x objective-c++" ; - gcc.setup-fpic $(targets) : $(sources) : $(properties) ; + gcc.set-fpic-options $(targets) : $(sources) : $(properties) ; setup-address-model $(targets) : $(sources) : $(properties) ; } diff --git a/src/tools/features/__init__.jam b/src/tools/features/__init_features__.jam similarity index 53% rename from src/tools/features/__init__.jam rename to src/tools/features/__init_features__.jam index a98ca6dc5..aedf3e1dc 100644 --- a/src/tools/features/__init__.jam +++ b/src/tools/features/__init_features__.jam @@ -3,19 +3,21 @@ # (See accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) -# Here we automatically define any feature modules in this directory. +# Here we automatically define any "feature" modules in this directory. + +local key = feature ; import os path modules ; .this-module's-file = [ modules.binding $(__name__) ] ; .this-module's-dir = [ path.parent [ path.make $(.this-module's-file) ] ] ; -.feature-jamfiles = [ path.glob $(.this-module's-dir) : *-feature.jam ] ; -.feature-modules = [ MATCH ^(.*)\.jam$ : $(.feature-jamfiles) ] ; +.to-load-jamfiles = [ path.glob $(.this-module's-dir) : *-$(key).jam ] ; +.to-load-modules = [ MATCH ^(.*)\.jam$ : $(.to-load-jamfiles) ] ; -# A loop over all feature modules in this directory -for local m in $(.feature-modules) +# A loop over all matched modules in this directory +for local m in $(.to-load-modules) { m = [ path.basename $(m) ] ; - m = features/$(m) ; + m = $(key)s/$(m) ; import $(m) ; } diff --git a/src/tools/gcc.jam b/src/tools/gcc.jam index 9d8d39bf6..007332bb5 100644 --- a/src/tools/gcc.jam +++ b/src/tools/gcc.jam @@ -1,5 +1,5 @@ # Copyright 2001 David Abrahams -# Copyright 2002-2006 Rene Rivera +# Copyright 2002-2017 Rene Rivera # Copyright 2002-2003 Vladimir Prus # Copyright 2005 Reece H. Dunn # Copyright 2006 Ilya Sokolov @@ -26,6 +26,7 @@ import set ; import toolset ; import type ; import unix ; +import virtual-target ; if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ] @@ -68,7 +69,7 @@ type.set-generated-target-suffix OBJ : gcc cygwin : o ; # version. # 3) Without user-provided restrictions use default 'g++'. # -rule init ( version ? : command * : options * ) +rule init ( version ? : command * : options * : requirement * ) { #1): use user-provided command local tool-command = ; @@ -195,25 +196,12 @@ rule init ( version ? : command * : options * ) { condition = flavor $(flavor) ; } - condition = [ common.check-init-parameters gcc : version $(version) + condition = [ common.check-init-parameters gcc $(requirement) : version $(version) : $(condition) ] ; common.handle-options gcc : $(condition) : $(command) : $(options) ; - local linker = [ feature.get-values : $(options) ] ; - # TODO: The logic below should actually be keyed on . - if ! $(linker) - { - switch [ os.name ] - { - case OSF : linker = osf ; - case HPUX : linker = hpux ; - case AIX : linker = aix ; - case SOLARIS : linker = sun ; - case * : linker = gnu ; - } - } - init-link-flags gcc $(linker) $(condition) ; + init-link-flags gcc "" $(condition) ; # If gcc is installed in a non-standard location, we would need to add # LD_LIBRARY_PATH when running programs created with it (for unit-test/run @@ -277,6 +265,8 @@ rule init ( version ? : command * : options * ) rc-type = null ; } rc.configure $(rc) : $(condition) : $(rc-type) ; + + toolset.flags gcc VERSION $(condition) : [ regex.split $(version) "[.]" ] ; } if [ os.name ] = NT @@ -296,19 +286,375 @@ rule .get-prog-name ( command-string : tool : flavor ? ) if !($(flavor) = vxworks || $(flavor) = mingw) && [ os.name ] = NT { - prog-name = [ cygwin.cygwin-to-windows-path $(prog-name) ] ; + prog-name = [ cygwin.cygwin-to-windows-path $(prog-name) ] ; } return $(prog-name) ; } -generators.register-c-compiler gcc.compile.c++.preprocess : CPP : PREPROCESSED_CPP : gcc ; -generators.register-c-compiler gcc.compile.c.preprocess : C : PREPROCESSED_C : gcc ; -generators.register-c-compiler gcc.compile.c++ : CPP : OBJ : gcc ; -generators.register-c-compiler gcc.compile.c : C : OBJ : gcc ; -generators.register-c-compiler gcc.compile.asm : ASM : OBJ : gcc ; -generators.register-fortran-compiler gcc.compile.fortran : FORTRAN FORTRAN90 : OBJ : gcc ; +### +### Functions that set options on the targets. +### -# pch support +rule set-fpic-options ( targets * : sources * : properties * ) +{ + local link = [ feature.get-values link : $(properties) ] ; + if $(link) = shared + { + local target-os = [ feature.get-values target-os : $(properties) ] ; + + # This logic will add -fPIC for all compilations: + # + # lib a : a.cpp b ; + # obj b : b.cpp ; + # exe c : c.cpp a d ; + # obj d : d.cpp ; + # + # This all is fine, except that 'd' will be compiled with -fPIC even + # though it is not needed, as 'd' is used only in exe. However, it is + # hard to detect where a target is going to be used. Alternatively, we + # can set -fPIC only when main target type is LIB but than 'b' would be + # compiled without -fPIC which would lead to link errors on x86-64. So, + # compile everything with -fPIC. + # + # Yet another alternative would be to create a propagated + # feature and set it when building shared libraries, but that would be + # hard to implement and would increase the target path length even more. + + # On Windows, fPIC is the default, and specifying -fPIC explicitly leads + # to a warning. + if ! $(target-os) in cygwin windows + { + OPTIONS on $(targets) += -fPIC ; + } + } +} + +rule set-address-model-options ( targets * : sources * : properties * ) +{ + local model = [ feature.get-values address-model : $(properties) ] ; + if $(model) + { + local option ; + local target-os = [ feature.get-values target-os : $(properties) ] ; + if $(target-os) = aix + { + if $(model) = 32 + { + option = -maix32 ; + } + else + { + option = -maix64 ; + } + } + else if $(target-os) = hpux + { + if $(model) = 32 + { + option = -milp32 ; + } + else + { + option = -mlp64 ; + } + } + else + { + local arch = [ feature.get-values architecture : $(properties) ] ; + if $(arch) = power || $(arch) = sparc || $(arch) = x86 + { + if $(model) = 32 + { + option = -m32 ; + } + else if $(model) = 64 + { + option = -m64 ; + } + } + # For darwin, the model can be 32_64. darwin.jam will handle that + # on its own. + } + OPTIONS on $(targets) += $(option) ; + } +} + +rule set-threading-options ( targets * : sources * : properties * ) +{ + local threading = [ feature.get-values threading : $(properties) ] ; + if $(threading) = multi + { + local target-os = [ feature.get-values target-os : $(properties) ] ; + local host-os = [ feature.get-values host-os : $(properties) ] ; + local toolset = [ feature.get-values toolset : $(properties) ] ; + local option ; + local libs ; + + if $(toolset) = clang && $(target-os) = windows + { + option = -pthread ; + } + + switch $(target-os) + { + case android : # No threading options, everything is in already. + case windows : option ?= -mthreads ; + case cygwin : option ?= -mthreads ; + case solaris : option ?= -pthreads ; libs = rt ; + case beos : # No threading options. + case haiku : # No threading options. + case *bsd : option ?= -pthread ; # There is no -lrt on BSD. + case sgi : # gcc on IRIX does not support multi-threading. + case darwin : # No threading options. + case vxworks : # No threading options. + case * : option ?= -pthread ; libs = rt ; + } + if $(option) + { + OPTIONS on $(targets) += $(option) ; + } + if $(libs) + { + FINDLIBS-SA on $(targets) += $(libs) ; + } + } +} + +local rule zero-pad ( numbers * ) +{ + local result ; + for local n in $(numbers) + { + switch $(n) + { + case ???? : result += $(n) ; + case ??? : result += 0$(n) ; + case ?? : result += 00$(n) ; + case ? : result += 000$(n) ; + } + } + return $(result) ; +} + +rule set-cxxstd-options ( targets * : sources * : properties * ) +{ + local toolset = [ feature.get-values toolset : $(properties) ] ; + local version = [ zero-pad [ on $(targets[1]) return $(VERSION) ] ] ; + version = $(version[1]).$(version[2]) ; + local cxxstd = [ feature.get-values cxxstd : $(properties) ] ; + local cxxstd-dialect = [ feature.get-values cxxstd-dialect : $(properties) ] ; + cxxstd-dialect ?= c++ ; + local option ; + if $(toolset) = gcc + { + switch $(cxxstd) + { + case 98 : if $(version) >= 0003.0003 { option = 98 ; } + case 03 : if $(version) >= 0004.0008 { option = 03 ; } + + case 11 : if $(version) >= 0004.0007 { option = 11 ; } + case 0x : if $(version) >= 0004.0003 { option = 0x ; } + + case 14 : if $(version) >= 0005.0001 { option = 14 ; } + case 1y : if $(version) >= 0004.0008 { option = 1y ; } + + case 17 : if $(version) >= 0005.0001 { option = 1z ; } + case 1z : if $(version) >= 0005.0001 { option = 1z ; } + + case 2a : if $(version) >= 0008.0000 { option = 2a ; } + case latest : + if $(version) >= 0008.0000 { option = 2a ; } + else if $(version) >= 0005.0001 { option = 1z ; } + else if $(version) >= 0004.0008 { option = 1y ; } + else if $(version) >= 0004.0007 { option = 11 ; } + else if $(version) >= 0003.0003 { option = 98 ; } + } + } + if $(toolset) = clang + { + switch $(cxxstd) + { + case 98 : option = 98 ; + case 03 : option = 03 ; + + case 11 : if $(version) >= 0003.0003 { option = 11 ; } + case 0x : if $(version) >= 0002.0009 { option = 0x ; } + + case 14 : if $(version) >= 0003.0004 { option = 14 ; } + case 1y : if $(version) >= 0002.0009 { option = 1y ; } + + case 17 : if $(version) >= 0003.0005 { option = 1z ; } + case 1z : if $(version) >= 0003.0005 { option = 1z ; } + + case 2a : option = 2a ; + case latest : + if $(version) >= 0003.0005 { option = 1z ; } + if $(version) >= 0003.0004 { option = 14 ; } + if $(version) >= 0003.0003 { option = 11 ; } + option ?= 03 ; + } + } + if $(cxxstd) && ! $(option) + { + ECHO Warning: cxxstd value \"$(cxxstd)\" not supported by + $(toolset) [ on $(targets[1]) return $(VERSION:J=.) ] ; + option = -invalid ; + } + OPTIONS on $(targets) += -std=$(cxxstd-dialect)$(option) ; +} + +### +### Compiling generators and actions. +### + +class gcc-c-compiling-generator : C-compiling-generator +{ + rule action-class ( ) + { + return gcc-c-compile-action ; + } +} + +class gcc-c-compile-action : compile-action +{ + import gcc ; + + rule execute ( action-name targets + : sources * : properties * ) + { + gcc.set-threading-options $(targets) : $(sources) : $(properties) ; + gcc.set-fpic-options $(targets) : $(sources) : $(properties) ; + gcc.set-address-model-options $(targets) : $(sources) : $(properties) ; + gcc.set-cxxstd-options $(targets) : $(sources) : $(properties) ; + compile-action.execute $(action-name) $(targets) : $(sources) : $(properties) ; + } +} + +local rule register-gcc-c-compiler ( id : source-types + : target-types + : requirements * + : optional-properties * ) +{ + generators.register [ new gcc-c-compiling-generator $(id) : $(source-types) : + $(target-types) : $(requirements) : $(optional-properties) ] ; +} + +register-gcc-c-compiler gcc.compile.c++.preprocess : CPP : PREPROCESSED_CPP : gcc ; +register-gcc-c-compiler gcc.compile.c.preprocess : C : PREPROCESSED_C : gcc ; +register-gcc-c-compiler gcc.compile.c++ : CPP : OBJ : gcc ; +register-gcc-c-compiler gcc.compile.c : C : OBJ : gcc ; +register-gcc-c-compiler gcc.compile.asm : ASM : OBJ : gcc ; + +class gcc-fortran-compiling-generator : fortran-compiling-generator +{ + rule action-class ( ) + { + return gcc-fortran-compile-action ; + } +} + +class gcc-fortran-compile-action : compile-action +{ + import gcc ; + + rule execute ( action-name targets + : sources * : properties * ) + { + gcc.set-threading-options $(targets) : $(sources) : $(properties) ; + gcc.set-fpic-options $(targets) : $(sources) : $(properties) ; + gcc.set-address-model-options $(targets) : $(sources) : $(properties) ; + gcc.set-cxxstd-options $(targets) : $(sources) : $(properties) ; + compile-action.execute $(action-name) $(targets) : $(sources) : $(properties) ; + } +} + +generators.register [ new gcc-fortran-compiling-generator + gcc.compile.fortran : FORTRAN FORTRAN90 : OBJ : gcc ] ; + +rule compile.c++.preprocess ( targets * : sources * : properties * ) +{ + # Some extensions are compiled as C++ by default. For others, we need to + # pass -x c++. We could always pass -x c++ but distcc does not work with it. + if ! $(>:S) in .cc .cp .cxx .cpp .c++ .C + { + LANG on $(<) = "-x c++" ; + } + DEPENDS $(<) : [ on $(<) return $(PCH_FILE) ] ; +} + +rule compile.c.preprocess ( targets * : sources * : properties * ) +{ + # If we use the name g++ then default file suffix -> language mapping does + # not work. So have to pass -x option. Maybe, we can work around this by + # allowing the user to specify both C and C++ compiler names. + #if $(>:S) != .c + #{ + LANG on $(<) = "-x c" ; + #} + DEPENDS $(<) : [ on $(<) return $(PCH_FILE) ] ; +} + +rule compile.c++ ( targets * : sources * : properties * ) +{ + # Some extensions are compiled as C++ by default. For others, we need to + # pass -x c++. We could always pass -x c++ but distcc does not work with it. + if ! $(>:S) in .cc .cp .cxx .cpp .c++ .C + { + LANG on $(<) = "-x c++" ; + } + DEPENDS $(<) : [ on $(<) return $(PCH_FILE) ] ; +} + +rule compile.c ( targets * : sources * : properties * ) +{ + # If we use the name g++ then default file suffix -> language mapping does + # not work. So have to pass -x option. Maybe, we can work around this by + # allowing the user to specify both C and C++ compiler names. + #if $(>:S) != .c + #{ + LANG on $(<) = "-x c" ; + #} + DEPENDS $(<) : [ on $(<) return $(PCH_FILE) ] ; +} + +rule compile.fortran ( targets * : sources * : properties * ) +{ +} + +actions compile.c++ bind PCH_FILE +{ + "$(CONFIG_COMMAND)" $(LANG) -ftemplate-depth-$(TEMPLATE_DEPTH) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" -c -o "$(<:W)" "$(>:W)" +} + +actions compile.c bind PCH_FILE +{ + "$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" -c -o "$(<)" "$(>)" +} + +actions compile.c++.preprocess bind PCH_FILE +{ + "$(CONFIG_COMMAND)" $(LANG) -ftemplate-depth-$(TEMPLATE_DEPTH) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" "$(>:W)" -E >"$(<:W)" +} + +actions compile.c.preprocess bind PCH_FILE +{ + "$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" "$(>)" -E >$(<) +} + +actions compile.fortran +{ + "$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" -c -o "$(<)" "$(>)" +} + +rule compile.asm ( targets * : sources * : properties * ) +{ + LANG on $(<) = "-x assembler-with-cpp" ; +} + +actions compile.asm +{ + "$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)" +} + +### +### Preconpiled header use and generation. +### # The compiler looks for a precompiled header in each directory just before it # looks for the include file in that directory. The name searched for is the @@ -369,6 +715,25 @@ class gcc-pch-generator : pch-generator return [ generator.generated-targets $(sources) : $(property-set) : $(project) $(name) ] ; } + + rule action-class ( ) + { + return gcc-pch-compile-action ; + } +} + +class gcc-pch-compile-action : compile-action +{ + import gcc ; + + rule execute ( action-name targets + : sources * : properties * ) + { + gcc.set-threading-options $(targets) : $(sources) : $(properties) ; + gcc.set-fpic-options $(targets) : $(sources) : $(properties) ; + gcc.set-address-model-options $(targets) : $(sources) : $(properties) ; + gcc.set-cxxstd-options $(targets) : $(sources) : $(properties) ; + compile-action.execute $(action-name) $(targets) : $(sources) : $(properties) ; + } } # Note: the 'H' source type will catch both '.h' header and '.hpp' header. The @@ -383,6 +748,28 @@ generators.override gcc.compile.c++.pch : pch.default-cpp-pch-generator ; toolset.flags gcc.compile PCH_FILE on : ; +rule compile.c++.pch ( targets * : sources * : properties * ) +{ +} + +actions compile.c++.pch +{ + "$(CONFIG_COMMAND)" -x c++-header $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)" +} + +rule compile.c.pch ( targets * : sources * : properties * ) +{ +} + +actions compile.c.pch +{ + "$(CONFIG_COMMAND)" -x c-header $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)" +} + +### +### General options, like optimization. +### + # Declare flags and action for compilation. toolset.flags gcc.compile OPTIONS off : -O0 ; toolset.flags gcc.compile OPTIONS speed : -O3 ; @@ -402,109 +789,10 @@ toolset.flags gcc.compile OPTIONS on : -pg ; toolset.flags gcc.compile.c++ OPTIONS off : -fno-rtti ; toolset.flags gcc.compile.c++ OPTIONS off : -fno-exceptions ; -# tell Dinkum STL exceptions are off -toolset.flags gcc.compile.c++ DEFINES off/vxworks : _NO_EX=1 ; -rule setup-fpic ( targets * : sources * : properties * ) -{ - local link = [ feature.get-values link : $(properties) ] ; - if $(link) = shared - { - local target = [ feature.get-values target-os : $(properties) ] ; - - # This logic will add -fPIC for all compilations: - # - # lib a : a.cpp b ; - # obj b : b.cpp ; - # exe c : c.cpp a d ; - # obj d : d.cpp ; - # - # This all is fine, except that 'd' will be compiled with -fPIC even - # though it is not needed, as 'd' is used only in exe. However, it is - # hard to detect where a target is going to be used. Alternatively, we - # can set -fPIC only when main target type is LIB but than 'b' would be - # compiled without -fPIC which would lead to link errors on x86-64. So, - # compile everything with -fPIC. - # - # Yet another alternative would be to create a propagated - # feature and set it when building shared libraries, but that would be - # hard to implement and would increase the target path length even more. - - # On Windows, fPIC is the default, and specifying -fPIC explicitly leads - # to a warning. - if ! $(target) in cygwin windows - { - OPTIONS on $(targets) += -fPIC ; - } - } -} - -rule setup-address-model ( targets * : sources * : properties * ) -{ - local model = [ feature.get-values address-model : $(properties) ] ; - if $(model) - { - local option ; - local os = [ feature.get-values target-os : $(properties) ] ; - if $(os) = aix - { - if $(model) = 32 - { - option = -maix32 ; - } - else - { - option = -maix64 ; - } - } - else if $(os) = hpux - { - if $(model) = 32 - { - option = -milp32 ; - } - else - { - option = -mlp64 ; - } - } - else - { - local arch = [ feature.get-values architecture : $(properties) ] ; - if $(arch) = power || $(arch) = sparc || $(arch) = x86 - { - if $(model) = 32 - { - option = -m32 ; - } - else if $(model) = 64 - { - option = -m64 ; - } - } - # For darwin, the model can be 32_64. darwin.jam will handle that - # on its own. - } - OPTIONS on $(targets) += $(option) ; - } -} - - -# FIXME: this should not use os.name. -if ! [ os.name ] in NT OSF HPUX AIX -{ - # OSF does have an option called -soname but it does not seem to work as - # expected, therefore it has been disabled. - HAVE_SONAME = "" ; - SONAME_OPTION = -h ; -} - -# HPUX, for some reason, seems to use '+h' instead of '-h'. -if [ os.name ] = HPUX -{ - HAVE_SONAME = "" ; - SONAME_OPTION = +h ; -} +### +### User free feature options. +### toolset.flags gcc.compile USER_OPTIONS ; toolset.flags gcc.compile.c++ USER_OPTIONS ; @@ -513,135 +801,9 @@ toolset.flags gcc.compile INCLUDES ; toolset.flags gcc.compile.c++ TEMPLATE_DEPTH ; toolset.flags gcc.compile.fortran USER_OPTIONS ; -rule compile.c++.pch ( targets * : sources * : properties * ) -{ - setup-threading $(targets) : $(sources) : $(properties) ; - setup-fpic $(targets) : $(sources) : $(properties) ; - setup-address-model $(targets) : $(sources) : $(properties) ; -} - -actions compile.c++.pch -{ - "$(CONFIG_COMMAND)" -x c++-header $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)" -} - -rule compile.c.pch ( targets * : sources * : properties * ) -{ - setup-threading $(targets) : $(sources) : $(properties) ; - setup-fpic $(targets) : $(sources) : $(properties) ; - setup-address-model $(targets) : $(sources) : $(properties) ; -} - -actions compile.c.pch -{ - "$(CONFIG_COMMAND)" -x c-header $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)" -} - -rule compile.c++.preprocess ( targets * : sources * : properties * ) -{ - setup-threading $(targets) : $(sources) : $(properties) ; - setup-fpic $(targets) : $(sources) : $(properties) ; - setup-address-model $(targets) : $(sources) : $(properties) ; - - # Some extensions are compiled as C++ by default. For others, we need to - # pass -x c++. We could always pass -x c++ but distcc does not work with it. - if ! $(>:S) in .cc .cp .cxx .cpp .c++ .C - { - LANG on $(<) = "-x c++" ; - } - DEPENDS $(<) : [ on $(<) return $(PCH_FILE) ] ; -} - -rule compile.c.preprocess ( targets * : sources * : properties * ) -{ - setup-threading $(targets) : $(sources) : $(properties) ; - setup-fpic $(targets) : $(sources) : $(properties) ; - setup-address-model $(targets) : $(sources) : $(properties) ; - - # If we use the name g++ then default file suffix -> language mapping does - # not work. So have to pass -x option. Maybe, we can work around this by - # allowing the user to specify both C and C++ compiler names. - #if $(>:S) != .c - #{ - LANG on $(<) = "-x c" ; - #} - DEPENDS $(<) : [ on $(<) return $(PCH_FILE) ] ; -} - -rule compile.c++ ( targets * : sources * : properties * ) -{ - setup-threading $(targets) : $(sources) : $(properties) ; - setup-fpic $(targets) : $(sources) : $(properties) ; - setup-address-model $(targets) : $(sources) : $(properties) ; - - # Some extensions are compiled as C++ by default. For others, we need to - # pass -x c++. We could always pass -x c++ but distcc does not work with it. - if ! $(>:S) in .cc .cp .cxx .cpp .c++ .C - { - LANG on $(<) = "-x c++" ; - } - DEPENDS $(<) : [ on $(<) return $(PCH_FILE) ] ; -} - -rule compile.c ( targets * : sources * : properties * ) -{ - setup-threading $(targets) : $(sources) : $(properties) ; - setup-fpic $(targets) : $(sources) : $(properties) ; - setup-address-model $(targets) : $(sources) : $(properties) ; - - # If we use the name g++ then default file suffix -> language mapping does - # not work. So have to pass -x option. Maybe, we can work around this by - # allowing the user to specify both C and C++ compiler names. - #if $(>:S) != .c - #{ - LANG on $(<) = "-x c" ; - #} - DEPENDS $(<) : [ on $(<) return $(PCH_FILE) ] ; -} - -rule compile.fortran ( targets * : sources * : properties * ) -{ - setup-threading $(targets) : $(sources) : $(properties) ; - setup-fpic $(targets) : $(sources) : $(properties) ; - setup-address-model $(targets) : $(sources) : $(properties) ; -} - -actions compile.c++ bind PCH_FILE -{ - "$(CONFIG_COMMAND)" $(LANG) -ftemplate-depth-$(TEMPLATE_DEPTH) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" -c -o "$(<:W)" "$(>:W)" -} - -actions compile.c bind PCH_FILE -{ - "$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" -c -o "$(<)" "$(>)" -} - -actions compile.c++.preprocess bind PCH_FILE -{ - "$(CONFIG_COMMAND)" $(LANG) -ftemplate-depth-$(TEMPLATE_DEPTH) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" "$(>:W)" -E >"$(<:W)" -} - -actions compile.c.preprocess bind PCH_FILE -{ - "$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" "$(>)" -E >$(<) -} - -actions compile.fortran -{ - "$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" -c -o "$(<)" "$(>)" -} - -rule compile.asm ( targets * : sources * : properties * ) -{ - setup-fpic $(targets) : $(sources) : $(properties) ; - setup-address-model $(targets) : $(sources) : $(properties) ; - LANG on $(<) = "-x assembler-with-cpp" ; -} - -actions compile.asm -{ - "$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)" -} +### +### Linking generators and actions. +### # Class checking that we do not try to use the static property # while creating or using a shared library, since it is not supported by @@ -650,14 +812,12 @@ class gcc-linking-generator : unix-linking-generator { rule run ( project name ? : property-set : sources + ) { - # TODO: Replace this with the use of a target-os property. - local no-static-link = ; - if [ modules.peek : UNIX ] + local target-os = [ $(property-set).get ] ; + local no-static-link = true ; + switch $(target-os) { - switch [ modules.peek : JAMUNAME ] - { - case * : no-static-link = true ; - } + case vms : no-static-link = ; + case windows : no-static-link = ; } local properties = [ $(property-set).raw ] ; @@ -694,6 +854,26 @@ class gcc-linking-generator : unix-linking-generator $(property-set) : $(sources) ] ; } } + + rule action-class ( ) + { + return gcc-link-action ; + } +} + +class gcc-link-action : action +{ + import gcc ; + + rule execute ( action-name targets + : sources * : properties * ) + { + gcc.set-threading-options $(targets) : $(sources) : $(properties) ; + gcc.set-fpic-options $(targets) : $(sources) : $(properties) ; + gcc.set-address-model-options $(targets) : $(sources) : $(properties) ; + gcc.set-cxxstd-options $(targets) : $(sources) : $(properties) ; + gcc.set-link-options $(action-name) $(targets) : $(sources) : $(properties) ; + action.execute $(action-name) $(targets) : $(sources) : $(properties) ; + } } # The set of permissible input types is different on mingw. So, define two sets @@ -762,22 +942,35 @@ toolset.flags gcc.link LIBRARIES ; toolset.flags gcc.link.dll .IMPLIB-COMMAND windows : "-Wl,--out-implib," ; toolset.flags gcc.link.dll .IMPLIB-COMMAND cygwin : "-Wl,--out-implib," ; -# For static we made sure there are no dynamic libraries in the -# link. On HP-UX not all system libraries exist as archived libraries (for -# example, there is no libunwind.a), so, on this platform, the -static option -# cannot be specified. -if [ os.name ] != HPUX -{ - toolset.flags gcc.link OPTIONS static : -static ; -} - # Now, the vendor specific flags. # The parameter linker can be either aix, darwin, gnu, hpux, osf or sun. -rule init-link-flags ( toolset linker condition ) +rule init-link-flags ( toolset subtool condition ) { - switch $(linker) + ## Need to define the linker-type feature once for each toolset module. + if ! [ feature.valid ] { - case aix : + toolset.add-requirements + $(condition),aix:aix + $(condition),darwin:darwin + $(condition),hpux:hpux + $(condition),osf:osf + $(condition),solaris:sun + ; + feature.subfeature toolset $(toolset) : linker-type : + gnu aix darwin hpux osf sun : propagated link-incompatible ; + } +} + +rule set-link-options ( action-name targets + : sources * : properties * ) +{ + local toolset = [ feature.get-values : $(properties) ] ; + local linker-type = [ feature.get-values : $(properties) ] ; + local target-os = [ feature.get-values : $(properties) ] ; + + switch $(linker-type:G=) + { + case aix : + # On AIX we *have* to use the native linker. # # Using -brtl, the AIX linker will look for libraries with both the .a @@ -804,19 +997,33 @@ rule init-link-flags ( toolset linker condition ) # http://download.boulder.ibm.com/ibmdl/pub/software/dw/aix/es-aix_ll.pdf # - toolset.flags $(toolset).link OPTIONS : -Wl,-brtl -Wl,-bnoipath -Wl,-bbigtoc - : unchecked ; + OPTIONS on $(targets) += -Wl,-brtl -Wl,-bnoipath -Wl,-bbigtoc ; + + # See note [1] + if static in $(properties) + { + OPTIONS on $(targets) += -static ; + } + + case darwin : - case darwin : # On Darwin, the -s option to ld does not work unless we pass -static, # and passing -static unconditionally is a bad idea. So, do not pass -s # at all and darwin.jam will use a separate 'strip' invocation. - toolset.flags $(toolset).link RPATH $(condition) : : - unchecked ; - toolset.flags $(toolset).link RPATH_LINK $(condition) : : - unchecked ; + RPATH on $(targets) += + [ feature.get-values : $(properties) ] ; + # This does not support -R. + RPATH_OPTION on $(targets) += -rpath ; + # -rpath-link is not supported at all. - case vxworks : + # See note [1] + if static in $(properties) + { + OPTIONS on $(targets) += -static ; + } + + case vxworks : + # On VxWorks we want to reflect what ever special flags have been set in the # environment for the CPU we are targeting in the cross build toolset.flags $(toolset).link OPTIONS $(condition)/on : -Wl,--strip-all : unchecked ; @@ -824,16 +1031,23 @@ rule init-link-flags ( toolset linker condition ) toolset.flags $(toolset).link.dll OPTIONS $(condition) : [ os.environ LDFLAGS_SO ] : unchecked ; toolset.flags $(toolset).link OPTIONS $(condition)/shared : [ os.environ LDFLAGS_DYNAMIC ] : unchecked ; - case gnu : + case gnu : + # Strip the binary when no debugging is needed. We use --strip-all flag # as opposed to -s since icc (intel's compiler) is generally # option-compatible with and inherits from the gcc toolset, but does not # support -s. - toolset.flags $(toolset).link OPTIONS $(condition)/on : -Wl,--strip-all : unchecked ; - toolset.flags $(toolset).link RPATH $(condition) : : unchecked ; - toolset.flags $(toolset).link RPATH_LINK $(condition) : : unchecked ; - toolset.flags $(toolset).link START-GROUP $(condition) : -Wl,--start-group : unchecked ; - toolset.flags $(toolset).link END-GROUP $(condition) : -Wl,--end-group : unchecked ; + if on in $(properties) + { + OPTIONS on $(targets) += -Wl,--strip-all ; + } + RPATH on $(targets) += + [ feature.get-values : $(properties) ] ; + RPATH_OPTION on $(targets) += -rpath ; + RPATH_LINK on $(targets) += + [ feature.get-values : $(properties) ] ; + START-GROUP on $(targets) += -Wl,--start-group ; + END-GROUP on $(targets) += -Wl,--end-group ; # gnu ld has the ability to change the search behaviour for libraries # referenced by the -l switch. These modifiers are -Bstatic and @@ -868,49 +1082,72 @@ rule init-link-flags ( toolset linker condition ) # search patterns! # On *nix mixing shared libs with static runtime is not a good idea. - toolset.flags $(toolset).link FINDLIBS-ST-PFX - $(condition)/shared : -Wl,-Bstatic : unchecked ; - toolset.flags $(toolset).link FINDLIBS-SA-PFX - $(condition)/shared : -Wl,-Bdynamic : unchecked ; + if shared in $(properties) + { + FINDLIBS-ST-PFX on $(targets) += -Wl,-Bstatic ; + FINDLIBS-SA-PFX on $(targets) += -Wl,-Bdynamic ; + } # On windows allow mixing of static and dynamic libs with static # runtime is not a good idea. - toolset.flags $(toolset).link FINDLIBS-ST-PFX - $(condition)/static/windows : -Wl,-Bstatic - : unchecked ; - toolset.flags $(toolset).link FINDLIBS-SA-PFX - $(condition)/static/windows : -Wl,-Bdynamic - : unchecked ; - toolset.flags $(toolset).link OPTIONS - $(condition)/static/windows : -Wl,-Bstatic - : unchecked ; + if static in $(properties) && windows in $(properties) + { + FINDLIBS-ST-PFX on $(targets) += -Wl,-Bstatic ; + FINDLIBS-SA-PFX on $(targets) += -Wl,-Bdynamic ; + OPTIONS on $(targets) += -Wl,-Bstatic ; + } - case hpux : - toolset.flags $(toolset).link OPTIONS $(condition)/on : -Wl,-s : - unchecked ; - toolset.flags $(toolset).link OPTIONS $(condition)/shared : -fPIC - : unchecked ; + HAVE_SONAME on $(targets) += "" ; + SONAME_OPTION on $(targets) += -h ; + + # See note [1] + if static in $(properties) + { + OPTIONS on $(targets) += -static ; + } + + case hpux : + + if on in $(properties) + { + OPTIONS on $(targets) += -Wl,-s ; + } + if shared in $(properties) + { + OPTIONS on $(targets) += -fPIC ; + } + + HAVE_SONAME on $(targets) += "" ; + SONAME_OPTION on $(targets) += +h ; + + case osf : - case osf : # No --strip-all, just -s. - toolset.flags $(toolset).link OPTIONS $(condition)/on : -Wl,-s : - unchecked ; - toolset.flags $(toolset).link RPATH $(condition) : : - unchecked ; + OPTIONS + osf/$(condition)/on + : -Wl,-s + : unchecked ; + RPATH on $(targets) += [ feature.get-values ] ; # This does not support -R. - toolset.flags $(toolset).link RPATH_OPTION $(condition) : -rpath : - unchecked ; + RPATH_OPTION on $(targets) += -rpath ; # -rpath-link is not supported at all. - case sun : - toolset.flags $(toolset).link OPTIONS $(condition)/on : -Wl,-s : - unchecked ; - toolset.flags $(toolset).link RPATH $(condition) : : - unchecked ; + # See note [1] + if static in $(properties) + { + OPTIONS on $(targets) += -static ; + } + + case sun : + + if on in $(properties) + { + OPTIONS on $(targets) += -Wl,-s ; + } + RPATH on $(targets) += [ feature.get-values ] ; # Solaris linker does not have a separate -rpath-link, but allows using # -L for the same purpose. - toolset.flags $(toolset).link LINKPATH $(condition) : : - unchecked ; + LINKPATH on $(targets) += [ feature.get-values ] ; # This permits shared libraries with non-PIC code on Solaris. # VP, 2004/09/07: Now that we have -fPIC hardcode in link.dll, the @@ -918,16 +1155,23 @@ rule init-link-flags ( toolset linker condition ) # separate question. # AH, 2004/10/16: it is still necessary because some tests link against # static libraries that were compiled without PIC. - toolset.flags $(toolset).link OPTIONS $(condition)/shared : - -mimpure-text : unchecked ; + if shared in $(properties) + { + OPTIONS on $(targets) += -mimpure-text ; + } - case * : - import errors ; - errors.user-error $(toolset) initialization: invalid linker '$(linker)' - : The value '$(linker)' specified for is not recognized. - : Possible values are 'aix', 'darwin', 'gnu', 'hpux', 'osf' or 'sun' - ; + # See note [1] + if static in $(properties) + { + OPTIONS on $(targets) += -static ; + } } + + # [1] + # For static we made sure there are no dynamic libraries in the + # link. On HP-UX not all system libraries exist as archived libraries (for + # example, there is no libunwind.a), so, on this platform, the -static option + # cannot be specified. } @@ -950,8 +1194,6 @@ rule quote-rpath ( targets * ) # Declare actions for linking. rule link ( targets * : sources * : properties * ) { - setup-threading $(targets) : $(sources) : $(properties) ; - setup-address-model $(targets) : $(sources) : $(properties) ; SPACE on $(targets) = " " ; # Serialize execution of the 'link' action, since running N links in # parallel is just slower. For now, serialize only gcc links, it might be a @@ -965,6 +1207,22 @@ actions link bind LIBRARIES "$(CONFIG_COMMAND)" -L"$(LINKPATH)" -Wl,$(RPATH_OPTION:E=-R)$(SPACE)-Wl,$(RPATH) -Wl,-rpath-link$(SPACE)-Wl,"$(RPATH_LINK)" -o "$(<)" $(START-GROUP) "$(>)" "$(LIBRARIES)" $(FINDLIBS-ST-PFX) -l$(FINDLIBS-ST) $(FINDLIBS-SA-PFX) -l$(FINDLIBS-SA) $(END-GROUP) $(OPTIONS) $(USER_OPTIONS) } +rule link.dll ( targets * : sources * : properties * ) +{ + SPACE on $(targets) = " " ; + JAM_SEMAPHORE on $(targets) = gcc-link-semaphore ; + quote-rpath $(targets) ; +} + +# Differs from 'link' above only by -shared. +actions link.dll bind LIBRARIES +{ + "$(CONFIG_COMMAND)" -L"$(LINKPATH)" -Wl,$(RPATH_OPTION:E=-R)$(SPACE)-Wl,$(RPATH) "$(.IMPLIB-COMMAND)$(<[1])" -o "$(<[-1])" $(HAVE_SONAME)-Wl,$(SONAME_OPTION)$(SPACE)-Wl,$(<[-1]:D=) -shared $(START-GROUP) "$(>)" "$(LIBRARIES)" $(FINDLIBS-ST-PFX) -l$(FINDLIBS-ST) $(FINDLIBS-SA-PFX) -l$(FINDLIBS-SA) $(END-GROUP) $(OPTIONS) $(USER_OPTIONS) +} + +### +### Archive library generation. +### # Default value. Mostly for the sake of intel-linux that inherits from gcc, but # does not have the same logic to set the .AR variable. We can put the same @@ -1016,56 +1274,9 @@ actions piecemeal archive "$(.RANLIB)" "$(<)" } -rule link.dll ( targets * : sources * : properties * ) -{ - setup-threading $(targets) : $(sources) : $(properties) ; - setup-address-model $(targets) : $(sources) : $(properties) ; - SPACE on $(targets) = " " ; - JAM_SEMAPHORE on $(targets) = gcc-link-semaphore ; - quote-rpath $(targets) ; -} - -# Differs from 'link' above only by -shared. -actions link.dll bind LIBRARIES -{ - "$(CONFIG_COMMAND)" -L"$(LINKPATH)" -Wl,$(RPATH_OPTION:E=-R)$(SPACE)-Wl,$(RPATH) "$(.IMPLIB-COMMAND)$(<[1])" -o "$(<[-1])" $(HAVE_SONAME)-Wl,$(SONAME_OPTION)$(SPACE)-Wl,$(<[-1]:D=) -shared $(START-GROUP) "$(>)" "$(LIBRARIES)" $(FINDLIBS-ST-PFX) -l$(FINDLIBS-ST) $(FINDLIBS-SA-PFX) -l$(FINDLIBS-SA) $(END-GROUP) $(OPTIONS) $(USER_OPTIONS) -} - -rule setup-threading ( targets * : sources * : properties * ) -{ - local threading = [ feature.get-values threading : $(properties) ] ; - if $(threading) = multi - { - local target = [ feature.get-values target-os : $(properties) ] ; - local option ; - local libs ; - - switch $(target) - { - case android : # No threading options, everything is in already. - case windows : option = -mthreads ; - case cygwin : option = -mthreads ; - case solaris : option = -pthreads ; libs = rt ; - case beos : # No threading options. - case haiku : option = ; - case *bsd : option = -pthread ; # There is no -lrt on BSD. - case sgi : # gcc on IRIX does not support multi-threading. - case darwin : # No threading options. - case vxworks : # No threading options. - case * : option = -pthread ; libs = rt ; - } - - if $(option) - { - OPTIONS on $(targets) += $(option) ; - } - if $(libs) - { - FINDLIBS-SA on $(targets) += $(libs) ; - } - } -} - +### +### CPU architecture and instruction set options. +### local rule cpu-flags ( toolset variable : architecture : instruction-set + : values + : default ? ) diff --git a/src/tools/generators/__init_generators__.jam b/src/tools/generators/__init_generators__.jam new file mode 100644 index 000000000..5f2483305 --- /dev/null +++ b/src/tools/generators/__init_generators__.jam @@ -0,0 +1,23 @@ +# Copyright 2017 Rene Rivera +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +# Here we automatically define any "generator" modules in this directory. + +local key = generator ; + +import os path modules ; + +.this-module's-file = [ modules.binding $(__name__) ] ; +.this-module's-dir = [ path.parent [ path.make $(.this-module's-file) ] ] ; +.to-load-jamfiles = [ path.glob $(.this-module's-dir) : *-$(key).jam ] ; +.to-load-modules = [ MATCH ^(.*)\.jam$ : $(.to-load-jamfiles) ] ; + +# A loop over all matched modules in this directory +for local m in $(.to-load-modules) +{ + m = [ path.basename $(m) ] ; + m = $(key)s/$(m) ; + import $(m) ; +} diff --git a/src/tools/generators/archive-generator.jam b/src/tools/generators/archive-generator.jam new file mode 100644 index 000000000..88ef16559 --- /dev/null +++ b/src/tools/generators/archive-generator.jam @@ -0,0 +1,73 @@ +# Copyright 2002-2017 Rene Rivera +# Copyright 2002-2017 Vladimir Prus +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import "class" : new ; +import generators ; + +# The generator class for handling STATIC_LIB creation. +# +class archive-generator : generator +{ + import property-set ; + + rule __init__ ( id composing ? : source-types + : target-types + + : requirements * ) + { + composing ?= true ; + generator.__init__ $(id) $(composing) : $(source-types) + : $(target-types) : $(requirements) ; + } + + rule run ( project name ? : property-set : sources + ) + { + sources += [ $(property-set).get ] ; + + local result = [ generator.run $(project) $(name) : $(property-set) + : $(sources) ] ; + + # For static linking, if we get a library in source, we can not directly + # link to it so we need to cause our dependencies to link to that + # library. There are two approaches: + # - adding the library to the list of returned targets. + # - using the usage requirements. + # The problem with the first is: + # + # lib a1 : : liba1.a ; + # lib a2 : a2.cpp a1 : static ; + # install dist : a2 ; + # + # here we will try to install 'a1', even though it is not necessary in + # the general case. With the second approach, even indirect dependants + # will link to the library, but it should not cause any harm. So, return + # all LIB sources together with created targets, so that dependants link + # to them. + local usage-requirements ; + if [ $(property-set).get ] = static + { + for local t in $(sources) + { + if [ type.is-derived [ $(t).type ] LIB ] + { + usage-requirements += $(t) ; + } + } + } + + usage-requirements = [ property-set.create $(usage-requirements) ] ; + + return $(usage-requirements) $(result) ; + } +} + + +rule register-archiver ( id composing ? : source-types + : target-types + + : requirements * ) +{ + generators.register [ new archive-generator $(id) $(composing) + : $(source-types) : $(target-types) : $(requirements) ] ; +} + +IMPORT $(__name__) : register-archiver : : generators.register-archiver ; diff --git a/src/tools/generators/c-compiling-generator.jam b/src/tools/generators/c-compiling-generator.jam new file mode 100644 index 000000000..00cd42a4d --- /dev/null +++ b/src/tools/generators/c-compiling-generator.jam @@ -0,0 +1,70 @@ +# Copyright 2002-2017 Rene Rivera +# Copyright 2002-2017 Vladimir Prus +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import "class" : new ; +import generators ; +import virtual-target ; + +# Declare a special compiler generator. The only thing it does is changing the +# type used to represent 'action' in the constructed dependency graph to +# 'compile-action'. That class in turn adds additional include paths to handle +# cases when a source file includes headers which are generated themselves. +# +class C-compiling-generator : generator +{ + rule __init__ ( id : source-types + : target-types + : requirements * + : optional-properties * ) + { + generator.__init__ $(id) : $(source-types) : $(target-types) : + $(requirements) : $(optional-properties) ; + } + + rule action-class ( ) + { + return compile-action ; + } +} + + +rule register-c-compiler ( id : source-types + : target-types + : requirements * + : optional-properties * ) +{ + generators.register [ new C-compiling-generator $(id) : $(source-types) : + $(target-types) : $(requirements) : $(optional-properties) ] ; +} + +# FIXME: this is ugly, should find a better way (we would like client code to +# register all generators as "generators.some-rule" instead of +# "some-module.some-rule".) +# +IMPORT $(__name__) : register-c-compiler : : generators.register-c-compiler ; + +class compile-action : action +{ + import sequence ; + + rule __init__ ( targets * : sources * : action-name : properties * ) + { + action.__init__ $(targets) : $(sources) : $(action-name) : $(properties) ; + } + + # For all virtual targets for the same dependency graph as self, i.e. which + # belong to the same main target, add their directories to the include path. + # + rule adjust-properties ( property-set ) + { + local s = [ $(self.targets[1]).creating-subvariant ] ; + if $(s) + { + return [ $(property-set).add-raw + [ $(s).implicit-includes "include" : H ] ] ; + } + else + { + return $(property-set) ; + } + } +} diff --git a/src/tools/generators/dummy-generator.jam b/src/tools/generators/dummy-generator.jam new file mode 100644 index 000000000..ee93cfe88 --- /dev/null +++ b/src/tools/generators/dummy-generator.jam @@ -0,0 +1,20 @@ +# Copyright 2002-2017 Rene Rivera +# Copyright 2002-2017 Vladimir Prus +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import generators ; + +# Generator that accepts everything and produces nothing. Useful as a general +# fallback for toolset-specific actions like PCH generation. +# +class dummy-generator : generator +{ + import property-set ; + + rule run ( project name ? : property-set : sources + ) + { + return [ property-set.empty ] ; + } +} diff --git a/src/tools/generators/lib-generator.jam b/src/tools/generators/lib-generator.jam new file mode 100644 index 000000000..f520b6102 --- /dev/null +++ b/src/tools/generators/lib-generator.jam @@ -0,0 +1,115 @@ +# Copyright 2002-2017 Rene Rivera +# Copyright 2002-2017 Vladimir Prus +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import "class" : new ; +import generators ; +import project ; +import targets ; + +# The generator class for libraries (target type LIB). Depending on properties +# it will request building of the appropriate specific library type -- +# -- SHARED_LIB, STATIC_LIB or SHARED_LIB. +# +class lib-generator : generator +{ + rule __init__ ( * : * ) + { + generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) + : $(9) : $(10) : $(11) : $(12) : $(13) : $(14) : $(15) : $(16) : + $(17) : $(18) : $(19) ; + } + + rule run ( project name ? : property-set : sources * ) + { + # The lib generator is composing, and can be only invoked with an + # explicit name. This check is present in generator.run (and so in + # builtin.linking-generator) but duplicated here to avoid doing extra + # work. + if $(name) + { + local properties = [ $(property-set).raw ] ; + # Determine the needed target type. + local actual-type ; + # files can be generated by @rule feature + # in which case we do not consider it a SEARCHED_LIB type. + if ! in $(properties:G) && + ( in $(properties:G) || in $(properties:G) ) + { + actual-type = SEARCHED_LIB ; + } + else if in $(properties:G) + { + actual-type = LIB ; + } + else if shared in $(properties) + { + actual-type = SHARED_LIB ; + } + else + { + actual-type = STATIC_LIB ; + } + property-set = [ $(property-set).add-raw LIB ] ; + # Construct the target. + return [ generators.construct $(project) $(name) : $(actual-type) + : $(property-set) : $(sources) ] ; + } + } + + rule viable-source-types ( ) + { + return * ; + } +} + +generators.register [ new lib-generator builtin.lib-generator : : LIB ] ; + +# The implementation of the 'lib' rule. Beyond standard syntax that rule allows +# simplified: "lib a b c ;". +# +rule lib ( names + : sources * : requirements * : default-build * : + usage-requirements * ) +{ + if $(names[2]) + { + if in $(requirements:G) + { + errors.user-error "When several names are given to the 'lib' rule" : + "it is not allowed to specify the feature." ; + } + if $(sources) + { + errors.user-error "When several names are given to the 'lib' rule" : + "it is not allowed to specify sources." ; + } + } + + # This is a circular module dependency so it must be imported here. + import targets ; + + local project = [ project.current ] ; + local result ; + + for local name in $(names) + { + local r = $(requirements) ; + # Support " lib a ; " and " lib a b c ; " syntax. + if ! $(sources) && ! in $(requirements:G) + && ! in $(requirements:G) + { + r += $(name) ; + } + result += [ targets.main-target-alternative + [ new typed-target $(name) : $(project) : LIB + : [ targets.main-target-sources $(sources) : $(name) ] + : [ targets.main-target-requirements $(r) : $(project) ] + : [ targets.main-target-default-build $(default-build) : $(project) ] + : [ targets.main-target-usage-requirements $(usage-requirements) : $(project) ] + ] ] ; + } + return $(result) ; +} +IMPORT $(__name__) : lib : : lib ; diff --git a/src/tools/generators/linking-generator.jam b/src/tools/generators/linking-generator.jam new file mode 100644 index 000000000..2184eea5a --- /dev/null +++ b/src/tools/generators/linking-generator.jam @@ -0,0 +1,185 @@ +# Copyright 2002-2017 Rene Rivera +# Copyright 2002-2017 Vladimir Prus +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import "class" : new ; +import generators ; + +# The generator class for handling EXE and SHARED_LIB creation. +# +class linking-generator : generator +{ + import path ; + import project ; + import property-set ; + import type ; + + rule __init__ ( id + composing ? : # The generator will be composing if a non-empty + # string is passed or the parameter is not given. To + # make the generator non-composing, pass an empty + # string (""). + source-types + : + target-types + : + requirements * ) + { + composing ?= true ; + generator.__init__ $(id) $(composing) : $(source-types) + : $(target-types) : $(requirements) ; + } + + rule run ( project name ? : property-set : sources + ) + { + sources += [ $(property-set).get ] ; + + # Add properties for all searched libraries. + local extra ; + for local s in $(sources) + { + if [ $(s).type ] = SEARCHED_LIB + { + local search = [ $(s).search ] ; + extra += $(search) ; + } + } + + # It is possible that sources include shared libraries that did not came + # from 'lib' targets, e.g. .so files specified as sources. In this case + # we have to add extra dll-path properties and propagate extra xdll-path + # properties so that application linking to us will get xdll-path to + # those libraries. + local extra-xdll-paths ; + for local s in $(sources) + { + if [ type.is-derived [ $(s).type ] SHARED_LIB ] && ! [ $(s).action ] + { + # Unfortunately, we do not have a good way to find the path to a + # file, so use this nasty approach. + # + # TODO: This needs to be done better. One thing that is really + # broken with this is that it does not work correctly with + # projects having multiple source locations. + local p = [ $(s).project ] ; + local location = [ path.root [ $(s).name ] + [ $(p).get source-location ] ] ; + extra-xdll-paths += [ path.parent $(location) ] ; + } + } + + # Hardcode DLL paths only when linking executables. + # Pros: do not need to relink libraries when installing. + # Cons: "standalone" libraries (plugins, python extensions) can not + # hardcode paths to dependent libraries. + if [ $(property-set).get ] = true + && [ type.is-derived $(self.target-types[1]) EXE ] + { + local xdll-path = [ $(property-set).get ] ; + extra += $(xdll-path) $(extra-xdll-paths) ; + } + + if $(extra) + { + property-set = [ $(property-set).add-raw $(extra) ] ; + } + + local result = [ generator.run $(project) $(name) : $(property-set) + : $(sources) ] ; + + local ur ; + if $(result) + { + ur = [ extra-usage-requirements $(result) : $(property-set) ] ; + ur = [ $(ur).add + [ property-set.create $(extra-xdll-paths) ] ] ; + } + return $(ur) $(result) ; + } + + rule extra-usage-requirements ( created-targets * : property-set ) + { + local result = [ property-set.empty ] ; + local extra ; + + # Add appropriate usage requirements. + local raw = [ $(property-set).raw ] ; + if shared in $(raw) + { + local paths ; + local pwd = [ path.pwd ] ; + for local t in $(created-targets) + { + if [ type.is-derived [ $(t).type ] SHARED_LIB ] + { + paths += [ path.root [ path.make [ $(t).path ] ] $(pwd) ] ; + } + } + extra += $(paths:G=) ; + } + + # We need to pass features that we've got from sources, + # because if a shared library is built, exe using it needs to know paths + # to other shared libraries this one depends on in order to be able to + # find them all at runtime. + + # Just pass all features in property-set, it is theoretically possible + # that we will propagate features explicitly specified by + # the user, but then the user is to blame for using an internal feature. + local values = [ $(property-set).get ] ; + extra += $(values:G=) ; + + if $(extra) + { + result = [ property-set.create $(extra) ] ; + } + return $(result) ; + } + + rule generated-targets ( sources + : property-set : project name ? ) + { + local sources2 ; # Sources to pass to inherited rule. + local properties2 ; # Properties to pass to inherited rule. + local libraries ; # Library sources. + + # Searched libraries are not passed as arguments to the linker but via + # some option. So, we pass them to the action using a property. + properties2 = [ $(property-set).raw ] ; + local fsa ; + local fst ; + for local s in $(sources) + { + if [ type.is-derived [ $(s).type ] SEARCHED_LIB ] + { + local name = [ $(s).name ] ; + if [ $(s).shared ] + { + fsa += $(name) ; + } + else + { + fst += $(name) ; + } + } + else + { + sources2 += $(s) ; + } + } + properties2 += $(fsa:J=&&) + $(fst:J=&&) ; + + return [ generator.generated-targets $(sources2) + : [ property-set.create $(properties2) ] : $(project) $(name) ] ; + } +} + + +rule register-linker ( id composing ? : source-types + : target-types + + : requirements * ) +{ + generators.register [ new linking-generator $(id) $(composing) + : $(source-types) : $(target-types) : $(requirements) ] ; +} + +IMPORT $(__name__) : register-linker : : generators.register-linker ; diff --git a/src/tools/generators/prebuilt-lib-generator.jam b/src/tools/generators/prebuilt-lib-generator.jam new file mode 100644 index 000000000..00c8e6bdc --- /dev/null +++ b/src/tools/generators/prebuilt-lib-generator.jam @@ -0,0 +1,30 @@ +# Copyright 2002-2017 Rene Rivera +# Copyright 2002-2017 Vladimir Prus +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import "class" : new ; +import generators ; + +class prebuilt-lib-generator : generator +{ + rule __init__ ( * : * ) + { + generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) + : $(9) : $(10) : $(11) : $(12) : $(13) : $(14) : $(15) : $(16) : + $(17) : $(18) : $(19) ; + } + + rule run ( project name ? : property-set : sources * ) + { + local f = [ $(property-set).get ] ; + return $(f) $(sources) ; + } +} + +generators.register + [ new prebuilt-lib-generator builtin.prebuilt : : LIB : ] ; + +generators.override builtin.prebuilt : builtin.lib-generator ; + \ No newline at end of file diff --git a/src/tools/generators/searched-lib-generator.jam b/src/tools/generators/searched-lib-generator.jam new file mode 100644 index 000000000..174d137e3 --- /dev/null +++ b/src/tools/generators/searched-lib-generator.jam @@ -0,0 +1,92 @@ +# Copyright 2002-2017 Rene Rivera +# Copyright 2002-2017 Vladimir Prus +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import "class" : new ; +import generators ; + +class searched-lib-generator : generator +{ + import property-set ; + + rule __init__ ( ) + { + # The requirements cause the generators to be tried *only* when we are + # building a lib target with a 'search' feature. This seems ugly --- all + # we want is to make sure searched-lib-generator is not invoked deep + # inside transformation search to produce intermediate targets. + generator.__init__ searched-lib-generator : : SEARCHED_LIB ; + } + + rule run ( project name ? : property-set : sources * ) + { + if $(name) + { + # If 'name' is empty, it means we have not been called to build a + # top-level target. In this case, we just fail immediately, because + # searched-lib-generator cannot be used to produce intermediate + # targets. + + local properties = [ $(property-set).raw ] ; + local shared ; + if shared in $(properties) + { + shared = true ; + } + + local search = [ feature.get-values : $(properties) ] ; + + local a = [ new null-action $(property-set) ] ; + local lib-name = [ feature.get-values : $(properties) ] ; + lib-name ?= $(name) ; + local t = [ new searched-lib-target $(lib-name) : $(project) + : $(shared) : $(search) : $(a) ] ; + # We return sources for a simple reason. If there is + # lib png : z : png ; + # the 'z' target should be returned, so that apps linking to 'png' + # will link to 'z', too. + return [ property-set.create $(search) ] + [ virtual-target.register $(t) ] $(sources) ; + } + } +} + +generators.register [ new searched-lib-generator ] ; + +class searched-lib-target : abstract-file-target +{ + rule __init__ ( name + : project + : shared ? + : search * + : action + ) + { + abstract-file-target.__init__ $(name) : SEARCHED_LIB : $(project) + : $(action) : ; + + self.shared = $(shared) ; + self.search = $(search) ; + } + + rule shared ( ) + { + return $(self.shared) ; + } + + rule search ( ) + { + return $(self.search) ; + } + + rule actualize-location ( target ) + { + NOTFILE $(target) ; + } + + rule path ( ) + { + } +} diff --git a/src/tools/intel-linux.jam b/src/tools/intel-linux.jam index d9164add8..c743e52d2 100644 --- a/src/tools/intel-linux.jam +++ b/src/tools/intel-linux.jam @@ -162,9 +162,6 @@ flags intel-linux.compile OPTIONS all : -w2 ; rule compile.c++ ( targets * : sources * : properties * ) { - gcc.setup-threading $(targets) : $(sources) : $(properties) ; - gcc.setup-fpic $(targets) : $(sources) : $(properties) ; - gcc.setup-address-model $(targets) : $(sources) : $(properties) ; DEPENDS $(<) : [ on $(<) return $(PCH_FILE) ] ; } @@ -175,9 +172,6 @@ actions compile.c++ bind PCH_FILE rule compile.c ( targets * : sources * : properties * ) { - gcc.setup-threading $(targets) : $(sources) : $(properties) ; - gcc.setup-fpic $(targets) : $(sources) : $(properties) ; - gcc.setup-address-model $(targets) : $(sources) : $(properties) ; DEPENDS $(<) : [ on $(<) return $(PCH_FILE) ] ; } @@ -188,9 +182,6 @@ actions compile.c bind PCH_FILE rule compile.c++.pch ( targets * : sources * : properties * ) { - gcc.setup-threading $(targets) : $(sources) : $(properties) ; - gcc.setup-fpic $(targets) : $(sources) : $(properties) ; - gcc.setup-address-model $(targets) : $(sources) : $(properties) ; } # # Compiling a pch first deletes any existing *.pchi file, as Intel's compiler @@ -209,9 +200,6 @@ actions compile.fortran rule compile.c.pch ( targets * : sources * : properties * ) { - gcc.setup-threading $(targets) : $(sources) : $(properties) ; - gcc.setup-fpic $(targets) : $(sources) : $(properties) ; - gcc.setup-address-model $(targets) : $(sources) : $(properties) ; } actions compile.c.pch @@ -221,8 +209,6 @@ actions compile.c.pch rule link ( targets * : sources * : properties * ) { - gcc.setup-threading $(targets) : $(sources) : $(properties) ; - gcc.setup-address-model $(targets) : $(sources) : $(properties) ; SPACE on $(targets) = " " ; JAM_SEMAPHORE on $(targets) = intel-linux-link-semaphore ; } @@ -234,8 +220,6 @@ actions link bind LIBRARIES rule link.dll ( targets * : sources * : properties * ) { - gcc.setup-threading $(targets) : $(sources) : $(properties) ; - gcc.setup-address-model $(targets) : $(sources) : $(properties) ; SPACE on $(targets) = " " ; JAM_SEMAPHORE on $(targets) = intel-linux-link-semaphore ; } diff --git a/test/BoostBuild.py b/test/BoostBuild.py index 83757e3c8..a6872dcbc 100644 --- a/test/BoostBuild.py +++ b/test/BoostBuild.py @@ -209,7 +209,7 @@ class Tester(TestCmd.TestCmd): def __init__(self, arguments=None, executable="bjam", match=TestCmd.match_exact, boost_build_path=None, translate_suffixes=True, pass_toolset=True, use_test_config=True, - ignore_toolset_requirements=True, workdir="", pass_d0=True, + ignore_toolset_requirements=False, workdir="", pass_d0=True, **keywords): assert arguments.__class__ is not str @@ -352,7 +352,7 @@ class Tester(TestCmd.TestCmd): def copy(self, src, dst): try: - self.write(dst, self.read(src, 1)) + self.write(dst, self.read(src, binary=True)) except: self.fail_test(1) @@ -360,7 +360,7 @@ class Tester(TestCmd.TestCmd): src_name = self.native_file_name(src) dst_name = self.native_file_name(dst) stats = os.stat(src_name) - self.write(dst, self.read(src, 1)) + self.write(dst, self.__read(src, binary=True)) os.utime(dst_name, (stats.st_atime, stats.st_mtime)) def touch(self, names, wait=True): @@ -523,26 +523,26 @@ class Tester(TestCmd.TestCmd): expected_duration)) self.fail_test(1, dump_stdio=False) + self.__ignore_junk() + def glob_file(self, name): + name = self.adjust_name(name) result = None if hasattr(self, "difference"): for f in (self.difference.added_files + self.difference.modified_files + self.difference.touched_files): if fnmatch.fnmatch(f, name): - result = self.native_file_name(f) + result = self.__native_file_name(f) break if not result: - result = glob.glob(self.native_file_name(name)) + result = glob.glob(self.__native_file_name(name)) if result: result = result[0] return result - def read(self, name, binary=False): + def __read(self, name, binary=False): try: - if self.toolset: - name = name.replace("$toolset", self.toolset + "*") - name = self.glob_file(name) openMode = "r" if binary: openMode += "b" @@ -557,6 +557,10 @@ class Tester(TestCmd.TestCmd): self.fail_test(1) return "" + def read(self, name, binary=False): + name = self.glob_file(name) + return self.__read(name, binary=binary) + def read_and_strip(self, name): if not self.glob_file(name): return "" @@ -694,7 +698,7 @@ class Tester(TestCmd.TestCmd): "File %s touched, but no action was expected" % name) self.fail_test(1) - def expect_nothing_more(self): + def __ignore_junk(self): # Not totally sure about this change, but I do not see a good # alternative. if windows: @@ -716,6 +720,10 @@ class Tester(TestCmd.TestCmd): # Compiled Python files created when running Python based Boost Build. self.ignore("*.pyc") + # OSX/Darwin files and dirs. + self.ignore("*.dSYM/*") + + def expect_nothing_more(self): if not self.unexpected_difference.empty(): annotation("failure", "Unexpected changes found") output = StringIO.StringIO() @@ -727,10 +735,10 @@ class Tester(TestCmd.TestCmd): self.__expect_lines(self.stdout(), lines, expected) def expect_content_lines(self, filename, line, expected=True): - self.__expect_lines(self.__read_file(filename), line, expected) + self.__expect_lines(self.read_and_strip(filename), line, expected) def expect_content(self, name, content, exact=False): - actual = self.__read_file(name, exact) + actual = self.read(name) content = content.replace("$toolset", self.toolset + "*") matched = False @@ -738,7 +746,7 @@ class Tester(TestCmd.TestCmd): matched = fnmatch.fnmatch(actual, content) else: def sorted_(x): - x.sort() + x.sort(lambda x, y: cmp(x.lower().replace("\\","/"), y.lower().replace("\\","/"))) return x actual_ = map(lambda x: sorted_(x.split()), actual.splitlines()) content_ = map(lambda x: sorted_(x.split()), content.splitlines()) @@ -827,10 +835,15 @@ class Tester(TestCmd.TestCmd): r = map(self.adjust_suffix, r) r = map(lambda x, t=self.toolset: x.replace("$toolset", t + "*"), r) return r + + def adjust_name(self, name): + return self.adjust_names(name)[0] + + def __native_file_name(self, name): + return os.path.normpath(os.path.join(self.workdir, *name.split("/"))) def native_file_name(self, name): - name = self.adjust_names(name)[0] - return os.path.normpath(os.path.join(self.workdir, *name.split("/"))) + return self.__native_file_name(self.adjust_name(name)) def wait_for_time_change(self, path, touch): """ @@ -1061,19 +1074,6 @@ class Tester(TestCmd.TestCmd): return next index += 1 - def __read_file(self, name, exact=False): - name = self.adjust_names(name)[0] - result = "" - try: - if exact: - result = self.read(name) - else: - result = self.read_and_strip(name).replace("\\", "/") - except (IOError, IndexError): - print "Note: could not open file", name - self.fail_test(1) - return result - def __wait_for_time_change(self, path, touch, last_build_time): """ Wait until a newly assigned file system modification timestamp for diff --git a/test/absolute_sources.py b/test/absolute_sources.py index 64cd770e1..22ff1d080 100644 --- a/test/absolute_sources.py +++ b/test/absolute_sources.py @@ -20,7 +20,7 @@ t.write("hello.cpp", "int main() {}\n") t.write("empty.cpp", "\n") t.run_build_system() -t.expect_addition("bin/$toolset/debug/hello.exe") +t.expect_addition("bin/$toolset/debug*/hello.exe") t.rm(".") # Test a contrived case in which an absolute name is used in a standalone @@ -53,7 +53,7 @@ alias('a', [os.path.join(pwd, 'a.cpp')]) """) t.run_build_system() -t.expect_addition("bin/$toolset/debug/a.exe") +t.expect_addition("bin/$toolset/debug*/a.exe") # Test absolute path in target ids. t.rm(".") @@ -68,6 +68,6 @@ alias x : $(pwd)/../d1//a ; """) t.run_build_system(subdir="d2") -t.expect_addition("d1/bin/$toolset/debug/a.exe") +t.expect_addition("d1/bin/$toolset/debug*/a.exe") t.cleanup() diff --git a/test/alias.py b/test/alias.py index 7ac4c6109..53371f4e6 100644 --- a/test/alias.py +++ b/test/alias.py @@ -38,20 +38,20 @@ exe hello : hello.cpp src ; # Check that targets to which "bin1" refers are updated, and only those. t.run_build_system(["bin1"]) - t.expect_addition(BoostBuild.List("bin/$toolset/debug/") * "a.exe a.obj") + t.expect_addition(BoostBuild.List("bin/$toolset/debug*/") * "a.exe a.obj") t.expect_nothing_more() # Try again with "bin2" t.run_build_system(["bin2"]) - t.expect_addition(BoostBuild.List("bin/$toolset/debug/") * "b.exe b.obj") + t.expect_addition(BoostBuild.List("bin/$toolset/debug*/") * "b.exe b.obj") t.expect_nothing_more() # Try building everything, making sure 'hello' target is created. t.run_build_system() - t.expect_addition(BoostBuild.List("bin/$toolset/debug/") * \ + t.expect_addition(BoostBuild.List("bin/$toolset/debug*/") * \ "hello.exe hello.obj") - t.expect_addition("bin/$toolset/debug/s.obj") - t.expect_addition(BoostBuild.List("bin/$toolset/debug/") * "c.exe c.obj") + t.expect_addition("bin/$toolset/debug*/s.obj") + t.expect_addition(BoostBuild.List("bin/$toolset/debug*/") * "c.exe c.obj") t.expect_nothing_more() diff --git a/test/alternatives.py b/test/alternatives.py index 645927304..e8f9220ff 100644 --- a/test/alternatives.py +++ b/test/alternatives.py @@ -26,7 +26,7 @@ t.write("a.cpp", "int main() {}\n") t.run_build_system(["release"]) -t.expect_addition("bin/$toolset/release/a.exe") +t.expect_addition("bin/$toolset/release*/a.exe") # Test that alternative selection works for ordinary properties, in particular # user-defined. @@ -43,10 +43,10 @@ t.write("b.cpp", "int main() {}\n") t.rm("bin") t.run_build_system() -t.expect_addition("bin/$toolset/debug/b.obj") +t.expect_addition("bin/$toolset/debug*/b.obj") t.run_build_system(["X=on"]) -t.expect_addition("bin/$toolset/debug/X-on/a.obj") +t.expect_addition("bin/$toolset/debug/X-on*/a.obj") t.rm("bin") @@ -57,7 +57,7 @@ exe a : a.cpp : debug ; """) t.run_build_system() -t.expect_addition("bin/$toolset/debug/a.exe") +t.expect_addition("bin/$toolset/debug*/a.exe") # Test that only properties which are in the build request matter for # alternative selection. IOW, alternative with release is better than @@ -68,7 +68,7 @@ exe a : a.cpp : release ; """) t.run_build_system(["release"]) -t.expect_addition("bin/$toolset/release/a.exe") +t.expect_addition("bin/$toolset/release*/a.exe") # Test that free properties do not matter. We really do not want # property in build request to affect alternative selection. @@ -78,8 +78,9 @@ exe a : a.cpp : release ; """) t.rm("bin/$toolset/release/a.exe") +t.rm("bin/$toolset/release/*/a.exe") t.run_build_system(["release", "define=FOO"]) -t.expect_addition("bin/$toolset/release/a.exe") +t.expect_addition("bin/$toolset/release*/a.exe") # Test that ambiguity is reported correctly. t.write("jamfile.jam", """\ diff --git a/test/build_dir.py b/test/build_dir.py index 50c2a906c..3b5551e21 100644 --- a/test/build_dir.py +++ b/test/build_dir.py @@ -31,8 +31,8 @@ t.write("src/b.cpp", "int main() {}\n") t.run_build_system() -t.expect_addition(["build/$toolset/debug/a.exe", - "build/src/$toolset/debug/b.exe"]) +t.expect_addition(["build/$toolset/debug*/a.exe", + "build/src/$toolset/debug*/b.exe"]) # Test that building from child projects work. t.run_build_system(subdir='src') @@ -52,8 +52,8 @@ exe b : b.cpp ; """) t.run_build_system() -t.expect_addition(["bin/$toolset/debug/a.exe", - "src/build/$toolset/debug/b.exe"]) +t.expect_addition(["bin/$toolset/debug*/a.exe", + "src/build/$toolset/debug*/b.exe"]) # Now test the '--build-dir' option. t.rm(".") @@ -74,8 +74,8 @@ t.write("sub/jamfile.jam", "exe b : b.cpp ;\n") t.write("sub/b.cpp", "int main() {}\n") t.run_build_system(["--build-dir=build"]) -t.expect_addition(["build/foo/$toolset/debug/a.exe", - "build/foo/sub/$toolset/debug/b.exe"]) +t.expect_addition(["build/foo/$toolset/debug*/a.exe", + "build/foo/sub/$toolset/debug*/b.exe"]) t.write("jamroot.jam", """\ project foo : build-dir bin.v2 ; @@ -84,15 +84,15 @@ build-project sub ; """) t.run_build_system(["--build-dir=build"]) -t.expect_addition(["build/foo/bin.v2/$toolset/debug/a.exe", - "build/foo/bin.v2/sub/$toolset/debug/b.exe"]) +t.expect_addition(["build/foo/bin.v2/$toolset/debug*/a.exe", + "build/foo/bin.v2/sub/$toolset/debug*/b.exe"]) # Try building in subdir. We expect that the entire build tree with be in # 'sub/build'. Today, I am not sure if this is what the user expects, but let # it be. t.rm('build') t.run_build_system(["--build-dir=build"], subdir="sub") -t.expect_addition(["sub/build/foo/bin.v2/sub/$toolset/debug/b.exe"]) +t.expect_addition(["sub/build/foo/bin.v2/sub/$toolset/debug*/b.exe"]) t.write("jamroot.jam", """\ project foo : build-dir %s ; diff --git a/test/build_file.py b/test/build_file.py index d670af428..1ae860917 100644 --- a/test/build_file.py +++ b/test/build_file.py @@ -37,7 +37,7 @@ exe sub : hello.cpp ; t.run_build_system(["sub", t.adjust_suffix("hello.obj")]) t.expect_output_lines("*depends on itself*", False) - t.expect_addition("sub/bin/$toolset/debug/hello.obj") + t.expect_addition("sub/bin/$toolset/debug*/hello.obj") t.expect_nothing_more() t.cleanup() @@ -63,7 +63,7 @@ exe hello3 : hello3.cpp ; t.write("hello3.cpp", "int main() {}\n") t.run_build_system(["hello1", t.adjust_suffix("hello1.obj")]) - t.expect_addition("bin/$toolset/debug/hello1.obj") + t.expect_addition("bin/$toolset/debug*/hello1.obj") t.expect_nothing_more() t.cleanup() @@ -117,8 +117,8 @@ exe hello3 : hello3.cpp ; t.run_build_system([t.adjust_suffix("hello1.obj"), t.adjust_suffix( "hello2.obj")]) - t.expect_addition("bin/$toolset/debug/hello1.obj") - t.expect_addition("bin/$toolset/debug/hello2.obj") + t.expect_addition("bin/$toolset/debug*/hello1.obj") + t.expect_addition("bin/$toolset/debug*/hello2.obj") t.expect_nothing_more() t.cleanup() @@ -149,8 +149,8 @@ exe sub : hello.cpp ; t.run_build_system([t.adjust_suffix("hello.obj")]) t.expect_output_lines("*depends on itself*", False) - t.expect_addition("bin/$toolset/debug/hello.obj") - t.expect_addition("sub/bin/$toolset/debug/hello.obj") + t.expect_addition("bin/$toolset/debug*/hello.obj") + t.expect_addition("sub/bin/$toolset/debug*/hello.obj") t.expect_nothing_more() t.cleanup() diff --git a/test/build_no.py b/test/build_no.py index 07b45804e..771e697a7 100644 --- a/test/build_no.py +++ b/test/build_no.py @@ -18,6 +18,6 @@ t.run_build_system() t.expect_nothing_more() t.run_build_system(["release"]) -t.expect_addition("bin/$toolset/release/hello.exe") +t.expect_addition("bin/$toolset/release*/hello.exe") t.cleanup() diff --git a/test/builtin_glob_archive.py b/test/builtin_glob_archive.py index d9eed3aef..847b14ac7 100644 --- a/test/builtin_glob_archive.py +++ b/test/builtin_glob_archive.py @@ -64,7 +64,7 @@ static-lib %s : t.write("lib/jamfile.jam", output.getvalue()) create_sources("lib", sources) t.run_build_system(subdir="lib") - built_archive = "lib/bin/$toolset/debug/%s" % name + built_archive = "lib/bin/$toolset/debug*/%s" % name t.expect_addition(built_archive) t.copy(built_archive, name) t.rm("lib") diff --git a/test/c_file.py b/test/c_file.py index 672fd4802..85407d5f1 100644 --- a/test/c_file.py +++ b/test/c_file.py @@ -31,6 +31,6 @@ int foo() """) t.run_build_system() -t.expect_addition("bin/$toolset/debug/hello.exe") +t.expect_addition("bin/$toolset/debug*/hello.exe") t.cleanup() diff --git a/test/chain.py b/test/chain.py index 4a39f520e..981e6ad11 100644 --- a/test/chain.py +++ b/test/chain.py @@ -51,6 +51,6 @@ t.write("dummy.cpp", "// msvc needs at least one object file\n") t.run_build_system() -t.expect_addition("bin/$toolset/debug/a.exe") +t.expect_addition("bin/$toolset/debug*/a.exe") t.cleanup() diff --git a/test/clean.py b/test/clean.py index b10644aac..dc72b924c 100644 --- a/test/clean.py +++ b/test/clean.py @@ -49,47 +49,47 @@ void sub3() {} # 'clean' should not remove files under separate jamroot.jam. t.run_build_system() t.run_build_system(["--clean"]) -t.expect_removal("bin/$toolset/debug/a.obj") -t.expect_removal("sub1/bin/$toolset/debug/sub1.obj") -t.expect_removal("sub1/bin/$toolset/debug/sub1_2.obj") -t.expect_removal("sub2/bin/$toolset/debug/sub2.obj") -t.expect_nothing("sub3/bin/$toolset/debug/sub3.obj") +t.expect_removal("bin/$toolset/debug*/a.obj") +t.expect_removal("sub1/bin/$toolset/debug*/sub1.obj") +t.expect_removal("sub1/bin/$toolset/debug*/sub1_2.obj") +t.expect_removal("sub2/bin/$toolset/debug*/sub2.obj") +t.expect_nothing("sub3/bin/$toolset/debug*/sub3.obj") # 'clean-all' removes everything it can reach. t.run_build_system() t.run_build_system(["--clean-all"]) -t.expect_removal("bin/$toolset/debug/a.obj") -t.expect_removal("sub1/bin/$toolset/debug/sub1.obj") -t.expect_removal("sub1/bin/$toolset/debug/sub1_2.obj") -t.expect_removal("sub2/bin/$toolset/debug/sub2.obj") -t.expect_nothing("sub3/bin/$toolset/debug/sub3.obj") +t.expect_removal("bin/$toolset/debug*/a.obj") +t.expect_removal("sub1/bin/$toolset/debug*/sub1.obj") +t.expect_removal("sub1/bin/$toolset/debug*/sub1_2.obj") +t.expect_removal("sub2/bin/$toolset/debug*/sub2.obj") +t.expect_nothing("sub3/bin/$toolset/debug*/sub3.obj") # 'clean' together with project target removes only under that project. t.run_build_system() t.run_build_system(["sub1", "--clean"]) -t.expect_nothing("bin/$toolset/debug/a.obj") -t.expect_removal("sub1/bin/$toolset/debug/sub1.obj") -t.expect_removal("sub1/bin/$toolset/debug/sub1_2.obj") -t.expect_nothing("sub2/bin/$toolset/debug/sub2.obj") -t.expect_nothing("sub3/bin/$toolset/debug/sub3.obj") +t.expect_nothing("bin/$toolset/debug*/a.obj") +t.expect_removal("sub1/bin/$toolset/debug*/sub1.obj") +t.expect_removal("sub1/bin/$toolset/debug*/sub1_2.obj") +t.expect_nothing("sub2/bin/$toolset/debug*/sub2.obj") +t.expect_nothing("sub3/bin/$toolset/debug*/sub3.obj") # 'clean-all' removes everything. t.run_build_system() t.run_build_system(["sub1", "--clean-all"]) -t.expect_nothing("bin/$toolset/debug/a.obj") -t.expect_removal("sub1/bin/$toolset/debug/sub1.obj") -t.expect_removal("sub1/bin/$toolset/debug/sub1_2.obj") -t.expect_removal("sub2/bin/$toolset/debug/sub2.obj") -t.expect_nothing("sub3/bin/$toolset/debug/sub3.obj") +t.expect_nothing("bin/$toolset/debug*/a.obj") +t.expect_removal("sub1/bin/$toolset/debug*/sub1.obj") +t.expect_removal("sub1/bin/$toolset/debug*/sub1_2.obj") +t.expect_removal("sub2/bin/$toolset/debug*/sub2.obj") +t.expect_nothing("sub3/bin/$toolset/debug*/sub3.obj") # If main target is explicitly named, we should not remove files from other # targets. t.run_build_system() t.run_build_system(["sub1//sub1", "--clean"]) -t.expect_removal("sub1/bin/$toolset/debug/sub1.obj") -t.expect_nothing("sub1/bin/$toolset/debug/sub1_2.obj") -t.expect_nothing("sub2/bin/$toolset/debug/sub2.obj") -t.expect_nothing("sub3/bin/$toolset/debug/sub3.obj") +t.expect_removal("sub1/bin/$toolset/debug*/sub1.obj") +t.expect_nothing("sub1/bin/$toolset/debug*/sub1_2.obj") +t.expect_nothing("sub2/bin/$toolset/debug*/sub2.obj") +t.expect_nothing("sub3/bin/$toolset/debug*/sub3.obj") # Regression test: sources of the 'cast' rule were mistakenly deleted. t.rm(".") diff --git a/test/composite.py b/test/composite.py index a35b88d1a..e3a334b4f 100644 --- a/test/composite.py +++ b/test/composite.py @@ -20,6 +20,6 @@ int main() {} t.run_build_system() -t.expect_addition("bin/$toolset/release/hello.exe") +t.expect_addition("bin/$toolset/release*/hello.exe") t.cleanup() diff --git a/test/conditionals.py b/test/conditionals.py index 7a9848b36..3ad36466c 100644 --- a/test/conditionals.py +++ b/test/conditionals.py @@ -23,7 +23,7 @@ int main() {} # Test conditionals in target requirements. t.write("jamroot.jam", "exe a : a.cpp : static:STATIC ;") t.run_build_system(["link=static"]) -t.expect_addition("bin/$toolset/debug/link-static/a.exe") +t.expect_addition("bin/$toolset/debug/link-static*/a.exe") t.rm("bin") # Test conditionals in project requirements. @@ -32,7 +32,7 @@ project : requirements static:STATIC ; exe a : a.cpp ; """) t.run_build_system(["link=static"]) -t.expect_addition("bin/$toolset/debug/link-static/a.exe") +t.expect_addition("bin/$toolset/debug/link-static*/a.exe") t.rm("bin") # Regression test for a bug found by Ali Azarbayejani. Conditionals inside @@ -43,6 +43,6 @@ exe a : a.cpp l ; """) t.write("l.cpp", "int i;") t.run_build_system(["link=static"]) -t.expect_addition("bin/$toolset/debug/link-static/a.exe") +t.expect_addition("bin/$toolset/debug/link-static*/a.exe") t.cleanup() diff --git a/test/conditionals3.py b/test/conditionals3.py index 028fad621..67c04c429 100644 --- a/test/conditionals3.py +++ b/test/conditionals3.py @@ -25,6 +25,6 @@ int main() """) t.run_build_system(stdout=None, stderr=None) -t.expect_addition("bin/$toolset/debug/hello.exe") +t.expect_addition("bin/$toolset/debug*/hello.exe") t.cleanup() diff --git a/test/copy_time.py b/test/copy_time.py index 4bdaa88f7..5fd4b8fdf 100755 --- a/test/copy_time.py +++ b/test/copy_time.py @@ -50,13 +50,13 @@ install test2i : test2 : test1 ; """) tester.run_build_system() -tester.expect_addition("bin/$toolset/debug/test2.obj") -tester.expect_addition("bin/$toolset/debug/test1.obj") +tester.expect_addition("bin/$toolset/debug*/test2.obj") +tester.expect_addition("bin/$toolset/debug*/test1.obj") tester.expect_addition("test2i/test2.obj") tester.expect_nothing_more() test2src = tester.read("test2i/test2.obj") -test2dest = tester.read("bin/$toolset/debug/test2.obj") +test2dest = tester.read("bin/$toolset/debug*/test2.obj") if test2src != test2dest: BoostBuild.annotation("failure", "The object file was not copied " "correctly") diff --git a/test/custom_generator.py b/test/custom_generator.py index 8c477a6f2..f98a46878 100644 --- a/test/custom_generator.py +++ b/test/custom_generator.py @@ -61,6 +61,6 @@ t.write("r.rcc", """ """) t.run_build_system() -t.expect_content("bin/$toolset/debug/r.obj", "rc-object") +t.expect_content("bin/$toolset/debug*/r.obj", "rc-object") t.cleanup() diff --git a/test/default_build.py b/test/default_build.py index f6c830210..6206507f4 100644 --- a/test/default_build.py +++ b/test/default_build.py @@ -16,20 +16,20 @@ t.write("jamfile.jam", "exe a : a.cpp : : debug release ;") t.write("a.cpp", "int main() {}\n") t.run_build_system() -t.expect_addition("bin/$toolset/debug/a.exe") -t.expect_addition("bin/$toolset/release/a.exe") +t.expect_addition("bin/$toolset/debug*/a.exe") +t.expect_addition("bin/$toolset/release*/a.exe") # Check that explictly-specified build variant suppresses default-build. t.rm("bin") t.run_build_system(["release"]) -t.expect_addition(BoostBuild.List("bin/$toolset/release/") * "a.exe a.obj") +t.expect_addition(BoostBuild.List("bin/$toolset/release*/") * "a.exe a.obj") t.expect_nothing_more() # Now check that we can specify explicit build request and default-build will be # combined with it. t.run_build_system(["optimization=space"]) -t.expect_addition("bin/$toolset/debug/optimization-space/a.exe") -t.expect_addition("bin/$toolset/release/optimization-space/a.exe") +t.expect_addition("bin/$toolset/debug/optimization-space*/a.exe") +t.expect_addition("bin/$toolset/release/optimization-space*/a.exe") # Test that default-build must be identical in all alternatives. Error case. t.write("jamfile.jam", """\ diff --git a/test/default_features.py b/test/default_features.py index 0d285a3f9..1d6d72a6f 100644 --- a/test/default_features.py +++ b/test/default_features.py @@ -45,6 +45,6 @@ void foo() {} t.run_build_system() -t.expect_addition("bin/$toolset/debug/hello.exe") +t.expect_addition("bin/$toolset/debug*/hello.exe") t.cleanup() diff --git a/test/dependency_test.py b/test/dependency_test.py index d53ce69a7..a495affff 100644 --- a/test/dependency_test.py +++ b/test/dependency_test.py @@ -144,7 +144,7 @@ get_manager().engine().register_action("foo.foo", # Check that main target 'c' was able to find 'x.h' from 'a's dependency # graph. t.run_build_system() - t.expect_addition("bin/$toolset/debug/c.exe") + t.expect_addition("bin/$toolset/debug*/c.exe") # Check handling of first level includes. @@ -152,35 +152,35 @@ get_manager().engine().register_action("foo.foo", t.touch("a.h") t.run_build_system() - t.expect_touch("bin/$toolset/debug/a.exe") - t.expect_touch("bin/$toolset/debug/a.obj") - t.expect_touch("bin/$toolset/debug/a_c.obj") - t.expect_touch("bin/$toolset/debug/b.exe") - t.expect_touch("bin/$toolset/debug/b.obj") + t.expect_touch("bin/$toolset/debug*/a.exe") + t.expect_touch("bin/$toolset/debug*/a.obj") + t.expect_touch("bin/$toolset/debug*/a_c.obj") + t.expect_touch("bin/$toolset/debug*/b.exe") + t.expect_touch("bin/$toolset/debug*/b.obj") t.expect_nothing_more() # Only source files using include should be compiled. t.touch("src1/a.h") t.run_build_system() - t.expect_touch("bin/$toolset/debug/a.exe") - t.expect_touch("bin/$toolset/debug/a.obj") - t.expect_touch("bin/$toolset/debug/a_c.obj") + t.expect_touch("bin/$toolset/debug*/a.exe") + t.expect_touch("bin/$toolset/debug*/a.obj") + t.expect_touch("bin/$toolset/debug*/a_c.obj") t.expect_nothing_more() # "src/a.h" includes "b.h" (in the same dir). t.touch("src1/b.h") t.run_build_system() - t.expect_touch("bin/$toolset/debug/a.exe") - t.expect_touch("bin/$toolset/debug/a.obj") - t.expect_touch("bin/$toolset/debug/a_c.obj") + t.expect_touch("bin/$toolset/debug*/a.exe") + t.expect_touch("bin/$toolset/debug*/a.obj") + t.expect_touch("bin/$toolset/debug*/a_c.obj") t.expect_nothing_more() # Included by "src/b.h". We had a bug: file included using double quotes # (e.g. "b.h") was not scanned at all in this case. t.touch("src1/c.h") t.run_build_system() - t.expect_touch("bin/$toolset/debug/a.exe") + t.expect_touch("bin/$toolset/debug*/a.exe") t.touch("b.h") t.run_build_system() @@ -193,14 +193,14 @@ get_manager().engine().register_action("foo.foo", # this check will be implemented later. t.touch("x.foo") t.run_build_system() - t.expect_touch("bin/$toolset/debug/a.obj") - t.expect_touch("bin/$toolset/debug/a_c.obj") + t.expect_touch("bin/$toolset/debug*/a.obj") + t.expect_touch("bin/$toolset/debug*/a_c.obj") # Check that generated headers are scanned for dependencies as well. t.touch("src1/z.h") t.run_build_system() - t.expect_touch("bin/$toolset/debug/a.obj") - t.expect_touch("bin/$toolset/debug/a_c.obj") + t.expect_touch("bin/$toolset/debug*/a.obj") + t.expect_touch("bin/$toolset/debug*/a_c.obj") t.cleanup() @@ -226,11 +226,11 @@ int main() {} t.write("include/dir/header.h", "\n") t.run_build_system() - t.expect_addition("bin/$toolset/debug/main.obj") + t.expect_addition("bin/$toolset/debug*/main.obj") t.touch("include/dir/header.h") t.run_build_system() - t.expect_touch("bin/$toolset/debug/main.obj") + t.expect_touch("bin/$toolset/debug*/main.obj") t.cleanup() diff --git a/test/direct_request_test.py b/test/direct_request_test.py index 49a083202..422276938 100644 --- a/test/direct_request_test.py +++ b/test/direct_request_test.py @@ -36,14 +36,14 @@ int __declspec(dllexport) force_implib_creation; """) t.run_build_system(["define=MACROS"]) -t.expect_addition("bin/$toolset/debug/" +t.expect_addition("bin/$toolset/debug*/" * (BoostBuild.List("a.obj b.obj b.dll a.exe"))) # When building a debug version, the 'define' still applies. t.rm("bin") t.run_build_system(["debug", "define=MACROS"]) -t.expect_addition("bin/$toolset/debug/" +t.expect_addition("bin/$toolset/debug*/" * (BoostBuild.List("a.obj b.obj b.dll a.exe"))) diff --git a/test/disambiguation.py b/test/disambiguation.py index 72867e0a1..9544aa0f6 100644 --- a/test/disambiguation.py +++ b/test/disambiguation.py @@ -25,8 +25,8 @@ int main() {} t.run_build_system() -t.expect_addition("bin/$toolset/debug/hello.exe") -t.expect_addition("bin/$toolset/debug/hello.obj") -t.expect_addition("bin/$toolset/release/hello.obj") +t.expect_addition("bin/$toolset/debug*/hello.exe") +t.expect_addition("bin/$toolset/debug*/hello.obj") +t.expect_addition("bin/$toolset/release*/hello.obj") t.cleanup() diff --git a/test/dll_path.py b/test/dll_path.py index 60acf6a49..e71b704b9 100644 --- a/test/dll_path.py +++ b/test/dll_path.py @@ -135,12 +135,12 @@ bar() {} t.run_build_system(["hardcode-dll-paths=true"]) -t.expect_addition("bin/$toolset/debug/mp.pathlist") +t.expect_addition("bin/$toolset/debug*/mp.pathlist") -es1 = t.adjust_names("a/bin/$toolset/debug")[0] -es2 = t.adjust_names("b/bin/$toolset/debug")[0] +es1 = t.adjust_name("a/bin/$toolset/debug*") +es2 = t.adjust_name("b/bin/$toolset/debug*") -t.expect_content_lines("bin/$toolset/debug/mp.pathlist", "*" + es1); -t.expect_content_lines("bin/$toolset/debug/mp.pathlist", "*" + es2); +t.expect_content_lines("bin/$toolset/debug*/mp.pathlist", "*" + es1); +t.expect_content_lines("bin/$toolset/debug*/mp.pathlist", "*" + es2); t.cleanup() diff --git a/test/example_customization.py b/test/example_customization.py index f8fe15cc2..462de5622 100644 --- a/test/example_customization.py +++ b/test/example_customization.py @@ -15,7 +15,7 @@ t.set_tree("../example/customization") t.run_build_system() -t.expect_addition(["bin/$toolset/debug/codegen.exe", - "bin/$toolset/debug/usage.cpp"]) +t.expect_addition(["bin/$toolset/debug*/codegen.exe", + "bin/$toolset/debug*/usage.cpp"]) t.cleanup() diff --git a/test/example_gettext.py b/test/example_gettext.py index e7cfa8eb7..dc178568e 100644 --- a/test/example_gettext.py +++ b/test/example_gettext.py @@ -17,10 +17,10 @@ t.set_tree("../example/gettext") t.run_build_system(stderr=None) -t.expect_addition(["bin/$toolset/debug/main.exe", - "bin/$toolset/debug/russian.mo"]) +t.expect_addition(["bin/$toolset/debug*/main.exe", + "bin/$toolset/debug*/russian.mo"]) -file = t.adjust_names(["bin/$toolset/debug/main.exe"])[0] +file = t.adjust_names(["bin/$toolset/debug*/main.exe"])[0] input_fd = os.popen(file) input = input_fd.read(); diff --git a/test/example_libraries.py b/test/example_libraries.py index 3097bd952..60607b149 100644 --- a/test/example_libraries.py +++ b/test/example_libraries.py @@ -15,7 +15,7 @@ t.set_tree("../example/libraries") t.run_build_system() -t.expect_addition(["app/bin/$toolset/debug/app.exe", - "util/foo/bin/$toolset/debug/bar.dll"]) +t.expect_addition(["app/bin/$toolset/debug*/app.exe", + "util/foo/bin/$toolset/debug*/bar.dll"]) t.cleanup() diff --git a/test/example_make.py b/test/example_make.py index 270541829..e65158ec2 100644 --- a/test/example_make.py +++ b/test/example_make.py @@ -13,5 +13,5 @@ import sys t = BoostBuild.Tester(['example.python.interpreter=%s' % sys.executable]) t.set_tree("../example/make") t.run_build_system() -t.expect_addition(["bin/$toolset/debug/main.cpp"]) +t.expect_addition(["bin/$toolset/debug*/main.cpp"]) t.cleanup() diff --git a/test/example_qt4.py b/test/example_qt4.py index 1b0dc27bd..936e6f718 100644 --- a/test/example_qt4.py +++ b/test/example_qt4.py @@ -13,14 +13,14 @@ t = BoostBuild.Tester() t.set_tree("../example/qt/qt4/hello") t.run_build_system() -t.expect_addition(["bin/$toolset/debug/threading-multi/arrow"]) +t.expect_addition(["bin/$toolset/debug*/threading-multi/arrow"]) t.set_tree("../example/qt/qt4/moccable-cpp") t.run_build_system() -t.expect_addition(["bin/$toolset/debug/threading-multi/main"]) +t.expect_addition(["bin/$toolset/debug*/threading-multi/main"]) t.set_tree("../example/qt/qt4/uic") t.run_build_system() -t.expect_addition(["bin/$toolset/debug/threading-multi/hello"]) +t.expect_addition(["bin/$toolset/debug*/threading-multi/hello"]) t.cleanup() diff --git a/test/expansion.py b/test/expansion.py index f49cbd833..c5bd30379 100644 --- a/test/expansion.py +++ b/test/expansion.py @@ -51,9 +51,9 @@ feature.compose 1 : CF_1 ; t.expand_toolset("jamfile.jam") t.run_build_system() -t.expect_addition(["bin/$toolset/debug/a.exe", - "bin/$toolset/debug/b.exe", - "bin/$toolset/release/c.exe"]) +t.expect_addition(["bin/$toolset/debug*/a.exe", + "bin/$toolset/debug*/b.exe", + "bin/$toolset/release*/c.exe"]) t.rm("bin") @@ -75,6 +75,6 @@ t.write("foo/header.h", "\n") t.write("jamroot.jam", "") t.run_build_system() -t.expect_addition("bin/$toolset/debug/test.exe") +t.expect_addition("bin/$toolset/debug*/test.exe") t.cleanup() diff --git a/test/explicit.py b/test/explicit.py index 387f3646c..14d421752 100644 --- a/test/explicit.py +++ b/test/explicit.py @@ -18,12 +18,12 @@ t.write("hello.cpp", "int main() {}\n") t.run_build_system() t.ignore("*.tds") -t.expect_addition(BoostBuild.List("bin/$toolset/debug/hello") * \ +t.expect_addition(BoostBuild.List("bin/$toolset/debug*/hello") * \ [".exe", ".obj"]) t.expect_nothing_more() t.run_build_system(["hello2"]) -t.expect_addition("bin/$toolset/debug/hello2.exe") +t.expect_addition("bin/$toolset/debug*/hello2.exe") t.rm(".") diff --git a/test/feature_cxxflags.py b/test/feature_cxxflags.py index 76e8b20d7..a4eeb52d4 100755 --- a/test/feature_cxxflags.py +++ b/test/feature_cxxflags.py @@ -31,7 +31,7 @@ t.write("test.c", """ """) t.run_build_system() -t.expect_addition("bin/$toolset/debug/test-cpp.obj") -t.expect_addition("bin/$toolset/debug/test-c.obj") +t.expect_addition("bin/$toolset/debug*/test-cpp.obj") +t.expect_addition("bin/$toolset/debug*/test-c.obj") t.cleanup() diff --git a/test/free_features_request.py b/test/free_features_request.py index e7949d145..c6bb4e9d6 100644 --- a/test/free_features_request.py +++ b/test/free_features_request.py @@ -37,6 +37,6 @@ void foo() {} # error at this point. t.run_build_system(["hello", "define=FOO"]) -t.expect_addition("bin/$toolset/debug/hello.exe") +t.expect_addition("bin/$toolset/debug*/hello.exe") t.cleanup() diff --git a/test/gcc_runtime.py b/test/gcc_runtime.py index bc56eae9f..28b6410a5 100644 --- a/test/gcc_runtime.py +++ b/test/gcc_runtime.py @@ -20,7 +20,7 @@ t.expect_output_lines("warning: On gcc, DLLs can not be built with " t.expect_nothing_more() t.run_build_system(["link=static", "runtime-link=static"]) -binFolder = "bin/$toolset/debug/link-static/runtime-link-static" +binFolder = "bin/$toolset/debug*/link-static/runtime-link-static" t.expect_addition("%s/hello.obj" % binFolder) t.expect_addition("%s/hello.lib" % binFolder) t.expect_nothing_more() diff --git a/test/generator_selection.py b/test/generator_selection.py index 87f0df33a..64f9cc7b3 100755 --- a/test/generator_selection.py +++ b/test/generator_selection.py @@ -87,9 +87,9 @@ my-obj other-obj : source.extension ; t.run_build_system() t.expect_output_lines("Generating a CPP file...") - t.expect_addition("bin/$toolset/debug/dummy.my_obj") - t.expect_addition("Other/bin/$toolset/debug/other-obj.cpp") - t.expect_addition("Other/bin/$toolset/debug/other-obj.my_obj") + t.expect_addition("bin/$toolset/debug*/dummy.my_obj") + t.expect_addition("Other/bin/$toolset/debug*/other-obj.cpp") + t.expect_addition("Other/bin/$toolset/debug*/other-obj.my_obj") t.expect_nothing_more() t.cleanup() @@ -139,8 +139,8 @@ yyy other : source.xxx2 ; """) t.run_build_system() - t.expect_addition("bin/$toolset/debug/dummy.yyy") - t.expect_addition("Other/bin/$toolset/debug/other.yyy") + t.expect_addition("bin/$toolset/debug*/dummy.yyy") + t.expect_addition("Other/bin/$toolset/debug*/other.yyy") t.expect_nothing_more() t.cleanup() diff --git a/test/generators_test.py b/test/generators_test.py index 755a391c3..d666d46c2 100644 --- a/test/generators_test.py +++ b/test/generators_test.py @@ -215,17 +215,17 @@ nm-exe e : e.cpp ; """) t.run_build_system() - t.expect_addition("bin/$toolset/debug/" * BoostBuild.List("a.my_exe " + t.expect_addition("bin/$toolset/debug*/" * BoostBuild.List("a.my_exe " "a.my_obj b.my_obj c.tui_h c.cpp c.my_obj d_parser.whl d_lexer.dlp " "d_parser.cpp d_lexer.cpp d_lexer.my_obj d_parser.lr0 d_parser.h " "d_parser.my_obj d_parser_symbols.h x.c x.my_obj y.x1 y.x2 y.cpp " "y.my_obj e.marked_cpp e.positions e.target_cpp e.my_obj e.my_exe " "f.my_exe obj_1.my_obj obj_2.my_obj")) - t.expect_addition("lib/bin/$toolset/debug/" * BoostBuild.List("c.my_obj " + t.expect_addition("lib/bin/$toolset/debug*/" * BoostBuild.List("c.my_obj " "auxilliary.my_lib")) t.expect_nothing_more() - folder = "bin/$toolset/debug" + folder = "bin/$toolset/debug*" t.expect_content_lines("%s/obj_1.my_obj" % folder, " Sources: 'z.cpp'") t.expect_content_lines("%s/obj_2.my_obj" % folder, " Sources: 'z.cpp'") t.expect_content_lines("%s/a.my_obj" % folder, " Sources: 'a.cpp'") @@ -311,7 +311,7 @@ ddd _xxx : _xxx._a ; def suffix(rename): if rename: return "_x" return "" - name = "bin/$toolset/debug/_xxx" + name = "bin/$toolset/debug*/_xxx" e = t.expect_addition e("%s%s._b1" % (name, suffix(rename1))) e("%s%s._b2" % (name, suffix(rename2))) diff --git a/test/implicit_dependency.py b/test/implicit_dependency.py index d6392c93a..dac9c7c54 100644 --- a/test/implicit_dependency.py +++ b/test/implicit_dependency.py @@ -43,7 +43,7 @@ int main() { return i; } t.run_build_system() -t.expect_addition("bin/$toolset/debug/hello.exe") +t.expect_addition("bin/$toolset/debug*/hello.exe") t.rm("bin") @@ -76,6 +76,6 @@ int main() { return i; } """) t.run_build_system() -t.expect_addition("bin/$toolset/debug/hello.exe") +t.expect_addition("bin/$toolset/debug*/hello.exe") t.cleanup() diff --git a/test/indirect_conditional.py b/test/indirect_conditional.py index b466910b3..48800f06e 100644 --- a/test/indirect_conditional.py +++ b/test/indirect_conditional.py @@ -55,9 +55,9 @@ rule a3-rule-2 ( properties * ) t.run_build_system() - t.expect_addition("bin/$toolset/debug/a1.exe") - t.expect_addition("bin/$toolset/debug/optimization-speed/a2.exe") - t.expect_addition("bin/$toolset/debug/optimization-speed/a3.exe") + t.expect_addition("bin/$toolset/debug*/a1.exe") + t.expect_addition("bin/$toolset/debug/optimization-speed*/a2.exe") + t.expect_addition("bin/$toolset/debug/optimization-speed*/a3.exe") t.cleanup() diff --git a/test/inherited_dependency.py b/test/inherited_dependency.py index 69eefeb8d..ae939f487 100755 --- a/test/inherited_dependency.py +++ b/test/inherited_dependency.py @@ -40,8 +40,8 @@ exe test1 : test1.cpp ; tester.run_build_system() -tester.expect_addition("bin/$toolset/debug/test.obj") -tester.expect_addition("a/bin/$toolset/debug/test1.exe") +tester.expect_addition("bin/$toolset/debug*/test.obj") +tester.expect_addition("a/bin/$toolset/debug*/test1.exe") tester.rm("bin") tester.rm("a/bin") @@ -55,8 +55,8 @@ tester.rm("a/bin") tester.run_build_system(subdir="a") -tester.expect_addition("bin/$toolset/debug/test.obj") -tester.expect_addition("a/bin/$toolset/debug/test1.exe") +tester.expect_addition("bin/$toolset/debug*/test.obj") +tester.expect_addition("a/bin/$toolset/debug*/test1.exe") tester.rm("bin") tester.rm("a/bin") @@ -76,8 +76,8 @@ build-project a ; tester.run_build_system() -tester.expect_addition("bin/$toolset/debug/test.obj") -tester.expect_addition("a/bin/$toolset/debug/test1.exe") +tester.expect_addition("bin/$toolset/debug*/test.obj") +tester.expect_addition("a/bin/$toolset/debug*/test1.exe") tester.rm("bin") tester.rm("a/bin") @@ -97,8 +97,8 @@ build-project a ; tester.run_build_system() -tester.expect_addition("bin/$toolset/debug/test.obj") -tester.expect_addition("a/bin/$toolset/debug/test1.exe") +tester.expect_addition("bin/$toolset/debug*/test.obj") +tester.expect_addition("a/bin/$toolset/debug*/test1.exe") tester.rm("bin") tester.rm("a/bin") @@ -118,8 +118,8 @@ build-project a ; tester.run_build_system() -tester.expect_addition("bin/$toolset/debug/test.obj") -tester.expect_addition("a/bin/$toolset/debug/test1.exe") +tester.expect_addition("bin/$toolset/debug*/test.obj") +tester.expect_addition("a/bin/$toolset/debug*/test1.exe") tester.rm("bin") tester.rm("a/bin") @@ -141,7 +141,7 @@ exe test : test.cpp ; """) tester.run_build_system() -tester.expect_addition("bin/$toolset/debug/test.exe") +tester.expect_addition("bin/$toolset/debug*/test.exe") tester.rm("bin") tester.rm("a/bin") @@ -162,7 +162,7 @@ exe test : test.cpp ; """) tester.run_build_system() -tester.expect_addition("bin/$toolset/debug/test.exe") +tester.expect_addition("bin/$toolset/debug*/test.exe") tester.rm("bin") tester.rm("a/bin") @@ -200,8 +200,8 @@ int main() { bar(); } """) tester.run_build_system() -tester.expect_addition("b/bin/$toolset/debug/test3.obj") -tester.expect_addition("a/bin/$toolset/debug/test.exe") +tester.expect_addition("b/bin/$toolset/debug*/test3.obj") +tester.expect_addition("a/bin/$toolset/debug*/test.exe") tester.rm("bin") tester.rm("a") @@ -232,6 +232,6 @@ tester.write("a_src/test1.cpp", """ """) tester.run_build_system(subdir="build/a") -tester.expect_addition("build/a/bin/$toolset/debug/test.exe") +tester.expect_addition("build/a/bin/$toolset/debug*/test.exe") tester.cleanup() diff --git a/test/inline.py b/test/inline.py index f076fde6f..d0ce91ae8 100644 --- a/test/inline.py +++ b/test/inline.py @@ -21,11 +21,12 @@ int main() {} t.write("helper.cpp", "void helper() {}\n") t.run_build_system() -t.expect_addition("bin/$toolset/debug/link-static/a__helper.lib") +t.expect_addition("bin/$toolset/debug/link-static*/a__helper.lib") t.rm("bin/$toolset/debug/link-static/a__helper.lib") +t.rm("bin/$toolset/debug/link-static/*/a__helper.lib") t.run_build_system(["a__helper"]) -t.expect_addition("bin/$toolset/debug/link-static/a__helper.lib") +t.expect_addition("bin/$toolset/debug/link-static*/a__helper.lib") t.rm("bin") @@ -39,9 +40,9 @@ exe a2 : a.cpp [ lib helper : helper.cpp ] ; """) t.run_build_system() -t.expect_addition("bin/$toolset/debug/link-static/a.exe") -t.expect_addition("bin/$toolset/debug/link-static/a__helper.lib") -t.expect_addition("bin/$toolset/debug/link-static/a2__helper.lib") +t.expect_addition("bin/$toolset/debug/link-static*/a.exe") +t.expect_addition("bin/$toolset/debug/link-static*/a__helper.lib") +t.expect_addition("bin/$toolset/debug/link-static*/a2__helper.lib") # Check that the 'alias' target does not change the name of inline targets, and @@ -57,6 +58,6 @@ t.run_build_system() t.expect_nothing_more() t.run_build_system(["a"]) -t.expect_addition("bin/$toolset/debug/link-static/helper.lib") +t.expect_addition("bin/$toolset/debug/link-static*/helper.lib") t.cleanup() diff --git a/test/lib_source_property.py b/test/lib_source_property.py index 826729398..24a90773c 100644 --- a/test/lib_source_property.py +++ b/test/lib_source_property.py @@ -25,7 +25,7 @@ void foo() {} """) t.run_build_system() -t.expect_addition("bin/$toolset/debug/a.obj") +t.expect_addition("bin/$toolset/debug*/a.obj") t.rm("bin") @@ -40,6 +40,6 @@ lib a : : @test ; """) t.run_build_system() -t.expect_addition("bin/$toolset/debug/a.obj") +t.expect_addition("bin/$toolset/debug*/a.obj") t.cleanup() diff --git a/test/library_chain.py b/test/library_chain.py index e7c3dcd92..d04f465a4 100644 --- a/test/library_chain.py +++ b/test/library_chain.py @@ -54,11 +54,11 @@ foo() { geek(); } t.write("b/jamfile.jam", "lib b : b.cpp ../a//a ;") t.run_build_system(["-d2"], stderr=None) -t.expect_addition("bin/$toolset/debug/main.exe") +t.expect_addition("bin/$toolset/debug*/main.exe") t.rm(["bin", "a/bin", "b/bin"]) t.run_build_system(["link=static"]) -t.expect_addition("bin/$toolset/debug/link-static/main.exe") +t.expect_addition("bin/$toolset/debug/link-static*/main.exe") t.rm(["bin", "a/bin", "b/bin"]) @@ -66,14 +66,14 @@ t.rm(["bin", "a/bin", "b/bin"]) t.write("b/jamfile.jam", "lib b : b.cpp : ../a//a ;") t.run_build_system(["link=static"]) -t.expect_addition("bin/$toolset/debug/link-static/main.exe") +t.expect_addition("bin/$toolset/debug/link-static*/main.exe") t.rm(["bin", "a/bin", "b/bin"]) t.write("b/jamfile.jam", "lib b : b.cpp ../a//a/shared : static ;") t.run_build_system() -t.expect_addition("bin/$toolset/debug/main.exe") +t.expect_addition("bin/$toolset/debug*/main.exe") t.rm(["bin", "a/bin", "b/bin"]) @@ -88,7 +88,7 @@ lib z : : zzz ; t.run_build_system(["-a", "-d+2"], status=None, stderr=None) # Try to find the "zzz" string either in response file (for Windows compilers), # or in the standard output. -rsp = t.adjust_names("bin/$toolset/debug/main.exe.rsp")[0] +rsp = t.adjust_names("bin/$toolset/debug*/main.exe.rsp")[0] if os.path.exists(rsp) and ( string.find(open(rsp).read(), "zzz") != -1 ): pass elif string.find(t.stdout(), "zzz") != -1: @@ -147,6 +147,6 @@ int main() { b(); } """) t.run_build_system() -t.expect_addition("bin/$toolset/debug/main.exe") +t.expect_addition("bin/$toolset/debug*/main.exe") t.cleanup() diff --git a/test/library_order.py b/test/library_order.py index 188f533ab..4b0585e00 100644 --- a/test/library_order.py +++ b/test/library_order.py @@ -47,7 +47,7 @@ lib liba : a.cpp : libb ; """) t.run_build_system(["-d2"]) -t.expect_addition("bin/$toolset/debug/main.exe") +t.expect_addition("bin/$toolset/debug*/main.exe") # Test the order between searched libraries. diff --git a/test/library_property.py b/test/library_property.py index b7c24c83b..6dc571440 100644 --- a/test/library_property.py +++ b/test/library_property.py @@ -50,7 +50,7 @@ t.write("lib/jamroot.jam", """ t.run_build_system() -t.expect_addition("bin/$toolset/debug/a.exe") +t.expect_addition("bin/$toolset/debug*/a.exe") t.expect_nothing("lib/bin/$toolset/release/x.obj") t.cleanup() diff --git a/test/link.py b/test/link.py index 17b412bf0..4f83e1b09 100755 --- a/test/link.py +++ b/test/link.py @@ -215,7 +215,7 @@ def test_include_scan(): t.run_build_system(["test"]) - t.expect_addition("bin/$toolset/debug/test.obj") + t.expect_addition("bin/$toolset/debug*/test.obj") t.run_build_system() t.expect_nothing_more() @@ -248,7 +248,7 @@ def test_include_scan_merge_existing(): t.run_build_system(["test"]) t.expect_addition("include/file1.h") - t.expect_addition("bin/$toolset/debug/test.obj") + t.expect_addition("bin/$toolset/debug*/test.obj") t.ignore_touch("include/file2.h") t.expect_nothing_more() diff --git a/test/load_dir.py b/test/load_dir.py index 09a59f951..faa47d216 100644 --- a/test/load_dir.py +++ b/test/load_dir.py @@ -51,7 +51,7 @@ footer = """ t.run_build_system() -t.expect_addition("bin/$toolset/debug/FILL_SOME_HERE.exe") +t.expect_addition("bin/$toolset/debug*/FILL_SOME_HERE.exe") t.cleanup() """ diff --git a/test/load_order.py b/test/load_order.py index c35ca8da3..6e0055026 100644 --- a/test/load_order.py +++ b/test/load_order.py @@ -32,7 +32,7 @@ int main() {} t.run_build_system() -t.expect_addition("child/bin/$toolset/debug/main.exe") +t.expect_addition("child/bin/$toolset/debug*/main.exe") t.fail_test(t.stdout().find("Setting child requirements") < t.stdout().find( "Setting parent requirements")) @@ -49,7 +49,7 @@ int main() {} """) t.run_build_system(subdir="src/app") -t.expect_addition("src/app/bin/$toolset/debug/test.exe") +t.expect_addition("src/app/bin/$toolset/debug*/test.exe") # child/child2 used to be loaded before child diff --git a/test/make_rule.py b/test/make_rule.py index f13bdb4cd..4a2e09ad9 100644 --- a/test/make_rule.py +++ b/test/make_rule.py @@ -28,8 +28,8 @@ make foo.bar : : creator : 12345678 ; """) t.run_build_system() -t.expect_addition("bin/$toolset/debug/foo.bar") -t.fail_test(string.find(t.read("bin/$toolset/debug/foo.bar"), "12345678") == -1) +t.expect_addition("bin/$toolset/debug*/foo.bar") +t.fail_test(string.find(t.read("bin/$toolset/debug*/foo.bar"), "12345678") == -1) # Regression test. Make sure that if a main target is requested two times, and diff --git a/test/message.py b/test/message.py index f0f0d3152..5b4f7da81 100755 --- a/test/message.py +++ b/test/message.py @@ -32,7 +32,7 @@ t.write("test.cpp", """ t.run_build_system(["test"], stdout="""Hello World! """) -t.expect_addition("bin/$toolset/link-static/test.obj") +t.expect_addition("bin/$toolset/link-static*/test.obj") t.expect_nothing_more() t.cleanup() diff --git a/test/notfile.py b/test/notfile.py index 10205f6ad..602415ae5 100644 --- a/test/notfile.py +++ b/test/notfile.py @@ -29,7 +29,7 @@ t.run_build_system(["-n", "-d+2"]) t.fail_test(t.stdout().find("echo hi") == -1) -name = t.adjust_names("bin/$toolset/debug/hello.exe")[0] +name = t.adjust_names("bin/$toolset/debug*/hello.exe")[0] name = apply(os.path.join, name.split("/")); t.expect_output_lines(" valgrind *%s " % name) diff --git a/test/ordered_include.py b/test/ordered_include.py index 72ab0d3d7..ef1d8745d 100644 --- a/test/ordered_include.py +++ b/test/ordered_include.py @@ -32,12 +32,12 @@ def test_default_order(): tester.run_build_system() - tester.expect_addition("bin/$toolset/debug/test.obj") + tester.expect_addition("bin/$toolset/debug*/test.obj") # Check that the dependencies are correct tester.touch("a/test.hpp") tester.run_build_system() - tester.expect_touch("bin/$toolset/debug/test.obj") + tester.expect_touch("bin/$toolset/debug*/test.obj") tester.expect_nothing_more() tester.touch("b/test.hpp") @@ -70,12 +70,12 @@ def test_default_order_mixed(): tester.run_build_system() - tester.expect_addition("bin/$toolset/debug/test.obj") + tester.expect_addition("bin/$toolset/debug*/test.obj") # Check that the dependencies are correct tester.touch("a/test.hpp") tester.run_build_system() - tester.expect_touch("bin/$toolset/debug/test.obj") + tester.expect_touch("bin/$toolset/debug*/test.obj") tester.expect_nothing_more() tester.touch("b/test.hpp") @@ -104,16 +104,16 @@ def test_basic(): tester.run_build_system() - tester.expect_addition("bin/$toolset/debug/test.obj") + tester.expect_addition("bin/$toolset/debug*/test.obj") # Check that the dependencies are correct tester.touch("a/test1.hpp") tester.run_build_system() - tester.expect_touch("bin/$toolset/debug/test.obj") + tester.expect_touch("bin/$toolset/debug*/test.obj") tester.touch("b/test2.hpp") tester.run_build_system() - tester.expect_touch("bin/$toolset/debug/test.obj") + tester.expect_touch("bin/$toolset/debug*/test.obj") tester.cleanup() @@ -135,7 +135,7 @@ def test_order1(): t.touch("a/test.h") t.run_build_system() - t.expect_touch("bin/$toolset/debug/test.obj") + t.expect_touch("bin/$toolset/debug*/test.obj") t.expect_nothing_more() t.touch("b/test.h") @@ -166,7 +166,7 @@ def test_order2(): t.touch("b/test.h") t.run_build_system() - t.expect_touch("bin/$toolset/debug/test.obj") + t.expect_touch("bin/$toolset/debug*/test.obj") t.expect_nothing_more() t.cleanup() @@ -203,11 +203,11 @@ def test_order_graph(): t.write("d/test4.h", "#error should find b/test4.h\n") t.run_build_system() - t.expect_addition("bin/$toolset/debug/test.obj") + t.expect_addition("bin/$toolset/debug*/test.obj") t.touch("b/test1.h") t.run_build_system() - t.expect_touch("bin/$toolset/debug/test.obj") + t.expect_touch("bin/$toolset/debug*/test.obj") t.expect_nothing_more() t.touch("a/test1.h") @@ -216,7 +216,7 @@ def test_order_graph(): t.touch("c/test2.h") t.run_build_system() - t.expect_touch("bin/$toolset/debug/test.obj") + t.expect_touch("bin/$toolset/debug*/test.obj") t.expect_nothing_more() t.touch("b/test2.h") @@ -225,7 +225,7 @@ def test_order_graph(): t.touch("e/test3.h") t.run_build_system() - t.expect_touch("bin/$toolset/debug/test.obj") + t.expect_touch("bin/$toolset/debug*/test.obj") t.expect_nothing_more() t.touch("b/test3.h") @@ -234,7 +234,7 @@ def test_order_graph(): t.touch("b/test4.h") t.run_build_system() - t.expect_touch("bin/$toolset/debug/test.obj") + t.expect_touch("bin/$toolset/debug*/test.obj") t.expect_nothing_more() t.touch("d/test4.h") diff --git a/test/ordered_properties.py b/test/ordered_properties.py index 58ea5a9f1..6976f3343 100644 --- a/test/ordered_properties.py +++ b/test/ordered_properties.py @@ -28,6 +28,6 @@ inline void foo() {} """) t.run_build_system() -t.expect_addition("bin/$toolset/debug/a.exe") +t.expect_addition("bin/$toolset/debug*/a.exe") t.cleanup() diff --git a/test/out_of_tree.py b/test/out_of_tree.py index b65529151..400101e93 100644 --- a/test/out_of_tree.py +++ b/test/out_of_tree.py @@ -23,7 +23,7 @@ exe hello3 : hello.cpp ; t.write("p2/hello.cpp", "int main() {}\n") t.run_build_system(["p1", "p2//hello3"]) -t.expect_addition("p1/bin/$toolset/debug/hello.exe") -t.expect_addition("p2/bin/$toolset/debug/hello3.exe") +t.expect_addition("p1/bin/$toolset/debug*/hello.exe") +t.expect_addition("p2/bin/$toolset/debug*/hello3.exe") t.cleanup() diff --git a/test/path_features.py b/test/path_features.py index 224dd3c2e..f8a3f7caa 100644 --- a/test/path_features.py +++ b/test/path_features.py @@ -72,7 +72,7 @@ int main() {} t.write("x/include2/h2.hpp", "\n") t.run_build_system() - t.expect_addition("x/bin/$toolset/debug/m.exe") + t.expect_addition("x/bin/$toolset/debug*/m.exe") t.cleanup() @@ -90,7 +90,7 @@ int main() { return OK; } """) t.write("h2/header.h", "int const OK = 0;\n") t.run_build_system() - t.expect_addition("sub/bin/$toolset/debug/a.exe") + t.expect_addition("sub/bin/$toolset/debug*/a.exe") t.cleanup() @@ -126,8 +126,8 @@ int main() {} t.write(header, "int some_func();\n") t.write("child_dir/folder_to_include/jamfile.jam", "") - expected_x1 = "child_dir/bin/$toolset/debug/x1.obj" - expected_x2 = "child_dir/bin/$toolset/debug/x2.obj" + expected_x1 = "child_dir/bin/$toolset/debug*/x1.obj" + expected_x2 = "child_dir/bin/$toolset/debug*/x2.obj" t.run_build_system() t.expect_addition(expected_x1) diff --git a/test/pch.py b/test/pch.py index d36260a55..872b037a1 100644 --- a/test/pch.py +++ b/test/pch.py @@ -38,7 +38,7 @@ int main() { TestClass c(1, 2); } """) t.run_build_system() -t.expect_addition("bin/$toolset/debug/hello.exe") +t.expect_addition("bin/$toolset/debug*/hello.exe") # Now make the header unusable, without changing timestamp. If everything is OK, @@ -48,8 +48,9 @@ t.expect_addition("bin/$toolset/debug/hello.exe") t.copy_preserving_timestamp("pch.hpp.bad", "pch.hpp") t.rm("bin/$toolset/debug/hello.obj") +t.rm("bin/$toolset/debug/*/hello.obj") t.run_build_system() -t.expect_addition("bin/$toolset/debug/hello.obj") +t.expect_addition("bin/$toolset/debug*/hello.obj") t.cleanup() diff --git a/test/prebuilt.py b/test/prebuilt.py index 5fe46f465..e67b726e8 100644 --- a/test/prebuilt.py +++ b/test/prebuilt.py @@ -27,8 +27,8 @@ t.expand_toolset("ext/jamfile.jam") # is picked, depending of variant. This also checks that correct includes for # prebuilt libraries are used. t.run_build_system() -t.expect_addition("bin/$toolset/debug/hello.exe") -t.expect_addition("bin/$toolset/release/hello.exe") +t.expect_addition("bin/$toolset/debug*/hello.exe") +t.expect_addition("bin/$toolset/release*/hello.exe") t.rm("bin") @@ -37,7 +37,7 @@ t.rm("bin") t.copy("ext/jamfile3.jam", "ext/jamfile.jam") t.expand_toolset("ext/jamfile.jam") t.run_build_system() -t.expect_addition("bin/$toolset/debug/hello.exe") -t.expect_addition("bin/$toolset/release/hello.exe") +t.expect_addition("bin/$toolset/debug*/hello.exe") +t.expect_addition("bin/$toolset/release*/hello.exe") t.cleanup() diff --git a/test/prebuilt/ext/jamfile2.jam b/test/prebuilt/ext/jamfile2.jam index a38bfa765..1c108d41b 100644 --- a/test/prebuilt/ext/jamfile2.jam +++ b/test/prebuilt/ext/jamfile2.jam @@ -18,7 +18,7 @@ else { prefix = "lib" ; } -if [ MATCH ^(clang-)?(darwin) : $toolset ] +if [ os.name ] in MACOSX { dll-suffix = dylib ; } diff --git a/test/prebuilt/ext/jamfile3.jam b/test/prebuilt/ext/jamfile3.jam index 1731f1743..4be602c4c 100644 --- a/test/prebuilt/ext/jamfile3.jam +++ b/test/prebuilt/ext/jamfile3.jam @@ -22,7 +22,7 @@ else { prefix = "lib" ; } -if [ MATCH ^(clang-)?(darwin) : $toolset ] +if [ os.name ] in MACOSX { dll-suffix = dylib ; } diff --git a/test/preprocessor.py b/test/preprocessor.py index 9faa711b7..715ae3e58 100755 --- a/test/preprocessor.py +++ b/test/preprocessor.py @@ -46,8 +46,8 @@ int foo() """) t.run_build_system() -t.expect_addition("bin/$toolset/debug/hello.ii") -t.expect_addition("bin/$toolset/debug/a.i") -t.expect_addition("bin/$toolset/debug/hello.exe") +t.expect_addition("bin/$toolset/debug*/hello.ii") +t.expect_addition("bin/$toolset/debug*/a.i") +t.expect_addition("bin/$toolset/debug*/hello.exe") t.cleanup() diff --git a/test/project_dependencies.py b/test/project_dependencies.py index 2e439d291..600bc0ed5 100644 --- a/test/project_dependencies.py +++ b/test/project_dependencies.py @@ -45,7 +45,7 @@ t.copy("src/a.cpp", "src/b.cpp") t.run_build_system() # Test that there is no "main-target-a" part. -# t.expect_addition("src/bin/$toolset/debug/a.exe") -# t.expect_addition("src/bin/$toolset/debug/b.exe") +# t.expect_addition("src/bin/$toolset/debug*/a.exe") +# t.expect_addition("src/bin/$toolset/debug*/b.exe") t.cleanup() diff --git a/test/project_glob.py b/test/project_glob.py index 95e3f30cf..362b450d9 100644 --- a/test/project_glob.py +++ b/test/project_glob.py @@ -27,14 +27,14 @@ void force_import_lib_creation() {} t.write("d3/a.cpp", "int main() {}\n") t.run_build_system(subdir="d1") - t.expect_addition("d1/bin/$toolset/debug/a.exe") + t.expect_addition("d1/bin/$toolset/debug*/a.exe") t.run_build_system(subdir="d3/d") - t.expect_addition("d3/d/bin/$toolset/debug/a.exe") + t.expect_addition("d3/d/bin/$toolset/debug*/a.exe") t.rm("d2/d/bin") t.run_build_system(subdir="d2/d") - t.expect_addition("d2/d/bin/$toolset/debug/l.dll") + t.expect_addition("d2/d/bin/$toolset/debug*/l.dll") t.cleanup() @@ -63,7 +63,7 @@ void force_import_lib_creation() {} t.write("d2/d/jamfile.jam", "lib l : [ glob *.cpp ] ;") t.run_build_system(subdir="d1") - t.expect_addition("d1/bin/$toolset/debug/a.exe") + t.expect_addition("d1/bin/$toolset/debug*/a.exe") t.cleanup() @@ -93,7 +93,7 @@ void force_import_lib_creation() {} t.write("d2/d/jamfile.jam", "lib l : [ glob *.cpp ] ;") t.run_build_system(subdir="d1") - t.expect_addition("d1/bin/$toolset/debug/a.exe") + t.expect_addition("d1/bin/$toolset/debug*/a.exe") t.cleanup() @@ -120,7 +120,7 @@ void force_import_lib_creation() {} t.write("d2/d/jamfile.jam", "lib l : [ glob *.cpp ] ;") t.run_build_system(subdir="d1") - t.expect_addition("d1/bin/$toolset/debug/a.exe") + t.expect_addition("d1/bin/$toolset/debug*/a.exe") t.cleanup() @@ -179,7 +179,7 @@ void force_import_lib_creation() {} t.write("d2/d/jamfile.jam", "lib l : [ glob *.cpp ] ;") t.run_build_system(subdir="d1") - t.expect_addition("d1/bin/$toolset/debug/a.exe") + t.expect_addition("d1/bin/$toolset/debug*/a.exe") t.cleanup() @@ -198,7 +198,7 @@ def test_glob_excludes_in_subdirectory(): t.write("p/jamfile.jam", "exe p : [ glob *.c : p_x.c ] ;") t.run_build_system(subdir="p") - t.expect_addition("p/bin/$toolset/debug/p.exe") + t.expect_addition("p/bin/$toolset/debug*/p.exe") t.cleanup() diff --git a/test/project_id.py b/test/project_id.py index f6846af5f..7f4070e07 100755 --- a/test/project_id.py +++ b/test/project_id.py @@ -280,7 +280,7 @@ bbb b-invalid-target : /foo//invalid ; """) t.run_build_system(["b1", "b2"]) - t.expect_addition("bin/$toolset/debug/b%d._b" % x for x in range(1, 3)) + t.expect_addition("bin/$toolset/debug*/b%d._b" % x for x in range(1, 3)) t.expect_nothing_more() t.run_build_system(["b-invalid"], status=1) diff --git a/test/project_root_rule.py b/test/project_root_rule.py index 9f5ca47f8..956c8953b 100644 --- a/test/project_root_rule.py +++ b/test/project_root_rule.py @@ -29,6 +29,6 @@ my-lib foo ; t.run_build_system(subdir="sub") -t.expect_addition("sub/bin/$toolset/debug/link-static/foo.lib") +t.expect_addition("sub/bin/$toolset/debug/link-static*/foo.lib") t.cleanup() diff --git a/test/project_test3.py b/test/project_test3.py index 4f6cda2a7..82b238f68 100644 --- a/test/project_test3.py +++ b/test/project_test3.py @@ -22,114 +22,114 @@ t.expect_output_lines("error: Could not find parent for project at '.'\n" t.set_tree("project-test3") t.run_build_system() -t.expect_addition("bin/$toolset/debug/a.obj") -t.expect_content("bin/$toolset/debug/a.obj", """\ +t.expect_addition("bin/$toolset/debug*/a.obj") +t.expect_content("bin/$toolset/debug*/a.obj", """\ $toolset/debug a.cpp """) -t.expect_addition("bin/$toolset/debug/a.exe") -t.expect_content("bin/$toolset/debug/a.exe", -"$toolset/debug\n" + -"bin/$toolset/debug/a.obj lib/bin/$toolset/debug/b.obj " + -"lib2/bin/$toolset/debug/c.obj lib2/bin/$toolset/debug/d.obj " + -"lib2/helper/bin/$toolset/debug/e.obj " + -"lib3/bin/$toolset/debug/f.obj\n" +t.expect_addition("bin/$toolset/debug*/a.exe") +t.expect_content("bin/$toolset/debug*/a.exe", +"$toolset/debug*\n" + +"bin/$toolset/debug*/a.obj lib/bin/$toolset/debug*/b.obj " + +"lib2/bin/$toolset/debug*/c.obj lib2/bin/$toolset/debug*/d.obj " + +"lib2/helper/bin/$toolset/debug*/e.obj " + +"lib3/bin/$toolset/debug*/f.obj\n" ) -t.expect_addition("lib/bin/$toolset/debug/b.obj") -t.expect_content("lib/bin/$toolset/debug/b.obj", """\ +t.expect_addition("lib/bin/$toolset/debug*/b.obj") +t.expect_content("lib/bin/$toolset/debug*/b.obj", """\ $toolset/debug lib/b.cpp """) -t.expect_addition("lib/bin/$toolset/debug/m.exe") -t.expect_content("lib/bin/$toolset/debug/m.exe", """\ +t.expect_addition("lib/bin/$toolset/debug*/m.exe") +t.expect_content("lib/bin/$toolset/debug*/m.exe", """\ $toolset/debug -lib/bin/$toolset/debug/b.obj lib2/bin/$toolset/debug/c.obj +lib/bin/$toolset/debug*/b.obj lib2/bin/$toolset/debug*/c.obj """) -t.expect_addition("lib2/bin/$toolset/debug/c.obj") -t.expect_content("lib2/bin/$toolset/debug/c.obj", """\ +t.expect_addition("lib2/bin/$toolset/debug*/c.obj") +t.expect_content("lib2/bin/$toolset/debug*/c.obj", """\ $toolset/debug lib2/c.cpp """) -t.expect_addition("lib2/bin/$toolset/debug/d.obj") -t.expect_content("lib2/bin/$toolset/debug/d.obj", """\ +t.expect_addition("lib2/bin/$toolset/debug*/d.obj") +t.expect_content("lib2/bin/$toolset/debug*/d.obj", """\ $toolset/debug lib2/d.cpp """) -t.expect_addition("lib2/bin/$toolset/debug/l.exe") -t.expect_content("lib2/bin/$toolset/debug/l.exe", """\ +t.expect_addition("lib2/bin/$toolset/debug*/l.exe") +t.expect_content("lib2/bin/$toolset/debug*/l.exe", """\ $toolset/debug -lib2/bin/$toolset/debug/c.obj bin/$toolset/debug/a.obj +lib2/bin/$toolset/debug*/c.obj bin/$toolset/debug*/a.obj """) -t.expect_addition("lib2/helper/bin/$toolset/debug/e.obj") -t.expect_content("lib2/helper/bin/$toolset/debug/e.obj", """\ +t.expect_addition("lib2/helper/bin/$toolset/debug*/e.obj") +t.expect_content("lib2/helper/bin/$toolset/debug*/e.obj", """\ $toolset/debug lib2/helper/e.cpp """) -t.expect_addition("lib3/bin/$toolset/debug/f.obj") -t.expect_content("lib3/bin/$toolset/debug/f.obj", """\ +t.expect_addition("lib3/bin/$toolset/debug*/f.obj") +t.expect_content("lib3/bin/$toolset/debug*/f.obj", """\ $toolset/debug -lib3/f.cpp lib2/helper/bin/$toolset/debug/e.obj +lib3/f.cpp lib2/helper/bin/$toolset/debug*/e.obj """) t.touch("a.cpp") t.run_build_system() -t.expect_touch(["bin/$toolset/debug/a.obj", - "bin/$toolset/debug/a.exe", - "lib2/bin/$toolset/debug/l.exe"]) +t.expect_touch(["bin/$toolset/debug*/a.obj", + "bin/$toolset/debug*/a.exe", + "lib2/bin/$toolset/debug*/l.exe"]) t.run_build_system(["release", "optimization=off,speed"]) -t.expect_addition(["bin/$toolset/release/a.exe", - "bin/$toolset/release/a.obj", - "bin/$toolset/release/optimization-off/a.exe", - "bin/$toolset/release/optimization-off/a.obj"]) +t.expect_addition(["bin/$toolset/release/optimization-off*/a.exe", + "bin/$toolset/release/optimization-off*/a.obj", + "bin/$toolset/release*/a.exe", + "bin/$toolset/release*/a.obj"]) t.run_build_system(["--clean-all"]) -t.expect_removal(["bin/$toolset/debug/a.obj", - "bin/$toolset/debug/a.exe", - "lib/bin/$toolset/debug/b.obj", - "lib/bin/$toolset/debug/m.exe", - "lib2/bin/$toolset/debug/c.obj", - "lib2/bin/$toolset/debug/d.obj", - "lib2/bin/$toolset/debug/l.exe", - "lib3/bin/$toolset/debug/f.obj"]) +t.expect_removal(["bin/$toolset/debug*/a.obj", + "bin/$toolset/debug*/a.exe", + "lib/bin/$toolset/debug*/b.obj", + "lib/bin/$toolset/debug*/m.exe", + "lib2/bin/$toolset/debug*/c.obj", + "lib2/bin/$toolset/debug*/d.obj", + "lib2/bin/$toolset/debug*/l.exe", + "lib3/bin/$toolset/debug*/f.obj"]) # Now test target ids in command line. t.set_tree("project-test3") t.run_build_system(["lib//b.obj"]) -t.expect_addition("lib/bin/$toolset/debug/b.obj") +t.expect_addition("lib/bin/$toolset/debug*/b.obj") t.expect_nothing_more() t.run_build_system(["--clean", "lib//b.obj"]) -t.expect_removal("lib/bin/$toolset/debug/b.obj") +t.expect_removal("lib/bin/$toolset/debug*/b.obj") t.expect_nothing_more() t.run_build_system(["lib//b.obj"]) -t.expect_addition("lib/bin/$toolset/debug/b.obj") +t.expect_addition("lib/bin/$toolset/debug*/b.obj") t.expect_nothing_more() t.run_build_system(["release", "lib2/helper//e.obj", "/lib3//f.obj"]) -t.expect_addition("lib2/helper/bin/$toolset/release/e.obj") -t.expect_addition("lib3/bin/$toolset/release/f.obj") +t.expect_addition("lib2/helper/bin/$toolset/release*/e.obj") +t.expect_addition("lib3/bin/$toolset/release*/f.obj") t.expect_nothing_more() # Test project ids in command line work as well. t.set_tree("project-test3") t.run_build_system(["/lib2"]) -t.expect_addition("lib2/bin/$toolset/debug/" * +t.expect_addition("lib2/bin/$toolset/debug*/" * BoostBuild.List("c.obj d.obj l.exe")) -t.expect_addition("bin/$toolset/debug/a.obj") +t.expect_addition("bin/$toolset/debug*/a.obj") t.expect_nothing_more() t.run_build_system(["lib"]) -t.expect_addition("lib/bin/$toolset/debug/" * +t.expect_addition("lib/bin/$toolset/debug*/" * BoostBuild.List("b.obj m.exe")) t.expect_nothing_more() diff --git a/test/project_test4.py b/test/project_test4.py index fc4115017..ee12c4d91 100644 --- a/test/project_test4.py +++ b/test/project_test4.py @@ -14,28 +14,28 @@ t.set_tree("project-test4") t.run_build_system() -t.expect_addition("bin/$toolset/debug/a.obj") -t.expect_content("bin/$toolset/debug/a.obj", -"""$toolset/debug/include-everything +t.expect_addition("bin/$toolset/debug*/a.obj") +t.expect_content("bin/$toolset/debug*/a.obj", +"""$toolset/debug*/include-everything a.cpp """) -t.expect_addition("bin/$toolset/debug/a.exe") -t.expect_content("bin/$toolset/debug/a.exe", -"$toolset/debug/include-everything\n" + -"bin/$toolset/debug/a.obj lib/bin/$toolset/debug/optimization-speed/b.obj\n" +t.expect_addition("bin/$toolset/debug*/a.exe") +t.expect_content("bin/$toolset/debug*/a.exe", +"$toolset/debug*/include-everything\n" + +"bin/$toolset/debug*/a.obj lib/bin/$toolset/debug/optimization-speed*/b.obj\n" ) -t.expect_addition("lib/bin/$toolset/debug/optimization-speed/b.obj") -t.expect_content("lib/bin/$toolset/debug/optimization-speed/b.obj", -"""$toolset/debug/include-everything/optimization-speed +t.expect_addition("lib/bin/$toolset/debug/optimization-speed*/b.obj") +t.expect_content("lib/bin/$toolset/debug/optimization-speed*/b.obj", +"""$toolset/debug/include-everything/optimization-speed* lib/b.cpp """) -t.expect_addition("bin/$toolset/debug/b.exe") -t.expect_content("bin/$toolset/debug/b.exe", -"$toolset/debug/define-MACROS/include-everything\n" + -"bin/$toolset/debug/a.obj\n" +t.expect_addition("bin/$toolset/debug*/b.exe") +t.expect_content("bin/$toolset/debug*/b.exe", +"$toolset/debug/define-MACROS/include-everything*\n" + +"bin/$toolset/debug*/a.obj\n" ) t.copy("lib/jamfile3.jam", "lib/jamfile.jam") @@ -55,11 +55,11 @@ t.copy("jamfile5.jam", "jamfile.jam") t.run_build_system() -t.expect_addition("lib/bin/$toolset/release/b.obj") +t.expect_addition("lib/bin/$toolset/release*/b.obj") -t.expect_content("bin/$toolset/debug/a.exe", -"$toolset/debug/include-everything\n" + -"bin/$toolset/debug/a.obj lib/bin/$toolset/release/b.obj\n" +t.expect_content("bin/$toolset/debug*/a.exe", +"$toolset/debug/include-everything*\n" + +"bin/$toolset/debug*/a.obj lib/bin/$toolset/release*/b.obj\n" ) t.cleanup() diff --git a/test/regression.py b/test/regression.py index dde4d8151..071e7ca54 100644 --- a/test/regression.py +++ b/test/regression.py @@ -47,13 +47,13 @@ helper() {} # First test that when outcomes are expected, all .test files are created. t.run_build_system(["hardcode-dll-paths=false"], stderr=None, status=None) -t.expect_addition("bin/c.test/$toolset/debug/c.test") -t.expect_addition("bin/c-f.test/$toolset/debug/c-f.test") -t.expect_addition("bin/r.test/$toolset/debug/r.test") -t.expect_addition("bin/r-f.test/$toolset/debug/r-f.test") +t.expect_addition("bin/c.test/$toolset/debug*/c.test") +t.expect_addition("bin/c-f.test/$toolset/debug*/c-f.test") +t.expect_addition("bin/r.test/$toolset/debug*/r.test") +t.expect_addition("bin/r-f.test/$toolset/debug*/r-f.test") # Make sure args are handled. -t.expect_content("bin/r.test/$toolset/debug/r.output", +t.expect_content("bin/r.test/$toolset/debug*/r.output", "foo\nbar\n*\nEXIT STATUS: 0*\n", True) # Test that input file is handled as well. @@ -84,13 +84,13 @@ time compilation : c-obj ; """) t.run_build_system(["hardcode-dll-paths=false"]) -t.expect_content("bin/r.test/$toolset/debug/r.output", """\ +t.expect_content("bin/r.test/$toolset/debug*/r.output", """\ test input EXIT STATUS: 0 """) -t.expect_addition('bin/$toolset/debug/execution.time') -t.expect_addition('bin/$toolset/debug/compilation.time') +t.expect_addition('bin/$toolset/debug*/execution.time') +t.expect_addition('bin/$toolset/debug*/compilation.time') # Make sure test failures are detected. Reverse expectation and see if .test # files are created or not. @@ -105,9 +105,9 @@ run r-f.cpp ; t.touch(BoostBuild.List("c.cpp c-f.cpp r.cpp r-f.cpp")) t.run_build_system(["hardcode-dll-paths=false"], stderr=None, status=1) -t.expect_removal("bin/c.test/$toolset/debug/c.test") -t.expect_removal("bin/c-f.test/$toolset/debug/c-f.test") -t.expect_removal("bin/r.test/$toolset/debug/r.test") -t.expect_removal("bin/r-f.test/$toolset/debug/r-f.test") +t.expect_removal("bin/c.test/$toolset/debug*/c.test") +t.expect_removal("bin/c-f.test/$toolset/debug*/c-f.test") +t.expect_removal("bin/r.test/$toolset/debug*/r.test") +t.expect_removal("bin/r-f.test/$toolset/debug*/r-f.test") t.cleanup() diff --git a/test/relative_sources.py b/test/relative_sources.py index f36e0b097..29f590fed 100644 --- a/test/relative_sources.py +++ b/test/relative_sources.py @@ -16,14 +16,14 @@ t.write("jamroot.jam", "exe a : src/a.cpp ;") t.write("src/a.cpp", "int main() {}\n") t.run_build_system() -t.expect_addition("bin/$toolset/debug/src/a.obj") +t.expect_addition("bin/$toolset/debug*/src/a.obj") # Test that the relative path to source is preserved # when using 'glob'. t.rm("bin") t.write("jamroot.jam", "exe a : [ glob src/*.cpp ] ;") t.run_build_system() -t.expect_addition("bin/$toolset/debug/src/a.obj") +t.expect_addition("bin/$toolset/debug*/src/a.obj") # Test that relative path with ".." is *not* added to @@ -33,6 +33,6 @@ t.write("jamroot.jam", "") t.write("a.cpp", "int main() { return 0; }\n") t.write("build/Jamfile", "exe a : ../a.cpp ; ") t.run_build_system(subdir="build") -t.expect_addition("build/bin/$toolset/debug/a.obj") +t.expect_addition("build/bin/$toolset/debug*/a.obj") t.cleanup() diff --git a/test/remove_requirement.py b/test/remove_requirement.py index fa820c869..8009e0f64 100644 --- a/test/remove_requirement.py +++ b/test/remove_requirement.py @@ -55,10 +55,10 @@ exe hello : hello.cpp ; t.run_build_system() -t.expect_addition("sub/bin/$toolset/debug/link-static/hello.exe") -t.expect_addition("sub2/bin/$toolset/debug/link-static/hello.exe") -t.expect_addition("sub3/bin/$toolset/debug/threading-multi/hello.exe") -t.expect_addition("sub4/bin/$toolset/debug/threading-multi/hello.exe") +t.expect_addition("sub/bin/$toolset/debug/link-static*/hello.exe") +t.expect_addition("sub2/bin/$toolset/debug/link-static*/hello.exe") +t.expect_addition("sub3/bin/$toolset/debug/threading-multi*/hello.exe") +t.expect_addition("sub4/bin/$toolset/debug/threading-multi*/hello.exe") t.rm(".") @@ -84,6 +84,6 @@ Broken t.run_build_system() -t.expect_addition("sub/bin/$toolset/debug/hello.exe") +t.expect_addition("sub/bin/$toolset/debug*/hello.exe") t.cleanup() diff --git a/test/rescan_header.py b/test/rescan_header.py index 1f07acaa8..37b37c7d4 100755 --- a/test/rescan_header.py +++ b/test/rescan_header.py @@ -35,8 +35,8 @@ obj test : test.cpp : header3.h ; """) t.run_build_system(["-j2"]) -t.expect_addition("bin/$toolset/debug/header3.h") -t.expect_addition("bin/$toolset/debug/test.obj") +t.expect_addition("bin/$toolset/debug*/header3.h") +t.expect_addition("bin/$toolset/debug*/test.obj") t.expect_nothing_more() t.rm(".") @@ -72,10 +72,10 @@ obj test : test.cpp : """) t.run_build_system(["-j2", "test"]) -t.expect_addition("bin/$toolset/debug/header1.h") -t.expect_addition("bin/$toolset/debug/header2.h") -t.expect_addition("bin/$toolset/debug/header3.h") -t.expect_addition("bin/$toolset/debug/test.obj") +t.expect_addition("bin/$toolset/debug*/header1.h") +t.expect_addition("bin/$toolset/debug*/header2.h") +t.expect_addition("bin/$toolset/debug*/header3.h") +t.expect_addition("bin/$toolset/debug*/test.obj") t.expect_nothing_more() t.rm(".") @@ -122,10 +122,10 @@ obj test : test.cpp : """) t.run_build_system(["-j2", "test"]) -t.expect_addition("bin/$toolset/debug/header1.h") -t.expect_addition("bin/$toolset/debug/header2.h") -t.expect_addition("bin/$toolset/debug/header3.h") -t.expect_addition("bin/$toolset/debug/test.obj") +t.expect_addition("bin/$toolset/debug*/header1.h") +t.expect_addition("bin/$toolset/debug*/header2.h") +t.expect_addition("bin/$toolset/debug*/header3.h") +t.expect_addition("bin/$toolset/debug*/test.obj") t.expect_nothing_more() t.rm(".") @@ -184,18 +184,18 @@ exe test : test2.cpp test1.cpp : header3.h ; """) t.run_build_system(["-j2", "test"]) -t.expect_addition("bin/$toolset/debug/header3.h") -t.expect_addition("bin/$toolset/debug/test1.obj") -t.expect_addition("bin/$toolset/debug/test2.obj") -t.expect_addition("bin/$toolset/debug/test.exe") +t.expect_addition("bin/$toolset/debug*/header3.h") +t.expect_addition("bin/$toolset/debug*/test1.obj") +t.expect_addition("bin/$toolset/debug*/test2.obj") +t.expect_addition("bin/$toolset/debug*/test.exe") t.expect_nothing_more() t.touch("header3.in") t.run_build_system(["-j2", "test"]) -t.expect_touch("bin/$toolset/debug/header3.h") -t.expect_touch("bin/$toolset/debug/test1.obj") -t.expect_touch("bin/$toolset/debug/test2.obj") -t.expect_touch("bin/$toolset/debug/test.exe") +t.expect_touch("bin/$toolset/debug*/header3.h") +t.expect_touch("bin/$toolset/debug*/test1.obj") +t.expect_touch("bin/$toolset/debug*/test2.obj") +t.expect_touch("bin/$toolset/debug*/test.exe") t.expect_nothing_more() t.rm(".") @@ -256,10 +256,10 @@ exe test : test2.cpp test1.cpp : header2.h . ; """) t.run_build_system(["-j2", "test"]) -t.expect_addition("bin/$toolset/debug/header2.h") -t.expect_addition("bin/$toolset/debug/test1.obj") -t.expect_addition("bin/$toolset/debug/test2.obj") -t.expect_addition("bin/$toolset/debug/test.exe") +t.expect_addition("bin/$toolset/debug*/header2.h") +t.expect_addition("bin/$toolset/debug*/test1.obj") +t.expect_addition("bin/$toolset/debug*/test2.obj") +t.expect_addition("bin/$toolset/debug*/test.exe") t.expect_nothing_more() t.cleanup() diff --git a/test/resolution.py b/test/resolution.py index a97085732..9cde218fa 100644 --- a/test/resolution.py +++ b/test/resolution.py @@ -24,12 +24,12 @@ t.write("hello.cpp", "int main() {}\n") t.run_build_system() -t.expect_addition("bin/$toolset/debug/hello.obj") +t.expect_addition("bin/$toolset/debug*/hello.obj") t.touch("hello.cpp") t.run_build_system(["s"]) # If 'hello' in the 's' target resolved to file in the current dir, nothing # will be rebuilt. -t.expect_touch("bin/$toolset/debug/hello.obj") +t.expect_touch("bin/$toolset/debug*/hello.obj") t.cleanup() diff --git a/test/searched_lib.py b/test/searched_lib.py index c9ad5852d..54c4f0878 100644 --- a/test/searched_lib.py +++ b/test/searched_lib.py @@ -26,17 +26,17 @@ void foo() {} """); t.run_build_system(subdir="lib") -t.expect_addition("lib/bin/$toolset/debug/test_lib.dll") +t.expect_addition("lib/bin/$toolset/debug*/test_lib.dll") # Auto adjusting of suffixes does not work, since we need to # change dll to lib. if ( ( os.name == "nt" ) or os.uname()[0].lower().startswith("cygwin") ) and \ ( BoostBuild.get_toolset() != "gcc" ): - t.copy("lib/bin/$toolset/debug/test_lib.implib", "lib/test_lib.implib") - t.copy("lib/bin/$toolset/debug/test_lib.dll", "lib/test_lib.dll") + t.copy("lib/bin/$toolset/debug*/test_lib.implib", "lib/test_lib.implib") + t.copy("lib/bin/$toolset/debug*/test_lib.dll", "lib/test_lib.dll") else: - t.copy("lib/bin/$toolset/debug/test_lib.dll", "lib/test_lib.dll") + t.copy("lib/bin/$toolset/debug*/test_lib.dll", "lib/test_lib.dll") # Test that the simplest usage of searched library works. @@ -65,8 +65,9 @@ helper() { foo(); } """) t.run_build_system(["-d2"]) -t.expect_addition("bin/$toolset/debug/main.exe") +t.expect_addition("bin/$toolset/debug*/main.exe") t.rm("bin/$toolset/debug/main.exe") +t.rm("bin/$toolset/debug/*/main.exe") # Test that 'unit-test' will correctly add runtime paths to searched libraries. @@ -83,8 +84,9 @@ lib test_lib : : test_lib lib ; """) t.run_build_system() -t.expect_addition("bin/$toolset/debug/main.passed") +t.expect_addition("bin/$toolset/debug*/main.passed") t.rm("bin/$toolset/debug/main.exe") +t.rm("bin/$toolset/debug/*/main.exe") # Now try using searched lib from static lib. Request shared version of searched @@ -96,9 +98,10 @@ lib test_lib : : test_lib lib ; """) t.run_build_system(stderr=None) -t.expect_addition("bin/$toolset/debug/main.exe") -t.expect_addition("bin/$toolset/debug/link-static/helper.lib") +t.expect_addition("bin/$toolset/debug*/main.exe") +t.expect_addition("bin/$toolset/debug/link-static*/helper.lib") t.rm("bin/$toolset/debug/main.exe") +t.rm("bin/$toolset/debug/*/main.exe") # A regression test: property referring to searched-lib was being # mishandled. As the result, we were putting target name to the command line! diff --git a/test/source_order.py b/test/source_order.py index af8fd54bc..d3cc2ab20 100755 --- a/test/source_order.py +++ b/test/source_order.py @@ -74,8 +74,8 @@ t.write("file2.c", "") t.write("file3.c", "") t.run_build_system() -t.expect_addition("bin/$toolset/debug/check.order-test") -t.expect_content("bin/$toolset/debug/check.order-test", """\ +t.expect_addition("bin/$toolset/debug*/check.order-test") +t.expect_content("bin/$toolset/debug*/check.order-test", """\ file2.c file1.c file3.c diff --git a/test/static_and_shared_library.py b/test/static_and_shared_library.py index ca50e26ad..da010a241 100755 --- a/test/static_and_shared_library.py +++ b/test/static_and_shared_library.py @@ -19,19 +19,19 @@ def reset(): t.rm("lib/bin") t.run_build_system(subdir='lib') -t.expect_addition("lib/bin/$toolset/debug/" * BoostBuild.List("c.obj " +t.expect_addition("lib/bin/$toolset/debug*/" * BoostBuild.List("c.obj " "auxilliary1.lib auxilliary2.dll")) t.expect_nothing_more() reset() t.run_build_system(["link=shared"], subdir="lib") -t.expect_addition("lib/bin/$toolset/debug/" * BoostBuild.List("c.obj " +t.expect_addition("lib/bin/$toolset/debug*/" * BoostBuild.List("c.obj " "auxilliary1.lib auxilliary2.dll")) t.expect_nothing_more() reset() t.run_build_system(["link=static"], subdir="lib") -t.expect_addition("lib/bin/$toolset/debug/link-static/" * BoostBuild.List( +t.expect_addition("lib/bin/$toolset/debug/link-static*/" * BoostBuild.List( "c.obj auxilliary1.lib auxilliary2.lib")) t.expect_nothing_more() diff --git a/test/suffix.py b/test/suffix.py index 386e36a9d..b6946a48a 100644 --- a/test/suffix.py +++ b/test/suffix.py @@ -73,6 +73,6 @@ second a : a.cpp ; """) t.run_build_system() -t.expect_addition("bin/$toolset/debug/a") +t.expect_addition("bin/$toolset/debug*/a") t.cleanup() diff --git a/test/tag.py b/test/tag.py index 09b4308a5..87f537c8c 100644 --- a/test/tag.py +++ b/test/tag.py @@ -34,7 +34,7 @@ exe a : a.cpp ; t.write("version-1.32.0/a.cpp", "int main() {}\n") t.run_build_system(subdir="version-1.32.0") - t.expect_addition("version-1.32.0/bin/$toolset/debug/a.exe") + t.expect_addition("version-1.32.0/bin/$toolset/debug*/a.exe") t.expect_output_lines("The tag rule has been invoked.") @@ -85,17 +85,17 @@ __declspec (dllexport) void x () {} """) file_list = ( - BoostBuild.List("bin/$toolset/debug/a_ds.exe") + - BoostBuild.List("bin/$toolset/debug/b_ds.dll") + + BoostBuild.List("bin/$toolset/debug*/a_ds.exe") + + BoostBuild.List("bin/$toolset/debug*/b_ds.dll") + BoostBuild.List("c/a_ds.exe") + - BoostBuild.List("bin/$toolset/release/a_rs.exe") + - BoostBuild.List("bin/$toolset/release/b_rs.dll") + + BoostBuild.List("bin/$toolset/release*/a_rs.exe") + + BoostBuild.List("bin/$toolset/release*/b_rs.dll") + BoostBuild.List("c/a_rs.exe") + - BoostBuild.List("bin/$toolset/debug/link-static/a_dt.exe") + - BoostBuild.List("bin/$toolset/debug/link-static/b_dt.lib") + + BoostBuild.List("bin/$toolset/debug/link-static*/a_dt.exe") + + BoostBuild.List("bin/$toolset/debug/link-static*/b_dt.lib") + BoostBuild.List("c/a_dt.exe") + - BoostBuild.List("bin/$toolset/release/link-static/a_rt.exe") + - BoostBuild.List("bin/$toolset/release/link-static/b_rt.lib") + + BoostBuild.List("bin/$toolset/release/link-static*/a_rt.exe") + + BoostBuild.List("bin/$toolset/release/link-static*/b_rt.lib") + BoostBuild.List("c/a_rt.exe")) variants = ["debug", "release", "link=static,shared"] diff --git a/test/template.py b/test/template.py index 1fbef07b8..f67e73988 100644 --- a/test/template.py +++ b/test/template.py @@ -27,7 +27,7 @@ int main() {} t.run_build_system() # First, create a list of three pathnames. -file_list = BoostBuild.List("bin/$toolset/debug/") * \ +file_list = BoostBuild.List("bin/$toolset/debug*/") * \ BoostBuild.List("hello.exe hello.obj") # Second, assert that those files were added as result of the last build system # invocation. diff --git a/test/test2.py b/test/test2.py index 938b36545..b7c99be12 100644 --- a/test/test2.py +++ b/test/test2.py @@ -11,7 +11,7 @@ t = BoostBuild.Tester() t.set_tree("test2") -file_list = 'bin/$toolset/debug/' * \ +file_list = 'bin/$toolset/debug*/' * \ BoostBuild.List("foo foo.o") t.run_build_system("-sBOOST_BUILD_PATH=" + t.original_workdir + "/..") diff --git a/test/test_all.py b/test/test_all.py index 4a6391264..fe97acd1a 100644 --- a/test/test_all.py +++ b/test/test_all.py @@ -170,7 +170,6 @@ tests = ["absolute_sources", "builtin_echo", "builtin_exit", "builtin_glob", - "builtin_glob_archive", "builtin_split_by_characters", "bzip2", "c_file", @@ -301,6 +300,10 @@ if toolset.startswith("gcc"): if toolset.startswith("gcc") or toolset.startswith("msvc"): tests.append("pch") +# Disable on OSX as it doesn't seem to work for unknown reasons. +if sys.platform != 'darwin': + tests.append("builtin_glob_archive") + if "--extras" in sys.argv: tests.append("boostbook") tests.append("qt4") diff --git a/test/testing_support.py b/test/testing_support.py index ad25b4aad..c76a1f2a7 100755 --- a/test/testing_support.py +++ b/test/testing_support.py @@ -34,18 +34,18 @@ testing.compile-fail "invalid source.cpp" ; """) t.run_build_system(status=0) - t.expect_addition("bin/invalid source.test/$toolset/debug/invalid source.obj") - t.expect_addition("bin/invalid source.test/$toolset/debug/invalid source.test") - t.expect_addition("bin/valid source.test/$toolset/debug/valid source.obj") - t.expect_addition("bin/valid source.test/$toolset/debug/valid source.test") + t.expect_addition("bin/invalid source.test/$toolset/debug*/invalid source.obj") + t.expect_addition("bin/invalid source.test/$toolset/debug*/invalid source.test") + t.expect_addition("bin/valid source.test/$toolset/debug*/valid source.obj") + t.expect_addition("bin/valid source.test/$toolset/debug*/valid source.test") - t.expect_content("bin/valid source.test/$toolset/debug/valid source.test", \ + t.expect_content("bin/valid source.test/$toolset/debug*/valid source.test", \ "passed" ) t.expect_content( \ - "bin/invalid source.test/$toolset/debug/invalid source.test", \ + "bin/invalid source.test/$toolset/debug*/invalid source.test", \ "passed" ) t.expect_content( \ - "bin/invalid source.test/$toolset/debug/invalid source.obj", \ + "bin/invalid source.test/$toolset/debug*/invalid source.obj", \ "failed as expected" ) t.cleanup() diff --git a/test/timedata.py b/test/timedata.py index 2bfc3ef31..32cec265a 100644 --- a/test/timedata.py +++ b/test/timedata.py @@ -118,15 +118,15 @@ time my-time : my-exe ; """) t.run_build_system() - t.expect_addition("bin/$toolset/debug/aaa.obj") - t.expect_addition("bin/$toolset/debug/my-exe.exe") - t.expect_addition("bin/$toolset/debug/my-time.time") + t.expect_addition("bin/$toolset/debug*/aaa.obj") + t.expect_addition("bin/$toolset/debug*/my-exe.exe") + t.expect_addition("bin/$toolset/debug*/my-time.time") - t.expect_content_lines("bin/$toolset/debug/my-time.time", + t.expect_content_lines("bin/$toolset/debug*/my-time.time", "user: *[0-9] seconds") - t.expect_content_lines("bin/$toolset/debug/my-time.time", + t.expect_content_lines("bin/$toolset/debug*/my-time.time", "system: *[0-9] seconds") - t.expect_content_lines("bin/$toolset/debug/my-time.time", + t.expect_content_lines("bin/$toolset/debug*/my-time.time", "clock: *[0-9] seconds") t.cleanup() @@ -156,12 +156,12 @@ time "my time" : "my exe" ; """) t.run_build_system() - t.expect_addition("bin/$toolset/debug/aaa bbb.obj") - t.expect_addition("bin/$toolset/debug/my exe.exe") - t.expect_addition("bin/$toolset/debug/my time.time") + t.expect_addition("bin/$toolset/debug*/aaa bbb.obj") + t.expect_addition("bin/$toolset/debug*/my exe.exe") + t.expect_addition("bin/$toolset/debug*/my time.time") - t.expect_content_lines("bin/$toolset/debug/my time.time", "user: *") - t.expect_content_lines("bin/$toolset/debug/my time.time", "system: *") + t.expect_content_lines("bin/$toolset/debug*/my time.time", "user: *") + t.expect_content_lines("bin/$toolset/debug*/my time.time", "system: *") t.cleanup() diff --git a/test/unit_test.py b/test/unit_test.py index 5b2c5dbc9..da28503bc 100644 --- a/test/unit_test.py +++ b/test/unit_test.py @@ -31,6 +31,6 @@ helper() {} """) t.run_build_system(["link=static"]) -t.expect_addition("bin/$toolset/debug/link-static/test.passed") +t.expect_addition("bin/$toolset/debug/link-static*/test.passed") t.cleanup() diff --git a/test/use_requirements.py b/test/use_requirements.py index 7fe829c0b..366281509 100644 --- a/test/use_requirements.py +++ b/test/use_requirements.py @@ -250,7 +250,7 @@ foo() {} """) t.run_build_system(["link=static"]) -t.expect_addition("libs/bin/$toolset/debug/link-static/a_d.obj") +t.expect_addition("libs/bin/$toolset/debug/link-static*/a_d.obj") # Test that indirect conditionals are respected in usage requirements. @@ -278,6 +278,6 @@ foo() {} """) t.run_build_system() -t.expect_addition("bin/$toolset/debug/a.exe") +t.expect_addition("bin/$toolset/debug*/a.exe") t.cleanup() diff --git a/test/using.py b/test/using.py index 31a07eb7b..495f412b1 100644 --- a/test/using.py +++ b/test/using.py @@ -27,6 +27,6 @@ t.write("sub/a.cpp", "int main() {}\n") t.write("sub/jamfile.jam", "exe a : a.cpp ;") t.run_build_system(subdir="sub") -t.expect_addition("sub/bin/$toolset/debug/a.exe") +t.expect_addition("sub/bin/$toolset/debug*/a.exe") t.cleanup() diff --git a/test/wrapper.py b/test/wrapper.py index 8501a7340..1adeb2c90 100644 --- a/test/wrapper.py +++ b/test/wrapper.py @@ -33,6 +33,6 @@ IMPORT $(__name__) : my-test : : my-test ; """) t.run_build_system() -t.expect_addition("bin/$toolset/debug/test.passed") +t.expect_addition("bin/$toolset/debug*/test.passed") t.cleanup() diff --git a/test/wrong_project.py b/test/wrong_project.py index 273ff5c97..7183a6062 100644 --- a/test/wrong_project.py +++ b/test/wrong_project.py @@ -34,6 +34,6 @@ def init(): """) t.run_build_system() -t.expect_addition("bin/$toolset/debug/a.exe") +t.expect_addition("bin/$toolset/debug*/a.exe") t.cleanup()