Open motiejus opened 2 years ago
As a first-time contributor to zig, I want to try to do this. Where is the code for zig cc?
Edit: think I found it ;)
Hm, after building Zig from source, version 0.10.0-dev.2997+1653a9b25, I can no longer reproduce the issue.
My OS is Artix Linux and I have LLVM 14.0.6.
I notice the version you used expected LLVM 13, which I can't seem to easily get my system to use. Could it have been fixed by this update?
The resolution to this issue was reverted in 4f9345d20b3b95a1ccfe894bddd8ba5879c10c31.
note that the proper flag is not -dynamic
but -shared
.
It ignores -Wl,--dynamic-linker=x
as well
0.12.0-dev.1718+3acb0e30a
I've been trying to build a dynamic executable for Python interpreter, with zig cc / musl
, and can confirm that it is not working - the resulting binary is always statically linked, no matter extra -dynamic
flags or whatnot.
Unless I am doing something wrong, I would say this issue is a showstopper for zig cc
usage with any big and complex projects requiring a dynamic executable, where setting up own build.zig flow from scratch is prohibitively tedious.
After some poking around and testing, I've found a temporary mitigation option. It appears, that if you directly pass LDFLAGS="-dynamic-linker <path-to-interpreter>"
along with compiler invocation, zig will pick it up and command the linker to build a dynamic executable.
However, there is a caveat to keep in mind: a linker path/name you pass there is not honored, and it defaults to /lib/ld-musl-x86_64.so.1
in the final linker invocation no matter what, so if you have one in some other place - you would have to use patchelf --set-interpreter <whatever-pathname-you-have>
on the resulting executable to fix it.
Just noting for any future readers that this seems to only affect executables, not shared libraries:
❯ bat main.c
File: main.c
1 #include <stdio.h>
2
3 int main()
4 {
5 printf("hello world\n");
6 }
❯ zig cc main.c -target x86_64-linux-musl -o main
❯ readelf -d main
There is no dynamic section in this file.
❯ ldd main
not a dynamic executable
❯ file main
main: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, with debug_info, not stripped
❯ bat test.c
File: test.c
1 #include <stdio.h>
2
3 void hello_world()
4 {
5 printf("hello world\n");
6 }
❯ zig cc test.c -target aarch64-linux-musl -shared -fPIC -o libtest.so
❯ readelf -d libtest.so
Dynamic section at offset 0x3f0 contains 16 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libc.so]
0x000000000000001e (FLAGS) BIND_NOW
0x000000006ffffffb (FLAGS_1) Flags: NOW
0x0000000000000017 (JMPREL) 0x2f8
0x0000000000000002 (PLTRELSZ) 24 (bytes)
0x0000000000000003 (PLTGOT) 0x204f0
0x0000000000000014 (PLTREL) RELA
0x0000000000000006 (SYMTAB) 0x200
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000005 (STRTAB) 0x2d0
0x000000000000000a (STRSZ) 40 (bytes)
0x000000006ffffef5 (GNU_HASH) 0x278
0x0000000000000004 (HASH) 0x2a0
0x000000000000000c (INIT) 0x10398
0x000000000000000d (FINI) 0x103a8
0x0000000000000000 (NULL) 0x0
❯ musl-ldd libtest.so
musl-ldd (0x7c907ad8d000)
libc.so => musl-ldd (0x7c907ad8d000)
Error relocating libtest.so: unsupported relocation type 1026
❯ file libtest.so
libtest.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, with debug_info, not stripped
After some poking around and testing, I've found a temporary mitigation option. It appears, that if you directly pass
LDFLAGS="-dynamic-linker <path-to-interpreter>"
along with compiler invocation, zig will pick it up and command the linker to build a dynamic executable.However, there is a caveat to keep in mind: a linker path/name you pass there is not honored, and it defaults to
/lib/ld-musl-x86_64.so.1
in the final linker invocation no matter what, so if you have one in some other place - you would have to usepatchelf --set-interpreter <whatever-pathname-you-have>
on the resulting executable to fix it.
Do you have a more exact example of how you managed to do this? I've been trying various incantations for awhile, but no luck yet. I always end up with a static binary. I am working on a project that uses zig to build some C stuff and I need to dynamically link against musl, so would be useful.
Zig Version
0.10.0-dev.2473+e498fb155
Like the title says: zig cc frontend cannot compile a dynaimcally-linked musl binary. Created a separate issue as requested by @ifreund in https://github.com/ziglang/zig/issues/5364#issuecomment-1163025810
Full repro
main.c
Compiling:
Inspect the resulting
main
. It is static:Looking at the linker line above, you can see that
-static
is passed to the linker, and at least--dynamic-linker
option is missing.