0d16217
This document contains documentation of the individual compiler flags
0d16217
and how to use them.
0d16217
0d16217
[TOC]
0d16217
0d16217
# Using RPM build flags
0d16217
fa08f0e
For packages which use autoconf to set up the build environment, use
fa08f0e
the `%configure` macro to obtain the full complement of flags, like
fa08f0e
this:
0d16217
0d16217
    %configure
0d16217
0d16217
This will invoke the `./configure` with arguments (such as
0d16217
`--prefix=/usr`) to adjust the paths to the packaging defaults.
0d16217
0d16217
As a side effect, this will set the environment variables `CFLAGS`,
0d16217
`CXXFLAGS`, `FFLAGS`, `FCFLAGS`, and `LDFLAGS`, so they can be used by
fa08f0e
makefiles and other build tools.  (However, existing values for this
fa08f0e
variables are not overwritten.)
0d16217
fa08f0e
If your package does not use autoconf, you can still set the same
fa08f0e
environment variables using
fa08f0e
fa08f0e
    %set_build_flags
fa08f0e
fa08f0e
early in the `%build` section.  (Again, existing environment variables
fa08f0e
are not overwritten.)
fa08f0e
fa08f0e
Individual build flags are also available through RPM macros:
fa08f0e
fa08f0e
* `%{build_cflags}` for the C compiler flags (also known as the
fa08f0e
  `CFLAGS` variable).  Also historically available as `%{optflags}`.
fa08f0e
  Furthermore, at the start of the `%build` section, the environment
fa08f0e
  variable `RPM_OPT_FLAGS` is set to this value.
6bc9480
* `%{build_cxxflags}` for the C++ compiler flags (usually assigned to
fa08f0e
  the `CXXFLAGS` shell variable).
