Shared Object with DMD v2.031

Sergey Gromov snake.scaly at gmail.com
Sat Aug 1 15:18:28 PDT 2009


Fri, 31 Jul 2009 18:50:28 +0000 (UTC), teo wrote:

> On Fri, 31 Jul 2009 18:47:29 +0400, Sergey Gromov wrote:
> 
>> Thu, 30 Jul 2009 06:52:14 +0000 (UTC), teo wrote:
>> 
>>> I have difficulties creating a Shared Object (.so) with D. Is it
>>> possible? Can I use classes defined in the library from the executable?
>>> 
>>> Here is my library file:
>>> module test; // file "test.d"
>>> export int testMe() { return 1; }
>>> export class Test
>>> {
>>>     private int n;
>>>     this(int i) { n = i; }
>>>     int get() { return n; }
>>> }
>>> 
>>> I compile like shown below:
>>> $ dmd -fPIC -c test.d
>>> $ gcc -shared -o libtest.so test.o
>>> 
>>> [snip]
>>> 
>>> And this is the program:
>>> module main; // file "prog.d"
>>> import std.stdio;
>>> import test;
>>> void main()
>>> {
>>>    writefln("testMe: %d", testMe());
>>>    writefln("Test class: %d", (new Test(3)).get());
>>> }
>>> 
>>> I compile it with:
>>> $ dmd prog.d -L-L`pwd` -L-ltest
>>> 
>>> And get:
>>> /usr/bin/ld: dynamic variable `_D4test4Test7__ClassZ' is zero size
>>> /usr/bin/ld: prog.o(.text._Dmain+0x26): unresolvable R_386_32
>>> relocation against symbol `_D4test4Test7__ClassZ' /usr/bin/ld: final
>>> link failed: Nonrepresentable section on output collect2: ld returned 1
>>> exit status
>>> --- errorlevel 1
>>> 
>>> Please note that "_D4test4Test7__ClassZ" is defined in the library.
>>> 
>>> BTW compiling with following works:
>>> $ dmd test.d prog.d
>> 
>> I get the same results, i.e. it does not work.  Though with one
>> clarification: from the command:
>> 
>>> $ gcc -shared -o libtest.so test.o
>> 
>> I get a warning:
>> 
>>> /usr/lib/gcc/i686-pc-linux-gnu/4.3.3/../../../../i686-pc-linux-gnu/bin/
> ld:
>>> warning: creating a DT_TEXTREL in object.
>> 
>> Internets say that this is because test.o is *not* position-independent.
>> Could this mean that -fPIC switch does not work?  Could it be the reason
>> linking fails?
>> 
>> Reproduced with both DMD 1.046 and 2.031.  GCC is 4.3.3 as you can see
>> from the warning.
> 
> I got it working:
> 0) setup
> $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/lib
> 
> 1) compile the library and move it in /opt/lib
> $ dmd -fPIC -c test.d
> $ gcc -shared -o libtest.so test.o
> $ dmd -c -H -o- test.d
> 
> 2) compile the program
> $ dmd prog.d test.di -L-L/opt/lib -L-ltest
> 
> The output of ldd is:
> $ ldd prog
> 	linux-gate.so.1 =>  (0xb8075000)
> 	libtest.so => /opt/lib/libtest.so (0xb8070000)
> 	libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb8053000)
> 	libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0xb802c000)
> 	libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7ec9000)
> 	/lib/ld-linux.so.2 (0xb8076000)
> 
> My problem was that I thought that DMD will read the .so and will obtain 
> required information from there, but it obviously needs the .di file.
> 
> You should try again - this above is the complete procedure.

My guess is that test.di is exactly the same as test.d because all the
functions are small.  Therefore compiling 'dmd prog.d test.di' resolves
all symbols statically and the .so is simply not linked.  Does your
'prog' have any unresolved symbols in its symbol table?


More information about the Digitalmars-d-learn mailing list