📄 builtin.jam
字号:
# usage requirement.
local search = [ $(rproperties).get <search> ] ;
if $(search)
{
result = [ $(result).add [
property-set.create $(search:G=<library-path>) ] ] ;
}
# If <hardcode-dll-paths> is true, add appropricate <dll-path> usage
# requirements.
local raw = [ $(rproperties).raw ] ;
if <link>shared in $(raw) && <hardcode-dll-paths>true 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) ] ;
}
}
if $(paths)
{
result = [ $(result).add
[ property-set.create $(paths:G=<dll-path>) ] ] ;
}
}
# Pass <dll-path> features that we've got from sources.
if <hardcode-dll-paths>true in $(raw)
{
local u = [ $(subvariant).sources-usage-requirements ] ;
local values = [ $(u).get <dll-path> ] ;
result = [ $(result).add-raw $(values:G=<dll-path>) ] ;
}
# For libraries that we've failed to consume, we need to
# pass <library-path> usage requirements, if any.
# We look at all generated target, and if they are created in different
# subvariant, we add usage requirements.
for local t in [ $(subvariant).created-targets ]
{
local s = [ $(t).creating-subvariant ] ;
if $(s) != $(subvariant)
{
result = [ $(result).add [ $(s).usage-requirements ] ] ;
}
}
return $(result) ;
}
}
rule lib ( name : sources * : requirements * : default-build *
: usage-requirements * )
{
local project = [ CALLER_MODULE ] ;
# This is a circular module dependency, so it must be imported here
import targets ;
targets.main-target-alternative
[ new lib-target-class $(name) : $(project)
: [ targets.main-target-sources $(sources) : $(name) ]
: [ targets.main-target-requirements $(requirements) : $(project) ]
: [ targets.main-target-default-build $(default-build) : $(project) ]
: [ targets.main-target-usage-requirements $(usage-requirements) : $(project) ]
] ;
}
IMPORT $(__name__) : lib : : lib ;
class exe-target-class : typed-target
{
rule __init__ ( name : project
: sources * : requirements * : default-build * : usage-requirements * )
{
typed-target.__init__ $(name) : $(project) : EXE
: $(sources) : $(requirements) : $(default-build) : $(usage-requirements) ;
}
rule compute-usage-requirements ( subvariant )
{
local result = [ typed-target.compute-usage-requirements $(subvariant) ] ;
local p = [ $(subvariant).build-properties ] ;
if <hardcode-dll-paths>true in [ $(p).raw ]
{
local dll-paths = [ $(p).get <dll-path> ] ;
if $(dll-paths)
{
result = [ $(result).add-raw $(dll-paths:G=<dll-path>) ] ;
}
}
return $(result) ;
}
}
rule exe ( name : sources * : requirements * : default-build *
: usage-requirements * )
{
local project = [ CALLER_MODULE ] ;
# This is a circular module dependency, so it must be imported here
import targets ;
targets.main-target-alternative
[ new exe-target-class $(name) : $(project)
: [ targets.main-target-sources $(sources) : $(name) ]
: [ targets.main-target-requirements $(requirements) : $(project) ]
: [ targets.main-target-default-build $(default-build) : $(project) ]
: [ targets.main-target-usage-requirements $(usage-requirements) : $(project) ]
] ;
}
IMPORT $(__name__) : exe : : exe ;
class searched-lib-generator : generator
{
rule __init__ ( )
{
# The requirements cause the generators to be tried *only* when we're building
# lib target and there's 'search' feature. This seems ugly --- all we want
# is make sure searched-lib-generator is not invoced deep in transformation
# search.
generator.__init__ searched-lib-generator : : SEARCHED_LIB ;
}
rule run ( project name ? : property-set : sources * : multiple ? )
{
if $(name)
{
# If name is empty, it means we're called not from top-level.
# 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 <link>shared in $(properties)
{
shared = true ;
}
local t = [ new searched-lib-target $(name) : $(project) : $(shared)
: [ feature.get-values <name> : $(properties) ]
: [ feature.get-values <search> : $(properties) ]
] ;
# attach an action and properties to the target
a = [ new null-action $(t) : $(property-set) ] ;
$(t).action $(a) ;
return [ virtual-target.register $(t) ] ;
}
}
}
generators.register [ new searched-lib-generator ] ;
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 include path.
rule adjust-properties ( properties * )
{
local s = [ $(self.targets[1]).creating-subvariant ] ;
return $(properties) [ $(s).implicit-includes "include" : H ] ;
}
}
class C-compiling-generator : generator
{
rule __init__ ( id : source-types + : target-types + :
requirements * )
{
generator.__init__ $(id) : $(source-types) : $(target-types) :
$(requirements) ;
}
rule action-class ( )
{
return compile-action ;
}
}
rule register-c-compiler ( id : source-types + : target-types + :
requirements * )
{
local g = [ new C-compiling-generator $(id) : $(source-types)
: $(target-types) : $(requirements) ] ;
generators.register $(g) ;
}
# FIXME: this is ugly, should find a better way (we'd want client code to
# register all generators as "generator.some-rule", not with "some-module.some-rule".)
IMPORT $(__name__) : register-c-compiler : : generators.register-c-compiler ;
class link-action : action
{
import path ;
import sequence ;
rule __init__ ( targets + : sources * : action-name : properties * )
{
action.__init__ $(targets) : $(sources) : $(action-name) : $(properties) ;
}
# Filters out all sources which are of LIB type and actualizes the remaining
# sources by calling base method.
rule actualize-sources ( sources * )
{
local real-sources ;
for local s in $(sources)
{
if ! [ type.is-derived [ $(s).type ] LIB ]
{
real-sources += $(s) ;
}
else
{
self.dependency-only-sources += [ $(s).actualize ] ;
}
}
action.actualize-sources $(real-sources) ;
}
}
class linking-generator : generator
{
import property-set ;
rule __init__ ( id
composing ? : # Specify if generator is composing. The generator will be
# composing if non-empty string is passed, or parameter is
# not given. To make generator non-composing, pass 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 + : multiple ? )
{
local libs = [ $(property-set).get <library> ] ;
sources += $(libs:G=) ;
local result = [ generator.run $(project) $(name) : $(property-set)
: $(sources) : $(multiple) ] ;
if $(result)
{
# Explicitly set dependency on all <library> features.
local libs = [ feature.get-values <library> :
[ $(property-set).raw ] ] ;
if $(libs)
{
for local t in $(result)
{
# The 'if' statement handles the case where
# one of the targets created by <library> is not
# consumed and is part of result. DLLs on windows
# are an example.
if $(libs:G=) != $(t)
{
$(t).depends $(libs:G=) ;
}
}
}
}
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 ; # sources which are libraries
# Separate 'sources' into 'libraries' and 'sources2'.
# It is needed because library sources need special treatment.
for local s in $(sources)
{
if [ type.is-derived [ $(s).type ] LIB ]
{
libraries += $(s) ;
}
else
{
sources2 += $(s) ;
}
}
# For all library source, add necessary property. Depending on
# target type, it's either <library-file>, <find-shared-library>
# or <find-static-library>.
properties2 = [ $(property-set).raw ] ;
for local s in $(libraries)
{
if [ class.is-a $(s) : searched-lib-target ]
{
local name = [ $(s).real-name ] ;
if [ $(s).shared ]
{
properties2 += <find-shared-library>$(name) ;
}
else
{
properties2 += <find-static-library>$(name) ;
}
}
else
{
properties2 += <library-file>$(s) ;
}
}
# Sorry, still pass 'sources', which includes library targets.
# We need to set dependency on libraries, which is currently done
# by 'actualize-sources' above, via some secret hook. We need a better
# mechanism, but until it's implemented, need to pass all sources.
local spawn = [ generator.generated-targets $(sources)
: [ property-set.create $(properties2) ] : $(project) $(name) ] ;
# And we'll also get warning about unused sources :-(
#if $(libraries)
#{
# for local s in $(spawn)
# {
# $(s).depends $(libraries) ;
# }
#}
return $(spawn) ;
}
rule action-class ( )
{
return link-action ;
}
}
rule register-linker ( id composing ? : source-types + : target-types + :
requirements * )
{
local g = [ new linking-generator $(id) $(composing) : $(source-types)
: $(target-types) : $(requirements) ] ;
generators.register $(g) ;
}
IMPORT $(__name__) : register-linker : : generators.register-linker ;
declare-type : RSP : rsp ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -