Thread overview
How to create a shared library with DMD on Linux?
Jan 09, 2007
Bradley Smith
Jan 10, 2007
Heinz
Jan 10, 2007
rochus
Jan 10, 2007
Bradley Smith
Jan 10, 2007
rochus
Jan 10, 2007
Bradley Smith
Jan 12, 2007
rochus
Jan 10, 2007
Bradley Smith
January 09, 2007
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
Exception 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



January 10, 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
January 10, 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
January 10, 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
January 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
January 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,
>   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


January 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
January 12, 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