Skip to content

Incorrect archiver Command Line Call When Linking a Static "System" Library to another Static Library #20476

Open
@haydenridd

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() and linkSystemLibrary/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"

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 into prebuilt_sys_lib folder
    • This is accomplished via addLibraryPath() and linkSystemLibrary2 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);
     }

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behaviorzig build systemstd.Build, the build runner, `zig build` subcommand, package management

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions