diff --git a/utils/build-script-impl b/utils/build-script-impl index 06b54cc6c8eb2..dea3f5931a4f9 100755 --- a/utils/build-script-impl +++ b/utils/build-script-impl @@ -803,20 +803,6 @@ function set_build_options_for_host() { esac - # We don't currently support building compiler-rt for cross-compile targets. - # It's not clear that's useful anyway. - if [[ $(is_cross_tools_host "${host}") ]] ; then - llvm_cmake_options+=( - -DLLVM_TOOL_COMPILER_RT_BUILD:BOOL=FALSE - -DLLVM_BUILD_EXTERNAL_COMPILER_RT:BOOL=FALSE - ) - else - llvm_cmake_options+=( - -DLLVM_TOOL_COMPILER_RT_BUILD:BOOL="$(false_true ${SKIP_BUILD_COMPILER_RT})" - -DLLVM_BUILD_EXTERNAL_COMPILER_RT:BOOL="$(false_true ${SKIP_BUILD_COMPILER_RT})" - ) - fi - # If we are asked to not generate test targets for LLVM and or Swift, # disable as many LLVM tools as we can. This improves compile time when # compiling with LTO. diff --git a/utils/build_swift/build_swift/defaults.py b/utils/build_swift/build_swift/defaults.py index 99b7b85d72aad..3a155f679913d 100644 --- a/utils/build_swift/build_swift/defaults.py +++ b/utils/build_swift/build_swift/defaults.py @@ -122,6 +122,8 @@ def llvm_install_components(): """Convenience function for getting the default llvm install components for platforms. """ + # llvm build product will take care of replacing compiler-rt with + # builtins,runtimes if need be components = ['llvm-ar', 'llvm-cov', 'llvm-profdata', 'IndexStore', 'clang', 'clang-resource-headers', 'compiler-rt', 'clangd', 'LTO', 'lld'] diff --git a/utils/build_swift/build_swift/driver_arguments.py b/utils/build_swift/build_swift/driver_arguments.py index a92afa6c78229..549b0a496820f 100644 --- a/utils/build_swift/build_swift/driver_arguments.py +++ b/utils/build_swift/build_swift/driver_arguments.py @@ -1398,6 +1398,11 @@ def create_argument_parser(): 'separated options "-DCMAKE_VAR1=YES,-DCMAKE_VAR2=/tmp". Can ' 'be called multiple times to add multiple such options.') + option('--llvm-build-compiler-rt-with-use-runtimes', toggle_true, + help='Switch to LLVM_ENABLE_RUNTIMES as the mechanism to build compiler-rt' + 'It will become the default with LLVM 21, this flag is ' + 'meant to stage its introduction and account for edge cases') + # ------------------------------------------------------------------------- in_group('Build settings for Android') diff --git a/utils/build_swift/tests/expected_options.py b/utils/build_swift/tests/expected_options.py index e89ac58a7cfc1..08d4b22329173 100644 --- a/utils/build_swift/tests/expected_options.py +++ b/utils/build_swift/tests/expected_options.py @@ -232,6 +232,7 @@ 'lldb_build_variant': 'Debug', 'lldb_build_with_xcode': '0', 'llvm_assertions': True, + 'llvm_build_compiler_rt_with_use_runtimes': False, 'llvm_build_variant': 'Debug', 'llvm_cmake_options': [], 'llvm_enable_modules': False, @@ -853,6 +854,7 @@ class BuildScriptImplOption(_BaseOption): AppendOption('--llvm-ninja-targets'), AppendOption('--llvm-ninja-targets-for-cross-compile-hosts'), AppendOption('--llvm-cmake-options'), + EnableOption('--llvm-build-compiler-rt-with-use-runtimes'), AppendOption('--darwin-symroot-path-filters'), UnsupportedOption('--build-jobs'), diff --git a/utils/swift_build_support/swift_build_support/products/cmake_product.py b/utils/swift_build_support/swift_build_support/products/cmake_product.py index dc338334f284d..2dd761f1bce95 100644 --- a/utils/swift_build_support/swift_build_support/products/cmake_product.py +++ b/utils/swift_build_support/swift_build_support/products/cmake_product.py @@ -133,6 +133,7 @@ def host_cmake_options(self, host_target): llvm_target_arch = None cmake_osx_deployment_target = None + cmake_os_sysroot = None swift_host_triple = None swift_host_variant = platform swift_host_variant_sdk = platform.upper() @@ -381,19 +382,6 @@ def host_cmake_options(self, host_target): # in the compiler checks CMake performs swift_cmake_options.define('CMAKE_OSX_ARCHITECTURES', arch) - # We don't currently support building compiler-rt for cross-compile targets. - # It's not clear that's useful anyway. - if self.is_cross_compile_target(host_target): - llvm_cmake_options.define('LLVM_TOOL_COMPILER_RT_BUILD:BOOL', 'FALSE') - llvm_cmake_options.define('LLVM_BUILD_EXTERNAL_COMPILER_RT:BOOL', 'FALSE') - else: - llvm_cmake_options.define('LLVM_TOOL_COMPILER_RT_BUILD:BOOL', - cmake.CMakeOptions.true_false( - self.args.build_compiler_rt)) - llvm_cmake_options.define('LLVM_BUILD_EXTERNAL_COMPILER_RT:BOOL', - cmake.CMakeOptions.true_false( - self.args.build_compiler_rt)) - # If we are asked to not generate test targets for LLVM and or Swift, # disable as many LLVM tools as we can. This improves compile time when # compiling with LTO. @@ -428,4 +416,8 @@ def host_cmake_options(self, host_target): llvm_cmake_options.define('COVERAGE_DB', self.args.coverage_db) - return (llvm_cmake_options, swift_cmake_options) + # This provides easier access to certain settings + # users may need without having to use CMakeOptions interface + relevant_options = {'CMAKE_OSX_SYSROOT': cmake_os_sysroot} + + return (llvm_cmake_options, swift_cmake_options, relevant_options) diff --git a/utils/swift_build_support/swift_build_support/products/llvm.py b/utils/swift_build_support/swift_build_support/products/llvm.py index 48f77c0af0b93..c22aab1a96ac8 100644 --- a/utils/swift_build_support/swift_build_support/products/llvm.py +++ b/utils/swift_build_support/swift_build_support/products/llvm.py @@ -225,7 +225,7 @@ def build(self, host_target): (platform, arch) = host_target.split('-') - llvm_cmake_options = self.host_cmake_options(host_target)[0] + llvm_cmake_options, _, relevant_options = self.host_cmake_options(host_target) llvm_cmake_options.extend_raw(self.args.llvm_cmake_options) # TODO: handle cross compilation @@ -291,18 +291,78 @@ def build(self, host_target): llvm_cmake_options.define('LLVM_INCLUDE_DOCS:BOOL', 'TRUE') llvm_cmake_options.define('LLVM_ENABLE_LTO:STRING', self.args.lto_type) llvm_cmake_options.define('COMPILER_RT_INTERCEPT_LIBDISPATCH', 'ON') + # Swift expects the old layout for the runtime directory + # updating this in tracked in #80180 + llvm_cmake_options.define('LLVM_ENABLE_PER_TARGET_RUNTIME_DIR', 'OFF') + if host_target.startswith('linux'): + # This preserves the behaviour we had when using + # LLVM_BUILD_EXTERNAL COMPILER_RT -- + # that is, having the linker not complaing if symbols used + # by TSan are undefined (namely the ones for Blocks Runtime) + # In the long term, we want to remove this and + # build Blocks Runtime before LLVM + llvm_cmake_options.define( + 'SANITIZER_COMMON_LINK_FLAGS:STRING', '-Wl,-z,undefs') + + builtins_runtimes_target_for_darwin = 'arm64-apple-darwin' + if system() == "Darwin": + llvm_cmake_options.define( + f'BUILTINS_{builtins_runtimes_target_for_darwin}_' + 'CMAKE_OSX_SYSROOT', + relevant_options['CMAKE_OSX_SYSROOT']) + llvm_cmake_options.define( + f'RUNTIMES_{builtins_runtimes_target_for_darwin}_' + 'CMAKE_OSX_SYSROOT', + relevant_options['CMAKE_OSX_SYSROOT']) + llvm_cmake_options.define( + 'LLVM_BUILTIN_TARGETS', builtins_runtimes_target_for_darwin) + llvm_cmake_options.define( + 'LLVM_RUNTIME_TARGETS', builtins_runtimes_target_for_darwin) + llvm_cmake_options.define('RUNTIMES_BUILD_ALLOW_DARWIN', 'ON') + # Build all except rtsan + llvm_cmake_options.define( + f'RUNTIMES_{builtins_runtimes_target_for_darwin}_' + 'COMPILER_RT_SANITIZERS_TO_BUILD', + 'asan;dfsan;msan;hwasan;tsan;safestack;cfi;scudo_standalone;' + 'ubsan_minimal;gwp_asan;nsan;asan_abi') if self.args.build_embedded_stdlib and system() == "Darwin": # Ask for Mach-O cross-compilation builtins (for Embedded Swift) llvm_cmake_options.define( 'COMPILER_RT_FORCE_BUILD_BAREMETAL_MACHO_BUILTINS_ARCHS:STRING', 'armv6 armv6m armv7 armv7m armv7em') + llvm_cmake_options.define( + f'BUILTINS_{builtins_runtimes_target_for_darwin}_' + 'COMPILER_RT_FORCE_BUILD_BAREMETAL_MACHO_BUILTINS_ARCHS:' + 'STRING', 'armv6 armv6m armv7 armv7m armv7em') llvm_enable_projects = ['clang'] + llvm_enable_runtimes = [] if self.args.build_compiler_rt and \ not self.is_cross_compile_target(host_target): - llvm_enable_projects.append('compiler-rt') + if self.args.llvm_build_compiler_rt_with_use_runtimes: + llvm_enable_runtimes.append('compiler-rt') + # This accounts for previous incremental runs that may have set + # those in the LLVM CMakeCache.txt + llvm_cmake_options.undefine('LLVM_TOOL_COMPILER_RT_BUILD') + llvm_cmake_options.undefine('LLVM_BUILD_EXTERNAL_COMPILER_RT') + else: + # No need to unset anything, + # since we set LLVM_ENABLE_RUNTIMES explicitly + llvm_enable_projects.append('compiler-rt') + llvm_cmake_options.define( + 'LLVM_TOOL_COMPILER_RT_BUILD:BOOL', 'TRUE') + llvm_cmake_options.define( + 'LLVM_BUILD_EXTERNAL_COMPILER_RT:BOOL', 'TRUE') + else: + if not self.args.llvm_build_compiler_rt_with_use_runtimes: + # No need to unset anything, + # since we set LLVM_ENABLE_RUNTIMES explicitly + llvm_cmake_options.define( + 'LLVM_TOOL_COMPILER_RT_BUILD:BOOL', 'FALSE') + llvm_cmake_options.define( + 'LLVM_BUILD_EXTERNAL_COMPILER_RT:BOOL', 'FALSE') if self.args.build_clang_tools_extra: llvm_enable_projects.append('clang-tools-extra') @@ -316,18 +376,15 @@ def build(self, host_target): if self.args.build_lld: llvm_enable_projects.append('lld') + if self.args.test: + # LLVMTestingSupport is not built at part of `all` + # and is required by some Swift tests + build_targets.append('LLVMTestingSupport') + llvm_cmake_options.define('LLVM_ENABLE_PROJECTS', ';'.join(llvm_enable_projects)) - - # In the near future we are aiming to build compiler-rt with - # LLVM_ENABLE_RUNTIMES - # Until that happens, we need to unset this variable from - # LLVM CMakeCache.txt for two reasons - # * prevent PRs testing this variable to affect other runs landing - # unrelated features - # * avoid fallouts should we land such change and then have to revert - # it to account for unforeseen regressions - llvm_cmake_options.undefine('LLVM_ENABLE_RUNTIMES') + llvm_cmake_options.define('LLVM_ENABLE_RUNTIMES', + ';'.join(llvm_enable_runtimes)) # NOTE: This is not a dead option! It is relied upon for certain # bots/build-configs! @@ -491,9 +548,21 @@ def install(self, host_target): self.args.llvm_install_components != 'all': install_targets = [] components = self.args.llvm_install_components.split(';') + if self.args.llvm_build_compiler_rt_with_use_runtimes and \ + 'compiler-rt' in components: + # This is a courtesy fallback to avoid breaking downstream presets + # we are not aware of + components.remove('compiler-rt') + components.append('builtins') + components.append('runtimes') + print('warning: replaced legacy LLVM component compiler-rt ' + 'with builtins;runtimes -- consider updating your preset', + flush=True) + for component in components: - if self.is_cross_compile_target(host_target): - if component == 'compiler-rt': + if self.is_cross_compile_target(host_target) \ + or not self.args.build_compiler_rt: + if component in ['compiler-rt', 'builtins', 'runtimes']: continue install_targets.append('install-{}'.format(component)) diff --git a/validation-test/BuildSystem/llvm-build-compiler-rt-on-linux.test b/validation-test/BuildSystem/llvm-build-compiler-rt-on-linux.test new file mode 100644 index 0000000000000..dcefed6d2466a --- /dev/null +++ b/validation-test/BuildSystem/llvm-build-compiler-rt-on-linux.test @@ -0,0 +1,17 @@ +# REQUIRES: standalone_build +# REQUIRES: OS=linux-gnu + +# RUN: %empty-directory(%t) +# RUN: SKIP_XCODE_VERSION_CHECK=1 SWIFT_BUILD_ROOT=%t %swift_src_root/utils/build-script --dry-run --skip-build --llvm-build-compiler-rt-with-use-runtimes --cmake %cmake 2>&1 | %FileCheck --check-prefix=LINUX %s +# RUN: %empty-directory(%t) +# RUN: SKIP_XCODE_VERSION_CHECK=1 SWIFT_BUILD_ROOT=%t %swift_src_root/utils/build-script --dry-run --skip-build --llvm-build-compiler-rt-with-use-runtimes=1 --cmake %cmake 2>&1 | %FileCheck --check-prefix=LINUX %s +# RUN: %empty-directory(%t) +# RUN: SKIP_XCODE_VERSION_CHECK=1 SWIFT_BUILD_ROOT=%t %swift_src_root/utils/build-script --dry-run --skip-build --cmake %cmake 2>&1 | %FileCheck --check-prefix=LINUX %s +# RUN: %empty-directory(%t) +# RUN: SKIP_XCODE_VERSION_CHECK=1 SWIFT_BUILD_ROOT=%t %swift_src_root/utils/build-script --dry-run --skip-build --llvm-build-compiler-rt-with-use-runtimes=0 --cmake %cmake 2>&1 | %FileCheck --check-prefix=LINUX %s + +# LINUX: Building llvm +# LINUX-DAG: cmake -G Ninja +# LINUX-SAME: -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR{{[^ ]*}}=OFF +# LINUX-SAME: -DSANITIZER_COMMON_LINK_FLAGS{{[^ ]*}}=-Wl,-z,undefs +# LINUX-SAME: llvm diff --git a/validation-test/BuildSystem/llvm-build-compiler-rt-on-macosx.test b/validation-test/BuildSystem/llvm-build-compiler-rt-on-macosx.test new file mode 100644 index 0000000000000..b565927f48b46 --- /dev/null +++ b/validation-test/BuildSystem/llvm-build-compiler-rt-on-macosx.test @@ -0,0 +1,28 @@ +# REQUIRES: standalone_build +# REQUIRES: OS=macosx + +# RUN: %empty-directory(%t) +# RUN: SKIP_XCODE_VERSION_CHECK=1 SWIFT_BUILD_ROOT=%t %swift_src_root/utils/build-script --dry-run --skip-build --llvm-build-compiler-rt-with-use-runtimes --cmake %cmake 2>&1 | %FileCheck --check-prefix=LLVM-USE-RUNTIMES %s +# RUN: %empty-directory(%t) +# RUN: SKIP_XCODE_VERSION_CHECK=1 SWIFT_BUILD_ROOT=%t %swift_src_root/utils/build-script --dry-run --skip-build --llvm-build-compiler-rt-with-use-runtimes=1 --cmake %cmake 2>&1 | %FileCheck --check-prefix=LLVM-USE-RUNTIMES %s + +# LLVM-USE-RUNTIMES: Building llvm +# LLVM-USE-RUNTIMES-DAG: cmake -G Ninja +# LLVM-USE-RUNTIMES-SAME: -DBUILTINS_{{[^ ]*}}_CMAKE_OSX_SYSROOT +# LLVM-USE-RUNTIMES-SAME: -DRUNTIMES_{{[^ ]*}}_CMAKE_OSX_SYSROOT +# LLVM-USE-RUNTIMES-SAME: -DLLVM_BUILTIN_TARGETS +# LLVM-USE-RUNTIMES-SAME: -DLLVM_RUNTIME_TARGETS +# LLVM-USE-RUNTIMES-SAME: -DRUNTIMES_{{[^ ]*}}_COMPILER_RT_SANITIZERS_TO_BUILD +# LLVM-USE-RUNTIMES-NOT: rtsan +# LLVM-USE-RUNTIMES-SAME: -DBUILTINS_{{[^ ]*}}_COMPILER_RT_FORCE_BUILD_BAREMETAL_MACHO_BUILTINS_ARCHS +# LLVM-USE-RUNTIMES-SAME: llvm + +# RUN: %empty-directory(%t) +# RUN: SKIP_XCODE_VERSION_CHECK=1 SWIFT_BUILD_ROOT=%t %swift_src_root/utils/build-script --dry-run --skip-build --cmake %cmake 2>&1 | %FileCheck --check-prefix=EXTERNAL-COMPILER-RT %s +# RUN: %empty-directory(%t) +# RUN: SKIP_XCODE_VERSION_CHECK=1 SWIFT_BUILD_ROOT=%t %swift_src_root/utils/build-script --dry-run --skip-build --llvm-build-compiler-rt-with-use-runtimes=0 --cmake %cmake 2>&1 | %FileCheck --check-prefix=EXTERNAL-COMPILER-RT %s + +# EXTERNAL-COMPILER-RT: Building llvm +# EXTERNAL-COMPILER-RT-DAG: cmake -G Ninja +# EXTERNAL-COMPILER-RT-SAME: -DCOMPILER_RT_FORCE_BUILD_BAREMETAL_MACHO_BUILTINS_ARCHS +# EXTERNAL-COMPILER-RT-SAME: llvm diff --git a/validation-test/BuildSystem/llvm-build-compiler-rt-with-enable-external-compiler-rt.test b/validation-test/BuildSystem/llvm-build-compiler-rt-with-enable-external-compiler-rt.test new file mode 100644 index 0000000000000..6f8e95a42d517 --- /dev/null +++ b/validation-test/BuildSystem/llvm-build-compiler-rt-with-enable-external-compiler-rt.test @@ -0,0 +1,25 @@ +# REQUIRES: standalone_build + +# RUN: %empty-directory(%t) +# RUN: SKIP_XCODE_VERSION_CHECK=1 SWIFT_BUILD_ROOT=%t %swift_src_root/utils/build-script --dry-run --skip-build --cmake %cmake 2>&1 | %FileCheck --check-prefix=EXTERNAL-COMPILER-RT-CHECK %s +# RUN: %empty-directory(%t) +# RUN: SKIP_XCODE_VERSION_CHECK=1 SWIFT_BUILD_ROOT=%t %swift_src_root/utils/build-script --dry-run --skip-build --llvm-build-compiler-rt-with-use-runtimes=0 --cmake %cmake 2>&1 | %FileCheck --check-prefix=EXTERNAL-COMPILER-RT-CHECK %s + +# EXTERNAL-COMPILER-RT-CHECK: Building llvm +# EXTERNAL-COMPILER-RT-CHECK-DAG: cmake -G Ninja +# EXTERNAL-COMPILER-RT-CHECK-SAME: -DLLVM_TOOL_COMPILER_RT_BUILD:BOOL=TRUE +# EXTERNAL-COMPILER-RT-CHECK-SAME: -DLLVM_BUILD_EXTERNAL_COMPILER_RT:BOOL=TRUE +# EXTERNAL-COMPILER-RT-CHECK-SAME: -DLLVM_ENABLE_PROJECTS{{[^ ]*}}={{[^ ]*}}compiler-rt +# EXTERNAL-COMPILER-RT-CHECK-SAME: llvm + +# RUN: %empty-directory(%t) +# RUN: SKIP_XCODE_VERSION_CHECK=1 SWIFT_BUILD_ROOT=%t %swift_src_root/utils/build-script --dry-run --skip-build --skip-build-compiler-rt --cmake %cmake 2>&1 | %FileCheck --check-prefix=DONT-BUILD-COMPILER-RT %s +# RUN: %empty-directory(%t) +# RUN: SKIP_XCODE_VERSION_CHECK=1 SWIFT_BUILD_ROOT=%t %swift_src_root/utils/build-script --dry-run --skip-build --llvm-build-compiler-rt-with-use-runtimes=0 --skip-build-compiler-rt --cmake %cmake 2>&1 | %FileCheck --check-prefix=DONT-BUILD-COMPILER-RT %s + +# DONT-BUILD-COMPILER-RT: Building llvm +# DONT-BUILD-COMPILER-RT-DAG: cmake -G Ninja +# DONT-BUILD-COMPILER-RT-SAME: -DLLVM_TOOL_COMPILER_RT_BUILD:BOOL=FALSE +# DONT-BUILD-COMPILER-RT-SAME: -DLLVM_BUILD_EXTERNAL_COMPILER_RT:BOOL=FALSE +# DONT-BUILD-COMPILER-RT-NOT: compiler-rt +# DONT-BUILD-COMPILER-RT-SAME: llvm diff --git a/validation-test/BuildSystem/llvm-build-compiler-rt-with-use-runtimes.test b/validation-test/BuildSystem/llvm-build-compiler-rt-with-use-runtimes.test new file mode 100644 index 0000000000000..1101c40f3bc38 --- /dev/null +++ b/validation-test/BuildSystem/llvm-build-compiler-rt-with-use-runtimes.test @@ -0,0 +1,26 @@ +# REQUIRES: standalone_build + +# RUN: %empty-directory(%t) +# RUN: SKIP_XCODE_VERSION_CHECK=1 SWIFT_BUILD_ROOT=%t %swift_src_root/utils/build-script --dry-run --skip-build --llvm-build-compiler-rt-with-use-runtimes --cmake %cmake 2>&1 | %FileCheck --check-prefix=LLVM-USE-RUNTIMES %s +# RUN: %empty-directory(%t) +# RUN: SKIP_XCODE_VERSION_CHECK=1 SWIFT_BUILD_ROOT=%t %swift_src_root/utils/build-script --dry-run --skip-build --llvm-build-compiler-rt-with-use-runtimes=1 --cmake %cmake 2>&1 | %FileCheck --check-prefix=LLVM-USE-RUNTIMES %s + +# LLVM-USE-RUNTIMES: Building llvm +# LLVM-USE-RUNTIMES-DAG: cmake -G Ninja +# LLVM-USE-RUNTIMES-SAME: -ULLVM_TOOL_COMPILER_RT_BUILD +# LLVM-USE-RUNTIMES-SAME: -ULLVM_BUILD_EXTERNAL_COMPILER_RT +# LLVM-USE-RUNTIMES-SAME: -DLLVM_ENABLE_RUNTIMES{{[^ ]*}}={{[^ ]*}}compiler-rt +# LLVM-USE-RUNTIMES-SAME: runtimes +# LLVM-USE-RUNTIMES-SAME: llvm + +# RUN: %empty-directory(%t) +# RUN: SKIP_XCODE_VERSION_CHECK=1 SWIFT_BUILD_ROOT=%t %swift_src_root/utils/build-script --dry-run --skip-build --llvm-build-compiler-rt-with-use-runtimes --skip-build-compiler-rt --cmake %cmake 2>&1 | %FileCheck --check-prefix=DONT-BUILD-COMPILER-RT %s +# RUN: %empty-directory(%t) +# RUN: SKIP_XCODE_VERSION_CHECK=1 SWIFT_BUILD_ROOT=%t %swift_src_root/utils/build-script --dry-run --skip-build --llvm-build-compiler-rt-with-use-runtimes=1 --skip-build-compiler-rt --cmake %cmake 2>&1 | %FileCheck --check-prefix=DONT-BUILD-COMPILER-RT %s + +# DONT-BUILD-COMPILER-RT: Building llvm +# DONT-BUILD-COMPILER-RT-DAG: cmake -G Ninja +# DONT-BUILD-COMPILER-RT-NOT: LLVM_TOOL_COMPILER_RT_BUILD +# DONT-BUILD-COMPILER-RT-NOT: LLVM_BUILD_EXTERNAL_COMPILER_RT +# DONT-BUILD-COMPILER-RT-NOT: compiler-rt +# DONT-BUILD-COMPILER-RT-SAME: llvm