diff options
author | Kenneth Heafield <github@kheafield.com> | 2012-05-12 14:01:52 -0400 |
---|---|---|
committer | Kenneth Heafield <github@kheafield.com> | 2012-05-12 14:01:52 -0400 |
commit | 3faecf9a00512dcbc8712c4bca9adae72fb64410 (patch) | |
tree | 9761b50d12f81a675fb7cbc663ceebad15079f78 /jam-files/boost-build/build/build-request.jam | |
parent | c806a8fff63043f63773874986301f2822a2b552 (diff) |
Give in and copy bjam into cdec source code
Diffstat (limited to 'jam-files/boost-build/build/build-request.jam')
-rw-r--r-- | jam-files/boost-build/build/build-request.jam | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/jam-files/boost-build/build/build-request.jam b/jam-files/boost-build/build/build-request.jam new file mode 100644 index 00000000..8a1f7b0e --- /dev/null +++ b/jam-files/boost-build/build/build-request.jam @@ -0,0 +1,322 @@ +# Copyright 2002 Dave Abrahams +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + +import "class" : new ; +import sequence ; +import set ; +import regex ; +import feature ; +import property ; +import container ; +import string ; + + +# Transform property-set by applying f to each component property. +# +local rule apply-to-property-set ( f property-set ) +{ + local properties = [ feature.split $(property-set) ] ; + return [ string.join [ $(f) $(properties) ] : / ] ; +} + + +# Expand the given build request by combining all property-sets which do not +# specify conflicting non-free features. Expects all the project files to +# already be loaded. +# +rule expand-no-defaults ( property-sets * ) +{ + # First make all features and subfeatures explicit. + local expanded-property-sets = [ sequence.transform apply-to-property-set + feature.expand-subfeatures : $(property-sets) ] ; + + # Now combine all of the expanded property-sets + local product = [ x-product $(expanded-property-sets) : $(feature-space) ] ; + + return $(product) ; +} + + +# Implementation of x-product, below. Expects all the project files to already +# be loaded. +# +local rule x-product-aux ( property-sets + ) +{ + local result ; + local p = [ feature.split $(property-sets[1]) ] ; + local f = [ set.difference $(p:G) : [ feature.free-features ] ] ; + local seen ; + # No conflict with things used at a higher level? + if ! [ set.intersection $(f) : $(x-product-used) ] + { + local x-product-seen ; + { + # Do not mix in any conflicting features. + local x-product-used = $(x-product-used) $(f) ; + + if $(property-sets[2]) + { + local rest = [ x-product-aux $(property-sets[2-]) : $(feature-space) ] ; + result = $(property-sets[1])/$(rest) ; + } + + result ?= $(property-sets[1]) ; + } + + # If we did not encounter a conflicting feature lower down, do not + # recurse again. + if ! [ set.intersection $(f) : $(x-product-seen) ] + { + property-sets = ; + } + + seen = $(x-product-seen) ; + } + + if $(property-sets[2]) + { + result += [ x-product-aux $(property-sets[2-]) : $(feature-space) ] ; + } + + # Note that we have seen these features so that higher levels will recurse + # again without them set. + x-product-seen += $(f) $(seen) ; + return $(result) ; +} + + +# Return the cross-product of all elements of property-sets, less any that would +# contain conflicting values for single-valued features. Expects all the project +# files to already be loaded. +# +local rule x-product ( property-sets * ) +{ + if $(property-sets).non-empty + { + # Prepare some "scoped globals" that can be used by the implementation + # function, x-product-aux. + local x-product-seen x-product-used ; + return [ x-product-aux $(property-sets) : $(feature-space) ] ; + } + # Otherwise return empty. +} + + +# Returns true if either 'v' or the part of 'v' before the first '-' symbol is +# an implicit value. Expects all the project files to already be loaded. +# +local rule looks-like-implicit-value ( v ) +{ + if [ feature.is-implicit-value $(v) ] + { + return true ; + } + else + { + local split = [ regex.split $(v) - ] ; + if [ feature.is-implicit-value $(split[1]) ] + { + return true ; + } + } +} + + +# Takes the command line tokens (such as taken from the ARGV rule) and +# constructs a build request from them. Returns a vector of two vectors (where +# "vector" means container.jam's "vector"). First is the set of targets +# specified in the command line, and second is the set of requested build +# properties. Expects all the project files to already be loaded. +# +rule from-command-line ( command-line * ) +{ + local targets ; + local properties ; + + command-line = $(command-line[2-]) ; + local skip-next = ; + for local e in $(command-line) + { + if $(skip-next) + { + skip-next = ; + } + else if ! [ MATCH "^(-).*" : $(e) ] + { + # Build request spec either has "=" in it or completely consists of + # implicit feature values. + local fs = feature-space ; + if [ MATCH "(.*=.*)" : $(e) ] + || [ looks-like-implicit-value $(e:D=) : $(feature-space) ] + { + properties += [ convert-command-line-element $(e) : + $(feature-space) ] ; + } + else + { + targets += $(e) ; + } + } + else if [ MATCH "^(-[-ldjfsto])$" : $(e) ] + { + skip-next = true ; + } + } + return [ new vector + [ new vector $(targets) ] + [ new vector $(properties) ] ] ; +} + + +# Converts one element of command line build request specification into internal +# form. Expects all the project files to already be loaded. +# +local rule convert-command-line-element ( e ) +{ + local result ; + local parts = [ regex.split $(e) "/" ] ; + while $(parts) + { + local p = $(parts[1]) ; + local m = [ MATCH "([^=]*)=(.*)" : $(p) ] ; + local lresult ; + local feature ; + local values ; + if $(m) + { + feature = $(m[1]) ; + values = [ regex.split $(m[2]) "," ] ; + lresult = <$(feature)>$(values) ; + } + else + { + lresult = [ regex.split $(p) "," ] ; + } + + if $(feature) && free in [ feature.attributes $(feature) ] + { + # If we have free feature, then the value is everything + # until the end of the command line token. Slashes in + # the following string are not taked to mean separation + # of properties. Commas are also not interpreted specially. + values = $(values:J=,) ; + values = $(values) $(parts[2-]) ; + values = $(values:J=/) ; + lresult = <$(feature)>$(values) ; + parts = ; + } + + if ! [ MATCH (.*-.*) : $(p) ] + { + # property.validate cannot handle subfeatures, so we avoid the check + # here. + for local p in $(lresult) + { + property.validate $(p) : $(feature-space) ; + } + } + + if ! $(result) + { + result = $(lresult) ; + } + else + { + result = $(result)/$(lresult) ; + } + + parts = $(parts[2-]) ; + } + + return $(result) ; +} + + +rule __test__ ( ) +{ + import assert ; + import feature ; + + feature.prepare-test build-request-test-temp ; + + import build-request ; + import build-request : expand-no-defaults : build-request.expand-no-defaults ; + import errors : try catch ; + import feature : feature subfeature ; + + feature toolset : gcc msvc borland : implicit ; + subfeature toolset gcc : version : 2.95.2 2.95.3 2.95.4 + 3.0 3.0.1 3.0.2 : optional ; + + feature variant : debug release : implicit composite ; + feature inlining : on off ; + feature "include" : : free ; + + feature stdlib : native stlport : implicit ; + + feature runtime-link : dynamic static : symmetric ; + + # Empty build requests should expand to empty. + assert.result + : build-request.expand-no-defaults ; + + assert.result + <toolset>gcc/<toolset-gcc:version>3.0.1/<stdlib>stlport/<variant>debug + <toolset>msvc/<stdlib>stlport/<variant>debug + <toolset>msvc/<variant>debug + : build-request.expand-no-defaults gcc-3.0.1/stlport msvc/stlport msvc debug ; + + assert.result + <toolset>gcc/<toolset-gcc:version>3.0.1/<stdlib>stlport/<variant>debug + <toolset>msvc/<variant>debug + <variant>debug/<toolset>msvc/<stdlib>stlport + : build-request.expand-no-defaults gcc-3.0.1/stlport msvc debug msvc/stlport ; + + assert.result + <toolset>gcc/<toolset-gcc:version>3.0.1/<stdlib>stlport/<variant>debug/<inlining>off + <toolset>gcc/<toolset-gcc:version>3.0.1/<stdlib>stlport/<variant>release/<inlining>off + : build-request.expand-no-defaults gcc-3.0.1/stlport debug release <inlining>off ; + + assert.result + <include>a/b/c/<toolset>gcc/<toolset-gcc:version>3.0.1/<stdlib>stlport/<variant>debug/<include>x/y/z + <include>a/b/c/<toolset>msvc/<stdlib>stlport/<variant>debug/<include>x/y/z + <include>a/b/c/<toolset>msvc/<variant>debug/<include>x/y/z + : build-request.expand-no-defaults <include>a/b/c gcc-3.0.1/stlport msvc/stlport msvc debug <include>x/y/z ; + + local r ; + + r = [ build-request.from-command-line bjam debug runtime-link=dynamic ] ; + assert.equal [ $(r).get-at 1 ] : ; + assert.equal [ $(r).get-at 2 ] : debug <runtime-link>dynamic ; + + try ; + { + build-request.from-command-line bjam gcc/debug runtime-link=dynamic/static ; + } + catch \"static\" is not a value of an implicit feature ; + + r = [ build-request.from-command-line bjam -d2 --debug debug target runtime-link=dynamic ] ; + assert.equal [ $(r).get-at 1 ] : target ; + assert.equal [ $(r).get-at 2 ] : debug <runtime-link>dynamic ; + + r = [ build-request.from-command-line bjam debug runtime-link=dynamic,static ] ; + assert.equal [ $(r).get-at 1 ] : ; + assert.equal [ $(r).get-at 2 ] : debug <runtime-link>dynamic <runtime-link>static ; + + r = [ build-request.from-command-line bjam debug gcc/runtime-link=dynamic,static ] ; + assert.equal [ $(r).get-at 1 ] : ; + assert.equal [ $(r).get-at 2 ] : debug gcc/<runtime-link>dynamic + gcc/<runtime-link>static ; + + r = [ build-request.from-command-line bjam msvc gcc,borland/runtime-link=static ] ; + assert.equal [ $(r).get-at 1 ] : ; + assert.equal [ $(r).get-at 2 ] : msvc gcc/<runtime-link>static + borland/<runtime-link>static ; + + r = [ build-request.from-command-line bjam gcc-3.0 ] ; + assert.equal [ $(r).get-at 1 ] : ; + assert.equal [ $(r).get-at 2 ] : gcc-3.0 ; + + feature.finish-test build-request-test-temp ; +} |