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.