Skip to content
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

apple_sdks: init with 11.1, 11.3, 12.1, 12.3, 13.1, and 13.3 #229210

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

ConnorBaker
Copy link
Contributor

@ConnorBaker ConnorBaker commented May 1, 2023

What's new?

Adds a new directory for apple-sdks and refactors Xcode directory. Both use a “builder” and “releases” pattern where a nix configuration file stores information about each release and a separate nix file contains the function to build each release. This pattern has proven useful in the CUDA work I’ve done where we need to support multiple SDKs.

Default Apple SDK for aarch64 has been bumped from 11.0 to 11.1.

Apple SDK versions 11.3, 12.1, 12.3, 13.1, and 13.3 are now available.

In addition, we now have a script to track Apple SDK releases (by parsing their sucatalog). The gen-frameworks.py script has been updated to accept command line arguments as well as support generating a public.nix file for each SDK release in the file generated by gen-apple-sdk-releases.py.

Current problems?

  • The 13.3 SDK is mean to be paired with Xcode 14.3, which is in turn backed by LLVM/Clang 15, so there are some compile errors when using old versions of LLVM/Clang.
  • Cleanly overriding the compiler used by stdenv and ensuring linking against the correct libc/libcxx.
  • There's a chance that jobs which have to rebuild perl for various stages of bootstrapping the stdenv compiler will fail if run in parallel. The specific error mentions miniperl. If encountered, limit the number of jobs to one until the bootstrapping is complete.

Docs

  • Please see pkgs/os-specific/darwin/apple-sdks/README.md for the beginnings of some documentation around how frameworks are generated.

Miscellaneous notes

Notes on the SDK's mkStdenv in default.nix, courtesy of @reckenrode:

  • While the minimum version of Darwin supported by the 13.3 SDK is 13.0, it’s possible to build against a newer SDK while targeting older platforms as long as you use an older deployment target and avoid (or dynamically check for) APIs specific to the newer SDK, so it's fine to set darwinMinVersion = "10.12".
  • Although the 13.3 SDK expects Xcode 14.3, we don't need to specify xcodeVer = "14.3". Nor do we need to override the default Xcode set in pkgs/os-specific/darwin/Xcode/default.nix because it only serves to copy the Xcode into the store and there aren't any derivations in Nixpkgs which seem to use it.
  • Because the 13.3 SDK is mean to be paired with Xcode 14.3, which is in turn backed by LLVM/Clang 15, there are some compile errors when using old versions of LLVM/Clang.
    • This is an open problem and requires further investigation
  • We specify darwinSdkVersion = "13.3" so our SDK is chosen instead of the default when building stdenv.
Things done
  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandbox = true set in nix.conf? (See Nix manual)
  • Tested, as applicable:
  • Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
  • Tested basic functionality of all binary files (usually in ./result/bin/)
  • 23.05 Release Notes (or backporting 22.11 Release notes)
    • (Package updates) Added a release notes entry if the change is major or breaking
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
  • Fits CONTRIBUTING.md.

@wegank wegank added the 6.topic: darwin Running or building packages on Darwin label May 1, 2023
@fgaz
Copy link
Member

fgaz commented May 2, 2023

ofborg bot requested review from fgaz

I wonder where did it get my username from. I don't see any change involving me and I don't have any darwin machine

@ConnorBaker
Copy link
Contributor Author

Okay! Did some fairly major refactoring of the 13.3 SDK to genericize it and make it easier to sub in other versions. I've also added a releases.nix with different versions of the SDK. @reckenrode what do you think? Thoughts on the direction it took?

@reckenrode
Copy link
Contributor

Should releases.nix be in the SDK or up a level? I like the idea of making the SDK more generic, so new versions can be added more easily, but how would this work with other SDKs? Did you have to do a lot of manual manipulate of the files from the generated ones?

@ConnorBaker
Copy link
Contributor Author

Should releases.nix be in the SDK or up a level?

It should, but I'm hesitant to refactor all of the SDKs at the moment, so I'm trying to keep changes localized to the SDK for 13.

I like the idea of making the SDK more generic, so new versions can be added more easily, but how would this work with other SDKs? Did you have to do a lot of manual manipulate of the files from the generated ones?

Thankfully, all of the 11.0+ releases seem to follow a similar pattern. I imagine each will have its own nix expression for public and private frameworks, as well as fixups, but that they'll have a lot in common.

If we wanted to move away from checking in the auto-generated public dependencies, we could instead make use of lib.optionals to conditionally add different frameworks depending on the SDK version.

I just updated the PR description with a bit of documentation for what the frameworks dir is for currently. Let me know if that's at all coherent!

@ConnorBaker
Copy link
Contributor Author

I want to note that I was also able to get rid of some recursion and switch over to using callPackage more consistently -- not sure what kind of breakages that will cause (if any at all) because I can't build things for the SDK right now.

@reckenrode
Copy link
Contributor

Should releases.nix be in the SDK or up a level?

It should, but I'm hesitant to refactor all of the SDKs at the moment, so I'm trying to keep changes localized to the SDK for 13.

Can it be at the top level without refactoring the other SDKs? That would allow them to be refactored later. Ideally, the SDKs should share as much of the build infrastructure to make adding new ones as painless as possible.

I like the idea of making the SDK more generic, so new versions can be added more easily, but how would this work with other SDKs? Did you have to do a lot of manual manipulate of the files from the generated ones?

Thankfully, all of the 11.0+ releases seem to follow a similar pattern. I imagine each will have its own nix expression for public and private frameworks, as well as fixups, but that they'll have a lot in common.

If we wanted to move away from checking in the auto-generated public dependencies, we could instead make use of lib.optionals to conditionally add different frameworks depending on the SDK version.

Would each dependency use lib.optionals? I’d fear that could get hard to read. Instead of using lib.optionals, could we adopt the override pattern? Each SDK would have an override function that receives the final set of dependencies and the unmodified set, then it returns a new set with whatever modifications it would need to make.

I just updated the PR description with a bit of documentation for what the frameworks dir is for currently. Let me know if that's at all coherent!

Looks good!

One other thing that comes to mind is making sure the system ncurses is excluded from the SDK. That’s not the case for the 11.0 SDK currently. It’s one of a few things that prevent Apple’s upstream cctools from building on aarch64-darwin. I grepped the current PR and don’t see it, so it appears it’s not excluded. Ideally, the 11.0 SDK would be updated/refactored and drop the system ncurses framework. Everything in nixpkgs should use the packaged ncurses.

There are a few private frameworks that also aren’t included. See #149692 (comment). If those could also be included, it might be possible to build the upstream cctools and fix the linker crash.

@domenkozar
Copy link
Member

cc @thefloweringash

@ConnorBaker ConnorBaker changed the title apple_sdk_13_3: init at 13.3 apple_sdks: init with 11.1, 11.3, 12.1, 12.3, 13.1, and 13.3 May 8, 2023
@reckenrode
Copy link
Contributor

I like the new organization. If this means adding new SDKs is a lot easier, that would be fantastic.

As discussed on Matrix, MoltenVK is well-behaved and can be built against the latest SDK. It uses dynamic feature detection to run on older systems. It supports a couple of macOS versions (10.11 and 10.12) for which it is impossible to build using those platforms’ SDKs.

@reckenrode
Copy link
Contributor

@ConnorBaker fyi, #241692 has been merged into staging and should hopefully make 23.11.

reckenrode added a commit to reckenrode/nixpkgs that referenced this pull request Oct 26, 2023
This is a replacement for using `darwin.apple_sdk_<ver>.callPackage`.
Instead of injecting the required packages, it provides a stdenv adapter
that modifies the derivation’s build inputs to use the requested SDK
versions. This modification extends to any build inputs propagated to it
as well. The `callPackage` approach is not deprecated yet, but it is
expected that it will be eventually.

Note that this is an MVP. It should work with most packages, but it only
handles build inputs and also only handles frameworks. Once more SDKs
are added (after NixOS#229210 is merged) and the SDK structure is normalized,
it can be extended to handle any package in the SDK namespace.

Cross-compilation may or may not work. Any cross-related issues can be
addressed after NixOS#256590 is merged.
reckenrode added a commit to reckenrode/nixpkgs that referenced this pull request Oct 26, 2023
This is a replacement for using `darwin.apple_sdk_<ver>.callPackage`.
Instead of injecting the required packages, it provides a stdenv adapter
that modifies the derivation’s build inputs to use the requested SDK
versions. This modification extends to any build inputs propagated to it
as well. The `callPackage` approach is not deprecated yet, but it is
expected that it will be eventually.

Note that this is an MVP. It should work with most packages, but it only
handles build inputs and also only handles frameworks. Once more SDKs
are added (after NixOS#229210 is merged) and the SDK structure is normalized,
it can be extended to handle any package in the SDK namespace.

Cross-compilation may or may not work. Any cross-related issues can be
addressed after NixOS#256590 is merged.
reckenrode added a commit to reckenrode/nixpkgs that referenced this pull request Oct 26, 2023
This is a replacement for using `darwin.apple_sdk_<ver>.callPackage`.
Instead of injecting the required packages, it provides a stdenv adapter
that modifies the derivation’s build inputs to use the requested SDK
versions. This modification extends to any build inputs propagated to it
as well. The `callPackage` approach is not deprecated yet, but it is
expected that it will be eventually.

Note that this is an MVP. It should work with most packages, but it only
handles build inputs and also only handles frameworks. Once more SDKs
are added (after NixOS#229210 is merged) and the SDK structure is normalized,
it can be extended to handle any package in the SDK namespace.

Cross-compilation may or may not work. Any cross-related issues can be
addressed after NixOS#256590 is merged.
reckenrode added a commit to reckenrode/nixpkgs that referenced this pull request Oct 26, 2023
This is a replacement for using `darwin.apple_sdk_<ver>.callPackage`.
Instead of injecting the required packages, it provides a stdenv adapter
that modifies the derivation’s build inputs to use the requested SDK
versions. This modification extends to any build inputs propagated to it
as well. The `callPackage` approach is not deprecated yet, but it is
expected that it will be eventually.

Note that this is an MVP. It should work with most packages, but it only
handles build inputs and also only handles frameworks. Once more SDKs
are added (after NixOS#229210 is merged) and the SDK structure is normalized,
it can be extended to handle any package in the SDK namespace.

Cross-compilation may or may not work. Any cross-related issues can be
addressed after NixOS#256590 is merged.
reckenrode added a commit to reckenrode/nixpkgs that referenced this pull request Oct 26, 2023
This is a replacement for using `darwin.apple_sdk_<ver>.callPackage`.
Instead of injecting the required packages, it provides a stdenv adapter
that modifies the derivation’s build inputs to use the requested SDK
versions. This modification extends to any build inputs propagated to it
as well. The `callPackage` approach is not deprecated yet, but it is
expected that it will be eventually.

Note that this is an MVP. It should work with most packages, but it only
handles build inputs and also only handles frameworks. Once more SDKs
are added (after NixOS#229210 is merged) and the SDK structure is normalized,
it can be extended to handle any package in the SDK namespace.

Cross-compilation may or may not work. Any cross-related issues can be
addressed after NixOS#256590 is merged.
@reckenrode
Copy link
Contributor

@ConnorBaker #234710 is complete. The Darwin stdenv update has been merged into master.

@khaneliman khaneliman mentioned this pull request Nov 20, 2023
13 tasks
@wegank wegank added 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md 2.status: merge conflict labels Mar 19, 2024
@stale stale bot removed the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Mar 20, 2024
@heimalne
Copy link

Any updates on the >= 12.x versions? This seems to be the new target architecture for many packages in the Python ecosystem and if i remember correctly the first official version to support Arm64 macs.

@reckenrode
Copy link
Contributor

reckenrode commented Apr 25, 2024

Any updates on the >= 12.x versions?

I will be picking this up after I get the cctools and ld64 updates successfully building the Darwin blockers channel and take a look at the Darwin cross-compilation issue after those and the recent LLVM changes. The plan is to land an SDK refactor into a common pattern first then add the missing SDKs (10.13 through 14.x) with as many source-based components as possible without regressing compatibility.

Once newer SDKs are available, packages that need one can use overrideSDK to change the SDK version used to build.

This seems to be the new target architecture for many packages in the Python ecosystem and if i remember correctly the first official version to support Arm64 macs.

11.0 was the first release of macOS to support Apple Silicon. There are no plans currently to change the default SDK on aarch64-darwin, but x86_64-darwin will be updated to 10.13 or 10.14 (but most likely 10.13).

grahamc added a commit to DeterminateSystems/apple-sdks.nix that referenced this pull request Apr 30, 2024
@gador gador mentioned this pull request Apr 30, 2024
13 tasks
@gador
Copy link
Contributor

gador commented Apr 30, 2024

@reckenrode did I read that correctly that you continue on this PR?
If so, that would be awesome! An update to the apple sdk system would be much appreciated! If you need some testing, let me know!

@reckenrode
Copy link
Contributor

@gador That’s right (more or less). The first iteration will be just the current SDKs in the common pattern. I’d like to do it without causing rebuilds, but I’m doubtful it’s possible. It may be a continuation, or it may just incorporate some of the approach. I’ll post an update to the Darwin updates news thread on Discourse once I have something to test.

@grahamc
Copy link
Member

grahamc commented Apr 30, 2024

Hey @reckenrode, I didn't mean to step on any toes with that flake. It was for an experiment, but I never managed to make it actually work. It'd definitely be better being part of nixpkgs, and we don't have any grand plans to maintain an apple sdk flake long term. Just trying to get out of a jam where we needed a newer SDK for a Swift program, but couldn't wait for a future merge, and it wasn't working as-is in the PR. Fwiw I emailed Connor Baker about this PR last night before I made the repo, but it didn't occur to me to email you first too. I'm sorry again.

@reckenrode
Copy link
Contributor

Hey @reckenrode, I didn't mean to step on any toes with that flake. It was for an experiment, but I never managed to make it actually work. It'd definitely be better being part of nixpkgs, and we don't have any grand plans to maintain an apple sdk flake long term. Just trying to get out of a jam.

It’s not about whether it’s a flake or an alternative. It’s the lack of communication and roadmap, especially in light of recent controversies. Is this going to be the solution? Is DetSys going to drive that? What’s going on?

@grahamc
Copy link
Member

grahamc commented Apr 30, 2024

There is no roadmap, and we're definitely not the people to decide if this is the solution, and we're not driving it, lol. Like I said: Just trying to get out of a jam where we needed a newer SDK for a Swift program, but couldn't wait for a future merge, and it wasn't working as-is in the PR.

@reckenrode
Copy link
Contributor

@grahamc Thanks for the clarification. I think if I had known the context when I saw the repo, I’d have reacted better. It’s understandable that you needed a solution when the soonest anything could possibly land is after the 24.05 release. The current SDK situation is definitely not great.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet