Skip to content

Commit 4b6b25d

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 8c34d5d commit 4b6b25d

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
@@ -975,6 +975,8 @@ endif()
975975
# Which default linker to use. Prefer LLVM_USE_LINKER if it set, otherwise use
976976
# our own defaults. This should only be possible in a unified (not stand alone)
977977
# build environment.
978+
include(GoldVersion)
979+
978980
if(LLVM_USE_LINKER)
979981
set(SWIFT_USE_LINKER_default "${LLVM_USE_LINKER}")
980982
elseif(SWIFT_HOST_VARIANT_SDK STREQUAL "ANDROID")
@@ -984,7 +986,17 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows" AND NOT CMAKE_HOST_SYSTEM_NAME STREQ
984986
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
985987
set(SWIFT_USE_LINKER_default "")
986988
else()
987-
set(SWIFT_USE_LINKER_default "gold")
989+
get_gold_version(gold_version)
990+
if(NOT gold_version)
991+
message(STATUS "GNU Gold not found; using lld instead")
992+
set(SWIFT_USE_LINKER_default "lld")
993+
elseif(gold_version VERSION_LESS "2.36")
994+
message(STATUS "GNU Gold is too old (${gold_version}); using lld instead")
995+
set(SWIFT_USE_LINKER_default "lld")
996+
else()
997+
message(STATUS "Using GNU Gold ${gold_version}")
998+
set(SWIFT_USE_LINKER_default "gold")
999+
endif()
9881000
endif()
9891001
set(SWIFT_USE_LINKER ${SWIFT_USE_LINKER_default} CACHE STRING
9901002
"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)