| |
| |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| import "class" : new ; |
| import errors ; |
| import modules ; |
| import path ; |
| import print ; |
| import property-set ; |
| import sequence ; |
|
|
|
|
| |
| |
| |
| |
| |
| rule load ( jamfile-location ) |
| { |
| if --debug-loading in [ modules.peek : ARGV ] |
| { |
| ECHO "Loading Jamfile at" '$(jamfile-location)' ; |
| } |
|
|
| local module-name = [ module-name $(jamfile-location) ] ; |
| |
| if ! $(module-name) in $(.jamfile-modules) |
| { |
| load-jamfile $(jamfile-location) : $(module-name) ; |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| load-used-projects $(module-name) ; |
| } |
| return $(module-name) ; |
| } |
|
|
|
|
| rule load-used-projects ( module-name ) |
| { |
| local used = [ modules.peek $(module-name) : .used-projects ] ; |
| local location = [ attribute $(module-name) location ] ; |
| import project ; |
| while $(used) |
| { |
| local id = $(used[1]) ; |
| local where = $(used[2]) ; |
|
|
| project.use $(id) : [ path.root [ path.make $(where) ] $(location) ] ; |
| used = $(used[3-]) ; |
| } |
| } |
|
|
|
|
| |
| |
| |
| JAMROOT ?= [ modules.peek : JAMROOT ] ; |
| JAMROOT ?= project-root.jam [Jj]amroot [Jj]amroot.jam ; |
|
|
|
|
| |
| |
| rule load-parent ( location ) |
| { |
| local found = [ path.glob-in-parents $(location) : $(JAMROOT) $(JAMFILE) ] ; |
|
|
| if ! $(found) |
| { |
| ECHO error: Could not find parent for project at '$(location)' ; |
| EXIT error: Did not find Jamfile.jam or Jamroot.jam in any parent |
| directory. ; |
| } |
|
|
| return [ load $(found[1]:D) ] ; |
| } |
|
|
|
|
| |
| |
| |
| |
| rule act-as-jamfile ( module : location ) |
| { |
| if [ module-name $(location) ] in $(.jamfile-modules) |
| { |
| errors.error "Jamfile was already loaded for '$(location)'" ; |
| } |
| |
| .module.$(location) = $(module) ; |
|
|
| |
| |
| .jamfile-modules += [ module-name $(location) ] ; |
|
|
| initialize $(module) : $(location) ; |
| } |
|
|
|
|
| |
| |
| |
| rule find ( name : current-location ) |
| { |
| local project-module ; |
|
|
| |
| if [ path.is-rooted $(name) ] |
| { |
| project-module = $($(name).jamfile-module) ; |
| } |
|
|
| if ! $(project-module) |
| { |
| local location = [ path.root [ path.make $(name) ] $(current-location) ] |
| ; |
|
|
| |
| |
| |
| |
|
|
| project-module = [ module-name $(location) ] ; |
| if ! $(project-module) in $(.jamfile-modules) |
| { |
| if [ path.glob $(location) : $(JAMROOT) $(JAMFILE) ] |
| { |
| project-module = [ load $(location) ] ; |
| } |
| else |
| { |
| project-module = ; |
| } |
| } |
| } |
|
|
| return $(project-module) ; |
| } |
|
|
|
|
| |
| |
| |
| |
| rule module-name ( jamfile-location ) |
| { |
| if ! $(.module.$(jamfile-location)) |
| { |
| |
| |
| jamfile-location = [ path.root $(jamfile-location) [ path.pwd ] ] ; |
| .module.$(jamfile-location) = Jamfile<$(jamfile-location)> ; |
| } |
| return $(.module.$(jamfile-location)) ; |
| } |
|
|
|
|
| |
| |
| JAMFILE = [ modules.peek : JAMFILE ] ; |
| JAMFILE ?= [Bb]uild.jam [Jj]amfile.v2 [Jj]amfile [Jj]amfile.jam ; |
|
|
|
|
| |
| |
| |
| |
| |
| rule find-jamfile ( |
| dir |
| parent-root ? |
| : no-errors ? |
| ) |
| { |
| |
| |
| local jamfile-glob = ; |
| if $(parent-root) |
| { |
| if ! $(.parent-jamfile.$(dir)) |
| { |
| .parent-jamfile.$(dir) = [ path.glob-in-parents $(dir) : $(JAMFILE) |
| ] ; |
| } |
| jamfile-glob = $(.parent-jamfile.$(dir)) ; |
| } |
| else |
| { |
| if ! $(.jamfile.$(dir)) |
| { |
| .jamfile.$(dir) = [ path.glob $(dir) : $(JAMFILE) ] ; |
| } |
| jamfile-glob = $(.jamfile.$(dir)) ; |
|
|
| } |
|
|
| local jamfile-to-load = $(jamfile-glob) ; |
| |
| |
| |
| |
| if $(jamfile-to-load[2-]) |
| { |
| local v2-jamfiles = [ MATCH (.*[Jj]amfile\\.v2)|(.*[Bb]uild\\.jam) : $(jamfile-to-load) ] ; |
|
|
| if $(v2-jamfiles) && ! $(v2-jamfiles[2]) |
| { |
| jamfile-to-load = $(v2-jamfiles) ; |
| } |
| else |
| { |
| local jamfile = [ path.basename $(jamfile-to-load[1]) ] ; |
| ECHO "warning: Found multiple Jamfiles at '"$(dir)"'!" |
| "Loading the first one: '$(jamfile)'." ; |
| } |
|
|
| jamfile-to-load = $(jamfile-to-load[1]) ; |
| } |
|
|
| |
| |
| if ! $(no-errors) && ! $(jamfile-to-load) |
| { |
| errors.error Unable to load Jamfile. |
| : Could not find a Jamfile in directory '$(dir)'. |
| : Attempted to find it with pattern '"$(JAMFILE:J= )"'. |
| : Please consult the documentation at 'http://www.boost.org'. ; |
| } |
|
|
| return $(jamfile-to-load) ; |
| } |
|
|
|
|
| |
| |
| |
| |
| local rule load-jamfile ( |
| dir |
| : jamfile-module |
| ) |
| { |
| |
| |
| local jamfile-to-load = [ path.glob $(dir) : $(JAMROOT) ] ; |
| if ! $(jamfile-to-load) |
| { |
| jamfile-to-load = [ find-jamfile $(dir) ] ; |
| } |
| |
| if $(jamfile-to-load[2]) |
| { |
| errors.error "Multiple Jamfiles found at '$(dir)'" |
| : "Filenames are: " $(jamfile-to-load:D=) ; |
| } |
| |
| |
| |
| |
| |
| |
| if ! $(jamfile-module) in $(.jamfile-modules) |
| { |
|
|
| |
| |
| initialize $(jamfile-module) : [ path.parent $(jamfile-to-load) ] |
| : $(jamfile-to-load:BS) ; |
|
|
| if ! $(jamfile-module) in $(.jamfile-modules) |
| { |
| .jamfile-modules += $(jamfile-module) ; |
|
|
| local saved-project = $(.current-project) ; |
|
|
| mark-as-user $(jamfile-module) ; |
| modules.load $(jamfile-module) : [ path.native $(jamfile-to-load) ] : . ; |
| if [ MATCH ($(JAMROOT)) : $(jamfile-to-load:BS) ] |
| { |
| jamfile = [ find-jamfile $(dir) : no-errors ] ; |
| if $(jamfile) |
| { |
| load-aux $(jamfile-module) : [ path.native $(jamfile) ] ; |
| } |
| } |
|
|
| |
| if $(.current-project) != $(saved-project) |
| { |
| errors.error "The value of the .current-project variable has magically" |
| : "changed after loading a Jamfile. This means some of the targets" |
| : "might be defined in the wrong project." |
| : "after loading" $(jamfile-module) |
| : "expected value" $(saved-project) |
| : "actual value" $(.current-project) ; |
| } |
|
|
| if $(.global-build-dir) |
| { |
| local id = [ attribute $(jamfile-module) id ] ; |
| local project-root = [ attribute $(jamfile-module) project-root ] ; |
| local location = [ attribute $(jamfile-module) location ] ; |
|
|
| if $(location) && $(project-root) = $(dir) |
| { |
| |
| if ! $(id) |
| { |
| ECHO "warning: the --build-dir option was specified" ; |
| ECHO "warning: but Jamroot at '$(dir)'" ; |
| ECHO "warning: specified no project id" ; |
| ECHO "warning: the --build-dir option will be ignored" ; |
| } |
| } |
| } |
| } |
| } |
| } |
|
|
|
|
| rule mark-as-user ( module-name ) |
| { |
| if USER_MODULE in [ RULENAMES ] |
| { |
| USER_MODULE $(module-name) ; |
| } |
| } |
|
|
|
|
| rule load-aux ( module-name : file ) |
| { |
| mark-as-user $(module-name) ; |
|
|
| module $(module-name) |
| { |
| include $(2) ; |
| local rules = [ RULENAMES $(1) ] ; |
| IMPORT $(1) : $(rules) : $(1) : $(1).$(rules) ; |
| } |
| } |
|
|
|
|
| .global-build-dir = [ MATCH --build-dir=(.*) : [ modules.peek : ARGV ] ] ; |
| if $(.global-build-dir) |
| { |
| |
| .global-build-dir = [ path.make $(.global-build-dir[-1]) ] ; |
| } |
|
|
|
|
| |
| |
| rule initialize ( |
| module-name |
| : location ? |
| |
| : basename ? |
| ) |
| { |
| if --debug-loading in [ modules.peek : ARGV ] |
| { |
| ECHO "Initializing project '$(module-name)'" ; |
| } |
|
|
| local jamroot ; |
|
|
| local parent-module ; |
| if $(module-name) = test-config |
| { |
| |
| } |
| else if $(module-name) = site-config |
| { |
| parent-module = test-config ; |
| } |
| else if $(module-name) = user-config |
| { |
| parent-module = site-config ; |
| } |
| else if $(module-name) = project-config |
| { |
| parent-module = user-config ; |
| } |
| else |
| { |
| |
| |
| if $(location) && ! [ MATCH ($(JAMROOT)) : $(basename) ] |
| { |
| parent-module = [ load-parent $(location) ] ; |
| } |
| else |
| { |
| |
| |
| if $(location) |
| { |
| |
| if $(project-config.attributes) |
| { |
| parent-module = project-config ; |
| } |
| else |
| { |
| parent-module = user-config ; |
| } |
| jamroot = true ; |
| } |
| } |
| } |
|
|
| |
| |
| |
| location ?= "" ; |
| |
| module $(module-name) |
| { |
| } |
|
|
| |
| |
| if ! $($(module-name).attributes) { |
|
|
| $(module-name).attributes = [ new project-attributes $(location) |
| $(module-name) ] ; |
| local attributes = $($(module-name).attributes) ; |
|
|
| if $(location) |
| { |
| $(attributes).set source-location : [ path.make $(location) ] : exact ; |
| } |
| else if ! $(module-name) in test-config site-config user-config project-config |
| { |
| |
| |
| |
| |
| local s = [ modules.binding $(module-name) ] ; |
| if ! $(s) |
| { |
| errors.error "Could not determine project location $(module-name)" ; |
| } |
| $(attributes).set source-location : $(s:D) : exact ; |
| } |
|
|
| $(attributes).set requirements : [ property-set.empty ] : exact ; |
| $(attributes).set usage-requirements : [ property-set.empty ] : exact ; |
|
|
| |
| |
| local rules = [ RULENAMES project-rules ] ; |
| IMPORT project-rules : $(rules) : $(module-name) : $(rules) ; |
|
|
| if $(parent-module) |
| { |
| inherit-attributes $(module-name) : $(parent-module) ; |
| $(attributes).set parent-module : $(parent-module) : exact ; |
| } |
|
|
| if $(jamroot) |
| { |
| $(attributes).set project-root : $(location) : exact ; |
| } |
|
|
| local parent ; |
| if $(parent-module) |
| { |
| parent = [ target $(parent-module) ] ; |
| } |
|
|
| if ! $(.target.$(module-name)) |
| { |
| .target.$(module-name) = [ new project-target $(module-name) |
| : $(module-name) $(parent) |
| : [ attribute $(module-name) requirements ] ] ; |
|
|
| if --debug-loading in [ modules.peek : ARGV ] |
| { |
| ECHO "Assigned project target" $(.target.$(module-name)) |
| "to '$(module-name)'" ; |
| } |
| } |
| } |
|
|
| .current-project = [ target $(module-name) ] ; |
| } |
|
|
|
|
| |
| |
| rule inherit-attributes ( project-module : parent-module ) |
| { |
| local attributes = $($(project-module).attributes) ; |
| local pattributes = [ attributes $(parent-module) ] ; |
| |
| if [ modules.binding $(parent-module) ] |
| { |
| $(attributes).set parent : [ path.parent |
| [ path.make [ modules.binding $(parent-module) ] ] ] ; |
| } |
| local v = [ $(pattributes).get project-root ] ; |
| $(attributes).set project-root : $(v) : exact ; |
| $(attributes).set default-build |
| : [ $(pattributes).get default-build ] ; |
| $(attributes).set requirements |
| : [ $(pattributes).get requirements ] : exact ; |
| $(attributes).set usage-requirements |
| : [ $(pattributes).get usage-requirements ] : exact ; |
|
|
| local parent-build-dir = [ $(pattributes).get build-dir ] ; |
| if $(parent-build-dir) |
| { |
| |
| |
| |
|
|
| local location = [ attribute $(project-module) location ] ; |
| local parent-location = [ attribute $(parent-module) location ] ; |
|
|
| local pwd = [ path.pwd ] ; |
| local parent-dir = [ path.root $(parent-location) $(pwd) ] ; |
| local our-dir = [ path.root $(location) $(pwd) ] ; |
| $(attributes).set build-dir : [ path.join $(parent-build-dir) |
| [ path.relative $(our-dir) $(parent-dir) ] ] : exact ; |
| } |
| } |
|
|
|
|
| |
| |
| rule register-id ( id : module ) |
| { |
| $(id).jamfile-module = $(module) ; |
| } |
|
|
|
|
| |
| |
| |
| |
| |
| class project-attributes |
| { |
| import property ; |
| import property-set ; |
| import errors ; |
| import path ; |
| import print ; |
| import sequence ; |
| import project ; |
|
|
| rule __init__ ( location project-module ) |
| { |
| self.location = $(location) ; |
| self.project-module = $(project-module) ; |
| } |
|
|
| |
| |
| |
| rule set ( attribute : specification * |
| : exact ? |
| ) |
| { |
| if $(exact) |
| { |
| self.$(attribute) = $(specification) ; |
| } |
| else if $(attribute) = "requirements" |
| { |
| local result = [ property-set.refine-from-user-input |
| $(self.requirements) : $(specification) |
| : $(self.project-module) : $(self.location) ] ; |
|
|
| if $(result[1]) = "@error" |
| { |
| errors.error Requirements for project at '$(self.location)' |
| conflict with parent's. : Explanation: $(result[2-]) ; |
| } |
| else |
| { |
| self.requirements = $(result) ; |
| } |
| } |
| else if $(attribute) = "usage-requirements" |
| { |
| local unconditional ; |
| for local p in $(specification) |
| { |
| local split = [ property.split-conditional $(p) ] ; |
| split ?= nothing $(p) ; |
| unconditional += $(split[2]) ; |
| } |
| |
| local non-free = [ property.remove free : $(unconditional) ] ; |
| if $(non-free) |
| { |
| errors.error usage-requirements $(specification) have non-free |
| properties $(non-free) ; |
| } |
| local t = [ property.translate-paths $(specification) |
| : $(self.location) ] ; |
| if $(self.usage-requirements) |
| { |
| self.usage-requirements = [ property-set.create |
| [ $(self.usage-requirements).raw ] $(t) ] ; |
| } |
| else |
| { |
| self.usage-requirements = [ property-set.create $(t) ] ; |
| } |
| } |
| else if $(attribute) = "default-build" |
| { |
| self.default-build = [ property.make $(specification) ] ; |
| } |
| else if $(attribute) = "source-location" |
| { |
| self.source-location = ; |
| for local src-path in $(specification) |
| { |
| self.source-location += [ path.root [ path.make $(src-path) ] |
| $(self.location) ] ; |
| } |
| } |
| else if $(attribute) = "build-dir" |
| { |
| self.build-dir = [ path.root |
| [ path.make $(specification) ] $(self.location) ] ; |
| } |
| else if $(attribute) = "id" |
| { |
| id = [ path.root $(specification) / ] ; |
| project.register-id $(id) : $(self.project-module) ; |
| self.id = $(id) ; |
| } |
| else if ! $(attribute) in "default-build" "location" "parent" |
| "projects-to-build" "project-root" "source-location" |
| { |
| errors.error Invalid project attribute '$(attribute)' specified for |
| project at '$(self.location)' ; |
| } |
| else |
| { |
| self.$(attribute) = $(specification) ; |
| } |
| } |
| |
| # Returns the value of the given attribute. |
| # |
| rule get ( attribute ) |
| { |
| return $(self.$(attribute)) ; |
| } |
| |
| # Prints the project attributes. |
| # |
| rule print ( ) |
| { |
| local id = $(self.id) ; id ?= (none) ; |
| local parent = $(self.parent) ; parent ?= (none) ; |
| print.section "'"$(id)"'" ; |
| print.list-start ; |
| print.list-item "Parent project:" $(parent) ; |
| print.list-item "Requirements:" [ $(self.requirements).raw ] ; |
| print.list-item "Default build:" $(self.default-build) ; |
| print.list-item "Source location:" $(self.source-location) ; |
| print.list-item "Projects to build:" |
| [ sequence.insertion-sort $(self.projects-to-build) ] ; |
| print.list-end ; |
| } |
| } |
| |
| |
| # Returns the project which is currently being loaded. |
| # |
| rule current ( ) |
| { |
| return $(.current-project) ; |
| } |
| |
| |
| # Temporarily changes the current project to 'project'. Should be followed by |
| # 'pop-current'. |
| # |
| rule push-current ( project ) |
| { |
| .saved-current-project += $(.current-project) ; |
| .current-project = $(project) ; |
| } |
| |
| |
| rule pop-current ( ) |
| { |
| .current-project = $(.saved-current-project[-1]) ; |
| .saved-current-project = $(.saved-current-project[1--2]) ; |
| } |
| |
| |
| # Returns the project-attribute instance for the specified Jamfile module. |
| # |
| rule attributes ( project ) |
| { |
| return $($(project).attributes) ; |
| } |
| |
| |
| # Returns the value of the specified attribute in the specified Jamfile module. |
| # |
| rule attribute ( project attribute ) |
| { |
| return [ $($(project).attributes).get $(attribute) ] ; |
| } |
| |
| |
| # Returns the project target corresponding to the 'project-module'. |
| # |
| rule target ( project-module ) |
| { |
| if ! $(.target.$(project-module)) |
| { |
| .target.$(project-module) = [ new project-target $(project-module) |
| : $(project-module) |
| : [ attribute $(project-module) requirements ] ] ; |
| } |
| return $(.target.$(project-module)) ; |
| } |
| |
| |
| # Use/load a project. |
| # |
| rule use ( id : location ) |
| { |
| local saved-project = $(.current-project) ; |
| local project-module = [ project.load $(location) ] ; |
| local declared-id = [ project.attribute $(project-module) id ] ; |
| |
| if ! $(declared-id) || $(declared-id) != $(id) |
| { |
| # The project at 'location' either has no id or that id is not equal to |
| # the 'id' parameter. |
| if $($(id).jamfile-module) && ( $($(id).jamfile-module) != |
| $(project-module) ) |
| { |
| errors.user-error Attempt to redeclare already existing project id |
| '$(id)' |
| location '$(location)' ; |
| } |
| $(id).jamfile-module = $(project-module) ; |
| } |
| .current-project = $(saved-project) ; |
| } |
| |
| |
| # Defines a Boost.Build extension project. Such extensions usually contain |
| # library targets and features that can be used by many people. Even though |
| # extensions are really projects, they can be initialized as a module would be |
| # with the "using" (project.project-rules.using) mechanism. |
| # |
| rule extension ( id : options * : * ) |
| { |
| # The caller is a standalone module for the extension. |
| local mod = [ CALLER_MODULE ] ; |
| |
| # We need to do the rest within the extension module. |
| module $(mod) |
| { |
| import path ; |
| |
| # Find the root project. |
| local root-project = [ project.current ] ; |
| root-project = [ $(root-project).project-module ] ; |
| while |
| [ project.attribute $(root-project) parent-module ] && |
| [ project.attribute $(root-project) parent-module ] != user-config |
| { |
| root-project = [ project.attribute $(root-project) parent-module ] ; |
| } |
| |
| # Create the project data, and bring in the project rules into the |
| # module. |
| project.initialize $(__name__) : [ path.join [ project.attribute |
| $(root-project) location ] ext $(1:L) ] ; |
| |
| # Create the project itself, i.e. the attributes. All extensions are |
| # created in the "/ext" project space. |
| project /ext/$(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : |
| $(9) ; |
| local attributes = [ project.attributes $(__name__) ] ; |
| |
| # Inherit from the root project of whomever is defining us. |
| project.inherit-attributes $(__name__) : $(root-project) ; |
| $(attributes).set parent-module : $(root-project) : exact ; |
| } |
| } |
| |
| |
| rule glob-internal ( project : wildcards + : excludes * : rule-name ) |
| { |
| local location = [ $(project).get source-location ] ; |
| |
| local result ; |
| local paths = [ path.$(rule-name) $(location) : |
| [ sequence.transform path.make : $(wildcards) ] : |
| [ sequence.transform path.make : $(excludes) ] ] ; |
| if $(wildcards:D) || $(rule-name) != glob |
| { |
| # The paths we have found are relative to the current directory, but the |
| # names specified in the sources list are assumed to be relative to the |
| # source directory of the corresponding project. So, just make the names |
| # absolute. |
| for local p in $(paths) |
| { |
| # If the path is below source location, use relative path. |
| # Otherwise, use full path just to avoid any ambiguities. |
| local rel = [ path.relative $(p) $(location) : no-error ] ; |
| if $(rel) = not-a-child |
| { |
| result += [ path.root $(p) [ path.pwd ] ] ; |
| } |
| else |
| { |
| result += $(rel) ; |
| } |
| } |
| } |
| else |
| { |
| # There were no wildcards in the directory path, so the files are all in |
| # the source directory of the project. Just drop the directory, instead |
| # of making paths absolute. |
| result = $(paths:D="") ; |
| } |
| |
| return $(result) ; |
| } |
| |
| |
| # This module defines rules common to all projects. |
| # |
| module project-rules |
| { |
| rule using ( toolset-module : * ) |
| { |
| import toolset ; |
| import modules ; |
| import project ; |
| |
| # Temporarily change the search path so the module referred to by |
| # 'using' can be placed in the same directory as Jamfile. User will |
| # expect the module to be found even though the directory is not in |
| # BOOST_BUILD_PATH. |
| local x = [ modules.peek : BOOST_BUILD_PATH ] ; |
| local caller = [ CALLER_MODULE ] ; |
| local caller-location = [ modules.binding $(caller) ] ; |
| modules.poke : BOOST_BUILD_PATH : $(caller-location:D) $(x) ; |
| toolset.using $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ; |
| modules.poke : BOOST_BUILD_PATH : $(x) ; |
| |
| # The above might have clobbered .current-project. Restore the correct |
| # value. |
| modules.poke project : .current-project |
| : [ project.target $(caller) ] ; |
| } |
| |
| import modules ; |
| |
| rule import ( * : * : * ) |
| { |
| modules.import project ; |
| |
| local caller = [ CALLER_MODULE ] ; |
| local saved = [ modules.peek project : .current-project ] ; |
| module $(caller) |
| { |
| modules.import $(1) : $(2) : $(3) ; |
| } |
| modules.poke project : .current-project : $(saved) ; |
| } |
| |
| rule project ( id ? : options * : * ) |
| { |
| import errors ; |
| import path ; |
| import project ; |
| |
| local caller = [ CALLER_MODULE ] ; |
| local attributes = [ project.attributes $(caller) ] ; |
| if $(id) |
| { |
| $(attributes).set id : $(id) ; |
| } |
| |
| local explicit-build-dir ; |
| |
| for n in 2 3 4 5 6 7 8 9 |
| { |
| local option = $($(n)) ; |
| if $(option) |
| { |
| $(attributes).set $(option[1]) : $(option[2-]) ; |
| } |
| if $(option[1]) = "build-dir" |
| { |
| explicit-build-dir = [ path.make $(option[2-]) ] ; |
| } |
| } |
| |
| # If '--build-dir' is specified, change the build dir for the project. |
| local global-build-dir = |
| [ modules.peek project : .global-build-dir ] ; |
| |
| if $(global-build-dir) |
| { |
| local location = [ $(attributes).get location ] ; |
| # Project with an empty location is a 'standalone' project such as |
| # user-config or qt. It has no build dir. If we try to set build dir |
| # for user-config, we shall then try to inherit it, with either |
| # weird or wrong consequences. |
| if $(location) && $(location) = [ $(attributes).get project-root ] |
| { |
| # Re-read the project id, since it might have been changed in |
| # the project's attributes. |
| id = [ $(attributes).get id ] ; |
| |
| if $(id) |
| { |
| if $(explicit-build-dir) && |
| [ path.is-rooted $(explicit-build-dir) ] |
| { |
| errors.user-error Absolute directory specified via |
| 'build-dir' project attribute : Do not know how to |
| combine that with the --build-dir option. ; |
| } |
| |
| local rid = [ MATCH /(.*) : $(id) ] ; |
| local p = [ path.join |
| $(global-build-dir) $(rid) $(explicit-build-dir) ] ; |
|
|
| $(attributes).set build-dir : $(p) : exact ; |
| } |
| } |
| else |
| { |
| |
| if $(explicit-build-dir) |
| { |
| errors.user-error When --build-dir is specified, the |
| 'build-dir' project : attribute is allowed only for |
| top-level 'project' invocations ; |
| } |
| } |
| } |
| } |
|
|
| |
| |
| |
| |
| rule constant ( |
| name |
| : value + |
| ) |
| { |
| import project ; |
| local caller = [ CALLER_MODULE ] ; |
| local p = [ project.target $(caller) ] ; |
| $(p).add-constant $(name) : $(value) ; |
| } |
|
|
| |
| |
| |
| |
| rule path-constant ( |
| name |
| : value + |
| ) |
| { |
| import project ; |
| local caller = [ CALLER_MODULE ] ; |
| local p = [ project.target $(caller) ] ; |
| $(p).add-constant $(name) : $(value) : path ; |
| } |
|
|
| rule use-project ( id : where ) |
| { |
| import modules ; |
| |
| local caller = [ CALLER_MODULE ] ; |
| modules.poke $(caller) : .used-projects : |
| [ modules.peek $(caller) : .used-projects ] |
| $(id) $(where) ; |
| } |
|
|
| rule build-project ( dir ) |
| { |
| import project ; |
| local caller = [ CALLER_MODULE ] ; |
| local attributes = [ project.attributes $(caller) ] ; |
|
|
| local now = [ $(attributes).get projects-to-build ] ; |
| $(attributes).set projects-to-build : $(now) $(dir) ; |
| } |
|
|
| rule explicit ( target-names * ) |
| { |
| import project ; |
| |
| |
| |
| local t = [ project.current ] ; |
| for local n in $(target-names) |
| { |
| $(t).mark-target-as-explicit $(n) ; |
| } |
| } |
|
|
| rule always ( target-names * ) |
| { |
| import project ; |
| local t = [ project.current ] ; |
| for local n in $(target-names) |
| { |
| $(t).mark-target-as-always $(n) ; |
| } |
| } |
| |
| rule glob ( wildcards + : excludes * ) |
| { |
| import project ; |
| return [ project.glob-internal [ project.current ] : $(wildcards) : |
| $(excludes) : glob ] ; |
| } |
|
|
| rule glob-tree ( wildcards + : excludes * ) |
| { |
| import project ; |
|
|
| if $(wildcards:D) || $(excludes:D) |
| { |
| errors.user-error The patterns to 'glob-tree' may not include |
| directory ; |
| } |
| return [ project.glob-internal [ project.current ] : $(wildcards) : |
| $(excludes) : glob-tree ] ; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| rule conditional ( condition + : requirements * ) |
| { |
| local condition = $(condition:J=,) ; |
| if [ MATCH (:) : $(condition) ] |
| { |
| return $(condition)$(requirements) ; |
| } |
| else |
| { |
| return $(condition):$(requirements) ; |
| } |
| } |
| |
| rule option ( name : value ) |
| { |
| local m = [ CALLER_MODULE ] ; |
| if $(m) != site-config && $(m) != user-config && $(m) != project-config |
| { |
| import errors ; |
| errors.error "The 'option' rule may be used only in site-config or user-config" ; |
| } |
| import option ; |
| option.set $(name) : $(value) ; |
| } |
| } |
|
|