Skip to content

Conversation

JacobCrabill
Copy link

@JacobCrabill JacobCrabill commented Sep 28, 2025

I think this should solve this issue: #19341

Thanks to @andrewrk for pointing me to the relevant portion of Compile.zig to find the cause (and for pointing out the resultant issue in the archive file).

Reproducing the issue

  • Define a dynamic library, dynamic-lib, from dynamic.c exporting a function void foo()
  • Define a static library, static-lib, from static.c exporting a function void bar() { foo(); }
  • Do static_lib.linkLibrary(dynamic_lib);
  • Define an executable that links static-lib and dynamic-lib
  • The error message will appear from lld while processing file libstatic-lib.a

Explanation of the issue

The error occurs because the archive file libstatic-lib.a contains symbols from the dynamic library libdynamic-lib.so, which is not valid for an archive file (static library).

$ nm -A  .zig-cache/o/.../libstatic-lib.a
.zig-cache/o/.../libstatic-lib.a:.zig-cache/o/.../libshared-lib.so:00000000000012e0 T bar       <-- BAD
.zig-cache/o/.../libstatic-lib.a:.zig-cache/o/.../libshared-lib.so:0000000000002300 d _DYNAMIC  <-- BAD
.zig-cache/o/.../libstatic-lib.a:.zig-cache/o/.../static.o:                 U bar
.zig-cache/o/.../libstatic-lib.a:.zig-cache/o/.../static.o:0000000000000000 T foo
.zig-cache/o/.../libstatic-lib.a:.zig-cache/o/.../static.o:0000000000000000 r .LCPI0_0
.zig-cache/o/.../libstatic-lib.a:.zig-cache/o/.../static.o:0000000000000004 r .LCPI0_1

The problematic command is the build-lib command to build the archive, which includes the .so file as a source:

zig build-lib /path/to//static-shared-error/src/static.c .zig-cache/o/.../libshared-lib.so -rpath .zig-cache/o/... -ODebug -I /path/to//static-shared-error/src -I .zig-cache/o/... -Mroot --cache-dir .zig-cache --global-cache-dir /home/jacob/.cache/zig --name static-lib -static --zig-lib-dir /path/to/zig/0.15.1/lib/

Note that both the static.c and libshared-lib.so files are given as position arguments to the build-lib command.

After these changes:

zig build-lib /path/to/static-shared-error/src/static.c -ODebug -I /path/to/static-shared-error/src -I .zig-cache/o/... -Mroot --cache-dir .zig-cache --global-cache-dir /home/jacob/.cache/zig --name static-lib -static --zig-lib-dir /path/to/zig/0.15.1/lib/

The .so file isn't listed, the error message does not appear, and the executable is still properly linked.

System Libraries

The above shows the issue with user-defined libraries, but this occurs with system libraries as well (as pointed out in the linked issue). To view a reproduction, clone https://github.com/zig-gamedev/zglfw/ (referenced from this comment) and build with Zig 0.14.1.

Testing

I only have a Linux machine to test on; not sure if there would be any linker-related differences on Mac or Windows that might cause issues.

When compiling static libraries, don't tell the linker to include other
libraries (static OR dynamic) as sources to include in the archive.

Should resolve ziglang#19341
@JacobCrabill JacobCrabill force-pushed the bugfix/jacob/static-shared-linkage branch from adcaae3 to cee59f1 Compare September 28, 2025 04:50
@JacobCrabill JacobCrabill changed the title Bugfix/jacob/static shared linkage Compile.zig: Fix static->dynamic library linkage Sep 28, 2025
@JacobCrabill JacobCrabill marked this pull request as ready for review September 28, 2025 04:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant