Simon Kérouack
Simon Kérouack

Reputation: 394

How to compile/link static library with DMD

Whenever I build a static library using DMD, I'm able to link it to my application and it compiles fine but anytime in the application the library is called I get:

Segmentation fault (core dumped)

For building the library I do

# $(FILE) for each file in "find source -name "*.d"
# $(OBJ) is $(FILE) with the extension ".o"
# $(IMP) is $(FILE) with the extension ".di"
dmd -O -d -m64 -L-ldl -m64 -Isource -c $(FILE) -ofbuild/$(OBJ)

ar rcs ./lib/libvibe.d-dmd.a build/*
ranlib ./lib/libvibe.d-dmd.a

dmd -O -d -m64 -L-ldl -m64 -Isource -c -o- $(FILE) -Hfimport/$(IMP)

and for building the application

SRC = $(shell find src -name "*.d")
dmd -debug -odbuild -I../../vibe.d/source -L-L../../vibe.d/lib -L-lvibe.d-dmd $(SRC) -ofbin/test

What am I doing wrong?


Update

Compiling vibe.d as libvibe.d-dmd.a

dmd -g -lib -oflib/libvibe.d-dmd.a $(SOURCES) -L-levent_pthreads -L-levent -L-lssl -L-lcrypto

Example code:

import vibe.core.file;
void main()
{
  openFile("test.d", FileMode.Read);
}

Compiling the example

dmd -g test.d vibe.d/lib/libvibe.d-dmd.a -Ivibe.d/source

And some gdb output:

Program received signal SIGSEGV, Segmentation fault.
0x00000000004554f5 in vibe.core.file.openFile() (mode=<incomplete type>, path=...) at source/vibe/core/file.d:29
29      return getEventDriver().openFile(path, mode);
(gdb) backtrace
#0  0x00000000004554f5 in vibe.core.file.openFile() (mode=<incomplete type>, path=...) at source/vibe/core/file.d:29
#1  0x000000000044f7d2 in vibe.core.file.openFile() (mode=<incomplete type>, path=...) at source/vibe/inet/path.d:24
#2  0x000000000044f539 in D main () at test.d:5
#3  0x000000000046b9e4 in rt.dmain2.main() ()
#4  0x000000000046b35e in rt.dmain2.main() ()
#5  0x000000000046ba2b in rt.dmain2.main() ()
#6  0x000000000046b35e in rt.dmain2.main() ()
#7  0x000000000046b2e9 in main ()
(gdb) fram 2
#2  0x000000000044f539 in D main () at test.d:5
5     openFile("test.d", FileMode.Read);
(gdb) frame 1
#1  0x000000000044f7d2 in vibe.core.file.openFile() (mode=<incomplete type>, path=...) at source/vibe/inet/path.d:24
24  struct Path {
(gdb) print mode
$1 = <incomplete type>

Upvotes: 3

Views: 2542

Answers (1)

DejanLekic
DejanLekic

Reputation: 19822

Why don't you use the dmd -lib -oflibmylib.a file1.d ...?

The best thing you can do is to run GDB, and see why your application segfaults. If you see that the reason for segfault is dereferencing a function pointer from your library then it is most likely you are right and something went wrong with linking.

If you are not familiar with GDB, here is an easy article how to do it: http://www.unknownroad.com/rtfm/gdbtut/gdbsegfault.html .

There is also a nice article on Wiki4D about this topic.

Here is a whole session how to compile a library libdstlib.a out of two files dstlib/foo.d and dstdlib/bar.d:

dejan@homeserver:~/work/dstlib> ls -R
.:
driver.d  dstlib

./dstlib:
bar.d  foo.d
dejan@homeserver:~/work/dstlib> dmd -lib -oflibdstlib.a dstlib/*.d
dejan@homeserver:~/work/dstlib> dmd driver.d libdstlib.a
dejan@homeserver:~/work/dstlib> ./driver
w: 80, h: 40
dejan@homeserver:~/work/dstlib> cat driver.d dstlib/foo.d dstlib/bar.d
module driver;
import std.stdio;
import dstlib.bar;

void main()
{
    auto rect = getRectangle();
    rect.display();
}    
module dstlib.foo;
import std.stdio : writefln;
struct Rectangle
{
    int width, height;
    void display()
    {
        writefln("w: %s, h: %s", width, height);
    }
}    
module dstlib.bar;
import dstlib.foo;

Rectangle getRectangle()
{
    return Rectangle(80, 40);
}

Upvotes: 2

Related Questions