digitalmars.D.learn - How to create a shared library with DMD on Linux?
- Bradley Smith <digitalmars-com baysmith.com> Jan 09 2007
- Heinz <billgates microsoft.com> Jan 09 2007
- rochus <rochus rochus.net> Jan 10 2007
- Bradley Smith <digitalmars-com baysmith.com> Jan 10 2007
- rochus <rochus rochus.net> Jan 10 2007
- Bradley Smith <digitalmars-com baysmith.com> Jan 10 2007
- rochus <rochus rochus.net> Jan 12 2007
- Bradley Smith <digitalmars-com baysmith.com> Jan 10 2007
Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit 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-shared
gcc 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=. nativetest
/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 luck
Hi 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 luck
Hi 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
Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Bradley Smith wrote:I was hoping that I was doing something wrong and it could be linked against a non-D language. Thanks, Bradley
Hi 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,
Bradley
Hi 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









rochus <rochus rochus.net> 