Blame SOURCES/buildflags.md

f9efe2
This document contains documentation of the individual compiler flags
f9efe2
and how to use them.
f9efe2
f9efe2
[TOC]
f9efe2
f9efe2
# Using RPM build flags
f9efe2
f9efe2
For packages which use autoconf to set up the build environment, use
f9efe2
the `%configure` macro to obtain the full complement of flags, like
f9efe2
this:
f9efe2
f9efe2
    %configure
f9efe2
f9efe2
This will invoke the `./configure` with arguments (such as
f9efe2
`--prefix=/usr`) to adjust the paths to the packaging defaults.
f9efe2
Prior to that, some common problems in autotools scripts are
f9efe2
automatically patched across the source tree.
f9efe2
f9efe2
As a side effect, this will set the environment variables `CFLAGS`,
f9efe2
`CXXFLAGS`, `FFLAGS`, `FCFLAGS`, `LDFLAGS` and `LT_SYS_LIBRARY_PATH`,
f9efe2
so they can be used by makefiles and other build tools.  (However,
f9efe2
existing values for these variables are not overwritten.)
f9efe2
f9efe2
If your package does not use autoconf, you can still set the same
f9efe2
environment variables using
f9efe2
f9efe2
    %set_build_flags
f9efe2
f9efe2
early in the `%build` section.  (Again, existing environment variables
f9efe2
are not overwritten.)  `%set_build_flags` does not perform autotools
f9efe2
script rewriting, unlike `%configure`.
f9efe2
f9efe2
Individual build flags are also available through RPM macros:
f9efe2
f9efe2
* `%{build_cflags}` for the C compiler flags (also known as the
f9efe2
  `CFLAGS` variable).  Also historically available as `%{optflags}`.
f9efe2
  Furthermore, at the start of the `%build` section, the environment
f9efe2
  variable `RPM_OPT_FLAGS` is set to this value.
f9efe2
* `%{build_cxxflags}` for the C++ compiler flags (usually assigned to
f9efe2
  the `CXXFLAGS` shell variable).
f9efe2
* `%{build_fflags} for `FFLAGS` (the Fortran compiler flags, also
f9efe2
  known as the `FCFLAGS` variable).
f9efe2
* `%{build_ldflags}` for the link editor (ld) flags, usually known as
f9efe2
  `LDFLAGS`.  Note that the contents quotes linker arguments using
f9efe2
  `-Wl`, so this variable is intended for use with the `gcc` compiler
f9efe2
  driver.  At the start of the `%build` section, the environment
f9efe2
  variable `RPM_LD_FLAGS` is set to this value.
f9efe2
f9efe2
The variable `LT_SYS_LIBRARY_PATH` is defined here to prevent the `libtool`
f9efe2
script (v2.4.6+) from hardcoding %_libdir into the binaries' RPATH.
f9efe2
f9efe2
These RPM macros do not alter shell environment variables.
f9efe2
f9efe2
For some other build tools separate mechanisms exist:
f9efe2
f9efe2
* CMake builds use the the `%cmake` macro from the `cmake-rpm-macros`
f9efe2
  package.
f9efe2
f9efe2
Care must be taking not to compile the current selection of compiler
f9efe2
flags into any RPM package besides `redhat-rpm-config`, so that flag
f9efe2
changes are picked up automatically once `redhat-rpm-config` is
f9efe2
updated.
f9efe2
f9efe2
# Flag selection for the build type
f9efe2
f9efe2
The default flags are suitable for building applications.
f9efe2
f9efe2
For building shared objects, you must compile with `-fPIC` in
f9efe2
(`CFLAGS` or `CXXFLAGS`) and link with `-shared` (in `LDFLAGS`).
f9efe2
f9efe2
For other considerations involving shared objects, see:
f9efe2
f9efe2
* [Fedora Packaging Guidelines: Shared Libraries](https://docs.fedoraproject.org/en-US/packaging-guidelines/#_shared_libraries)
f9efe2
f9efe2
# Customizing compiler and other build flags
f9efe2
f9efe2
It is possible to set RPM macros to change some aspects of the
f9efe2
compiler flags.  Changing these flags should be used as a last
f9efe2
recourse if other workarounds are not available.
f9efe2
f9efe2
### Toolchain selection
f9efe2
f9efe2
The default toolchain uses GCC, and the `%toolchain` macro is defined
f9efe2
as `gcc`.
f9efe2
f9efe2
It is enough to override `toolchain` macro and all relevant macro for C/C++
f9efe2
compilers will be switched. Either in the spec or in the command-line.
f9efe2
f9efe2
    %global toolchain clang
f9efe2
f9efe2
or:
f9efe2
f9efe2
    rpmbuild -D "toolchain clang" …
f9efe2
f9efe2
Inside a spec file it is also possible to determine which toolchain is in use
f9efe2
by testing the same macro. For example:
f9efe2
f9efe2
    %if "%{toolchain}" == "gcc"
f9efe2
    BuildRequires: gcc
f9efe2
    %endif
f9efe2
f9efe2
or:
f9efe2
f9efe2
    %if "%{toolchain}" == "clang"
f9efe2
    BuildRequires: clang compiler-rt
f9efe2
    %endif
f9efe2
f9efe2
### Disable autotools compatibility patching
f9efe2
f9efe2
By default, the invocation of the `%configure` macro replaces
f9efe2
`config.guess` files in the source tree with the system version.  To
f9efe2
disable that, define this macro:
f9efe2
f9efe2
    %global _configure_gnuconfig_hack 0
f9efe2
f9efe2
`%configure` also patches `ltmain.sh` scripts, so that linker flags
f9efe2
are set as well during libtool-.  This can be switched off using:
f9efe2
f9efe2
    %global _configure_libtool_hardening_hack 0
f9efe2
f9efe2
Further patching happens in LTO mode, see below.
f9efe2
f9efe2
### Disabling Link-Time Optimization
f9efe2
f9efe2
By default, builds use link-time optimization.  In this build mode,
f9efe2
object code is generated at the time of the final link, by combining
f9efe2
information from all available translation units, and taking into
f9efe2
account which symbols are exported.
f9efe2
f9efe2
To disable this optimization, include this in the spec file:
f9efe2
f9efe2
   %define _lto_cflags %{nil}
f9efe2
f9efe2
If LTO is enabled, `%configure` applies some common required fixes to
f9efe2
`configure` scripts.  To disable that, define the RPM macro
f9efe2
`_fix_broken_configure_for_lto` as `true` (sic; it has to be a shell
f9efe2
command).
f9efe2
f9efe2
### Lazy binding
f9efe2
f9efe2
If your package depends on the semantics of lazy binding (e.g., it has
f9efe2
plugins which load additional plugins to complete their dependencies,
f9efe2
before which some referenced functions are undefined), you should put
f9efe2
`-Wl,-z,lazy` at the end of the `LDFLAGS` setting when linking objects
f9efe2
which have such requirements.  Under these circumstances, it is
f9efe2
unnecessary to disable hardened builds (and thus lose full ASLR for
f9efe2
executables), or link everything without `-Wl,z,now` (non-lazy
f9efe2
binding).
f9efe2
f9efe2
### Hardened builds
f9efe2
f9efe2
By default, the build flags enable fully hardened builds.  To change
f9efe2
this, include this in the RPM spec file:
f9efe2
f9efe2
    %undefine _hardened_build
f9efe2
f9efe2
This turns off certain hardening features, as described in detail
f9efe2
below.  The main difference is that executables will be
f9efe2
position-dependent (no full ASLR) and use lazy binding.
f9efe2
f9efe2
### Annotated builds/watermarking
f9efe2
f9efe2
By default, the build flags cause a special output section to be
f9efe2
included in ELF files which describes certain aspects of the build.
f9efe2
To change this for all compiler invocations, include this in the RPM
f9efe2
spec file:
f9efe2
f9efe2
    %undefine _annotated_build
f9efe2
f9efe2
Be warned that this turns off watermarking, making it impossible to do
f9efe2
full hardening coverage analysis for any binaries produced.
f9efe2
f9efe2
It is possible to disable annotations for individual compiler
f9efe2
invocations, using the `-fplugin-arg-annobin-disable` flag.  However,
f9efe2
the annobin plugin must still be loaded for this flag to be
f9efe2
recognized, so it has to come after the hardening flags on the command
f9efe2
line (it has to be added at the end of `CFLAGS`, or specified after
f9efe2
the `CFLAGS` variable contents).
f9efe2
f9efe2
### Keeping dependencies on unused shared objects
f9efe2
f9efe2
By default, ELF shared objects which are listed on the linker command
f9efe2
line, but which have no referencing symbols in the preceding objects,
f9efe2
are not added to the output file during the final link.
f9efe2
f9efe2
In order to keep dependencies on shared objects even if none of
f9efe2
their symbols are used, include this in the RPM spec file:
f9efe2
f9efe2
    %undefine _ld_as_needed
f9efe2
f9efe2
For example, this can be required if shared objects are used for their
f9efe2
side effects in ELF constructors, or for making them available to
f9efe2
dynamically loaded plugins.
f9efe2
f9efe2
### Strict symbol checks in the link editor (ld)
f9efe2
f9efe2
Optionally, the link editor will refuse to link shared objects which
f9efe2
contain undefined symbols.  Such symbols lack symbol versioning
f9efe2
information and can be bound to the wrong (compatibility) symbol
f9efe2
version at run time, and not the actual (default) symbol version which
f9efe2
would have been used if the symbol definition had been available at
f9efe2
static link time.  Furthermore, at run time, the dynamic linker will
f9efe2
not have complete dependency information (in the form of DT_NEEDED
f9efe2
entries), which can lead to errors (crashes) if IFUNC resolvers are
f9efe2
executed before the shared object containing them is fully relocated.
f9efe2
f9efe2
To switch on these checks, define this macro in the RPM spec file:
f9efe2
f9efe2
    %define _strict_symbol_defs_build 1
f9efe2
f9efe2
If this RPM spec option is active, link failures will occur if the
f9efe2
linker command line does not list all shared objects which are needed.
f9efe2
In this case, you need to add the missing DSOs (with linker arguments
f9efe2
such as `-lm`).  As a result, the link editor will also generated the
f9efe2
necessary DT_NEEDED entries.
f9efe2
f9efe2
In some cases (such as when a DSO is loaded as a plugin and is
f9efe2
expected to bind to symbols in the main executable), undefined symbols
f9efe2
are expected.  In this case, you can add
f9efe2
f9efe2
    %undefine _strict_symbol_defs_build
f9efe2
f9efe2
to the RPM spec file to disable these strict checks.  Alternatively,
f9efe2
you can pass `-z undefs` to ld (written as `-Wl,-z,undefs` on the gcc
f9efe2
command line).  The latter needs binutils 2.29.1-12.fc28 or later.
f9efe2
f9efe2
### Legacy -fcommon
f9efe2
f9efe2
Since version 10, [gcc defaults to `-fno-common`](https://gcc.gnu.org/gcc-10/porting_to.html#common).
f9efe2
Builds may fail with `multiple definition of ...` errors.
f9efe2
f9efe2
As a short term workaround for such failure,
f9efe2
it is possible to add `-fcommon` to the flags by defining `%_legacy_common_support`.
f9efe2
f9efe2
    %define _legacy_common_support 1
f9efe2
f9efe2
Properly fixing the failure is always preferred!
f9efe2
f9efe2
### Post-build ELF object processing
f9efe2
f9efe2
By default, DWARF debugging information is separated from installed
f9efe2
ELF objects and put into `-debuginfo` subpackages.  To disable most
f9efe2
debuginfo processing (and thus the generation of these subpackages),
f9efe2
define `_enable_debug_packages` as `0`.
f9efe2
f9efe2
Processing of debugging information is controlled using the
f9efe2
`find-debuginfo` tool from the `debugedit` package.  Several aspects
f9efe2
of its operation can be controlled at the RPM level.
f9efe2
f9efe2
* Creation of `-debuginfo` subpackages is enabled by default.
f9efe2
  To disable, undefine `_debuginfo_subpackages`.
f9efe2
* Likewise, `-debugsource` subpackages are automatically created.
f9efe2
  To disable, undefine `_debugsource_subpackages`.
f9efe2
  See [Separate Subpackage and Source Debuginfo](https://fedoraproject.org/wiki/Changes/SubpackageAndSourceDebuginfo)
f9efe2
  for background information.
f9efe2
* `_build_id_links`, `_unique_build_ids`, `_unique_debug_names`,
f9efe2
  `_unique_debug_srcs` control how debugging information and
f9efe2
  corresponding source files are represented on disk.
f9efe2
  See `/usr/lib/rpm/macros` for details.  The defaults
f9efe2
  enable parallel installation of `-debuginfo` packages for
f9efe2
  different package versions, as described in
f9efe2
  [Parallel Installable Debuginfo](https://fedoraproject.org/wiki/Changes/ParallelInstallableDebuginfo).
f9efe2
* By default, a compressed symbol table is preserved in the
f9efe2
  `.gnu_debugdata` section.  To disable that, undefine
f9efe2
  `_include_minidebuginfo`.
f9efe2
* To speed up debuggers, a `.gdb_index` section is created.  It can be
f9efe2
  disabled by undefining `_include_gdb_index`.
f9efe2
* Missing build IDs result in a build failure.  To ignore such
f9efe2
  problems, undefine `_missing_build_ids_terminate_build`.
f9efe2
* During processing, build IDs are recomputed to match the binary
f9efe2
  content.  To skip this step, define `_no_recompute_build_ids` as `1`.
f9efe2
* By default, the options in `_find_debuginfo_dwz_opts` turn on `dwz`
f9efe2
  (DWARF compression) processing.  Undefine this macro to disable this
f9efe2
  step.
f9efe2
* Additional options can be passed by defining the
f9efe2
  `_find_debuginfo_opts` macro.
f9efe2
f9efe2
After separation of debugging information, additional transformations
f9efe2
are applied, most of them also related to debugging information.
f9efe2
These steps can be skipped by undefining the corresponding macros:
f9efe2
f9efe2
* `__brp_strip`: Removal of leftover debugging information.  The tool
f9efe2
  specified by the `__strip` macro is invoked with the `-g` option on
f9efe2
  ELF object (`.o`) files.
f9efe2
* `__brp_strip_static_archive`: This is similar to `__brp_strip`, but
f9efe2
  processes static `.a` archives instead.
f9efe2
* `__brp_strip_comment_note`: This step removes unallocated `.note`
f9efe2
  sections, and `.comment` sections from ELF files.
f9efe2
* `__brp_strip_lto`: This step removes GCC LTO intermediate representation
f9efe2
  in ELF sections starting with `.gnu.lto_` and `.gnu.debuglto_`.  Skipping
f9efe2
  this step is strongly discouraged because the tight coupling of LTO
f9efe2
  data with the GCC version.  The underlying tool is again determined by the
f9efe2
  `__strip` macro.
f9efe2
* `__brp_llvm_compile_lto_elf`: This step replaces LLVM bitcode files
f9efe2
  with object files, thereby removing LLVM bitcode from the installed
f9efe2
  files.  This transformation is applied to object files in static `.a`
f9efe2
  archives, too.
f9efe2
* `__brp_ldconfig`: For each shared object on the library search path
f9efe2
  whose soname does not match its file name, a symbolic link from the
f9efe2
  soname to the file name is created.  This way, these shared objects
f9efe2
  are loadable immediately after installation, even if they are not yet
f9efe2
  listed in the `/etc/ld.so.cache` file (because `ldconfig` has not been
f9efe2
  invoked yet).
f9efe2
f9efe2
# Individual compiler flags
f9efe2
f9efe2
Compiler flags end up in the environment variables `CFLAGS`,
f9efe2
`CXXFLAGS`, `FFLAGS`, and `FCFLAGS`.
f9efe2
f9efe2
The general (architecture-independent) build flags are:
f9efe2
f9efe2
* `-O2`: Turn on various GCC optimizations.  See the [GCC manual](https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-O2).
f9efe2
  Optimization improves performance, the accuracy of warnings, and the
f9efe2
  reach of toolchain-based hardening, but it makes debugging harder.
f9efe2
* `-g`: Generate debugging information (DWARF).  In Fedora, this data
f9efe2
  is separated into `-debuginfo` RPM packages whose installation is
f9efe2
  optional, so debuging information does not increase the size of
f9efe2
  installed binaries by default.
f9efe2
* `-pipe`: Run compiler and assembler in parallel and do not use a
f9efe2
  temporary file for the assembler input.  This can improve
f9efe2
  compilation performance.  (This does not affect code generation.)
f9efe2
* `-Wall`: Turn on various GCC warnings.
f9efe2
  See the [GCC manual](https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wall).
f9efe2
* `-Werror=format-security`: Turn on format string warnings and treat
f9efe2
  them as errors.
f9efe2
  See the [GCC manual](https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wformat-security).
f9efe2
  This can occasionally result in compilation errors.  In this case,
f9efe2
  the best option is to rewrite the source code so that only constant
f9efe2
  format strings (string literals) are used.
f9efe2
* `-Wp,-D_FORTIFY_SOURCE=2`: Source fortification activates various
f9efe2
  hardening features in glibc:
f9efe2
    * String functions such as `memcpy` attempt to detect buffer lengths
f9efe2
      and terminate the process if a buffer overflow is detected.
f9efe2
    * `printf` format strings may only contain the `%n` format specifier
f9efe2
      if the format string resides in read-only memory.
f9efe2
    * `open` and `openat` flags are checked for consistency with the
f9efe2
      presence of a *mode* argument.
f9efe2
    * Plus other minor hardening changes.
f9efe2
  (These changes can occasionally break valid programs.)
f9efe2
* `-fexceptions`: Provide exception unwinding support for C programs.
f9efe2
  See the [`-fexceptions` option in the GCC
f9efe2
  manual](https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#index-fexceptions)
f9efe2
  and the [`cleanup` variable
f9efe2
  attribute](https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-cleanup-variable-attribute).
f9efe2
  This also hardens cancellation handling in C programs because
f9efe2
  it is not required to use an on-stack jump buffer to install
f9efe2
  a cancellation handler with `pthread_cleanup_push`.  It also makes
f9efe2
  it possible to unwind the stack (using C++ `throw` or Rust panics)
f9efe2
  from C callback functions if a C library supports non-local exits
f9efe2
  from them (e.g., via `longjmp`).
f9efe2
* `-fasynchronous-unwind-tables`: Generate full unwind information
f9efe2
  covering all program points.  This is required for support of
f9efe2
  asynchronous cancellation and proper unwinding from signal
f9efe2
  handlers.  It also makes performance and debugging tools more
f9efe2
  useful because unwind information is available without having to
f9efe2
  install (and load) debugging information.
f9efe2
* `-Wp,-D_GLIBCXX_ASSERTIONS`: Enable lightweight assertions in the
f9efe2
  C++ standard library, such as bounds checking for the subscription
f9efe2
  operator on vectors.  (This flag is added to both `CFLAGS` and
f9efe2
  `CXXFLAGS`; C compilations will simply ignore it.)
f9efe2
* `-fstack-protector-strong`: Instrument functions to detect
f9efe2
  stack-based buffer overflows before jumping to the return address on
f9efe2
  the stack.  The *strong* variant only performs the instrumentation
f9efe2
  for functions whose stack frame contains addressable local
f9efe2
  variables.  (If the address of a variable is never taken, it is not
f9efe2
  possible that a buffer overflow is caused by incorrect pointer
f9efe2
  arithmetic involving a pointer to that variable.)
f9efe2
* `-fstack-clash-protection`: Turn on instrumentation to avoid
f9efe2
  skipping the guard page in large stack frames.  (Without this flag,
f9efe2
  vulnerabilities can result where the stack overlaps with the heap,
f9efe2
  or thread stacks spill into other regions of memory.)  This flag is
f9efe2
  fully ABI-compatible and has adds very little run-time overhead.
f9efe2
  This flag is currently not available on aarch64 with the `clang` toolchain.
f9efe2
* `-flto=auto`: Enable link-time optimization (LTO), using `make` job server
f9efe2
  integration for parallel processing.  (`gcc` toolchain only)
f9efe2
* `-ffat-lto-objects`: Generate EFL object files which contain both
f9efe2
  object code and LTO intermediate representation.  (`gcc` toolchain only)
f9efe2
* `-flto`: Enable link-time optimization. (`clang` toolchain only)
f9efe2
* `-grecord-gcc-switches`: Include select GCC command line switches in
f9efe2
  the DWARF debugging information.  This is useful for detecting the
f9efe2
  presence of certain build flags and general hardening coverage.
f9efe2
* `-fcommon`: This optional flag is used to build legacy software
f9efe2
  which relies on C tentative definitions.  It is disabled by default.
f9efe2
f9efe2
For hardened builds (which are enabled by default, see above for how
f9efe2
to disable them), the flag
f9efe2
`-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1` is added to the
f9efe2
command line.  It adds the following flag to the command line:
f9efe2
f9efe2
*   `-fPIE`: Compile for a position-independent executable (PIE),
f9efe2
    enabling full address space layout randomization (ASLR).  This is
f9efe2
    similar to `-fPIC`, but avoids run-time indirections on certain
f9efe2
    architectures, resulting in improved performance and slightly
f9efe2
    smaller executables.  However, compared to position-dependent code
f9efe2
    (the default generated by GCC), there is still a measurable
f9efe2
    performance impact.
f9efe2
f9efe2
    If the command line also contains `-r` (producing a relocatable
f9efe2
    object file), `-fpic` or `-fPIC`, this flag is automatically
f9efe2
    dropped.  (`-fPIE` can only be used for code which is linked into
f9efe2
    the main program.) Code which goes into static libraries should be
f9efe2
    compiled with `-fPIE`, except when this code is expected to be
f9efe2
    linked into DSOs, when `-fPIC` must be used.
f9efe2
f9efe2
    To be effective, `-fPIE` must be used with the `-pie` linker flag
f9efe2
    when producing an executable, see below.
f9efe2
f9efe2
To support [binary watermarks for ELF
f9efe2
objects](https://fedoraproject.org/wiki/Toolchain/Watermark) using
f9efe2
annobin, the `-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1` flag is
f9efe2
added by default (with the `gcc` toolchain).  This can be switched off
f9efe2
by undefining the `%_annotated_build` RPM macro (see above).  Binary
f9efe2
watermarks are currently disabled with the `clang` toolchain.
f9efe2
f9efe2
### Architecture-specific compiler flags
f9efe2
f9efe2
These compiler flags are enabled for all builds (hardened/annotated or
f9efe2
not), but their selection depends on the architecture:
f9efe2
f9efe2
*   `-fcf-protection`: Instrument binaries to guard against
f9efe2
    ROP/JOP attacks.  Used on i686 and x86_64.
f9efe2
*   `-m64` and `-m32`: Some GCC builds support both 32-bit and 64-bit in
f9efe2
    the same compilation.  For such architectures, the RPM build process
f9efe2
    explicitly selects the architecture variant by passing this compiler
f9efe2
    flag.
f9efe2
f9efe2
In addition, `redhat-rpm-config` re-selects the built-in default
f9efe2
tuning in the `gcc` package.  These settings are:
f9efe2
f9efe2
*   **i686**: `-march=i686` is used to select a minmum support CPU level
f9efe2
    of i686 (corresponding to the Pentium Pro).  SSE2 support is
f9efe2
    enabled with `-msse2` (so only CPUs with SSE2 support can run the
f9efe2
    compiled code; SSE2 was introduced first with the Pentium 4).
f9efe2
    `-mtune=generic` activates tuning for a current blend of CPUs
f9efe2
    (under the assumption that most users of i686 packages obtain them
f9efe2
    through an x86_64 installation on current hardware).
f9efe2
    `-mfpmath=sse` instructs GCC to use the SSE2 unit for floating
f9efe2
    point math to avoid excess precision issues.  `-mstackrealign`
f9efe2
    avoids relying on the stack alignment guaranteed by the current
f9efe2
    version of the i386 ABI.
f9efe2
*   **ppc64le**: `-mcpu=power9 -mtune=power9` selects a minimum supported
f9efe2
    CPU level of POWER9.
f9efe2
*   **s390x**: `-march=z14 -mtune=z15` specifies a minimum supported CPU
f9efe2
    level of z14, while optimizing for a subsequent CPU generation
f9efe2
    (z15).
f9efe2
*   **x86_64**: `-march=x86-64-v2 -mtune=generic` builds for the
f9efe2
    [x86-64-v2 micro-architecture level](https://gitlab.com/x86-psABIs/x86-64-ABI/-/blob/master/x86-64-ABI/low-level-sys-info.tex)
f9efe2
    and selects tuning which is expected to beneficial for a broad range
f9efe2
    of current CPUs.
f9efe2
*   **aarch64** does not have any architecture-specific tuning.
f9efe2
f9efe2
# Individual linker flags
f9efe2
f9efe2
Linker flags end up in the environment variable `LDFLAGS`.
f9efe2
f9efe2
The linker flags listed below are injected.  Note that they are
f9efe2
prefixed with `-Wl` because it is expected that these flags are passed
f9efe2
to the compiler driver `gcc`, and not directly to the link editor
f9efe2
`ld`.
f9efe2
f9efe2
* `-z relro`: Activate the *read-only after relocation* feature.
f9efe2
  Constant data and relocations are placed on separate pages, and the
f9efe2
  dynamic linker is instructed to revoke write permissions after
f9efe2
  dynamic linking.  Full protection of relocation data requires the
f9efe2
  `-z now` flag (see below).
f9efe2
* `--as-needed`: In the final link, only generate ELF dependencies
f9efe2
  for shared objects that actually provide symbols required by the link.
f9efe2
  Shared objects which are not needed to fulfill symbol dependencies
f9efe2
  are essentially ignored due to this flag.
f9efe2
* `-z defs`: Refuse to link shared objects (DSOs) with undefined symbols
f9efe2
  (optional, see above).
f9efe2
f9efe2
For hardened builds, the
f9efe2
`-specs=/usr/lib/rpm/redhat/redhat-hardened-ld` flag is added to the
f9efe2
compiler driver command line.  (This can be disabled by undefining the
f9efe2
`%_hardened_build` macro; see above) This activates the following
f9efe2
linker flags:
f9efe2
f9efe2
* `-pie`: Produce a PIE binary.  This is only activated for the main
f9efe2
  executable, and only if it is dynamically linked.  This requires
f9efe2
  that all objects which are linked in the main executable have been
f9efe2
  compiled with `-fPIE` or `-fPIC` (or `-fpie` or `-fpic`; see above).
f9efe2
  By itself, `-pie` has only a slight performance impact because it
f9efe2
  disables some link editor optimization, however the `-fPIE` compiler
f9efe2
  flag has some overhead.
f9efe2
* `-z now`: Disable lazy binding and turn on the `BIND_NOW` dynamic
f9efe2
  linker feature.  Lazy binding involves an array of function pointers
f9efe2
  which is writable at run time (which could be overwritten as part of
f9efe2
  security exploits, redirecting execution).  Therefore, it is
f9efe2
  preferable to turn of lazy binding, although it increases startup
f9efe2
  time.
f9efe2
f9efe2
# Support for extension builders
f9efe2
f9efe2
Some packages include extension builders that allow users to build
f9efe2
extension modules (which are usually written in C and C++) under the
f9efe2
control of a special-purpose build system.  This is a common
f9efe2
functionality provided by scripting languages such as Python and Perl.
f9efe2
Traditionally, such extension builders captured the Fedora build flags
f9efe2
when these extension were built.  However, these compiler flags are
f9efe2
adjusted for a specific Fedora release and toolchain version and
f9efe2
therefore do not work with a custom toolchain (e.g., different C/C++
f9efe2
compilers), and users might want to build their own extension modules
f9efe2
with such toolchains.
f9efe2
f9efe2
The macros `%{extension_cflags}`, `%{extension_cxxflags}`,
f9efe2
`%{extension_fflags}`, `%{extension_ldflags}` contain a subset of
f9efe2
flags that have been adjusted for compatibility with alternative
f9efe2
toolchains, while still preserving some of the compile-time security
f9efe2
hardening that the standard Fedora build flags provide.
f9efe2
f9efe2
The current set of differences are:
f9efe2
f9efe2
* No GCC plugins (such as annobin) are activated.
f9efe2
* No GCC spec files (`-specs=` arguments) are used.
f9efe2
f9efe2
Additional flags may be removed in the future if they prove to be
f9efe2
incompatible with alternative toolchains.
f9efe2
f9efe2
Extension builders should detect whether they are performing a regular
f9efe2
RPM build (e.g., by looking for an `RPM_OPT_FLAGS` variable).  In this
f9efe2
case, they should use the *current* set of Fedora build flags (that
f9efe2
is, the output from `rpm --eval '%{build_cflags}'` and related
f9efe2
commands).  Otherwise, when not performing an RPM build, they can
f9efe2
either use hard-coded extension builder flags (thus avoiding a
f9efe2
run-time dependency on `redhat-rpm-config`), or use the current
f9efe2
extension builder flags (with a run-time dependency on
f9efe2
`redhat-rpm-config`).
f9efe2
f9efe2
As a result, extension modules built for Fedora will use the official
f9efe2
Fedora build flags, while users will still be able to build their own
f9efe2
extension modules with custom toolchains.