📄 virtual-target.jam
字号:
# the sources of the target. For example to make unique names of object # files based on the source file. --grafik ps = [ property-set.create [ $(ps).raw ] <target>$(__name__) ] ; local tag = [ $(ps).get <tag> ] ; if $(tag) { local rule-name = [ MATCH ^@(.*) : $(tag) ] ; if $(rule-name) { if $(tag[2]) { errors.error "<tag>@rulename is present but is not the only" "<tag> feature" ; } self.name = [ indirect.call $(rule-name) $(specified-name) : $(self.type) : $(ps) ] ; } else { errors.error "The value of the <tag> feature must be '@rule-name'" ; } } # If there is no tag or the tag rule returned nothing. if ! $(tag) || ! $(self.name) { self.name = [ virtual-target.add-prefix-and-suffix $(specified-name) : $(self.type) : $(ps) ] ; } } rule actualize-no-scanner ( ) { local name = [ actual-name ] ; # Do anything only on the first invocation. if ! $(self.made.$(name)) { self.made.$(name) = true ; if $(self.action) { # For non-derived target, we do not care if there are several # virtual targets that refer to the same name. One case when # this is unavoidable is when the file name is main.cpp and two # targets have types CPP (for compiling) and MOCCABLE_CPP (for # conversion to H via Qt tools). virtual-target.register-actual-name $(name) : $(__name__) ; } for local i in $(self.dependencies) { DEPENDS $(name) : [ $(i).actualize ] ; } actualize-location $(name) ; actualize-action $(name) ; } return $(name) ; }}# Appends the suffix appropriate to 'type/property-set' combination to the# specified name and returns the result.#rule add-prefix-and-suffix ( specified-name : type ? : property-set ){ local suffix = [ type.generated-target-suffix $(type) : $(property-set) ] ; # Handle suffixes for which no leading dot is desired. Those are specified # by enclosing them in <...>. Needed by python so it can create "_d.so" # extensions, for example. if $(suffix:G) { suffix = [ utility.ungrist $(suffix) ] ; } else { suffix = .$(suffix) ; } local prefix = [ type.generated-target-prefix $(type) : $(property-set) ] ; if [ MATCH ^($(prefix)) : $(specified-name) ] { prefix = ; } return $(prefix:E="")$(specified-name)$(suffix:E="") ;}# File targets with explicitly known location.## The file path is determined as# * Value passed to the 'set-path' method, if any.# * For derived files, project's build dir, joined with components that# describe action properties. If free properties are not equal to the# project's reference properties an element with the name of the main# target is added.# * For source files, project's source dir.## The file suffix is determined as:# * The value passed to the 'suffix' method, if any.# * The suffix corresponding to the target's type.#class file-target : abstract-file-target{ import "class" : new ; import common ; import errors ; rule __init__ ( name exact ? : type ? # Optional type for this target. : project : action ? : path ? ) { abstract-file-target.__init__ $(name) $(exact) : $(type) : $(project) : $(action) ; self.path = $(path) ; } rule clone-with-different-type ( new-type ) { return [ new file-target $(self.name) exact : $(new-type) : $(self.project) : $(self.action) : $(self.path) ] ; } rule actualize-location ( target ) { if $(self.action) { # This is a derived file. local path = [ path ] ; LOCATE on $(target) = $(path) ; # Make sure the path exists. DEPENDS $(target) : $(path) ; common.MkDir $(path) ; # It is possible that the target name includes a directory too, for # example when installing headers. Create that directory. if $(target:D) { local d = $(target:D) ; d = $(d:R=$(path)) ; DEPENDS $(target) : $(d) ; common.MkDir $(d) ; } # For a real file target, we create a fake target depending on the # real target. This allows us to run # # bjam hello.o # # without trying to guess the name of the real target. Note that the # target has no directory name and uses a special <e> grist. # # First, that means that "bjam hello.o" will build all known hello.o # targets. Second, the <e> grist makes sure this target will not be # confused with other targets, for example, if we have subdir 'test' # with target 'test' in it that includes a 'test.o' file, then the # target for directory will be just 'test' the target for test.o # will be <ptest/bin/gcc/debug>test.o and the target we create below # will be <e>test.o DEPENDS $(target:G=e) : $(target) ; # Allow bjam <path-to-file>/<file> to work. This will not catch all # possible ways to refer to the path (relative/absolute, extra ".", # various "..", but should help in obvious cases. DEPENDS $(target:G=e:R=$(path)) : $(target) ; } else { SEARCH on $(target) = [ path.native $(self.path) ] ; } } # Returns the directory for this target. # rule path ( ) { if ! $(self.path) { if $(self.action) { local p = [ $(self.action).properties ] ; local path,relative-to-build-dir = [ $(p).target-path ] ; local path = $(path,relative-to-build-dir[1]) ; local relative-to-build-dir = $(path,relative-to-build-dir[2]) ; if $(relative-to-build-dir) { path = [ path.join [ $(self.project).build-dir ] $(path) ] ; } self.path = [ path.native $(path) ] ; } } return $(self.path) ; }}class notfile-target : abstract-file-target{ rule __init__ ( name : project : action ? ) { abstract-file-target.__init__ $(name) : : $(project) : $(action) ; } # Returns nothing to indicate that the target's path is not known. # rule path ( ) { return ; } rule actualize-location ( target ) { NOTFILE $(target) ; ALWAYS $(target) ; }}# Class representing an action. Both 'targets' and 'sources' should list# instances of 'virtual-target'. Action name should name a rule with this# prototype:# rule action-name ( targets + : sources * : properties * )# Targets and sources are passed as actual Jam targets. The rule may not# establish additional dependency relationships.#class action{ import "class" ; import errors ; import type ; import toolset ; import property-set ; import indirect ; import path ; rule __init__ ( sources * : action-name + : property-set ? ) { self.sources = $(sources) ; self.action-name = [ indirect.make-qualified $(action-name) ] ; if ! $(property-set) { property-set = [ property-set.empty ] ; } if ! [ class.is-instance $(property-set) ] { errors.error "Property set instance required" ; } self.properties = $(property-set) ; } rule add-targets ( targets * ) { self.targets += $(targets) ; } rule targets ( ) { return $(self.targets) ; } rule sources ( ) { return $(self.sources) ; } rule action-name ( ) { return $(self.action-name) ; } rule properties ( ) { return $(self.properties) ; } # Generates actual build instructions. # rule actualize ( ) { if ! $(self.actualized) { self.actualized = true ; local ps = [ properties ] ; local properties = [ adjust-properties $(ps) ] ; local actual-targets ; for local i in [ targets ] { actual-targets += [ $(i).actualize ] ; } actualize-sources [ sources ] : $(properties) ; DEPENDS $(actual-targets) : $(self.actual-sources) $(self.dependency-only-sources) ; # Action name can include additional argument to rule, which should # not be passed to 'set-target-variables' toolset.set-target-variables [ indirect.get-rule $(self.action-name[1]) ] $(actual-targets) : $(properties) ; # Reflect ourselves in a variable for the target. This allows # looking up additional info for the action given the raw target. # For example to debug or output action information from action # rules. .action on $(actual-targets) = $(__name__) ; indirect.call $(self.action-name) $(actual-targets) : $(self.actual-sources) : [ $(properties).raw ] ; # Since we set up the creating action here, we set up the action for # cleaning up as well. common.Clean clean-all : $(actual-targets) ; } } # Helper for 'actualize-sources'. For each passed source, actualizes it with # the appropriate scanner. Returns the actualized virtual targets. # rule actualize-source-type ( sources * : property-set ) { local result = ; for local i in $(sources) { local scanner ; if [ $(i).type ] { scanner = [ type.get-scanner [ $(i).type ] : $(property-set) ] ; } result += [ $(i).actualize $(scanner) ] ; } return $(result) ; } # Creates actual Jam targets for sources. Initializes the following member # variables: # 'self.actual-sources' -- sources passed to the updating action. # 'self.dependency-only-sources' -- sources marked as dependencies, but # are not used otherwise. # # New values will be *appended* to the variables. They may be non-empty if # caller wants it. # rule actualize-sources ( sources * : property-set ) { local dependencies = [ $(self.properties).get <dependency> ] ; self.dependency-only-sources += [ actualize-source-type $(dependencies) : $(property-set) ] ; self.actual-sources += [ actualize-source-type $(sources) : $(property-set) ] ; # This is used to help bjam find dependencies in generated headers and # other main targets, e.g. in: # # make a.h : ....... ; # exe hello : hello.cpp : <implicit-dependency>a.h ; # # For bjam to find the dependency the generated target must be # actualized (i.e. have its Jam target constructed). In the above case, # if we are building just hello ("bjam hello"), 'a.h' will not be # actualized unless we do it here. local implicit = [ $(self.properties).get <implicit-dependency> ] ; for local i in $(implicit) { $(i:G=).actualize ; } } # Determines real properties when trying to build with 'properties'. This is # the last chance to fix properties, for example to adjust includes to get # generated headers correctly. Default implementation simply returns its # argument. # rule adjust-properties ( property-set ) { return $(property-set) ; }}# Action class which does nothing --- it produces the targets with specific# properties out of nowhere. It is needed to distinguish virtual targets with# different properties that are known to exist and have no actions which create# them.#class null-action : action{ rule __init__ ( property-set ? ) { action.__init__ : .no-action : $(property-set) ; } rule actualize ( ) { if ! $(self.actualized) { self.actualized = true ; for local i in [ targets ] { $(i).actualize ; } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -