The D ecosystem in Debian with free-as-in-freedom DMD

Iain Buclaw via Digitalmars-d digitalmars-d at puremagic.com
Tue Apr 11 09:54:46 PDT 2017


On 11 April 2017 at 17:48, Matthias Klumpp via Digitalmars-d
<digitalmars-d at puremagic.com> wrote:
> On Tuesday, 11 April 2017 at 15:31:46 UTC, David Nadlinger wrote:
>>
>> On Tuesday, 11 April 2017 at 12:38:01 UTC, Matthias Klumpp wrote:
>>>
>>> If you could change the SOVERSION with every one of these changes, or
>>> simply just tie it to the respective Phobos release, distributions would
>>> automatically do the right thing and compile all D code using Phobos against
>>> the new version.
>>
>>
>> As you mention, this is already done in LDC; not just the Debian packages,
>> but also upstream. The soname will always be `libphobos2-ldc.so.74` or what
>> have you.
>>
>> (Thinking about it, it should probably include the patch version as well,
>> although we haven't had a situation so far where we would have wanted to
>> release multiple LDC versions for ABI-incompatible patch releases.)
>
>
> Phobos is versioned properly in both GDC and LDC, and as long as that
> continues, no problems exist at all :-)
> https://packages.debian.org/search?suite=stretch&keywords=phobos
>
> This would - as said - also work for other D shared libraries, unless the D
> ABI in general breaks or someone tries to build a program with GDC and uses
> a library that was built with LDC or DMD (or any other possible compiler
> combination).
>

I thought I might try a "will it blend" experiment:

$ cat foo.d
module foo;

int times2(int a)
{
   return a * 2;
}

void throwIt(Throwable t)
{
    throw t;
}

$ cat test.d
import foo;

void main()
{
    import std.stdio;
    writeln("2 x 2 = ", times2(2));

    Throwable t = new Exception("Die!");
    try
    {
        throwIt(t);
    }
    catch (Exception e)
    {
        writeln("Caught Exception for: ", e.msg);
    }
}


1. Naive:

$ dmd -g -shared foo.d
$ ldd foo.so
    linux-vdso.so.1 =>  (0x00007ffc1a293000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0
(0x00007f0f78bed000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f0f789e5000)
    libgcc_s.so.1 => /usr/lib64/libgcc_s.so.1 (0x00007f0f787ce000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0f78405000)
    /lib64/ld-linux-x86-64.so.2 (0x0000557aa8c5f000)
$ gdc -g test.d foo.so -shared-libphobos
$ ldd a.out
    linux-vdso.so.1 =>  (0x00007fff020b9000)
    foo.so => ./foo.so (0x00007f262d66d000)
    libgphobos.so.71 => //usr/lib64/libgphobos.so.71 (0x00007f262cfd7000)
    libgdruntime.so.71 => /usr/lib64/libgdruntime.so.71 (0x00007f262ccde000)
    libgcc_s.so.1 => /usr/lib64/libgcc_s.so.1 (0x00007f262cac8000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f262c6d6000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f262c3cc000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0
(0x00007f262c1af000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f262bfab000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f262bda2000)
    /lib64/ld-linux-x86-64.so.2 (0x0000564d0bc19000)
$ ./a.out
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7bc01ae in gc_disable () from ./foo.so

Ouch, DMD's statically linked libphobos has overridden GDC's gc_disable().


2. Mixing shared libs.

$ dmd -g -defaultlib=phobos2 -shared foo.d
$ ldd foo.so
    linux-vdso.so.1 =>  (0x00007ffc84dfb000)
--> libphobos2.so.0.74 => /usr/lib/x86_64-linux-gnu/libphobos2.so.0.74
(0x00007f7574f53000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7574b8a000)
--> libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f7574985000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0
(0x00007f7574768000)
--> libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f757445f000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f7574256000)
    libgcc_s.so.1 => /usr/lib64/libgcc_s.so.1 (0x00007f7574040000)
    /lib64/ld-linux-x86-64.so.2 (0x000055c715c3e000)
$ gdc -g test.d foo.so -shared-libphobos
$ ldd a.out
    linux-vdso.so.1 =>  (0x00007ffd9e3eb000)
    foo.so => ./foo.so (0x00007fd09d9cc000)
    libgphobos.so.71 => /usr/lib64/libgphobos.so.71 (0x00007fd09d336000)
    libgdruntime.so.71 => /usr/lib64/libgdruntime.so.71 (0x00007fd09d03d000)
    libgcc_s.so.1 => /usr/lib64/libgcc_s.so.1 (0x00007fd09ce27000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd09ca35000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fd09c72b000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0
(0x00007fd09c50e000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fd09c30a000)
--> libphobos2.so.0.74 => /usr/lib/x86_64-linux-gnu/libphobos2.so.0.74
(0x00007fd09bae2000)
    /lib64/ld-linux-x86-64.so.2 (0x000056135abd3000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fd09b8da000)
$ ./a.out
Fatal Error while loading '/usr/lib/x86_64-linux-gnu/libphobos2.so.0.74':
    The module 'std.array' is already defined in '/usr/lib64/libgphobos.so.71'.

This seems bad, but it's actually a good sign.  GDC's copy of
rt.sections.checkModuleCollisions() has loaded DMD's shared libphobos
and has correctly determined that in there exists a module that shares
the same name.


3. Telling DMD not to link libphobos

$ dmd -g -defaultlib= -shared foo.d
$ ldd foo.so
    linux-vdso.so.1 =>  (0x00007ffdc2155000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f44ede1d000)
    /lib64/ld-linux-x86-64.so.2 (0x000055e14d836000)
$ gdc -g test.d foo.so -shared-libphobos
foo.so: undefined reference to `_d_throwdwarf'
collect2: error: ld returned 1 exit status

This is expected, GDC's libgdruntime doesn't have this.  So I added it
as a stub:

extern(C) void _d_throwdwarf(Throwable o)
{
   throw o;
}


$ gdc -g test.d foo.so -shared-libphobos
$ ldd a.out
    linux-vdso.so.1 =>  (0x00007fffb05ee000)
    foo.so => ./foo.so (0x00007fe818644000)
    libgphobos.so.71 => /usr/lib64/libgphobos.so.71 (0x00007fe817fae000)
    libgdruntime.so.71 => /usr/lib64/libgdruntime.so.71 (0x00007fe817cb5000)
    libgcc_s.so.1 => /usr/lib64/libgcc_s.so.1 (0x00007fe817a9f000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe8176ad000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fe8173a3000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0
(0x00007fe817186000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fe816f82000)
    /lib64/ld-linux-x86-64.so.2 (0x00005644b677f000)
$ ./a.out
2 x 2 = 4
Caught Exception for: Die!


Success!  There may be some hope, but you currently need a
compatibility library for linking DMD compiled objects with GDC
programs.  And you must cut out Phobos out of the third party D
library so that the library for the compiler building the application
holds the one and only reference to symbols.


More information about the Digitalmars-d mailing list