📄 build-system.jam
字号:
# Flags indicating that this build system run has been started in order to # clean existing instead of create new targets. Note that these are not the # final flag values as they may get changed later on due to some special # targets being specified on the command line. local clean ; if "--clean" in $(.argv) { clean = true ; } local cleanall ; if "--clean-all" in $(.argv) { cleanall = true ; } # List of explicitly requested files to build. Any target references read # from the command line parameter not recognized as one of the targets # defined in the loaded Jamfiles will be interpreted as an explicitly # requested file to build. If any such files are explicitly requested then # only those files and the targets they depend on will be built and they # will be searched for among targets that would have been built had there # been no explicitly requested files. local explicitly-requested-files # List of Boost Build meta-targets, virtual-targets and actual Jam targets # constructed in this build system run. local targets ; local virtual-targets ; local actual-targets ; # Process each target specified on the command-line and convert it into # internal Boost Build target objects. Detect special clean target. If no # main Boost Build targets were explictly requested use the current project # as the target. for local id in $(target-ids) { if $(id) = clean { clean = true ; } else { local t ; if $(current-project) { t = [ $(current-project).find $(id) : no-error ] ; } else { t = [ find-target $(id) ] ; } if ! $(t) { ECHO "notice: could not find main target" $(id) ; ECHO "notice: assuming it is a name of file to create." ; explicitly-requested-files += $(id) ; } else { targets += $(t) ; } } } if ! $(targets) { targets += [ project.target [ project.module-name "." ] ] ; } # Now that we have a set of targets to build and a set of property sets to # build the targets with, we can start the main build process by using each # property set to generate virtual targets from all of our listed targets # and any of their dependants. for local p in $(expanded) { .command-line-free-features = [ property-set.create [ $(p).free ] ] ; for local t in $(targets) { local g = [ $(t).generate $(p) ] ; if ! [ class.is-a $(t) : project-target ] { .results-of-main-targets += $(g[2-]) ; } virtual-targets += $(g[2-]) ; } } # Convert collected virtual targets into actual raw Jam targets. for t in $(virtual-targets) { actual-targets += [ $(t).actualize ] ; } # If XML data output has been requested prepare additional rules and targets # so we can hook into Jam to collect build data while its building and have # it trigger the final XML report generation after all the planned targets # have been built. if $(.out-xml) { # Get a qualified virtual target name. rule full-target-name ( target ) { local name = [ $(target).name ] ; local project = [ $(target).project ] ; local project-path = [ $(project).get location ] ; return $(project-path)//$(name) ; } # Generate an XML file containing build statistics for each constituent. # rule out-xml ( xml-file : constituents * ) { # Prepare valid XML header and footer with some basic info. local nl = "" ; local jam = [ version.jam ] ; local os = [ modules.peek : OS OSPLAT JAMUNAME ] "" ; local timestamp = [ modules.peek : JAMDATE ] ; local cwd = [ PWD ] ; local command = $(.argv) ; local bb-version = [ version.boost-build ] ; .header on $(xml-file) = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" "$(nl)<build format=\"1.0\" version=\"$(bb-version)\">" "$(nl) <jam version=\"$(jam:J=.)\" />" "$(nl) <os name=\"$(os[1])\" platform=\"$(os[2])\"><![CDATA[$(os[3-]:J= )]]></os>" "$(nl) <timestamp><![CDATA[$(timestamp)]]></timestamp>" "$(nl) <directory><![CDATA[$(cwd)]]></directory>" "$(nl) <command><![CDATA[\"$(command:J=\" \")\"]]></command>" ; .footer on $(xml-file) = "$(nl)</build>" ; # Generate the target dependency graph. .contents on $(xml-file) += "$(nl) <targets>" ; for local t in [ virtual-target.all-targets ] { local action = [ $(t).action ] ; if $(action) # If a target has no action, it has no dependencies. { local name = [ full-target-name $(t) ] ; local sources = [ $(action).sources ] ; local dependencies ; for local s in $(sources) { dependencies += [ full-target-name $(s) ] ; } local path = [ $(t).path ] ; local jam-target = [ $(t).actual-name ] ; .contents on $(xml-file) += "$(nl) <target>" "$(nl) <name><![CDATA[$(name)]]></name>" "$(nl) <dependencies>" "$(nl) <dependency><![CDATA[$(dependencies)]]></dependency>" "$(nl) </dependencies>" "$(nl) <path><![CDATA[$(path)]]></path>" "$(nl) <jam-target><![CDATA[$(jam-target)]]></jam-target>" "$(nl) </target>" ; } } .contents on $(xml-file) += "$(nl) </targets>" ; # Build $(xml-file) after $(constituents). Do so even if a # constituent action fails and regenerate the xml on every bjam run. INCLUDES $(xml-file) : $(constituents) ; ALWAYS $(xml-file) ; __ACTION_RULE__ on $(xml-file) = build-system.out-xml.generate-action ; out-xml.generate $(xml-file) ; } # The actual build actions are here; if we did this work in the actions # clause we would have to form a valid command line containing the # result of @(...) below (the name of the XML file). # rule out-xml.generate-action ( args * : xml-file : command status start end user system : output ? ) { local contents = [ on $(xml-file) return $(.header) $(.contents) $(.footer) ] ; local f = @($(xml-file):E=$(contents)) ; } # Nothing to do here; the *real* actions happen in # out-xml.generate-action. actions quietly out-xml.generate { } # Define the out-xml file target, which depends on all the targets so # that it runs the collection after the targets have run. out-xml $(.out-xml) : $(actual-targets) ; # Set up a global __ACTION_RULE__ that records all the available # statistics about each actual target in a variable "on" the --out-xml # target. # rule out-xml.collect ( xml-file : target : command status start end user system : output ? ) { local nl = "" ; # Open the action with some basic info. .contents on $(xml-file) += "$(nl) <action status=\"$(status)\" start=\"$(start)\" end=\"$(end)\" user=\"$(user)\" system=\"$(system)\">" ; # If we have an action object we can print out more detailed info. local action = [ on $(target) return $(.action) ] ; if $(action) { local action-name = [ $(action).action-name ] ; local action-sources = [ $(action).sources ] ; local action-props = [ $(action).properties ] ; # The qualified name of the action which we created the target. .contents on $(xml-file) += "$(nl) <name><![CDATA[$(action-name)]]></name>" ; # The sources that made up the target. .contents on $(xml-file) += "$(nl) <sources>" ; for local source in $(action-sources) { local source-actual = [ $(source).actual-name ] ; .contents on $(xml-file) += "$(nl) <source><![CDATA[$(source-actual)]]></source>" ; } .contents on $(xml-file) += "$(nl) </sources>" ; # The properties that define the conditions under which the # target was built. .contents on $(xml-file) += "$(nl) <properties>" ; for local prop in [ $(action-props).raw ] { local prop-name = [ MATCH ^<(.*)>$ : $(prop:G) ] ; .contents on $(xml-file) += "$(nl) <property name=\"$(prop-name)\"><![CDATA[$(prop:G=)]]></property>" ; } .contents on $(xml-file) += "$(nl) </properties>" ; } local locate = [ on $(target) return $(LOCATE) ] ; locate ?= "" ; .contents on $(xml-file) += "$(nl) <jam-target><![CDATA[$(target)]]></jam-target>" "$(nl) <path><![CDATA[$(target:G=:R=$(locate))]]></path>" "$(nl) <command><![CDATA[$(command)]]></command>" "$(nl) <output><![CDATA[$(output)]]></output>" ; .contents on $(xml-file) += "$(nl) </action>" ; } # When no __ACTION_RULE__ is set "on" a target, the search falls back to # the global module. module { __ACTION_RULE__ = build-system.out-xml.collect [ modules.peek build-system : .out-xml ] ; } } # The 'all' pseudo target is not strictly needed expect in the case when we # use it below but people often assume they always have this target # available and do not declare it themselves before use which may cause # build failures with an error message about not being able to build the # 'all' target. NOTFILE all ; # And now that all the actual raw Jam targets and all the dependencies # between them have been prepared all that is left is to tell Jam to update # those targets. if $(explicitly-requested-files) { # Note that this case can not be joined with the regular one when only # exact Boost Build targets are requested as here we do not build those # requested targets but only use them to construct the dependency tree # needed to build the explicitly requested files. UPDATE $(explicitly-requested-files:G=e) $(.out-xml) ; } else if $(cleanall) { UPDATE clean-all ; } else if $(clean) { common.Clean clean : [ actual-clean-targets ] ; UPDATE clean ; } else { DEPENDS all : $(actual-targets) ; UPDATE all $(.out-xml) ; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -