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

curl: fix build failures due to needing to propagate frameworks #263598

Merged
merged 5 commits into from
Oct 27, 2023

Conversation

reckenrode
Copy link
Contributor

Description of changes

curl expects to propagate any libraries and frameworks it links against, which was missed in #260963. This results in Nix and other packages that have curl as a dependency to fail to build. Since propagating frameworks is not compatible with the current mechanism for overriding the SDK used, a new mechanism has been introduced that handles propagated build inputs. This mechanism will likely replace the existing one in the future.

Things done

  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandboxing enabled in nix.conf? (See Nix manual)
    • sandbox = relaxed
    • sandbox = true
  • 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.11 Release Notes (or backporting 23.05 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.

@reckenrode
Copy link
Contributor Author

I pushed a change to make it handle paths with spaces. I wanted to use the ASCII record separator, but there’s no way to use hex escapes in Nix, and I didn’t want to put the raw character in the file (since it seemed brittle due to how/whether different editors would treat or display the character).

@drupol
Copy link
Contributor

drupol commented Oct 26, 2023

LGTM, I fully trust you on this @reckenrode !

Copy link
Contributor

@toonn toonn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about the latest attribute. I worry it might be abused and then cause unnecessary rebuilds. I assume you're thinking of cases like MoltenVK but wouldn't you only need an SDK bump for those when the version is bumped?

Overall I support the approach if cURL necessitates it.

@@ -246,4 +246,106 @@ rec {
env = (args.env or {}) // { NIX_CFLAGS_COMPILE = toString (args.env.NIX_CFLAGS_COMPILE or "") + " ${toString compilerFlags}"; };
});
});

# Override SDK changes the SDK used to build the package. It does two things:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Override SDK changes the SDK used to build the package. It does two things:
# Overriding the SDK changes the SDK used to build the package. It does two things:

Alternatively stick to the name of the function, the current form reads a bit weird.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can clean this and the other comments up.

Comment on lines 251 to 252
# * It ensures that the compiler and bintools have the correct Libsystem version; and
# * It replaces any SDK references with those in the SDK corresponding to darwinSdkVersion.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# * It ensures that the compiler and bintools have the correct Libsystem version; and
# * It replaces any SDK references with those in the SDK corresponding to darwinSdkVersion.
# * Ensure that the compiler and bintools have the correct Libsystem version
# * Replace any SDK references with those in the SDK corresponding to darwinSdkVersion.

Since the argument isn't necessarily an attrset with the darwinSdkVersion attribute, this reads a bit weird. Maybe "the requested version?"

for targetPath in "$pkgOutputPath"/*; do
targetName=$(basename "$targetPath")

# `nix-support` is special-cased because any propgated inputs need their SDK
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# `nix-support` is special-cased because any propgated inputs need their SDK
# `nix-support` is special-cased because any propagated inputs need their SDK

pkgs/stdenv/adapters.nix Show resolved Hide resolved

sdk = pkgs.darwin."apple_sdk_${lib.replaceStrings [ "." ] [ "_" ] darwinSdkVersion}";

isSDKFramework = pkg: lib.hasPrefix "apple-framework-" (lib.getName pkg);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we not do something similar for apple-lib-*? That includes things like XPC.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eventually. That’s something I’d like to review in conjunction with or after #229210. There’s not a lot of consistency outside of the framework case, and I didn’t want to make the scope of this too broad. That’s why I’m calling it an MVP and keeping it limited to these packages. There’s still a lot of work left before we could conceivably do a tree-wide switch to the adapter over using apple_sdk_11_0.callPackage.

@@ -5755,7 +5755,9 @@ with pkgs;

joystickwake = callPackage ../tools/games/joystickwake { };

juce = darwin.apple_sdk_11_0.callPackage ../development/misc/juce { };
juce = callPackage ../development/misc/juce {
stdenv = if stdenv.isDarwin then overrideSDK stdenv "11.0" else stdenv;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be worth introducing a stdenv_SDK_11 or such for this. The if-then-else makes it look kind of complicated.

Copy link
Contributor Author

@reckenrode reckenrode Oct 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SDK-specific stdenvs don’t compose very well. Even if the adapter is available, people might think you have to use one of those instead of overriding the SDK in the stdenv you want to use. For example, if overrideSDK stdenv is the standard pattern, it’s obvious you should be able to do overrideSDK llvmPackages_15.stdenv "11.0" or overrideSDK qt6Packages.stdenv "11.0" or overrideSDK python3.stdenv "11.0" or even overrideSDK python3.stdenv { darwinMinVersion = "10.13";}.

The last one is equivalent to what I had to do manually to fix pybind11 for clang 16. There are a couple of other packages that have to do that as well. It would be much nicer if they could just use the adapter to set the deployment target in the stdenv.

Regarding the conditional, you’d need it even if there were a SDK-specific stdenv. I’ve intentionally chosen not to make the adapter platform-neutral. It’s for Darwin, so you need to conditionally use it only on Darwin. I’m pretty sure I’ve seen it mentioned that the current approach is a layering violation, and I agree. This PR fixes that by making the adapter work like other platform-specific stuff in nixpkgs.

@reckenrode reckenrode force-pushed the curl-propagation-fix branch from 93fcc5f to 2864180 Compare October 26, 2023 17:08
@reckenrode
Copy link
Contributor Author

reckenrode commented Oct 26, 2023

@toonn I pushed an update that fixes the comments, cleans up the code a bit, and drops support for specifying the latest SDK. You’re right I was thinking of MoltenVK. I can handle that manually as necessary.

Copy link
Contributor

@toonn toonn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only another typo. LGTM

pkgs/stdenv/adapters.nix Outdated Show resolved Hide resolved
@@ -246,4 +246,103 @@ rec {
env = (args.env or {}) // { NIX_CFLAGS_COMPILE = toString (args.env.NIX_CFLAGS_COMPILE or "") + " ${toString compilerFlags}"; };
});
});

# Overriding the SDK changes the Darwin SDK used to build the package, which:
# * Ensures that the compiler and bintools have the correct Libsystem version; and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "; and" feels very awkward in a bulleted list, IMHO. Not important though.

Copy link
Contributor Author

@reckenrode reckenrode Oct 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It’s a style thing. I try to write bulleted lists as if they were part of the sentence that precedes them (but laid out as lists for readability). But I can drop it if that’s the preference.

# * Replaces any SDK references with those in the SDK corresponding to requested SDK version.
#
# `sdkVersion` can be any of the following:
# * A version string indicating the requested SDK version; or
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the "; and" from before is dropped the "; or" here needs the same treatment.

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.
Using overrideSDK allows juce to use the correct SDK frameworks
even when they are propagated from curl.
Using overrideSDK allows datadog_trace to use the correct SDK frameworks
even when they are propagated from curl.
Using overrideSDK allows cargo-codspeed to use the correct SDK frameworks
even when they are propagated from curl.
`libcurl.la` and `curl-config --static-libs` both include the frameworks
curl needs to link, so propgate them in case dependents don’t include
those frameworks in their build inputs. This fixes building Nix and
probably other things (like netcdf).
@reckenrode reckenrode force-pushed the curl-propagation-fix branch from 2864180 to 028534b Compare October 26, 2023 17:26
@reckenrode
Copy link
Contributor Author

I pushed a fix for the typo. I left the lists as they were unless I get feedback requesting otherwise.

@ofborg ofborg bot added the 10.rebuild-darwin-stdenv This PR causes stdenv to rebuild label Oct 26, 2023
@ofborg ofborg bot added 10.rebuild-darwin: 501+ 10.rebuild-darwin: 5001+ 10.rebuild-linux: 0 This PR does not cause any packages to rebuild on Linux labels Oct 26, 2023
@vcunat
Copy link
Member

vcunat commented Oct 27, 2023

FYI, the builds happening for several hours on Hydra already use the first version of this PR, but there won't be that much done yet today, so trashing those builds won't be a real issue.

@reckenrode
Copy link
Contributor Author

FYI, the builds happening for several hours on Hydra already use the first version of this PR, but there won't be that much done yet today, so trashing those builds won't be a real issue.

The changes have been in the adapter, which affects three packages. The core change of propagating the build inputs from curl hasn’t changed, so unless something happens to drastically change or drop 028534b, there shouldn’t be much in the way of rebuilds once this gets merged.

Copy link
Contributor

@toonn toonn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Nix built for me with this PR.

@toonn toonn merged commit f65ccb3 into NixOS:staging-next Oct 27, 2023
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
6.topic: stdenv Standard environment 10.rebuild-darwin: 501+ 10.rebuild-darwin: 5001+ 10.rebuild-darwin-stdenv This PR causes stdenv to rebuild 10.rebuild-linux: 0 This PR does not cause any packages to rebuild on Linux
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants