Skip to content

Commit

Permalink
Fix issue #3795 - Fix LDC linked dynamically
Browse files Browse the repository at this point in the history
with Phobos and DRuntime when built with GDMD.

Prepend each argument in D_LINKER_ARGS with "-Wl," when using GDMD.
The above 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 -libgdruntime 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 were linked statically several symbol
conflicts were revealed which are fixed by moving the offending symbols
within "version (LDC)" blocks.
  • Loading branch information
dbankov-vmware committed Aug 11, 2021
1 parent 054df3a commit 43d4b5d
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 17 deletions.
2 changes: 1 addition & 1 deletion cmake/Modules/ExtractDMDSystemLinker.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ if("${D_COMPILER_ID}" STREQUAL "GDMD")
set(D_LINKER_ARGS)
foreach(arg ${linker_line})
if("${arg}" MATCHES ^-L.*|^-l.*|^-B.*)
list(APPEND D_LINKER_ARGS "${arg}")
list(APPEND D_LINKER_ARGS "-Wl,${arg}")
endif()
endforeach()
else()
Expand Down
44 changes: 28 additions & 16 deletions dmd/root/rmem.d
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,12 @@ static if (OVERRIDE_MEMALLOC)
// That scheme is faster and comes with less memory overhead than using a
// disabled GC alone.

extern (C) void* _d_allocmemory(size_t m_size) nothrow
version (LDC)
{
return allocmemory(m_size);
extern (C) void* _d_allocmemory(size_t m_size) nothrow
{
return allocmemory(m_size);
}
}

private void* allocClass(const ClassInfo ci) nothrow pure
Expand All @@ -242,13 +245,16 @@ static if (OVERRIDE_MEMALLOC)

extern (C) void* _d_newitemU(const TypeInfo ti) nothrow;

extern (C) Object _d_newclass(const ClassInfo ci) nothrow
version (LDC)
{
const initializer = ci.initializer;
extern (C) Object _d_newclass(const ClassInfo ci) nothrow
{
const initializer = ci.initializer;

auto p = mem.isGCEnabled ? allocClass(ci) : allocmemoryNoFree(initializer.length);
memcpy(p, initializer.ptr, initializer.length);
return cast(Object) p;
auto p = mem.isGCEnabled ? allocClass(ci) : allocmemoryNoFree(initializer.length);
memcpy(p, initializer.ptr, initializer.length);
return cast(Object) p;
}
}

version (LDC)
Expand All @@ -262,19 +268,25 @@ static if (OVERRIDE_MEMALLOC)
}
}

extern (C) void* _d_newitemT(TypeInfo ti) nothrow
version (LDC)
{
auto p = mem.isGCEnabled ? _d_newitemU(ti) : allocmemoryNoFree(ti.tsize);
memset(p, 0, ti.tsize);
return p;
extern (C) void* _d_newitemT(TypeInfo ti) nothrow
{
auto p = mem.isGCEnabled ? _d_newitemU(ti) : allocmemoryNoFree(ti.tsize);
memset(p, 0, ti.tsize);
return p;
}
}

extern (C) void* _d_newitemiT(TypeInfo ti) nothrow
version (LDC)
{
auto p = mem.isGCEnabled ? _d_newitemU(ti) : allocmemoryNoFree(ti.tsize);
const initializer = ti.initializer;
memcpy(p, initializer.ptr, initializer.length);
return p;
extern (C) void* _d_newitemiT(TypeInfo ti) nothrow
{
auto p = mem.isGCEnabled ? _d_newitemU(ti) : allocmemoryNoFree(ti.tsize);
const initializer = ti.initializer;
memcpy(p, initializer.ptr, initializer.length);
return p;
}
}

// TypeInfo.initializer for compilers older than 2.070
Expand Down

0 comments on commit 43d4b5d

Please sign in to comment.