Thread overview | |||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
September 26, 2016 Linking D code into existing C programs | ||||
---|---|---|---|---|
| ||||
Linking C libraries and object code into D programs has always worked easily in D. The other way around, not so well. Consider the following C program: ---- main.c ---- extern int foo(); void main(int argc, char* argv[]) { foo(); } ---- foo.c ---- int foo() { return 7; } --------------- Compile/link in the usual way: gcc main.c -c gcc foo.c -c gcc main.o foo.o No problem. Now replace foo.c with foo.d: ---- foo.d ---- extern (C) int foo() { return 7; } --------------- Compile/link with: gcc main.c -c dmd foo.d -c gcc main.o foo.o Produces: bar.o:(.eh_frame+0x13): undefined reference to `__dmd_personality_v0' bar.o: In function `_D3bar7__arrayZ': bar.d:(.text._D3bar7__arrayZ+0x21): undefined reference to `_d_arraybounds' bar.o: In function `_D3bar8__assertFiZv': bar.d:(.text._D3bar8__assertFiZv+0x21): undefined reference to `_d_assert' bar.o: In function `_D3bar15__unittest_failFiZv': bar.d:(.text._D3bar15__unittest_failFiZv+0x21): undefined reference to `_d_unittest' bar.o: In function `__d_dso_init': bar.d:(.text.d_dso_init[.data.d_dso_rec]+0x28): undefined reference to `_d_dso_registry' collect2: error: ld returned 1 exit status How much of an issue is this with D? Is it something we need to address? |
September 26, 2016 Re: Linking D code into existing C programs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Monday, September 26, 2016 16:32:05 Walter Bright via Digitalmars-d wrote:
> Linking C libraries and object code into D programs has always worked easily in D. The other way around, not so well.
>
> Consider the following C program:
>
> ---- main.c ----
> extern int foo();
> void main(int argc, char* argv[]) {
> foo();
> }
> ---- foo.c ----
> int foo() { return 7; }
> ---------------
>
> Compile/link in the usual way:
>
> gcc main.c -c
> gcc foo.c -c
> gcc main.o foo.o
>
> No problem.
> Now replace foo.c with foo.d:
>
> ---- foo.d ----
> extern (C) int foo() { return 7; }
> ---------------
>
> Compile/link with:
>
> gcc main.c -c
> dmd foo.d -c
> gcc main.o foo.o
>
> Produces:
>
> bar.o:(.eh_frame+0x13): undefined reference to `__dmd_personality_v0'
> bar.o: In function `_D3bar7__arrayZ':
> bar.d:(.text._D3bar7__arrayZ+0x21): undefined reference to
> `_d_arraybounds' bar.o: In function `_D3bar8__assertFiZv':
> bar.d:(.text._D3bar8__assertFiZv+0x21): undefined reference to
> `_d_assert' bar.o: In function `_D3bar15__unittest_failFiZv':
> bar.d:(.text._D3bar15__unittest_failFiZv+0x21): undefined reference to
> `_d_unittest'
> bar.o: In function `__d_dso_init':
> bar.d:(.text.d_dso_init[.data.d_dso_rec]+0x28): undefined reference to
> `_d_dso_registry'
> collect2: error: ld returned 1 exit status
>
> How much of an issue is this with D? Is it something we need to address?
Well, in this case, you're basically trying to use D without druntime, which generally is a total non-starter anyway. If you're not using druntime, then you might as well be using C, since you're not even going to get basic stuff like array bounds checking. So, I don't think that that really matters.
That being said, I would hope that it wouldn't be all that hard to properly link D code into a C/C++ program and use it (complete with druntime and Phobos). There's no guarantee that D is going to get to be what's driving the program even if you can use D for a lot of it. But isn't the fix for that to link in libphobos.a? I'm pretty sure that I've linked D into a C program before, but it's been a while, so I don't recall exactly what you have to do. But it doesn't seem all that unreasonable to me that you'd have to explicitly link in D's runtime library. It's not like the C linker is going to know about it auto-magically.
As long as there's a reasonably easy and properly documented way to link D code into a C/C++ program, I think that we're fine. But I don't think that your exact example needs to work exactly as-is. It just shouldn't be much harder than that. e.g. something like
gcc main.o foo.o -lphobos.a
should probably work.
- Jonathan M Davis
|
September 26, 2016 Re: Linking D code into existing C programs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On 09/26/2016 07:32 PM, Walter Bright wrote: > > How much of an issue is this with D? Is it something we need to address? I don't know anything about the technical side of this issue, but I do think it's an important thing to have working well, since I believe it's important for us to start marketing our D-based libraries as easily usable from C: https://semitwist.com/articles/article/view/we-re-overlooking-a-key-part-of-c-c-d-user-migration |
September 27, 2016 Re: Linking D code into existing C programs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Monday, 26 September 2016 at 23:32:05 UTC, Walter Bright wrote: > Linking C libraries and object code into D programs has always worked easily in D. The other way around, not so well. > > [...] > Produces: > > bar.o:(.eh_frame+0x13): undefined reference to `__dmd_personality_v0' > bar.o: In function `_D3bar7__arrayZ': > bar.d:(.text._D3bar7__arrayZ+0x21): undefined reference to `_d_arraybounds' > bar.o: In function `_D3bar8__assertFiZv': > bar.d:(.text._D3bar8__assertFiZv+0x21): undefined reference to `_d_assert' > bar.o: In function `_D3bar15__unittest_failFiZv': > bar.d:(.text._D3bar15__unittest_failFiZv+0x21): undefined reference to `_d_unittest' > bar.o: In function `__d_dso_init': > bar.d:(.text.d_dso_init[.data.d_dso_rec]+0x28): undefined reference to `_d_dso_registry' > collect2: error: ld returned 1 exit status > > How much of an issue is this with D? Is it something we need to address? This reminds me a huge clusterfuck encountered when trying to link an interfaced version of libdparse in Object Pascal: http://forum.lazarus.freepascal.org/index.php/topic,32340.msg208499.html#msg208499 Soon or later this will happen again. But the next time the guy could completely give up and say "D is shitty". |
September 27, 2016 Re: Linking D code into existing C programs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On 2016-09-27 01:32, Walter Bright wrote: > Linking C libraries and object code into D programs has always worked > easily in D. The other way around, not so well. > > Consider the following C program: > > ---- main.c ---- > extern int foo(); > void main(int argc, char* argv[]) { > foo(); > } > ---- foo.c ---- > int foo() { return 7; } > --------------- > > Compile/link in the usual way: > > gcc main.c -c > gcc foo.c -c > gcc main.o foo.o > > No problem. > Now replace foo.c with foo.d: > > ---- foo.d ---- > extern (C) int foo() { return 7; } > --------------- > > Compile/link with: > > gcc main.c -c > dmd foo.d -c > gcc main.o foo.o > > Produces: > > bar.o:(.eh_frame+0x13): undefined reference to `__dmd_personality_v0' > bar.o: In function `_D3bar7__arrayZ': > bar.d:(.text._D3bar7__arrayZ+0x21): undefined reference to > `_d_arraybounds' > bar.o: In function `_D3bar8__assertFiZv': > bar.d:(.text._D3bar8__assertFiZv+0x21): undefined reference to > `_d_assert' > bar.o: In function `_D3bar15__unittest_failFiZv': > bar.d:(.text._D3bar15__unittest_failFiZv+0x21): undefined reference to > `_d_unittest' > bar.o: In function `__d_dso_init': > bar.d:(.text.d_dso_init[.data.d_dso_rec]+0x28): undefined reference to > `_d_dso_registry' > collect2: error: ld returned 1 exit status > > How much of an issue is this with D? Is it something we need to address? I don't see how that can be expected to work. You're not linking druntime. The easiest is to link with DMD instead of GCC. An alternative is to compile the D code with -betterC to avoid the runtime (not sure what happens with the personality function), although that's currently broken [1]. [1] https://issues.dlang.org/show_bug.cgi?id=16547 -- /Jacob Carlborg |
September 27, 2016 Re: Linking D code into existing C programs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On 9/27/2016 12:03 AM, Jacob Carlborg wrote:
> You're not linking druntime.
That's one issue. The other one is druntime needs to be initialized, and calling a random D function won't do that.
|
September 27, 2016 Re: Linking D code into existing C programs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Monday, 26 September 2016 at 23:32:05 UTC, Walter Bright wrote:
> Linking C libraries and object code into D programs has always worked easily in D. The other way around, not so well.
>
> [...]
Yes, this is what Mir need to replace Eigen and OpenBLAS. Mir do not need DRuntime.
|
September 27, 2016 Re: Linking D code into existing C programs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Tuesday, 27 September 2016 at 08:12:58 UTC, Walter Bright wrote:
> On 9/27/2016 12:03 AM, Jacob Carlborg wrote:
>> You're not linking druntime.
>
> That's one issue. The other one is druntime needs to be initialized, and calling a random D function won't do that.
We've got to consider that when it is statically linked, and also dynamically as well.
Also, if it's statically linked, will the linker just use parts of druntime that are actually used by the D libtrary?
For instance, if the D library does not use exceptions, ideally it should not link any related code in druntime (it's important, especially in embedded software).
|
September 27, 2016 Re: Linking D code into existing C programs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Claude | On 2016-09-27 10:50, Claude wrote: > We've got to consider that when it is statically linked, and also > dynamically as well. > > Also, if it's statically linked, will the linker just use parts of > druntime that are actually used by the D libtrary? > > For instance, if the D library does not use exceptions, ideally it > should not link any related code in druntime (it's important, especially > in embedded software). In will include module and type info. It might include some runtime functions for exceptions unless all functions are marked with "nothrow". -- /Jacob Carlborg |
September 27, 2016 Re: Linking D code into existing C programs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On 2016-09-27 10:12, Walter Bright wrote: > That's one issue. The other one is druntime needs to be initialized, and > calling a random D function won't do that. Long time ago I suggested doing that [1]. Not sure if that file is currently compiled and linked into the runtime. But, IIRC, there was complains when I suggested doing this because, as I was told, if you're using a D library in a C application you most likely want to have more control of the initialization of druntime. [1] https://github.com/dlang/druntime/blob/master/src/rt/dylib_fixes.c -- /Jacob Carlborg |
Copyright © 1999-2021 by the D Language Foundation