Ejemplo n.º 1
0
    def __init__(self, name, project, sources, requirements, default_build,
                 usage_requirements):

        AliasTarget.__init__(self, name, project, sources, requirements, default_build,
                             usage_requirements)

        # On Linux, we build release variant by default, since few users will
        # ever want to debug C++ Boost libraries, and there's no ABI
        # incompatibility between debug and release variants. We build
        # shared and static libraries since that's what most packages
        # seem to provide (.so in libfoo and .a in libfoo-dev).
        self.minimal_properties = property_set.create([
            "<variant>release", "<threading>multi", "<link>shared", "<link>static",
            "<runtime-link>shared"])
        # On Windows, new IDE projects use:
        #
        #   runtime-link=dynamic, threading=multi, variant=(debug|release)
        #
        # and in addition, C++ Boost's autolink defaults to static linking.
        self.minimal_properties_win = property_set.create([
            "<variant>debug", "<variant>release", "<threading>multi", "<link>static",
            "<runtime-link>shared"])

        self.complete_properties = property_set.create([
            "<variant>debug", "<variant>release",
            "<threading>single", "<threading>multi"
            "<link>shared", "<link>static",
            "<runtime-link>shared", "<runtime-link>static"])
Ejemplo n.º 2
0
    def __init__(self, name, project, sources, requirements, default_build,
                 usage_requirements):

        AliasTarget.__init__(self, name, project, sources, requirements,
                             default_build, usage_requirements)

        # On Linux, we build release variant by default, since few users will
        # ever want to debug C++ Boost libraries, and there's no ABI
        # incompatibility between debug and release variants. We build
        # shared and static libraries since that's what most packages
        # seem to provide (.so in libfoo and .a in libfoo-dev).
        self.minimal_properties = property_set.create([
            "<variant>release", "<threading>multi", "<link>shared",
            "<link>static", "<runtime-link>shared"
        ])
        # On Windows, new IDE projects use:
        #
        #   runtime-link=dynamic, threading=multi, variant=(debug|release)
        #
        # and in addition, C++ Boost's autolink defaults to static linking.
        self.minimal_properties_win = property_set.create([
            "<variant>debug", "<variant>release", "<threading>multi",
            "<link>static", "<runtime-link>shared"
        ])

        self.complete_properties = property_set.create([
            "<variant>debug", "<variant>release", "<threading>single",
            "<threading>multi"
            "<link>shared", "<link>static", "<runtime-link>shared",
            "<runtime-link>static"
        ])
Ejemplo n.º 3
0
    def set(self, attribute, specification, exact):
        """Set the named attribute from the specification given by the user.
        The value actually set may be different."""

        if exact:
            self.__dict__[attribute] = specification

        elif attribute == "requirements":
            self.requirements = property_set.refine_from_user_input(
                self.requirements, specification, self.project_module,
                self.location)

        elif attribute == "usage-requirements":
            unconditional = []
            for p in specification:
                split = property.split_conditional(p)
                if split:
                    unconditional.append(split[1])
                else:
                    unconditional.append(p)

            non_free = property.remove("free", unconditional)
            if non_free:
                pass
                # FIXME:
                #errors.error "usage-requirements" $(specification) "have non-free properties" $(non-free) ;

            t = property.translate_paths(specification, self.location)

            existing = self.__dict__.get("usage-requirements")
            if existing:
                new = property_set.create(existing.raw() + t)
            else:
                new = property_set.create(t)
            self.__dict__["usage-requirements"] = new

        elif attribute == "default-build":
            self.__dict__["default-build"] = property_set.create(specification)

        elif attribute == "source-location":
            source_location = []
            for path in specification:
                source_location += os.path.join(self.location, path)
            self.__dict__["source-location"] = source_location

        elif attribute == "build-dir":
            self.__dict__["build-dir"] = os.path.join(self.location,
                                                      specification)

        elif not attribute in [
                "id", "default-build", "location", "source-location", "parent",
                "projects-to-build", "project-root"
        ]:
            self.manager.errors()("""Invalid project attribute '%s' specified
for project at '%s'""" % (attribute, self.location))
        else:
            self.__dict__[attribute] = specification
Ejemplo n.º 4
0
    def set(self, attribute, specification, exact):
        """Set the named attribute from the specification given by the user.
        The value actually set may be different."""

        if exact:
            self.__dict__[attribute] = specification
            
        elif attribute == "requirements":
            self.requirements = property_set.refine_from_user_input(
                self.requirements, specification,
                self.project_module, self.location)
            
        elif attribute == "usage-requirements":
            unconditional = []
            for p in specification:
                split = property.split_conditional(p)
                if split:
                    unconditional.append(split[1])
                else:
                    unconditional.append(p)

            non_free = property.remove("free", unconditional)
            if non_free:                
                pass
                # FIXME:
                #errors.error "usage-requirements" $(specification) "have non-free properties" $(non-free) ;

            t = property.translate_paths(specification, self.location)

            existing = self.__dict__.get("usage-requirements")
            if existing:
                new = property_set.create(existing.raw() +  t)
            else:
                new = property_set.create(t)
            self.__dict__["usage-requirements"] = new

                
        elif attribute == "default-build":
            self.__dict__["default-build"] = property_set.create(specification)
            
        elif attribute == "source-location":
            source_location = []
            for path in specification:
                source_location += os.path.join(self.location, path)
            self.__dict__["source-location"] = source_location
                
        elif attribute == "build-dir":
            self.__dict__["build-dir"] = os.path.join(self.location, specification)
                 
        elif not attribute in ["id", "default-build", "location",
                               "source-location", "parent",
                               "projects-to-build", "project-root"]:
            self.manager.errors()(
"""Invalid project attribute '%s' specified
for project at '%s'""" % (attribute, self.location))
        else:
            self.__dict__[attribute] = specification
