-
-
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
darwin: change the SDK pattern, update the SDKs, and update source releases #346043
Conversation
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: |
Pinging @emilazy, @paparodeo, @toonn, @RossComputerGuy, and @Ericson2314 (for cross-related stuff). |
4688112
to
03e0b5d
Compare
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.
This is incredible work, Randy, and I can’t thank you enough for all the time and effort you’ve put into it. Every time I hit a commit that removes hundreds of lines of unmaintained and cobweb‐filled code I was delighted. Even the scary commits were less scary than I was expecting them to be. The code quality here is so consistently high that I have largely been reduced to nitpicking code I understand and asking questions about code I don’t understand.
This is surely the biggest change to Darwin support since we moved off impure frameworks and I am confident that it is going to make things vastly nicer for both maintainers of the core Darwin infrastructure and contributors to packages across the tree, who will be faced with far fewer confusing and painful Darwin‐only build errors. I am proud to have had my small part in shaping the interface and implementation decisions used here, and I think the result is fantastic. I am excited for the 25.05 minimum version bump that will allow a lot of the remaining technical debt here can be dropped and x86_64-darwin
should stop being such a problem.
I am too tired today to do a really deep dive on the core stdenv
code here given my inexperience with the bootstrap, so please consider these reviews to be largely me familiarizing myself with the code, asking questions, and pointing out relatively shallow things that seem wrong to me. I hope to do another, closer read in the next few days after this round of reviews is dealt with.
I have a few general concerns about the source release situation:
-
Xcode project files are baroque and unreadable. Keeping them in sync with our Meson build system rewrites may be painful. I have been convinced that rewriting the build systems into Meson is the right approach here, but I still worry about bitrot and drift. This is not really an avoidable problem, but it ties in to the subsequent points.
-
It seems like it might be a good idea to merge the source release updates into the commits that rewrite them, as in some parts you have ported build system logic to Meson only to rearrange and rewrite it before anyone has even had a chance to use it.
-
While I am glad that it is so relatively easy to package new source releases (
x86_64-darwin
notwithstanding), it works as a great proof‐of‐concept for the new format, and I hate to poke at the sunk cost of the fun distraction here, I am still uneasy about the new packages being introduced here, especially in light of (1).We have already moved away from the source‐based PureDarwin dream and accepted a runtime dependency on the shipped binary code of the proprietary OS we’re targeting. I am not sure it makes sense to try and package every available source release of core system commands when canonical versions of those binaries are already bundled with the system that is required to run our packages in the first place, especially as we have to make sacrifices to functionality because of missing entitlements and private headers. It’s not like Apple release enough source dumps that you could avoid running things from
/usr/bin
, anyway.It would be one thing if it was a one‐and‐done job of packaging them and using their upstream build systems and then letting update scripts handle the rest, but we can see from this PR that new source releases often require active build system intervention due to our Meson rewrites, and I worry about this turning into a situation like we’ve had too much of in the past for Darwin, where the next person to maintain all this is resigned to going through the motions and burden of maintaining these packages despite extreme scepticism about whether anyone is actually benefiting from them. Additionally, these source dumps often require messing with private headers due to Apple’s messed up internal SDK situation, which makes them a distinctly different type of challenge from packaging any old random source dump of applications on the internet.
I think we should focus on packaging things that are useful for Nixpkgs builds; even
unixtools
aliases that are not used anywhere else in the tree I am somewhat sceptical of.
cc @tie for Bash review (please feel free to ignore this ping if you’re still taking a break!) |
22a832f
to
b1bb74e
Compare
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/breaking-changes-announcement-for-unstable/17574/65 |
Nixpkgs now has much more reasonable handling of macOS SDKs, and this old default is not generally needed for builds anymore. I think having these SDKs in the inputs is a bit of a nuisance now, since it means there are mixed framework versions in the closure. See: https://discourse.nixos.org/t/on-the-future-of-darwin-sdks-or-how-you-can-stop-worrying-and-put-the-sdk-in-build-inputs/50574 See: NixOS/nixpkgs#346043
Nixpkgs now has much more reasonable handling of macOS SDKs, and this old default is not generally needed for builds anymore. I think having these SDKs in the inputs is a bit of a nuisance now, since it means there are mixed framework versions in the closure. See: https://discourse.nixos.org/t/on-the-future-of-darwin-sdks-or-how-you-can-stop-worrying-and-put-the-sdk-in-build-inputs/50574 See: NixOS/nixpkgs#346043
Nixpkgs now has much more reasonable handling of macOS SDKs, and this old default is not generally needed for builds anymore. I think having these SDKs in the inputs is a bit of a nuisance now, since it means there are mixed framework versions in the closure. See: https://discourse.nixos.org/t/on-the-future-of-darwin-sdks-or-how-you-can-stop-worrying-and-put-the-sdk-in-build-inputs/50574 See: NixOS/nixpkgs#346043
There are currently three different SDKs in nixpkgs, which are all built slightly differently. The 10.12 SDK is built from a mixture of source releases, stubs and headers (from source releases), and headers from the upstream SDK. The 11.0 (really, 11.1) SDK is built mostly from the upstream SDK. These two SDKs have served nixpkgs well for several years, but they have several limitations. The 12.3 SDK was added several months ago based on a stripped down version of the pattern used in #229210. It is a newer pattern still, but it shares many of the same limitations.
overrideSDK
).To elaborate on the above,
overrideSDK
works currently by enumerating the transitive, propagated inputs of a package. This set of packages is then examined, and propagated SDK inputs are replaced with versions corresponding to the requested SDK. The problem is that the set of build inputs does not and cannot include all possible dependencies because dependencies can be propagated in other ways. Packages can capture a framework and include it in their build files (such as abseil-cpp prior to #265395 orrustPlatform
, which captures various build/host/target clangs in its hooks.The solution is to stop trying to fight how the platform works and embrace it: make the SDK a package laid out like a normal SDK would be on Darwin. The tooling expects it. Instead of having to hack build systems to deal with nixpkgs idiosyncrasies, most builds should be able to Just Work™ by default.
This PR adds a new SDK pattern for Darwin that provides a single SDK package for each version. A default SDK is provided as an
extraBuildInput
in the Darwin stdenv. To use a newer SDK version, add it as abuildInput
. A hook is used to pick which SDK of those available is used (currently always the newest); and it is possible to have a different SDK for build, for host, and for target platforms. Most importantly, it is never possible to have more than one SDK active. Weird errors due to semicolons or other punctuation should be a thing of the past.Additionally, a separate hook is also provided to set the minimum version (also known as the deployment target). If your package specifies that it works on 11.0 and newer, you can use the hook to do that. If your package is a library, you can propagate the hook to make sure users of your library also target the correct version.
This combination allows SDKs and SDK requirements to be propagated to packages without using a new scope and
callPackage
. Packages that would be prevented from usingby-name
can now be moved there and use whatever SDKs they need or are propagated to them by their dependencies.To provide better compatibility with build systems that assume Xcode is available,
xcrun
is also included in the stdenv. It and the xcbuild derivation have been reworked to find the SDK dynamically. It should hopefully no longer be necessary to patch out invocations of xcrun in build systems (e.g.,xcrun --find clang
in a build will return clang from nixpkgs).In addition to adding the new SDK pattern, this PR fixes cross-compilation on Darwin. It should now be possible to build static packages for both aarch64- and x86_64-darwin (assuming the packages support it). It should also be possible to cross-compile between both architectures (again assuming the packages support it).
New SDKs
The following SDKs are added in this PR: 10.12.2, 10.13.2, 10.14.6, 10.15.6, 11.3, 12.3, 13.3, and 14.4. The 15.0 SDK has been left out to be added later as a test of the SDK update infrastructure to assess and confirm how easy it is to add a new one. In my testing, adding the 15.0 SDK is a ~5 minute task. Hopefully, it goes as easily for @emilazy.
Source Releases
The 10.12 SDK builds several frameworks and libraries from source. It also makes use of their headers. The new SDK pattern no longer tries to get headers from the source releases. They’re just too inconsistent with the headers in the SDK. Some headers are even older than the 10.12 because newer sources are not available or complete enough to use.
However, this update actually builds and uses more source releases than before. The following libraries are built. Of these, libresolv is new on aarch64-darwin, libsbuf is new for both (ported from FreeBSD due to the lack of a source release), libpcap is new for both, and copyfile and removefile are built from source for the first time.
Currently, libiconv and libresolv are propagated with the SDK on both platforms. For 25.05, libpcap and ICU may be made to be the default implementation on Darwin due to containing Apple-specific changes.
It is also worth noting: all source releases correspond to the source released for macOS 15. When possible, it has been backported to build with the default SDKs.
Source release version updates
Transition Strategy
Because this is a non-trivial change to how Darwin works, a transition is necessary. This update tries to avoid breaking existing packages, but there are breaking changes (see below). To minimize breakage, all existing SDK frameworks and libraries as well as dropped source releases (anything not above) have been replaced with stubs. These stubs contain a
README
advising the user to read the documentation on how to update to the new pattern. Currently, these stubs do nothing other than provide stubs. After a treewide has been done, they will moved todarwin-aliases.nix
. It is expected that these aliases will remain in place until at least the 26.05 release.Breaking Changes
SDKROOT/System/Library/Frameworks
;sdkroot
attribute on the package (e.g.,apple-sdk.sdkroot
).llvmPackages.libcxxStdenv
. This aligns Darwin with Linux wherellvmPackages.stdenv
uses the default libstdc++.darwin.libSystem
contains emptylib
andinclude
folders to avoid compiler and linker warnings that may be turned into errors. The libSystem stubs can be located at$SDKROOT/usr/lib/libSystem.tbd
.configd
option to disable the_scproxy
module. The SDK always has the SystemConfiguration framework.darwin.libutil
as a build input.apple-sdk.sourceRelease
function. This is mostly useful for copying private headers for use to build a derivation. See various source releases for examples.Closed Issues and PRs
Security
framework #269646Things Still to be Done
This PR is almost completely ready. If need be, it could be merged into staging to make the next staging-next cycle. The following.
netstat
doesn’t print active Internet connections. It prints other kinds but not those. It requires further investigation. Punted for now.Related PRs
These issues were found during testing. This flake was used to help find issues. Some of these can target staging or even master without waiting. Others depend on this PR or even other PRs.
nix.conf
? (See Nix manual)sandbox = relaxed
sandbox = true
nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD"
. Note: all changes have to be committed, also see nixpkgs-review usage./result/bin/
)Add a 👍 reaction to pull requests you find important.