diff --git a/SOURCES/buildflags.md b/SOURCES/buildflags.md index 033c070..58a27ad 100644 --- a/SOURCES/buildflags.md +++ b/SOURCES/buildflags.md @@ -13,6 +13,8 @@ this: 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`, @@ -25,7 +27,8 @@ environment variables using %set_build_flags early in the `%build` section. (Again, existing environment variables -are not overwritten.) +are not overwritten.) `%set_build_flags` does not perform autotools +script rewriting, unlike `%configure`. Individual build flags are also available through RPM macros: @@ -69,12 +72,70 @@ For other considerations involving shared objects, see: * [Fedora Packaging Guidelines: Shared Libraries](https://docs.fedoraproject.org/en-US/packaging-guidelines/#_shared_libraries) -# Customizing compiler flags +# 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 @@ -116,6 +177,21 @@ 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 @@ -160,6 +236,72 @@ it is possible to add `-fcommon` to the flags by defining `%_legacy_common_suppo 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`, @@ -206,6 +348,12 @@ The general (architecture-independent) build flags are: 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 @@ -217,9 +365,22 @@ The general (architecture-independent) build flags are: 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 @@ -247,49 +408,25 @@ command line. It adds the following flag to the command line: 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. This can be switched off by undefining the -`%_annotated_build` RPM macro (see above). +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: -* `-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, but - is only available on certain architectures (currently aarch64, i386, - ppc64, ppc64le, s390x, x86_64). * `-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. -* `-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 ienformation. - Asynchronous unwind tables are enabled for aarch64, i686, ppc64, - ppc64le, s390x, and x86_64. They are not needed on armhfp due to - architectural differences in stack management. On these - architectures, `-fexceptions` (see above) still enables regular - unwind tables (or they are enabled by default even without this - option). In addition, `redhat-rpm-config` re-selects the built-in default tuning in the `gcc` package. These settings are: -* **armhfp**: `-march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=hard` - selects an Arm subarchitecture based on the ARMv7-A architecture - with 16 64-bit floating point registers. `-mtune=cortex-8a` selects - tuning for the Cortex-A8 implementation (while preserving compatibility - with other ARMv7-A implementations). `-mabi=aapcs-linux` switches to - the AAPCS ABI for GNU/Linux. * **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 @@ -301,15 +438,16 @@ tuning in the `gcc` package. These settings are: 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=power8 -mtune=power8` selects a minimum supported - CPU level of POWER8 (the first CPU with ppc64le support) and tunes - for POWER8. -* **s390x**: `-march=zEC12 -mtune=z13` specifies a minimum supported CPU - level of zEC12, while optimizing for a subsequent CPU generation - (z13). -* **x86_64**: `-mtune=generic` selects tuning which is expected to - beneficial for a broad range of current CPUs. -* **ppc64** and **aarch64** do not have any architecture-specific tuning. +* **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 @@ -325,6 +463,10 @@ to the compiler driver `gcc`, and not directly to the link editor 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). diff --git a/SOURCES/macros b/SOURCES/macros index 7a1b333..81471b0 100644 --- a/SOURCES/macros +++ b/SOURCES/macros @@ -37,29 +37,6 @@ %__cpp_clang clang-cpp # Default to the GCC toolchain -# -# 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 -# %toolchain gcc %__cc %{expand:%%{__cc_%{toolchain}}} diff --git a/SOURCES/macros.vpath b/SOURCES/macros.vpath index a37f1f9..93723a2 100644 --- a/SOURCES/macros.vpath +++ b/SOURCES/macros.vpath @@ -4,4 +4,4 @@ %_vpath_srcdir . # directory (doesn't need to exist) where all generated build files will be placed -%_vpath_builddir %_target_platform +%_vpath_builddir %{_vendor}-%{_target_os}-build diff --git a/SPECS/redhat-rpm-config.spec b/SPECS/redhat-rpm-config.spec index 6246479..3921bca 100644 --- a/SPECS/redhat-rpm-config.spec +++ b/SPECS/redhat-rpm-config.spec @@ -6,7 +6,7 @@ Summary: Red Hat specific rpm configuration files Name: redhat-rpm-config -Version: 188 +Version: 190 Release: 1%{?dist} # No version specified. License: GPL+ @@ -189,6 +189,13 @@ install -p -m 644 -t %{buildroot}%{_rpmluadir}/fedora/srpm forge.lua %doc buildflags.md %changelog +* Thu Dec 02 2021 Neal Gompa - 190-1 +- Make vpath builddir not include arch-specific info + Resolves: rhbz#1984679 + +* Tue Nov 16 2021 Florian Weimer - 189-1 +- buildflags.md: Documentation updates (#2005080) + * Tue Aug 24 2021 Florian Weimer - 188-1 - redhat-rpm-config: Enable x86-64-v2 baseline for Clang/LLVM (#1890170)