www.digitalmars.com         C & C++   DMDScript  

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

reply d-bugmail puremagic.com writes:
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 puremagic.com
        ReportedBy: pastas4 gmail.com



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: -------
Sep 22 2011
parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=6716


Denis Shelomovskij <verylonglogin.reg gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |verylonglogin.reg gmail.com



08:47:15 MSD ---
 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.
No, you don't need to call D `main` function. You just have to define it.
 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...
No, you can define D `main` in a separate file, not in your library and link with its object file. For more information read this: -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 12 2012