Thread overview | ||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
April 08, 2012 Shared library in D on Linux | ||||
---|---|---|---|---|
| ||||
I am still testing which setup gives me reliable shared D libraries which can be used from C. Here is my latest test: * test.d: import std.stdio; extern (C) { void hiD() { writeln("hi from D lib"); } } * main.c #include <stdio.h> #include <dlfcn.h> #include <stdlib.h> void main() { void (*hiD)(void); void* handle = dlopen("./libtest.so", RTLD_LAZY); if (handle == NULL) { printf("%s\n", dlerror()); exit(1); } hiD = dlsym(handle, "hiD"); if (hiD != NULL) { hiD(); } else { printf("hiD is null\n"); } dlclose(handle); } * Makefile #!/bin/bash test: #gdc-4.6 -g -c test.d -fPIC -o test.o #gdc-4.6 -shared -o libtest.so -fPIC test.o -lc -nostartfiles dmd -g -c test.d -fPIC ld -shared -o libtest.so test.o -lrt -lphobos2 -lpthread gcc -g main.c -ldl -lpthread ./a.out clean: rm -rf *.so *.o *.out With this setup I get ./libtest.so: undefined symbol: _deh_beg With a fake main method added I get make: *** [test] Segmentation fault This is what I get from gdb Program received signal SIGSEGV, Segmentation fault. 0xb7fd1ed3 in std.stdio.__T7writelnTAyaZ.writeln() (_param_0=...) at /usr/include/d/dmd/phobos/std/stdio.d:1550 1550 enforce(fprintf(.stdout.p.handle, "%.*s\n", Event with the following startup hooks extern(C) { void gc_init(); void gc_term(); void _init() { gc_init(); } void _fini() { gc_term(); } } I get the same error. I am using dmd 2.058 on Ubuntu 11.10 (32 bit) With gdc I get different errors, but it seems even more difficult to get it working. Does anyone know what is missing to get proper shared library support working on Linux? |
April 08, 2012 Re: Shared library in D on Linux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timo Westkämper | On 2012-04-08 10:45, "Timo Westkämper" <timo.westkamper@gmail.com>" wrote: > I am still testing which setup gives me reliable shared D libraries > which can be used from C. > > Here is my latest test: > > * test.d: > import std.stdio; > extern (C) { > void hiD() { > writeln("hi from D lib"); > } > } > > * main.c > #include <stdio.h> > #include <dlfcn.h> > #include <stdlib.h> > void main() { > void (*hiD)(void); > void* handle = dlopen("./libtest.so", RTLD_LAZY); > if (handle == NULL) { > printf("%s\n", dlerror()); > exit(1); > } > hiD = dlsym(handle, "hiD"); > if (hiD != NULL) { > hiD(); > } else { > printf("hiD is null\n"); > } > dlclose(handle); > } > > * Makefile > #!/bin/bash > test: > #gdc-4.6 -g -c test.d -fPIC -o test.o > #gdc-4.6 -shared -o libtest.so -fPIC test.o -lc -nostartfiles > dmd -g -c test.d -fPIC > ld -shared -o libtest.so test.o -lrt -lphobos2 -lpthread > gcc -g main.c -ldl -lpthread > ./a.out > clean: > rm -rf *.so *.o *.out > > With this setup I get > > ./libtest.so: undefined symbol: _deh_beg > > With a fake main method added I get > > make: *** [test] Segmentation fault > > This is what I get from gdb > > Program received signal SIGSEGV, Segmentation fault. > 0xb7fd1ed3 in std.stdio.__T7writelnTAyaZ.writeln() (_param_0=...) at > /usr/include/d/dmd/phobos/std/stdio.d:1550 > 1550 enforce(fprintf(.stdout.p.handle, "%.*s\n", > > Event with the following startup hooks > > extern(C) { > > void gc_init(); > void gc_term(); > > void _init() { > gc_init(); > } > > void _fini() { > gc_term(); > } > > } > > I get the same error. I am using dmd 2.058 on Ubuntu 11.10 (32 bit) > > With gdc I get different errors, but it seems even more difficult to get > it working. > > Does anyone know what is missing to get proper shared library support > working on Linux? This is what I can think of for now: * Proper initialization of TLS data * Setting up exception handling tables * Setting up module info -- /Jacob Carlborg |
April 08, 2012 Re: Shared library in D on Linux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timo Westkämper | On 04/08/2012 03:45 AM, "Timo Westkämper" <timo.westkamper@gmail.com>" wrote:
>
> extern(C) {
>
> void gc_init();
> void gc_term();
>
> void _init() {
> gc_init();
> }
>
> void _fini() {
> gc_term();
> }
>
> }
I think you want rt_init and rt_term here.
|
April 08, 2012 Re: Shared library in D on Linux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | I'm interessting in the same stuff. I've a question to _tlsend and _tlsstart. What are they used for? My disputable presumption was that they point to the begin of TLS segment. What is _deh_begin and _deh_end used for? |
April 08, 2012 Re: Shared library in D on Linux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ellery Newcomer | On Sunday, 8 April 2012 at 14:52:55 UTC, Ellery Newcomer wrote:
> On 04/08/2012 03:45 AM, "Timo Westkämper" <timo.westkamper@gmail.com>" wrote:
>>
>> extern(C) {
>>
>> void gc_init();
>> void gc_term();
>>
>> void _init() {
>> gc_init();
>> }
>>
>> void _fini() {
>> gc_term();
>> }
>>
>> }
>
> I think you want rt_init and rt_term here.
I got now the simple example working:
* Makefile:
#!/bin/bash
test:
dmd -lib -g -c test.d -fPIC
ld -shared -o libtest.so test.a -lrt -lphobos2 -lpthread
gcc -g main.c -ldl -lpthread
./a.out
clean:
rm -rf *.a *.so *.o *.out
* test.d:
import std.stdio;
extern (C) void hiD() {
writeln("hi from D lib");
}
Compiling as lib did the track and added the missing parts.
I will now advance with more complex examples.
|
April 08, 2012 Re: Shared library in D on Linux | ||||
---|---|---|---|---|
| ||||
Posted in reply to mta`chrono | On 2012-04-08 17:53, mta`chrono wrote: > I'm interessting in the same stuff. I've a question to _tlsend and > _tlsstart. What are they used for? My disputable presumption was that > they point to the begin of TLS segment. Yes, exactly, the start and end of the TLS segment. > What is _deh_begin and _deh_end used for? That would be start and end of the segment containing the exception handling tables. -- /Jacob Carlborg |
April 08, 2012 Re: Shared library in D on Linux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timo Westkämper | Does someone know why the lib (.a) packaging instead of objects (.o) works better in this case? |
April 09, 2012 Re: Shared library in D on Linux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timo Westkämper | On Sunday, 8 April 2012 at 17:59:28 UTC, Timo Westkämper wrote:
> Does someone know why the lib (.a) packaging instead of objects (.o) works better in this case?
Didn't work after all with -lib. I mixed up outputs.
|
April 09, 2012 Re: Shared library in D on Linux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timo Westkämper | Well, if you're really hankering for a shared lib, try ldc. I have gotten it to compile working shared libs in the past.
On 04/09/2012 01:24 AM, "Timo Westkämper" <timo.westkamper@gmail.com>" wrote:
> On Sunday, 8 April 2012 at 17:59:28 UTC, Timo Westkämper wrote:
>> Does someone know why the lib (.a) packaging instead of objects (.o)
>> works better in this case?
>
> Didn't work after all with -lib. I mixed up outputs.
|
April 09, 2012 Re: Shared library in D on Linux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ellery Newcomer | On Monday, 9 April 2012 at 15:14:45 UTC, Ellery Newcomer wrote: > Well, if you're really hankering for a shared lib, try ldc. I have gotten it to compile working shared libs in the past. > > On 04/09/2012 01:24 AM, "Timo Westkämper" <timo.westkamper@gmail.com>" wrote: >> On Sunday, 8 April 2012 at 17:59:28 UTC, Timo Westkämper wrote: >>> Does someone know why the lib (.a) packaging instead of objects (.o) >>> works better in this case? >> >> Didn't work after all with -lib. I mixed up outputs. Thanks, I might switch to ldc, if dmd and gdc fail here. I found this tls.S script in the druntime sources (src/rt/tls.S). Do you think it could be included in the library to make tls initialization work? #if linux /* The memory between the addresses of _tlsstart and _tlsend is the storage for * thread-local data in D 2.0. Both of these rely on the default linker script * of: * .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } * .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } * to group the sections in that order. * * Sadly, this does not work because ld orders .tdata after .tdata.*, despite * what the linker script says. */ .file "tls.S" .globl _tlsstart .section .tdata,"awT",@progbits .align 4 .type _tlsstart, @object .size _tlsstart, 4 _tlsstart: .long 3 .globl _tlsend .section .tcommon,"awT",@nobits .align 4 .type _tlsend, @object .size _tlsend, 4 _tlsend: .zero 4 #endif I will see if I can copy the exception handling parts from the D main wrapping code. As a temporary solution I did this extern(C) void _deh_beg() { } extern(C) void _deh_end() { } |
Copyright © 1999-2021 by the D Language Foundation