diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt index 761dab8c28c13..ee783d52e4a4e 100644 --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -15,6 +15,7 @@ endif() # Must go below project(..) include(GNUInstallDirs) +include(GetDarwinLinkerVersion) if(CLANG_BUILT_STANDALONE) set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ standard to conform to") @@ -346,20 +347,7 @@ endif () # Determine HOST_LINK_VERSION on Darwin. set(HOST_LINK_VERSION) if (APPLE AND NOT CMAKE_LINKER MATCHES ".*lld.*") - set(LD_V_OUTPUT) - execute_process( - COMMAND sh -c "${CMAKE_LINKER} -v 2>&1 | head -1" - RESULT_VARIABLE HAD_ERROR - OUTPUT_VARIABLE LD_V_OUTPUT - ) - if (HAD_ERROR) - message(FATAL_ERROR "${CMAKE_LINKER} failed with status ${HAD_ERROR}") - endif() - if ("${LD_V_OUTPUT}" MATCHES ".*ld64-([0-9.]+).*") - string(REGEX REPLACE ".*ld64-([0-9.]+).*" "\\1" HOST_LINK_VERSION ${LD_V_OUTPUT}) - elseif ("${LD_V_OUTPUT}" MATCHES "[^0-9]*([0-9.]+).*") - string(REGEX REPLACE "[^0-9]*([0-9.]+).*" "\\1" HOST_LINK_VERSION ${LD_V_OUTPUT}) - endif() + get_darwin_linker_version(HOST_LINK_VERSION) message(STATUS "Host linker version: ${HOST_LINK_VERSION}") endif() diff --git a/cmake/Modules/GetDarwinLinkerVersion.cmake b/cmake/Modules/GetDarwinLinkerVersion.cmake new file mode 100644 index 0000000000000..c27e50128586d --- /dev/null +++ b/cmake/Modules/GetDarwinLinkerVersion.cmake @@ -0,0 +1,19 @@ +# Get the linker version on Darwin +function(get_darwin_linker_version variable) + set(LINK_VERSION) + set(LD_V_OUTPUT) + execute_process( + COMMAND sh -c "${CMAKE_LINKER} -v 2>&1 | head -1" + RESULT_VARIABLE HAD_ERROR + OUTPUT_VARIABLE LD_V_OUTPUT + ) + if (HAD_ERROR) + message(FATAL_ERROR "${CMAKE_LINKER} failed with status ${HAD_ERROR}") + endif() + if ("${LD_V_OUTPUT}" MATCHES ".*ld64-([0-9.]+).*") + string(REGEX REPLACE ".*ld64-([0-9.]+).*" "\\1" LINK_VERSION ${LD_V_OUTPUT}) + elseif ("${LD_V_OUTPUT}" MATCHES "[^0-9]*([0-9.]+).*") + string(REGEX REPLACE "[^0-9]*([0-9.]+).*" "\\1" LINK_VERSION ${LD_V_OUTPUT}) + endif() + set(${variable} ${LINK_VERSION} PARENT_SCOPE) +endfunction() diff --git a/compiler-rt/CMakeLists.txt b/compiler-rt/CMakeLists.txt index d562a6206c00e..f4e92f14db857 100644 --- a/compiler-rt/CMakeLists.txt +++ b/compiler-rt/CMakeLists.txt @@ -36,6 +36,7 @@ include(SetPlatformToolchainTools) include(base-config-ix) include(CompilerRTUtils) include(CMakeDependentOption) +include(GetDarwinLinkerVersion) option(COMPILER_RT_BUILD_BUILTINS "Build builtins" ON) mark_as_advanced(COMPILER_RT_BUILD_BUILTINS) @@ -444,6 +445,15 @@ else() set(SANITIZER_USE_SYMBOLS FALSE) endif() +# Get the linker version while configuring compiler-rt and explicitly pass it +# in cflags during testing. This fixes the compiler/linker version mismatch +# issue when running a clang built with a newer Xcode in an older Xcode +set(COMPILER_RT_DARWIN_LINKER_VERSION) +if (APPLE AND NOT CMAKE_LINKER MATCHES ".*lld.*") + get_darwin_linker_version(COMPILER_RT_DARWIN_LINKER_VERSION) + message(STATUS "Host linker version: ${COMPILER_RT_DARWIN_LINKER_VERSION}") +endif() + # Build sanitizer runtimes with debug info. if(MSVC) # Use /Z7 instead of /Zi for the asan runtime. This avoids the LNK4099 diff --git a/compiler-rt/test/lit.common.cfg.py b/compiler-rt/test/lit.common.cfg.py index bd9b926c1505b..0ac20a9831d95 100644 --- a/compiler-rt/test/lit.common.cfg.py +++ b/compiler-rt/test/lit.common.cfg.py @@ -882,6 +882,10 @@ def is_windows_lto_supported(): elif config.use_lld and (not config.has_lld): config.unsupported = True +if config.host_os == "Darwin": + if getattr(config, "darwin_linker_version", None): + extra_cflags += ["-mlinker-version=" + config.darwin_linker_version] + # Append any extra flags passed in lit_config append_target_cflags = lit_config.params.get("append_target_cflags", None) if append_target_cflags: diff --git a/compiler-rt/test/lit.common.configured.in b/compiler-rt/test/lit.common.configured.in index db5d7c598b731..fff5dc6cc7509 100644 --- a/compiler-rt/test/lit.common.configured.in +++ b/compiler-rt/test/lit.common.configured.in @@ -51,6 +51,7 @@ set_default("expensive_checks", @LLVM_ENABLE_EXPENSIVE_CHECKS_PYBOOL@) set_default("test_standalone_build_libs", @COMPILER_RT_TEST_STANDALONE_BUILD_LIBS_PYBOOL@) set_default("has_compiler_rt_libatomic", @COMPILER_RT_BUILD_STANDALONE_LIBATOMIC_PYBOOL@) set_default("aarch64_sme", @COMPILER_RT_HAS_AARCH64_SME_PYBOOL@) +set_default("darwin_linker_version", "@COMPILER_RT_DARWIN_LINKER_VERSION@") # True iff the test suite supports ignoring the test compiler's runtime library path # and using `config.compiler_rt_libdir` instead. This only matters when the runtime # library paths differ.