-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Dynamically link libc++ if integrating with system LLVM
#12085
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
libc++ if integrating with system LLVM, Clang, etc.libc++ if integrating with system LLVM
|
Thanks for this! Let me play around with this a bit... |
andrewrk
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On my dev machine, with LLVM compiled from source:
$ stage1/bin/zig build -p stage2 -Dskip-install-lib-files -Denable-llvm
This completes but produces a non-viable binary:
$ ldd stage2/bin/zig
linux-vdso.so.1 (0x00007ffd9f4e7000)
libstdc++.so.6 => not found
libz.so.1 => /nix/store/2yy85x1bhwmynzmpr4n29caxpfm0bkk4-zlib-1.2.12/lib/libz.so.1 (0x00007fe8dbb02000)
libm.so.6 => /nix/store/0xxjx37fcy2nl3yz6igmv4mag2a7giq6-glibc-2.33-123/lib/libm.so.6 (0x00007fe8db9c1000)
libpthread.so.0 => /nix/store/0xxjx37fcy2nl3yz6igmv4mag2a7giq6-glibc-2.33-123/lib/libpthread.so.0 (0x00007fe8db9a1000)
libc.so.6 => /nix/store/0xxjx37fcy2nl3yz6igmv4mag2a7giq6-glibc-2.33-123/lib/libc.so.6 (0x00007fe8db7cc000)
/nix/store/0xxjx37fcy2nl3yz6igmv4mag2a7giq6-glibc-2.33-123/lib/ld-linux-x86-64.so.2 => /nix/store/0xxjx37fcy2nl3yz6igmv4mag2a7giq6-glibc-2.33-123/lib64/ld-linux-x86-64.so.2 (0x00007fe8dbb22000)
libdl.so.2 => /nix/store/0xxjx37fcy2nl3yz6igmv4mag2a7giq6-glibc-2.33-123/lib/libdl.so.2 (0x00007fe8db7c5000)
Running it:
$ stage2/bin/zig build -p stage3 -Dskip-install-lib-files -Denable-llvm
stage2/bin/zig: error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directory
I believe there are two problems here:
- In this case we actually do want static libc++ because there are no dynamic dependencies which have a dynamic dependency against libc++. Proper logic should detect the difference between these two situations by examining the positional CLI arguments which are dynamic libraries.
- Linking dynamically against libc++ has not been done properly, since it ended up creating a binary where the libc++ library could not be found.
I suspect that the end-game here may be to include support for proper libc++ linking directly into the compiler rather than the build system. The user would supply -lc++ and Zig would have smart defaults for whether to dynamic link it or static link it, depending on the other dynamic dependencies, if any, that are part of the compilation.
|
Oh boy, I guess it's not called dependency hell for nothing.
Ah, maybe an I'm going to convert this PR to a draft until I can play around with this later this week. I want to wrestle with the linker to see if we can get it to export the statically-linked libstc++ symbols to the dynamic symbol table ( I also noticed a problem with how CMake is finding |
|
Now that #12136 has landed, I'll follow up on this one shortly |
|
Here's what it looks like building master branch now that #12136 has landed, on my nixos system: |
4f9ed16 to
495dba3
Compare
This check is needed because if static/dynamic linking is mixed incorrectly, it's possible for Clang and LLVM to end up with duplicate "copies" of libc++. This is not benign: Static variables are not shared, so equality comparisons that depend on pointers to static variables will fail. One such failure is std::generic_category(), which causes POSIX error codes to compare as unequal when passed between LLVM and Clang. I believe this is the cause of ziglang#11168 In order to avoid affecting build times when Zig is repeatedly invoked, we only enable this check for "zig env" and "zig version"
This ensures that the zigcpp clang driver and LLVM are using the same copy of libc++. See prior commit for more details.
495dba3 to
7250236
Compare
|
Alright, I think this might be finally cooked:
|
Shared libraries can be provided on the command line as if they were objects, as a path to the ".so" file. The "each-lib-rpath" functionality was ignoring these shared libraries accidentally, causing missing rpaths in the output executable.
7250236 to
58540f9
Compare
andrewrk
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this! I tested this locally and was able to do all of the following things successfully:
- build zig stage1 against system nixos llvm package
- build stage2
- build stage3
- pass all the behavior tests with stage3
If we are integrating with system LLVM, build.zig attempts to statically link
libc++.As a result, LLVM ends up with a separate "copy" of the library. This causes POSIX
std::error_codes generated by LLVM and Clang always compare unequal, since they refer to (duplicated) static variables.This PR changes libc++ to be linked dynamically and adds a runtime check to verify that LLVM and Clang are using a single instance of libc++. I believe this resolves #11168 (cc @mitchellh)
I might have missed some important build system details, so feel free to take this change over if needed.