diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 29b3f627f8..0f3d564ad0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -381,6 +381,7 @@ stages: -Ddeveloper=enabled -Dleak-detection=enabled -Doptimization=1 + -Dnamed-lto=thin $EXTRA_CONFIGURE build @@ -1511,7 +1512,7 @@ clang:tsan: CC: "${CLANG}" CFLAGS: "${CFLAGS_COMMON}" LDFLAGS: "-Wl,--disable-new-dtags" - EXTRA_CONFIGURE: "${TSAN_CONFIGURE_FLAGS_COMMON} -Db_lundef=false -Dnamed-lto=off --native-file ci/clang-trixie.ini" + EXTRA_CONFIGURE: "${TSAN_CONFIGURE_FLAGS_COMMON} -Db_lundef=false -Dnamed-lto=disabled --native-file ci/clang-trixie.ini" <<: *build_job system:clang:tsan: @@ -1985,7 +1986,7 @@ respdiff:tsan: CC: "${CLANG}" CFLAGS: "${CFLAGS_COMMON}" LDFLAGS: "-Wl,--disable-new-dtags" - EXTRA_CONFIGURE: "${TSAN_CONFIGURE_FLAGS_COMMON} -Dnamed-lto=off -Db_lundef=false" + EXTRA_CONFIGURE: "${TSAN_CONFIGURE_FLAGS_COMMON} -Dnamed-lto=disabled -Db_lundef=false" MAX_DISAGREEMENTS_PERCENTAGE: "0.3" TSAN_OPTIONS: "${TSAN_OPTIONS_DEBIAN}" script: diff --git a/doc/arm/build.inc.rst b/doc/arm/build.inc.rst index 0dfaec1ab3..9999b89157 100644 --- a/doc/arm/build.inc.rst +++ b/doc/arm/build.inc.rst @@ -89,9 +89,11 @@ required when in use. To further improve performance, compilation with link-time optimization is recommended. This is enabled by default via the ``-Dnamed-lto`` option -(default: ``thin``). Link-time optimization can be disabled if needed by -using ``-Dnamed-lto=off``. The optimization level can be controlled with -``-Dnamed-lto=thin`` or ``-Dnamed-lto=full``. +(default: ``auto``). Link-time optimization can be disabled if needed by +using ``-Dnamed-lto=disabled``. The optimization level can be controlled with +``-Dnamed-lto=thin`` or ``-Dnamed-lto=full``. The ``auto`` option enables +thin LTO when supported by the compiler and linker combination, and disables +LTO otherwise. Link-time optimization requires close coordination between the compiler and the linker. Due to ``clang`` limitations, compiling ``named`` with ``clang`` diff --git a/meson.build b/meson.build index 4315d697c6..cb7a6e2620 100644 --- a/meson.build +++ b/meson.build @@ -923,28 +923,79 @@ assert( # LTO +# Taken from Meson's compilers/mixins/clang.py:get_lto_compile_args +# (technically mold requires version 1.1) +supported_clang_lto_linkers = [ + 'ld64', + 'lld-link', + 'ld.lld', + 'ld.gold', + 'ld.mold', +] + +is_darwin = host_machine.system() == 'darwin' +is_auto_lto = named_lto_opt == 'auto' +is_supported_linker = cc.get_linker_id() in supported_clang_lto_linkers +has_fat_lto = cc.has_argument('-ffat-lto-objects') and not is_darwin +has_fuzzing_backend = fuzzing_backend_opt != 'none' + +# First, resolution of the 'auto' case for LTO. +if is_auto_lto + if has_fuzzing_backend + # Fuzzers might need sanitizer converage sections, which LTO discards. + # Disable LTO when a fuzzing backend is configured. + # NB: enabling -Dfuzzing is fine since it justs builds the binaries. + named_lto_opt = 'disabled' + elif is_darwin + # On Mac OS, the has_argument('-ffat-lto-objects') check returns true, + # but compilation fails, so we simply disable LTO. + named_lto_opt = 'disabled' + elif not has_fat_lto + # Some very old compilers don't support fat lto objects. + named_lto_opt = 'disabled' + elif cc.get_id() == 'clang' and not is_supported_linker + # Per LLVM docs [1], -ffat-lto-objects is supported only with lld and gold, + # and gold is deprecated/unmantained. Manual testing shows that mold + # works too though. + named_lto_opt = 'disabled' + elif get_option('auto_features').disabled() + # Fake being a boolean option for the purpose of -Dauto-features + named_lto_opt = 'disabled' + else + named_lto_opt = 'thin' + endif +endif + static_lto_c_args = [] static_lto_link_args = [] -if named_lto_opt == 'full' +if developer_mode and is_auto_lto + # Build a static `named` but do not enable -flto to improve compilation speed. +elif named_lto_opt == 'full' static_lto_c_args = ['-ffat-lto-objects', '-flto'] static_lto_link_args = ['-flto'] -elif named_lto_opt == 'thin' and cc.get_id() == 'clang' and cc.get_linker_id() == 'ld.lld' - # Per LLVM docs [1], -ffat-lto-objects is supported only with lld and gold, - # and gold is deprecated/unmantained. - # [1]: https://llvm.org/docs/FatLTO.html - +elif named_lto_opt == 'thin' and cc.get_id() == 'clang' and is_supported_linker static_lto_c_args = ['-ffat-lto-objects', '-flto=thin'] static_lto_link_args = ['-flto=thin'] elif named_lto_opt == 'thin' and cc.get_id() == 'gcc' static_lto_c_args = ['-ffat-lto-objects', '-flto=auto'] static_lto_link_args = ['-flto=auto'] elif named_lto_opt == 'thin' - error('LTO requires clang with ld.lld, or gcc with any linker') + if cc.get_id() == 'clang' + error( + 'Clang ThinLTO only works with gold, lld, lld-link, ld64 or mold, not ' + + cc.get_linker_id() + + '. To build, use a supported linker or disable LTO with -Dnamed-lto=disabled.', + ) + else + error( + 'Unsupported configuration for LTO. To build, use a supported linker or disable LTO with -Dnamed-lto=disabled.', + ) + endif endif add_project_arguments(static_lto_c_args, language: 'c') -if named_lto_opt != 'off' and cc.get_id() == 'clang' and sanitizer.contains('address') +if named_lto_opt != 'disabled' and cc.get_id() == 'clang' and sanitizer.contains('address') # Needed to suppress the # warning: Redundant instrumentation detected, with module flag: # nosanitize_address [-Werror,-Wbackend-plugin] @@ -957,7 +1008,7 @@ if named_lto_opt != 'off' and cc.get_id() == 'clang' and sanitizer.contains('add add_project_arguments('-Wno-backend-plugin', language: 'c') endif -if meson_lto and named_lto_opt != 'off' +if meson_lto and named_lto_opt != 'disabled' # Meson's builtin LTO settings do not set -ffat-lto-objects, which can cause # build issues. # Since we don't want two, possibly conflicting, sets of LTO flags, we @@ -966,7 +1017,7 @@ if meson_lto and named_lto_opt != 'off' error( ''' Meson builtin -Db_lto and BIND's -Dnamed-lto options are incompatible. - Either disable named-lto with -Dnamed-lto=off, or avoid setting + Either disable named-lto with -Dnamed-lto=disabled, or avoid setting -Db_lto. Note that using -Db_lto is not a recommended configuration, might @@ -1542,7 +1593,7 @@ executable( named_deps = [] -if named_lto_opt == 'off' +if named_lto_opt == 'disabled' named_deps = [ libdns_dep, libisc_dep, diff --git a/meson.options b/meson.options index 0fac926a4a..ca0d2fc6e1 100644 --- a/meson.options +++ b/meson.options @@ -199,7 +199,7 @@ option( option( 'named-lto', type: 'combo', - choices: ['off', 'thin', 'full'], - value: 'thin', + choices: ['disabled', 'auto', 'thin', 'full'], + value: 'auto', description: 'Enable Link Time Optimization for named.', )