Ejemplo n.º 5
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
Ejemplo n.º 6
0
    def run_pch(self, project, name, prop_set, sources):
        # Find the header in sources. Ignore any CPP sources.
        header = None
        for s in sources:
            if type.is_derived(s.type(), 'H'):
                header = s

        # Error handling: Base header file name should be the same as the base
        # precompiled header name.
        header_name = header.name()
        header_basename = os.path.basename(header_name).rsplit('.', 1)[0]
        if header_basename != name:
            location = project.project_module
            ###FIXME:
            raise Exception()
            ### errors.user-error "in" $(location)": pch target name `"$(name)"' should be the same as the base name of header file `"$(header-name)"'" ;

        pch_file = Generator.run(self, project, name, prop_set, [header])

        # return result of base class and pch-file property as usage-requirements
        # FIXME: what about multiple results from generator.run?
        return (property_set.create([
            Property('pch-file', pch_file[0]),
            Property('cflags', '-Winvalid-pch')
        ]), pch_file)
Ejemplo n.º 7
0
def convert_command_line_element(e):

    result = None
    parts = e.split("/")
    for p in parts:
        m = p.split("=")
        if len(m) > 1:
            feature = m[0]
            values = m[1].split(",")
            lresult = [("<%s>%s" % (feature, v)) for v in values]
        else:
            lresult = p.split(",")
            
        if p.find('-') == -1:
            # FIXME: first port property.validate
            # property.validate cannot handle subfeatures,
            # so we avoid the check here.
            #for p in lresult:
            #    property.validate(p)
            pass

        if not result:
            result = lresult
        else:
            result = [e1 + "/" + e2 for e1 in result for e2 in lresult]

    return [property_set.create(b2.build.feature.split(r)) for r in result]
Ejemplo n.º 8
0
def convert_command_line_element(e):
    assert isinstance(e, basestring)
    result = None
    parts = e.split("/")
    for p in parts:
        m = p.split("=")
        if len(m) > 1:
            feature = m[0]
            values = m[1].split(",")
            lresult = [("<%s>%s" % (feature, v)) for v in values]
        else:
            lresult = p.split(",")

        if p.find('-') == -1:
            # FIXME: first port property.validate
            # property.validate cannot handle subfeatures,
            # so we avoid the check here.
            #for p in lresult:
            #    property.validate(p)
            pass

        if not result:
            result = lresult
        else:
            result = [e1 + "/" + e2 for e1 in result for e2 in lresult]

    return [property_set.create(b2.build.feature.split(r)) for r in result]
Ejemplo n.º 9
0
    def run(self, project, name, prop_set, sources):

        if not name:
            return None

        # If name is empty, it means we're called not from top-level.
        # In this case, we just fail immediately, because SearchedLibGenerator
        # cannot be used to produce intermediate targets.
        
        properties = prop_set.raw ()
        shared = '<link>shared' in properties

        a = virtual_target.NullAction (project.manager(), prop_set)
        
        real_name = feature.get_values ('<name>', properties)
        if real_name:
            real_name = real_name[0]
        else:
            real_name = name
        search = feature.get_values('<search>', properties)
        usage_requirements = property_set.create(['<xdll-path>' + p for p in search])
        t = SearchedLibTarget(real_name, project, shared, search, a)

        # We return sources for a simple reason. If there's
        #    lib png : z : <name>png ; 
        # the 'z' target should be returned, so that apps linking to
        # 'png' will link to 'z', too.
        return(usage_requirements, [b2.manager.get_manager().virtual_targets().register(t)] + sources)
Ejemplo n.º 10
0
    def generated_targets (self, sources, prop_set, project, name):

        # sources to pass to inherited rule
        sources2 = []
        # properties to pass to inherited rule
        properties2  = []
        # sources which are libraries
        libraries  = []
        
        # Searched libraries are not passed as argument to linker
        # but via some option. So, we pass them to the action
        # via property. 
        properties2 = prop_set.raw()
        fsa = []
        fst = []
        for s in sources:
            if type.is_derived(s.type(), 'SEARCHED_LIB'):
                name = s.real_name()
                if s.shared():
                    fsa.append(name)

                else:
                    fst.append(name)

            else:
                sources2.append(s)

        if fsa:
            properties2 += [replace_grist('&&'.join(fsa), '<find-shared-library>')]
        if fst:
            properties2 += [replace_grist('&&'.join(fst), '<find-static-library>')]
                
        spawn = generators.Generator.generated_targets(self, sources2, property_set.create(properties2), project, name)
        
        return spawn
Ejemplo n.º 11
0
    def run(self, project, name, prop_set, sources):

        if not name:
            return None

        # If name is empty, it means we're called not from top-level.
        # In this case, we just fail immediately, because SearchedLibGenerator
        # cannot be used to produce intermediate targets.

        properties = prop_set.raw()
        shared = '<link>shared' in properties

        a = virtual_target.NullAction(project.manager(), prop_set)

        real_name = feature.get_values('<name>', properties)
        if real_name:
            real_name = real_name[0]
        else:
            real_nake = name
        search = feature.get_values('<search>', properties)
        usage_requirements = property_set.create(
            ['<xdll-path>' + p for p in search])
        t = SearchedLibTarget(name, project, shared, real_name, search, a)

        # We return sources for a simple reason. If there's
        #    lib png : z : <name>png ;
        # the 'z' target should be returned, so that apps linking to
        # 'png' will link to 'z', too.
        return (usage_requirements,
                [b2.manager.get_manager().virtual_targets().register(t)] +
                sources)
