Esempio n. 1
0
    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
Esempio n. 2
0
    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
Esempio n. 3
0
    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)
Esempio n. 4
0
    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(), [])
Esempio n. 5
0
    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(), [])
Esempio n. 6
0
    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))
Esempio n. 7
0
    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)
Esempio n. 8
0
 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)
Esempio n. 9
0
    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))
Esempio n. 10
0
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())
Esempio n. 11
0
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())
Esempio n. 12
0
    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)
Esempio n. 13
0
    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)
Esempio n. 14
0
    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
Esempio n. 15
0
    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
Esempio n. 16
0
    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)
Esempio n. 17
0
    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_ = []
Esempio n. 18
0
    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_ = []
Esempio n. 19
0
    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)
Esempio n. 20
0
    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)
Esempio n. 21
0
 def run(self, project, name, prop_set, sources):
     return (property_set.empty(), [])
Esempio n. 22
0
 def run (self, project, name, prop_set, sources):
   return (property_set.empty(), [])
Esempio n. 23
0
    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)
Esempio n. 24
0
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
Esempio n. 25
0
    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)
Esempio n. 26
0
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
Esempio n. 27
0
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
Esempio n. 28
0
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