Description
Zig Version
0.13.0
Steps to Reproduce and Observed Behavior
High Level Summary
Zig appears to be erroneously passing .a
files directly to ar
when the following scenario takes place:
- You are building a static library
- You establish a dependency on a system library through
addLibraryPath()
andlinkSystemLibrary
/linkSystemLibrary2
This is possibly the root cause of this issue:
#13177
Detailed Info
Observe the example repo here:
https://github.com/haydenridd/zig-static-system-library-bug
In this example we have the following:
- An executable that depends on:
- A static library "static_library", which depends on:
- Another static library "sys_lib"
- A static library "static_library", which depends on:
In build.zig
there is a boolean system_library_method
that controls two different types of building this executable that should be equivalent.
When false
:
- Builds the project by:
- Building "sys_lib" from source
- Building "static_library" from source, "linking" against "sys_lib" (which really just adds this as a link dependency, there isn't really such a thing as "linking" one static library into another)
- Building the executable which links against "static_library"
This behaves as expected, the build calls (common flags truncated for readability) look like:
zig clang /home/hayden/Documents/zig/system_includes_bug/sys_lib/src/sys_lib.c --no-default-config -fno-caret-diagnostics -target x86_64-unknown-linux-gnu -nostdinc -fno-spell-checking -isystem /home/hayden/.zvm/0.12.1/lib/include [-Xclang flags] [-f flags] -MD -MV -MF /home/hayden/Documents/zig/system_includes_bug/zig-cache/tmp/4e6ca6b8d2ff8d89-sys_lib.o.d -I /home/hayden/Documents/zig/system_includes_bug/sys_lib/src -c -o /home/hayden/Documents/zig/system_includes_bug/zig-cache/tmp/4e6ca6b8d2ff8d89-sys_lib.o --serialize-diagnostics /home/hayden/Documents/zig/system_includes_bug/zig-cache/tmp/4e6ca6b8d2ff8d89-sys_lib.o.diag
ar rcs /home/hayden/Documents/zig/system_includes_bug/zig-cache/o/790e50c2293689a2ff7f00f8f1fc00eb/libsys_lib.a /home/hayden/Documents/zig/system_includes_bug/zig-cache/o/3d3238ce221f946fb403332c4d443666/sys_lib.o
zig clang /home/hayden/Documents/zig/system_includes_bug/static_library/staticlib.c --no-default-config -fno-caret-diagnostics -target x86_64-unknown-linux-gnu -nostdinc -fno-spell-checking -isystem /home/hayden/.zvm/0.12.1/lib/include [-Xclang flags] [-f flags] -MD -MV -MF /home/hayden/Documents/zig/system_includes_bug/zig-cache/tmp/f112571b40b7097b-staticlib.o.d -I /home/hayden/Documents/zig/system_includes_bug/static_library -I /home/hayden/Documents/zig/system_includes_bug/zig-cache/o/baf03d5407472fb279c770a3919a020f -c -o /home/hayden/Documents/zig/system_includes_bug/zig-cache/tmp/f112571b40b7097b-staticlib.o --serialize-diagnostics /home/hayden/Documents/zig/system_includes_bug/zig-cache/tmp/f112571b40b7097b-staticlib.o.diag
ar rcs /home/hayden/Documents/zig/system_includes_bug/zig-cache/o/9306f2bf20f5853898d11b321e6f8fdb/libstaticlib.a /home/hayden/Documents/zig/system_includes_bug/zig-cache/o/b90eb644cbc286ea7edb3286aca2779a/staticlib.o
zig clang /home/hayden/Documents/zig/system_includes_bug/src/main.c --no-default-config -fno-caret-diagnostics -D__GLIBC_MINOR__=36 -target x86_64-unknown-linux-gnu -nostdinc -fno-spell-checking -isystem /home/hayden/.zvm/0.12.1/lib/include -isystem /usr/include [-Xclang flags] [-f flags] --param ssp-buffer-size=4 -D_DEBUG -O0 -fPIC -funwind-tables -gdwarf-4 -gdwarf32 -MD -MV -MF /home/hayden/Documents/zig/system_includes_bug/zig-cache/tmp/e451cba3f03d6294-main.o.d -I /home/hayden/Documents/zig/system_includes_bug/zig-cache/o/dda94905e809a5afabb5af92f37340c0 -c -o /home/hayden/Documents/zig/system_includes_bug/zig-cache/tmp/e451cba3f03d6294-main.o --serialize-diagnostics /home/hayden/Documents/zig/system_includes_bug/zig-cache/tmp/e451cba3f03d6294-main.o.diag
ld.lld --error-limit=0 --entry _start -z stack-size=16777216 --image-base=16777216 --eh-frame-hdr -znow -m elf_x86_64 -o /home/hayden/Documents/zig/system_includes_bug/zig-cache/o/fbfea196a3fefe3353258a5b17fcb0b6/main /usr/lib/gcc/x86_64-redhat-linux/12/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-redhat-linux/12/../../../../lib64/crti.o -L /usr/lib/gcc/x86_64-redhat-linux/12/../../../../lib64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /home/hayden/Documents/zig/system_includes_bug/zig-cache/o/9306f2bf20f5853898d11b321e6f8fdb/libstaticlib.a /home/hayden/Documents/zig/system_includes_bug/zig-cache/o/790e50c2293689a2ff7f00f8f1fc00eb/libsys_lib.a /home/hayden/Documents/zig/system_includes_bug/zig-cache/o/f545c2ea819fb388113868404264f77e/main.o --as-needed -lm -lpthread -lc -ldl -lrt -lutil /home/hayden/.cache/zig/o/f721cc9442cf1a25959b93955c415395/libcompiler_rt.a /usr/lib/gcc/x86_64-redhat-linux/12/../../../../lib64/crtn.o
There's a lot here, but the important part to pay attention to is the ar
call that archives "static_lib" into a library:
ar rcs /home/hayden/Documents/zig/system_includes_bug/zig-cache/o/9306f2bf20f5853898d11b321e6f8fdb/libstaticlib.a /home/hayden/Documents/zig/system_includes_bug/zig-cache/o/b90eb644cbc286ea7edb3286aca2779a/staticlib.o
Now compare this to the behavior when system_library_method = true
:
- Builds the project by:
- Building "static_library" from source, and again "linking" against "sys_lib", except this time against a prebuilt
libsys_lib.a
copied from the previous output intoprebuilt_sys_lib
folder - This is accomplished via
addLibraryPath()
andlinkSystemLibrary2
calls respectively - Building the executable which links against "static_library" in the same way, with the caveat that we now need to manually add the system library paths via:
for (static_lib.root_module.lib_paths.items) |path| { exe.addLibraryPath(path); }
- Building "static_library" from source, and again "linking" against "sys_lib", except this time against a prebuilt
This produces the following warning from ld.lld
:
error: warning(link): unexpected LLD stderr:
ld.lld: warning: /home/hayden/Documents/zig/archiver_bug/.zig-cache/o/d14eb5f67992e73d6aef84dd739d4e63/libstaticlib.a: archive member '/home/hayden/Documents/zig/archiver_bug/prebuilt_sys_lib/lib/libsys_lib.a' is neither ET_REL nor LLVM bitcode
Examining the build calls, the culprit is this:
ar rcs /home/hayden/Documents/zig/system_includes_bug/zig-cache/o/34c04c0538e9a2ae1889b1bbdfe20397/libstaticlib.a /home/hayden/Documents/zig/system_includes_bug/sys_lib_folder/lib/libsys_lib.a /home/hayden/Documents/zig/system_includes_bug/zig-cache/o/29b356271420edfbf68e3497ca117069/staticlib.o
Zig is passing libsys_lib.a
to the archiver, which LLVM is rightfully complaining about, as that isn't valid. However, the program still works because Zig also correctly passes the link dependency libsys_lib.a
to the executable:
ld.lld --error-limit=0 --entry _start -z stack-size=16777216 --image-base=16777216 --eh-frame-hdr -znow -m elf_x86_64 -o /home/hayden/Documents/zig/system_includes_bug/zig-cache/o/46fb86a5c2db675a704552cca0155a25/main /usr/lib/gcc/x86_64-redhat-linux/12/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-redhat-linux/12/../../../../lib64/crti.o -rpath /home/hayden/Documents/zig/system_includes_bug/sys_lib_folder/lib -L /home/hayden/Documents/zig/system_includes_bug/sys_lib_folder/lib -L /usr/local/lib64 -L /usr/local/lib -L /usr/lib/x86_64-linux-gnu -L /lib64 -L /lib -L /usr/lib64 -L /usr/lib -L /lib/x86_64-linux-gnu -L /usr/lib/gcc/x86_64-redhat-linux/12/../../../../lib64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /home/hayden/Documents/zig/system_includes_bug/zig-cache/o/34c04c0538e9a2ae1889b1bbdfe20397/libstaticlib.a /home/hayden/Documents/zig/system_includes_bug/sys_lib_folder/lib/libsys_lib.a /home/hayden/Documents/zig/system_includes_bug/zig-cache/o/a55704026b7918d88b03d934b7f436b6/main.o --as-needed -lm -lpthread -lc -ldl -lrt -lutil /home/hayden/.cache/zig/o/f721cc9442cf1a25959b93955c415395/libcompiler_rt.a /usr/lib/gcc/x86_64-redhat-linux/12/../../../../lib64/crtn.o
Expected Behavior
- Zig should not be passing
.a
files directly to the archiver (ar
) - The warning described above ("BLANK.a is neither ET_REL nor LLVM bitcode" should not occur as AFAIK what I present in my example is a valid way to add a dependency on a system library to a static library
Activity