def cpu_flags(toolset, variable, architecture, instruction_set, values, default=None): #FIXME: for some reason this fails. Probably out of date feature code ## if default: ## flags(toolset, variable, ## ['<architecture>' + architecture + '/<instruction-set>'], ## values) flags(toolset, variable, #FIXME: same as above [##'<architecture>/<instruction-set>' + instruction_set, '<architecture>' + architecture + '/<instruction-set>' + instruction_set], values)
def configure (command = None, condition = None, options = None): """ Configures a new resource compilation command specific to a condition, usually a toolset selection condition. The possible options are: * <rc-type>(rc|windres) - Indicates the type of options the command accepts. Even though the arguments are all optional, only when a command, condition, and at minimum the rc-type option are given will the command be configured. This is so that callers don't have to check auto-configuration values before calling this. And still get the functionality of build failures when the resource compiler can't be found. """ rc_type = feature.get_values('<rc-type>', options) if rc_type: assert(len(rc_type) == 1) rc_type = rc_type[0] if command and condition and rc_type: flags('rc.compile.resource', '.RC', condition, command) flags('rc.compile.resource', '.RC_TYPE', condition, rc_type.lower()) flags('rc.compile.resource', 'DEFINES', [], ['<define>']) flags('rc.compile.resource', 'INCLUDES', [], ['<include>']) if debug(): print 'notice: using rc compiler ::', condition, '::', command
def init_link_flags(toolset, linker, condition): """ Now, the vendor specific flags. The parameter linker can be either gnu, darwin, osf, hpux or sun. """ toolset_link = toolset + '.link' if linker == 'gnu': # Strip the binary when no debugging is needed. We use --strip-all flag # as opposed to -s since icc (intel's compiler) is generally # option-compatible with and inherits from the gcc toolset, but does not # support -s. # FIXME: what does unchecked translate to? flags(toolset_link, 'OPTIONS', map(lambda x: x + '/<debug-symbols>off', condition), ['-Wl,--strip-all']) # : unchecked ; flags(toolset_link, 'RPATH', condition, ['<dll-path>']) # : unchecked ; flags(toolset_link, 'RPATH_LINK', condition, ['<xdll-path>']) # : unchecked ; flags(toolset_link, 'START-GROUP', condition, ['-Wl,--start-group'])# : unchecked ; flags(toolset_link, 'END-GROUP', condition, ['-Wl,--end-group']) # : unchecked ; # gnu ld has the ability to change the search behaviour for libraries # referenced by -l switch. These modifiers are -Bstatic and -Bdynamic # and change search for -l switches that follow them. The following list # shows the tried variants. # The search stops at the first variant that has a match. # *nix: -Bstatic -lxxx # libxxx.a # # *nix: -Bdynamic -lxxx # libxxx.so # libxxx.a # # windows (mingw,cygwin) -Bstatic -lxxx # libxxx.a # xxx.lib # # windows (mingw,cygwin) -Bdynamic -lxxx # libxxx.dll.a # xxx.dll.a # libxxx.a # xxx.lib # cygxxx.dll (*) # libxxx.dll # xxx.dll # libxxx.a # # (*) This is for cygwin # Please note that -Bstatic and -Bdynamic are not a guarantee that a # static or dynamic lib indeed gets linked in. The switches only change # search patterns! # On *nix mixing shared libs with static runtime is not a good idea. flags(toolset_link, 'FINDLIBS-ST-PFX', map(lambda x: x + '/<runtime-link>shared', condition), ['-Wl,-Bstatic']) # : unchecked ; flags(toolset_link, 'FINDLIBS-SA-PFX', map(lambda x: x + '/<runtime-link>shared', condition), ['-Wl,-Bdynamic']) # : unchecked ; # On windows allow mixing of static and dynamic libs with static # runtime. flags(toolset_link, 'FINDLIBS-ST-PFX', map(lambda x: x + '/<runtime-link>static/<target-os>windows', condition), ['-Wl,-Bstatic']) # : unchecked ; flags(toolset_link, 'FINDLIBS-SA-PFX', map(lambda x: x + '/<runtime-link>static/<target-os>windows', condition), ['-Wl,-Bdynamic']) # : unchecked ; flags(toolset_link, 'OPTIONS', map(lambda x: x + '/<runtime-link>static/<target-os>windows', condition), ['-Wl,-Bstatic']) # : unchecked ; elif linker == 'darwin': # On Darwin, the -s option to ld does not work unless we pass -static, # and passing -static unconditionally is a bad idea. So, don't pass -s. # at all, darwin.jam will use separate 'strip' invocation. flags(toolset_link, 'RPATH', condition, ['<dll-path>']) # : unchecked ; flags(toolset_link, 'RPATH_LINK', condition, ['<xdll-path>']) # : unchecked ; elif linker == 'osf': # No --strip-all, just -s. flags(toolset_link, 'OPTIONS', map(lambda x: x + '/<debug-symbols>off', condition), ['-Wl,-s']) # : unchecked ; flags(toolset_link, 'RPATH', condition, ['<dll-path>']) # : unchecked ; # This does not supports -R. flags(toolset_link, 'RPATH_OPTION', condition, ['-rpath']) # : unchecked ; # -rpath-link is not supported at all. elif linker == 'sun': flags(toolset_link, 'OPTIONS', map(lambda x: x + '/<debug-symbols>off', condition), ['-Wl,-s']) # : unchecked ; flags(toolset_link, 'RPATH', condition, ['<dll-path>']) # : unchecked ; # Solaris linker does not have a separate -rpath-link, but allows to use # -L for the same purpose. flags(toolset_link, 'LINKPATH', condition, ['<xdll-path>']) # : unchecked ; # This permits shared libraries with non-PIC code on Solaris. # VP, 2004/09/07: Now that we have -fPIC hardcode in link.dll, the # following is not needed. Whether -fPIC should be hardcoded, is a # separate question. # AH, 2004/10/16: it is still necessary because some tests link against # static libraries that were compiled without PIC. flags(toolset_link, 'OPTIONS', map(lambda x: x + '/<link>shared', condition), ['-mimpure-text']) # : unchecked ; elif linker == 'hpux': flags(toolset_link, 'OPTIONS', map(lambda x: x + '/<debug-symbols>off', condition), ['-Wl,-s']) # : unchecked ; flags(toolset_link, 'OPTIONS', map(lambda x: x + '/<link>shared', condition), ['-fPIC']) # : unchecked ; else: # FIXME: errors.user_error( "$(toolset) initialization: invalid linker '$(linker)' " + "The value '$(linker)' specified for <linker> is not recognized. " + "Possible values are 'gnu', 'darwin', 'osf', 'hpux' or 'sun'")
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']) flags('gcc.compile', 'OPTIONS', ['<inlining>full'], ['-finline-functions', '-Wno-inline']) flags('gcc.compile', 'OPTIONS', ['<warnings>off'], ['-w']) flags('gcc.compile', 'OPTIONS', ['<warnings>on'], ['-Wall']) flags('gcc.compile', 'OPTIONS', ['<warnings>all'], ['-Wall', '-pedantic']) flags('gcc.compile', 'OPTIONS', ['<warnings-as-errors>on'], ['-Werror'])
["RUN_FAIL"]) generators.register_standard("testing.expect-success", ["EXE"], ["LINK"]) generators.register_standard("testing.expect-failure", ["EXE"], ["LINK_FAIL"]) # Generator which runs an EXE and captures output. generators.register_standard("testing.capture-output", ["EXE"], ["RUN_OUTPUT"]) # Generator which creates a target if sources run successfully. Differs from RUN # in that run output is not captured. The reason why it exists is that the 'run' # rule is much better for automated testing, but is not user-friendly (see # http://article.gmane.org/gmane.comp.lib.boost.build/6353). generators.register_standard("testing.unit-test", ["EXE"], ["UNIT_TEST"]) # FIXME: if those calls are after bjam.call, then bjam will crash # when toolset.flags calls bjam.caller. toolset.flags("testing.capture-output", "ARGS", [], ["<testing.arg>"]) toolset.flags("testing.capture-output", "INPUT_FILES", [], ["<testing.input-file>"]) toolset.flags("testing.capture-output", "LAUNCHER", [], ["<testing.launcher>"]) toolset.flags("testing.unit-test", "LAUNCHER", [], ["<testing.launcher>"]) toolset.flags("testing.unit-test", "ARGS", [], ["<testing.arg>"]) type.register("TIME", ["time"]) generators.register_standard("testing.time", [], ["TIME"]) # The following code sets up actions for this module. It's pretty convoluted, # but the basic points is that we most of actions are defined by Jam code # contained in testing-aux.jam, which we load into Jam module named 'testing'
def init(version=None, command=None, options=None): """ Initializes the gcc toolset for the given version. If necessary, command may be used to specify where the compiler is located. The parameter 'options' is a space-delimited list of options, each one specified as <option-name>option-value. Valid option names are: cxxflags, linkflags and linker-type. Accepted linker-type values are gnu, darwin, osf, hpux or sun and the default value will be selected based on the current OS. Example: using gcc : 3.4 : : <cxxflags>foo <linkflags>bar <linker-type>sun ; """ options = to_seq(options) command = to_seq(command) # Information about the gcc command... # The command. command = to_seq(common.get_invocation_command('gcc', 'g++', command)) # The root directory of the tool install. root = feature.get_values('<root>', options) # The bin directory where to find the command to execute. bin = None # The flavor of compiler. flavor = feature.get_values('<flavor>', options) # Autodetect the root and bin dir if not given. if command: if not bin: bin = common.get_absolute_tool_path(command[-1]) if not root: root = os.path.dirname(bin) # Autodetect the version and flavor if not given. if command: machine_info = subprocess.Popen( command + ['-dumpmachine'], stdout=subprocess.PIPE).communicate()[0] machine = __machine_match.search(machine_info).group(1) version_info = subprocess.Popen( command + ['-dumpversion'], stdout=subprocess.PIPE).communicate()[0] version = __version_match.search(version_info).group(1) if not flavor and machine.find('mingw') != -1: flavor = 'mingw' condition = None if flavor: condition = common.check_init_parameters('gcc', None, ('version', version), ('flavor', flavor)) else: condition = common.check_init_parameters('gcc', None, ('version', version)) if command: command = command[0] common.handle_options('gcc', condition, command, options) linker = feature.get_values('<linker-type>', options) if not linker: if os_name() == 'OSF': linker = 'osf' elif os_name() == 'HPUX': linker = 'hpux' else: linker = 'gnu' init_link_flags('gcc', linker, condition) # If gcc is installed in non-standard location, we'd need to add # LD_LIBRARY_PATH when running programs created with it (for unit-test/run # rules). if command: # On multilib 64-bit boxes, there are both 32-bit and 64-bit libraries # and all must be added to LD_LIBRARY_PATH. The linker will pick the # right onces. Note that we don't provide a clean way to build 32-bit # binary with 64-bit compiler, but user can always pass -m32 manually. lib_path = [ os.path.join(root, 'bin'), os.path.join(root, 'lib'), os.path.join(root, 'lib32'), os.path.join(root, 'lib64') ] if debug(): print 'notice: using gcc libraries ::', condition, '::', lib_path toolset.flags('gcc.link', 'RUN_PATH', condition, lib_path) # If it's not a system gcc install we should adjust the various programs as # needed to prefer using the install specific versions. This is essential # for correct use of MinGW and for cross-compiling. # - The archive builder. archiver = common.get_invocation_command('gcc', 'ar', feature.get_values( '<archiver>', options), [bin], path_last=True) toolset.flags('gcc.archive', '.AR', condition, [archiver]) if debug(): print 'notice: using gcc archiver ::', condition, '::', archiver # - Ranlib ranlib = common.get_invocation_command('gcc', 'ranlib', feature.get_values( '<ranlib>', options), [bin], path_last=True) toolset.flags('gcc.archive', '.RANLIB', condition, [ranlib]) if debug(): print 'notice: using gcc archiver ::', condition, '::', ranlib # - The resource compiler. rc_command = common.get_invocation_command_nodefault('gcc', 'windres', feature.get_values( '<rc>', options), [bin], path_last=True) rc_type = feature.get_values('<rc-type>', options) if not rc_type: rc_type = 'windres' if not rc_command: # If we can't find an RC compiler we fallback to a null RC compiler that # creates empty object files. This allows the same Jamfiles to work # across the board. The null RC uses the assembler to create the empty # objects, so configure that. rc_command = common.get_invocation_command('gcc', 'as', [], [bin], path_last=True) rc_type = 'null' rc.configure(rc_command, condition, '<rc-type>' + rc_type)
get_manager().scanners().propagate( type.get_scanner("CPP", PropertySet(self.includes)), included_angle + included_quoted ) get_manager().scanners().propagate(self, imported) scanner.register(MidlScanner, "include") type.set_scanner("IDL", MidlScanner) # Command line options feature("midl-stubless-proxy", ["yes", "no"], ["propagated"]) feature("midl-robust", ["yes", "no"], ["propagated"]) flags("midl.compile.idl", "MIDLFLAGS", ["<midl-stubless-proxy>yes"], ["/Oicf"]) flags("midl.compile.idl", "MIDLFLAGS", ["<midl-stubless-proxy>no"], ["/Oic"]) flags("midl.compile.idl", "MIDLFLAGS", ["<midl-robust>yes"], ["/robust"]) flags("midl.compile.idl", "MIDLFLAGS", ["<midl-robust>no"], ["/no_robust"]) # Architecture-specific options architecture_x86 = ["<architecture>", "<architecture>x86"] address_model_32 = ["<address-model>", "<address-model>32"] address_model_64 = ["<address-model>", "<address-model>64"] flags("midl.compile.idl", "MIDLFLAGS", [ar + "/" + m for ar in architecture_x86 for m in address_model_32], ["/win32"]) flags("midl.compile.idl", "MIDLFLAGS", [ar + "/<address-model>64" for ar in architecture_x86], ["/x64"]) flags("midl.compile.idl", "MIDLFLAGS", ["<architecture>ia64/" + m for m in address_model_64], ["/ia64"]) flags("midl.compile.idl", "DEFINES", [], ["<define>"]) flags("midl.compile.idl", "UNDEFS", [], ["<undef>"])
def handle_options(tool, condition, command, options): """ Handle common options for toolset, specifically sets the following flag variables: - CONFIG_COMMAND to 'command' - OPTIOns for compile to the value of <compileflags> in options - OPTIONS for compile.c to the value of <cflags> in options - OPTIONS for compile.c++ to the value of <cxxflags> in options - OPTIONS for compile.fortran to the value of <fflags> in options - OPTIONs for link to the value of <linkflags> in options """ from b2.build import toolset assert(isinstance(tool, str)) assert(isinstance(condition, list)) assert(isinstance(command, str)) assert(isinstance(options, list)) assert(command) toolset.flags(tool, 'CONFIG_COMMAND', condition, [command]) toolset.flags(tool + '.compile', 'OPTIONS', condition, feature.get_values('<compileflags>', options)) toolset.flags(tool + '.compile.c', 'OPTIONS', condition, feature.get_values('<cflags>', options)) toolset.flags(tool + '.compile.c++', 'OPTIONS', condition, feature.get_values('<cxxflags>', options)) toolset.flags(tool + '.compile.fortran', 'OPTIONS', condition, feature.get_values('<fflags>', options)) toolset.flags(tool + '.link', 'OPTIONS', condition, feature.get_values('<linkflags>', options))
engine.set_target_variable(included_quoted, 'SEARCH', [utility.get_value(inc) for inc in self.includes]) engine.set_target_variable(imported , 'SEARCH', [utility.get_value(inc) for inc in self.includes]) engine.set_target_variable(imported_tlbs , 'SEARCH', [utility.get_value(inc) for inc in self.includes]) get_manager().scanners().propagate(type.get_scanner('CPP', PropertySet(self.includes)), included_angle + included_quoted) get_manager().scanners().propagate(self, imported) scanner.register(MidlScanner, 'include') type.set_scanner('IDL', MidlScanner) # Command line options feature('midl-stubless-proxy', ['yes', 'no'], ['propagated'] ) feature('midl-robust', ['yes', 'no'], ['propagated'] ) flags('midl.compile.idl', 'MIDLFLAGS', ['<midl-stubless-proxy>yes'], ['/Oicf' ]) flags('midl.compile.idl', 'MIDLFLAGS', ['<midl-stubless-proxy>no' ], ['/Oic' ]) flags('midl.compile.idl', 'MIDLFLAGS', ['<midl-robust>yes' ], ['/robust' ]) flags('midl.compile.idl', 'MIDLFLAGS', ['<midl-robust>no' ], ['/no_robust']) # Architecture-specific options architecture_x86 = ['<architecture>' , '<architecture>x86'] address_model_32 = ['<address-model>', '<address-model>32'] address_model_64 = ['<address-model>', '<address-model>64'] flags('midl.compile.idl', 'MIDLFLAGS', [ar + '/' + m for ar in architecture_x86 for m in address_model_32 ], ['/win32']) flags('midl.compile.idl', 'MIDLFLAGS', [ar + '/<address-model>64' for ar in architecture_x86], ['/x64']) flags('midl.compile.idl', 'MIDLFLAGS', ['<architecture>ia64/' + m for m in address_model_64], ['/ia64']) flags('midl.compile.idl', 'DEFINES', [], ['<define>']) flags('midl.compile.idl', 'UNDEFS', [], ['<undef>'])
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, []) get_manager().projects().add_rule("notfile", notfile)
command = common.get_invocation_command ('darwin', 'g++', command) common.handle_options ('darwin', condition, command, options) gcc.init_link_flags ('darwin', 'darwin', condition) # Darwin has a different shared library suffix type.set_generated_target_suffix ('SHARED_LIB', ['<toolset>darwin'], 'dylib') # we need to be able to tell the type of .dylib files type.register_suffixes ('dylib', 'SHARED_LIB') feature.feature ('framework', [], ['free']) toolset.flags ('darwin.compile', 'OPTIONS', '<link>shared', ['-dynamic']) toolset.flags ('darwin.compile', 'OPTIONS', None, ['-Wno-long-double', '-no-cpp-precomp']) toolset.flags ('darwin.compile.c++', 'OPTIONS', None, ['-fcoalesce-templates']) toolset.flags ('darwin.link', 'FRAMEWORK', '<framework>') # This is flag is useful for debugging the link step # uncomment to see what libtool is doing under the hood # toolset.flags ('darwin.link.dll', 'OPTIONS', None, '[-Wl,-v']) action.register ('darwin.compile.cpp', None, ['$(CONFIG_COMMAND) $(ST_OPTIONS) -L"$(LINKPATH)" -o "$(<)" "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST) -framework$(_)$(FRAMEWORK) $(OPTIONS)']) # TODO: how to set 'bind LIBRARIES'? action.register ('darwin.link.dll', None, ['$(CONFIG_COMMAND) -dynamiclib -L"$(LINKPATH)" -o "$(<)" "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST) -framework$(_)$(FRAMEWORK) $(OPTIONS)']) def darwin_archive (manager, targets, sources, properties):
generators.register_standard("testing.expect-failure", ["RUN_OUTPUT"], ["RUN_FAIL"]) generators.register_standard("testing.expect-success", ["EXE"], ["LINK"]) generators.register_standard("testing.expect-failure", ["EXE"], ["LINK_FAIL"]) # Generator which runs an EXE and captures output. generators.register_standard("testing.capture-output", ["EXE"], ["RUN_OUTPUT"]) # Generator which creates a target if sources run successfully. Differs from RUN # in that run output is not captured. The reason why it exists is that the 'run' # rule is much better for automated testing, but is not user-friendly (see # http://article.gmane.org/gmane.comp.lib.boost.build/6353). generators.register_standard("testing.unit-test", ["EXE"], ["UNIT_TEST"]) # FIXME: if those calls are after bjam.call, then bjam will crash # when toolset.flags calls bjam.caller. toolset.flags("testing.capture-output", "ARGS", [], ["<testing.arg>"]) toolset.flags("testing.capture-output", "INPUT_FILES", [], ["<testing.input-file>"]) toolset.flags("testing.capture-output", "LAUNCHER", [], ["<testing.launcher>"]) toolset.flags("testing.unit-test", "LAUNCHER", [], ["<testing.launcher>"]) toolset.flags("testing.unit-test", "ARGS", [], ["<testing.arg>"]) # This is a composing generator to support cases where a generator for the # specified target constructs other targets as well. One such example is msvc's # exe generator that constructs both EXE and PDB targets. type.register("TIME", ["time"]) generators.register_composing("testing.time", [], ["TIME"]) # The following code sets up actions for this module. It's pretty convoluted, # but the basic points is that we most of actions are defined by Jam code
command = common.get_invocation_command('darwin', 'g++', command) common.handle_options('darwin', condition, command, options) gcc.init_link_flags('darwin', 'darwin', condition) # Darwin has a different shared library suffix type.set_generated_target_suffix('SHARED_LIB', ['<toolset>darwin'], 'dylib') # we need to be able to tell the type of .dylib files type.register_suffixes('dylib', 'SHARED_LIB') feature.feature('framework', [], ['free']) toolset.flags('darwin.compile', 'OPTIONS', '<link>shared', ['-dynamic']) toolset.flags('darwin.compile', 'OPTIONS', None, ['-Wno-long-double', '-no-cpp-precomp']) toolset.flags('darwin.compile.c++', 'OPTIONS', None, ['-fcoalesce-templates']) toolset.flags('darwin.link', 'FRAMEWORK', '<framework>') # This is flag is useful for debugging the link step # uncomment to see what libtool is doing under the hood # toolset.flags ('darwin.link.dll', 'OPTIONS', None, '[-Wl,-v']) action.register('darwin.compile.cpp', None, [ '$(CONFIG_COMMAND) $(ST_OPTIONS) -L"$(LINKPATH)" -o "$(<)" "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST) -framework$(_)$(FRAMEWORK) $(OPTIONS)' ]) # TODO: how to set 'bind LIBRARIES'?
def handle_options(tool, condition, command, options): """ Handle common options for toolset, specifically sets the following flag variables: - CONFIG_COMMAND to 'command' - OPTIOns for compile to the value of <compileflags> in options - OPTIONS for compile.c to the value of <cflags> in options - OPTIONS for compile.c++ to the value of <cxxflags> in options - OPTIONS for compile.fortran to the value of <fflags> in options - OPTIONs for link to the value of <linkflags> in options """ from b2.build import toolset assert (isinstance(tool, str)) assert (isinstance(condition, list)) assert (isinstance(command, str)) assert (isinstance(options, list)) assert (command) toolset.flags(tool, 'CONFIG_COMMAND', condition, [command]) toolset.flags(tool + '.compile', 'OPTIONS', condition, feature.get_values('<compileflags>', options)) toolset.flags(tool + '.compile.c', 'OPTIONS', condition, feature.get_values('<cflags>', options)) toolset.flags(tool + '.compile.c++', 'OPTIONS', condition, feature.get_values('<cxxflags>', options)) toolset.flags(tool + '.compile.fortran', 'OPTIONS', condition, feature.get_values('<fflags>', options)) toolset.flags(tool + '.link', 'OPTIONS', condition, feature.get_values('<linkflags>', options))
def init(version = None, command = None, options = None): """ Initializes the gcc toolset for the given version. If necessary, command may be used to specify where the compiler is located. The parameter 'options' is a space-delimited list of options, each one specified as <option-name>option-value. Valid option names are: cxxflags, linkflags and linker-type. Accepted linker-type values are gnu, darwin, osf, hpux or sun and the default value will be selected based on the current OS. Example: using gcc : 3.4 : : <cxxflags>foo <linkflags>bar <linker-type>sun ; """ options = to_seq(options) command = to_seq(command) # Information about the gcc command... # The command. command = to_seq(common.get_invocation_command('gcc', 'g++', command)) # The root directory of the tool install. root = feature.get_values('<root>', options) ; # The bin directory where to find the command to execute. bin = None # The flavor of compiler. flavor = feature.get_values('<flavor>', options) # Autodetect the root and bin dir if not given. if command: if not bin: bin = common.get_absolute_tool_path(command[-1]) if not root: root = os.path.dirname(bin) # Autodetect the version and flavor if not given. if command: machine_info = subprocess.Popen(command + ['-dumpmachine'], stdout=subprocess.PIPE).communicate()[0] machine = __machine_match.search(machine_info).group(1) version_info = subprocess.Popen(command + ['-dumpversion'], stdout=subprocess.PIPE).communicate()[0] version = __version_match.search(version_info).group(1) if not flavor and machine.find('mingw') != -1: flavor = 'mingw' condition = None if flavor: condition = common.check_init_parameters('gcc', None, ('version', version), ('flavor', flavor)) else: condition = common.check_init_parameters('gcc', None, ('version', version)) if command: command = command[0] common.handle_options('gcc', condition, command, options) linker = feature.get_values('<linker-type>', options) if not linker: if os_name() == 'OSF': linker = 'osf' elif os_name() == 'HPUX': linker = 'hpux' ; else: linker = 'gnu' init_link_flags('gcc', linker, condition) # If gcc is installed in non-standard location, we'd need to add # LD_LIBRARY_PATH when running programs created with it (for unit-test/run # rules). if command: # On multilib 64-bit boxes, there are both 32-bit and 64-bit libraries # and all must be added to LD_LIBRARY_PATH. The linker will pick the # right onces. Note that we don't provide a clean way to build 32-bit # binary with 64-bit compiler, but user can always pass -m32 manually. lib_path = [os.path.join(root, 'bin'), os.path.join(root, 'lib'), os.path.join(root, 'lib32'), os.path.join(root, 'lib64')] if debug(): print 'notice: using gcc libraries ::', condition, '::', lib_path toolset.flags('gcc.link', 'RUN_PATH', condition, lib_path) # If it's not a system gcc install we should adjust the various programs as # needed to prefer using the install specific versions. This is essential # for correct use of MinGW and for cross-compiling. # - The archive builder. archiver = common.get_invocation_command('gcc', 'ar', feature.get_values('<archiver>', options), [bin], path_last=True) toolset.flags('gcc.archive', '.AR', condition, [archiver]) if debug(): print 'notice: using gcc archiver ::', condition, '::', archiver # - The resource compiler. rc_command = common.get_invocation_command_nodefault('gcc', 'windres', feature.get_values('<rc>', options), [bin], path_last=True) rc_type = feature.get_values('<rc-type>', options) if not rc_type: rc_type = 'windres' if not rc_command: # If we can't find an RC compiler we fallback to a null RC compiler that # creates empty object files. This allows the same Jamfiles to work # across the board. The null RC uses the assembler to create the empty # objects, so configure that. rc_command = common.get_invocation_command('gcc', 'as', [], [bin], path_last=True) rc_type = 'null' rc.configure(rc_command, condition, '<rc-type>' + rc_type)
from b2.build import generators, type from b2.build.feature import feature from b2.build.toolset import flags from b2.manager import get_manager def init(): pass type.register('MC', ['mc']) # Command line options feature('mc-input-encoding', ['ansi', 'unicode'], ['free']) feature('mc-output-encoding', ['unicode', 'ansi'], ['free']) feature('mc-set-customer-bit', ['no', 'yes'], ['free']) flags('mc.compile', 'MCFLAGS', ['<mc-input-encoding>ansi'], ['-a']) flags('mc.compile', 'MCFLAGS', ['<mc-input-encoding>unicode'], ['-u']) flags('mc.compile', 'MCFLAGS', ['<mc-output-encoding>ansi'], '-A') flags('mc.compile', 'MCFLAGS', ['<mc-output-encoding>unicode'], ['-U']) flags('mc.compile', 'MCFLAGS', ['<mc-set-customer-bit>no'], []) flags('mc.compile', 'MCFLAGS', ['<mc-set-customer-bit>yes'], ['-c']) generators.register_standard('mc.compile', ['MC'], ['H', 'RC']) get_manager().engine().register_action( 'mc.compile', 'mc $(MCFLAGS) -h "$(<[1]:DW)" -r "$(<[2]:DW)" "$(>:W)"')
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, [])
# 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']) flags('gcc.compile', 'OPTIONS', ['<inlining>full'], ['-finline-functions', '-Wno-inline']) flags('gcc.compile', 'OPTIONS', ['<warnings>off'], ['-w']) flags('gcc.compile', 'OPTIONS', ['<warnings>on'], ['-Wall']) flags('gcc.compile', 'OPTIONS', ['<warnings>all'], ['-Wall', '-pedantic']) flags('gcc.compile', 'OPTIONS', ['<warnings-as-errors>on'], ['-Werror'])
def init_link_flags(toolset, linker, condition): """ Now, the vendor specific flags. The parameter linker can be either gnu, darwin, osf, hpux or sun. """ toolset_link = toolset + '.link' if linker == 'gnu': # Strip the binary when no debugging is needed. We use --strip-all flag # as opposed to -s since icc (intel's compiler) is generally # option-compatible with and inherits from the gcc toolset, but does not # support -s. # FIXME: what does unchecked translate to? flags(toolset_link, 'OPTIONS', map(lambda x: x + '/<debug-symbols>off', condition), ['-Wl,--strip-all']) # : unchecked ; flags(toolset_link, 'RPATH', condition, ['<dll-path>']) # : unchecked ; flags(toolset_link, 'RPATH_LINK', condition, ['<xdll-path>']) # : unchecked ; flags(toolset_link, 'START-GROUP', condition, ['-Wl,--start-group']) # : unchecked ; flags(toolset_link, 'END-GROUP', condition, ['-Wl,--end-group']) # : unchecked ; # gnu ld has the ability to change the search behaviour for libraries # referenced by -l switch. These modifiers are -Bstatic and -Bdynamic # and change search for -l switches that follow them. The following list # shows the tried variants. # The search stops at the first variant that has a match. # *nix: -Bstatic -lxxx # libxxx.a # # *nix: -Bdynamic -lxxx # libxxx.so # libxxx.a # # windows (mingw,cygwin) -Bstatic -lxxx # libxxx.a # xxx.lib # # windows (mingw,cygwin) -Bdynamic -lxxx # libxxx.dll.a # xxx.dll.a # libxxx.a # xxx.lib # cygxxx.dll (*) # libxxx.dll # xxx.dll # libxxx.a # # (*) This is for cygwin # Please note that -Bstatic and -Bdynamic are not a guarantee that a # static or dynamic lib indeed gets linked in. The switches only change # search patterns! # On *nix mixing shared libs with static runtime is not a good idea. flags(toolset_link, 'FINDLIBS-ST-PFX', map(lambda x: x + '/<runtime-link>shared', condition), ['-Wl,-Bstatic']) # : unchecked ; flags(toolset_link, 'FINDLIBS-SA-PFX', map(lambda x: x + '/<runtime-link>shared', condition), ['-Wl,-Bdynamic']) # : unchecked ; # On windows allow mixing of static and dynamic libs with static # runtime. flags(toolset_link, 'FINDLIBS-ST-PFX', map(lambda x: x + '/<runtime-link>static/<target-os>windows', condition), ['-Wl,-Bstatic']) # : unchecked ; flags(toolset_link, 'FINDLIBS-SA-PFX', map(lambda x: x + '/<runtime-link>static/<target-os>windows', condition), ['-Wl,-Bdynamic']) # : unchecked ; flags(toolset_link, 'OPTIONS', map(lambda x: x + '/<runtime-link>static/<target-os>windows', condition), ['-Wl,-Bstatic']) # : unchecked ; elif linker == 'darwin': # On Darwin, the -s option to ld does not work unless we pass -static, # and passing -static unconditionally is a bad idea. So, don't pass -s. # at all, darwin.jam will use separate 'strip' invocation. flags(toolset_link, 'RPATH', condition, ['<dll-path>']) # : unchecked ; flags(toolset_link, 'RPATH_LINK', condition, ['<xdll-path>']) # : unchecked ; elif linker == 'osf': # No --strip-all, just -s. flags(toolset_link, 'OPTIONS', map(lambda x: x + '/<debug-symbols>off', condition), ['-Wl,-s']) # : unchecked ; flags(toolset_link, 'RPATH', condition, ['<dll-path>']) # : unchecked ; # This does not supports -R. flags(toolset_link, 'RPATH_OPTION', condition, ['-rpath']) # : unchecked ; # -rpath-link is not supported at all. elif linker == 'sun': flags(toolset_link, 'OPTIONS', map(lambda x: x + '/<debug-symbols>off', condition), ['-Wl,-s']) # : unchecked ; flags(toolset_link, 'RPATH', condition, ['<dll-path>']) # : unchecked ; # Solaris linker does not have a separate -rpath-link, but allows to use # -L for the same purpose. flags(toolset_link, 'LINKPATH', condition, ['<xdll-path>']) # : unchecked ; # This permits shared libraries with non-PIC code on Solaris. # VP, 2004/09/07: Now that we have -fPIC hardcode in link.dll, the # following is not needed. Whether -fPIC should be hardcoded, is a # separate question. # AH, 2004/10/16: it is still necessary because some tests link against # static libraries that were compiled without PIC. flags(toolset_link, 'OPTIONS', map(lambda x: x + '/<link>shared', condition), ['-mimpure-text']) # : unchecked ; elif linker == 'hpux': flags(toolset_link, 'OPTIONS', map(lambda x: x + '/<debug-symbols>off', condition), ['-Wl,-s']) # : unchecked ; flags(toolset_link, 'OPTIONS', map(lambda x: x + '/<link>shared', condition), ['-fPIC']) # : unchecked ; else: # FIXME: errors.user_error( "$(toolset) initialization: invalid linker '$(linker)' " + "The value '$(linker)' specified for <linker> is not recognized. " + "Possible values are 'gnu', 'darwin', 'osf', 'hpux' or 'sun'")
from b2.tools import common, rc from b2.build import generators, type from b2.build.toolset import flags from b2.build.feature import feature from b2.manager import get_manager def init(): pass type.register('MC', ['mc']) # Command line options feature('mc-input-encoding', ['ansi', 'unicode'], ['free']) feature('mc-output-encoding', ['unicode', 'ansi'], ['free']) feature('mc-set-customer-bit', ['no', 'yes'], ['free']) flags('mc.compile', 'MCFLAGS', ['<mc-input-encoding>ansi'], ['-a']) flags('mc.compile', 'MCFLAGS', ['<mc-input-encoding>unicode'], ['-u']) flags('mc.compile', 'MCFLAGS', ['<mc-output-encoding>ansi'], '-A') flags('mc.compile', 'MCFLAGS', ['<mc-output-encoding>unicode'], ['-U']) flags('mc.compile', 'MCFLAGS', ['<mc-set-customer-bit>no'], []) flags('mc.compile', 'MCFLAGS', ['<mc-set-customer-bit>yes'], ['-c']) generators.register_standard('mc.compile', ['MC'], ['H', 'RC']) get_manager().engine().register_action( 'mc.compile', 'mc $(MCFLAGS) -h "$(<[1]:DW)" -r "$(<[2]:DW)" "$(>:W)"')