Ejemplo n.º 12
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
Ejemplo n.º 13
0
    def run(self, project, name, prop_set, sources):
        assert isinstance(project, targets.ProjectTarget)
        assert isinstance(name, basestring) or name is None
        assert isinstance(prop_set, property_set.PropertySet)
        assert is_iterable_typed(sources, virtual_target.VirtualTarget)

        # create a copy since sources is being modified
        sources = list(sources)
        sources.extend(prop_set.get('<library>'))

        # Add <library-path> properties for all searched libraries
        extra = []
        for s in sources:
            if s.type() == 'SEARCHED_LIB':
                search = s.search()
                extra.extend(
                    property.Property('<library-path>', sp) for sp in search)

        # It's possible that we have libraries in sources which did not came
        # from 'lib' target. For example, libraries which are specified
        # just as filenames as sources. We don't have xdll-path properties
        # for such target, but still need to add proper dll-path properties.
        extra_xdll_path = []
        for s in sources:
            if type.is_derived(s.type(), 'SHARED_LIB') and not s.action():
                # Unfortunately, we don't have a good way to find the path
                # to a file, so use this nasty approach.
                p = s.project()
                location = path.root(s.name(), p.get('source-location')[0])
                extra_xdll_path.append(os.path.dirname(location))

        # Hardcode DLL paths only when linking executables.
        # Pros: do not need to relink libraries when installing.
        # Cons: "standalone" libraries (plugins, python extensions) can not
        # hardcode paths to dependent libraries.
        if prop_set.get('<hardcode-dll-paths>') == ['true'] \
              and type.is_derived(self.target_types_ [0], 'EXE'):
            xdll_path = prop_set.get('<xdll-path>')
            extra.extend(property.Property('<dll-path>', sp) \
                 for sp in extra_xdll_path)
            extra.extend(property.Property('<dll-path>', sp) \
                 for sp in xdll_path)

        if extra:
            prop_set = prop_set.add_raw(extra)
        result = generators.Generator.run(self, project, name, prop_set,
                                          sources)

        if result:
            ur = self.extra_usage_requirements(result, prop_set)
            ur = ur.add(
                property_set.create(
                    ['<xdll-path>' + p for p in extra_xdll_path]))
        else:
            return None
        return (ur, result)
Ejemplo n.º 14
0
def expand_no_defaults (property_sets):
    """ Expand the given build request by combining all property_sets which don't
        specify conflicting non-free features.
    """
    # First make all features and subfeatures explicit
    expanded_property_sets = [ps.expand_subfeatures() for ps in property_sets]
    
    # Now combine all of the expanded property_sets
    product = __x_product (expanded_property_sets)
    
    return [property_set.create(p) for p in product]
Ejemplo n.º 15
0
def boost_std(inc=None, lib=None):
    # The default definitions for pre-built libraries.
    rules.project(['boost'], ['usage-requirements'] +
                  ['<include>{}'.format(i)
                   for i in inc] + ['<define>BOOST_ALL_NO_LIB'],
                  ['requirements'] + ['<search>{}'.format(l) for l in lib])

    # TODO: There should be a better way to add a Python function into a
    # project requirements property set.
    tag_prop_set = property_set.create([property.Property('<tag>', tag_std)])
    attributes = projects.attributes(projects.current().project_module())
    attributes.requirements = attributes.requirements.refine(tag_prop_set)

    alias('headers')

    def boost_lib(lib_name, dyn_link_macro):
        if (isinstance(lib_name, str)):
            lib_name = [lib_name]
        builtin.lib(lib_name,
                    usage_requirements=[
                        '<link>shared:<define>{}'.format(dyn_link_macro)
                    ])

    boost_lib('container', 'BOOST_CONTAINER_DYN_LINK')
    boost_lib('date_time', 'BOOST_DATE_TIME_DYN_LINK')
    boost_lib('filesystem', 'BOOST_FILE_SYSTEM_DYN_LINK')
    boost_lib('graph', 'BOOST_GRAPH_DYN_LINK')
    boost_lib('graph_parallel', 'BOOST_GRAPH_DYN_LINK')
    boost_lib('iostreams', 'BOOST_IOSTREAMS_DYN_LINK')
    boost_lib('locale', 'BOOST_LOG_DYN_LINK')
    boost_lib('log', 'BOOST_LOG_DYN_LINK')
    boost_lib('log_setup', 'BOOST_LOG_DYN_LINK')
    boost_lib('math_tr1', 'BOOST_MATH_TR1_DYN_LINK')
    boost_lib('math_tr1f', 'BOOST_MATH_TR1_DYN_LINK')
    boost_lib('math_tr1l', 'BOOST_MATH_TR1_DYN_LINK')
    boost_lib('math_c99', 'BOOST_MATH_TR1_DYN_LINK')
    boost_lib('math_c99f', 'BOOST_MATH_TR1_DYN_LINK')
    boost_lib('math_c99l', 'BOOST_MATH_TR1_DYN_LINK')
    boost_lib('mpi', 'BOOST_MPI_DYN_LINK')
    boost_lib('program_options', 'BOOST_PROGRAM_OPTIONS_DYN_LINK')
    boost_lib('python', 'BOOST_PYTHON_DYN_LINK')
    boost_lib('python3', 'BOOST_PYTHON_DYN_LINK')
    boost_lib('random', 'BOOST_RANDOM_DYN_LINK')
    boost_lib('regex', 'BOOST_REGEX_DYN_LINK')
    boost_lib('serialization', 'BOOST_SERIALIZATION_DYN_LINK')
    boost_lib('wserialization', 'BOOST_SERIALIZATION_DYN_LINK')
    boost_lib('signals', 'BOOST_SIGNALS_DYN_LINK')
    boost_lib('system', 'BOOST_SYSTEM_DYN_LINK')
    boost_lib('unit_test_framework', 'BOOST_TEST_DYN_LINK')
    boost_lib('prg_exec_monitor', 'BOOST_TEST_DYN_LINK')
    boost_lib('test_exec_monitor', 'BOOST_TEST_DYN_LINK')
    boost_lib('thread', 'BOOST_THREAD_DYN_DLL')
    boost_lib('wave', 'BOOST_WAVE_DYN_LINK')
Ejemplo n.º 16
0
    def run (self, project, name, prop_set, sources):
        assert isinstance(project, targets.ProjectTarget)
        assert isinstance(name, basestring) or name is None
        assert isinstance(prop_set, property_set.PropertySet)
        assert is_iterable_typed(sources, virtual_target.VirtualTarget)

        # create a copy since sources is being modified
        sources = list(sources)
        sources.extend(prop_set.get('<library>'))

        # Add <library-path> properties for all searched libraries
        extra = []
        for s in sources:
            if s.type () == 'SEARCHED_LIB':
                search = s.search()
                extra.extend(property.Property('<library-path>', sp) for sp in search)

        # It's possible that we have libraries in sources which did not came
        # from 'lib' target. For example, libraries which are specified
        # just as filenames as sources. We don't have xdll-path properties
        # for such target, but still need to add proper dll-path properties.
        extra_xdll_path = []
        for s in sources:
                if type.is_derived (s.type (), 'SHARED_LIB') and not s.action ():
                    # Unfortunately, we don't have a good way to find the path
                    # to a file, so use this nasty approach.
                    p = s.project()
                    location = path.root(s.name(), p.get('source-location')[0])
                    extra_xdll_path.append(os.path.dirname(location))

        # Hardcode DLL paths only when linking executables.
        # Pros: do not need to relink libraries when installing.
        # Cons: "standalone" libraries (plugins, python extensions) can not
        # hardcode paths to dependent libraries.
        if prop_set.get('<hardcode-dll-paths>') == ['true'] \
              and type.is_derived(self.target_types_ [0], 'EXE'):
                xdll_path = prop_set.get('<xdll-path>')
                extra.extend(property.Property('<dll-path>', sp) \
                     for sp in extra_xdll_path)
                extra.extend(property.Property('<dll-path>', sp) \
                     for sp in xdll_path)

        if extra:
            prop_set = prop_set.add_raw (extra)
        result = generators.Generator.run(self, project, name, prop_set, sources)

        if result:
            ur = self.extra_usage_requirements(result, prop_set)
            ur = ur.add(property_set.create(['<xdll-path>' + p for p in extra_xdll_path]))
        else:
            return None
        return (ur, result)
Ejemplo n.º 17
0
    def adjust_properties(self, target, build_ps):
        a = target.action()
        properties = []
        if a:
            ps = a.properties()
            properties = ps.all()

            # Unless <hardcode-dll-paths>true is in properties, which can happen
            # only if the user has explicitly requested it, nuke all <dll-path>
            # properties.

            if build_ps.get('hardcode-dll-paths') != ['true']:
                properties = [
                    p for p in properties if p.feature().name() != 'dll-path'
                ]

            # If any <dll-path> properties were specified for installing, add
            # them.
            properties.extend(build_ps.get_properties('dll-path'))

            # Also copy <linkflags> feature from current build set, to be used
            # for relinking.
            properties.extend(build_ps.get_properties('linkflags'))

            # Remove the <tag> feature on original targets.
            # And <location>. If stage target has another stage target in
            # sources, then we shall get virtual targets with the <location>
            # property set.
            properties = [
                p for p in properties
                if not p.feature().name() in ['tag', 'location']
            ]

        properties.extend(build_ps.get_properties('dependency'))

        properties.extend(build_ps.get_properties('location'))

        properties.extend(
            build_ps.get_properties('install-no-version-symlinks'))

        d = build_ps.get_properties('install-source-root')

        # Make the path absolute: we shall use it to compute relative paths and
        # making the path absolute will help.
        if d:
            p = d[0]
            properties.append(
                property.Property(p.feature(), os.path.abspath(p.value())))

        return property_set.create(properties)
Ejemplo n.º 18
0
def boost_std(inc = None, lib = None):
    # The default definitions for pre-built libraries.
    rules.project(
        ['boost'],
        ['usage-requirements'] + ['<include>{}'.format(i) for i in inc] + ['<define>BOOST_ALL_NO_LIB'],
        ['requirements'] + ['<search>{}'.format(l) for l in lib])

    # TODO: There should be a better way to add a Python function into a
    # project requirements property set.
    tag_prop_set = property_set.create([property.Property('<tag>', tag_std)])
    attributes = projects.attributes(projects.current().project_module())
    attributes.requirements = attributes.requirements.refine(tag_prop_set)

    alias('headers')

    def boost_lib(lib_name, dyn_link_macro):
        if (isinstance(lib_name,str)):
            lib_name = [lib_name]
        builtin.lib(lib_name, usage_requirements=['<link>shared:<define>{}'.format(dyn_link_macro)])

    boost_lib('container'           , 'BOOST_CONTAINER_DYN_LINK'      )
    boost_lib('date_time'           , 'BOOST_DATE_TIME_DYN_LINK'      )
    boost_lib('filesystem'          , 'BOOST_FILE_SYSTEM_DYN_LINK'    )
    boost_lib('graph'               , 'BOOST_GRAPH_DYN_LINK'          )
    boost_lib('graph_parallel'      , 'BOOST_GRAPH_DYN_LINK'          )
    boost_lib('iostreams'           , 'BOOST_IOSTREAMS_DYN_LINK'      )
    boost_lib('locale'              , 'BOOST_LOG_DYN_LINK'            )
    boost_lib('log'                 , 'BOOST_LOG_DYN_LINK'            )
    boost_lib('log_setup'           , 'BOOST_LOG_DYN_LINK'            )
    boost_lib('math_tr1'            , 'BOOST_MATH_TR1_DYN_LINK'       )
    boost_lib('math_tr1f'           , 'BOOST_MATH_TR1_DYN_LINK'       )
    boost_lib('math_tr1l'           , 'BOOST_MATH_TR1_DYN_LINK'       )
    boost_lib('math_c99'            , 'BOOST_MATH_TR1_DYN_LINK'       )
    boost_lib('math_c99f'           , 'BOOST_MATH_TR1_DYN_LINK'       )
    boost_lib('math_c99l'           , 'BOOST_MATH_TR1_DYN_LINK'       )
    boost_lib('mpi'                 , 'BOOST_MPI_DYN_LINK'            )
    boost_lib('program_options'     , 'BOOST_PROGRAM_OPTIONS_DYN_LINK')
    boost_lib('python'              , 'BOOST_PYTHON_DYN_LINK'         )
    boost_lib('python3'             , 'BOOST_PYTHON_DYN_LINK'         )
    boost_lib('random'              , 'BOOST_RANDOM_DYN_LINK'         )
    boost_lib('regex'               , 'BOOST_REGEX_DYN_LINK'          )
    boost_lib('serialization'       , 'BOOST_SERIALIZATION_DYN_LINK'  )
    boost_lib('wserialization'      , 'BOOST_SERIALIZATION_DYN_LINK'  )
    boost_lib('signals'             , 'BOOST_SIGNALS_DYN_LINK'        )
    boost_lib('system'              , 'BOOST_SYSTEM_DYN_LINK'         )
    boost_lib('unit_test_framework' , 'BOOST_TEST_DYN_LINK'           )
    boost_lib('prg_exec_monitor'    , 'BOOST_TEST_DYN_LINK'           )
    boost_lib('test_exec_monitor'   , 'BOOST_TEST_DYN_LINK'           )
    boost_lib('thread'              , 'BOOST_THREAD_DYN_DLL'          )
    boost_lib('wave'                , 'BOOST_WAVE_DYN_LINK'           )
Ejemplo n.º 19
0
def boost_std(inc=None, lib=None):
    # The default definitions for pre-built libraries.
    rules.project(
        ["boost"],
        ["usage-requirements"] + ["<include>{}".format(i) for i in inc] + ["<define>BOOST_ALL_NO_LIB"],
        ["requirements"] + ["<search>{}".format(l) for l in lib],
    )

    # TODO: There should be a better way to add a Python function into a
    # project requirements property set.
    tag_prop_set = property_set.create([property.Property("<tag>", tag_std)])
    attributes = projects.attributes(projects.current().project_module())
    attributes.requirements = attributes.requirements.refine(tag_prop_set)

    alias("headers")

    def boost_lib(lib_name, dyn_link_macro):
        if isinstance(lib_name, str):
            lib_name = [lib_name]
        builtin.lib(lib_name, usage_requirements=["<link>shared:<define>{}".format(dyn_link_macro)])

    boost_lib("date_time", "BOOST_DATE_TIME_DYN_LINK")
    boost_lib("filesystem", "BOOST_FILE_SYSTEM_DYN_LINK")
    boost_lib("graph", "BOOST_GRAPH_DYN_LINK")
    boost_lib("graph_parallel", "BOOST_GRAPH_DYN_LINK")
    boost_lib("iostreams", "BOOST_IOSTREAMS_DYN_LINK")
    boost_lib("locale", "BOOST_LOG_DYN_LINK")
    boost_lib("log", "BOOST_LOG_DYN_LINK")
    boost_lib("log_setup", "BOOST_LOG_DYN_LINK")
    boost_lib("math_tr1", "BOOST_MATH_TR1_DYN_LINK")
    boost_lib("math_tr1f", "BOOST_MATH_TR1_DYN_LINK")
    boost_lib("math_tr1l", "BOOST_MATH_TR1_DYN_LINK")
    boost_lib("math_c99", "BOOST_MATH_TR1_DYN_LINK")
    boost_lib("math_c99f", "BOOST_MATH_TR1_DYN_LINK")
    boost_lib("math_c99l", "BOOST_MATH_TR1_DYN_LINK")
    boost_lib("mpi", "BOOST_MPI_DYN_LINK")
    boost_lib("program_options", "BOOST_PROGRAM_OPTIONS_DYN_LINK")
    boost_lib("python", "BOOST_PYTHON_DYN_LINK")
    boost_lib("python3", "BOOST_PYTHON_DYN_LINK")
    boost_lib("random", "BOOST_RANDOM_DYN_LINK")
    boost_lib("regex", "BOOST_REGEX_DYN_LINK")
    boost_lib("serialization", "BOOST_SERIALIZATION_DYN_LINK")
    boost_lib("wserialization", "BOOST_SERIALIZATION_DYN_LINK")
    boost_lib("signals", "BOOST_SIGNALS_DYN_LINK")
    boost_lib("system", "BOOST_SYSTEM_DYN_LINK")
    boost_lib("unit_test_framework", "BOOST_TEST_DYN_LINK")
    boost_lib("prg_exec_monitor", "BOOST_TEST_DYN_LINK")
    boost_lib("test_exec_monitor", "BOOST_TEST_DYN_LINK")
    boost_lib("thread", "BOOST_THREAD_DYN_DLL")
    boost_lib("wave", "BOOST_WAVE_DYN_LINK")
Ejemplo n.º 20
0
    def run(self, project, name, prop_set, sources):

        lib_sources = prop_set.get('<library>')
        sources.extend(lib_sources)

        # Add <library-path> properties for all searched libraries
        extra = []
        for s in sources:
            if s.type() == 'SEARCHED_LIB':
                search = s.search()
                extra.extend(
                    property.Property('<library-path>', sp) for sp in search)

        orig_xdll_path = []

        if prop_set.get('<hardcode-dll-paths>') == ['true'] \
               and type.is_derived(self.target_types_ [0], 'EXE'):
            xdll_path = prop_set.get('<xdll-path>')
            orig_xdll_path = [
                replace_grist(x, '<dll-path>') for x in xdll_path
            ]
            # It's possible that we have libraries in sources which did not came
            # from 'lib' target. For example, libraries which are specified
            # just as filenames as sources. We don't have xdll-path properties
            # for such target, but still need to add proper dll-path properties.
            for s in sources:
                if type.is_derived(s.type(), 'SHARED_LIB') and not s.action():
                    # Unfortunately, we don't have a good way to find the path
                    # to a file, so use this nasty approach.
                    p = s.project()
                    location = path.root(s.name(), p.get('source-location'))
                    xdll_path.append(path.parent(location))

            extra.extend(
                property.Property('<dll-path>', sp) for sp in xdll_path)

        if extra:
            prop_set = prop_set.add_raw(extra)

        result = generators.Generator.run(self, project, name, prop_set,
                                          sources)

        if result:
            ur = self.extra_usage_requirements(result, prop_set)
            ur = ur.add(property_set.create(orig_xdll_path))
        else:
            return None

        return (ur, result)
Ejemplo n.º 21
0
    def adjust_properties(self, target, build_ps):
        a = target.action()
        properties = []
        if a:
            ps = a.properties()
            properties = ps.all()

            # Unless <hardcode-dll-paths>true is in properties, which can happen
            # only if the user has explicitly requested it, nuke all <dll-path>
            # properties.

            if build_ps.get('hardcode-dll-paths') != ['true']:
                properties = [p for p in properties if p.feature.name != 'dll-path']

            # If any <dll-path> properties were specified for installing, add
            # them.
            properties.extend(build_ps.get_properties('dll-path'))

            # Also copy <linkflags> feature from current build set, to be used
            # for relinking.
            properties.extend(build_ps.get_properties('linkflags'))

            # Remove the <tag> feature on original targets.
            # And <location>. If stage target has another stage target in
            # sources, then we shall get virtual targets with the <location>
            # property set.
            properties = [p for p in properties
                          if not p.feature.name in ['tag', 'location']]

        properties.extend(build_ps.get_properties('dependency'))

        properties.extend(build_ps.get_properties('location'))


        properties.extend(build_ps.get_properties('install-no-version-symlinks'))

        d = build_ps.get_properties('install-source-root')

        # Make the path absolute: we shall use it to compute relative paths and
        # making the path absolute will help.
        if d:
            p = d[0]
            properties.append(property.Property(p.feature, os.path.abspath(p.value)))

        return property_set.create(properties)
Ejemplo n.º 22
0
    def run (self, project, name, prop_set, sources):
       
        lib_sources = prop_set.get('<library>')
        sources.extend(lib_sources)
        
        # Add <library-path> properties for all searched libraries
        extra = []
        for s in sources:
            if s.type () == 'SEARCHED_LIB':
                search = s.search()
                extra.extend(property.Property('<library-path>', sp) for sp in search)

        orig_xdll_path = []
                   
        if prop_set.get('<hardcode-dll-paths>') == ['true'] \
               and type.is_derived(self.target_types_ [0], 'EXE'):
            xdll_path = prop_set.get('<xdll-path>')
            orig_xdll_path = [ replace_grist(x, '<dll-path>') for x in xdll_path ]
            # It's possible that we have libraries in sources which did not came
            # from 'lib' target. For example, libraries which are specified
            # just as filenames as sources. We don't have xdll-path properties
            # for such target, but still need to add proper dll-path properties.
            for s in sources:
                if type.is_derived (s.type (), 'SHARED_LIB') and not s.action ():
                    # Unfortunately, we don't have a good way to find the path
                    # to a file, so use this nasty approach.
                    p = s.project()
                    location = path.root(s.name(), p.get('source-location'))
                    xdll_path.append(path.parent(location))
                          
            extra.extend(property.Property('<dll-path>', sp) for sp in xdll_path)
        
        if extra:
            prop_set = prop_set.add_raw (extra)
                        
        result = generators.Generator.run(self, project, name, prop_set, sources)

        if result:
            ur = self.extra_usage_requirements(result, prop_set)
            ur = ur.add(property_set.create(orig_xdll_path))
        else:
            return None
        
        return(ur, result)
Ejemplo n.º 23
0
 def check(self, ps):
     assert isinstance(ps, property_set.PropertySet)
     # FIXME: this should not be hardcoded. Other checks might
     # want to consider different set of features as relevant.
     toolset = ps.get('toolset')[0]
     toolset_version_property = "<toolset-" + toolset + ":version>"
     relevant = ps.get_properties('target-os') + \
                ps.get_properties("toolset") + \
                ps.get_properties(toolset_version_property) + \
                ps.get_properties("address-model") + \
                ps.get_properties("architecture")
     rps = property_set.create(relevant)
     t = get_manager().targets().current()
     p = t.project()
     if builds(self.target, p, rps, "%s builds" % self.target):
         choosen = self.true_properties
     else:
         choosen = self.false_properties
     return property.evaluate_conditionals_in_context(choosen, ps)
Ejemplo n.º 24
0
 def check(self, ps):
     assert isinstance(ps, property_set.PropertySet)
     # FIXME: this should not be hardcoded. Other checks might
     # want to consider different set of features as relevant.
     toolset = ps.get('toolset')[0]
     toolset_version_property = "<toolset-" + toolset + ":version>" ;
     relevant = ps.get_properties('target-os') + \
                ps.get_properties("toolset") + \
                ps.get_properties(toolset_version_property) + \
                ps.get_properties("address-model") + \
                ps.get_properties("architecture")
     rps = property_set.create(relevant)
     t = get_manager().targets().current()
     p = t.project()
     if builds(self.target, p, rps, "%s builds" % self.target):
         choosen = self.true_properties
     else:
         choosen = self.false_properties
     return property.evaluate_conditionals_in_context(choosen, ps)
