Skip to content

Commit d20c02d

Browse files
committed
[Build] Detect ld.gold version and prefer lld if gold is too old.
If we're on a system that has ld.gold 2.35 or earlier, we want to use lld instead because otherwise we end up with duplicate sections in the output. rdar://123504095
1 parent 77944e6 commit d20c02d

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

CMakeLists.txt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -977,6 +977,8 @@ endif()
977977
# Which default linker to use. Prefer LLVM_USE_LINKER if it set, otherwise use
978978
# our own defaults. This should only be possible in a unified (not stand alone)
979979
# build environment.
980+
include(GoldVersion)
981+
980982
if(LLVM_USE_LINKER)
981983
set(SWIFT_USE_LINKER_default "${LLVM_USE_LINKER}")
982984
elseif(SWIFT_HOST_VARIANT_SDK STREQUAL "ANDROID")
@@ -988,7 +990,17 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
988990
elseif(DISTRO_NAME STREQUAL "Amazon Linux 2023")
989991
set(SWIFT_USE_LINKER_default "lld")
990992
else()
991-
set(SWIFT_USE_LINKER_default "gold")
993+
get_gold_version(gold_version)
994+
if(NOT gold_version)
995+
message(STATUS "GNU Gold not found; using lld instead")
996+
set(SWIFT_USE_LINKER_default "lld")
997+
elseif(gold_version VERSION_LESS "2.36")
998+
message(STATUS "GNU Gold is too old (${gold_version}); using lld instead")
999+
set(SWIFT_USE_LINKER_default "lld")
1000+
else()
1001+
message(STATUS "Using GNU Gold ${gold_version}")
1002+
set(SWIFT_USE_LINKER_default "gold")
1003+
endif()
9921004
endif()
9931005
set(SWIFT_USE_LINKER ${SWIFT_USE_LINKER_default} CACHE STRING
9941006
"Build Swift with a non-default linker")

cmake/modules/GoldVersion.cmake

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Find the version of ld.gold, if installed.
2+
#
3+
# Versions prior to 2.36 break Swift programs because they won't coalesce
4+
# sections with different SHF_GNU_RETAIN flags.
5+
function(get_gold_version result_var_name)
6+
find_program(gold_executable "ld.gold")
7+
if(gold_executable)
8+
execute_process(
9+
COMMAND "${gold_executable}" "--version"
10+
COMMAND "head" "-n" "1"
11+
COMMAND "sed" "-e" "s/^.* (\\([^)]*\\)).*$/\\1/g;s/.* \\([0-9][0-9]*\\(\\.[0-9][0-9]*\\)*\\).*/\\1/g"
12+
OUTPUT_VARIABLE gold_version
13+
OUTPUT_STRIP_TRAILING_WHITESPACE)
14+
set("${result_var_name}" "${gold_version}" PARENT_SCOPE)
15+
else()
16+
set("${result_var_name}" "" PARENT_SCOPE)
17+
endif()
18+
endfunction()

0 commit comments

Comments
 (0)