📄 builtin.jam
字号:
{ parents = $(parents-or-properties) ; } } else { parents = $(parents-or-properties) ; } # The problem is that we have to check for conflicts between base variants. if $(parents[2]) { errors.error "multiple base variants are not yet supported" ; } local inherited ; # Add explicitly specified properties for parents. for local p in $(parents) { # TODO: This check may be made stricter. if ! [ feature.is-implicit-value $(p) ] { errors.error "Invalid base variant" $(p) ; } inherited += $(.explicit-properties.$(p)) ; } property.validate $(explicit-properties) ; explicit-properties = [ property.refine $(inherited) : $(explicit-properties) ] ; # Record explicitly specified properties for this variant. We do this after # inheriting parents' properties so they affect other variants derived from # this one. .explicit-properties.$(name) = $(explicit-properties) ; feature.extend variant : $(name) ; feature.compose <variant>$(name) : $(explicit-properties) ;}IMPORT $(__name__) : variant : : variant ;variant debug : <optimization>off <debug-symbols>on <inlining>off <runtime-debugging>on ;variant release : <optimization>speed <debug-symbols>off <inlining>full <runtime-debugging>off <define>NDEBUG ;variant profile : release : <profiling>on <debug-symbols>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 ( ) { }}class c-scanner : scanner{ import path ; import regex ; import scanner ; import sequence ; import virtual-target ; rule __init__ ( includes * ) { scanner.__init__ ; for local i in $(includes) { self.includes += [ sequence.transform path.native : [ regex.split $(i:G=) "&&" ] ] ; } } rule pattern ( ) { return "#[ \t]*include[ ]*(<(.*)>|\"(.*)\")" ; } rule process ( target : matches * : binding ) { local angle = [ regex.transform $(matches) : "<(.*)>" ] ; local quoted = [ regex.transform $(matches) : "\"(.*)\"" ] ; # CONSIDER: the new scoping rule seem to defeat "on target" variables. local g = [ on $(target) return $(HDRGRIST) ] ; local b = [ NORMALIZE_PATH $(binding:D) ] ; # Attach binding of including file to included targets. When a target is # directly created from virtual target this extra information is # unnecessary. But in other cases, it allows us to distinguish between # two headers of the same name included from different places. We do not # need this extra information for angle includes, since they should not # depend on including file (we can not get literal "." in include path). local g2 = $(g)"#"$(b) ; angle = $(angle:G=$(g)) ; quoted = $(quoted:G=$(g2)) ; local all = $(angle) $(quoted) ; INCLUDES $(target) : $(all) ; NOCARE $(all) ; SEARCH on $(angle) = $(self.includes:G=) ; SEARCH on $(quoted) = $(b) $(self.includes:G=) ; # Just propagate the current scanner to includes in hope that includes # do not change scanners. scanner.propagate $(__name__) : $(angle) $(quoted) : $(target) ; ISFILE $(angle) $(quoted) ; }}type.register H : h ;type.register HPP : hpp : H ;type.register C : c ;scanner.register c-scanner : include ;# It most cases where a CPP file or a H file is a source of some action, we# should rebuild the result if any of files included by CPP/H are changed. One# case when this is not needed is installation, which is handled specifically.type.set-scanner CPP : c-scanner ;type.set-scanner C : c-scanner ;# One case where scanning of H/HPP files is necessary is PCH generation -- if# any header included by HPP being precompiled changes, we need to recompile the# header.type.set-scanner H : c-scanner ;type.set-scanner HPP : c-scanner ;# 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) ; } 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 ; # <source>files can be generated by <conditional>@rule feature # in which case we do not consider it a SEARCHED_LIB type. if ! <source> in $(properties:G) && ( <search> in $(properties:G) || <name> in $(properties:G) ) { actual-type = SEARCHED_LIB ; } else if <file> in $(properties:G) { actual-type = LIB ; } else if <link>shared in $(properties) { actual-type = SHARED_LIB ; } else { actual-type = STATIC_LIB ; } property-set = [ $(property-set).add-raw <main-target-type>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 <name> in $(requirements:G) { errors.user-error "When several names are given to the 'lib' rule" : "it is not allowed to specify the <name> 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) && ! <name> in $(requirements:G) && ! <file> in $(requirements:G) { r += <name>$(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're # 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 <link>shared in $(properties) { shared = true ; } local search = [ feature.get-values <search> : $(properties) ] ; local a = [ new null-action $(property-set) ] ; local lib-name = [ feature.get-values <name> : $(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 : <name>png ; # the 'z' target should be returned, so that apps linking to 'png' # will link to 'z', too. return [ property-set.create <xdll-path>$(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) ; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -