diff --git a/SOURCES/brp-llvm-compile-lto-elf b/SOURCES/brp-llvm-compile-lto-elf new file mode 100755 index 0000000..7eb53a1 --- /dev/null +++ b/SOURCES/brp-llvm-compile-lto-elf @@ -0,0 +1,52 @@ +#!/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 +find "$RPM_BUILD_ROOT" -type f -name "*.[ao]" -print0 | \ + xargs -0 -r -n1 -P$NCPUS sh -c "check_convert_bitcode \$@ $CLANG_FLAGS" ARG0 diff --git a/SOURCES/macros b/SOURCES/macros index 70b343e..74e9bf3 100644 --- a/SOURCES/macros +++ b/SOURCES/macros @@ -233,6 +233,8 @@ print(result) # __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} + %__os_install_post \ %{?__brp_ldconfig} \ %{?__brp_compress} \ @@ -249,6 +251,7 @@ print(result) %{nil} %__spec_install_post\ + %[ "%{toolchain}" == "clang" ? "%{?__brp_llvm_compile_lto_elf}" : "%{nil}" ] \ %{?__debug_package:%{__debug_install_post}}\ %{__arch_install_post}\ %{__os_install_post}\ diff --git a/SPECS/redhat-rpm-config.spec b/SPECS/redhat-rpm-config.spec index cb21d27..31dff91 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: 196 +Version: 199 Release: 1%{?dist} # No version specified. License: GPL+ @@ -59,6 +59,9 @@ Source202: brp-python-bytecompile # https://github.com/fedora-python/marshalparser Source203: brp-fix-pyc-reproducibility +# for converting llvm LTO bitcode objects into ELF +Source204: brp-llvm-compile-lto-elf + # Dependency generator scripts (deprecated) Source300: find-provides Source304: find-requires @@ -103,6 +106,7 @@ Requires: perl-srpm-macros Requires: python-srpm-macros >= 3-46 Requires: qt5-srpm-macros Requires: rust-srpm-macros +Requires: pyproject-srpm-macros %if ! 0%{?rhel} Requires: fpc-srpm-macros @@ -166,16 +170,49 @@ install -p -m 644 -t %{buildroot}%{_rpmluadir}/fedora/srpm forge.lua # This trigger is used to decide which version of the annobin plugin for gcc # should be used. See comments in the script for full details. +# +# Note: for RHEL the rpm containing the annobin built plugin is called +# "annobin", whereas in Fedora it is called "annobin-plugin-gcc". This is +# for historical reasons and will change with the introduction of RHEL-10. +# +# Note - whilst "gcc-plugin-annobin" requires "gcc" and hence in theory we +# do not need to trigger on "gcc", the redhat-annobin-plugin-select.sh +# script invokes gcc to determine the version of the gcc plugin, and this +# can be significant. +# +# For example, suppose that version N of gcc is installed and that annobin +# version A (built by gcc version N) is also installed. Then a new version +# of gcc is released. If the rpms are updated in this order: +# gcc-plugin-annobin +# gcc +# then when the trigger for gcc-plugin-annobin is run, the script will see +# (the not yet updated) gcc is currently version N, which matches the current +# annobin plugin A, so no changes are necessary. Then gcc is updated and, +# if the trigger below did not include "gcc", the script would not run again +# and so now you would have an out of date version of the annobin plugin. +# +# Alternatively imagine installing gcc and annobin for the first time. +# If the installation order is: +# gcc +# annobin-plugin-gcc +# gcc-plugin-annobin +# then the installation of gcc will not cause the gcc-plugin-annobin to be +# selected, since it does not exist yet. Then annobin-plugin-gcc is installed +# and since it is the only plugin, it will be selected. Then +# gcc-plugin-annobin is installed, and if the trigger below was not set to +# run on gcc-plugin-annobin, it would pass unnoticed. +# +# Hence it is necessary to trigger on both gcc and gcc-plugin-annobin. -%triggerin -- annobin gcc-plugin-annobin +%triggerin -- annobin gcc-plugin-annobin gcc %{rrcdir}/redhat-annobin-plugin-select.sh %end -# We also trigger when annobin is uninstalled. This allows us to switch -# over to the gcc generated version of the plugin. It does not matter if +# We also trigger when an annobin plugin is uninstalled. This allows us to switch +# over to the other version of the plugin. It does not matter if # gcc is uninstalled, since if that happens the plugin cannot be used. -%triggerpostun -- annobin +%triggerpostun -- annobin gcc-plugin-annobin %{rrcdir}/redhat-annobin-plugin-select.sh %end @@ -213,6 +250,16 @@ install -p -m 644 -t %{buildroot}%{_rpmluadir}/fedora/srpm forge.lua %doc buildflags.md %changelog +* Mon Feb 13 2023 Miro Hrončok - 199-1 +- Add pyproject-srpm-macros to the default buildroot +- Related: rhbz#2168193 + +* Tue Feb 07 2023 Nick Clifton - 198-1 +- Fix triggers for the installation and removal of gcc-plugin-annobin. (#2167713) + +* Wed Sep 21 2022 Timm Bäder - 197-1 +- Ship brp-llvm-compile-lto-elf script + * Mon Jun 27 2022 Nick Clifton - 196-1 - Pass "--remove section .gnu.build.attributes" to the find-debuginfo script. - Resolves: rhbz#2099613