From 4bcc171bd247a02ff211051fa2b08fd625864299 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sun, 25 Sep 2022 15:09:46 +0200 Subject: [PATCH 1/3] buildsystem: support choosing default linker Default linker can be set with DEFAULT_LINKER in options. Packages can influence linker selection both by positive and/or negative PKG_BUILD_FLAGS, eg +bfd or -gold. Positive build flags take priority over the default linker so eg DEFAULT_LINKER="gold" and PKG_BUILD_FLAGS="+bfd" will select bfd. Negative flags mean a specific linker should not be used, eg -gold prevents using gold. If the default linker is disabled via a build flag then any other available linker will be used. Optional linkers like gold have to be enabled with eg GOLD_SUPPORT="yes" in options. If an optional linker is not enabled it won't be a candidate for linker selection. So eg "+mold" will have no effect if MOLD_SUPPORT isn't set to "yes". Signed-off-by: Matthias Reichl --- config/functions | 55 ++++++++++++++++++++++++++++----- config/optimize | 6 ++-- config/show_config | 1 + distributions/LibreELEC/options | 3 ++ packages/readme.md | 3 +- 5 files changed, 58 insertions(+), 10 deletions(-) diff --git a/config/functions b/config/functions index a377454622..459df94541 100644 --- a/config/functions +++ b/config/functions @@ -254,8 +254,50 @@ check_toolchain_config() { done } +# args: linker, default availability yes/no +linker_allowed() { + if flag_enabled "$1" "$2"; then + # bfd is always available, others need to be enabled with _SUPPORT="yes" + local linker_support="${1^^}_SUPPORT" + if [ "$1" = "bfd" ] || [ "${!linker_support}" = "yes" ]; then + return 0 + fi + fi + return 1 +} + +# return target linker to use for a package +get_target_linker() { + # all known linkers, in descending order of priority + # those are candidates for explicit opt-in via PKG_BUILD_FLAGS + local all_linkers="gold bfd" + + # linkers to choose from unless disabled via PKG_BUILD_FLAGS + local linker_candidates="${DEFAULT_LINKER:-bfd} ${all_linkers}" + + local linker + + # check if package prefers a specific linker + for linker in ${all_linkers}; do + if linker_allowed "${linker}" "no"; then + echo "${linker}" + return + fi + done + + # select linker which isn't disabled by PKG_BUILD_FLAGS + for linker in ${linker_candidates}; do + if linker_allowed "${linker}" "yes"; then + echo "${linker}" + return + fi + done + + # none of our linkers matched, use the compiler's default linker + echo "compiler_default" +} + setup_toolchain() { - local have_gold="no" if [ "$LTO_SUPPORT" = "yes" ]; then if flag_enabled "lto-parallel" "no"; then TARGET_CFLAGS+=" $FLAGS_OPTIM_LTO_PARALLEL $FLAGS_OPTIM_LTO_NO_FAT" @@ -278,15 +320,14 @@ setup_toolchain() { TARGET_LDFLAGS+=" $FLAGS_OPTIM_LTO_OFF" fi - # gold flag - if flag_enabled "gold" "$GOLD_SUPPORT" "only-disable"; then - TARGET_LDFLAGS+=" $LDFLAGS_OPTIM_GOLD" - have_gold="yes" - fi + local linker="$(get_target_linker)" + local linker_opts="LDFLAGS_OPTIM_LINKER_${linker^^}" + + TARGET_LDFLAGS+=" ${!linker_opts}" # compiler optimization, descending priority: speed, size, default if [ "${BUILD_WITH_DEBUG}" = "yes" ]; then - if [ "${SPLIT_DEBUG_INFO}" = "yes" -a "${have_gold}" = "yes" ]; then + if [ "${SPLIT_DEBUG_INFO}" = "yes" -a "${linker}" = "gold" ]; then TARGET_CFLAGS+=" $CFLAGS_OPTIM_DEBUG_SPLIT" TARGET_CXXFLAGS+=" $CXXFLAGS_OPTIM_DEBUG_SPLIT" TARGET_LDFLAGS+=" $LDFLAGS_OPTIM_DEBUG_SPLIT" diff --git a/config/optimize b/config/optimize index fe5f8ec625..14eb946aca 100644 --- a/config/optimize +++ b/config/optimize @@ -27,8 +27,10 @@ FLAGS_OPTIM_LTO_FAT="-ffat-lto-objects" FLAGS_OPTIM_LTO_OFF="-fno-lto" LDFLAGS_OPTIM_LTO_COMMON="-fuse-linker-plugin" -# gold flags -LDFLAGS_OPTIM_GOLD="-fuse-ld=gold" +# linker specific flags +LDFLAGS_OPTIM_LINKER_COMPILER_DEFAULT="" +LDFLAGS_OPTIM_LINKER_BFD="-fuse-ld=bfd" +LDFLAGS_OPTIM_LINKER_GOLD="-fuse-ld=gold" # default compiler optimization CFLAGS_OPTIM_DEFAULT="-O2 -fomit-frame-pointer -DNDEBUG" diff --git a/config/show_config b/config/show_config index edb636e1e2..7b7628465b 100644 --- a/config/show_config +++ b/config/show_config @@ -31,6 +31,7 @@ show_config() { config_message+="\n - CPU features:\t\t\t ${TARGET_FEATURES}" config_message+="\n - LTO (Link Time Optimization) support: ${LTO_SUPPORT}" config_message+="\n - GOLD (Google Linker) Support:\t ${GOLD_SUPPORT}" + config_message+="\n - Default Linker:\t\t\t ${DEFAULT_LINKER}" config_message+="\n - LLVM support:\t\t\t ${LLVM_SUPPORT}" config_message+="\n - DEBUG:\t\t\t\t ${DEBUG:-no}" config_message+="\n - CFLAGS:\t\t\t\t ${TARGET_CFLAGS}" diff --git a/distributions/LibreELEC/options b/distributions/LibreELEC/options index 2cfe469d4a..ccbd590a48 100644 --- a/distributions/LibreELEC/options +++ b/distributions/LibreELEC/options @@ -32,6 +32,9 @@ # GOLD (Google Linker) support GOLD_SUPPORT="yes" +# default linker (bfd / gold) + DEFAULT_LINKER="gold" + # HARDENING (security relevant linker and compiler flags) support HARDENING_SUPPORT="no" diff --git a/packages/readme.md b/packages/readme.md index 3724b7a329..c284c5f005 100644 --- a/packages/readme.md +++ b/packages/readme.md @@ -126,7 +126,8 @@ Set the variable `PKG_BUILD_FLAGS` in the `package.mk` to enable/disable the sin | lto-parallel | disabled | target, init | same as `lto` but enables parallel optimization at link stage. Only enable this if the package build doesn't run multiple linkers in parallel otherwise this can result in lots of parallel processes! | | lto-fat | disabled | target, init | same as `lto` but compile fat LTO objects (bytecode plus optimized assembly). This increases compile time but can be useful to create static libraries suitable both for LTO and non-LTO linking | | lto-off | disabled | target, init | explicitly disable LTO in the compiler and linker | -| gold | enabled by `GOLD_SUPPORT` | target, init | do not use GOLD-Llinker (can only disable) | +| bfd | - | target, init | `+bfd` prefers bfd linker over default linker, `-bfd` disables using bfd | +| gold | - | target, init | `+gold` prefers gold linker over default linker, `-gold` disables using gold | | parallel | enabled | all | `make` or `ninja` builds with multiple threads/processes (or not) | | strip | enabled | target | strips executables (or not) | | sysroot | enabled | target | installs the package to the sysroot folder (or not) | From ff772b638ca2a19b0840cbb79ff866acd5efa581 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Sun, 25 Sep 2022 20:04:46 +0200 Subject: [PATCH 2/3] kodi: use get_target_linker helper to set linker options Signed-off-by: Matthias Reichl --- packages/mediacenter/kodi/package.mk | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/packages/mediacenter/kodi/package.mk b/packages/mediacenter/kodi/package.mk index 99be4888e8..01bf0966fc 100644 --- a/packages/mediacenter/kodi/package.mk +++ b/packages/mediacenter/kodi/package.mk @@ -20,13 +20,16 @@ configure_package() { fi # Set linker options - if [ "${GOLD_SUPPORT}" = "yes" ]; then - PKG_KODI_LINKER="-DENABLE_GOLD=ON \ - -DENABLE_MOLD=OFF" - else - PKG_KODI_LINKER="-DENABLE_GOLD=OFF \ - -DENABLE_MOLD=OFF" - fi + case $(get_target_linker) in + gold) + PKG_KODI_LINKER="-DENABLE_GOLD=ON \ + -DENABLE_MOLD=OFF" + ;; + *) + PKG_KODI_LINKER="-DENABLE_GOLD=OFF \ + -DENABLE_MOLD=OFF" + ;; + esac get_graphicdrivers From 87b07a816a41526633f9ef5b4b5c5562f6cdc2a8 Mon Sep 17 00:00:00 2001 From: Matthias Reichl Date: Tue, 27 Sep 2022 23:46:42 +0200 Subject: [PATCH 3/3] glibc: set preferred linker to bfd glibc has minimal dependencies so only bfd and gold linkers from binutils are available. As glibc doesn't link with gold set bfd as the preferred linker to prevent linking with gold or any other linker. Signed-off-by: Matthias Reichl --- packages/devel/glibc/package.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/devel/glibc/package.mk b/packages/devel/glibc/package.mk index f589a8340d..fc23ec2a95 100644 --- a/packages/devel/glibc/package.mk +++ b/packages/devel/glibc/package.mk @@ -11,7 +11,7 @@ PKG_URL="https://ftp.gnu.org/pub/gnu/glibc/${PKG_NAME}-${PKG_VERSION}.tar.xz" PKG_DEPENDS_TARGET="ccache:host autotools:host linux:host gcc:bootstrap pigz:host Python3:host" PKG_DEPENDS_INIT="glibc" PKG_LONGDESC="The Glibc package contains the main C library." -PKG_BUILD_FLAGS="-gold" +PKG_BUILD_FLAGS="+bfd" PKG_CONFIGURE_OPTS_TARGET="BASH_SHELL=/bin/sh \ ac_cv_path_PERL=no \