September 27, 2016
On 2016-09-27 11:18, Jacob Carlborg wrote:
> 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
>

"doing that", I meant to say "automatically initialize druntime".

-- 
/Jacob Carlborg
September 27, 2016
Don't think it can be made much better for object files but it should be relatively simple to enable creating "C-friendly" static D libraries that include all required runtime bits as part of the library.
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.
>
> [snip]
>
> How much of an issue is this with D? Is it something we need to address?

We've been toying with this in setting up LDC's build such that it works on different platforms. Wait, "toying" implies "fun". It was anything but.
At first, we used the D compiler to do the final linking, but it resulted in troubles when special linker flags are needed.
We've now moved to using the system linker separately to do the linking.
https://github.com/ldc-developers/ldc/pull/1594

For this, we use `-v` to figure out what the system linker is and what linker flags are passed by the D compiler (link with phobos, druntime, etc.). But it needs "parsing" of `-v` output, quite annoying.
See https://github.com/ldc-developers/ldc/blob/master/cmake/Modules/ExtractDMDSystemLinker.cmake

The idea to add a cmdline flag `-ldflags` that would just output the linking flags, did not get a response.
https://forum.dlang.org/post/gqaujnbgbpauirbezjki@forum.dlang.org
I think it will save people a lot of time and frustration. (possible improvements can be made such that the output of `-ldflags` also includes extra link flags when special compiler flags are passed, such as `-fprofile-instr-generate`.)

-Johan
September 27, 2016
On 9/27/16 4:12 AM, 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.
>

Does it? your function seems to not require any druntime features.

I would say -betterC is the way to fix this, as conservatively not emitting druntime requirements is probably a lot more involved than a directive from the build that no druntime is required.

-Steve
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.
>
> [...]

I think it should work as well as it does in C++, if possible. The equivalent to the example above links fine for foo.cpp. It's only if you use the standard library or throw exceptions that you need to link with g++ instead.

Atila
September 27, 2016
On Tuesday, 27 September 2016 at 10:46:23 UTC, Johan Engelen wrote:
> 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.
>>
>> [snip]
>>
>> How much of an issue is this with D? Is it something we need to address?
>
> We've been toying with this in setting up LDC's build such that it works on different platforms. […]
> We've now moved to using the system linker separately to do the linking.

To clarify: What we are doing in LDC is of course not what was suggested in the initial post, i.e. linking D object files into C executables without any (explicit) druntime dependencies and expecting this to work.

The problem we were facing in particular is that many C/C++ libraries (such as LLVM) come with a list of linker flags to use in the form of pkg-config or a similar tool. These will usually be formatted for the default way of linking C on the system (i.e. through a gcc-compatible interface). Thus, you can't just prefix them with -L and forward them to the D compiler since that forwards them directly to the low-level linker (-Xlinker, …).

This is a problem which *every* D project that wants to seamlessly link against system C libraries on Linux needs to solve.

There are two obvious ways to improve the situation:
 - Like Johan suggested, add a D compiler flag that prints the default linker flags used to create D executables.
 - Add a D compiler flag to forward flags directly to the linker driver used, without using -Xlinker.

Unfortunately, the LDC build system of course needs to work with existing host compilers anyway, so these wouldn't have helped us with shipping the first DDMD-based version. The most robust solution I could come up with was to extract the linker command line used from `$DMD -v some_test_executable.d` to then pass the same flags directly to the system gcc when building the D program.

 — David
September 28, 2016
On Monday, 26 September 2016 at 23:47:45 UTC, Jonathan M Davis wrote:
> 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.

Ugh, no, you can't use C as well as D. Dare I say, C is only for maintenance of legacy code; if you have a choice, use D, it's just better. Non-starters are GC and exceptions. Asserts and bounds checking are one-liners (and for really minimal code even they are not needed), string switch is another couple of lines and you get the type system and all the compile time capabilities of D that you're never going to have in C (that modern convenience and modelling power).
September 28, 2016
On Tuesday, 27 September 2016 at 12:58:36 UTC, Steven Schveighoffer wrote:
> Does it? your function seems to not require any druntime features.
>
> I would say -betterC is the way to fix this, as conservatively not emitting druntime requirements is probably a lot more involved than a directive from the build that no druntime is required.

LDC only emits one unresolved symbol _Dmodule_ref from module initializer and that's all, so it can be linked with, say, ld --defsym _Dmodule_ref=16
September 28, 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.
>
> 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?

Many users that want/need to use D without druntime, which implies nothrow @nogc, --boundscheck=off, no unittests (and probably a couple of other things) and we need to support these use cases. In other words,
the compiler should detect if a given module does not use any druntime features and in such cases it should not emit calls/ linktime references to druntime. I don't know if in general the compiler can tell if certain runtime features (e.g. exception handling support) are not used needed, so at first we may require the -betterC switch to supplied.
September 29, 2016
On Monday, 26 September 2016 at 23:32:05 UTC, Walter Bright wrote:
> How much of an issue is this with D? Is it something we need to address?

I've run into this problem a few times and it took me a while to understand how to correctly initialize the druntime (including attaching pthreads), when I was implementing dfuse. This is not necessarily only limited to using D from C but also from using C libraries that create threads or do other funky things that the druntime needs to be aware of.

It would be great to have a section in the documentation on how to correctly initialize the druntime, which are typical pitfalls (threads created in C land, callbacks into C, etc) and how to correctly link druntime.

If we don't do this already we should offer a phobos.lib on windows, and phobos.a on MacOS/Linux (the latter one i think we do).