Program built by Zig can't link correctly against system LLVM libraries in Arch Linux
Zig Version
0.12.0-dev.3191+9cf28d1e9
Steps to Reproduce and Observed Behavior
> uname -a
Linux minipc-linux 6.6.21-1-lts #1 SMP PREEMPT_DYNAMIC Wed, 06 Mar 2024 16:59:55 +0000 x86_64 GNU/Linux
Observe https://github.com/birth-software/nativity/pull/112 I get these linking errors: https://zigbin.io/d2c32c
Relevant part of the build.zig code:
compiler.linkLibC();
compiler.linkLibCpp();
compiler.linkSystemLibrary("LLVM");
compiler.linkSystemLibrary("clang");
compiler.linkSystemLibrary("clang-cpp");
compiler.linkSystemLibrary("lldCommon");
compiler.linkSystemLibrary("lldCOFF");
compiler.linkSystemLibrary("lldELF");
compiler.linkSystemLibrary("lldMachO");
Am I doing anything wrong? Or is it just impossible to work with C++ system libraries from Zig. I tried with Clang and it works...
Expected Behavior
To be able to compile and link correctly.
these seem much more relevant
error: unable to find Dynamic system library 'lldCommon' using strategy 'paths_first'. searched paths:
error: unable to find Dynamic system library 'lldCOFF' using strategy 'paths_first'. searched paths:
error: unable to find Dynamic system library 'lldELF' using strategy 'paths_first'. searched paths:
error: unable to find Dynamic system library 'lldMachO' using strategy 'paths_first'. searched paths:
I would double check that llvm is visible to your build
these seem much more relevant
error: unable to find Dynamic system library 'lldCommon' using strategy 'paths_first'. searched paths: error: unable to find Dynamic system library 'lldCOFF' using strategy 'paths_first'. searched paths: error: unable to find Dynamic system library 'lldELF' using strategy 'paths_first'. searched paths: error: unable to find Dynamic system library 'lldMachO' using strategy 'paths_first'. searched paths:I would double check that llvm is visible to your build
As I said, using Clang works just fine:
clang src/llvm/clang_cc1.cpp src/llvm/clang_main.cpp src/llvm/clang_cc1as.cpp src/llvm/ar.cpp src/llvm/lld.cpp src/llvm/llvm.cpp -lc -lstdc++ -lLLVM -lclang -lclang-cpp -llldCommon -llldCOFF -llldELF -llldMachO -llldWasm
/usr/bin/ld: /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../lib64/Scrt1.o: in function `_start':
(.text+0x1b): undefined reference to `main'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
clang: error: [...]
no it didn't ?
Yes, it did. It just doesn't find the main entry point (which is normal because I don't have an entry point in those files), it can resolve the LLVM symbols just fine.
So after trying to understand what Zig does to link against libstdc++, I came out with something that works:
compiler.addObjectFile(.{ .cwd_relative = "/usr/lib/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../lib/libstdc++.so" });
compiler.addIncludePath(.{ .cwd_relative = "/usr/include"});
compiler.addIncludePath(.{ .cwd_relative = "/usr/include/c++/13.2.1"});
compiler.addIncludePath(.{ .cwd_relative = "/usr/include/c++/13.2.1/x86_64-pc-linux-gnu"});
compiler.addLibraryPath(.{ .cwd_relative = "/usr/lib"});
The solution is not ideal and probably the best thing is to let the user link against libstdc++ without these workarounds, unless I am missing something?
You can't mix different libc++