fa08f0e
* `%{build_fflags} for `FFLAGS` (the Fortran compiler flags, also
fa08f0e
  known as the `FCFLAGS` variable).
ddb8455
* `%{build_ldflags}` for the link editor (ld) flags, usually known as
fa08f0e
  `LDFLAGS`.  Note that the contents quotes linker arguments using
fa08f0e
  `-Wl`, so this variable is intended for use with the `gcc` compiler
fa08f0e
  driver.  At the start of the `%build` section, the environment
fa08f0e
  variable `RPM_LD_FLAGS` is set to this value.
fa08f0e
fa08f0e
These RPM macros do not alter shell environment variables.
fa08f0e
fa08f0e
For some other build tools separate mechanisms exist:
0d16217
0d16217
* CMake builds use the the `%cmake` macro from the `cmake-rpm-macros`
0d16217
  package.
0d16217
0d16217
Care must be taking not to compile the current selection of compiler
0d16217
flags into any RPM package besides `redhat-rpm-config`, so that flag
0d16217
changes are picked up automatically once `redhat-rpm-config` is
0d16217
updated.
0d16217
0d16217
# Flag selection for the build type
0d16217
0d16217
The default flags are suitable for building applications.
0d16217
0d16217
For building shared objects, you must compile with `-fPIC` in
0d16217
(`CFLAGS` or `CXXFLAGS`) and link with `-shared` (in `LDFLAGS`).
0d16217
0d16217
For other considerations involving shared objects, see:
0d16217
0d16217
* [Fedora Packaging Guidelines: Shared Libraries](https://fedoraproject.org/wiki/Packaging:Guidelines#Shared_Libraries)
0d16217
0d16217
# Customizing compiler flags
0d16217
0d16217
It is possible to set RPM macros to change some aspects of the
0d16217
compiler flags.  Changing these flags should be used as a last
521c1a9
recourse if other workarounds are not available.
0d16217
0448c23
### Lazy binding
0448c23
0448c23
If your package depends on the semantics of lazy binding (e.g., it has
0448c23
plugins which load additional plugins to complete their dependencies,
0448c23
before which some referenced functions are undefined), you should put
0448c23
`-Wl,-z,lazy` at the end of the `LDFLAGS` setting when linking objects
0448c23
which have such requirements.  Under these circumstances, it is
0448c23
unnecessary to disable hardened builds (and thus lose full ASLR for
0448c23
executables), or link everything without `-Wl,z,now` (non-lazy
0448c23
binding).
0448c23
c873752
### Hardened builds
c873752
c873752
By default, the build flags enable fully hardened builds.  To change
c873752
this, include this in the RPM spec file:
0d16217
0d16217
    %undefine _hardened_build
0d16217
0d16217
This turns off certain hardening features, as described in detail
0d16217
below.  The main difference is that executables will be
0d16217
position-dependent (no full ASLR) and use lazy binding.
0d16217
c873752
### Annotated builds/watermarking
c873752
c873752
By default, the build flags cause a special output section to be
c873752
included in ELF files which describes certain aspects of the build.
a013956
To change this for all compiler invocations, include this in the RPM
a013956
spec file:
0d16217
0d16217
    %undefine _annotated_build
0d16217
a013956
Be warned that this turns off watermarking, making it impossible to do
a013956
full hardening coverage analysis for any binaries produced.
a013956
a013956
It is possible to disable annotations for individual compiler
a013956
invocations, using the `-fplugin-arg-annobin-disable` flag.  However,
a013956
the annobin plugin must still be loaded for this flag to be
a013956
recognized, so it has to come after the hardening flags on the command
a013956
line (it has to be added at the end of `CFLAGS`, or specified after
a013956
the `CFLAGS` variable contents).
0d16217
c873752
### Strict symbol checks in the link editor (ld)
078af19
8d6c6d0
Optionally, the link editor will refuse to link shared objects which
c873752
contain undefined symbols.  Such symbols lack symbol versioning
c873752
information and can be bound to the wrong (compatibility) symbol
c873752
version at run time, and not the actual (default) symbol version which
c873752
would have been used if the symbol definition had been available at
c873752
static link time.  Furthermore, at run time, the dynamic linker will
c873752
not have complete dependency information (in the form of DT_NEEDED
c873752
entries), which can lead to errors (crashes) if IFUNC resolvers are
c873752
executed before the shared object containing them is fully relocated.
c873752
8d6c6d0
To switch on these checks, define this macro in the RPM spec file:
8d6c6d0
8d6c6d0
    %define _strict_symbol_defs_build 1
8d6c6d0
8d6c6d0
If this RPM spec option is active, link failures will occur if the
8d6c6d0
linker command line does not list all shared objects which are needed.
8d6c6d0
In this case, you need to add the missing DSOs (with linker arguments
8d6c6d0
such as `-lm`).  As a result, the link editor will also generated the
c873752
necessary DT_NEEDED entries.
c873752
c873752
In some cases (such as when a DSO is loaded as a plugin and is
c873752
expected to bind to symbols in the main executable), undefined symbols
c873752
are expected.  In this case, you can add
078af19
078af19
    %undefine _strict_symbol_defs_build
078af19
078af19
to the RPM spec file to disable these strict checks.  Alternatively,
078af19
you can pass `-z undefs` to ld (written as `-Wl,-z,undefs` on the gcc
078af19
command line).  The latter needs binutils 2.29.1-12.fc28 or later.
078af19
0d16217
# Individual compiler flags
0d16217
0d16217
Compiler flags end up in the environment variables `CFLAGS`,
0d16217
`CXXFLAGS`, `FFLAGS`, and `FCFLAGS`.
0d16217
0d16217
The general (architecture-independent) build flags are:
0d16217
0d16217
* `-O2`: Turn on various GCC optimizations.  See the [GCC manual](https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-O2).
0d16217
  Optimization improves performance, the accuracy of warnings, and the
0d16217
  reach of toolchain-based hardening, but it makes debugging harder.
0d16217
* `-g`: Generate debugging information (DWARF).  In Fedora, this data
0d16217
  is separated into `-debuginfo` RPM packages whose installation is
0d16217
  optional, so debuging information does not increase the size of
0d16217
  installed binaries by default.
0d16217
* `-pipe`: Run compiler and assembler in parallel and do not use a
0d16217
  temporary file for the assembler input.  This can improve
0d16217
  compilation performance.  (This does not affect code generation.)
0d16217
* `-Wall`: Turn on various GCC warnings.
0d16217
  See the [GCC manual](https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wall).
0d16217
* `-Werror=format-security`: Turn on format string warnings and treat
0d16217
  them as errors.
0d16217
  See the [GCC manual](https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wformat-security).
0d16217
  This can occasionally result in compilation errors.  In this case,
0d16217
  the best option is to rewrite the source code so that only constant
0d16217
  format strings (string literals) are used.
0d16217
* `-Wp,-D_FORTIFY_SOURCE=2`: Source fortification activates various
0d16217
  hardening features in glibc:
0d16217
    * String functions such as `memcpy` attempt to detect buffer lengths
0d16217
      and terminate the process if a buffer overflow is detected.
0d16217
    * `printf` format strings may only contain the `%n` format specifier
0d16217
      if the format string resides in read-only memory.
0d16217
    * `open` and `openat` flags are checked for consistency with the
0d16217
      presence of a *mode* argument.
0d16217
    * Plus other minor hardening changes.
0d16217
  (These changes can occasionally break valid programs.)
0d16217
* `-fexceptions`: Provide exception unwinding support for C programs.
0d16217
  See the [`-fexceptions` option in the GCC
0d16217
  manual](https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#index-fexceptions)
0d16217
  and the [`cleanup` variable
0d16217
  attribute](https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-cleanup-variable-attribute).
0d16217
  This also hardens cancellation handling in C programs because
0d16217
  it is not required to use an on-stack jump buffer to install
0d16217
  a cancellation handler with `pthread_cleanup_push`.  It also makes
0d16217
  it possible to unwind the stack (using C++ `throw` or Rust panics)
0d16217
  from C callback functions if a C library supports non-local exits
0d16217
  from them (e.g., via `longjmp`).
0d16217
* `-Wp,-D_GLIBCXX_ASSERTIONS`: Enable lightweight assertions in the
0d16217
  C++ standard library, such as bounds checking for the subscription
0d16217
  operator on vectors.  (This flag is added to both `CFLAGS` and
0d16217
  `CXXFLAGS`; C compilations will simply ignore it.)
0d16217
* `-fstack-protector-strong`: Instrument functions to detect
0d16217
  stack-based buffer overflows before jumping to the return address on
0d16217
  the stack.  The *strong* variant only performs the instrumentation
0d16217
  for functions whose stack frame contains addressable local
0d16217
  variables.  (If the address of a variable is never taken, it is not
0d16217
  possible that a buffer overflow is caused by incorrect pointer
0d16217
  arithmetic involving a pointer to that variable.)
0d16217
* `-grecord-gcc-switches`: Include select GCC command line switches in
0d16217
  the DWARF debugging information.  This is useful for detecting the
0d16217
  presence of certain build flags and general hardening coverage.
0d16217
0d16217
For hardened builds (which are enabled by default, see above for how
0d16217
to disable them), the flag
0d16217
`-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1` is added to the
0d16217
command line.  It adds the following flag to the command line:
0d16217
0d16217
*   `-fPIE`: Compile for a position-independent executable (PIE),
0d16217
    enabling full address space layout randomization (ASLR).  This is
0d16217
    similar to `-fPIC`, but avoids run-time indirections on certain
0d16217
    architectures, resulting in improved performance and slightly
0d16217
    smaller executables.  However, compared to position-dependent code
0d16217
    (the default generated by GCC), there is still a measurable
0d16217
    performance impact.
0d16217
0d16217
    If the command line also contains `-r` (producing a relocatable
0d16217
    object file), `-fpic` or `-fPIC`, this flag is automatically
0d16217
    dropped.  (`-fPIE` can only be used for code which is linked into
0d16217
    the main program.) Code which goes into static libraries should be
0d16217
    compiled with `-fPIE`, except when this code is expected to be
0d16217
    linked into DSOs, when `-fPIC` must be used.
0d16217
0d16217
    To be effective, `-fPIE` must be used with the `-pie` linker flag
0d16217
    when producing an executable, see below.
0d16217
0d16217
To support [binary watermarks for ELF
0d16217
objects](https://fedoraproject.org/wiki/Toolchain/Watermark) using
0d16217
annobin, the `-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1` flag is
0d16217
added by default.  This can be switched off by undefining the
0d16217
`%_annotated_build` RPM macro (see above).
0d16217
0d16217
### Architecture-specific compiler flags
0d16217
0d16217
These compiler flags are enabled for all builds (hardened/annotated or
0d16217
not), but their selection depends on the architecture:
0d16217
0d16217
*   `-fstack-clash-protection`: Turn on instrumentation to avoid
0d16217
    skipping the guard page in large stack frames.  (Without this flag,
0d16217
    vulnerabilities can result where the stack overlaps with the heap,
0d16217
    or thread stacks spill into other regions of memory.)  This flag is
0d16217
    fully ABI-compatible and has adds very little run-time overhead, but
5b96b31
    is only available on certain architectures (currently aarch64, i386,
72b1044
    ppc64, ppc64le, s390x, x86_64).
6b620c9
*   `-fcf-protection`: Instrument binaries to guard against
1b296f0
    ROP/JOP attacks.  Used on i686 and x86_64.
0d16217
*   `-m64` and `-m32`: Some GCC builds support both 32-bit and 64-bit in
0d16217
    the same compilation.  For such architectures, the RPM build process
0d16217
    explicitly selects the architecture variant by passing this compiler
0d16217
    flag.
0d16217
*   `-fasynchronous-unwind-tables`: Generate full unwind information
0d16217
    covering all program points.  This is required for support of
0d16217
    asynchronous cancellation and proper unwinding from signal
e43ce31
    handlers.  It also makes performance and debugging tools more
e43ce31
    useful because unwind information is available without having to
e43ce31
    install (and load) debugging ienformation.
f25f1b7
    Asynchronous unwind tables are enabled for aarch64, i686, ppc64,
f25f1b7
    ppc64le, s390x, and x86_64.  They are not needed on armhfp due to
f25f1b7
    architectural differences in stack management.  On these
e43ce31
    architectures, `-fexceptions` (see above) still enables regular
e43ce31
    unwind tables (or they are enabled by default even without this
e43ce31
    option).
0d16217
0d16217
In addition, `redhat-rpm-config` re-selects the built-in default
0d16217
tuning in the `gcc` package.  These settings are:
0d16217
0d16217
*   **armhfp**: `-march=armv7-a -mfpu=vfpv3-d16  -mfloat-abi=hard`
0d16217
    selects an Arm subarchitecture based on the ARMv7-A architecture
75a53b7
    with 16 64-bit floating point registers.  `-mtune=cortex-8a` selects
75a53b7
    tuning for the Cortex-A8 implementation (while preserving compatibility
75a53b7
    with other ARMv7-A implementations).  `-mabi=aapcs-linux` switches to
75a53b7
    the AAPCS ABI for GNU/Linux.
0d16217
*   **i686**: `-march=i686` is used to select a minmum support CPU level
a5c9843
    of i686 (corresponding to the Pentium Pro).  SSE2 support is
a5c9843
    enabled with `-msse2` (so only CPUs with SSE2 support can run the
a5c9843
    compiled code; SSE2 was introduced first with the Pentium 4).
a5c9843
    `-mtune=generic` activates tuning for a current blend of CPUs
a5c9843
    (under the assumption that most users of i686 packages obtain them
a5c9843
    through an x86_64 installation on current hardware).
a5c9843
    `-mfpmath=sse` instructs GCC to use the SSE2 unit for floating
a5c9843
    point math to avoid excess precision issues.  `-mstackrealign`
a5c9843
    avoids relying on the stack alignment guaranteed by the current
a5c9843
    version of the i386 ABI.
0d16217
*   **ppc64le**: `-mcpu=power8 -mtune=power8` selects a minimum supported
0d16217
    CPU level of POWER8 (the first CPU with ppc64le support) and tunes
0d16217
    for POWER8.
0d16217
*   **s390x**: `-march=zEC12 -mtune=z13` specifies a minimum supported CPU
0d16217
    level of zEC12, while optimizing for a subsequent CPU generation
0d16217
    (z13).
72b1044
*   **x86_64**: `-mtune=generic` selects tuning which is expected to
0d16217
     beneficial for a broad range of current CPUs.
0d16217
*   **ppc64** and **aarch64** do not have any architecture-specific tuning.
0d16217
0d16217
# Individual linker flags
0d16217
0d16217
Linker flags end up in the environment variable `LDFLAGS`.
0d16217
0d16217
The linker flags listed below are injected.  Note that they are
0d16217
prefixed with `-Wl` because it is expected that these flags are passed
0d16217
to the compiler driver `gcc`, and not directly to the link editor
0d16217
`ld`.
0d16217
0d16217
* `-z relro`: Activate the *read-only after relocation* feature.
0d16217
  Constant data and relocations are placed on separate pages, and the
0d16217
  dynamic linker is instructed to revoke write permissions after
0d16217
  dynamic linking.  Full protection of relocation data requires the
0d16217
  `-z now` flag (see below).
c873752
* `-z defs`: Refuse to link shared objects (DSOs) with undefined symbols
8d6c6d0
  (optional, see above).
0d16217
0d16217
For hardened builds, the
0d16217
`-specs=/usr/lib/rpm/redhat/redhat-hardened-ld` flag is added to the
0d16217
compiler driver command line.  (This can be disabled by undefining the
0d16217
`%_hardened_build` macro; see above) This activates the following
0d16217
linker flags:
0d16217
0d16217
* `-pie`: Produce a PIE binary.  This is only activated for the main
0d16217
  executable, and only if it is dynamically linked.  This requires
0d16217
  that all objects which are linked in the main executable have been
0d16217
  compiled with `-fPIE` or `-fPIC` (or `-fpie` or `-fpic`; see above).
0d16217
  By itself, `-pie` has only a slight performance impact because it
0d16217
  disables some link editor optimization, however the `-fPIE` compiler
0d16217
  flag has some overhead.
0d16217
* `-z now`: Disable lazy binding and turn on the `BIND_NOW` dynamic
0d16217
  linker feature.  Lazy binding involves an array of function pointers
0d16217
  which is writable at run time (which could be overwritten as part of
0d16217
  security exploits, redirecting execution).  Therefore, it is
0d16217
  preferable to turn of lazy binding, although it increases startup
0d16217
  time.
e80fa13
e80fa13
# Support for extension builders
e80fa13
e80fa13
Some packages include extension builders that allow users to build
e80fa13
extension modules (which are usually written in C and C++) under the
e80fa13
control of a special-purpose build system.  This is a common
e80fa13
functionality provided by scripting languages such as Python and Perl.
e80fa13
Traditionally, such extension builders captured the Fedora build flags
e80fa13
when these extension were built.  However, these compiler flags are
e80fa13
adjusted for a specific Fedora release and toolchain version and
e80fa13
therefore do not work with a custom toolchain (e.g., different C/C++
e80fa13
compilers), and users might want to build their own extension modules
e80fa13
with such toolchains.
e80fa13
e80fa13
The macros `%{extension_cflags}`, `%{extension_cxxflags}`,
e80fa13
`%{extension_fflags}`, `%{extension_ldflags}` contain a subset of
e80fa13
flags that have been adjusted for compatibility with alternative
e80fa13
toolchains, while still preserving some of the compile-time security
e80fa13
hardening that the standard Fedora build flags provide.
e80fa13
e80fa13
The current set of differences are:
e80fa13
e80fa13
* No GCC plugins (such as annobin) are activated.
e80fa13
* No GCC spec files (`-specs=` arguments) are used.
e80fa13
e80fa13
Additional flags may be removed in the future if they prove to be
e80fa13
incompatible with alternative toolchains.
e80fa13
e80fa13
Extension builders should detect whether they are performing a regular
e80fa13
RPM build (e.g., by looking for an `RPM_OPT_FLAGS` variable).  In this
e80fa13
case, they should use the *current* set of Fedora build flags (that
e80fa13
is, the output from `rpm --eval '%{build_cflags}'` and related
e80fa13
commands).  Otherwise, when not performing an RPM build, they can
e80fa13
either use hard-coded extension builder flags (thus avoiding a
e80fa13
run-time dependency on `redhat-rpm-config`), or use the current
e80fa13
extension builder flags (with a run-time dependency on
e80fa13
`redhat-rpm-config`).
e80fa13
e80fa13
As a result, extension modules built for Fedora will use the official
e80fa13
Fedora build flags, while users will still be able to build their own
e80fa13
extension modules with custom toolchains.