• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Status: being ported by Steven Watanabe
2# Base revision: 47077
3# TODO: common.jam needs to be ported
4# TODO: generators.jam needs to have register_c_compiler.
5#
6# Copyright 2001 David Abrahams.
7# Copyright 2002-2006 Rene Rivera.
8# Copyright 2002-2003 Vladimir Prus.
9#  Copyright (c) 2005 Reece H. Dunn.
10# Copyright 2006 Ilya Sokolov.
11# Copyright 2007 Roland Schwarz
12# Copyright 2007 Boris Gubenko.
13# Copyright 2008 Steven Watanabe
14#
15# Distributed under the Boost Software License, Version 1.0.
16#    (See accompanying file LICENSE_1_0.txt or copy at
17#          http://www.boost.org/LICENSE_1_0.txt)
18
19import os
20import subprocess
21import re
22
23import bjam
24
25from b2.tools import unix, common, rc, pch, builtin
26from b2.build import feature, type, toolset, generators, property_set
27from b2.build.property import Property
28from b2.util.utility import os_name, on_windows
29from b2.manager import get_manager
30from b2.build.generators import Generator
31from b2.build.toolset import flags
32from b2.util.utility import to_seq
33
34
35
36__debug = None
37
38def debug():
39    global __debug
40    if __debug is None:
41        __debug = "--debug-configuration" in bjam.variable("ARGV")
42    return __debug
43
44feature.extend('toolset', ['gcc'])
45
46
47toolset.inherit_generators('gcc', [], 'unix', ['unix.link', 'unix.link.dll'])
48toolset.inherit_flags('gcc', 'unix')
49toolset.inherit_rules('gcc', 'unix')
50
51generators.override('gcc.prebuilt', 'builtin.prebuilt')
52generators.override('gcc.searched-lib-generator', 'searched-lib-generator')
53
54# Target naming is determined by types/lib.jam and the settings below this
55# comment.
56#
57# On *nix:
58#     libxxx.a     static library
59#     libxxx.so    shared library
60#
61# On windows (mingw):
62#     libxxx.lib   static library
63#     xxx.dll      DLL
64#     xxx.lib      import library
65#
66# On windows (cygwin) i.e. <target-os>cygwin
67#     libxxx.a     static library
68#     xxx.dll      DLL
69#     libxxx.dll.a import library
70#
71# Note: user can always override by using the <tag>@rule
72#       This settings have been chosen, so that mingw
73#       is in line with msvc naming conventions. For
74#       cygwin the cygwin naming convention has been chosen.
75
76# Make the "o" suffix used for gcc toolset on all
77# platforms
78type.set_generated_target_suffix('OBJ', ['<toolset>gcc'], 'o')
79type.set_generated_target_suffix('STATIC_LIB', ['<toolset>gcc', '<target-os>cygwin'], 'a')
80
81type.set_generated_target_suffix('IMPORT_LIB', ['<toolset>gcc', '<target-os>cygwin'], 'dll.a')
82type.set_generated_target_prefix('IMPORT_LIB', ['<toolset>gcc', '<target-os>cygwin'], 'lib')
83
84__machine_match = re.compile('^([^ ]+)')
85__version_match = re.compile('^([0-9.]+)')
86
87def init(version = None, command = None, options = None):
88    """
89        Initializes the gcc toolset for the given version. If necessary, command may
90        be used to specify where the compiler is located. The parameter 'options' is a
91        space-delimited list of options, each one specified as
92        <option-name>option-value. Valid option names are: cxxflags, linkflags and
93        linker-type. Accepted linker-type values are gnu, darwin, osf, hpux or sun
94        and the default value will be selected based on the current OS.
95        Example:
96          using gcc : 3.4 : : <cxxflags>foo <linkflags>bar <linker-type>sun ;
97    """
98
99    options = to_seq(options)
100    command = to_seq(command)
101
102    # Information about the gcc command...
103    #   The command.
104    command = to_seq(common.get_invocation_command('gcc', 'g++', command))
105    #   The root directory of the tool install.
106    root = feature.get_values('<root>', options)
107    root = root[0] if root else ''
108    #   The bin directory where to find the command to execute.
109    bin = None
110    #   The flavor of compiler.
111    flavor = feature.get_values('<flavor>', options)
112    flavor = flavor[0] if flavor else ''
113    #   Autodetect the root and bin dir if not given.
114    if command:
115        if not bin:
116            bin = common.get_absolute_tool_path(command[-1])
117        if not root:
118            root = os.path.dirname(bin)
119    #   Autodetect the version and flavor if not given.
120    if command:
121        machine_info = subprocess.Popen(command + ['-dumpmachine'], stdout=subprocess.PIPE).communicate()[0]
122        machine = __machine_match.search(machine_info).group(1)
123
124        version_info = subprocess.Popen(command + ['-dumpversion'], stdout=subprocess.PIPE).communicate()[0]
125        version = __version_match.search(version_info).group(1)
126        if not flavor and machine.find('mingw') != -1:
127            flavor = 'mingw'
128
129    condition = None
130    if flavor:
131        condition = common.check_init_parameters('gcc', None,
132            ('version', version),
133            ('flavor', flavor))
134    else:
135        condition = common.check_init_parameters('gcc', None,
136            ('version', version))
137
138    if command:
139        command = command[0]
140
141    common.handle_options('gcc', condition, command, options)
142
143    linker = feature.get_values('<linker-type>', options)
144    if not linker:
145        if os_name() == 'OSF':
146            linker = 'osf'
147        elif os_name() == 'HPUX':
148            linker = 'hpux' ;
149        else:
150            linker = 'gnu'
151
152    init_link_flags('gcc', linker, condition)
153
154    # If gcc is installed in non-standard location, we'd need to add
155    # LD_LIBRARY_PATH when running programs created with it (for unit-test/run
156    # rules).
157    if command:
158        # On multilib 64-bit boxes, there are both 32-bit and 64-bit libraries
159        # and all must be added to LD_LIBRARY_PATH. The linker will pick the
160        # right ones. Note that we don't provide a clean way to build 32-bit
161        # binary with 64-bit compiler, but user can always pass -m32 manually.
162        lib_path = [os.path.join(root, 'bin'),
163                    os.path.join(root, 'lib'),
164                    os.path.join(root, 'lib32'),
165                    os.path.join(root, 'lib64')]
166        if debug():
167            print 'notice: using gcc libraries ::', condition, '::', lib_path
168        toolset.flags('gcc.link', 'RUN_PATH', condition, lib_path)
169
170    # If it's not a system gcc install we should adjust the various programs as
171    # needed to prefer using the install specific versions. This is essential
172    # for correct use of MinGW and for cross-compiling.
173
174    # - The archive builder.
175    archiver = common.get_invocation_command('gcc',
176            'ar', feature.get_values('<archiver>', options), [bin], path_last=True)
177    toolset.flags('gcc.archive', '.AR', condition, [archiver])
178    if debug():
179        print 'notice: using gcc archiver ::', condition, '::', archiver
180
181    # - Ranlib
182    ranlib = common.get_invocation_command('gcc',
183            'ranlib', feature.get_values('<ranlib>', options), [bin], path_last=True)
184    toolset.flags('gcc.archive', '.RANLIB', condition, [ranlib])
185    if debug():
186        print 'notice: using gcc archiver ::', condition, '::', ranlib
187
188    # - The resource compiler.
189    rc_command = common.get_invocation_command_nodefault('gcc',
190            'windres', feature.get_values('<rc>', options), [bin], path_last=True)
191    rc_type = feature.get_values('<rc-type>', options)
192
193    if not rc_type:
194        rc_type = 'windres'
195
196    if not rc_command:
197        # If we can't find an RC compiler we fallback to a null RC compiler that
198        # creates empty object files. This allows the same Jamfiles to work
199        # across the board. The null RC uses the assembler to create the empty
200        # objects, so configure that.
201        rc_command = common.get_invocation_command('gcc', 'as', [], [bin], path_last=True)
202        rc_type = 'null'
203    rc.configure([rc_command], condition, ['<rc-type>' + rc_type])
204
205###if [ os.name ] = NT
206###{
207###    # This causes single-line command invocation to not go through .bat files,
208###    # thus avoiding command-line length limitations.
209###    JAMSHELL = % ;
210###}
211
212#FIXME: when register_c_compiler is moved to
213# generators, these should be updated
214builtin.register_c_compiler('gcc.compile.c++.preprocess', ['CPP'], ['PREPROCESSED_CPP'], ['<toolset>gcc'])
215builtin.register_c_compiler('gcc.compile.c.preprocess', ['C'], ['PREPROCESSED_C'], ['<toolset>gcc'])
216builtin.register_c_compiler('gcc.compile.c++', ['CPP'], ['OBJ'], ['<toolset>gcc'])
217builtin.register_c_compiler('gcc.compile.c', ['C'], ['OBJ'], ['<toolset>gcc'])
218builtin.register_c_compiler('gcc.compile.asm', ['ASM'], ['OBJ'], ['<toolset>gcc'])
219
220# pch support
221
222# The compiler looks for a precompiled header in each directory just before it
223# looks for the include file in that directory. The name searched for is the
224# name specified in the #include directive with ".gch" suffix appended. The
225# logic in gcc-pch-generator will make sure that BASE_PCH suffix is appended to
226# full name of the header.
227
228type.set_generated_target_suffix('PCH', ['<toolset>gcc'], 'gch')
229
230# GCC-specific pch generator.
231class GccPchGenerator(pch.PchGenerator):
232
233    # Inherit the __init__ method
234
235    def run_pch(self, project, name, prop_set, sources):
236        # Find the header in sources. Ignore any CPP sources.
237        header = None
238        for s in sources:
239            if type.is_derived(s.type(), 'H'):
240                header = s
241
242        # Error handling: Base header file name should be the same as the base
243        # precompiled header name.
244        header_name = header.name()
245        header_basename = os.path.basename(header_name).rsplit('.', 1)[0]
246        if header_basename != name:
247            location = project.project_module
248            ###FIXME:
249            raise Exception()
250            ### errors.user-error "in" $(location)": pch target name `"$(name)"' should be the same as the base name of header file `"$(header-name)"'" ;
251
252        pch_file = Generator.run(self, project, name, prop_set, [header])
253
254        # return result of base class and pch-file property as usage-requirements
255        # FIXME: what about multiple results from generator.run?
256        return (property_set.create([Property('pch-file', pch_file[0]),
257                                     Property('cflags', '-Winvalid-pch')]),
258                pch_file)
259
260    # Calls the base version specifying source's name as the name of the created
261    # target. As result, the PCH will be named whatever.hpp.gch, and not
262    # whatever.gch.
263    def generated_targets(self, sources, prop_set, project, name = None):
264        name = sources[0].name()
265        return Generator.generated_targets(self, sources,
266            prop_set, project, name)
267
268# Note: the 'H' source type will catch both '.h' header and '.hpp' header. The
269# latter have HPP type, but HPP type is derived from H. The type of compilation
270# is determined entirely by the destination type.
271generators.register(GccPchGenerator('gcc.compile.c.pch', False, ['H'], ['C_PCH'], ['<pch>on', '<toolset>gcc' ]))
272generators.register(GccPchGenerator('gcc.compile.c++.pch', False, ['H'], ['CPP_PCH'], ['<pch>on', '<toolset>gcc' ]))
273
274# Override default do-nothing generators.
275generators.override('gcc.compile.c.pch', 'pch.default-c-pch-generator')
276generators.override('gcc.compile.c++.pch', 'pch.default-cpp-pch-generator')
277
278flags('gcc.compile', 'PCH_FILE', ['<pch>on'], ['<pch-file>'])
279
280# Declare flags and action for compilation
281flags('gcc.compile', 'OPTIONS', ['<optimization>off'], ['-O0'])
282flags('gcc.compile', 'OPTIONS', ['<optimization>speed'], ['-O3'])
283flags('gcc.compile', 'OPTIONS', ['<optimization>space'], ['-Os'])
284
285flags('gcc.compile', 'OPTIONS', ['<inlining>off'], ['-fno-inline'])
286flags('gcc.compile', 'OPTIONS', ['<inlining>on'], ['-Wno-inline'])
287flags('gcc.compile', 'OPTIONS', ['<inlining>full'], ['-finline-functions', '-Wno-inline'])
288
289flags('gcc.compile', 'OPTIONS', ['<warnings>off'], ['-w'])
290flags('gcc.compile', 'OPTIONS', ['<warnings>on'], ['-Wall'])
291flags('gcc.compile', 'OPTIONS', ['<warnings>all'], ['-Wall', '-pedantic'])
292flags('gcc.compile', 'OPTIONS', ['<warnings-as-errors>on'], ['-Werror'])
293
294flags('gcc.compile', 'OPTIONS', ['<debug-symbols>on'], ['-g'])
295flags('gcc.compile', 'OPTIONS', ['<profiling>on'], ['-pg'])
296
297flags('gcc.compile.c++', 'OPTIONS', ['<rtti>off'], ['-fno-rtti'])
298flags('gcc.compile.c++', 'OPTIONS', ['<exception-handling>off'], ['-fno-exceptions'])
299
300# On cygwin and mingw, gcc generates position independent code by default, and
301# warns if -fPIC is specified. This might not be the right way of checking if
302# we're using cygwin. For example, it's possible to run cygwin gcc from NT
303# shell, or using crosscompiling. But we'll solve that problem when it's time.
304# In that case we'll just add another parameter to 'init' and move this login
305# inside 'init'.
306if not os_name () in ['CYGWIN', 'NT']:
307    # This logic will add -fPIC for all compilations:
308    #
309    # lib a : a.cpp b ;
310    # obj b : b.cpp ;
311    # exe c : c.cpp a d ;
312    # obj d : d.cpp ;
313    #
314    # This all is fine, except that 'd' will be compiled with -fPIC even though
315    # it's not needed, as 'd' is used only in exe. However, it's hard to detect
316    # where a target is going to be used. Alternative, we can set -fPIC only
317    # when main target type is LIB but than 'b' will be compiled without -fPIC.
318    # In x86-64 that will lead to link errors. So, compile everything with
319    # -fPIC.
320    #
321    # Yet another alternative would be to create propagated <sharedable>
322    # feature, and set it when building shared libraries, but that's hard to
323    # implement and will increase target path length even more.
324    flags('gcc.compile', 'OPTIONS', ['<link>shared'], ['-fPIC'])
325
326if os_name() != 'NT' and os_name() != 'OSF' and os_name() != 'HPUX':
327    # OSF does have an option called -soname but it doesn't seem to work as
328    # expected, therefore it has been disabled.
329    HAVE_SONAME   = ''
330    SONAME_OPTION = '-h'
331
332
333flags('gcc.compile', 'USER_OPTIONS', [], ['<cflags>'])
334flags('gcc.compile.c++', 'USER_OPTIONS',[], ['<cxxflags>'])
335flags('gcc.compile', 'DEFINES', [], ['<define>'])
336flags('gcc.compile', 'INCLUDES', [], ['<include>'])
337
338engine = get_manager().engine()
339
340engine.register_action('gcc.compile.c++.pch',
341    '"$(CONFIG_COMMAND)" -x c++-header $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"')
342
343engine.register_action('gcc.compile.c.pch',
344    '"$(CONFIG_COMMAND)" -x c-header $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"')
345
346
347def gcc_compile_cpp(targets, sources, properties):
348    # Some extensions are compiled as C++ by default. For others, we need to
349    # pass -x c++. We could always pass -x c++ but distcc does not work with it.
350    extension = os.path.splitext (sources [0]) [1]
351    lang = ''
352    if not extension in ['.cc', '.cp', '.cxx', '.cpp', '.c++', '.C']:
353        lang = '-x c++'
354    get_manager().engine().set_target_variable (targets, 'LANG', lang)
355    engine.add_dependency(targets, bjam.call('get-target-variable', targets, 'PCH_FILE'))
356
357def gcc_compile_c(targets, sources, properties):
358    engine = get_manager().engine()
359    # If we use the name g++ then default file suffix -> language mapping does
360    # not work. So have to pass -x option. Maybe, we can work around this by
361    # allowing the user to specify both C and C++ compiler names.
362    #if $(>:S) != .c
363    #{
364    engine.set_target_variable (targets, 'LANG', '-x c')
365    #}
366    engine.add_dependency(targets, bjam.call('get-target-variable', targets, 'PCH_FILE'))
367
368engine.register_action(
369    'gcc.compile.c++',
370    '"$(CONFIG_COMMAND)" $(LANG) -ftemplate-depth-128 $(OPTIONS) ' +
371        '$(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" ' +
372        '-c -o "$(<:W)" "$(>:W)"',
373    function=gcc_compile_cpp,
374    bound_list=['PCH_FILE'])
375
376engine.register_action(
377    'gcc.compile.c',
378    '"$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) ' +
379        '-I"$(PCH_FILE:D)" -I"$(INCLUDES)" -c -o "$(<)" "$(>)"',
380    function=gcc_compile_c,
381    bound_list=['PCH_FILE'])
382
383engine.register_action(
384    'gcc.compile.c++.preprocess',
385    function=gcc_compile_cpp,
386    bound_list=['PCH_FILE'],
387    command="""
388    $(CONFIG_COMMAND) $(LANG) -ftemplate-depth-$(TEMPLATE_DEPTH) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" "$(>:W)" -E >"$(<:W)"
389    """
390)
391
392engine.register_action(
393    'gcc.compile.c.preprocess',
394    function=gcc_compile_c,
395    bound_list=['PCH_FILE'],
396    command="""
397    $(CONFIG_COMMAND) $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" "$(>)" -E >$(<)
398    """
399)
400
401def gcc_compile_asm(targets, sources, properties):
402    get_manager().engine().set_target_variable(targets, 'LANG', '-x assembler-with-cpp')
403
404engine.register_action(
405    'gcc.compile.asm',
406    '"$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"',
407    function=gcc_compile_asm)
408
409
410class GccLinkingGenerator(unix.UnixLinkingGenerator):
411    """
412        The class which check that we don't try to use the <runtime-link>static
413        property while creating or using shared library, since it's not supported by
414        gcc/libc.
415    """
416    def run(self, project, name, ps, sources):
417        # TODO: Replace this with the use of a target-os property.
418
419        no_static_link = False
420        if bjam.variable('UNIX'):
421            no_static_link = True;
422        ##FIXME: what does this mean?
423##        {
424##            switch [ modules.peek : JAMUNAME ]
425##            {
426##                case * : no-static-link = true ;
427##            }
428##        }
429
430        reason = None
431        if no_static_link and ps.get('runtime-link') == 'static':
432            if ps.get('link') == 'shared':
433                reason = "On gcc, DLL can't be build with '<runtime-link>static'."
434            elif type.is_derived(self.target_types[0], 'EXE'):
435                for s in sources:
436                    source_type = s.type()
437                    if source_type and type.is_derived(source_type, 'SHARED_LIB'):
438                        reason = "On gcc, using DLLS together with the " +\
439                                 "<runtime-link>static options is not possible "
440        if reason:
441            print 'warning:', reason
442            print 'warning:',\
443                "It is suggested to use '<runtime-link>static' together",\
444                "with '<link>static'." ;
445            return
446        else:
447            generated_targets = unix.UnixLinkingGenerator.run(self, project,
448                name, ps, sources)
449            return generated_targets
450
451if on_windows():
452    flags('gcc.link.dll', '.IMPLIB-COMMAND', [], ['-Wl,--out-implib,'])
453    generators.register(
454        GccLinkingGenerator('gcc.link', True,
455            ['OBJ', 'SEARCHED_LIB', 'STATIC_LIB', 'IMPORT_LIB'],
456            [ 'EXE' ],
457            [ '<toolset>gcc' ]))
458    generators.register(
459        GccLinkingGenerator('gcc.link.dll', True,
460            ['OBJ', 'SEARCHED_LIB', 'STATIC_LIB', 'IMPORT_LIB'],
461            ['IMPORT_LIB', 'SHARED_LIB'],
462            ['<toolset>gcc']))
463else:
464    generators.register(
465        GccLinkingGenerator('gcc.link', True,
466            ['LIB', 'OBJ'],
467            ['EXE'],
468            ['<toolset>gcc']))
469    generators.register(
470        GccLinkingGenerator('gcc.link.dll', True,
471            ['LIB', 'OBJ'],
472            ['SHARED_LIB'],
473            ['<toolset>gcc']))
474
475# Declare flags for linking.
476# First, the common flags.
477flags('gcc.link', 'OPTIONS', ['<debug-symbols>on'], ['-g'])
478flags('gcc.link', 'OPTIONS', ['<profiling>on'], ['-pg'])
479flags('gcc.link', 'USER_OPTIONS', [], ['<linkflags>'])
480flags('gcc.link', 'LINKPATH', [], ['<library-path>'])
481flags('gcc.link', 'FINDLIBS-ST', [], ['<find-static-library>'])
482flags('gcc.link', 'FINDLIBS-SA', [], ['<find-shared-library>'])
483flags('gcc.link', 'LIBRARIES', [], ['<library-file>'])
484
485# For <runtime-link>static we made sure there are no dynamic libraries in the
486# link. On HP-UX not all system libraries exist as archived libraries (for
487# example, there is no libunwind.a), so, on this platform, the -static option
488# cannot be specified.
489if os_name() != 'HPUX':
490    flags('gcc.link', 'OPTIONS', ['<runtime-link>static'], ['-static'])
491
492# Now, the vendor specific flags.
493# The parameter linker can be either gnu, darwin, osf, hpux or sun.
494def init_link_flags(toolset, linker, condition):
495    """
496        Now, the vendor specific flags.
497        The parameter linker can be either gnu, darwin, osf, hpux or sun.
498    """
499    toolset_link = toolset + '.link'
500    if linker == 'gnu':
501        # Strip the binary when no debugging is needed. We use --strip-all flag
502        # as opposed to -s since icc (intel's compiler) is generally
503        # option-compatible with and inherits from the gcc toolset, but does not
504        # support -s.
505
506        # FIXME: what does unchecked translate to?
507        flags(toolset_link, 'OPTIONS', map(lambda x: x + '/<debug-symbols>off', condition), ['-Wl,--strip-all'])  # : unchecked ;
508        flags(toolset_link, 'RPATH',       condition,                      ['<dll-path>'])       # : unchecked ;
509        flags(toolset_link, 'RPATH_LINK',  condition,                      ['<xdll-path>'])      # : unchecked ;
510        flags(toolset_link, 'START-GROUP', condition,                      ['-Wl,--start-group'])# : unchecked ;
511        flags(toolset_link, 'END-GROUP',   condition,                      ['-Wl,--end-group'])  # : unchecked ;
512
513        # gnu ld has the ability to change the search behaviour for libraries
514        # referenced by -l switch. These modifiers are -Bstatic and -Bdynamic
515        # and change search for -l switches that follow them. The following list
516        # shows the tried variants.
517        # The search stops at the first variant that has a match.
518        # *nix: -Bstatic -lxxx
519        #    libxxx.a
520        #
521        # *nix: -Bdynamic -lxxx
522        #    libxxx.so
523        #    libxxx.a
524        #
525        # windows (mingw,cygwin) -Bstatic -lxxx
526        #    libxxx.a
527        #    xxx.lib
528        #
529        # windows (mingw,cygwin) -Bdynamic -lxxx
530        #    libxxx.dll.a
531        #    xxx.dll.a
532        #    libxxx.a
533        #    xxx.lib
534        #    cygxxx.dll (*)
535        #    libxxx.dll
536        #    xxx.dll
537        #    libxxx.a
538        #
539        # (*) This is for cygwin
540        # Please note that -Bstatic and -Bdynamic are not a guarantee that a
541        # static or dynamic lib indeed gets linked in. The switches only change
542        # search patterns!
543
544        # On *nix mixing shared libs with static runtime is not a good idea.
545        flags(toolset_link, 'FINDLIBS-ST-PFX',
546              map(lambda x: x + '/<runtime-link>shared', condition),
547            ['-Wl,-Bstatic']) # : unchecked ;
548        flags(toolset_link, 'FINDLIBS-SA-PFX',
549              map(lambda x: x + '/<runtime-link>shared', condition),
550            ['-Wl,-Bdynamic']) # : unchecked ;
551
552        # On windows allow mixing of static and dynamic libs with static
553        # runtime.
554        flags(toolset_link, 'FINDLIBS-ST-PFX',
555              map(lambda x: x + '/<runtime-link>static/<target-os>windows', condition),
556              ['-Wl,-Bstatic']) # : unchecked ;
557        flags(toolset_link, 'FINDLIBS-SA-PFX',
558              map(lambda x: x + '/<runtime-link>static/<target-os>windows', condition),
559              ['-Wl,-Bdynamic']) # : unchecked ;
560        flags(toolset_link, 'OPTIONS',
561              map(lambda x: x + '/<runtime-link>static/<target-os>windows', condition),
562              ['-Wl,-Bstatic']) # : unchecked ;
563
564    elif linker == 'darwin':
565        # On Darwin, the -s option to ld does not work unless we pass -static,
566        # and passing -static unconditionally is a bad idea. So, don't pass -s.
567        # at all, darwin.jam will use separate 'strip' invocation.
568        flags(toolset_link, 'RPATH', condition, ['<dll-path>']) # : unchecked ;
569        flags(toolset_link, 'RPATH_LINK', condition, ['<xdll-path>']) # : unchecked ;
570
571    elif linker == 'osf':
572        # No --strip-all, just -s.
573        flags(toolset_link, 'OPTIONS', map(lambda x: x + '/<debug-symbols>off', condition), ['-Wl,-s'])
574            # : unchecked ;
575        flags(toolset_link, 'RPATH', condition, ['<dll-path>']) # : unchecked ;
576        # This does not supports -R.
577        flags(toolset_link, 'RPATH_OPTION', condition, ['-rpath']) # : unchecked ;
578        # -rpath-link is not supported at all.
579
580    elif linker == 'sun':
581        flags(toolset_link, 'OPTIONS', map(lambda x: x + '/<debug-symbols>off', condition), ['-Wl,-s'])
582            # : unchecked ;
583        flags(toolset_link, 'RPATH', condition, ['<dll-path>']) # : unchecked ;
584        # Solaris linker does not have a separate -rpath-link, but allows to use
585        # -L for the same purpose.
586        flags(toolset_link, 'LINKPATH', condition, ['<xdll-path>']) # : unchecked ;
587
588        # This permits shared libraries with non-PIC code on Solaris.
589        # VP, 2004/09/07: Now that we have -fPIC hardcode in link.dll, the
590        # following is not needed. Whether -fPIC should be hardcoded, is a
591        # separate question.
592        # AH, 2004/10/16: it is still necessary because some tests link against
593        # static libraries that were compiled without PIC.
594        flags(toolset_link, 'OPTIONS', map(lambda x: x + '/<link>shared', condition), ['-mimpure-text'])
595            # : unchecked ;
596
597    elif linker == 'hpux':
598        flags(toolset_link, 'OPTIONS', map(lambda x: x + '/<debug-symbols>off', condition),
599            ['-Wl,-s']) # : unchecked ;
600        flags(toolset_link, 'OPTIONS', map(lambda x: x + '/<link>shared', condition),
601            ['-fPIC']) # : unchecked ;
602
603    else:
604        # FIXME:
605        errors.user_error(
606        "$(toolset) initialization: invalid linker '$(linker)' " +
607        "The value '$(linker)' specified for <linker> is not recognized. " +
608        "Possible values are 'gnu', 'darwin', 'osf', 'hpux' or 'sun'")
609
610# Declare actions for linking.
611def gcc_link(targets, sources, properties):
612    engine = get_manager().engine()
613    engine.set_target_variable(targets, 'SPACE', ' ')
614    # Serialize execution of the 'link' action, since running N links in
615    # parallel is just slower. For now, serialize only gcc links, it might be a
616    # good idea to serialize all links.
617    engine.set_target_variable(targets, 'JAM_SEMAPHORE', '<s>gcc-link-semaphore')
618
619engine.register_action(
620    'gcc.link',
621    '"$(CONFIG_COMMAND)" -L"$(LINKPATH)" ' +
622        '-Wl,$(RPATH_OPTION:E=-R)$(SPACE)-Wl,"$(RPATH)" ' +
623        '-Wl,-rpath-link$(SPACE)-Wl,"$(RPATH_LINK)" -o "$(<)" ' +
624        '$(START-GROUP) "$(>)" "$(LIBRARIES)" $(FINDLIBS-ST-PFX) ' +
625        '-l$(FINDLIBS-ST) $(FINDLIBS-SA-PFX) -l$(FINDLIBS-SA) $(END-GROUP) ' +
626        '$(OPTIONS) $(USER_OPTIONS)',
627    function=gcc_link,
628    bound_list=['LIBRARIES'])
629
630# Default value. Mostly for the sake of intel-linux that inherits from gcc, but
631# does not have the same logic to set the .AR variable. We can put the same
632# logic in intel-linux, but that's hardly worth the trouble as on Linux, 'ar' is
633# always available.
634__AR = 'ar'
635
636flags('gcc.archive', 'AROPTIONS', [], ['<archiveflags>'])
637
638def gcc_archive(targets, sources, properties):
639    # Always remove archive and start again. Here's rationale from
640    #
641    # Andre Hentz:
642    #
643    # I had a file, say a1.c, that was included into liba.a. I moved a1.c to
644    # a2.c, updated my Jamfiles and rebuilt. My program was crashing with absurd
645    # errors. After some debugging I traced it back to the fact that a1.o was
646    # *still* in liba.a
647    #
648    # Rene Rivera:
649    #
650    # Originally removing the archive was done by splicing an RM onto the
651    # archive action. That makes archives fail to build on NT when they have
652    # many files because it will no longer execute the action directly and blow
653    # the line length limit. Instead we remove the file in a different action,
654    # just before building the archive.
655    clean = targets[0] + '(clean)'
656    bjam.call('TEMPORARY', clean)
657    bjam.call('NOCARE', clean)
658    engine = get_manager().engine()
659    engine.set_target_variable('LOCATE', clean, bjam.call('get-target-variable', targets, 'LOCATE'))
660    engine.add_dependency(clean, sources)
661    engine.add_dependency(targets, clean)
662    engine.set_update_action('common.RmTemps', clean, targets)
663
664# Declare action for creating static libraries.
665# The letter 'r' means to add files to the archive with replacement. Since we
666# remove archive, we don't care about replacement, but there's no option "add
667# without replacement".
668# The letter 'c' suppresses the warning in case the archive does not exists yet.
669# That warning is produced only on some platforms, for whatever reasons.
670engine.register_action('gcc.archive',
671                       '''"$(.AR)" $(AROPTIONS) rc "$(<)" "$(>)"
672                       "$(.RANLIB)" "$(<)"
673                       ''',
674                       function=gcc_archive,
675                       flags=['piecemeal'])
676
677def gcc_link_dll(targets, sources, properties):
678    engine = get_manager().engine()
679    engine.set_target_variable(targets, 'SPACE', ' ')
680    engine.set_target_variable(targets, 'JAM_SEMAPHORE', '<s>gcc-link-semaphore')
681    engine.set_target_variable(targets, "HAVE_SONAME", HAVE_SONAME)
682    engine.set_target_variable(targets, "SONAME_OPTION", SONAME_OPTION)
683
684engine.register_action(
685    'gcc.link.dll',
686    # Differ from 'link' above only by -shared.
687    '"$(CONFIG_COMMAND)" -L"$(LINKPATH)" ' +
688        '-Wl,$(RPATH_OPTION:E=-R)$(SPACE)-Wl,"$(RPATH)" ' +
689        '"$(.IMPLIB-COMMAND)$(<[1])" -o "$(<[-1])" ' +
690        '$(HAVE_SONAME)-Wl,$(SONAME_OPTION)$(SPACE)-Wl,$(<[-1]:D=) ' +
691        '-shared $(START-GROUP) "$(>)" "$(LIBRARIES)" $(FINDLIBS-ST-PFX) ' +
692        '-l$(FINDLIBS-ST) $(FINDLIBS-SA-PFX) -l$(FINDLIBS-SA) $(END-GROUP) ' +
693        '$(OPTIONS) $(USER_OPTIONS)',
694    function = gcc_link_dll,
695    bound_list=['LIBRARIES'])
696
697# Set up threading support. It's somewhat contrived, so perform it at the end,
698# to avoid cluttering other code.
699
700if on_windows():
701    flags('gcc', 'OPTIONS', ['<threading>multi'], ['-mthreads'])
702elif bjam.variable('UNIX'):
703    jamuname = bjam.variable('JAMUNAME')
704    host_os_name = jamuname[0]
705    if host_os_name.startswith('SunOS'):
706        flags('gcc', 'OPTIONS', ['<threading>multi'], ['-pthreads'])
707        flags('gcc', 'FINDLIBS-SA', [], ['rt'])
708    elif host_os_name == 'BeOS':
709        # BeOS has no threading options, don't set anything here.
710        pass
711    elif host_os_name == 'Haiku':
712        flags('gcc', 'OPTIONS', ['<threading>multi'], ['-lroot'])
713        # there is no -lrt on Haiku, and -pthread is implicit
714    elif host_os_name.endswith('BSD'):
715        flags('gcc', 'OPTIONS', ['<threading>multi'], ['-pthread'])
716        # there is no -lrt on BSD
717    elif host_os_name == 'DragonFly':
718        flags('gcc', 'OPTIONS', ['<threading>multi'], ['-pthread'])
719        # there is no -lrt on BSD - DragonFly is a FreeBSD variant,
720        # which anoyingly doesn't say it's a *BSD.
721    elif host_os_name == 'IRIX':
722        # gcc on IRIX does not support multi-threading, don't set anything here.
723        pass
724    elif host_os_name == 'Darwin':
725        # Darwin has no threading options, don't set anything here.
726        pass
727    else:
728        flags('gcc', 'OPTIONS', ['<threading>multi'], ['-pthread'])
729        flags('gcc', 'FINDLIBS-SA', [], ['rt'])
730
731def cpu_flags(toolset, variable, architecture, instruction_set, values, default=None):
732    #FIXME: for some reason this fails.  Probably out of date feature code
733##    if default:
734##        flags(toolset, variable,
735##              ['<architecture>' + architecture + '/<instruction-set>'],
736##              values)
737    flags(toolset, variable,
738          #FIXME: same as above
739          [##'<architecture>/<instruction-set>' + instruction_set,
740           '<architecture>' + architecture + '/<instruction-set>' + instruction_set],
741          values)
742
743# Set architecture/instruction-set options.
744#
745# x86 and compatible
746flags('gcc', 'OPTIONS', ['<architecture>x86/<address-model>32'], ['-m32'])
747flags('gcc', 'OPTIONS', ['<architecture>x86/<address-model>64'], ['-m64'])
748cpu_flags('gcc', 'OPTIONS', 'x86', 'native', ['-march=native'])
749cpu_flags('gcc', 'OPTIONS', 'x86', 'i486', ['-march=i486'])
750cpu_flags('gcc', 'OPTIONS', 'x86', 'i586', ['-march=i586'])
751cpu_flags('gcc', 'OPTIONS', 'x86', 'i686', ['-march=i686'], default=True)
752cpu_flags('gcc', 'OPTIONS', 'x86', 'pentium', ['-march=pentium'])
753cpu_flags('gcc', 'OPTIONS', 'x86', 'pentium-mmx', ['-march=pentium-mmx'])
754cpu_flags('gcc', 'OPTIONS', 'x86', 'pentiumpro', ['-march=pentiumpro'])
755cpu_flags('gcc', 'OPTIONS', 'x86', 'pentium2', ['-march=pentium2'])
756cpu_flags('gcc', 'OPTIONS', 'x86', 'pentium3', ['-march=pentium3'])
757cpu_flags('gcc', 'OPTIONS', 'x86', 'pentium3m', ['-march=pentium3m'])
758cpu_flags('gcc', 'OPTIONS', 'x86', 'pentium-m', ['-march=pentium-m'])
759cpu_flags('gcc', 'OPTIONS', 'x86', 'pentium4', ['-march=pentium4'])
760cpu_flags('gcc', 'OPTIONS', 'x86', 'pentium4m', ['-march=pentium4m'])
761cpu_flags('gcc', 'OPTIONS', 'x86', 'prescott', ['-march=prescott'])
762cpu_flags('gcc', 'OPTIONS', 'x86', 'nocona', ['-march=nocona'])
763cpu_flags('gcc', 'OPTIONS', 'x86', 'core2', ['-march=core2'])
764cpu_flags('gcc', 'OPTIONS', 'x86', 'conroe', ['-march=core2'])
765cpu_flags('gcc', 'OPTIONS', 'x86', 'conroe-xe', ['-march=core2'])
766cpu_flags('gcc', 'OPTIONS', 'x86', 'conroe-l', ['-march=core2'])
767cpu_flags('gcc', 'OPTIONS', 'x86', 'allendale', ['-march=core2'])
768cpu_flags('gcc', 'OPTIONS', 'x86', 'wolfdale', ['-march=core2', '-msse4.1'])
769cpu_flags('gcc', 'OPTIONS', 'x86', 'merom', ['-march=core2'])
770cpu_flags('gcc', 'OPTIONS', 'x86', 'merom-xe', ['-march=core2'])
771cpu_flags('gcc', 'OPTIONS', 'x86', 'kentsfield', ['-march=core2'])
772cpu_flags('gcc', 'OPTIONS', 'x86', 'kentsfield-xe', ['-march=core2'])
773cpu_flags('gcc', 'OPTIONS', 'x86', 'yorksfield', ['-march=core2'])
774cpu_flags('gcc', 'OPTIONS', 'x86', 'penryn', ['-march=core2'])
775cpu_flags('gcc', 'OPTIONS', 'x86', 'corei7', ['-march=corei7'])
776cpu_flags('gcc', 'OPTIONS', 'x86', 'nehalem', ['-march=corei7'])
777cpu_flags('gcc', 'OPTIONS', 'x86', 'corei7-avx', ['-march=corei7-avx'])
778cpu_flags('gcc', 'OPTIONS', 'x86', 'sandy-bridge', ['-march=corei7-avx'])
779cpu_flags('gcc', 'OPTIONS', 'x86', 'core-avx-i', ['-march=core-avx-i'])
780cpu_flags('gcc', 'OPTIONS', 'x86', 'ivy-bridge', ['-march=core-avx-i'])
781cpu_flags('gcc', 'OPTIONS', 'x86', 'haswell', ['-march=core-avx-i', '-mavx2', '-mfma', '-mbmi', '-mbmi2', '-mlzcnt'])
782cpu_flags('gcc', 'OPTIONS', 'x86', 'broadwell', ['-march=broadwell'])
783cpu_flags('gcc', 'OPTIONS', 'x86', 'skylake', ['-march=skylake'])
784cpu_flags('gcc', 'OPTIONS', 'x86', 'skylake-avx512', ['-march=skylake-avx512'])
785cpu_flags('gcc', 'OPTIONS', 'x86', 'cannonlake', ['-march=skylake-avx512', '-mavx512vbmi', '-mavx512ifma', '-msha'])
786cpu_flags('gcc', 'OPTIONS', 'x86', 'icelake-client', ['-march=icelake-client'])
787cpu_flags('gcc', 'OPTIONS', 'x86', 'icelake-server', ['-march=icelake-server'])
788cpu_flags('gcc', 'OPTIONS', 'x86', 'cascadelake', ['-march=skylake-avx512', '-mavx512vnni'])
789cpu_flags('gcc', 'OPTIONS', 'x86', 'cooperlake', ['-march=cooperlake'])
790cpu_flags('gcc', 'OPTIONS', 'x86', 'tigerlake', ['-march=tigerlake'])
791cpu_flags('gcc', 'OPTIONS', 'x86', 'k6', ['-march=k6'])
792cpu_flags('gcc', 'OPTIONS', 'x86', 'k6-2', ['-march=k6-2'])
793cpu_flags('gcc', 'OPTIONS', 'x86', 'k6-3', ['-march=k6-3'])
794cpu_flags('gcc', 'OPTIONS', 'x86', 'athlon', ['-march=athlon'])
795cpu_flags('gcc', 'OPTIONS', 'x86', 'athlon-tbird', ['-march=athlon-tbird'])
796cpu_flags('gcc', 'OPTIONS', 'x86', 'athlon-4', ['-march=athlon-4'])
797cpu_flags('gcc', 'OPTIONS', 'x86', 'athlon-xp', ['-march=athlon-xp'])
798cpu_flags('gcc', 'OPTIONS', 'x86', 'athlon-mp', ['-march=athlon-mp'])
799##
800cpu_flags('gcc', 'OPTIONS', 'x86', 'k8', ['-march=k8'])
801cpu_flags('gcc', 'OPTIONS', 'x86', 'opteron', ['-march=opteron'])
802cpu_flags('gcc', 'OPTIONS', 'x86', 'athlon64', ['-march=athlon64'])
803cpu_flags('gcc', 'OPTIONS', 'x86', 'athlon-fx', ['-march=athlon-fx'])
804cpu_flags('gcc', 'OPTIONS', 'x86', 'k8-sse3', ['-march=k8-sse3'])
805cpu_flags('gcc', 'OPTIONS', 'x86', 'opteron-sse3', ['-march=opteron-sse3'])
806cpu_flags('gcc', 'OPTIONS', 'x86', 'athlon64-sse3', ['-march=athlon64-sse3'])
807cpu_flags('gcc', 'OPTIONS', 'x86', 'amdfam10', ['-march=amdfam10'])
808cpu_flags('gcc', 'OPTIONS', 'x86', 'barcelona', ['-march=barcelona'])
809cpu_flags('gcc', 'OPTIONS', 'x86', 'bdver1', ['-march=bdver1'])
810cpu_flags('gcc', 'OPTIONS', 'x86', 'bdver2', ['-march=bdver2'])
811cpu_flags('gcc', 'OPTIONS', 'x86', 'bdver3', ['-march=bdver3'])
812cpu_flags('gcc', 'OPTIONS', 'x86', 'btver1', ['-march=btver1'])
813cpu_flags('gcc', 'OPTIONS', 'x86', 'btver2', ['-march=btver2'])
814cpu_flags('gcc', 'OPTIONS', 'x86', 'znver1', ['-march=znver1'])
815cpu_flags('gcc', 'OPTIONS', 'x86', 'znver2', ['-march=znver2'])
816cpu_flags('gcc', 'OPTIONS', 'x86', 'winchip-c6', ['-march=winchip-c6'])
817cpu_flags('gcc', 'OPTIONS', 'x86', 'winchip2', ['-march=winchip2'])
818cpu_flags('gcc', 'OPTIONS', 'x86', 'c3', ['-march=c3'])
819cpu_flags('gcc', 'OPTIONS', 'x86', 'c3-2', ['-march=c3-2'])
820cpu_flags('gcc', 'OPTIONS', 'x86', 'c7', ['-march=c7'])
821##
822cpu_flags('gcc', 'OPTIONS', 'x86', 'atom', ['-march=atom'])
823# Sparc
824flags('gcc', 'OPTIONS', ['<architecture>sparc/<address-model>32'], ['-m32'])
825flags('gcc', 'OPTIONS', ['<architecture>sparc/<address-model>64'], ['-m64'])
826cpu_flags('gcc', 'OPTIONS', 'sparc', 'v7', ['-mcpu=v7'], default=True)
827cpu_flags('gcc', 'OPTIONS', 'sparc', 'cypress', ['-mcpu=cypress'])
828cpu_flags('gcc', 'OPTIONS', 'sparc', 'v8', ['-mcpu=v8'])
829cpu_flags('gcc', 'OPTIONS', 'sparc', 'supersparc', ['-mcpu=supersparc'])
830cpu_flags('gcc', 'OPTIONS', 'sparc', 'sparclite', ['-mcpu=sparclite'])
831cpu_flags('gcc', 'OPTIONS', 'sparc', 'hypersparc', ['-mcpu=hypersparc'])
832cpu_flags('gcc', 'OPTIONS', 'sparc', 'sparclite86x', ['-mcpu=sparclite86x'])
833cpu_flags('gcc', 'OPTIONS', 'sparc', 'f930', ['-mcpu=f930'])
834cpu_flags('gcc', 'OPTIONS', 'sparc', 'f934', ['-mcpu=f934'])
835cpu_flags('gcc', 'OPTIONS', 'sparc', 'sparclet', ['-mcpu=sparclet'])
836cpu_flags('gcc', 'OPTIONS', 'sparc', 'tsc701', ['-mcpu=tsc701'])
837cpu_flags('gcc', 'OPTIONS', 'sparc', 'v9', ['-mcpu=v9'])
838cpu_flags('gcc', 'OPTIONS', 'sparc', 'ultrasparc', ['-mcpu=ultrasparc'])
839cpu_flags('gcc', 'OPTIONS', 'sparc', 'ultrasparc3', ['-mcpu=ultrasparc3'])
840# RS/6000 & PowerPC
841flags('gcc', 'OPTIONS', ['<architecture>power/<address-model>32'], ['-m32'])
842flags('gcc', 'OPTIONS', ['<architecture>power/<address-model>64'], ['-m64'])
843cpu_flags('gcc', 'OPTIONS', 'power', '403', ['-mcpu=403'])
844cpu_flags('gcc', 'OPTIONS', 'power', '505', ['-mcpu=505'])
845cpu_flags('gcc', 'OPTIONS', 'power', '601', ['-mcpu=601'])
846cpu_flags('gcc', 'OPTIONS', 'power', '602', ['-mcpu=602'])
847cpu_flags('gcc', 'OPTIONS', 'power', '603', ['-mcpu=603'])
848cpu_flags('gcc', 'OPTIONS', 'power', '603e', ['-mcpu=603e'])
849cpu_flags('gcc', 'OPTIONS', 'power', '604', ['-mcpu=604'])
850cpu_flags('gcc', 'OPTIONS', 'power', '604e', ['-mcpu=604e'])
851cpu_flags('gcc', 'OPTIONS', 'power', '620', ['-mcpu=620'])
852cpu_flags('gcc', 'OPTIONS', 'power', '630', ['-mcpu=630'])
853cpu_flags('gcc', 'OPTIONS', 'power', '740', ['-mcpu=740'])
854cpu_flags('gcc', 'OPTIONS', 'power', '7400', ['-mcpu=7400'])
855cpu_flags('gcc', 'OPTIONS', 'power', '7450', ['-mcpu=7450'])
856cpu_flags('gcc', 'OPTIONS', 'power', '750', ['-mcpu=750'])
857cpu_flags('gcc', 'OPTIONS', 'power', '801', ['-mcpu=801'])
858cpu_flags('gcc', 'OPTIONS', 'power', '821', ['-mcpu=821'])
859cpu_flags('gcc', 'OPTIONS', 'power', '823', ['-mcpu=823'])
860cpu_flags('gcc', 'OPTIONS', 'power', '860', ['-mcpu=860'])
861cpu_flags('gcc', 'OPTIONS', 'power', '970', ['-mcpu=970'])
862cpu_flags('gcc', 'OPTIONS', 'power', '8540', ['-mcpu=8540'])
863cpu_flags('gcc', 'OPTIONS', 'power', 'power', ['-mcpu=power'])
864cpu_flags('gcc', 'OPTIONS', 'power', 'power2', ['-mcpu=power2'])
865cpu_flags('gcc', 'OPTIONS', 'power', 'power3', ['-mcpu=power3'])
866cpu_flags('gcc', 'OPTIONS', 'power', 'power4', ['-mcpu=power4'])
867cpu_flags('gcc', 'OPTIONS', 'power', 'power5', ['-mcpu=power5'])
868cpu_flags('gcc', 'OPTIONS', 'power', 'powerpc', ['-mcpu=powerpc'])
869cpu_flags('gcc', 'OPTIONS', 'power', 'powerpc64', ['-mcpu=powerpc64'])
870cpu_flags('gcc', 'OPTIONS', 'power', 'rios', ['-mcpu=rios'])
871cpu_flags('gcc', 'OPTIONS', 'power', 'rios1', ['-mcpu=rios1'])
872cpu_flags('gcc', 'OPTIONS', 'power', 'rios2', ['-mcpu=rios2'])
873cpu_flags('gcc', 'OPTIONS', 'power', 'rsc', ['-mcpu=rsc'])
874cpu_flags('gcc', 'OPTIONS', 'power', 'rs64a', ['-mcpu=rs64'])
875cpu_flags('gcc', 'OPTIONS', 's390x',  'z196', ['-march=z196'])
876cpu_flags('gcc', 'OPTIONS', 's390x',  'zEC12', ['-march=zEC12'])
877cpu_flags('gcc', 'OPTIONS', 's390x',  'z13', ['-march=z13'])
878cpu_flags('gcc', 'OPTIONS', 's390x',  'z14', ['-march=z14'])
879cpu_flags('gcc', 'OPTIONS', 's390x',  'z15', ['-march=z15'])
880# AIX variant of RS/6000 & PowerPC
881flags('gcc', 'OPTIONS', ['<architecture>power/<address-model>32/<target-os>aix'], ['-maix32'])
882flags('gcc', 'OPTIONS', ['<architecture>power/<address-model>64/<target-os>aix'], ['-maix64'])
883flags('gcc', 'AROPTIONS', ['<architecture>power/<address-model>64/<target-os>aix'], ['-X64'])
884