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
@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
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`.