• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2001 David Abrahams
2# Copyright 2002-2017 Rene Rivera
3# Copyright 2002-2003 Vladimir Prus
4# Copyright 2005 Reece H. Dunn
5# Copyright 2006 Ilya Sokolov
6# Copyright 2007 Roland Schwarz
7# Copyright 2007 Boris Gubenko
8#
9# Distributed under the Boost Software License, Version 1.0.
10#    (See accompanying file LICENSE_1_0.txt or copy at
11#          http://www.boost.org/LICENSE_1_0.txt)
12
13#| tag::doc[]
14
15[[bbv2.reference.tools.compiler.gcc]]
16= GNU C++
17
18The `gcc` module supports the http://gcc.gnu.org[GNU C++ compiler] on
19Linux, a number of Unix-like system including SunOS and on Windows
20(either http://www.cygwin.com[Cygwin] or http://www.mingw.org[MinGW]).
21
22The `gcc` module is initialized using the following syntax:
23
24----
25using gcc : [version] : [c++-compile-command] : [compiler options] ;
26----
27
28This statement may be repeated several times, if you want to configure
29several versions of the compiler.
30
31If the version is not explicitly specified, it will be automatically
32detected by running the compiler with the `-v` option. If the command is
33not specified, the `g++` binary will be searched in PATH.
34
35The following options can be provided, using
36_`<option-name>option-value syntax`_:
37
38`cflags`::
39Specifies additional compiler flags that will be used when compiling C
40sources.
41
42`cxxflags`::
43Specifies additional compiler flags that will be used when compiling C++
44sources.
45
46`compileflags`::
47Specifies additional compiler flags that will be used when compiling both C
48and C++ sources.
49
50`linkflags`::
51Specifies additional command line options that will be passed to the linker.
52
53`root`::
54Specifies root directory of the compiler installation. This option is
55necessary only if it is not possible to detect this information from the
56compiler command--for example if the specified compiler command is a user
57script.
58
59`archiver`::
60Specifies the archiver command that is used to produce static
61libraries. Normally, it is autodetected using gcc `-print-prog-name`
62option or defaulted to `ar`, but in some cases you might want to
63override it, for example to explicitly use a system version instead of
64one included with gcc.
65
66`ranlib`::
67Specifies the ranlib command that is used to generated symbol table
68for static libraries. Normally, it is autodetected using gcc
69`-print-prog-name` option or defaulted to `ranlib`, but in some cases
70you might want to override it, for example to explicitly use a system
71version instead of one included with gcc.
72
73`rc`::
74Specifies the resource compiler command that will be used with the
75version of gcc that is being configured. This setting makes sense only
76for Windows and only if you plan to use resource files. By default
77`windres` will be used.
78
79`rc-type`::
80Specifies the type of resource compiler. The value can be either
81`windres` for msvc resource compiler, or `rc` for borland's resource
82compiler.
83
84In order to compile 64-bit applications, you have to specify
85`address-model=64`, and the `instruction-set` feature should refer to a 64
86bit processor. Currently, those include `nocona`, `opteron`, `athlon64` and
87`athlon-fx`.
88
89|# # end::doc[]
90
91import "class" : new ;
92import common ;
93import cygwin ;
94import feature ;
95import fortran ;
96import generators ;
97import os ;
98import pch ;
99import property ;
100import property-set ;
101import rc ;
102import regex ;
103import sequence ;
104import set ;
105import toolset ;
106import type ;
107import unix ;
108import virtual-target ;
109import errors ;
110
111
112if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
113{
114    .debug-configuration = true ;
115}
116
117
118feature.extend toolset : gcc ;
119
120toolset.inherit-generators gcc : unix : unix.link unix.link.dll ;
121toolset.inherit-flags gcc : unix ;
122toolset.inherit-rules gcc : unix ;
123
124generators.override gcc.prebuilt : builtin.prebuilt ;
125generators.override gcc.searched-lib-generator : searched-lib-generator ;
126
127# Make gcc toolset object files use the "o" suffix on all platforms.
128type.set-generated-target-suffix OBJ : <toolset>gcc : o ;
129type.set-generated-target-suffix OBJ : <toolset>gcc <target-os>windows : o ;
130type.set-generated-target-suffix OBJ : <toolset>gcc <target-os>cygwin : o ;
131
132
133# Initializes the gcc toolset for the given version. If necessary, command may
134# be used to specify where the compiler is located. The parameter 'options' is a
135# space-delimited list of options, each one specified as
136# <option-name>option-value. Valid option names are: cxxflags, linkflags and
137# linker-type. Accepted linker-type values are aix, darwin, gnu, hpux, osf or
138# sun and the default value will be selected based on the current OS.
139# Example:
140#   using gcc : 3.4 : : <cxxflags>foo <linkflags>bar <linker-type>sun ;
141#
142# The compiler command to use is detected in three steps:
143# 1) If an explicit command is specified by the user, it will be used and must
144#    be available.
145# 2) If only a certain version is specified, it is enforced:
146#    - either the 'g++-VERSION' command must be available
147#    - or the default command 'g++' must be available and match the exact
148#      version.
149# 3) Without user-provided restrictions use default 'g++'.
150#
151rule init ( version ? : command * : options * : requirement * )
152{
153    #1): use user-provided command
154    local tool-command = ;
155    if $(command)
156    {
157        tool-command = [ common.get-invocation-command-nodefault gcc : g++ :
158            $(command) ] ;
159        if ! $(tool-command)
160        {
161            import errors ;
162            errors.error toolset gcc "initialization:"
163                : provided command '$(command)' not found
164                : initialized from [ errors.nearest-user-location ] ;
165        }
166    }
167    #2): enforce user-provided version
168    else if $(version)
169    {
170        tool-command = [ common.get-invocation-command-nodefault gcc :
171            "g++-$(version[1])" ] ;
172
173        #2.1) fallback: check whether "g++" reports the requested version
174        if ! $(tool-command)
175        {
176            tool-command = [ common.get-invocation-command-nodefault gcc : g++ ]
177                ;
178            if $(tool-command)
179            {
180                local tool-command-string = \"$(tool-command)\" ;
181                tool-command-string = $(tool-command-string:J=" ") ;
182                local tool-version = [ dump-full-version
183                    $(tool-command-string) ] ;
184                # Permit a match between a two-digit version specified by the
185                # user (e.g. 4.4) and a 3-digit version reported by gcc.
186                # Since only two digits are present in the binary name
187                # anyway, insisting that user specify the 3-digit version
188                # when configuring B2, while it is not required on
189                # the command line, would be strange.
190                local versionl = [ regex.split $(version) "[.]" ] ;
191                local tool-versionl = [ regex.split $(tool-version) "[.]" ] ;
192                if ! ( $(versionl[1]) = $(tool-versionl[1]) &&
193                   $(versionl[2]:E=$(tool-versionl[2])) = $(tool-versionl[2]) &&
194                   $(versionl[3]:E=$(tool-versionl[3])) = $(tool-versionl[3]) )
195                {
196                    import errors ;
197                    errors.error toolset gcc "initialization:"
198                        : version '$(version)' requested but
199                            'g++-$(version)' not found and version
200                            '$(tool-version)' of default '$(tool-command)'
201                            does not match
202                        : initialized from [ errors.nearest-user-location ]
203                        ;
204                    tool-command = ;
205                }
206            }
207            else
208            {
209                import errors ;
210                errors.error toolset gcc "initialization:"
211                    : version '$(version)' requested but neither
212                        'g++-$(version)' nor default 'g++' found
213                    : initialized from [ errors.nearest-user-location ] ;
214            }
215        }
216    }
217    #3) default: no command and no version specified, try using "g++"
218    else
219    {
220        tool-command = [ common.get-invocation-command-nodefault gcc : g++ ] ;
221        if ! $(tool-command)
222        {
223            import errors ;
224            errors.error toolset gcc "initialization:"
225                : no command provided, default command 'g++' not found
226                : initialized from [ errors.nearest-user-location ] ;
227        }
228    }
229
230
231    # Information about the gcc command...
232    #   The command.
233    local command = $(tool-command) ;
234    #   The 'command' variable can have multiple elements but when calling the
235    # SHELL builtin we need a single string, and we need to quote elements
236    # with spaces.
237    local command-string = \"$(command)\" ;
238    command-string = $(command-string:J=" ") ;
239    #   The root directory of the tool install.
240    local root = [ feature.get-values <root> : $(options) ] ;
241    #   The bin directory where to find the command to execute.
242    local bin ;
243    #   The compiler flavor.
244    local flavor = [ feature.get-values <flavor> : $(options) ] ;
245    #   vxworks build on windows uses csh that is neither mingw or cygwin
246    if [ feature.get-values <target-os> : $(options) ] = vxworks
247    {
248        flavor ?= vxworks ;
249    }
250    #   Autodetect the root and bin dir if not given.
251    if $(command)
252    {
253        bin ?= [ common.get-absolute-tool-path $(command[-1]) ] ;
254        root ?= $(bin:D) ;
255    }
256    local target-os ;
257    #   Autodetect the version and flavor if not given.
258    if $(command)
259    {
260        local machine = [ MATCH "^([^ ]+)" :
261            [ SHELL "$(command-string) -dumpmachine" ] ] ;
262        version ?= [ dump-version $(command-string) ] ;
263        switch $(machine:L)
264        {
265            case *mingw* : flavor ?= mingw ;
266            case *cygwin* : flavor ?= cygwin ;
267        }
268        switch $(machine:L)
269        {
270            case *mingw*  : target-os ?= windows ;
271            case *cygwin* : target-os ?= cygwin ;
272            case *linux*  : target-os ?= linux ;
273            # TODO: finish this list.
274        }
275    }
276
277    local condition ;
278    condition = [ common.check-init-parameters gcc $(requirement) : version $(version)
279        : $(condition) ] ;
280
281    common.handle-options gcc : $(condition) : $(command) : $(options) ;
282
283    # Set the default target-os for this toolset.
284    if $(target-os) && ! [ feature.get-values <target-os> : $(requirement) ]
285    {
286        local conditionx = [ regex.replace $(condition) "/" "," ] ;
287        toolset.add-defaults $(conditionx)\:<target-os>$(target-os) ;
288    }
289
290    # If gcc is installed in a non-standard location, we would need to add
291    # LD_LIBRARY_PATH when running programs created with it (for unit-test/run
292    # rules).
293    if $(command)
294    {
295        # On multilib 64-bit boxes, there are both 32-bit and 64-bit libraries
296        # and all must be added to LD_LIBRARY_PATH. The linker will pick the
297        # right onces. Note that we do not provide a clean way to build a 32-bit
298        # binary using a 64-bit compiler, but user can always pass -m32
299        # manually.
300        local lib_path = $(root)/bin $(root)/lib $(root)/lib32 $(root)/lib64 ;
301        if $(.debug-configuration)
302        {
303            ECHO "notice:" using gcc libraries "::" $(condition) "::" $(lib_path) ;
304        }
305        toolset.flags gcc.link RUN_PATH $(condition) : $(lib_path) ;
306    }
307
308    # If we are not using a system gcc installation we should adjust the various
309    # programs as needed to prefer using their installation specific versions.
310    # This is essential for correct use of MinGW and for cross-compiling.
311
312    # - Archive builder.
313    local archiver = [ common.get-invocation-command gcc
314        : [ .get-prog-name $(command-string) : ar : $(flavor) ]
315        : [ feature.get-values <archiver> : $(options) ]
316        : $(bin)
317        : search-path ] ;
318    toolset.flags gcc.archive .AR $(condition) : $(archiver[1]) ;
319    if $(.debug-configuration)
320    {
321        ECHO "notice:" using gcc archiver "::" $(condition) "::" $(archiver[1]) ;
322    }
323    local arflags = [ feature.get-values <arflags> : $(options) ] ;
324    toolset.flags gcc.archive .ARFLAGS $(condition) : $(arflags) ;
325
326    # - Ranlib.
327    local ranlib = [ common.get-invocation-command gcc
328        : [ .get-prog-name $(command-string) : ranlib : $(flavor) ]
329        : [ feature.get-values <ranlib> : $(options) ]
330        : $(bin)
331        : search-path ] ;
332    toolset.flags gcc.archive .RANLIB $(condition) : $(ranlib[1]) ;
333    if $(.debug-configuration)
334    {
335        ECHO "notice:" using gcc ranlib "::" $(condition) "::" $(ranlib[1]) ;
336    }
337
338    # - Resource compiler.
339    local rc = [ common.get-invocation-command-nodefault gcc : windres :
340        [ feature.get-values <rc> : $(options) ] : $(bin) : search-path ] ;
341    local rc-type = [ feature.get-values <rc-type> : $(options) ] ;
342    rc-type ?= windres ;
343    if ! $(rc)
344    {
345        # If we can not find an RC compiler we fallback to a null one that
346        # creates empty object files. This allows the same Jamfiles to work
347        # across the board. The null RC uses assembler to create the empty
348        # objects, so configure that.
349        rc = [ common.get-invocation-command gcc : as : : $(bin) : search-path ]
350            ;
351        rc-type = null ;
352    }
353    rc.configure $(rc) : $(condition) : <rc-type>$(rc-type) ;
354
355    toolset.flags gcc VERSION $(condition) : [ regex.split $(version) "[.]" ] ;
356
357    init-cxxstd-flags $(condition) : $(version) ;
358}
359
360if [ os.name ] = NT
361{
362    # This causes single-line command invocation to not go through .bat files,
363    # thus avoiding command-line length limitations.
364    # TODO: Set JAMSHELL on specific targets instead of globally.
365    JAMSHELL = % ;
366}
367
368local rule dump-full-version ( command-string )
369{
370    # -dumpfullversion is only supported for gcc 7+.
371    # Passing both options works, as the first one that's
372    # recognized will be used.
373    return [ MATCH "^([0-9.]+)" :
374        [ SHELL "$(command-string) -dumpfullversion -dumpversion" ] ] ;
375}
376
377local rule dump-version ( command-string )
378{
379    return [ MATCH "^([0-9.]+)" :
380        [ SHELL "$(command-string) -dumpversion" ] ] ;
381}
382
383# Uses -print-prog-name to get the name of the tool.
384# Converts the path to native form if using cygwin.
385rule .get-prog-name ( command-string : tool : flavor ? )
386{
387    local prog-name = [ NORMALIZE_PATH [ MATCH "(.*)[\n]+" :
388        [ SHELL "$(command-string) -print-prog-name=$(tool)" ] ] ] ;
389
390    if $(flavor) = cygwin && [ os.name ] = NT
391    {
392        prog-name = [ cygwin.cygwin-to-windows-path $(prog-name) ] ;
393    }
394    return $(prog-name) ;
395}
396
397###
398### Functions that set options on the targets.
399###
400
401local all-os = [ feature.values <target-os> ] ;
402
403local rule compile-link-flags ( * )
404{
405    toolset.flags gcc.compile OPTIONS $(1) : $(2) ;
406    toolset.flags gcc.link OPTIONS $(1) : $(2) ;
407}
408
409{
410    # This logic will add -fPIC for all compilations:
411    #
412    # lib a : a.cpp b ;
413    # obj b : b.cpp ;
414    # exe c : c.cpp a d ;
415    # obj d : d.cpp ;
416    #
417    # This all is fine, except that 'd' will be compiled with -fPIC even
418    # though it is not needed, as 'd' is used only in exe. However, it is
419    # hard to detect where a target is going to be used. Alternatively, we
420    # can set -fPIC only when main target type is LIB but than 'b' would be
421    # compiled without -fPIC which would lead to link errors on x86-64. So,
422    # compile everything with -fPIC.
423    #
424    # Yet another alternative would be to create a propagated <sharedable>
425    # feature and set it when building shared libraries, but that would be
426    # hard to implement and would increase the target path length even more.
427
428    # On Windows, fPIC is the default, and specifying -fPIC explicitly leads
429    # to a warning.
430    local non-windows = [ set.difference $(all-os) : cygwin windows ] ;
431    compile-link-flags <link>shared/<target-os>$(non-windows) : -fPIC ;
432}
433
434{
435    # Handle address-model
436    compile-link-flags <target-os>aix/<address-model>32 : -maix32 ;
437    compile-link-flags <target-os>aix/<address-model>64 : -maix64 ;
438
439    compile-link-flags <target-os>hpux/<address-model>32 : -milp32 ;
440    compile-link-flags <target-os>hpux/<address-model>64 : -mlp64 ;
441
442    local generic-os = [ set.difference $(all-os) : aix hpux ] ;
443    local arch = power sparc x86 ;
444    compile-link-flags <target-os>$(generic-os)/<architecture>$(arch)/<address-model>32 : -m32 ;
445    compile-link-flags <target-os>$(generic-os)/<architecture>$(arch)/<address-model>64 : -m64 ;
446}
447
448{
449    # Handle threading
450    local rule threading-flags ( * )
451    {
452        compile-link-flags <threading>multi/$(1) : $(2) ;
453        if $(3)
454        {
455            toolset.flags gcc.link FINDLIBS-SA <threading>multi/$(1) : $(3) ;
456        }
457    }
458
459    threading-flags <target-os>windows : -mthreads ;
460    threading-flags <target-os>cygwin  : -mthreads ;
461    threading-flags <target-os>solaris  : -pthreads : rt ;
462    threading-flags <target-os>qnx : -pthread ;
463
464    local bsd = [ MATCH ^(.*bsd)$ : $(all-os) ] ;
465    threading-flags <target-os>$(bsd) : -pthread ;
466
467    local no-threading = android beos haiku sgi darwin vxworks ;
468    local threading-generic-os = [ set.difference $(all-os) : $(no-threading) $(bsd) windows cygwin solaris qnx ] ;
469    threading-flags <target-os>$(threading-generic-os) : -pthread : rt ;
470}
471
472{
473    local rule cxxstd-flags ( * )
474    {
475        toolset.flags gcc.compile.c++ OPTIONS $(1) : $(2) ;
476        toolset.flags gcc.link OPTIONS $(1) : $(2) ;
477    }
478
479    local cxxstd = [ feature.values <cxxstd> ] ;
480    local dialects = [ feature.values <cxxstd-dialect> ] ;
481    .cxxstd-dialects = [ set.difference $(dialects) : gnu iso ] ;
482    # C++ latest needs to be set up on a per-toolset basis
483    for local std in [ set.difference $(cxxstd) : latest ]
484    {
485        cxxstd-flags <cxxstd>$(std)/<cxxstd-dialect>iso : -std=c++$(std) ;
486        cxxstd-flags <cxxstd>$(std)/<cxxstd-dialect>gnu : -std=gnu++$(std) ;
487        # If we see this it's probably a mistake, but
488        # toolset.flags has no way to set up diagnostics.
489        cxxstd-flags <cxxstd>$(std)/<cxxstd-dialect>$(.cxxstd-dialects) : -std=c++$(std) ;
490    }
491
492    local rule version-ge ( lhs : rhs )
493    {
494        lhs = [ regex.split $(lhs) "[.]" ] ;
495        rhs = [ regex.split $(rhs) "[.]" ] ;
496        return [ sequence.compare $(rhs) : $(lhs) : numbers.less ] ;
497    }
498    # Version specific flags
499    local rule init-cxxstd-flags ( condition * : version )
500    {
501        local std ;
502        if [ version-ge $(version) : 10 ] { std = 20 ; }
503        else if [ version-ge $(version) : 8 ] { std = 2a ; }
504        else if [ version-ge $(version) : 6 ] { std = 17 ; }
505        else if [ version-ge $(version) : 5 ] { std = 1z ; }
506        else if [ version-ge $(version) : 4.9 ] { std = 14 ; }
507        else if [ version-ge $(version) : 4.8 ] { std = 1y ; }
508        else if [ version-ge $(version) : 4.7 ] { std = 11 ; }
509        else if [ version-ge $(version) : 3.3 ] { std = 98 ; }
510        if $(std)
511        {
512            cxxstd-flags $(condition)/<cxxstd>latest/<cxxstd-dialect>iso : -std=c++$(std) ;
513            cxxstd-flags $(condition)/<cxxstd>latest/<cxxstd-dialect>gnu : -std=gnu++$(std) ;
514            cxxstd-flags $(condition)/<cxxstd>latest/<cxxstd-dialect>$(.cxxstd-dialects) : -std=c++$(std) ;
515        }
516    }
517}
518
519generators.register-c-compiler gcc.compile.c++.preprocess : CPP : PREPROCESSED_CPP : <toolset>gcc ;
520generators.register-c-compiler gcc.compile.c.preprocess   : C   : PREPROCESSED_C   : <toolset>gcc ;
521generators.register-c-compiler gcc.compile.c++ : CPP : OBJ : <toolset>gcc ;
522generators.register-c-compiler gcc.compile.c   : C   : OBJ : <toolset>gcc ;
523generators.register-c-compiler gcc.compile.asm : ASM : OBJ : <toolset>gcc ;
524
525generators.register [ new fortran-compiling-generator
526    gcc.compile.fortran : FORTRAN FORTRAN90 : OBJ : <toolset>gcc ] ;
527
528rule compile.c++.preprocess ( targets * : sources * : properties * )
529{
530    # Some extensions are compiled as C++ by default. For others, we need to
531    # pass -x c++. We could always pass -x c++ but distcc does not work with it.
532    if ! $(>:S) in .cc .cp .cxx .cpp .c++ .C
533    {
534        LANG on $(<) = "-x c++" ;
535    }
536    DEPENDS $(<) : [ on $(<) return $(PCH_FILE) ] ;
537}
538
539rule compile.c.preprocess ( targets * : sources * : properties * )
540{
541    # If we use the name g++ then default file suffix -> language mapping does
542    # not work. So have to pass -x option. Maybe, we can work around this by
543    # allowing the user to specify both C and C++ compiler names.
544    #if $(>:S) != .c
545    #{
546        LANG on $(<) = "-x c" ;
547    #}
548    DEPENDS $(<) : [ on $(<) return $(PCH_FILE) ] ;
549}
550
551rule compile.c++ ( targets * : sources * : properties * )
552{
553    # Some extensions are compiled as C++ by default. For others, we need to
554    # pass -x c++. We could always pass -x c++ but distcc does not work with it.
555    if ! $(>:S) in .cc .cp .cxx .cpp .c++ .C
556    {
557        LANG on $(<) = "-x c++" ;
558    }
559    DEPENDS $(<) : [ on $(<) return $(PCH_FILE) ] ;
560}
561
562rule compile.c ( targets * : sources * : properties * )
563{
564    # If we use the name g++ then default file suffix -> language mapping does
565    # not work. So have to pass -x option. Maybe, we can work around this by
566    # allowing the user to specify both C and C++ compiler names.
567    #if $(>:S) != .c
568    #{
569        LANG on $(<) = "-x c" ;
570    #}
571    DEPENDS $(<) : [ on $(<) return $(PCH_FILE) ] ;
572}
573
574rule compile.fortran ( targets * : sources * : properties * )
575{
576}
577
578actions compile.c++ bind PCH_FILE
579{
580    "$(CONFIG_COMMAND)" $(LANG) -ftemplate-depth-$(TEMPLATE_DEPTH) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" -include"$(FORCE_INCLUDES)" -c -o "$(<:W)" "$(>:W)"
581}
582
583actions compile.c bind PCH_FILE
584{
585    "$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" -include"$(FORCE_INCLUDES)" -c -o "$(<)" "$(>)"
586}
587
588actions compile.c++.preprocess bind PCH_FILE
589{
590    "$(CONFIG_COMMAND)" $(LANG) -ftemplate-depth-$(TEMPLATE_DEPTH) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" -include"$(FORCE_INCLUDES)" "$(>:W)" -E >"$(<:W)"
591}
592
593actions compile.c.preprocess bind PCH_FILE
594{
595    "$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" -include"$(FORCE_INCLUDES)" "$(>)" -E >$(<)
596}
597
598actions compile.fortran
599{
600    "$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(PCH_FILE:D)" -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
601}
602
603rule compile.asm ( targets * : sources * : properties * )
604{
605    LANG on $(<) = "-x assembler-with-cpp" ;
606}
607
608actions compile.asm
609{
610    "$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
611}
612
613###
614### Precompiled header use and generation.
615###
616
617# The compiler looks for a precompiled header in each directory just before it
618# looks for the include file in that directory. The name searched for is the
619# name specified in the #include directive with ".gch" suffix appended. The
620# logic in gcc-pch-generator will make sure that the BASE_PCH suffix is appended
621# to the full header name.
622
623type.set-generated-target-suffix PCH : <toolset>gcc : gch ;
624
625# GCC-specific pch generator.
626class gcc-pch-generator : pch-generator
627{
628    import project ;
629    import property-set ;
630    import type ;
631
632    rule run-pch ( project name ? : property-set : sources + )
633    {
634        # Find the header in sources. Ignore any CPP sources.
635        local header ;
636        for local s in $(sources)
637        {
638            if [ type.is-derived [ $(s).type ] H ]
639            {
640                header = $(s) ;
641            }
642        }
643
644        local path-prefix = [ path.join $(name)
645                                        [ feature.get-values location-prefix
646                                          : $(property-set).raw ] ] ;
647        property-set = [ $(property-set).add-raw
648                         <location-prefix>$(path-prefix) ] ;
649
650        local pch-file = [ generator.run $(project) $(name) : $(property-set)
651            : $(header) ] ;
652
653        # Return result of base class and pch-file property as
654        # usage-requirements.
655        return
656            [ $(pch-file[1]).add-raw <pch-file>$(pch-file[2-]) <cflags>-Winvalid-pch ]
657            $(pch-file[2-])
658          ;
659    }
660
661    # Calls the base version specifying source's name as the name of the created
662    # target. As a result, the PCH will be named whatever.hpp.gch, and not
663    # whatever.gch.
664    rule generated-targets ( sources + : property-set : project name ? )
665    {
666        name = [ $(sources[1]).name ] ;
667        return [ generator.generated-targets $(sources)
668          : $(property-set) : $(project) $(name) ] ;
669    }
670}
671
672# Note: the 'H' source type will catch both '.h' header and '.hpp' header. The
673# latter have HPP type, but HPP type is derived from H. The type of compilation
674# is determined entirely by the destination type.
675generators.register [ new gcc-pch-generator gcc.compile.c.pch   : H :   C_PCH : <pch>on <toolset>gcc ] ;
676generators.register [ new gcc-pch-generator gcc.compile.c++.pch : H : CPP_PCH : <pch>on <toolset>gcc ] ;
677
678# Override default do-nothing generators.
679generators.override gcc.compile.c.pch   : pch.default-c-pch-generator   ;
680generators.override gcc.compile.c++.pch : pch.default-cpp-pch-generator ;
681
682toolset.flags gcc.compile PCH_FILE <pch>on : <pch-file> ;
683
684rule compile.c++.pch ( targets * : sources * : properties * )
685{
686}
687
688actions compile.c++.pch
689{
690    "$(CONFIG_COMMAND)" -x c++-header $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
691}
692
693rule compile.c.pch ( targets * : sources * : properties * )
694{
695}
696
697actions compile.c.pch
698{
699    "$(CONFIG_COMMAND)" -x c-header $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
700}
701
702###
703### General options, like optimization.
704###
705
706# Declare flags and action for compilation.
707toolset.flags gcc.compile OPTIONS <optimization>off   : -O0 ;
708toolset.flags gcc.compile OPTIONS <optimization>speed : -O3 ;
709toolset.flags gcc.compile OPTIONS <optimization>space : -Os ;
710
711toolset.flags gcc.compile OPTIONS <inlining>off  : -fno-inline ;
712toolset.flags gcc.compile OPTIONS <inlining>on   : -Wno-inline ;
713toolset.flags gcc.compile OPTIONS <inlining>full : -finline-functions -Wno-inline ;
714
715toolset.flags gcc.compile OPTIONS <warnings>off : -w ;
716toolset.flags gcc.compile OPTIONS <warnings>on  : -Wall ;
717toolset.flags gcc.compile OPTIONS <warnings>all : -Wall ;
718toolset.flags gcc.compile OPTIONS <warnings>extra : -Wall -Wextra ;
719toolset.flags gcc.compile OPTIONS <warnings>pedantic : -Wall -Wextra -pedantic ;
720toolset.flags gcc.compile OPTIONS <warnings-as-errors>on : -Werror ;
721
722toolset.flags gcc.compile OPTIONS <debug-symbols>on : -g ;
723toolset.flags gcc.compile OPTIONS <profiling>on : -pg ;
724
725toolset.flags gcc.compile OPTIONS <local-visibility>hidden : -fvisibility=hidden ;
726toolset.flags gcc.compile.c++ OPTIONS <local-visibility>hidden : -fvisibility-inlines-hidden ;
727toolset.flags gcc.compile OPTIONS <local-visibility>protected : -fvisibility=protected ;
728toolset.flags gcc.compile OPTIONS <local-visibility>protected/<target-os>darwin : ;
729toolset.flags gcc.compile OPTIONS <local-visibility>global : -fvisibility=default ;
730
731toolset.flags gcc.compile.c++ OPTIONS <exception-handling>off : -fno-exceptions ;
732toolset.flags gcc.compile.c++ OPTIONS <rtti>off : -fno-rtti ;
733
734# sanitizers
735toolset.flags gcc.compile.c++ OPTIONS <address-sanitizer>on : -fsanitize=address -fno-omit-frame-pointer ;
736toolset.flags gcc.compile.c++ OPTIONS <address-sanitizer>norecover : -fsanitize=address -fno-sanitize-recover=address -fno-omit-frame-pointer ;
737toolset.flags gcc.compile.c++ OPTIONS <leak-sanitizer>on : -fsanitize=leak -fno-omit-frame-pointer ;
738toolset.flags gcc.compile.c++ OPTIONS <leak-sanitizer>norecover : -fsanitize=leak -fno-sanitize-recover=leak -fno-omit-frame-pointer ;
739toolset.flags gcc.compile.c++ OPTIONS <thread-sanitizer>on : -fsanitize=thread -fno-omit-frame-pointer ;
740toolset.flags gcc.compile.c++ OPTIONS <thread-sanitizer>norecover : -fsanitize=thread -fno-sanitize-recover=thread -fno-omit-frame-pointer ;
741toolset.flags gcc.compile.c++ OPTIONS <undefined-sanitizer>on : -fsanitize=undefined -fno-omit-frame-pointer ;
742toolset.flags gcc.compile.c++ OPTIONS <undefined-sanitizer>norecover : -fsanitize=undefined -fno-sanitize-recover=undefined -fno-omit-frame-pointer ;
743
744toolset.flags gcc.compile.c++ OPTIONS <coverage>on : --coverage ;
745
746# configure Dinkum STL to match compiler options
747toolset.flags gcc.compile.c++ DEFINES <rtti>off/<target-os>vxworks : _NO_RTTI ;
748toolset.flags gcc.compile.c++ DEFINES <exception-handling>off/<target-os>vxworks : _NO_EX=1 ;
749
750# LTO
751toolset.flags gcc.compile OPTIONS <lto>on/<lto-mode>full : -flto ;
752toolset.flags gcc.link OPTIONS <lto>on/<lto-mode>full : -flto ;
753
754toolset.flags gcc.compile OPTIONS <lto>on/<lto-mode>fat : -flto -ffat-lto-objects ;
755toolset.flags gcc.link OPTIONS <lto>on/<lto-mode>fat : -flto ;
756
757# ABI selection
758toolset.flags gcc.compile.c++ DEFINES <stdlib>gnu : _GLIBCXX_USE_CXX11_ABI=0 ;
759toolset.flags gcc.compile.c++ DEFINES <stdlib>gnu11 : _GLIBCXX_USE_CXX11_ABI=1 ;
760
761###
762### User free feature options.
763###
764
765toolset.flags gcc.compile USER_OPTIONS <cflags> ;
766toolset.flags gcc.compile.c++ USER_OPTIONS <cxxflags> ;
767toolset.flags gcc.compile.asm USER_OPTIONS <asmflags> ;
768toolset.flags gcc.compile DEFINES <define> ;
769toolset.flags gcc.compile INCLUDES <include> ;
770toolset.flags gcc.compile FORCE_INCLUDES <force-include> ;
771toolset.flags gcc.compile.c++ TEMPLATE_DEPTH <c++-template-depth> ;
772toolset.flags gcc.compile.fortran USER_OPTIONS <fflags> ;
773
774###
775### Linking generators and actions.
776###
777
778# Class checking that we do not try to use the <runtime-link>static property
779# while creating or using a shared library, since it is not supported by
780# gcc/libc.
781class gcc-linking-generator : unix-linking-generator
782{
783    rule run ( project name ? : property-set : sources + )
784    {
785        local target-os = [ $(property-set).get <target-os> ] ;
786        local no-static-link = true ;
787        switch $(target-os)
788        {
789            case vms : no-static-link = ;
790            case windows : no-static-link = ;
791        }
792
793        local properties = [ $(property-set).raw ] ;
794        local reason ;
795        if $(no-static-link) && <runtime-link>static in $(properties)
796        {
797            if <link>shared in $(properties)
798            {
799                reason = On gcc, DLLs can not be built with
800                    '<runtime-link>static'. ;
801            }
802            else if [ type.is-derived $(self.target-types[1]) EXE ]
803            {
804                for local s in $(sources)
805                {
806                    local type = [ $(s).type ] ;
807                    if $(type) && [ type.is-derived $(type) SHARED_LIB ]
808                    {
809                        reason = On gcc, using DLLs together with the
810                            '<runtime-link>static' option is not possible. ;
811                    }
812                }
813            }
814        }
815        if $(reason)
816        {
817            ECHO "warning:" $(reason) ;
818            ECHO "warning:" It is suggested to use '<runtime-link>static' together
819                with '<link>static'. ;
820        }
821        else
822        {
823            return [ unix-linking-generator.run $(project) $(name) :
824                $(property-set) : $(sources) ] ;
825        }
826    }
827}
828
829# The set of permissible input types is different on mingw. So, define two sets
830# of generators, with mingw generators selected when target-os=windows.
831
832local g ;
833g = [ new gcc-linking-generator gcc.mingw.link
834      : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB
835      : EXE
836      : <toolset>gcc <target-os>windows ] ;
837$(g).set-rule-name gcc.link.mingw ;
838generators.register $(g) ;
839
840g = [ new gcc-linking-generator gcc.mingw.link.dll
841      : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB
842      : IMPORT_LIB SHARED_LIB
843      : <toolset>gcc <target-os>windows ] ;
844$(g).set-rule-name gcc.link.dll.mingw ;
845generators.register $(g) ;
846
847generators.register
848  [ new gcc-linking-generator gcc.link
849      : LIB OBJ
850      : EXE
851      : <toolset>gcc ] ;
852generators.register
853  [ new gcc-linking-generator gcc.link.dll
854      : LIB OBJ
855      : SHARED_LIB
856      : <toolset>gcc ] ;
857
858generators.override gcc.mingw.link : gcc.link ;
859generators.override gcc.mingw.link.dll : gcc.link.dll ;
860
861# Cygwin is similar to msvc and mingw in that it uses import libraries. While in
862# simple cases, it can directly link to a shared library, it is believed to be
863# slower, and not always possible. Define cygwin-specific generators here.
864
865g = [ new gcc-linking-generator gcc.cygwin.link
866      : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB
867      : EXE
868      : <toolset>gcc <target-os>cygwin ] ;
869$(g).set-rule-name gcc.link ;
870generators.register $(g) ;
871
872g = [ new gcc-linking-generator gcc.cygwin.link.dll
873      : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB
874      : IMPORT_LIB SHARED_LIB
875      : <toolset>gcc <target-os>cygwin ] ;
876$(g).set-rule-name gcc.link.dll ;
877generators.register $(g) ;
878
879generators.override gcc.cygwin.link : gcc.link ;
880generators.override gcc.cygwin.link.dll : gcc.link.dll ;
881
882# Declare flags for linking.
883# First, the common flags.
884toolset.flags gcc.link OPTIONS <debug-symbols>on : -g ;
885toolset.flags gcc.link OPTIONS <profiling>on : -pg ;
886toolset.flags gcc.link USER_OPTIONS <linkflags> ;
887toolset.flags gcc.link LINKPATH <library-path> ;
888toolset.flags gcc.link FINDLIBS-ST <find-static-library> ;
889toolset.flags gcc.link FINDLIBS-SA <find-shared-library> ;
890toolset.flags gcc.link LIBRARIES <library-file> ;
891
892# Specify compile flags for linker as well as they may be needed for LTO
893toolset.flags gcc.link OPTIONS <local-visibility>hidden : -fvisibility=hidden -fvisibility-inlines-hidden ;
894toolset.flags gcc.link OPTIONS <local-visibility>protected : -fvisibility=protected ;
895toolset.flags gcc.link OPTIONS <local-visibility>protected/<target-os>darwin : ;
896toolset.flags gcc.link OPTIONS <local-visibility>global : -fvisibility=default ;
897
898# sanitizers
899toolset.flags gcc.link OPTIONS <address-sanitizer>on : -fsanitize=address -fno-omit-frame-pointer ;
900toolset.flags gcc.link OPTIONS <address-sanitizer>norecover : -fsanitize=address -fno-sanitize-recover=address -fno-omit-frame-pointer ;
901toolset.flags gcc.link OPTIONS <leak-sanitizer>on : -fsanitize=leak -fno-omit-frame-pointer ;
902toolset.flags gcc.link OPTIONS <leak-sanitizer>norecover : -fsanitize=leak -fno-sanitize-recover=leak -fno-omit-frame-pointer ;
903toolset.flags gcc.link OPTIONS <thread-sanitizer>on : -fsanitize=thread -fno-omit-frame-pointer ;
904toolset.flags gcc.link OPTIONS <thread-sanitizer>norecover : -fsanitize=thread -fno-sanitize-recover=thread -fno-omit-frame-pointer ;
905toolset.flags gcc.link OPTIONS <undefined-sanitizer>on : -fsanitize=undefined -fno-omit-frame-pointer ;
906toolset.flags gcc.link OPTIONS <undefined-sanitizer>norecover : -fsanitize=undefined -fno-sanitize-recover=undefined -fno-omit-frame-pointer ;
907
908toolset.flags gcc.link OPTIONS <coverage>on : --coverage ;
909
910toolset.flags gcc.link.dll .IMPLIB-COMMAND <target-os>windows : "-Wl,--out-implib," ;
911toolset.flags gcc.link.dll .IMPLIB-COMMAND <target-os>cygwin : "-Wl,--out-implib," ;
912
913# target specific link flags
914{
915    # aix
916
917    # On AIX we *have* to use the native linker.
918    #
919    # Using -brtl, the AIX linker will look for libraries with both the .a
920    # and .so extensions, such as libfoo.a and libfoo.so. Without -brtl, the
921    # AIX linker looks only for libfoo.a. Note that libfoo.a is an archived
922    # file that may contain shared objects and is different from static libs
923    # as on Linux.
924    #
925    # The -bnoipath strips the prepending (relative) path of libraries from
926    # the loader section in the target library or executable. Hence, during
927    # load-time LIBPATH (identical to LD_LIBRARY_PATH) or a hard-coded
928    # -blibpath (*similar* to -lrpath/-lrpath-link) is searched. Without
929    # this option, the prepending (relative) path + library name is
930    # hard-coded in the loader section, causing *only* this path to be
931    # searched during load-time. Note that the AIX linker does not have an
932    # -soname equivalent, this is as close as it gets.
933    #
934    # The -bbigtoc option instrcuts the linker to create a TOC bigger than 64k.
935    # This is necessary for some submodules such as math, but it does make running
936    # the tests a tad slower.
937    #
938    # The above options are definitely for AIX 5.x, and most likely also for
939    # AIX 4.x and AIX 6.x. For details about the AIX linker see:
940    # http://download.boulder.ibm.com/ibmdl/pub/software/dw/aix/es-aix_ll.pdf
941    #
942    toolset.flags gcc.link OPTIONS <target-os>aix : -Wl,-brtl -Wl,-bnoipath -Wl,-bbigtoc ;
943
944    # See note [1]
945    toolset.flags gcc.link OPTIONS <target-os>aix/<runtime-link>static : -static ;
946
947    # darwin
948
949    # On Darwin, the -s option to ld does not work unless we pass -static,
950    # and passing -static unconditionally is a bad idea. So, do not pass -s
951    # at all and darwin.jam will use a separate 'strip' invocation.
952    toolset.flags gcc.link RPATH <target-os>darwin : <dll-path> ;
953    # This does not support -R.
954    toolset.flags gcc.link RPATH_OPTION <target-os>darwin : -rpath ;
955    # -rpath-link is not supported at all.
956
957    # See note [1]
958    toolset.flags gcc.link OPTIONS <target-os>darwin/<runtime-link>static : -static ;
959
960    # vxworks
961    # On VxWorks we want to reflect what ever special flags have been set in the
962    # environment for the CPU we are targeting in the cross build
963    toolset.flags gcc.link     OPTIONS     <target-os>vxworks/<strip>on    : -Wl,--strip-all                ;
964    toolset.flags gcc.link     OPTIONS     <target-os>vxworks/<link>static : [ os.environ LDFLAGS_STATIC ]  ;
965    toolset.flags gcc.link.dll OPTIONS     <target-os>vxworks              : [ os.environ LDFLAGS_SO ]      ;
966    toolset.flags gcc.link     OPTIONS     <target-os>vxworks/<link>shared : [ os.environ LDFLAGS_DYNAMIC ] ;
967
968    # default
969
970    local generic-os = [ set.difference $(all-os) : aix darwin vxworks solaris osf hpux ] ;
971    # Strip the binary when no debugging is needed. We use --strip-all flag
972    # as opposed to -s since icc (intel's compiler) is generally
973    # option-compatible with and inherits from the gcc toolset, but does not
974    # support -s.
975    toolset.flags gcc.link OPTIONS <target-os>$(generic-os)/<strip>on :
976        -Wl,--strip-all ;
977    toolset.flags gcc.link RPATH <target-os>$(generic-os) : <dll-path> ;
978    toolset.flags gcc.link RPATH_OPTION <target-os>$(generic-os) : -rpath ;
979    toolset.flags gcc.link RPATH_LINK <target-os>$(generic-os) : <xdll-path> ;
980    toolset.flags gcc.link START-GROUP <target-os>$(generic-os) :
981        -Wl,--start-group ;
982    toolset.flags gcc.link END-GROUP <target-os>$(generic-os) : -Wl,--end-group ;
983
984    # gnu ld has the ability to change the search behaviour for libraries
985    # referenced by the -l switch. These modifiers are -Bstatic and
986    # -Bdynamic and change search for -l switches that follow them. The
987    # following list shows the tried variants. Search stops at the first
988    # variant that has a match.
989    #
990    # *nix: -Bstatic -lxxx
991    #    libxxx.a
992    #
993    # *nix: -Bdynamic -lxxx
994    #    libxxx.so
995    #    libxxx.a
996    #
997    # windows (mingw, cygwin) -Bstatic -lxxx
998    #    libxxx.a
999    #    xxx.lib
1000    #
1001    # windows (mingw, cygwin) -Bdynamic -lxxx
1002    #    libxxx.dll.a
1003    #    xxx.dll.a
1004    #    libxxx.a
1005    #    xxx.lib
1006    #    cygxxx.dll (*)
1007    #    libxxx.dll
1008    #    xxx.dll
1009    #    libxxx.a
1010    #
1011    # (*) This is for cygwin
1012    # Please note that -Bstatic and -Bdynamic are not a guarantee that a
1013    # static or dynamic lib indeed gets linked in. The switches only change
1014    # search patterns!
1015
1016    # On *nix mixing shared libs with static runtime is not a good idea.
1017    toolset.flags gcc.link FINDLIBS-ST-PFX <target-os>$(generic-os)/<runtime-link>shared : -Wl,-Bstatic ;
1018    toolset.flags gcc.link FINDLIBS-SA-PFX <target-os>$(generic-os)/<runtime-link>shared : -Wl,-Bdynamic ;
1019
1020    # On windows allow mixing of static and dynamic libs with static
1021    # runtime is not a good idea.
1022    toolset.flags gcc.link FINDLIBS-ST-PFX <target-os>windows/<runtime-link>static : -Wl,-Bstatic ;
1023    toolset.flags gcc.link FINDLIBS-SA-PFX <target-os>windows/<runtime-link>static : -Wl,-Bdynamic ;
1024    toolset.flags gcc.link OPTIONS <target-os>windows/<runtime-link>static : -Wl,-Bstatic ;
1025
1026    toolset.flags gcc.link HAVE_SONAME <target-os>$(generic-os) : "" ;
1027    toolset.flags gcc.link SONAME_OPTION <target-os>$(generic-os) : -h ;
1028
1029    # See note [1]
1030    toolset.flags gcc.link OPTIONS <target-os>$(generic-os)/<runtime-link>static : -static ;
1031
1032    # hpux
1033
1034    toolset.flags gcc.link OPTIONS <target-os>hpux/<strip>on : -Wl,-s ;
1035
1036    toolset.flags gcc.link HAVE_SONAME <target-os>hpux : "" ;
1037    toolset.flags gcc.link SONAME_OPTION <target-os>hpux : +h ;
1038
1039    # osf
1040
1041    # No --strip-all, just -s.
1042    toolset.flags gcc.link OPTIONS <target-os>osf/<strip>on : -Wl,-s ;
1043    toolset.flags gcc.link RPATH <target-os>osf : <dll-path> ;
1044    # This does not support -R.
1045    toolset.flags gcc.link RPATH_OPTION <target-os>osf : -rpath ;
1046    # -rpath-link is not supported at all.
1047
1048    # See note [1]
1049    toolset.flags gcc.link OPTIONS <target-os>osf/<runtime-link>static : -static ;
1050
1051    # sun
1052
1053    toolset.flags gcc.link OPTIONS <target-os>solaris/<strip>on : -Wl,-s ;
1054
1055    toolset.flags gcc.link RPATH <target-os>solaris : <dll-path> ;
1056    # Solaris linker does not have a separate -rpath-link, but allows using
1057    # -L for the same purpose.
1058    toolset.flags gcc.link LINKPATH <target-os>solaris : <xdll-path> ;
1059
1060    # This permits shared libraries with non-PIC code on Solaris.
1061    # VP, 2004/09/07: Now that we have -fPIC hardcode in link.dll, the
1062    # following is not needed. Whether -fPIC should be hardcoded, is a
1063    # separate question.
1064    # AH, 2004/10/16: it is still necessary because some tests link against
1065    # static libraries that were compiled without PIC.
1066    toolset.flags gcc.link OPTIONS <target-os>solaris : -mimpure-text ;
1067
1068    # See note [1]
1069    toolset.flags gcc.link OPTIONS <target-os>solaris/<runtime-link>static : -static ;
1070
1071    # [1]
1072    # For <runtime-link>static we made sure there are no dynamic libraries in the
1073    # link. On HP-UX not all system libraries exist as archived libraries (for
1074    # example, there is no libunwind.a), so, on this platform, the -static option
1075    # cannot be specified.
1076}
1077
1078
1079# Enclose the RPATH variable on 'targets' in double quotes, unless it is already
1080# enclosed in single quotes. This special casing is done because it is common to
1081# pass '$ORIGIN' to linker -- and it has to have single quotes to prevent shell
1082# expansion -- and if we add double quotes then the preventing properties of
1083# single quotes disappear.
1084#
1085rule quote-rpath ( targets * )
1086{
1087    local r = [ on $(targets[1]) return $(RPATH) ] ;
1088    if ! [ MATCH ('.*') : $(r) ]
1089    {
1090        r = \"$(r)\" ;
1091    }
1092    RPATH on $(targets) = $(r) ;
1093}
1094
1095# Declare actions for linking.
1096rule link ( targets * : sources * : properties * )
1097{
1098    SPACE on $(targets) = " " ;
1099    # Serialize execution of the 'link' action, since running N links in
1100    # parallel is just slower. For now, serialize only gcc links, it might be a
1101    # good idea to serialize all links.
1102    JAM_SEMAPHORE on $(targets) = <s>gcc-link-semaphore ;
1103    quote-rpath $(targets) ;
1104}
1105
1106rule link.dll ( targets * : sources * : properties * )
1107{
1108    SPACE on $(targets) = " " ;
1109    JAM_SEMAPHORE on $(targets) = <s>gcc-link-semaphore ;
1110    quote-rpath $(targets) ;
1111}
1112
1113rule link.mingw ( targets * : sources * : properties * )
1114{
1115    SPACE on $(targets) = " " ;
1116    # Serialize execution of the 'link' action, since running N links in
1117    # parallel is just slower. For now, serialize only gcc links, it might be a
1118    # good idea to serialize all links.
1119    JAM_SEMAPHORE on $(targets) = <s>gcc-link-semaphore ;
1120}
1121
1122rule link.dll.mingw ( targets * : sources * : properties * )
1123{
1124    SPACE on $(targets) = " " ;
1125    JAM_SEMAPHORE on $(targets) = <s>gcc-link-semaphore ;
1126}
1127
1128actions link.mingw bind LIBRARIES
1129{
1130    "$(CONFIG_COMMAND)" -L"$(LINKPATH)" -o "$(<)" @"@($(<[1]:T).rsp:E=$(START-GROUP) "$(>:T)" "$(LIBRARIES:T)" $(FINDLIBS-ST-PFX:T) -l$(FINDLIBS-ST:T) $(FINDLIBS-SA-PFX:T) -l$(FINDLIBS-SA:T) $(END-GROUP))" $(OPTIONS) $(USER_OPTIONS)
1131}
1132
1133actions link.dll.mingw bind LIBRARIES
1134{
1135    "$(CONFIG_COMMAND)" -L"$(LINKPATH)" "$(.IMPLIB-COMMAND)$(<[1])" -o "$(<[-1])" -shared @"@($(<[-1]:T).rsp:E=$(START-GROUP) "$(>:T)" "$(LIBRARIES:T)" $(FINDLIBS-ST-PFX:T) -l$(FINDLIBS-ST:T) $(FINDLIBS-SA-PFX:T) -l$(FINDLIBS-SA:T) $(END-GROUP))" $(OPTIONS) $(USER_OPTIONS)
1136}
1137
1138actions link bind LIBRARIES
1139{
1140    "$(CONFIG_COMMAND)" -L"$(LINKPATH)" -Wl,$(RPATH_OPTION:E=-R)$(SPACE)-Wl,$(RPATH) -Wl,-rpath-link$(SPACE)-Wl,"$(RPATH_LINK)" -o "$(<)" $(START-GROUP) "$(>)" "$(LIBRARIES)" $(FINDLIBS-ST-PFX) -l$(FINDLIBS-ST) $(FINDLIBS-SA-PFX) -l$(FINDLIBS-SA) $(END-GROUP) $(OPTIONS) $(USER_OPTIONS)
1141}
1142
1143actions link.dll bind LIBRARIES
1144{
1145    "$(CONFIG_COMMAND)" -L"$(LINKPATH)" -Wl,$(RPATH_OPTION:E=-R)$(SPACE)-Wl,$(RPATH) "$(.IMPLIB-COMMAND)$(<[1])" -o "$(<[-1])" $(HAVE_SONAME)-Wl,$(SONAME_OPTION)$(SPACE)-Wl,$(<[-1]:D=) -shared $(START-GROUP) "$(>)" "$(LIBRARIES)" $(FINDLIBS-ST-PFX) -l$(FINDLIBS-ST) $(FINDLIBS-SA-PFX) -l$(FINDLIBS-SA) $(END-GROUP) $(OPTIONS) $(USER_OPTIONS)
1146}
1147
1148###
1149### Archive library generation.
1150###
1151
1152# Default value. Mostly for the sake of intel-linux that inherits from gcc, but
1153# does not have the same logic to set the .AR variable. We can put the same
1154# logic in intel-linux, but that is hardly worth the trouble as on Linux, 'ar'
1155# is always available.
1156.AR = ar ;
1157.ARFLAGS = rc ;
1158.RANLIB = ranlib ;
1159
1160toolset.flags gcc.archive AROPTIONS <archiveflags> ;
1161
1162rule archive ( targets * : sources * : properties * )
1163{
1164    # Always remove archive and start again. Here is the rationale from
1165    #
1166    # Andre Hentz:
1167    #
1168    # I had a file, say a1.c, that was included into liba.a. I moved a1.c to
1169    # a2.c, updated my Jamfiles and rebuilt. My program was crashing with absurd
1170    # errors. After some debugging I traced it back to the fact that a1.o was
1171    # *still* in liba.a
1172    #
1173    # Rene Rivera:
1174    #
1175    # Originally removing the archive was done by splicing an RM onto the
1176    # archive action. That makes archives fail to build on NT when they have
1177    # many files because it will no longer execute the action directly and blow
1178    # the line length limit. Instead we remove the file in a different action,
1179    # just before building the archive.
1180    #
1181    local clean.a = $(targets[1])(clean) ;
1182    TEMPORARY $(clean.a) ;
1183    NOCARE $(clean.a) ;
1184    LOCATE on $(clean.a) = [ on $(targets[1]) return $(LOCATE) ] ;
1185    DEPENDS $(clean.a) : $(sources) ;
1186    DEPENDS $(targets) : $(clean.a) ;
1187    common.RmTemps $(clean.a) : $(targets) ;
1188}
1189
1190# Declare action for creating static libraries.
1191# The letter 'r' means to add files to the archive with replacement. Since we
1192# remove archive, we do not care about replacement, but there is no option "add
1193# without replacement".
1194# The letter 'c' suppresses the warning in case the archive does not exists yet.
1195# That warning is produced only on some platforms, for whatever reasons.
1196#
1197actions piecemeal archive
1198{
1199    "$(.AR)" $(AROPTIONS) $(.ARFLAGS) "$(<)" "$(>)"
1200    "$(.RANLIB)" "$(<)"
1201}
1202
1203###
1204### CPU architecture and instruction set options.
1205###
1206
1207local rule cpu-flags ( toolset variable : architecture : instruction-set + :
1208    values + : default ? )
1209{
1210    if $(default)
1211    {
1212        toolset.flags $(toolset) $(variable)
1213            <architecture>$(architecture)/<instruction-set> : $(values) ;
1214    }
1215    toolset.flags $(toolset) $(variable)
1216        <architecture>/<instruction-set>$(instruction-set)
1217        <architecture>$(architecture)/<instruction-set>$(instruction-set)
1218        : $(values) ;
1219}
1220
1221
1222# Set architecture/instruction-set options.
1223#
1224# x86 and compatible
1225# The 'native' option appeared in gcc 4.2 so we cannot safely use it as default.
1226# Use i686 instead for 32-bit.
1227toolset.flags gcc OPTIONS <architecture>x86/<address-model>32/<instruction-set> : -march=i686 ;
1228cpu-flags gcc OPTIONS : x86 : native : -march=native ;
1229cpu-flags gcc OPTIONS : x86 : i486 : -march=i486 ;
1230cpu-flags gcc OPTIONS : x86 : i586 : -march=i586 ;
1231cpu-flags gcc OPTIONS : x86 : i686 : -march=i686 ;
1232cpu-flags gcc OPTIONS : x86 : pentium : -march=pentium ;
1233cpu-flags gcc OPTIONS : x86 : pentium-mmx : -march=pentium-mmx ;
1234cpu-flags gcc OPTIONS : x86 : pentiumpro : -march=pentiumpro ;
1235cpu-flags gcc OPTIONS : x86 : pentium2 : -march=pentium2 ;
1236cpu-flags gcc OPTIONS : x86 : pentium3 : -march=pentium3 ;
1237cpu-flags gcc OPTIONS : x86 : pentium3m : -march=pentium3m ;
1238cpu-flags gcc OPTIONS : x86 : pentium-m : -march=pentium-m ;
1239cpu-flags gcc OPTIONS : x86 : pentium4 : -march=pentium4 ;
1240cpu-flags gcc OPTIONS : x86 : pentium4m : -march=pentium4m ;
1241cpu-flags gcc OPTIONS : x86 : prescott : -march=prescott ;
1242cpu-flags gcc OPTIONS : x86 : nocona : -march=nocona ;
1243cpu-flags gcc OPTIONS : x86 : core2 : -march=core2 ;
1244cpu-flags gcc OPTIONS : x86 : conroe : -march=core2 ;
1245cpu-flags gcc OPTIONS : x86 : conroe-xe : -march=core2 ;
1246cpu-flags gcc OPTIONS : x86 : conroe-l : -march=core2 ;
1247cpu-flags gcc OPTIONS : x86 : allendale : -march=core2 ;
1248cpu-flags gcc OPTIONS : x86 : wolfdale : -march=core2 -msse4.1 ;
1249cpu-flags gcc OPTIONS : x86 : merom : -march=core2 ;
1250cpu-flags gcc OPTIONS : x86 : merom-xe : -march=core2 ;
1251cpu-flags gcc OPTIONS : x86 : kentsfield : -march=core2 ;
1252cpu-flags gcc OPTIONS : x86 : kentsfield-xe : -march=core2 ;
1253cpu-flags gcc OPTIONS : x86 : yorksfield : -march=core2 ;
1254cpu-flags gcc OPTIONS : x86 : penryn : -march=core2 ;
1255cpu-flags gcc OPTIONS : x86 : corei7 : -march=corei7 ;
1256cpu-flags gcc OPTIONS : x86 : nehalem : -march=corei7 ;
1257cpu-flags gcc OPTIONS : x86 : corei7-avx : -march=corei7-avx ;
1258cpu-flags gcc OPTIONS : x86 : sandy-bridge : -march=corei7-avx ;
1259cpu-flags gcc OPTIONS : x86 : core-avx-i : -march=core-avx-i ;
1260cpu-flags gcc OPTIONS : x86 : ivy-bridge : -march=core-avx-i ;
1261cpu-flags gcc OPTIONS : x86 : haswell : -march=core-avx-i -mavx2 -mfma -mbmi -mbmi2 -mlzcnt ;
1262cpu-flags gcc OPTIONS : x86 : broadwell : -march=broadwell ;
1263cpu-flags gcc OPTIONS : x86 : skylake : -march=skylake ;
1264cpu-flags gcc OPTIONS : x86 : skylake-avx512 : -march=skylake-avx512 ;
1265cpu-flags gcc OPTIONS : x86 : cannonlake : -march=skylake-avx512 -mavx512vbmi -mavx512ifma -msha ;
1266cpu-flags gcc OPTIONS : x86 : icelake-client : -march=icelake-client ;
1267cpu-flags gcc OPTIONS : x86 : icelake-server : -march=icelake-server ;
1268cpu-flags gcc OPTIONS : x86 : cascadelake : -march=skylake-avx512 -mavx512vnni ;
1269cpu-flags gcc OPTIONS : x86 : cooperlake : -march=cooperlake ;
1270cpu-flags gcc OPTIONS : x86 : tigerlake : -march=tigerlake ;
1271cpu-flags gcc OPTIONS : x86 : k6 : -march=k6 ;
1272cpu-flags gcc OPTIONS : x86 : k6-2 : -march=k6-2 ;
1273cpu-flags gcc OPTIONS : x86 : k6-3 : -march=k6-3 ;
1274cpu-flags gcc OPTIONS : x86 : athlon : -march=athlon ;
1275cpu-flags gcc OPTIONS : x86 : athlon-tbird : -march=athlon-tbird ;
1276cpu-flags gcc OPTIONS : x86 : athlon-4 : -march=athlon-4 ;
1277cpu-flags gcc OPTIONS : x86 : athlon-xp : -march=athlon-xp ;
1278cpu-flags gcc OPTIONS : x86 : athlon-mp : -march=athlon-mp ;
1279##
1280cpu-flags gcc OPTIONS : x86 : k8 : -march=k8 ;
1281cpu-flags gcc OPTIONS : x86 : opteron : -march=opteron ;
1282cpu-flags gcc OPTIONS : x86 : athlon64 : -march=athlon64 ;
1283cpu-flags gcc OPTIONS : x86 : athlon-fx : -march=athlon-fx ;
1284cpu-flags gcc OPTIONS : x86 : k8-sse3 : -march=k8-sse3 ;
1285cpu-flags gcc OPTIONS : x86 : opteron-sse3 : -march=opteron-sse3 ;
1286cpu-flags gcc OPTIONS : x86 : athlon64-sse3 : -march=athlon64-sse3 ;
1287cpu-flags gcc OPTIONS : x86 : amdfam10 : -march=amdfam10 ;
1288cpu-flags gcc OPTIONS : x86 : barcelona : -march=barcelona ;
1289cpu-flags gcc OPTIONS : x86 : bdver1 : -march=bdver1 ;
1290cpu-flags gcc OPTIONS : x86 : bdver2 : -march=bdver2 ;
1291cpu-flags gcc OPTIONS : x86 : bdver3 : -march=bdver3 ;
1292cpu-flags gcc OPTIONS : x86 : bdver4 : -march=bdver4 ;
1293cpu-flags gcc OPTIONS : x86 : btver1 : -march=btver1 ;
1294cpu-flags gcc OPTIONS : x86 : btver2 : -march=btver2 ;
1295cpu-flags gcc OPTIONS : x86 : znver1 : -march=znver1 ;
1296cpu-flags gcc OPTIONS : x86 : znver2 : -march=znver2 ;
1297cpu-flags gcc OPTIONS : x86 : winchip-c6 : -march=winchip-c6 ;
1298cpu-flags gcc OPTIONS : x86 : winchip2 : -march=winchip2 ;
1299cpu-flags gcc OPTIONS : x86 : c3 : -march=c3 ;
1300cpu-flags gcc OPTIONS : x86 : c3-2 : -march=c3-2 ;
1301cpu-flags gcc OPTIONS : x86 : c7 : -march=c7 ;
1302##
1303cpu-flags gcc OPTIONS : x86 : atom : -march=atom ;
1304# Sparc
1305cpu-flags gcc OPTIONS : sparc : v7 : -mcpu=v7 : default ;
1306cpu-flags gcc OPTIONS : sparc : cypress : -mcpu=cypress ;
1307cpu-flags gcc OPTIONS : sparc : v8 : -mcpu=v8 ;
1308cpu-flags gcc OPTIONS : sparc : supersparc : -mcpu=supersparc ;
1309cpu-flags gcc OPTIONS : sparc : sparclite : -mcpu=sparclite ;
1310cpu-flags gcc OPTIONS : sparc : hypersparc : -mcpu=hypersparc ;
1311cpu-flags gcc OPTIONS : sparc : sparclite86x : -mcpu=sparclite86x ;
1312cpu-flags gcc OPTIONS : sparc : f930 : -mcpu=f930 ;
1313cpu-flags gcc OPTIONS : sparc : f934 : -mcpu=f934 ;
1314cpu-flags gcc OPTIONS : sparc : sparclet : -mcpu=sparclet ;
1315cpu-flags gcc OPTIONS : sparc : tsc701 : -mcpu=tsc701 ;
1316cpu-flags gcc OPTIONS : sparc : v9 : -mcpu=v9 ;
1317cpu-flags gcc OPTIONS : sparc : ultrasparc : -mcpu=ultrasparc ;
1318cpu-flags gcc OPTIONS : sparc : ultrasparc3 : -mcpu=ultrasparc3 ;
1319# RS/6000 & PowerPC
1320cpu-flags gcc OPTIONS : power : 403 : -mcpu=403 ;
1321cpu-flags gcc OPTIONS : power : 505 : -mcpu=505 ;
1322cpu-flags gcc OPTIONS : power : 601 : -mcpu=601 ;
1323cpu-flags gcc OPTIONS : power : 602 : -mcpu=602 ;
1324cpu-flags gcc OPTIONS : power : 603 : -mcpu=603 ;
1325cpu-flags gcc OPTIONS : power : 603e : -mcpu=603e ;
1326cpu-flags gcc OPTIONS : power : 604 : -mcpu=604 ;
1327cpu-flags gcc OPTIONS : power : 604e : -mcpu=604e ;
1328cpu-flags gcc OPTIONS : power : 620 : -mcpu=620 ;
1329cpu-flags gcc OPTIONS : power : 630 : -mcpu=630 ;
1330cpu-flags gcc OPTIONS : power : 740 : -mcpu=740 ;
1331cpu-flags gcc OPTIONS : power : 7400 : -mcpu=7400 ;
1332cpu-flags gcc OPTIONS : power : 7450 : -mcpu=7450 ;
1333cpu-flags gcc OPTIONS : power : 750 : -mcpu=750 ;
1334cpu-flags gcc OPTIONS : power : 801 : -mcpu=801 ;
1335cpu-flags gcc OPTIONS : power : 821 : -mcpu=821 ;
1336cpu-flags gcc OPTIONS : power : 823 : -mcpu=823 ;
1337cpu-flags gcc OPTIONS : power : 860 : -mcpu=860 ;
1338cpu-flags gcc OPTIONS : power : 970 : -mcpu=970 ;
1339cpu-flags gcc OPTIONS : power : 8540 : -mcpu=8540 ;
1340cpu-flags gcc OPTIONS : power : power : -mcpu=power ;
1341cpu-flags gcc OPTIONS : power : power2 : -mcpu=power2 ;
1342cpu-flags gcc OPTIONS : power : power3 : -mcpu=power3 ;
1343cpu-flags gcc OPTIONS : power : power4 : -mcpu=power4 ;
1344cpu-flags gcc OPTIONS : power : power5 : -mcpu=power5 ;
1345cpu-flags gcc OPTIONS : power : powerpc : -mcpu=powerpc ;
1346cpu-flags gcc OPTIONS : power : powerpc64 : -mcpu=powerpc64 ;
1347cpu-flags gcc OPTIONS : power : rios : -mcpu=rios ;
1348cpu-flags gcc OPTIONS : power : rios1 : -mcpu=rios1 ;
1349cpu-flags gcc OPTIONS : power : rios2 : -mcpu=rios2 ;
1350cpu-flags gcc OPTIONS : power : rsc : -mcpu=rsc ;
1351cpu-flags gcc OPTIONS : power : rs64a : -mcpu=rs64 ;
1352cpu-flags gcc OPTIONS : s390x : z196 : -march=z196 ;
1353cpu-flags gcc OPTIONS : s390x : zEC12 : -march=zEC12 ;
1354cpu-flags gcc OPTIONS : s390x : z13 : -march=z13 ;
1355cpu-flags gcc OPTIONS : s390x : z14 : -march=z14 ;
1356cpu-flags gcc OPTIONS : s390x : z15 : -march=z15 ;
1357# AIX variant of RS/6000 & PowerPC
1358toolset.flags gcc AROPTIONS <address-model>64/<target-os>aix : "-X64" ;
1359