Comment #0 by timothee.cour2 — 2016-01-09T04:26:29Z
I ran into this issue several times:
path/to/dmd some_d_flags some_linker_flags
Undefined symbols for architecture x86_64:
"_D6object9Throwable7messageMxFZAxa", referenced from [...]
which can be hard to debug why.
it works if I add:
path/to/dmd some_d_flags -L-Lfoo some_linker_flags
where foo=$dirname path/to/dmd
but this is harder to use and not DRY
The issue at hand is some_linker_flags (here containing -L-L/path/to/homebrew/lib/) may overwrite the library path for phobos libs, eg pointing to an older version of them compared to the one from path/to/dmd, and the flags from path/to/dmd.conf are not taken into account.
Things would work if linker flags in dmd.conf (or from $DMD_FLAGS) were prepended (instead of appended) to subsequent linker flags when dmd calls the system linker.
If i want to indeed overwrite the dmd.conf flags, I can always call:
DMD_FLAGS="" path/to/dmd some_d_flags some_linker_flags
so we're loosing nothing.
Comment #1 by mike — 2016-01-09T11:28:23Z
While pretending would solve the problems for the library paths, it will cause problems with the actual libraries. (at leased with GNU ld).
This because libraries are only searched once for undefined symbols and in the order in which they appear on the command line.
So if you are linking to a D library -lphobos should appear on the command line after the d library and libraries phobos depends on after that.
One option around this is to use --start-group and --end group. The OSX version of ld doesn't have these options, the OSX man page does say the placement of the -l flag is significant.
Comment #2 by bitworld — 2017-09-29T07:55:23Z
Running this command on Linux:
dmd -g -ofunittest/debug/thrift/server/transport/ssl -unittest -w -wi -I../../lib/d/src src/thrift/server/transport/ssl.d libthriftd-event.a libthriftd-ssl.a libthriftd.a -L-L/usr/bin/dmd -L-levent -L-lcrypto -L-lssl unittest/emptymain.d
Would get some error messages like:
libthriftd-ssl.a(ssl_2a8_3af.o): In function `_D6thrift9transport3ssl10TSSLSocket6isOpenMFNdZb':
src/thrift/transport/ssl.d:(.text._D6thrift9transport3ssl10TSSLSocket6isOpenMFNdZb+0x69): undefined reference to `SSL_get_shutdown'
The underlying command line is:
cc unittest/debug/thrift/server/transport/ssl.o -o unittest/debug/thrift/server/transport/ssl -g -m64 **-levent -lcrypto -lssl** -L/usr/lib/x86_64-linux-gnu -Xlinker --export-dynamic libthriftd-event.a libthriftd-ssl.a libthriftd.a -Xlinker -Bstatic -lphobos2 -Xlinker -Bdynamic -lpthread -lm -lrt -ldl
The correct command line should be:
cc unittest/debug/thrift/server/transport/ssl.o -o unittest/debug/thrift/server/transport/ssl -g -m64 -L/usr/lib/x86_64-linux-gnu -Xlinker --export-dynamic libthriftd-event.a libthriftd-ssl.a libthriftd.a **-levent -lcrypto -lssl** -Xlinker -Bstatic -lphobos2 -Xlinker -Bdynamic -lpthread -lm -lrt -ldl
The difference is that
-levent -lcrypto -lssl
is behind *.a.
The order of custom linker flags seem wrong.
Comment #3 by robert.schadek — 2024-12-13T18:46:25Z