Skip to content

Commit a014bd2

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 f5b1ef7 commit a014bd2

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
@@ -983,6 +983,8 @@ endif()
983983
# Which default linker to use. Prefer LLVM_USE_LINKER if it set, otherwise use
984984
# our own defaults. This should only be possible in a unified (not stand alone)
985985
# build environment.
986+
include(GoldVersion)
987+
986988
if(LLVM_USE_LINKER)
987989
set(SWIFT_USE_LINKER_default "${LLVM_USE_LINKER}")
988990
elseif(SWIFT_HOST_VARIANT_SDK STREQUAL "ANDROID")
@@ -994,7 +996,17 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
994996
elseif(DISTRO_NAME STREQUAL "Amazon Linux 2023")
995997
set(SWIFT_USE_LINKER_default "lld")
996998
else()
997-
set(SWIFT_USE_LINKER_default "gold")
999+
get_gold_version(gold_version)
1000+
if(NOT gold_version)
1001+
message(STATUS "GNU Gold not found; using lld instead")
1002+
set(SWIFT_USE_LINKER_default "lld")
1003+
elseif(gold_version VERSION_LESS "2.36")
1004+
message(STATUS "GNU Gold is too old (${gold_version}); using lld instead")
1005+
set(SWIFT_USE_LINKER_default "lld")
1006+
else()
1007+
message(STATUS "Using GNU Gold ${gold_version}")
1008+
set(SWIFT_USE_LINKER_default "gold")
1009+
endif()
9981010
endif()
9991011
set(SWIFT_USE_LINKER ${SWIFT_USE_LINKER_default} CACHE STRING
10001012
"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)