From 29d229fb0e5593f8b5afd27bf3f5e726adae99a7 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 6 Dec 2023 10:09:28 +0100 Subject: [PATCH] Use Fat LTO with Clang Currently, when the clang toolchain is used, we use the brp-llvm-compile-lto-to-elf script to post-process any shipped object files or static libraries to convert the LLVM bitcode they contain into ELF object code. With LLVM 18, Clang has introduced support for fat LTO objects (https://llvm.org/docs/FatLTO.html), which work essentially the same way as with GCC: If `-ffat-lto-objects` is passed, then the objects will contain both the ELF code, as well as the LLVM bitcode in a special section. This redhat-rpm-config change enables the use of fat LTO and drops the brp-llvm-compile-lto-to-elf script. Instead, the brp-strip-lto script used by GCC also strips the LLVM section name now. Resolves: RHEL-87634 --- brp-llvm-compile-lto-elf | 54 ---------------------------------------- brp-strip-lto | 3 ++- macros | 5 +--- redhat-rpm-config.spec | 12 +++------ 4 files changed, 7 insertions(+), 67 deletions(-) delete mode 100755 brp-llvm-compile-lto-elf diff --git a/brp-llvm-compile-lto-elf b/brp-llvm-compile-lto-elf deleted file mode 100755 index 1756651..0000000 --- a/brp-llvm-compile-lto-elf +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/bash -eu - - -if [ -z "$RPM_BUILD_ROOT" ] || [ "$RPM_BUILD_ROOT" = "/" ]; then - exit 0 -fi - -CLANG_FLAGS=$@ -NCPUS=${RPM_BUILD_NCPUS:-1} - -check_convert_bitcode () { - local file_name=$(realpath ${1}) - local file_type=$(file ${file_name}) - - shift - CLANG_FLAGS="$@" - - if [[ "${file_type}" == *"LLVM IR bitcode"* ]]; then - # Check the output of llvm-strings for the command line, which is in the LLVM bitcode because - # we pass -frecord-gcc-switches. - # Check for a line that has "-flto" after (or without) "-fno-lto". - llvm-strings ${file_name} | while read line ; do - flto=$(echo $line | grep -o -b -e -flto | tail -n 1 | cut -d : -f 1) - fnolto=$(echo $line | grep -o -b -e -fno-lto | tail -n 1 | cut -d : -f 1) - - if test -n "$flto" && { test -z "$fnolto" || test "$flto" -gt "$fnolto"; } ; then - echo "Compiling LLVM bitcode file ${file_name}." - clang ${CLANG_FLAGS} -fno-lto -Wno-unused-command-line-argument \ - -x ir ${file_name} -c -o ${file_name} - break - fi - done - elif [[ "${file_type}" == *"current ar archive"* ]]; then - echo "Unpacking ar archive ${file_name} to check for LLVM bitcode components." - # create archive stage for objects - local archive_stage=$(mktemp -d) - local archive=${file_name} - pushd ${archive_stage} - ar x ${archive} - for archived_file in $(find -not -type d); do - check_convert_bitcode ${archived_file} ${CLANG_FLAGS} - echo "Repacking ${archived_file} into ${archive}." - ar r ${archive} ${archived_file} - done - popd - fi -} - -echo "Checking for LLVM bitcode artifacts" -export -f check_convert_bitcode -# Deduplicate by device:inode to avoid processing hardlinks in parallel. -find "$RPM_BUILD_ROOT" -type f -name "*.[ao]" -printf "%D:%i %p\n" | \ - awk '!seen[$1]++' | cut -d" " -f2- | \ - xargs -d"\n" -r -n1 -P$NCPUS sh -c "check_convert_bitcode \$@ $CLANG_FLAGS" ARG0 diff --git a/brp-strip-lto b/brp-strip-lto index 8890541..9d36b74 100755 --- a/brp-strip-lto +++ b/brp-strip-lto @@ -14,4 +14,5 @@ esac # Strip ELF binaries find "$RPM_BUILD_ROOT" -type f -name '*.[ao]' \! -regex "$RPM_BUILD_ROOT/*usr/lib/debug.*" -print0 | \ - eu-elfclassify --not-program --not-library --not-linux-kernel-module --stdin0 --print0 | xargs -0 -r -P$NCPUS -n32 sh -c "$STRIP -p -R .gnu.lto_* -R .gnu.debuglto_* -N __gnu_lto_v1 \"\$@\"" ARG0 + eu-elfclassify --not-program --not-library --not-linux-kernel-module --stdin0 --print0 | \ + xargs -0 -r -P$NCPUS -n32 sh -c "$STRIP -p -R .gnu.lto_* -R .gnu.debuglto_* -R .llvm.lto -N __gnu_lto_v1 \"\$@\"" ARG0 diff --git a/macros b/macros index 94165a2..f3c06f0 100644 --- a/macros +++ b/macros @@ -275,8 +275,6 @@ for k,_ in pairs(stripped_flags) do print(k .. " ") end # __brp_mangle_shebangs_exclude_from_file - file from which to get files to ignore %__brp_mangle_shebangs /usr/lib/rpm/redhat/brp-mangle-shebangs %{?__brp_mangle_shebangs_exclude:--shebangs "%{?__brp_mangle_shebangs_exclude}"} %{?__brp_mangle_shebangs_exclude_file:--shebangs-from "%{__brp_mangle_shebangs_exclude_file}"} %{?__brp_mangle_shebangs_exclude_from:--files "%{?__brp_mangle_shebangs_exclude_from}"} %{?__brp_mangle_shebangs_exclude_from_file:--files-from "%{__brp_mangle_shebangs_exclude_from_file}"} -%__brp_llvm_compile_lto_elf /usr/lib/rpm/redhat/brp-llvm-compile-lto-elf %{build_cflags} %{build_ldflags} - # note: %%__os_install_post_python is defined in python-srpm-macros and contains several policies # redhat-rpm-config maintainers, don't remove it from %%__os_install_post unless coordinating the change with Python maintainers # packagers, don't undefine the entire macro, see the individual macros in /usr/lib/rpm/macros.d/macros.python-srpm @@ -297,7 +295,6 @@ for k,_ in pairs(stripped_flags) do print(k .. " ") end %{nil} %__spec_install_post\ - %[ "%{toolchain}" == "clang" ? "%{?__brp_llvm_compile_lto_elf}" : "%{nil}" ] \ %{?__debug_package:%{__debug_install_post}}\ %{__arch_install_post}\ %{__os_install_post}\ @@ -397,7 +394,7 @@ for k,_ in pairs(stripped_flags) do print(k .. " ") end # way we can detect installing an unusable .o/.a file. This is on the TODO # list for F34. %_gcc_lto_cflags -flto=auto -ffat-lto-objects -%_clang_lto_cflags -flto=thin +%_clang_lto_cflags -flto=thin -ffat-lto-objects %_lto_cflags %{expand:%%{_%{toolchain}_lto_cflags}} # Default fortification level. diff --git a/redhat-rpm-config.spec b/redhat-rpm-config.spec index b252e48..a004149 100644 --- a/redhat-rpm-config.spec +++ b/redhat-rpm-config.spec @@ -4,7 +4,7 @@ # 2) When making changes, increment the version (in baserelease) by 1. # rpmdev-bumpspec and other tools update the macro below, which is used # in Version: to get the desired effect. -%global baserelease 291 +%global baserelease 292 Summary: Red Hat specific rpm configuration files Name: redhat-rpm-config @@ -60,9 +60,6 @@ Source158: macros.rpmautospec # and an echo when the mangling happens Source201: brp-mangle-shebangs -# for converting llvm LTO bitcode objects into ELF -Source204: brp-llvm-compile-lto-elf - # Dependency generator scripts (deprecated) Source300: find-provides Source304: find-requires @@ -132,10 +129,6 @@ Requires: %{_bindir}/grep Requires: %{_bindir}/sed Requires: %{_bindir}/xargs -# for brp-llvm-compile-lto-elf -Requires: (llvm if clang) -Requires: (gawk if clang) - # -fstack-clash-protection and -fcf-protection require GCC 8. Conflicts: gcc < 8.0.1-0.22 @@ -257,6 +250,9 @@ install -p -m 644 -t %{buildroot}%{_rpmluadir}/fedora common.lua %doc buildflags.md %changelog +* Mon Jun 02 2025 Nikita Popov - 292-1 +- Use Fat LTO with Clang + * Mon May 12 2025 Michal Domonkos - 290-1 - Use upstream versions of find-provides/requires (RHEL-39760) - brp-mangle-shebangs: Strip env flags when mangling shebangs (RHEL-84703)