Bug 6952 – Static Linking on Linux

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
Other
OS
Linux
Creation time
2011-11-15T09:08:02Z
Last change time
2022-05-19T07:25:56Z
Keywords
bootcamp
Assigned to
No Owner
Creator
David Simcha
Depends on
20244

Comments

Comment #0 by dsimcha — 2011-11-15T09:08:02Z
It seems that the stuff that DMD outputs to GCC on Linux is misconfigured for static linking. I've observed this on several machines with various Linux distros, all of which can statically link a C hello world program successfully with the machine's GCC install. hello.d: import std.stdio; void main() { write("Hello, world\n"); } $ dmd -L-static hello.d /usr/bin/ld: cannot find -lgcc_s collect2: ld returned 1 exit status --- errorlevel 1 Yet somehow when I compile/link a C hello world on the same machine it Just Works: hello.c: #include <stdio.h> int main() { printf("Hello, world.\n"); return 0; } $ gcc -o hello -static hello.c $ ./hello Hello, world. $ file hello hello: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.15, not stripped
Comment #1 by schveiguy — 2011-11-15T09:40:22Z
The issue is that -Lxxx passes the parameter like this: -Xlinker xxx Which means to gcc "pass this argument to the linker" Whereas your gcc compile line is passing -static to the compiler. doing this: gcc -Xlinker -static -o hello hello.c should result in the same failure (not tested). It's not that dmd outputs misconfigured code, it's just that the link line is not geared towards static linking. I'm not sure you want to do static linking anyways. It's not supported by GCC IIRC. You can fix this by doing dmd -v, then running the link line, removing the -Xlinker arg in front of -static.
Comment #2 by issues.dlang — 2011-11-15T11:17:07Z
See Bug# 4376.
Comment #3 by schveiguy — 2011-11-16T05:26:34Z
*** Issue 4376 has been marked as a duplicate of this issue. ***
Comment #4 by slavo5150 — 2014-11-12T11:23:47Z
This also affects options like -nodefaultlibs and -nostdlib
Comment #5 by slavo5150 — 2014-11-15T02:47:54Z
Comment #6 by dlang-bot — 2019-08-24T01:58:47Z
@JinShil updated dlang/dmd pull request #10341 "Refactor link.d in preparation for fix to issue 6952" mentioning this issue: - Refactor link.d in preparation for fix to issue 6952 https://github.com/dlang/dmd/pull/10341
Comment #7 by dlang-bot — 2019-08-24T05:32:24Z
dlang/dmd pull request #10341 "Refactor link.d in preparation for fix to issue 6952" was merged into master: - 08a793e7924933f6d37a7a54f89ab87d7821a970 by JinShil: Refactor link.d in preparation for fix to issue 6952 https://github.com/dlang/dmd/pull/10341
Comment #8 by dlang-bot — 2019-08-24T07:51:51Z
@JinShil created dlang/dmd pull request #10342 "Refactor link.d in preparation for fix to issue 6952 (Part 2)" mentioning this issue: - Refactor link.d in preparation for fix to issue 6952 (Part 2) https://github.com/dlang/dmd/pull/10342
Comment #9 by dlang-bot — 2019-08-24T12:21:22Z
dlang/dmd pull request #10342 "Refactor link.d in preparation for fix to issue 6952 (Part 2)" was merged into master: - 21e7a3518e2a5af71b3bee72dfdb3529271a9dee by JinShil: Refactor link.d in preparation for fix to issue 6952 (Part 2) https://github.com/dlang/dmd/pull/10342
Comment #10 by pro.mathias.lang — 2019-09-15T16:47:10Z
Fixed by https://github.com/dlang/dmd/pull/10339 but the commit title wasn't properly worded.
Comment #11 by Alan.W.Irwin1234 — 2019-09-26T03:34:33Z
It turns out the new feature in <https://github.com/dlang/dmd/pull/10339> does not pass simple build tests of a "hello, world" example, see <https://issues.dlang.org/show_bug.cgi?id=20244>.
Comment #12 by slavo5150 — 2019-09-26T04:26:56Z
That behavior is expected. I've clarified in Issue 20244
Comment #13 by jens.k.mueller — 2020-01-10T23:09:39Z
I tried building a statically executable on Linux recently. When reading this issue it sounds as if the problem was solved. But I cannot make David's example work. $ cat hello.d void main() { import std.stdio; writeln("Hello, World!"); } $ dmd --version DMD64 D Compiler v2.089.1 Note that the introduced -preview=noXlinker was replaced by -Xcc (see https://github.com/dlang/dmd/commit/f0bd9351a704edf8531838b2a49041ac9244668a#diff-6b306396aa9fdbc560492611d41dd56f and https://github.com/dlang/dmd/commit/c45c17327868cc376fe8fad9f48bdd28d687b45f#diff-6b306396aa9fdbc560492611d41dd56f). But $ dmd -Xcc=-static hello.d doesn't create a statically linked executable. $ ldd hello linux-vdso.so.1 (0x00007fff9cd94000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fdce0d5f000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fdce0bdc000) librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fdce0bd2000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fdce0bcd000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fdce0a0c000) /lib/ld64.so.1 => /lib64/ld-linux-x86-64.so.2 (0x00007fdce0d87000) which you can verify when adding -v which reports cc hello.o -o hello -m64 -static -Xlinker --export-dynamic -L/home/jkm/dlang/dmd-2.089.1/linux/bin64/../lib64 -Xlinker -Bstatic -lphobos2 -Xlinker -Bdynamic -lpthread -lm -lrt -ldl At the end of the line you can see that there are still dynamically linked libraries. It is true that linking doesn't fail but still the compiler doesn't generate what it was asked for. That's why I think this issue it not solved. But maybe I'm doing it wrong. If so let me know how to create a statically linked executable using dmd. As a workaround for now I would even consider using the C compiler okay. But I couldn't even make this work. By the way with ldc it works (tested with version 1.19.0). $ ldc2 -static hello.d $ ldd hello not a dynamic executable $ ./hello Hello, World!
Comment #14 by ttanjo — 2022-05-19T07:25:56Z
I have the same issue on Alpine Linux (dmd installed via apk, and dmd 7f88bab). `dmd -v` shows the following link command: ``` cc sample.o -o sample -m64 -Xlinker --export-dynamic -L./generated/linux/release/64/../../../../../phobos/generated/linux/release/64 -Xlinker -Bstatic -lphobos2 -Xlinker -Bdynamic -lpthread -lm -lrt -ldl ``` To make a static binary, we have to: - add `-static` option, and - remove `-Xlinker -Bdynamic` from the command line or add extra `-Xlinker -Bstatic` to cancel dynamic link options. dmd provides ways to solve the former case: `-Xcc` and `-L`. On the other hand, there are no ways to solve the latter case. It makes harder to build a static binary with dub. It would be nice if dmd provides a way to solve the latter case to cancel `-Xlinker -Bdynamic`.