def extra_usage_requirements(self, created_targets, prop_set): result = property_set.empty() extra = [] # Add appropriate <xdll-path> usage requirements. raw = prop_set.raw() if '<link>shared' in raw: paths = [] # TODO: is it safe to use the current directory? I think we should use # another mechanism to allow this to be run from anywhere. pwd = os.getcwd() for t in created_targets: if type.is_derived(t.type(), 'SHARED_LIB'): paths.append(path.root(path.make(t.path()), pwd)) extra += replace_grist(paths, '<xdll-path>') # We need to pass <xdll-path> features that we've got from sources, # because if shared library is built, exe which uses it must know paths # to other shared libraries this one depends on, to be able to find them # all at runtime. # Just pass all features in property_set, it's theorically possible # that we'll propagate <xdll-path> features explicitly specified by # the user, but then the user's to blaim for using internal feature. values = prop_set.get('<xdll-path>') extra += replace_grist(values, '<xdll-path>') if extra: result = property_set.create(extra) return result
def extra_usage_requirements (self, created_targets, prop_set): result = property_set.empty () extra = [] # Add appropriate <xdll-path> usage requirements. raw = prop_set.raw () if '<link>shared' in raw: paths = [] # TODO: is it safe to use the current directory? I think we should use # another mechanism to allow this to be run from anywhere. pwd = os.getcwd() for t in created_targets: if type.is_derived(t.type(), 'SHARED_LIB'): paths.append(path.root(path.make(t.path()), pwd)) extra += replace_grist(paths, '<xdll-path>') # We need to pass <xdll-path> features that we've got from sources, # because if shared library is built, exe which uses it must know paths # to other shared libraries this one depends on, to be able to find them # all at runtime. # Just pass all features in property_set, it's theorically possible # that we'll propagate <xdll-path> features explicitly specified by # the user, but then the user's to blaim for using internal feature. values = prop_set.get('<xdll-path>') extra += replace_grist(values, '<xdll-path>') if extra: result = property_set.create(extra) return result
def __adjust_name(self, specified_name): """Given the target name specified in constructor, returns the name which should be really used, by looking at the <tag> properties. The tag properties come in two flavour: - <tag>value, - <tag>@rule-name In the first case, value is just added to name In the second case, the specified rule is called with specified name, target type and properties and should return the new name. If not <tag> property is specified, or the rule specified by <tag> returns nothing, returns the result of calling virtual-target.add-suffix""" assert isinstance(specified_name, basestring) if self.action_: ps = self.action_.properties() else: ps = property_set.empty() # FIXME: I'm not sure how this is used, need to check with # Rene to figure out how to implement #~ We add ourselves to the properties so that any tag rule can get #~ more direct information about the target than just that available #~ through the properties. This is useful in implementing #~ name changes based on 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>%s" % "XXXX"]) #ps = [ property-set.create [ $(ps).raw ] <target>$(__name__) ] ; tag = ps.get("<tag>") if tag: if len(tag) > 1: get_manager().errors( )("""<tag>@rulename is present but is not the only <tag> feature""" ) tag = tag[0] if callable(tag): self.name_ = tag(specified_name, self.type_, ps) else: if not tag[0] == '@': self.manager_.errors( )("""The value of the <tag> feature must be '@rule-nane'""" ) exported_ps = b2.util.value_to_jam(ps, methods=True) self.name_ = b2.util.call_jam_function(tag[1:], specified_name, self.type_, exported_ps) if self.name_: self.name_ = self.name_[0] # If there's no tag or the tag rule returned nothing. if not tag or not self.name_: self.name_ = add_prefix_and_suffix(specified_name, self.type_, ps)
def construct(self, name, sources, ps): if not self.built: for arg in self.args: if type(arg) == type([]): arg = " ".join(arg) print arg self.built = True return (property_set.empty(), [])
def build_multiple(self, property_sets): usage_requirements = property_set.empty() result = [] for p in property_sets: r = AliasTarget.generate(self, p) if r: usage_requirements = usage_requirements.add(r.usage_requirements()) result.extend(r.targets()) return targets.GenerateResult(usage_requirements, unique(result))
def __adjust_name(self, specified_name): """Given the target name specified in constructor, returns the name which should be really used, by looking at the <tag> properties. The tag properties come in two flavour: - <tag>value, - <tag>@rule-name In the first case, value is just added to name In the second case, the specified rule is called with specified name, target type and properties and should return the new name. If not <tag> property is specified, or the rule specified by <tag> returns nothing, returns the result of calling virtual-target.add-suffix""" if self.action_: ps = self.action_.properties() else: ps = property_set.empty() # FIXME: I'm not sure how this is used, need to check with # Rene to figure out how to implement #~ We add ourselves to the properties so that any tag rule can get #~ more direct information about the target than just that available #~ through the properties. This is useful in implementing #~ name changes based on 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>%s" % "XXXX"]) #ps = [ property-set.create [ $(ps).raw ] <target>$(__name__) ] ; tag = ps.get("<tag>") if tag: if len(tag) > 1: get_manager().errors()( """<tag>@rulename is present but is not the only <tag> feature""") tag = tag[0] if callable(tag): self.name_ = tag(specified_name, self.type_, ps) else: if not tag[0] == '@': self.manager_.errors()("""The value of the <tag> feature must be '@rule-nane'""") exported_ps = b2.util.value_to_jam(ps, methods=True) self.name_ = b2.util.call_jam_function( tag[1:], specified_name, self.type_, exported_ps) if self.name_: self.name_ = self.name_[0] # If there's no tag or the tag rule returned nothing. if not tag or not self.name_: self.name_ = add_prefix_and_suffix(specified_name, self.type_, ps)
def set_update_action (self, action_name, targets, sources, properties=property_set.empty()): """ Binds a target to the corresponding update action. If target needs to be updated, the action registered with action_name will be used. The 'action_name' must be previously registered by either 'register_action' or 'register_bjam_action' method. """ assert(isinstance(properties, property_set.PropertySet)) if isinstance (targets, str): targets = [targets] self.do_set_update_action (action_name, targets, sources, properties)
def build_multiple(self, property_sets): usage_requirements = property_set.empty() result = [] for p in property_sets: r = AliasTarget.generate(self, p) if r: usage_requirements = usage_requirements.add( r.usage_requirements()) result.extend(r.targets()) return targets.GenerateResult(usage_requirements, unique(result))
def variant(name, parents_or_properties, explicit_properties=[]): """ Declares a new variant. First determines explicit properties for this variant, by refining parents' explicit properties with the passed explicit properties. The result is remembered and will be used if this variant is used as parent. Second, determines the full property set for this variant by adding to the explicit properties default values for all properties which neither present nor are symmetric. Lastly, makes appropriate value of 'variant' property expand to the full property set. name: Name of the variant parents_or_properties: Specifies parent variants, if 'explicit_properties' are given, and explicit_properties otherwise. explicit_properties: Explicit properties. """ parents = [] if not explicit_properties: explicit_properties = parents_or_properties else: parents = parents_or_properties inherited = property_set.empty() if parents: # If we allow multiple parents, we'd have to to check for conflicts # between base variants, and there was no demand for so to bother. if len(parents) > 1: raise BaseException("Multiple base variants are not yet supported") p = parents[0] # TODO: the check may be stricter if not feature.is_implicit_value(p): raise BaseException("Invalid base varaint '%s'" % p) inherited = __variant_explicit_properties[p] explicit_properties = property_set.create_with_validation( explicit_properties) explicit_properties = inherited.refine(explicit_properties) # Record explicitly specified properties for this variant # We do this after inheriting parents' properties, so that # they affect other variants, derived from this one. __variant_explicit_properties[name] = explicit_properties feature.extend('variant', [name]) feature.compose("<variant>" + name, explicit_properties.all())
def variant(name, parents_or_properties, explicit_properties=[]): """ Declares a new variant. First determines explicit properties for this variant, by refining parents' explicit properties with the passed explicit properties. The result is remembered and will be used if this variant is used as parent. Second, determines the full property set for this variant by adding to the explicit properties default values for all properties which neither present nor are symmetric. Lastly, makes appropriate value of 'variant' property expand to the full property set. name: Name of the variant parents_or_properties: Specifies parent variants, if 'explicit_properties' are given, and explicit_properties otherwise. explicit_properties: Explicit properties. """ parents = [] if not explicit_properties: explicit_properties = parents_or_properties else: parents = parents_or_properties inherited = property_set.empty() if parents: # If we allow multiple parents, we'd have to to check for conflicts # between base variants, and there was no demand for so to bother. if len(parents) > 1: raise BaseException("Multiple base variants are not yet supported") p = parents[0] # TODO: the check may be stricter if not feature.is_implicit_value(p): raise BaseException("Invalid base variant '%s'" % p) inherited = __variant_explicit_properties[p] explicit_properties = property_set.create_with_validation( explicit_properties) explicit_properties = inherited.refine(explicit_properties) # Record explicitly specified properties for this variant # We do this after inheriting parents' properties, so that # they affect other variants, derived from this one. __variant_explicit_properties[name] = explicit_properties feature.extend('variant', [name]) feature.compose("<variant>" + name, explicit_properties.all())
def construct(self, name, source_targets, ps): source_targets = self.targets_to_stage(source_targets, ps) ps = self.update_location(ps) ename = ps.get('name') if ename: ename = ename[0] if ename and len(source_targets) > 1: get_manager().errors( )("When <name> property is used in 'install', only one source is allowed" ) result = [] for i in source_targets: staged_targets = [] new_ps = self.adjust_properties(i, ps) # See if something special should be done when staging this type. It # is indicated by the presence of a special "INSTALLED_" type. t = i.type() if t and b2.build.type.registered("INSTALLED_" + t): if ename: get_manager().errors( )("In 'install': <name> property specified with target that requires relinking." ) else: (r, targets) = generators.construct(self.project(), name, "INSTALLED_" + t, new_ps, [i]) assert isinstance(r, property_set.PropertySet) staged_targets.extend(targets) else: staged_targets.append( copy_file(self.project(), ename, i, new_ps)) if not staged_targets: get_manager().errors()( "Unable to generate staged version of " + i) result.extend(get_manager().virtual_targets().register(t) for t in staged_targets) return (property_set.empty(), result)
def construct(self, name, source_targets, ps): i = 0 for t in source_targets: s = self.targets[i] a = virtual_target.Action(self.manager(), [t], "symlink.ln", ps) vt = virtual_target.FileTarget(os.path.basename(s), t.type(), self.project(), a) # Place the symlink in the directory relative to the project # location, instead of placing it in the build directory. if not ps.get('symlink-location') == "project-relative": vt.set_path(os.path.join(self.project().get('location'), os.path.dirname(s))) vt = get_manager().virtual_targets().register(vt) self.virtual_targets.append(vt) i = i + 1 return (property_set.empty(), self.virtual_targets)
def construct(self, name, source_targets, ps): assert isinstance(name, basestring) assert is_iterable_typed(source_targets, virtual_target.VirtualTarget) assert isinstance(ps, property_set.PropertySet) result = [] for s in source_targets: if not isinstance(s, virtual_target.FileTarget): get_manager().errors()("Source to the 'cast' metatager is not a file") if s.action(): get_manager().errors()("Only non-derived targets allowed as sources for 'cast'.") r = s.clone_with_different_type(self.type()) result.append(get_manager().virtual_targets().register(r)) return property_set.empty(), result
def construct(self, name, source_targets, ps): source_targets = self.targets_to_stage(source_targets, ps) ps = self.update_location(ps) ename = ps.get("name") if ename: ename = ename[0] if ename and len(source_targets) > 1: get_manager().errors()("When <name> property is used in 'install', only one source is allowed") result = [] for i in source_targets: staged_targets = [] new_ps = self.adjust_properties(i, ps) # See if something special should be done when staging this type. It # is indicated by the presence of a special "INSTALLED_" type. t = i.type() if t and b2.build.type.registered("INSTALLED_" + t): if ename: get_manager().errors()( "In 'install': <name> property specified with target that requires relinking." ) else: (r, targets) = generators.construct(self.project(), name, "INSTALLED_" + t, new_ps, [i]) assert isinstance(r, property_set.PropertySet) staged_targets.extend(targets) else: staged_targets.append(copy_file(self.project(), ename, i, new_ps)) if not staged_targets: get_manager().errors()("Unable to generate staged version of " + i) result.extend(get_manager().virtual_targets().register(t) for t in staged_targets) return (property_set.empty(), result)
def __init__ (self, manager, sources, action_name, prop_set): assert(isinstance(prop_set, property_set.PropertySet)) assert type(sources) == types.ListType self.sources_ = sources self.action_name_ = action_name if not prop_set: prop_set = property_set.empty() self.properties_ = prop_set if not all(isinstance(v, VirtualTarget) for v in prop_set.get('implicit-dependency')): import pdb pdb.set_trace() self.manager_ = manager self.engine_ = self.manager_.engine () self.targets_ = [] # Indicates whether this has been actualized or not. self.actualized_ = False self.dependency_only_sources_ = [] self.actual_sources_ = []
def __init__(self, manager, sources, action_name, prop_set): assert is_iterable_typed(sources, VirtualTarget) assert isinstance(action_name, basestring) or action_name is None assert isinstance(prop_set, property_set.PropertySet) self.sources_ = sources self.action_name_ = action_name if not prop_set: prop_set = property_set.empty() self.properties_ = prop_set if not all(isinstance(v, VirtualTarget) for v in prop_set.get("implicit-dependency")): import pdb pdb.set_trace() self.manager_ = manager self.engine_ = self.manager_.engine() self.targets_ = [] # Indicates whether this has been actualized or not. self.actualized_ = False self.dependency_only_sources_ = [] self.actual_sources_ = []
def initialize(self, module_name, location=None, basename=None): """Initialize the module for a project. module-name is the name of the project module. location is the location (directory) of the project to initialize. If not specified, stanalone project will be initialized """ if "--debug-loading" in self.manager.argv(): print "Initializing project '%s'" % module_name # TODO: need to consider if standalone projects can do anything but defining # prebuilt targets. If so, we need to give more sensible "location", so that # source paths are correct. if not location: location = "" else: location = b2.util.path.relpath(os.getcwd(), location) attributes = ProjectAttributes(self.manager, location, module_name) self.module2attributes[module_name] = attributes if location: attributes.set("source-location", [location], exact=1) else: attributes.set("source-location", "", exact=1) attributes.set("requirements", property_set.empty(), exact=True) attributes.set("usage-requirements", property_set.empty(), exact=True) attributes.set("default-build", [], exact=True) attributes.set("projects-to-build", [], exact=True) attributes.set("project-root", None, exact=True) attributes.set("build-dir", None, exact=True) self.project_rules_.init_project(module_name) jamroot = False parent_module = None if module_name == "site-config": # No parent pass elif module_name == "user-config": parent_module = "site-config" elif location and not self.is_jamroot(basename): # We search for parent/project-root only if jamfile was specified # --- i.e # if the project is not standalone. parent_module = self.load_parent(location) else: # It's either jamroot, or standalone project. # If it's jamroot, inherit from user-config. if location: parent_module = "user-config" jamroot = True if parent_module: self.inherit_attributes(module_name, parent_module) attributes.set("parent-module", parent_module, exact=1) if jamroot: attributes.set("project-root", location, exact=1) parent = None if parent_module: parent = self.target(parent_module) if not self.module2target.has_key(module_name): target = b2.build.targets.ProjectTarget( self.manager, module_name, module_name, parent, self.attribute(module_name, "requirements"), # FIXME: why we need to pass this? It's not # passed in jam code. self.attribute(module_name, "default-build")) self.module2target[module_name] = target self.current_project = self.target(module_name)
def initialize(self, module_name, location=None, basename=None): """Initialize the module for a project. module-name is the name of the project module. location is the location (directory) of the project to initialize. If not specified, stanalone project will be initialized """ if "--debug-loading" in self.manager.argv(): print "Initializing project '%s'" % module_name # TODO: need to consider if standalone projects can do anything but defining # prebuilt targets. If so, we need to give more sensible "location", so that # source paths are correct. if not location: location = "" else: location = b2.util.path.relpath(os.getcwd(), location) attributes = ProjectAttributes(self.manager, location, module_name) self.module2attributes[module_name] = attributes if location: attributes.set("source-location", [location], exact=1) else: attributes.set("source-location", "", exact=1) attributes.set("requirements", property_set.empty(), exact=True) attributes.set("usage-requirements", property_set.empty(), exact=True) attributes.set("default-build", [], exact=True) attributes.set("projects-to-build", [], exact=True) attributes.set("project-root", None, exact=True) attributes.set("build-dir", None, exact=True) self.project_rules_.init_project(module_name) jamroot = False parent_module = None if module_name == "site-config": # No parent pass elif module_name == "user-config": parent_module = "site-config" elif location and not self.is_jamroot(basename): # We search for parent/project-root only if jamfile was specified # --- i.e # if the project is not standalone. parent_module = self.load_parent(location) else: # It's either jamroot, or standalone project. # If it's jamroot, inherit from user-config. if location: parent_module = "user-config" jamroot = True if parent_module: self.inherit_attributes(module_name, parent_module) attributes.set("parent-module", parent_module, exact=1) if jamroot: attributes.set("project-root", location, exact=1) parent = None if parent_module: parent = self.target(parent_module) if not self.module2target.has_key(module_name): target = b2.build.targets.ProjectTarget( self.manager, module_name, module_name, parent, self.attribute(module_name, "requirements"), # FIXME: why we need to pass this? It's not # passed in jam code. self.attribute(module_name, "default-build"), ) self.module2target[module_name] = target self.current_project = self.target(module_name)
def run(self, project, name, prop_set, sources): return (property_set.empty(), [])
def run (self, project, name, prop_set, sources): return (property_set.empty(), [])
def initialize(self, module_name, location=None, basename=None): """Initialize the module for a project. module-name is the name of the project module. location is the location (directory) of the project to initialize. If not specified, standalone project will be initialized """ if "--debug-loading" in self.manager.argv(): print "Initializing project '%s'" % module_name # TODO: need to consider if standalone projects can do anything but defining # prebuilt targets. If so, we need to give more sensible "location", so that # source paths are correct. if not location: location = "" attributes = ProjectAttributes(self.manager, location, module_name) self.module2attributes[module_name] = attributes python_standalone = False if location: attributes.set("source-location", [location], exact=1) elif not module_name in [ "test-config", "site-config", "user-config", "project-config" ]: # This is a standalone project with known location. Set source location # so that it can declare targets. This is intended so that you can put # a .jam file in your sources and use it via 'using'. Standard modules # (in 'tools' subdir) may not assume source dir is set. attributes.set("source-location", self.loaded_tool_module_path_[module_name], exact=1) python_standalone = True attributes.set("requirements", property_set.empty(), exact=True) attributes.set("usage-requirements", property_set.empty(), exact=True) attributes.set("default-build", property_set.empty(), exact=True) attributes.set("projects-to-build", [], exact=True) attributes.set("project-root", None, exact=True) attributes.set("build-dir", None, exact=True) self.project_rules_.init_project(module_name, python_standalone) jamroot = False parent_module = None if module_name == "test-config": # No parent pass elif module_name == "site-config": parent_module = "test-config" elif module_name == "user-config": parent_module = "site-config" elif module_name == "project-config": parent_module = "user-config" elif location and not self.is_jamroot(basename): # We search for parent/project-root only if jamfile was specified # --- i.e # if the project is not standalone. parent_module = self.load_parent(location) else: # It's either jamroot, or standalone project. # If it's jamroot, inherit from user-config. if location: # If project-config module exist, inherit from it. if self.module2attributes.has_key("project-config"): parent_module = "project-config" else: parent_module = "user-config" jamroot = True if parent_module: self.inherit_attributes(module_name, parent_module) attributes.set("parent-module", parent_module, exact=1) if jamroot: attributes.set("project-root", location, exact=1) parent = None if parent_module: parent = self.target(parent_module) if not self.module2target.has_key(module_name): target = b2.build.targets.ProjectTarget( self.manager, module_name, module_name, parent, self.attribute(module_name, "requirements"), # FIXME: why we need to pass this? It's not # passed in jam code. self.attribute(module_name, "default-build")) self.module2target[module_name] = target self.current_project = self.target(module_name)
def main_real(): global ignore_config global debug_config boost_build_path = bjam.variable("BOOST_BUILD_PATH") engine = Engine() global_build_dir = get_string_option("build-dir") debug_config = get_boolean_option("debug-configuration") manager = Manager(engine, global_build_dir) # This module defines types and generator and what not, # and depends on manager's existence import b2.tools.builtin # Check if we can load 'test-config.jam'. If we can, load it and # ignore user configs. test_config = glob(boost_build_path, ["test-config.jam"]) if test_config: test_config = test_config[0] if test_config: if debug_config: print "notice: loading testing-config.jam from '%s'" % test_config print "notice: user-config.jam and site-config.jam will be ignored" manager.projects().load_standalone("test-config", test_config) ignore_config = test_config or get_boolean_option("ignore-config") user_path = home_directories() + boost_build_path site_path = ["/etc"] + user_path if bjam.variable("OS") in ["NT", "CYGWIN"]: site_path = [os.environ("SystemRoot")] + user_path load_config(manager, "site-config", site_path) user_config_path = get_string_option("user-config") if not user_config_path: user_config_path = os.environ.get("BOOST_BUILD_USER_CONFIG") if user_config_path: if debug_config: print "Loading explicitly specifier user configuration file:" print " %s" % user_config_path manager.projects().load_standalone("user-config", user_config_path) else: load_config(manager, "user-config", user_path) # FIXME: ## # ## # Autoconfigure toolsets based on any instances of --toolset=xx,yy,...zz or ## # toolset=xx,yy,...zz in the command line ## # ## local option-toolsets = [ regex.split-list [ MATCH ^--toolset=(.*) : $(argv) ] : "," ] ; ## local feature-toolsets = [ regex.split-list [ MATCH ^toolset=(.*) : $(argv) ] : "," ] ; ## # if the user specified --toolset=..., we need to add toolset=... to ## # the build request ## local extra-build-request ; extra_build_request = [] ## if ! $(ignore-config) ## { ## for local t in $(option-toolsets) $(feature-toolsets) ## { ## # Parse toolset-version/properties ## local (t-v,t,v) = [ MATCH (([^-/]+)-?([^/]+)?)/?.* : $(t) ] ; ## local toolset-version = $((t-v,t,v)[1]) ; ## local toolset = $((t-v,t,v)[2]) ; ## local version = $((t-v,t,v)[3]) ; ## if $(debug-config) ## { ## ECHO notice: [cmdline-cfg] Detected command-line request for ## $(toolset-version): toolset= \"$(toolset)\" "version= \""$(version)\" ; ## } ## local known ; ## # if the toolset isn't known, configure it now. ## if $(toolset) in [ feature.values <toolset> ] ## { ## known = true ; ## } ## if $(known) && $(version) ## && ! [ feature.is-subvalue toolset : $(toolset) : version : $(version) ] ## { ## known = ; ## } ## if ! $(known) ## { ## if $(debug-config) ## { ## ECHO notice: [cmdline-cfg] toolset $(toolset-version) ## not previously configured; configuring now ; ## } ## toolset.using $(toolset) : $(version) ; ## } ## else ## { ## if $(debug-config) ## { ## ECHO notice: [cmdline-cfg] toolset $(toolset-version) already configured ; ## } ## } ## # make sure we get an appropriate property into the build request in ## # case the user used the "--toolset=..." form ## if ! $(t) in $(argv) ## && ! $(t) in $(feature-toolsets) ## { ## if $(debug-config) ## { ## ECHO notice: [cmdline-cfg] adding toolset=$(t) "to build request." ; ## } ## extra-build-request += toolset=$(t) ; ## } ## } ## } # FIXME: ## if USER_MODULE in [ RULENAMES ] ## { ## USER_MODULE site-config user-config ; ## } if get_boolean_option("version"): # FIXME: Move to a separate module. Include bjam # verision. print "Boost.Build M15 (Python port in development)" sys.exit(0) b2.tools.common.init(manager) # We always load project in "." so that 'use-project' directives has # any chance of been seen. Otherwise, we won't be able to refer to # subprojects using target ids. current_project = None projects = manager.projects() if projects.find(".", "."): current_project = projects.target(projects.load(".")) # FIXME: revive this logic, when loading of gcc works if not feature.values("<toolset>") and not ignore_config and 0: default_toolset = "gcc" ; if bjam.variable("OS") == "NT": default_toolset = "msvc" print "warning: No toolsets are configured." ; print "warning: Configuring default toolset '%s'" % default_toolset print "warning: If the default is wrong, you may not be able to build C++ programs." print "warning: Use the \"--toolset=xxxxx\" option to override our guess." print "warning: For more configuration options, please consult" print "warning: http://boost.org/boost-build2/doc/html/bbv2/advanced/configuration.html" projects.project_rules().using([default_toolset]) (target_ids, properties) = b2.build.build_request.from_command_line( argv[1:] + extra_build_request) if properties: expanded = b2.build.build_request.expand_no_defaults(properties) xexpanded = [] for e in expanded: xexpanded.append(property_set.create(feature.split(e))) expanded = xexpanded else: expanded = [property_set.empty()] targets = [] clean = get_boolean_option("clean") clean_all = get_boolean_option("clean-all") bjam_targets = [] # Given a target id, try to find and return corresponding target. # This is only invoked when there's no Jamfile in "." # This code somewhat duplicates code in project-target.find but we can't reuse # that code without project-targets instance. def find_target (target_id): split = target_id.split("//") pm = None if len(split) > 1: pm = projects.find(split[0], ".") else: pm = projects.find(target_id, ".") result = None if pm: result = projects.target(pm) if len(split) > 1: result = result.find(split[1]) if not current_project and not target_ids: print "error: no Jamfile in current directory found, and no target references specified." sys.exit(1) for id in target_ids: if id == "clean": clean = 1 else: t = None if current_project: t = current_project.find(id, no_error=1) else: t = find_target(id) if not t: print "notice: could not find main target '%s'" % id print "notice: assuming it's a name of file to create " ; bjam_targets.append(id) else: targets.append(t) if not targets: targets = [projects.target(projects.module_name("."))] virtual_targets = [] # Virtual targets obtained when building main targets references on # the command line. When running # # bjam --clean main_target # # we want to clean the files that belong only to that main target, # so we need to record which targets are produced. results_of_main_targets = [] for p in expanded: manager.set_command_line_free_features(property_set.create(p.free())) for t in targets: try: g = t.generate(p) if not isinstance(t, ProjectTarget): results_of_main_targets.extend(g.targets()) virtual_targets.extend(g.targets()) except ExceptionWithUserContext, e: e.report() except Exception: raise
def initialize(self, module_name, location=None, basename=None): """Initialize the module for a project. module-name is the name of the project module. location is the location (directory) of the project to initialize. If not specified, stanalone project will be initialized """ if "--debug-loading" in self.manager.argv(): print "Initializing project '%s'" % module_name # TODO: need to consider if standalone projects can do anything but defining # prebuilt targets. If so, we need to give more sensible "location", so that # source paths are correct. if not location: location = "" attributes = ProjectAttributes(self.manager, location, module_name) self.module2attributes[module_name] = attributes python_standalone = False if location: attributes.set("source-location", [location], exact=1) elif not module_name in ["test-config", "site-config", "user-config", "project-config"]: # This is a standalone project with known location. Set source location # so that it can declare targets. This is intended so that you can put # a .jam file in your sources and use it via 'using'. Standard modules # (in 'tools' subdir) may not assume source dir is set. module = sys.modules[module_name] attributes.set("source-location", self.loaded_tool_module_path_[module_name], exact=1) python_standalone = True attributes.set("requirements", property_set.empty(), exact=True) attributes.set("usage-requirements", property_set.empty(), exact=True) attributes.set("default-build", property_set.empty(), exact=True) attributes.set("projects-to-build", [], exact=True) attributes.set("project-root", None, exact=True) attributes.set("build-dir", None, exact=True) self.project_rules_.init_project(module_name, python_standalone) jamroot = False parent_module = None; if module_name == "test-config": # No parent pass elif module_name == "site-config": parent_module = "test-config" elif module_name == "user-config": parent_module = "site-config" elif module_name == "project-config": parent_module = "user-config" elif location and not self.is_jamroot(basename): # We search for parent/project-root only if jamfile was specified # --- i.e # if the project is not standalone. parent_module = self.load_parent(location) else: # It's either jamroot, or standalone project. # If it's jamroot, inherit from user-config. if location: # If project-config module exist, inherit from it. if self.module2attributes.has_key("project-config"): parent_module = "project-config" else: parent_module = "user-config" ; jamroot = True ; if parent_module: self.inherit_attributes(module_name, parent_module) attributes.set("parent-module", parent_module, exact=1) if jamroot: attributes.set("project-root", location, exact=1) parent = None if parent_module: parent = self.target(parent_module) if not self.module2target.has_key(module_name): target = b2.build.targets.ProjectTarget(self.manager, module_name, module_name, parent, self.attribute(module_name,"requirements"), # FIXME: why we need to pass this? It's not # passed in jam code. self.attribute(module_name, "default-build")) self.module2target[module_name] = target self.current_project = self.target(module_name)
def main_real(): global debug_config, out_xml debug_config = "--debug-configuration" in sys.argv out_xml = any(re.match("^--out-xml=(.*)$", a) for a in sys.argv) engine = Engine() global_build_dir = option.get("build-dir") manager = Manager(engine, global_build_dir) import b2.build.configure as configure if "--version" in sys.argv: from b2.build import version version.report() return # This module defines types and generator and what not, # and depends on manager's existence import b2.tools.builtin b2.tools.common.init(manager) load_configuration_files() # Load explicitly specified toolset modules. extra_properties = process_explicit_toolset_requests() # Load the actual project build script modules. We always load the project # in the current folder so 'use-project' directives have any chance of # being seen. Otherwise, we would not be able to refer to subprojects using # target ids. current_project = None projects = get_manager().projects() if projects.find(".", "."): current_project = projects.target(projects.load(".")) # Load the default toolset module if no other has already been specified. if not feature.values("toolset"): dt = default_toolset dtv = None if default_toolset: dtv = default_toolset_version else: dt = "gcc" if os.name == 'nt': dt = "msvc" # FIXME: #else if [ os.name ] = MACOSX #{ # default-toolset = darwin ; #} print "warning: No toolsets are configured." print "warning: Configuring default toolset '%s'." % dt print "warning: If the default is wrong, your build may not work correctly." print "warning: Use the \"toolset=xxxxx\" option to override our guess." print "warning: For more configuration options, please consult" print "warning: http://boost.org/boost-build2/doc/html/bbv2/advanced/configuration.html" using(dt, dtv) # Parse command line for targets and properties. Note that this requires # that all project files already be loaded. (target_ids, properties) = build_request.from_command_line(sys.argv[1:] + extra_properties) # Expand properties specified on the command line into multiple property # sets consisting of all legal property combinations. Each expanded property # set will be used for a single build run. E.g. if multiple toolsets are # specified then requested targets will be built with each of them. if properties: expanded = build_request.expand_no_defaults(properties) else: expanded = [property_set.empty()] # Check that we actually found something to build. if not current_project and not target_ids: get_manager().errors()("no Jamfile in current directory found, and no target references specified.") # FIXME: # EXIT # 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. clean = "--clean" in sys.argv cleanall = "--clean-all" in sys.argv # 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. explicitly_requested_files = [] # List of Boost Build meta-targets, virtual-targets and actual Jam targets # constructed in this build system run. targets = [] virtual_targets = [] actual_targets = [] explicitly_requested_files = [] # 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 id in target_ids: if id == "clean": clean = 1 else: t = None if current_project: t = current_project.find(id, no_error=1) else: t = find_target(id) if not t: print "notice: could not find main target '%s'" % id print "notice: assuming it's a name of file to create " ; explicitly_requested_files.append(id) else: targets.append(t) if not targets: targets = [projects.target(projects.module_name("."))] # FIXME: put this BACK. ## if [ option.get dump-generators : : true ] ## { ## generators.dump ; ## } # We wish to put config.log in the build directory corresponding # to Jamroot, so that the location does not differ depending on # directory where we do build. The amount of indirection necessary # here is scary. first_project = targets[0].project() first_project_root_location = first_project.get('project-root') first_project_root_module = manager.projects().load(first_project_root_location) first_project_root = manager.projects().target(first_project_root_module) first_build_build_dir = first_project_root.build_dir() configure.set_log_file(os.path.join(first_build_build_dir, "config.log")) virtual_targets = [] global results_of_main_targets # 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 p in expanded: manager.set_command_line_free_features(property_set.create(p.free())) for t in targets: try: g = t.generate(p) if not isinstance(t, ProjectTarget): results_of_main_targets.extend(g.targets()) virtual_targets.extend(g.targets()) except ExceptionWithUserContext, e: e.report() except Exception: raise
def main_real(): global debug_config, out_xml debug_config = "--debug-configuration" in sys.argv out_xml = any(re.match("^--out-xml=(.*)$", a) for a in sys.argv) engine = Engine() global_build_dir = option.get("build-dir") manager = Manager(engine, global_build_dir) import b2.build.configure as configure if "--version" in sys.argv: version.report() return # This module defines types and generator and what not, # and depends on manager's existence import b2.tools.builtin b2.tools.common.init(manager) load_configuration_files() # Load explicitly specified toolset modules. extra_properties = process_explicit_toolset_requests() # Load the actual project build script modules. We always load the project # in the current folder so 'use-project' directives have any chance of # being seen. Otherwise, we would not be able to refer to subprojects using # target ids. current_project = None projects = get_manager().projects() if projects.find(".", "."): current_project = projects.target(projects.load(".")) # Load the default toolset module if no other has already been specified. if not feature.values("toolset"): dt = default_toolset dtv = None if default_toolset: dtv = default_toolset_version else: dt = "gcc" if os.name == 'nt': dt = "msvc" # FIXME: # else if [ os.name ] = MACOSX # { # default-toolset = darwin ; # } print "warning: No toolsets are configured." print "warning: Configuring default toolset '%s'." % dt print "warning: If the default is wrong, your build may not work correctly." print "warning: Use the \"toolset=xxxxx\" option to override our guess." print "warning: For more configuration options, please consult" print "warning: http://boost.org/boost-build2/doc/html/bbv2/advanced/configuration.html" using(dt, dtv) # Parse command line for targets and properties. Note that this requires # that all project files already be loaded. (target_ids, properties) = build_request.from_command_line(sys.argv[1:] + extra_properties) # Expand properties specified on the command line into multiple property # sets consisting of all legal property combinations. Each expanded property # set will be used for a single build run. E.g. if multiple toolsets are # specified then requested targets will be built with each of them. if properties: expanded = build_request.expand_no_defaults(properties) else: expanded = [property_set.empty()] # Check that we actually found something to build. if not current_project and not target_ids: get_manager().errors( )("no Jamfile in current directory found, and no target references specified." ) # FIXME: # EXIT # 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. clean = "--clean" in sys.argv cleanall = "--clean-all" in sys.argv # 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. explicitly_requested_files = [] # List of Boost Build meta-targets, virtual-targets and actual Jam targets # constructed in this build system run. targets = [] virtual_targets = [] actual_targets = [] explicitly_requested_files = [] # 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 id in target_ids: if id == "clean": clean = 1 else: t = None if current_project: t = current_project.find(id, no_error=1) else: t = find_target(id) if not t: print "notice: could not find main target '%s'" % id print "notice: assuming it's a name of file to create " explicitly_requested_files.append(id) else: targets.append(t) if not targets: targets = [projects.target(projects.module_name("."))] # FIXME: put this BACK. ## if [ option.get dump-generators : : true ] ## { ## generators.dump ; ## } # We wish to put config.log in the build directory corresponding # to Jamroot, so that the location does not differ depending on # directory where we do build. The amount of indirection necessary # here is scary. first_project = targets[0].project() first_project_root_location = first_project.get('project-root') first_project_root_module = manager.projects().load( first_project_root_location) first_project_root = manager.projects().target(first_project_root_module) first_build_build_dir = first_project_root.build_dir() configure.set_log_file(os.path.join(first_build_build_dir, "config.log")) virtual_targets = [] global results_of_main_targets # 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 p in expanded: manager.set_command_line_free_features(property_set.create(p.free())) for t in targets: try: g = t.generate(p) if not isinstance(t, ProjectTarget): results_of_main_targets.extend(g.targets()) virtual_targets.extend(g.targets()) except ExceptionWithUserContext, e: e.report() except Exception: raise
def main_real(): global ignore_config global debug_config boost_build_path = bjam.variable("BOOST_BUILD_PATH") engine = Engine() global_build_dir = get_string_option("build-dir") debug_config = get_boolean_option("debug-configuration") manager = Manager(engine, global_build_dir) # This module defines types and generator and what not, # and depends on manager's existence import b2.tools.builtin # Check if we can load 'test-config.jam'. If we can, load it and # ignore user configs. test_config = glob(boost_build_path, ["test-config.jam"]) if test_config: test_config = test_config[0] if test_config: if debug_config: print "notice: loading testing-config.jam from '%s'" % test_config print "notice: user-config.jam and site-config.jam will be ignored" manager.projects().load_standalone("test-config", test_config) ignore_config = test_config or get_boolean_option("ignore-config") user_path = home_directories() + boost_build_path site_path = ["/etc"] + user_path if bjam.variable("OS") in ["NT", "CYGWIN"]: site_path = [os.environ("SystemRoot")] + user_path load_config(manager, "site-config", site_path) user_config_path = get_string_option("user-config") if not user_config_path: user_config_path = os.environ.get("BOOST_BUILD_USER_CONFIG") if user_config_path: if debug_config: print "Loading explicitly specifier user configuration file:" print " %s" % user_config_path manager.projects().load_standalone("user-config", user_config_path) else: load_config(manager, "user-config", user_path) # FIXME: ## # ## # Autoconfigure toolsets based on any instances of --toolset=xx,yy,...zz or ## # toolset=xx,yy,...zz in the command line ## # ## local option-toolsets = [ regex.split-list [ MATCH ^--toolset=(.*) : $(argv) ] : "," ] ; ## local feature-toolsets = [ regex.split-list [ MATCH ^toolset=(.*) : $(argv) ] : "," ] ; ## # if the user specified --toolset=..., we need to add toolset=... to ## # the build request ## local extra-build-request ; extra_build_request = [] ## if ! $(ignore-config) ## { ## for local t in $(option-toolsets) $(feature-toolsets) ## { ## # Parse toolset-version/properties ## local (t-v,t,v) = [ MATCH (([^-/]+)-?([^/]+)?)/?.* : $(t) ] ; ## local toolset-version = $((t-v,t,v)[1]) ; ## local toolset = $((t-v,t,v)[2]) ; ## local version = $((t-v,t,v)[3]) ; ## if $(debug-config) ## { ## ECHO notice: [cmdline-cfg] Detected command-line request for ## $(toolset-version): toolset= \"$(toolset)\" "version= \""$(version)\" ; ## } ## local known ; ## # if the toolset isn't known, configure it now. ## if $(toolset) in [ feature.values <toolset> ] ## { ## known = true ; ## } ## if $(known) && $(version) ## && ! [ feature.is-subvalue toolset : $(toolset) : version : $(version) ] ## { ## known = ; ## } ## if ! $(known) ## { ## if $(debug-config) ## { ## ECHO notice: [cmdline-cfg] toolset $(toolset-version) ## not previously configured; configuring now ; ## } ## toolset.using $(toolset) : $(version) ; ## } ## else ## { ## if $(debug-config) ## { ## ECHO notice: [cmdline-cfg] toolset $(toolset-version) already configured ; ## } ## } ## # make sure we get an appropriate property into the build request in ## # case the user used the "--toolset=..." form ## if ! $(t) in $(argv) ## && ! $(t) in $(feature-toolsets) ## { ## if $(debug-config) ## { ## ECHO notice: [cmdline-cfg] adding toolset=$(t) "to build request." ; ## } ## extra-build-request += toolset=$(t) ; ## } ## } ## } # FIXME: ## if USER_MODULE in [ RULENAMES ] ## { ## USER_MODULE site-config user-config ; ## } if get_boolean_option("version"): # FIXME: Move to a separate module. Include bjam # verision. print "Boost.Build M15 (Python port in development)" sys.exit(0) b2.tools.common.init(manager) # We always load project in "." so that 'use-project' directives has # any chance of been seen. Otherwise, we won't be able to refer to # subprojects using target ids. current_project = None projects = manager.projects() if projects.find(".", "."): current_project = projects.target(projects.load(".")) # FIXME: revive this logic, when loading of gcc works if not feature.values("<toolset>") and not ignore_config and 0: default_toolset = "gcc" if bjam.variable("OS") == "NT": default_toolset = "msvc" print "warning: No toolsets are configured." print "warning: Configuring default toolset '%s'" % default_toolset print "warning: If the default is wrong, you may not be able to build C++ programs." print "warning: Use the \"--toolset=xxxxx\" option to override our guess." print "warning: For more configuration options, please consult" print "warning: http://boost.org/boost-build2/doc/html/bbv2/advanced/configuration.html" projects.project_rules().using([default_toolset]) (target_ids, properties ) = b2.build.build_request.from_command_line(argv[1:] + extra_build_request) if properties: expanded = b2.build.build_request.expand_no_defaults(properties) xexpanded = [] for e in expanded: xexpanded.append(property_set.create(feature.split(e))) expanded = xexpanded else: expanded = [property_set.empty()] targets = [] clean = get_boolean_option("clean") clean_all = get_boolean_option("clean-all") bjam_targets = [] # Given a target id, try to find and return corresponding target. # This is only invoked when there's no Jamfile in "." # This code somewhat duplicates code in project-target.find but we can't reuse # that code without project-targets instance. def find_target(target_id): split = target_id.split("//") pm = None if len(split) > 1: pm = projects.find(split[0], ".") else: pm = projects.find(target_id, ".") result = None if pm: result = projects.target(pm) if len(split) > 1: result = result.find(split[1]) if not current_project and not target_ids: print "error: no Jamfile in current directory found, and no target references specified." sys.exit(1) for id in target_ids: if id == "clean": clean = 1 else: t = None if current_project: t = current_project.find(id, no_error=1) else: t = find_target(id) if not t: print "notice: could not find main target '%s'" % id print "notice: assuming it's a name of file to create " bjam_targets.append(id) else: targets.append(t) if not targets: targets = [projects.target(projects.module_name("."))] virtual_targets = [] # Virtual targets obtained when building main targets references on # the command line. When running # # bjam --clean main_target # # we want to clean the files that belong only to that main target, # so we need to record which targets are produced. results_of_main_targets = [] for p in expanded: manager.set_command_line_free_features(property_set.create(p.free())) for t in targets: try: g = t.generate(p) if not isinstance(t, ProjectTarget): results_of_main_targets.extend(g.targets()) virtual_targets.extend(g.targets()) except ExceptionWithUserContext, e: e.report() except Exception: raise