Skip to content

Commit f64b1ca

Browse files
author
Dentcho Bankov
committed
Fix issue #3795 - Fix LDC linked dynamically
with Phobos and DRuntime when built with GDMD. Prepend arguments starting with "-B" in D_LINKER_ARGS with "-Wl," when using GDMD. The latter is needed because the arguments reported by GDMD are what is passed to COLLECT2 while D_LINKER_ARGS are later passed to CXX. The problem with that is that without "-Wl," prefix the -Bstatic and -Bdynamic arguments before and after -lgphobos and -lgdruntime are dropped. And that is a problem because without these the produced LDC is linked dynamically to libgphobos and libgdruntime so these have to be available whereever LDC is used. Once libgphobos and libgdruntime are linked statically symbol conflicts for _d_allocmemory, _d_newclass, _d_newitemiT and _d_newitemT symbols were revealed which are fixed by checking if these symbols are marked as weak in libgdruntime.a and if not "-Wl,-allow-multiple-definition" link option is added to avoid link failure.
1 parent 054df3a commit f64b1ca

File tree

1 file changed

+52
-2
lines changed

1 file changed

+52
-2
lines changed

cmake/Modules/ExtractDMDSystemLinker.cmake

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,63 @@ list(GET linker_line 0 D_LINKER_COMMAND)
6565
list(REMOVE_AT linker_line 0)
6666

6767
if("${D_COMPILER_ID}" STREQUAL "GDMD")
68-
# Filter linker arguments for those we know can be safely reused
68+
# Filter linker arguments for those we know can be safely reused.
69+
# Prepend arguments starting with "-B" in D_LINKER_ARGS with "-Wl," when
70+
# using GDMD. The latter is needed because the arguments reported by GDMD
71+
# are what is passed to COLLECT2 while D_LINKER_ARGS are later passed to
72+
# CXX. The problem with that is that without "-Wl," prefix the -Bstatic
73+
# and -Bdynamic arguments before and after -lgphobos and -lgdruntime are
74+
# dropped. And that is a problem because without these the produced LDC is
75+
# linked dynamically to libgphobos and libgdruntime so these have to be
76+
# available whereever LDC is used.
77+
78+
# Once libgphobos and libgdruntime are linked statically symbol conflicts
79+
# for _d_allocmemory, _d_newclass, _d_newitemiT and _d_newitemT symbols
80+
# were revealed which are fixed by checking if these symbols are marked as
81+
# weak in libgdruntime.a and if not "-Wl,-allow-multiple-definition" link
82+
# option is added to avoid link failure.
6983
set(D_LINKER_ARGS)
84+
set(BSTATIC OFF)
85+
set(STATIC_GPHOBOS OFF)
7086
foreach(arg ${linker_line})
71-
if("${arg}" MATCHES ^-L.*|^-l.*|^-B.*)
87+
if("${arg}" MATCHES ^-L.*|^-l.*)
7288
list(APPEND D_LINKER_ARGS "${arg}")
89+
if(BSTATIC)
90+
if("${arg}" STREQUAL -lgphobos)
91+
set(STATIC_GPHOBOS ON)
92+
endif()
93+
endif()
94+
elseif("${arg}" MATCHES ^-B.*)
95+
list(APPEND D_LINKER_ARGS "-Wl,${arg}")
96+
if("${arg}" STREQUAL -Bstatic)
97+
set(BSTATIC ON)
98+
elseif("${arg}" STREQUAL -Bdynamic)
99+
set(BSTATIC OFF)
100+
endif()
73101
endif()
74102
endforeach()
103+
if(STATIC_GPHOBOS)
104+
execute_process(
105+
COMMAND "${D_COMPILER}" -q,-print-file-name=libgdruntime.a
106+
COMMAND "head" -n1
107+
COMMAND "xargs" nm -gC
108+
COMMAND "grep"
109+
-e \\<_d_allocmemory\\>
110+
-e \\<_d_newclass\\>
111+
-e \\<_d_newitemiT\\>
112+
-e \\<_d_newitemT\\>
113+
COMMAND "cut" -d " " -f 2
114+
COMMAND "sort"
115+
COMMAND "uniq"
116+
OUTPUT_VARIABLE LIB_GDRUNTIME_LIFETIME_SYMBOL_TYPES
117+
ERROR_QUIET)
118+
string(STRIP
119+
${LIB_GDRUNTIME_LIFETIME_SYMBOL_TYPES}
120+
LIB_GDRUNTIME_LIFETIME_SYMBOL_TYPES)
121+
if(NOT LIB_GDRUNTIME_LIFETIME_SYMBOL_TYPES STREQUAL W)
122+
list(APPEND D_LINKER_ARGS "-Wl,--allow-multiple-definition")
123+
endif()
124+
endif()
75125
else()
76126
set(D_LINKER_ARGS ${linker_line})
77127
endif()

0 commit comments

Comments
 (0)