From 3faecf9a00512dcbc8712c4bca9adae72fb64410 Mon Sep 17 00:00:00 2001 From: Kenneth Heafield Date: Sat, 12 May 2012 14:01:52 -0400 Subject: Give in and copy bjam into cdec source code --- jam-files/boost-build/tools/stage.jam | 524 ++++++++++++++++++++++++++++++++++ 1 file changed, 524 insertions(+) create mode 100644 jam-files/boost-build/tools/stage.jam (limited to 'jam-files/boost-build/tools/stage.jam') diff --git a/jam-files/boost-build/tools/stage.jam b/jam-files/boost-build/tools/stage.jam new file mode 100644 index 00000000..296e7558 --- /dev/null +++ b/jam-files/boost-build/tools/stage.jam @@ -0,0 +1,524 @@ +# Copyright 2003 Dave Abrahams +# Copyright 2005, 2006 Rene Rivera +# Copyright 2002, 2003, 2004, 2005, 2006 Vladimir Prus +# 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) + +# This module defines the 'install' rule, used to copy a set of targets to a +# single location. + +import targets ; +import "class" : new ; +import errors ; +import type ; +import generators ; +import feature ; +import project ; +import virtual-target ; +import path ; +import types/register ; + + +feature.feature : off on : incidental ; +feature.feature : : free incidental ; +feature.feature : : free path ; +feature.feature : : free incidental ; + +# If 'on', version symlinks for shared libraries will not be created. Affects +# Unix builds only. +feature.feature : on : optional incidental ; + + +class install-target-class : basic-target +{ + import feature ; + import project ; + import type ; + import errors ; + import generators ; + import path ; + import stage ; + import "class" : new ; + import property ; + import property-set ; + + rule __init__ ( name-and-dir : project : sources * : requirements * : default-build * ) + { + basic-target.__init__ $(name-and-dir) : $(project) : $(sources) : + $(requirements) : $(default-build) ; + } + + # If is not set, sets it based on the project data. + # + rule update-location ( property-set ) + { + local loc = [ $(property-set).get ] ; + if ! $(loc) + { + loc = [ path.root $(self.name) [ $(self.project).get location ] ] ; + property-set = [ $(property-set).add-raw $(loc:G=) ] ; + } + + return $(property-set) ; + } + + # Takes a target that is installed and a property set which is used when + # installing. + # + rule adjust-properties ( target : build-property-set ) + { + local ps-raw ; + local a = [ $(target).action ] ; + if $(a) + { + local ps = [ $(a).properties ] ; + ps-raw = [ $(ps).raw ] ; + + # Unless true is in properties, which can happen + # only if the user has explicitly requested it, nuke all + # properties. + if [ $(build-property-set).get ] != true + { + ps-raw = [ property.change $(ps-raw) : ] ; + } + + # If any properties were specified for installing, add + # them. + local l = [ $(build-property-set).get ] ; + ps-raw += $(l:G=) ; + + # Also copy feature from current build set, to be used + # for relinking. + local l = [ $(build-property-set).get ] ; + ps-raw += $(l:G=) ; + + # Remove the feature on original targets. + ps-raw = [ property.change $(ps-raw) : ] ; + + # And . If stage target has another stage target in + # sources, then we shall get virtual targets with the + # property set. + ps-raw = [ property.change $(ps-raw) : ] ; + } + + local d = [ $(build-property-set).get ] ; + ps-raw += $(d:G=) ; + + local d = [ $(build-property-set).get ] ; + ps-raw += $(d:G=) ; + + local ns = [ $(build-property-set).get ] ; + ps-raw += $(ns:G=) ; + + local d = [ $(build-property-set).get ] ; + # Make the path absolute: we shall use it to compute relative paths and + # making the path absolute will help. + if $(d) + { + d = [ path.root $(d) [ path.pwd ] ] ; + ps-raw += $(d:G=) ; + } + + if $(ps-raw) + { + return [ property-set.create $(ps-raw) ] ; + } + else + { + return [ property-set.empty ] ; + } + } + + rule construct ( name : source-targets * : property-set ) + { + source-targets = [ targets-to-stage $(source-targets) : + $(property-set) ] ; + + property-set = [ update-location $(property-set) ] ; + + local ename = [ $(property-set).get ] ; + + if $(ename) && $(source-targets[2]) + { + errors.error "When property is used in 'install', only one" + "source is allowed" ; + } + + local result ; + for local i in $(source-targets) + { + local staged-targets ; + + local new-properties = [ adjust-properties $(i) : + $(property-set) ] ; + + # See if something special should be done when staging this type. It + # is indicated by the presence of a special "INSTALLED_" type. + local t = [ $(i).type ] ; + if $(t) && [ type.registered INSTALLED_$(t) ] + { + if $(ename) + { + errors.error "In 'install': property specified with target that requires relinking." ; + } + else + { + local targets = [ generators.construct $(self.project) + $(name) : INSTALLED_$(t) : $(new-properties) : $(i) ] ; + staged-targets += $(targets[2-]) ; + } + } + else + { + staged-targets = [ stage.copy-file $(self.project) $(ename) : + $(i) : $(new-properties) ] ; + } + + if ! $(staged-targets) + { + errors.error "Unable to generate staged version of " [ $(source).str ] ; + } + + for t in $(staged-targets) + { + result += [ virtual-target.register $(t) ] ; + } + } + + return [ property-set.empty ] $(result) ; + } + + # Given the list of source targets explicitly passed to 'stage', returns the + # list of targets which must be staged. + # + rule targets-to-stage ( source-targets * : property-set ) + { + local result ; + + # Traverse the dependencies, if needed. + if [ $(property-set).get ] = "on" + { + source-targets = [ collect-targets $(source-targets) ] ; + } + + # Filter the target types, if needed. + local included-types = [ $(property-set).get ] ; + for local r in $(source-targets) + { + local ty = [ $(r).type ] ; + if $(ty) + { + # Do not stage searched libs. + if $(ty) != SEARCHED_LIB + { + if $(included-types) + { + if [ include-type $(ty) : $(included-types) ] + { + result += $(r) ; + } + } + else + { + result += $(r) ; + } + } + } + else if ! $(included-types) + { + # Don't install typeless target if there is an explicit list of + # allowed types. + result += $(r) ; + } + } + + return $(result) ; + } + + # CONSIDER: figure out why we can not use virtual-target.traverse here. + # + rule collect-targets ( targets * ) + { + # Find subvariants + local s ; + for local t in $(targets) + { + s += [ $(t).creating-subvariant ] ; + } + s = [ sequence.unique $(s) ] ; + + local result = [ new set ] ; + $(result).add $(targets) ; + + for local i in $(s) + { + $(i).all-referenced-targets $(result) ; + } + local result2 ; + for local r in [ $(result).list ] + { + if $(r:G) != + { + result2 += $(r:G=) ; + } + } + DELETE_MODULE $(result) ; + result = [ sequence.unique $(result2) ] ; + } + + # Returns true iff 'type' is subtype of some element of 'types-to-include'. + # + local rule include-type ( type : types-to-include * ) + { + local found ; + while $(types-to-include) && ! $(found) + { + if [ type.is-subtype $(type) $(types-to-include[1]) ] + { + found = true ; + } + types-to-include = $(types-to-include[2-]) ; + } + + return $(found) ; + } +} + + +# Creates a copy of target 'source'. The 'properties' object should have a +# property which specifies where the target must be placed. +# +rule copy-file ( project name ? : source : properties ) +{ + name ?= [ $(source).name ] ; + local relative ; + + local new-a = [ new non-scanning-action $(source) : common.copy : + $(properties) ] ; + local source-root = [ $(properties).get ] ; + if $(source-root) + { + # Get the real path of the target. We probably need to strip relative + # path from the target name at construction. + local path = [ $(source).path ] ; + path = [ path.root $(name:D) $(path) ] ; + # Make the path absolute. Otherwise, it would be hard to compute the + # relative path. The 'source-root' is already absolute, see the + # 'adjust-properties' method above. + path = [ path.root $(path) [ path.pwd ] ] ; + + relative = [ path.relative-to $(source-root) $(path) ] ; + } + + # Note: Using $(name:D=$(relative)) might be faster here, but then we would + # need to explicitly check that relative is not ".", otherwise we might get + # paths like '/boost/.', try to create it and mkdir would obviously + # fail. + name = [ path.join $(relative) $(name:D=) ] ; + + return [ new file-target $(name) exact : [ $(source).type ] : $(project) : + $(new-a) ] ; +} + + +rule symlink ( name : project : source : properties ) +{ + local a = [ new action $(source) : symlink.ln : $(properties) ] ; + return [ new file-target $(name) exact : [ $(source).type ] : $(project) : + $(a) ] ; +} + + +rule relink-file ( project : source : property-set ) +{ + local action = [ $(source).action ] ; + local cloned-action = [ virtual-target.clone-action $(action) : $(project) : + "" : $(property-set) ] ; + return [ $(cloned-action).targets ] ; +} + + +# Declare installed version of the EXE type. Generator for this type will cause +# relinking to the new location. +type.register INSTALLED_EXE : : EXE ; + + +class installed-exe-generator : generator +{ + import type ; + import property-set ; + import modules ; + import stage ; + + rule __init__ ( ) + { + generator.__init__ install-exe : EXE : INSTALLED_EXE ; + } + + rule run ( project name ? : property-set : source : multiple ? ) + { + local need-relink ; + + if [ $(property-set).get ] in NT CYGWIN || + [ $(property-set).get ] in windows cygwin + { + } + else + { + # See if the dll-path properties are not changed during + # install. If so, copy, don't relink. + local a = [ $(source).action ] ; + local p = [ $(a).properties ] ; + local original = [ $(p).get ] ; + local current = [ $(property-set).get ] ; + + if $(current) != $(original) + { + need-relink = true ; + } + } + + + if $(need-relink) + { + return [ stage.relink-file $(project) + : $(source) : $(property-set) ] ; + } + else + { + return [ stage.copy-file $(project) + : $(source) : $(property-set) ] ; + } + } +} + + +generators.register [ new installed-exe-generator ] ; + + +# Installing a shared link on Unix might cause a creation of versioned symbolic +# links. +type.register INSTALLED_SHARED_LIB : : SHARED_LIB ; + + +class installed-shared-lib-generator : generator +{ + import type ; + import property-set ; + import modules ; + import stage ; + + rule __init__ ( ) + { + generator.__init__ install-shared-lib : SHARED_LIB + : INSTALLED_SHARED_LIB ; + } + + rule run ( project name ? : property-set : source : multiple ? ) + { + if [ $(property-set).get ] in NT CYGWIN || + [ $(property-set).get ] in windows cygwin + { + local copied = [ stage.copy-file $(project) : $(source) : + $(property-set) ] ; + return [ virtual-target.register $(copied) ] ; + } + else + { + local a = [ $(source).action ] ; + local copied ; + if ! $(a) + { + # Non-derived file, just copy. + copied = [ stage.copy-file $(project) : $(source) : + $(property-set) ] ; + } + else + { + local cp = [ $(a).properties ] ; + local current-dll-path = [ $(cp).get ] ; + local new-dll-path = [ $(property-set).get ] ; + + if $(current-dll-path) != $(new-dll-path) + { + # Rpath changed, need to relink. + copied = [ stage.relink-file $(project) : $(source) : + $(property-set) ] ; + } + else + { + copied = [ stage.copy-file $(project) : $(source) : + $(property-set) ] ; + } + } + + copied = [ virtual-target.register $(copied) ] ; + + local result = $(copied) ; + # If the name is in the form NNN.XXX.YYY.ZZZ, where all 'X', 'Y' and + # 'Z' are numbers, we need to create NNN.XXX and NNN.XXX.YYY + # symbolic links. + local m = [ MATCH (.*)\\.([0123456789]+)\\.([0123456789]+)\\.([0123456789]+)$ + : [ $(copied).name ] ] ; + if $(m) + { + # Symlink without version at all is used to make + # -lsome_library work. + result += [ stage.symlink $(m[1]) : $(project) : $(copied) : + $(property-set) ] ; + + # Symlinks of some libfoo.N and libfoo.N.M are used so that + # library can found at runtime, if libfoo.N.M.X has soname of + # libfoo.N. That happens when the library makes some binary + # compatibility guarantees. If not, it is possible to skip those + # symlinks. + local suppress = + [ $(property-set).get ] ; + + if $(suppress) != "on" + { + result += [ stage.symlink $(m[1]).$(m[2]) : $(project) + : $(copied) : $(property-set) ] ; + result += [ stage.symlink $(m[1]).$(m[2]).$(m[3]) : $(project) + : $(copied) : $(property-set) ] ; + } + } + + return $(result) ; + } + } +} + +generators.register [ new installed-shared-lib-generator ] ; + + +# Main target rule for 'install'. +# +rule install ( name : sources * : requirements * : default-build * ) +{ + local project = [ project.current ] ; + + # Unless the user has explicitly asked us to hardcode dll paths, add + # false in requirements, to override default value. + if ! true in $(requirements) + { + requirements += false ; + } + + if in $(requirements:G) + { + errors.user-error + "The property is not allowed for the 'install' rule" ; + } + + targets.main-target-alternative + [ new install-target-class $(name) : $(project) + : [ targets.main-target-sources $(sources) : $(name) ] + : [ targets.main-target-requirements $(requirements) : $(project) ] + : [ targets.main-target-default-build $(default-build) : $(project) ] + ] ; +} + + +IMPORT $(__name__) : install : : install ; +IMPORT $(__name__) : install : : stage ; -- cgit v1.2.3