Ejemplo n.º 25
0
    def run(self, project, name, prop_set, sources):

        sources.extend(prop_set.get("<library>"))

        # Add <library-path> properties for all searched libraries
        extra = []
        for s in sources:
            if s.type() == "SEARCHED_LIB":
                search = s.search()
                extra.extend(property.Property("<library-path>", sp) for sp in search)

        # It's possible that we have libraries in sources which did not came
        # from 'lib' target. For example, libraries which are specified
        # just as filenames as sources. We don't have xdll-path properties
        # for such target, but still need to add proper dll-path properties.
        extra_xdll_path = []
        for s in sources:
            if type.is_derived(s.type(), "SHARED_LIB") and not s.action():
                # Unfortunately, we don't have a good way to find the path
                # to a file, so use this nasty approach.
                p = s.project()
                location = path.root(s.name(), p.get("source-location")[0])
                extra_xdll_path.append(os.path.dirname(location))

        # Hardcode DLL paths only when linking executables.
        # Pros: do not need to relink libraries when installing.
        # Cons: "standalone" libraries (plugins, python extensions) can not
        # hardcode paths to dependent libraries.
        if prop_set.get("<hardcode-dll-paths>") == ["true"] and type.is_derived(self.target_types_[0], "EXE"):
            xdll_path = prop_set.get("<xdll-path>")
            extra.extend(property.Property("<dll-path>", sp) for sp in extra_xdll_path)
            extra.extend(property.Property("<dll-path>", sp) for sp in xdll_path)

        if extra:
            prop_set = prop_set.add_raw(extra)
        result = generators.Generator.run(self, project, name, prop_set, sources)

        if result:
            ur = self.extra_usage_requirements(result, prop_set)
            ur = ur.add(property_set.create(["<xdll-path>" + p for p in extra_xdll_path]))
        else:
            return None
        return (ur, result)
Ejemplo n.º 26
0
    def generated_targets(self, sources, prop_set, project, name):

        # sources to pass to inherited rule
        sources2 = []
        # properties to pass to inherited rule
        properties2 = []
        # sources which are libraries
        libraries = []

        # Searched libraries are not passed as argument to linker
        # but via some option. So, we pass them to the action
        # via property.
        properties2 = prop_set.raw()
        fsa = []
        fst = []
        for s in sources:
            if type.is_derived(s.type(), 'SEARCHED_LIB'):
                name = s.real_name()
                if s.shared():
                    fsa.append(name)

                else:
                    fst.append(name)

            else:
                sources2.append(s)

        if fsa:
            properties2 += [
                replace_grist('&&'.join(fsa), '<find-shared-library>')
            ]
        if fst:
            properties2 += [
                replace_grist('&&'.join(fst), '<find-static-library>')
            ]

        spawn = generators.Generator.generated_targets(
            self, sources2, property_set.create(properties2), project, name)

        return spawn
Ejemplo n.º 27
0
    def run (self, project, name, prop_set, sources):
        assert isinstance(project, targets.ProjectTarget)
        assert isinstance(name, basestring) or name is None
        assert isinstance(prop_set, property_set.PropertySet)
        assert is_iterable_typed(sources, virtual_target.VirtualTarget)

        # create a copy since this modifies the sources list
        sources = list(sources)
        sources.extend(prop_set.get('<library>'))

        result = generators.Generator.run (self, project, name, prop_set, sources)

        usage_requirements = []
        link = prop_set.get('<link>')
        if 'static' in link:
            for t in sources:
                if type.is_derived(t.type(), 'LIB'):
                    usage_requirements.append(property.Property('<library>', t))

        usage_requirements = property_set.create(usage_requirements)

        return usage_requirements, result
Ejemplo n.º 28
0
    def run(self, project, name, prop_set, sources):
        assert isinstance(project, targets.ProjectTarget)
        assert isinstance(name, basestring) or name is None
        assert isinstance(prop_set, property_set.PropertySet)
        assert is_iterable_typed(sources, virtual_target.VirtualTarget)

        # create a copy since this modifies the sources list
        sources = list(sources)
        sources.extend(prop_set.get("<library>"))

        result = generators.Generator.run(self, project, name, prop_set, sources)

        usage_requirements = []
        link = prop_set.get("<link>")
        if "static" in link:
            for t in sources:
                if type.is_derived(t.type(), "LIB"):
                    usage_requirements.append(property.Property("<library>", t))

        usage_requirements = property_set.create(usage_requirements)

        return usage_requirements, result
Ejemplo n.º 29
0
    def run_pch(self, project, name, prop_set, sources):
        # Find the header in sources. Ignore any CPP sources.
        header = None
        for s in sources:
            if type.is_derived(s.type(), 'H'):
                header = s

        # Error handling: Base header file name should be the same as the base
        # precompiled header name.
        header_name = header.name()
        header_basename = os.path.basename(header_name).rsplit('.', 1)[0]
        if header_basename != name:
            location = project.project_module
            ###FIXME:
            raise Exception()
            ### errors.user-error "in" $(location)": pch target name `"$(name)"' should be the same as the base name of header file `"$(header-name)"'" ;

        pch_file = Generator.run(self, project, name, prop_set, [header])

        # return result of base class and pch-file property as usage-requirements
        # FIXME: what about multiple results from generator.run?
        return (property_set.create([Property('pch-file', pch_file[0]),
                                     Property('cflags', '-Winvalid-pch')]),
                pch_file)
Ejemplo n.º 30
0
import bjam

from b2.build import alias, property, property_set, feature
from b2.manager import get_manager
from b2.tools import builtin, common
from b2.util import bjam_signature, regex


# TODO: This is currently necessary in Python Port, but was not in Jam.
feature.feature("layout", ["system", "versioned", "tag"], ["optional"])
feature.feature("root", [], ["optional", "free"])
feature.feature("build-id", [], ["optional", "free"])

__initialized = None
__boost_auto_config = property_set.create([property.Property("layout", "system")])
__boost_configured = {}
__boost_default = None
__build_id = None

__debug = None


def debug():
    global __debug
    if __debug is None:
        __debug = "--debug-configuration" in bjam.variable("ARGV")
    return __debug


# Configuration of the boost library to use.
Ejemplo n.º 31
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
import bjam

from b2.build import alias, property, property_set, feature
from b2.manager import get_manager
from b2.tools import builtin, common
from b2.util import bjam_signature, regex


# TODO: This is currently necessary in Python Port, but was not in Jam.
feature.feature('layout', ['system', 'versioned', 'tag'], ['optional'])
feature.feature('root', [], ['optional', 'free'])
feature.feature('build-id', [], ['optional', 'free'])

__initialized = None
__boost_auto_config = property_set.create([property.Property('layout', 'system')])
__boost_configured = {}
__boost_default = None
__build_id = None

__debug = None

def debug():
    global __debug
    if __debug is None:
        __debug = "--debug-configuration" in bjam.variable("ARGV")        
    return __debug


# Configuration of the boost library to use.
#
Ejemplo n.º 33
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
Ejemplo n.º 34
0
import bjam

from b2.build import alias, property, property_set, feature
from b2.manager import get_manager
from b2.tools import builtin, common
from b2.util import bjam_signature, regex


# TODO: This is currently necessary in Python Port, but was not in Jam.
feature.feature('layout', ['system', 'versioned', 'tag'], ['optional'])
feature.feature('root', [], ['optional', 'free'])
feature.feature('build-id', [], ['optional', 'free'])

__initialized = None
__boost_auto_config = property_set.create([property.Property('layout', 'system')])
__boost_configured = {}
__boost_default = None
__build_id = None

__debug = None

def debug():
    global __debug
    if __debug is None:
        __debug = "--debug-configuration" in bjam.variable("ARGV")        
    return __debug


# Configuration of the boost library to use.
#
Ejemplo n.º 35
0
    def set(self, attribute, specification, exact=False):
        """Set the named attribute from the specification given by the user.
        The value actually set may be different."""

        if exact:
            self.__dict__[attribute] = specification

        elif attribute == "requirements":
            self.requirements = property_set.refine_from_user_input(
                self.requirements, specification, self.project_module,
                self.location)

        elif attribute == "usage-requirements":
            unconditional = []
            for p in specification:
                split = property.split_conditional(p)
                if split:
                    unconditional.append(split[1])
                else:
                    unconditional.append(p)

            non_free = property.remove("free", unconditional)
            if non_free:
                get_manager().errors()("usage-requirements %s have non-free properties %s" \
                                       % (specification, non_free))

            t = property.translate_paths(
                property.create_from_strings(specification,
                                             allow_condition=True),
                self.location)

            existing = self.__dict__.get("usage-requirements")
            if existing:
                new = property_set.create(existing.all() + t)
            else:
                new = property_set.create(t)
            self.__dict__["usage-requirements"] = new

        elif attribute == "default-build":
            self.__dict__["default-build"] = property_set.create(specification)

        elif attribute == "source-location":
            source_location = []
            for path in specification:
                source_location.append(os.path.join(self.location, path))
            self.__dict__["source-location"] = source_location

        elif attribute == "build-dir":
            self.__dict__["build-dir"] = os.path.join(self.location,
                                                      specification[0])

        elif attribute == "id":
            id = specification[0]
            if id[0] != '/':
                id = "/" + id
            self.manager.projects().register_id(id, self.project_module)
            self.__dict__["id"] = id

        elif not attribute in [
                "default-build", "location", "source-location", "parent",
                "projects-to-build", "project-root"
        ]:
            self.manager.errors()("""Invalid project attribute '%s' specified
for project at '%s'""" % (attribute, self.location))
        else:
            self.__dict__[attribute] = specification
Ejemplo n.º 36
0
    def set(self, attribute, specification, exact=False):
        """Set the named attribute from the specification given by the user.
        The value actually set may be different."""

        if exact:
            self.__dict__[attribute] = specification
            
        elif attribute == "requirements":
            self.requirements = property_set.refine_from_user_input(
                self.requirements, specification,
                self.project_module, self.location)
            
        elif attribute == "usage-requirements":
            unconditional = []
            for p in specification:
                split = property.split_conditional(p)
                if split:
                    unconditional.append(split[1])
                else:
                    unconditional.append(p)

            non_free = property.remove("free", unconditional)
            if non_free:                
                get_manager().errors()("usage-requirements %s have non-free properties %s" \
                                       % (specification, non_free))

            t = property.translate_paths(
                    property.create_from_strings(specification, allow_condition=True),
                    self.location)

            existing = self.__dict__.get("usage-requirements")
            if existing:
                new = property_set.create(existing.all() +  t)
            else:
                new = property_set.create(t)
            self.__dict__["usage-requirements"] = new

                
        elif attribute == "default-build":
            self.__dict__["default-build"] = property_set.create(specification)
            
        elif attribute == "source-location":
            source_location = []
            for path in specification:
                source_location.append(os.path.join(self.location, path))
            self.__dict__["source-location"] = source_location
                
        elif attribute == "build-dir":
            self.__dict__["build-dir"] = os.path.join(self.location, specification[0])

        elif attribute == "id":
            id = specification[0]
            if id[0] != '/':
                id = "/" + id
            self.manager.projects().register_id(id, self.project_module)
            self.__dict__["id"] = id
                
        elif not attribute in ["default-build", "location",
                               "source-location", "parent",
                               "projects-to-build", "project-root"]:
            self.manager.errors()(
"""Invalid project attribute '%s' specified
for project at '%s'""" % (attribute, self.location))
        else:
            self.__dict__[attribute] = specification
Ejemplo n.º 37
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
Ejemplo n.º 38
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