Jump to page: 1 2 3
Thread overview
Linking D code into existing C programs
Sep 26, 2016
Walter Bright
Sep 26, 2016
Jonathan M Davis
Sep 28, 2016
Kagamin
Sep 27, 2016
Nick Sabalausky
Sep 27, 2016
Basile B.
Sep 27, 2016
Jacob Carlborg
Sep 27, 2016
Walter Bright
Sep 27, 2016
Claude
Sep 27, 2016
Jacob Carlborg
Sep 27, 2016
Jacob Carlborg
Sep 27, 2016
Jacob Carlborg
Sep 28, 2016
Kagamin
Sep 27, 2016
Ilya Yaroshenko
Sep 27, 2016
Dicebot
Sep 27, 2016
Johan Engelen
Sep 27, 2016
David Nadlinger
Sep 27, 2016
Atila Neves
Sep 28, 2016
ZombineDev
Sep 29, 2016
David Soria Parra
Sep 29, 2016
Walter Bright
September 26, 2016
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
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
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
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
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
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
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
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
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
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
« First   ‹ Prev
1 2 3