Bug 19243 – [REG 2.081] Can no longer override pragma(lib) with -L switch
Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
Linux
Creation time
2018-09-13T07:04:23Z
Last change time
2018-10-06T16:22:04Z
Assigned to
No Owner
Creator
Vladimir Panteleev
Comments
Comment #0 by dlang-bugzilla — 2018-09-13T07:04:23Z
Consider a program written against the OpenSSL 1.0 API, e.g.:
////////////////////////////////// test.d //////////////////////////////////
pragma(lib, "ssl");
pragma(lib, "crypto");
extern (C)
{
struct SSL_METHOD;
struct SSL_CTX;
void SSL_load_error_strings();
void SSL_library_init();
void OPENSSL_add_all_algorithms_noconf();
alias OpenSSL_add_all_algorithms = OPENSSL_add_all_algorithms_noconf;
SSL_METHOD* SSLv23_client_method();
SSL_CTX* SSL_CTX_new(in SSL_METHOD*);
}
shared static this()
{
SSL_load_error_strings();
SSL_library_init();
OpenSSL_add_all_algorithms();
}
T sslEnforce(T)(T v, string message)
{
if (v) return v;
throw new Exception(message);
}
unittest
{
auto method = SSLv23_client_method().sslEnforce("SSLv23_client_method");
SSL_CTX_new(method)
.sslEnforce("SSL_CTX_new");
}
////////////////////////////////////////////////////////////////////////////
pragma(lib) allows it to be linked to the necessary libraries automatically, without having to specify them on the compiler/linker command line.
However, on some systems, the default libraries (i.e. e.g. /usr/lib/libssl.so) might be the wrong version. We can override them with -L switches, i.e.:
$ dmd -main -unittest -g -L/usr/lib/libssl.so.1.0.0 -L/usr/lib/libcrypto.so.1.0.0 -run test.d
This no longer works in 2.081. The change introduced by the PR linked below changes how linker arguments on the compiler's command line are processed, breaking existing build scripts.
The example above can be reproduced on Arch Linux with the openssl-1.0 package installed. The dmd command above succeeds with DMD 2.080 but fails with 2.081.
Introduced in https://github.com/dlang/dmd/pull/8172
Comment #1 by remi.thebault — 2018-09-13T19:30:23Z
Here is linker command line of your test with 2.080.1:
cc test.o -o /tmp/dmd_run0nNQYZ -g -m64 -Xlinker /usr/lib/libssl.so.1.0.0 -Xlinker /usr/lib/libcrypto.so.1.0.0 -L/home/remi/dev/dlang/dmd/generated/linux/release/64/../../../../../phobos/generated/linux/release/64 -Xlinker --export-dynamic -lssl -lcrypto -Xlinker -Bstatic -lphobos2 -Xlinker -Bdynamic -lpthread -lm -lrt -ldl
with 2.081.2:
cc test.o -o /tmp/dmd_runHMkjB3 -g -m64 -lssl -lcrypto -Xlinker /usr/lib/libssl.so.1.0.0 -Xlinker /usr/lib/libcrypto.so.1.0.0 -L/home/remi/dev/dlang/dmd/generated/linux/release/64/../../../../../phobos/generated/linux/release/64 -Xlinker --export-dynamic -Xlinker -Bstatic -lphobos2 -Xlinker -Bdynamic -lpthread -lm -lrt -ldl
(pragmas are pushed at the beginning)
On my system, neither will link succesfully without the additional .so on command line, but both will link succesfully with.
However I have a runtime exception with 2.081.2 that I don't have with 2.080.2.
My PR indeed seems to break this, but the PR wouldn't be needed if dmd didn't already shuffle arguments. What I did is shuffling them in a different way to solve another situation.
I guess what is needed is the following order:
- command line linker args in preserved order
- pragma libs
- standard library
Comment #2 by remi.thebault — 2018-09-14T06:20:12Z