📄 builtin.jam
字号:
rule run ( project name ? : property-set : sources * ) { local f = [ $(property-set).get <file> ] ; return $(f) $(sources) ; }}generators.register [ new prebuilt-lib-generator builtin.prebuilt : : LIB : <file> ] ;generators.override builtin.prebuilt : builtin.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 the include path. # rule adjust-properties ( property-set ) { local s = [ $(self.targets[1]).creating-subvariant ] ; return [ $(property-set).add-raw [ $(s).implicit-includes "include" : H ] ] ; }}# 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 <library> ] ; # Add <library-path> properties for all searched libraries. local extra ; for local s in $(sources) { if [ $(s).type ] = SEARCHED_LIB { local search = [ $(s).search ] ; extra += <library-path>$(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 <hardcode-dll-paths> ] = true && [ type.is-derived $(self.target-types[1]) EXE ] { local xdll-path = [ $(property-set).get <xdll-path> ] ; extra += <dll-path>$(xdll-path) <dll-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 <xdll-path>$(extra-xdll-paths) ] ] ; } return $(ur) $(result) ; } rule extra-usage-requirements ( created-targets * : property-set ) { local result = [ property-set.empty ] ; local extra ; # Add appropricate <xdll-path> usage requirements. local raw = [ $(property-set).raw ] ; if <link>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=<xdll-path>) ; } # We need to pass <xdll-path> 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 theorically possible # that we will propagate <xdll-path> features explicitly specified by # the user, but then the user is to blaim for using an internal feature. local values = [ $(property-set).get <xdll-path> ] ; extra += $(values:G=<xdll-path>) ; 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 += <find-shared-library>$(fsa:J=&&) <find-static-library>$(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 <library> ] ; 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 <library> usage requirements. # The problem with the first is: # # lib a1 : : <file>liba1.a ; # lib a2 : a2.cpp a1 : <link>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 <link> ] = static { for local t in $(sources) { if [ type.is-derived [ $(t).type ] LIB ] { usage-requirements += <library>$(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 ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -