def register_c_compiler(id, source_types, target_types, requirements, optional_properties=[]): g = CCompilingGenerator(id, False, source_types, target_types, requirements + optional_properties) return generators.register(g)
elif '<link>shared' in properties: actual_type = 'SHARED_LIB' else: actual_type = 'STATIC_LIB' prop_set = prop_set.add_raw(['<main-target-type>LIB']) # Construct the target. return generators.construct(project, name, actual_type, prop_set, sources) def viable_source_types(self): return ['*'] generators.register(LibGenerator()) def lib(names, sources=[], requirements=[], default_build=[], usage_requirements=[]): """The implementation of the 'lib' rule. Beyond standard syntax that rule allows simplified: 'lib a b c ;'.""" if len(names) > 1: if any(r.startswith('<name>') for r in requirements): get_manager().errors()( "When several names are given to the 'lib' rule\n" + "it is not allowed to specify the <name> feature.")
] or ps.get('target-os') in ['windows', 'cygwin']: # Never relink pass else: # See if the dll-path properties are not changed during # install. If so, copy, don't relink. need_relink = source[0].action() and ps.get( 'dll-path') != source[0].action().properties().get('dll-path') if need_relink: return [relink_file(project, source, ps)] else: return [copy_file(project, None, source[0], ps)] generators.register(InstalledExeGenerator()) # Installing a shared link on Unix might cause a creation of versioned symbolic # links. b2.build.type.register('INSTALLED_SHARED_LIB', [], 'SHARED_LIB') class InstalledSharedLibGenerator(generators.Generator): def __init__(self): generators.Generator.__init__(self, 'install-shared-lib', False, ['SHARED_LIB'], ['INSTALLED_SHARED_LIB']) def run(self, project, name, ps, source): source = source[0] if ps.get('os') in ['NT', 'CYGWIN'
def register_archiver(id, source_types, target_types, requirements): g = ArchiveGenerator(id, True, source_types, target_types, requirements) generators.register(g)
elif '<link>shared' in properties: actual_type = 'SHARED_LIB' else: actual_type = 'STATIC_LIB' prop_set = prop_set.add_raw(['<main-target-type>LIB']) # Construct the target. return generators.construct(project, name, actual_type, prop_set, sources) def viable_source_types(self): return ['*'] generators.register(LibGenerator("builtin.lib-generator")) generators.override("builtin.prebuilt", "builtin.lib-generator") def lib(names, sources=[], requirements=[], default_build=[], usage_requirements=[]): """The implementation of the 'lib' rule. Beyond standard syntax that rule allows simplified: 'lib a b c ;'.""" assert is_iterable_typed(names, basestring) assert is_iterable_typed(sources, basestring) assert is_iterable_typed(requirements, basestring) assert is_iterable_typed(default_build, basestring)
pass action_name = ps.get('action')[0] if action_name[0] == '@': action = virtual_target.Action(get_manager(), sources, action_name[1:], ps) else: action = virtual_target.Action(get_manager(), sources, "notfile.run", ps) return [ get_manager().virtual_targets().register( virtual_target.NotFileTarget(name, project, action)) ] generators.register( NotfileGenerator("notfile.main", False, [], ["NOTFILE_MAIN"])) toolset.flags("notfile.run", "ACTION", [], ["<action>"]) get_manager().engine().register_action("notfile.run", "$(ACTION)") @bjam_signature( (["target_name"], ["action"], ["sources", "*"], ["requirements", "*"], ["default_build", "*"])) def notfile(target_name, action, sources, requirements, default_build): requirements.append("<action>" + action) return targets.create_typed_metatarget(target_name, "NOTFILE_MAIN", sources, requirements,
class UnixPrebuiltLibGenerator (generators.Generator): def __init__ (self, id, composing, source_types, target_types_and_names, requirements): generators.Generator.__init__ (self, id, composing, source_types, target_types_and_names, requirements) def run (self, project, name, prop_set, sources, multiple): f = prop_set.get ('<file>') set_library_order_aux (f, sources) return (f, sources) ### # The derived toolset must specify their own rules and actions. # FIXME: restore? # action.register ('unix.prebuilt', None, None) generators.register (UnixPrebuiltLibGenerator ('unix.prebuilt', False, [], ['LIB'], ['<file>', '<toolset>unix'])) ### # Declare generators ### generators.register [ new UnixLinkingGenerator unix.link : LIB OBJ : EXE ### : <toolset>unix ] ; generators.register (UnixArchiveGenerator ('unix.archive', True, ['OBJ'], ['STATIC_LIB'], ['<toolset>unix'])) ### generators.register [ new UnixLinkingGenerator unix.link.dll : LIB OBJ : SHARED_LIB ### : <toolset>unix ] ; ### ### generators.register [ new UnixSearchedLibGenerator ### unix.SearchedLibGenerator : : SEARCHED_LIB : <toolset>unix ] ;
# The generator for actual_type = 'LIB' elif '<link>shared' in properties: actual_type = 'SHARED_LIB' else: actual_type = 'STATIC_LIB' prop_set = prop_set.add_raw(['<main-target-type>LIB']) # Construct the target. return generators.construct(project, name, actual_type, prop_set, sources) def viable_source_types(self): return ['*'] generators.register(LibGenerator("builtin.lib-generator")) generators.override("builtin.prebuilt", "builtin.lib-generator") def lib(names, sources=[], requirements=[], default_build=[], usage_requirements=[]): """The implementation of the 'lib' rule. Beyond standard syntax that rule allows simplified: 'lib a b c ;'.""" if len(names) > 1: if any(r.startswith('<name>') for r in requirements): get_manager().errors()("When several names are given to the 'lib' rule\n" + "it is not allowed to specify the <name> feature.") if sources: get_manager().errors()("When several names are given to the 'lib' rule\n" + "it is not allowed to specify sources.")
def run(self, project, name, prop_set, sources): if not name: # Unless this generator is invoked as the top-most generator for a # main target, fail. This allows using 'H' type as input type for # this generator, while preventing Boost.Build to try this generator # when not explicitly asked for. # # One bad example is msvc, where pch generator produces both PCH # target and OBJ target, so if there's any header generated (like by # bison, or by msidl), we'd try to use pch generator to get OBJ from # that H, which is completely wrong. By restricting this generator # only to pch main target, such problem is solved. pass else: r = self.run_pch(project, name, prop_set.add_raw(['<define>BOOST_BUILD_PCH_ENABLED']), sources) return generators.add_usage_requirements( r, ['<define>BOOST_BUILD_PCH_ENABLED']) # This rule must be overridden by the derived classes. def run_pch(self, project, name, prop_set, sources): pass # NOTE: requirements are empty, default pch generator can be applied when # pch=off. generators.register(builtin.DummyGenerator( "pch.default-c-pch-generator", False, [], ['C_PCH'], [])) generators.register(builtin.DummyGenerator( "pch.default-cpp-pch-generator", False, [], ['CPP_PCH'], []))
# FIXME: what about multiple results from generator.run? return (property_set.create('<pch-file>' + pch_file[0], '<cflags>-Winvalid-pch'), pch_file) # Calls the base version specifying source's name as the name of the created # target. As result, the PCH will be named whatever.hpp.gch, and not # whatever.gch. def generated_targets(self, sources, prop_set, project, name = None): name = sources[0].name return Generator.generated_targets(self, sources, prop_set, project, name) # Note: the 'H' source type will catch both '.h' header and '.hpp' header. The # latter have HPP type, but HPP type is derived from H. The type of compilation # is determined entirely by the destination type. generators.register(GccPchGenerator('gcc.compile.c.pch', False, ['H'], ['C_PCH'], ['<pch>on', '<toolset>gcc' ])) generators.register(GccPchGenerator('gcc.compile.c++.pch', False, ['H'], ['CPP_PCH'], ['<pch>on', '<toolset>gcc' ])) # Override default do-nothing generators. generators.override('gcc.compile.c.pch', 'pch.default-c-pch-generator') generators.override('gcc.compile.c++.pch', 'pch.default-cpp-pch-generator') flags('gcc.compile', 'PCH_FILE', ['<pch>on'], ['<pch-file>']) # Declare flags and action for compilation flags('gcc.compile', 'OPTIONS', ['<optimization>off'], ['-O0']) flags('gcc.compile', 'OPTIONS', ['<optimization>speed'], ['-O3']) flags('gcc.compile', 'OPTIONS', ['<optimization>space'], ['-Os']) flags('gcc.compile', 'OPTIONS', ['<inlining>off'], ['-fno-inline']) flags('gcc.compile', 'OPTIONS', ['<inlining>on'], ['-Wno-inline'])
]), pch_file) # Calls the base version specifying source's name as the name of the created # target. As result, the PCH will be named whatever.hpp.gch, and not # whatever.gch. def generated_targets(self, sources, prop_set, project, name=None): name = sources[0].name() return Generator.generated_targets(self, sources, prop_set, project, name) # Note: the 'H' source type will catch both '.h' header and '.hpp' header. The # latter have HPP type, but HPP type is derived from H. The type of compilation # is determined entirely by the destination type. generators.register( GccPchGenerator('gcc.compile.c.pch', False, ['H'], ['C_PCH'], ['<pch>on', '<toolset>gcc'])) generators.register( GccPchGenerator('gcc.compile.c++.pch', False, ['H'], ['CPP_PCH'], ['<pch>on', '<toolset>gcc'])) # Override default do-nothing generators. generators.override('gcc.compile.c.pch', 'pch.default-c-pch-generator') generators.override('gcc.compile.c++.pch', 'pch.default-cpp-pch-generator') flags('gcc.compile', 'PCH_FILE', ['<pch>on'], ['<pch-file>']) # Declare flags and action for compilation flags('gcc.compile', 'OPTIONS', ['<optimization>off'], ['-O0']) flags('gcc.compile', 'OPTIONS', ['<optimization>speed'], ['-O3']) flags('gcc.compile', 'OPTIONS', ['<optimization>space'], ['-Os'])
type.register("NOTFILE_MAIN") class NotfileGenerator(generators.Generator): def run(self, project, name, ps, sources): pass action_name = ps.get('action')[0] if action_name[0] == '@': action = virtual_target.Action(get_manager(), sources, action_name[1:], ps) else: action = virtual_target.Action(get_manager(), sources, "notfile.run", ps) return [get_manager().virtual_targets().register( virtual_target.NotFileTarget(name, project, action))] generators.register(NotfileGenerator("notfile.main", False, [], ["NOTFILE_MAIN"])) toolset.flags("notfile.run", "ACTION", [], ["<action>"]) get_manager().engine().register_action("notfile.run", "$(ACTION)") @bjam_signature((["target_name"], ["action"], ["sources", "*"], ["requirements", "*"], ["default_build", "*"])) def notfile(target_name, action, sources, requirements, default_build): requirements.append("<action>" + action) return targets.create_typed_metatarget(target_name, "NOTFILE_MAIN", sources, requirements, default_build, [])
requirements): generators.Generator.__init__(self, id, composing, source_types, target_types_and_names, requirements) def run(self, project, name, prop_set, sources): f = prop_set.get('<file>') set_library_order_aux(f, sources) return f + sources ### # The derived toolset must specify their own rules and actions. # FIXME: restore? # action.register ('unix.prebuilt', None, None) generators.register( UnixPrebuiltLibGenerator('unix.prebuilt', False, [], ['LIB'], ['<file>', '<toolset>unix'])) ### # Declare generators ### generators.register [ new UnixLinkingGenerator unix.link : LIB OBJ : EXE ### : <toolset>unix ] ; generators.register( UnixArchiveGenerator('unix.archive', True, ['OBJ'], ['STATIC_LIB'], ['<toolset>unix'])) ### generators.register [ new UnixLinkingGenerator unix.link.dll : LIB OBJ : SHARED_LIB ### : <toolset>unix ] ; ### ### generators.register [ new UnixSearchedLibGenerator ### unix.SearchedLibGenerator : : SEARCHED_LIB : <toolset>unix ] ; ###
# The generator for actual_type = 'LIB' elif '<link>shared' in properties: actual_type = 'SHARED_LIB' else: actual_type = 'STATIC_LIB' prop_set = prop_set.add_raw(['<main-target-type>LIB']) # Construct the target. return generators.construct(project, name, actual_type, prop_set, sources) def viable_source_types(self): return ['*'] generators.register(LibGenerator()) def lib(names, sources=[], requirements=[], default_build=[], usage_requirements=[]): """The implementation of the 'lib' rule. Beyond standard syntax that rule allows simplified: 'lib a b c ;'.""" if len(names) > 1: if any(r.startswith('<name>') for r in requirements): get_manager().errors()("When several names are given to the 'lib' rule\n" + "it is not allowed to specify the <name> feature.") if sources: get_manager().errors()("When several names are given to the 'lib' rule\n" + "it is not allowed to specify sources.") project = get_manager().projects().current()
def register_linker(id, source_types, target_types, requirements): g = LinkingGenerator(id, True, source_types, target_types, requirements) generators.register(g)
need_relink = False; if ps.get('os') in ['NT', 'CYGWIN'] or ps.get('target-os') in ['windows', 'cygwin']: # Never relink pass else: # See if the dll-path properties are not changed during # install. If so, copy, don't relink. need_relink = source[0].action() and ps.get('dll-path') != source[0].action().properties().get('dll-path') if need_relink: return [relink_file(project, source, ps)] else: return [copy_file(project, None, source[0], ps)] generators.register(InstalledExeGenerator()) # Installing a shared link on Unix might cause a creation of versioned symbolic # links. b2.build.type.register('INSTALLED_SHARED_LIB', [], 'SHARED_LIB') class InstalledSharedLibGenerator(generators.Generator): def __init__(self): generators.Generator.__init__(self, 'install-shared-lib', False, ['SHARED_LIB'], ['INSTALLED_SHARED_LIB']) def run(self, project, name, ps, source): source = source[0] if ps.get('os') in ['NT', 'CYGWIN'] or ps.get('target-os') in ['windows', 'cygwin']:
# main target, fail. This allows using 'H' type as input type for # this generator, while preventing Boost.Build to try this generator # when not explicitly asked for. # # One bad example is msvc, where pch generator produces both PCH # target and OBJ target, so if there's any header generated (like by # bison, or by msidl), we'd try to use pch generator to get OBJ from # that H, which is completely wrong. By restricting this generator # only to pch main target, such problem is solved. pass else: r = self.run_pch( project, name, prop_set.add_raw(['<define>BOOST_BUILD_PCH_ENABLED']), sources) return generators.add_usage_requirements( r, ['<define>BOOST_BUILD_PCH_ENABLED']) # This rule must be overridden by the derived classes. def run_pch(self, project, name, prop_set, sources): pass # NOTE: requirements are empty, default pch generator can be applied when # pch=off. generators.register( builtin.DummyGenerator("pch.default-c-pch-generator", False, [], ['C_PCH'], [])) generators.register( builtin.DummyGenerator("pch.default-cpp-pch-generator", False, [], ['CPP_PCH'], []))