Bug 15574 – wrong order of linker arguments

Status
RESOLVED
Resolution
FIXED
Severity
blocker
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
Linux
Creation time
2016-01-17T15:49:14Z
Last change time
2018-09-17T11:20:39Z
Keywords
industry
Assigned to
No Owner
Creator
Martin Nowak
See also
https://issues.dlang.org/show_bug.cgi?id=12572, https://issues.dlang.org/show_bug.cgi?id=7044

Comments

Comment #0 by code — 2016-01-17T15:49:14Z
Refer to https://github.com/D-Programming-Language/dlang.org/pull/1195#issuecomment-172342018 for more details. Basically dmd puts libraries like -L-levent in front of any object files or static libraries, which always leads to link errors when used w/ --as-needed b/c the libraries aren't preceded by anything that requires them. Linking w/ --as-needed is the default on Ubuntu, so dmd is effectively unable to use external libraries on Ubuntu.
Comment #1 by code — 2016-01-17T18:23:35Z
We should pass any linker arguments in the same order as they were passed to dmd. This requires some refactoring of command line parsing and link part. For pragma(lib) we can only choose between prepending and appending them, both of which has issues. But appending seems like the better choice (so you can add library paths with -L-L) and pragma(lib) shouldn't be used anyhow.
Comment #2 by john.loughran.colvin — 2016-11-18T14:59:27Z
Just want to report that this bug is causing significant friction in a commercial project. It's really important that linker arguments are passed on in the order they were given.
Comment #3 by john.loughran.colvin — 2016-11-18T17:09:37Z
This problem isn't actually specific to --as-needed, because the following happens with or without it: Given myLib.a, putting -lmyLib before otherLibThatNeedsMyLib.a on the linker command line will (normally) fail to link, because - working from left to right on the command line - symbols from libraries passed by -l are not kept around unless something has already needed them.
Comment #4 by remi.thebault — 2018-04-15T13:04:07Z
Here is a simple test case to reproduce what is decribed by John: $ git clone https://github.com/rtbo/dmd_link_args_order $ cd dmd_link_args_order $ make app It builds a static lib with C code, a static lib with D code that calls a C function (bindings to the C code) and an D app that uses the D code. $ dmd -ofapp app.d libdsquare.a -L-L. -L-lcsquare issues the following linker command: $ cc app.o -o app -m64 -L. -lcsquare -L/usr/lib -Xlinker --export-dynamic libdsquare.a -Xlinker -Bstatic -lphobos2 -Xlinker -Bdynamic -lpthread -lm -lrt -ldl Note that libdsquare.a is after -lcsquare and causes a link error. An intermediate fix would be to place the *.a files before the linker switches given on the command line. I argue that *.a have much more chances to depend on -l libraries than the opposite. This is what LDC is doing.
Comment #5 by github-bugzilla — 2018-04-17T19:07:56Z
Commits pushed to master at https://github.com/dlang/dmd https://github.com/dlang/dmd/commit/fbaeeaee1cac009d9f7157b7d63ea22dee1d3b0e Fix issue 15574 - wrong order of link arguments This essentially places *.a arguments before the -l and -L switches in the linker command line. This allows to link applications that link against a static archive *.a that depends on -l lib switches. Such dependency scheme is typical of the following situation: - have a D package that contains binding to a C library. - this D package is itself built as a static library (libdpackage.a). - the C library is built in the same build process as a static library (pathtoClib/libclib.a) - dmd is invoked in the following way: $ dmd ... libdpackage.a -L-LpathtoClib -L-lclib Currently dmd reorders arguments and places *.a after -l linker switches which causes link errors if the -l points to a static library. This is especially useful with Dub, which can be configured to probe for the C library, and build it as a static lib if not found system-wide. In both cases, the C library is provided with "libs" json entry. So this is not about keeping relative order of linker arguments, it is about providing an order of linker arguments that is more sound than the current one. https://github.com/dlang/dmd/commit/10c8fa536879536b4fa339d8325b7a3ab0990d51 add test for issue 15574 https://github.com/dlang/dmd/commit/6371942b1bf26dc6c65cc7e0668bc82e1974c18d Merge pull request #8172 from rtbo/linker_arg_order Fix issue 15574 - wrong order of link arguments merged-on-behalf-of: Razvan Nitu <[email protected]>
Comment #6 by github-bugzilla — 2018-09-17T11:20:39Z
Commits pushed to master at https://github.com/dlang/dmd https://github.com/dlang/dmd/commit/84b64ff24bd46513aa4622c98a6373002a9e8877 Have issue15574.sh use $(CC) instead of hard coded 'cc'. This fails GNU Guix builds and is in line with other test scripts. Includes a fix for compilation issue with C++ compilers by adding extern "C" definition. https://github.com/dlang/dmd/commit/57944f595e7684ffeffdf615546302b8ddfa530a Merge pull request #8702 from pjotrp/master Have issue15574.sh use $(CC) instead of hard coded 'cc'. merged-on-behalf-of: Petar Kirov <[email protected]>