digitalmars.D.learn - How to create a shared library with DMD on Linux?
- Bradley Smith (28/32) Jan 09 2007 I'm experimenting with using D for Java Native Interface (JNI)
- Heinz (6/6) Jan 09 2007 Hi,
- rochus (7/16) Jan 10 2007 Hi Heinz,
- Bradley Smith (5/25) Jan 10 2007 I was hoping that I was doing something wrong and it could be linked
- rochus (38/43) Jan 10 2007 Hi Bradly,
- Bradley Smith (18/73) Jan 10 2007 Yes, your example works, but when I start using the standard library
- rochus (6/6) Jan 12 2007 Hi Bradley and sorry for the late answer, I couldn't afford to post
- Bradley Smith (4/13) Jan 10 2007 I can confirm that GDC 0.21 can do it.
I'm experimenting with using D for Java Native Interface (JNI) programming. Although DMD 1.0 appears to support shared objects on Linux, I can't figure out how to create a shared library which can be used by a non-D program (in this case java). Is it possible to create a shared library with DMD which can be used by a C program? If I try to create the shared library with dmd, I get an error on the symbol _d_throw 4.dmd -fPIC nativetest.d jni.d jni_md.d -oflibnativetest.so -L-sharedgcc nativetest.o jni.o jni_md.o -o libnativetest.so -m32 -lphobos -lpthread -lm -Xlinker -shared -Xlinker -L/home/basmith/tools/dmd/dmd/lib /usr/bin/ld: libnativetest.so: undefined versioned symbol name _d_throw 4 /usr/bin/ld: failed to set dynamic section sizes: Bad value collect2: ld returned 1 exit status If I create shared objects with -fPIC and then create a shared library with gcc, the library is missing symbols from phobos.dmd -c -fPIC nativetest.d jni.d jni_md.d gcc nativetest.o jni.o jni_md.o -o libnativetest.so -shared java -Djava.library.path=. nativetestException in thread "main" java.lang.UnsatisfiedLinkError: /home/basmith/programming/d/djni/libnativetest.so: /home/basmith/programming/d/djni/libnativetest.so: undefined symbol: _Dmodule_ref at java.lang.ClassLoader$NativeLibrary.load(Native Method) at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1751) at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1676) at java.lang.Runtime.loadLibrary0(Runtime.java:822) at java.lang.System.loadLibrary(System.java:993) at nativetest.<clinit>(nativetest.java:4) The full code and a build.sh script are in the attached tar.gz file. Thanks, Bradley
Jan 09 2007
Hi, You can't create shared libraries for unix with DMD, it's written somewhere around the website (i remerber it says that Walter haven't figured about library structure or implementation or something under unix, it's on the todo list). BUT, i think GDC can do it: http://dgcc.sourceforge.net/ Good luck
Jan 09 2007
Heinz wrote:Hi, You can't create shared libraries for unix with DMD, it's written somewhere around the website (i remerber it says that Walter haven't figured about library structure or implementation or something under unix, it's on the todo list). BUT, i think GDC can do it: http://dgcc.sourceforge.net/ Good luckHi Heinz, It _is_ possible to write shared objects for unix using DMD. What does not work is linking against this shared object using another language than D. best regards, nicolai
Jan 10 2007
I was hoping that I was doing something wrong and it could be linked against a non-D language. Thanks, Bradley rochus wrote:Heinz wrote:Hi, You can't create shared libraries for unix with DMD, it's written somewhere around the website (i remerber it says that Walter haven't figured about library structure or implementation or something under unix, it's on the todo list). BUT, i think GDC can do it: http://dgcc.sourceforge.net/ Good luckHi Heinz, It _is_ possible to write shared objects for unix using DMD. What does not work is linking against this shared object using another language than D. best regards, nicolai
Jan 10 2007
Bradley Smith wrote:I was hoping that I was doing something wrong and it could be linked against a non-D language. Thanks, BradleyHi Bradly, Good news! The topic won't let me sleep and i figured out how to create a shared object that may be accessed from an application written in plain C, so i guess it might work for your JNI-problem, too. The "magic" thing to add is: Instead of simply "exporting" your functions in your library, place them within an "extern (C)"-Block: extern (C) { int myFunction(int i) { doSomething; return somethingElse; } } I attached my sample layout, a library that has one function called "squareIt" (guess what it does *g*). There are three directories: app_c, app_d and lib, each containing a Makefile. They should be self explaining as there's not much in them. Important though: i called dmd with the argument "-fPIC" when compiling the library, though I don't think that this switch is recognized - it's just there to remind myself that it's PIC we're gonna create. So here's what you should do: compile the library: #cd lib #make copy the library to a place, where ld might find it. for example /usr/lib or /usr/local/lib or temporarily alter the LD_LIBRARY_PATH var to /where/you/extracted/the/sample/lib/bin compile the sample applications: #cd app_d #make #cd app_c #make Run the applications. They worked for me. good luck, Nicolai
Jan 10 2007
Yes, your example works, but when I start using the standard library things don't work. Suppose I want to create a debugging version of a library with simple print statement. int squareIt(int i) { writefln("squareIt ", i); return i*i; } The app_d will now crash, and the app_c will not link because std.stdio.writefln is not defined. For app_c, if I add -lphobos -lm -lpthread, it still has unresolved references in deh2.o. I also tried to add phobos/internal/deh2.d to the libsquare.so, but that gives an unresolved symbol _d_throw 4. Any other ideas? Thanks, Bradley rochus wrote:Bradley Smith wrote:I was hoping that I was doing something wrong and it could be linked against a non-D language. Thanks, BradleyHi Bradly, Good news! The topic won't let me sleep and i figured out how to create a shared object that may be accessed from an application written in plain C, so i guess it might work for your JNI-problem, too. The "magic" thing to add is: Instead of simply "exporting" your functions in your library, place them within an "extern (C)"-Block: extern (C) { int myFunction(int i) { doSomething; return somethingElse; } } I attached my sample layout, a library that has one function called "squareIt" (guess what it does *g*). There are three directories: app_c, app_d and lib, each containing a Makefile. They should be self explaining as there's not much in them. Important though: i called dmd with the argument "-fPIC" when compiling the library, though I don't think that this switch is recognized - it's just there to remind myself that it's PIC we're gonna create. So here's what you should do: compile the library: #cd lib #make copy the library to a place, where ld might find it. for example /usr/lib or /usr/local/lib or temporarily alter the LD_LIBRARY_PATH var to /where/you/extracted/the/sample/lib/bin compile the sample applications: #cd app_d #make #cd app_c #make Run the applications. They worked for me. good luck, Nicolai
Jan 10 2007
Hi Bradley and sorry for the late answer, I couldn't afford to post earlier because the university required all my attention. I tried it with different ways, but it won't work. I guess the problem is that the phobos' functions don't expose themselves as extern(C) (the way I proposed doing it). Nicolai
Jan 12 2007
I can confirm that GDC 0.21 can do it. Thanks, Bradley Heinz wrote:Hi, You can't create shared libraries for unix with DMD, it's written somewhere around the website (i remerber it says that Walter haven't figured about library structure or implementation or something under unix, it's on the todo list). BUT, i think GDC can do it: http://dgcc.sourceforge.net/ Good luck
Jan 10 2007