[Issue 6716] New: Linking a C program with D library causes DEH errors

d-bugmail at puremagic.com d-bugmail at puremagic.com
Thu Sep 22 12:03:03 PDT 2011


http://d.puremagic.com/issues/show_bug.cgi?id=6716

           Summary: Linking a C program with D library causes DEH errors
           Product: D
           Version: D2
          Platform: x86_64
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Phobos
        AssignedTo: nobody at puremagic.com
        ReportedBy: pastas4 at gmail.com


--- Comment #0 from GreatEmerald <pastas4 at gmail.com> 2011-09-22 12:02:32 PDT ---
This is a pretty specific bug in that it happens only on Linux ld, and has a
pretty specific workaround. If we have two files, a D library like this:

-----------
module lib;
import std.stdio;

extern (C):
void libraryFunction()
{
    writeln("Hello library world!");
}
-----------

And a C executable like this:

-----------
#include <stdio.h>

int main()
{
    rt_init();
    libraryFunction();
    rt_term();
    printf("Hello executable world!");
    getchar();
    return 0;
}
-----------

They will not link properly. These are the commands used:

-----------
dmd -lib lib.d
gcc -c bin.c
dmd bin.o lib.a
-----------

The linker errors are these (skipped duplicates):

-----------
src/core/thread.d:(.text._D4core6thread6Thread6__ctorMFPFZvmZC4core6thread6Thread+0x2b):
undefined reference to `_tlsend'
src/core/thread.d:(.text._D4core6thread6Thread6__ctorMFPFZvmZC4core6thread6Thread+0x36):
undefined reference to `_tlsstart'
src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0xa):
undefined reference to `_deh_beg'
src/rt/deh2.d:(.text._D2rt4deh213__eh_finddataFPvZPS2rt4deh213DHandlerTable+0x1e):
undefined reference to `_deh_end'
src/rt/lifetime.d:(.text._D2rt8lifetime18_sharedStaticCtor9FZv+0x15): undefined
reference to `_tlsend'
src/rt/lifetime.d:(.text._D2rt8lifetime18_sharedStaticCtor9FZv+0x29): undefined
reference to `_tlsstart'
-----------

In order to work around the problem, you have to define a main() function that
is not extern(C) and that gets called from an extern(C) function at some point.
That makes the D library file look like this:

-----------
module lib;
import std.stdio;

void main(){}
extern (C):
void libraryFunction()
{
    main();
    writeln("Hello library world!");
}
-----------

Naturally, the downside of this method is that you can no longer use such
library with D executables, since a redundancy is created by two conflicting
definitions of main(). And the only way to work around the latter problem so
far is to use a version(identifier) system...

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------


More information about the Digitalmars-d-bugs mailing list