-
-
Notifications
You must be signed in to change notification settings - Fork 14.4k
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
cmake: detect libc location at runtime #181431
Conversation
I've now also successfully tested building and running |
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.
LGTM.
Caveat: I have very little understanding of how darwin packaging works. Do I understand it correctly you are planning to use
What does it do? Does it only substitute Would something like that work for darwin? |
This is a recent change in nixpkgs. It used to be Intel was built with the 10.12 SDK, and Apple Silicon was built with 11.0 SDK. The recent change is to opt-in per-package into the 11.0 SDK on Intel too. What that means technically is also something I'm not an expert on. For example, libc / libsystem on darwin is typically injected by the loader (kernel?) at run-time, so I imagine despite linking against different libcs, they use the same at run-time. I imagine frameworks provided by Apple also use the same binary at run-time (sans injection), but maybe there are some exceptions for the ones we have source code of. I'm really speculating here, because I don't know the specifics. 🙂 In practice this PR may not necessarily be darwin specific. It's about about using cmake to build with a different libc (via cc wrapper override), without having to rebuild cmake itself.
I do feel that a separate The relevant part of that special let
clang = stdenv.cc.override {
bintools = stdenv.cc.bintools.override { libc = packages.Libsystem; };
libc = packages.Libsystem;
};
in
overrideCC stdenv clang; But yes, it overrides specific packages (beyond stdenv), and all the Apple frameworks. See: pkgs/os-specific/darwin/apple-sdk-11.0/default.nix I don't believe it recurses into dependencies. |
Sorry, I rushed the last comment a bit, and made some small edits to it just now. I think a relevant previous comment is #176661 (comment), quoting:
I can't easily find the Matrix discussion mentioned, unfortunately. From what I can tell, a Whether we do For a Another difference is that a So, there is I think good reason to at least prefer I wonder if we can maybe even reduce the amount of overrides to just be limited to the P.S.: In an ideal world, I believe that we'd always use the latest SDK and set |
Yeah,
Yeah. That makes sense.
Would putting
Do @NixOS/darwin-maintainers have a vision how things should be laid out in multiple SDKs world? Reading #101229 AFAIU we normally expect only one default SDK. That is somewhat similar to linux |
It was my understanding that Go 1.18 is already being built with the 11.0 SDK, and Go 1.18 is the default in unstable. Is there additional context I’m missing? (I’m aware some packages still have problems building, but I believe that’s due to golang/go#51091). Regarding cmake: I added cmake to Regarding the SDK: As I understand it, the default SDK on x86_64-darwin is still 10.12. Making the 11.0 (and eventually newer) SDKs available was meant to be an escape hatch for packages that don’t build on the default SDK (my motivating example being MoltenVK, but Go and some other packages also wouldn’t build on the 10.12 SDK). Meaning, if packages can build with the 10.13 SDK once the SDK is bumped, those packages should be reverted to the default stdenv. |
I don't know anything about cmake, so I can't review the code change, but I've been thinking about this exact issue in our build tooling more broadly, have started a discussion here: #185742. I completely agree with the approach of detecting libc at runtime, though I would prefer if it was done with a mechanism that isn't nix specific. |
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.
Aha. Let's give runtime detection a try.
Okay then! |
This PR broke a build: https://hydra.nixos.org/build/187642932 |
That is probably a
Where we fail to read |
|
Without this change pkgsLLVM fails to build any packages as compiler-rt fails early in cmake: CMake Error at ...-cmake-3.24.0/share/cmake-3.24/Modules/Platform/UnixPaths.cmake:53 (file): file STRINGS file "...-x86_64-unknown-linux-gnu-clang-wrapper-11.1.0/nix-support/orig-libc-dev" cannot be read. It's a regression caused by 871cf9f "cmake: detect libc location at runtime NixOS#181431" where we started using `orig-libc-dev` as a libc pointer. During pkgsLLVM pootstrap first compiler has no libc support yet. The change skips runtime detection if there are no libc signs.
Description of changes
This PR updates the patch to
Modules/Platform/UnixPaths.cmake
to detect the libc location at runtime, based on the cc-wrapper specified in$NIX_CC
. If$NIX_CC
is not (or incorrectly) set, it falls back to the original behavior (ie.: use the libc that was used to build CMake itself).This allows CMake to automatically pick up an alternate libc in package builds. The alternative would be to do something like
-DCMAKE_SYSTEM_INCLUDE_PATH=${stdenv.cc.libc_dev}/include
in every package build that wants a different libc.This may sound niche, but I suspect may become a more common thing on Darwin as the option to use different macOS SDKs becomes available. #176661 was recently merged, making a second SDK available for
x86_64-darwin
by doingdarwin.apple_sdk_11_0.callPackage ./my-package { }
, which also swaps in a different stdenv with a different version of libSystem.I'm specifically working on the Swift build on Darwin, which is picking up the wrong libSystem in a couple of places. A simple one is a call to
find_package(Backtrace)
, which does afind_path(Backtrace_INCLUDE_DIR "execinfo.h")
. Both calls can be easily tested in isolation.Besides that, I also tested rebuilding
fish
on Linux with this change in place onmaster
. Fish uses CMake, and apparently also pulls in a handful of CMake-using deps. That all worked fine and produced a working build.Things done
sandbox = true
set innix.conf
? (See Nix manual)nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD"
. Note: all changes have to be committed, also see nixpkgs-review usage./result/bin/
)nixos/doc/manual/md-to-db.sh
to update generated release notes