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