summary refs log tree commit diff
path: root/pkgs/stdenv
diff options
context:
space:
mode:
authortoonn <toonn@toonn.io>2023-10-27 18:25:39 +0200
committerGitHub <noreply@github.com>2023-10-27 18:25:39 +0200
commitf65ccb3163adc4b6e72547c893d6f614defa0b3a (patch)
treed7c03c8b9665a2d7f49ed5d64c2a442514b52e42 /pkgs/stdenv
parent5c3b38dc9ce8d89af48678affc7f77d0f39d166e (diff)
parent028534b7d43b40e6f82e45d0b850164803c10959 (diff)
downloadnixpkgs-f65ccb3163adc4b6e72547c893d6f614defa0b3a.tar
nixpkgs-f65ccb3163adc4b6e72547c893d6f614defa0b3a.tar.gz
nixpkgs-f65ccb3163adc4b6e72547c893d6f614defa0b3a.tar.bz2
nixpkgs-f65ccb3163adc4b6e72547c893d6f614defa0b3a.tar.lz
nixpkgs-f65ccb3163adc4b6e72547c893d6f614defa0b3a.tar.xz
nixpkgs-f65ccb3163adc4b6e72547c893d6f614defa0b3a.tar.zst
nixpkgs-f65ccb3163adc4b6e72547c893d6f614defa0b3a.zip
Merge pull request #263598 from reckenrode/curl-propagation-fix
curl: fix build failures due to needing to propagate frameworks
Diffstat (limited to 'pkgs/stdenv')
-rw-r--r--pkgs/stdenv/adapters.nix99
1 files changed, 99 insertions, 0 deletions
diff --git a/pkgs/stdenv/adapters.nix b/pkgs/stdenv/adapters.nix
index 7c64fd7e392..a7985b474ed 100644
--- a/pkgs/stdenv/adapters.nix
+++ b/pkgs/stdenv/adapters.nix
@@ -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
+  # * Replaces any SDK references with those in the SDK corresponding to the requested SDK version.
+  #
+  # `sdkVersion` can be any of the following:
+  # * A version string indicating the requested SDK version; or
+  # * An attrset consisting of either or both of the following fields: darwinSdkVersion and darwinMinVersion.
+  overrideSDK = stdenv: sdkVersion:
+    let
+      inherit (
+        { inherit (stdenv.hostPlatform) darwinMinVersion darwinSdkVersion; }
+        // (if lib.isAttrs sdkVersion then sdkVersion else { darwinSdkVersion = sdkVersion; })
+      ) darwinMinVersion darwinSdkVersion;
+
+      sdk = pkgs.darwin."apple_sdk_${lib.replaceStrings [ "." ] [ "_" ] darwinSdkVersion}";
+
+      isSDKFramework = pkg: lib.hasPrefix "apple-framework-" (lib.getName pkg);
+
+      replacePropagatedFrameworks = pkg:
+        let
+          propagatedFrameworks = lib.filter isSDKFramework pkg.propagatedBuildInputs;
+          env = {
+            inherit (pkg) outputs;
+            # Map the old frameworks to new and the package’s outputs to their original outPaths.
+            # The mappings are rendered into tab-separated files to be read back with `read`.
+            frameworks = lib.concatMapStrings (pkg: "${pkg}\t${mapPackageToSDK pkg}\n") propagatedFrameworks;
+            pkgOutputs = lib.concatMapStrings (output: "${output}\t${(lib.getOutput output pkg).outPath}\n") pkg.outputs;
+            passAsFile = [ "frameworks" "pkgOutputs" ];
+          };
+        in
+        if lib.length propagatedFrameworks > 0
+          then pkgs.runCommand pkg.name env ''
+            # Iterate over the outputs in the package being replaced to make sure the proxy is
+            # a fully functional replacement. This is like `symlinkJoin` except for outputs and
+            # the contents of `nix-support`, which will be customized for the requested SDK.
+            while IFS=$'\t\n' read -r outputName pkgOutputPath; do
+              mkdir -p "''${!outputName}"
+
+              for targetPath in "$pkgOutputPath"/*; do
+                targetName=$(basename "$targetPath")
+
+                # `nix-support` is special-cased because any propagated inputs need their SDK
+                # frameworks replaced with those from the requested SDK.
+                if [ "$targetName" == "nix-support" ]; then
+                  mkdir "''${!outputName}/nix-support"
+
+                  for file in "$targetPath"/*; do
+                    fileName=$(basename "$file")
+
+                    if [ "$fileName" == "propagated-build-inputs" ]; then
+                      cp "$file" "''${!outputName}/nix-support/$fileName"
+
+                      while IFS=$'\t\n' read -r oldFramework newFramework; do
+                        substituteInPlace "''${!outputName}/nix-support/$fileName" \
+                          --replace "$oldFramework" "$newFramework"
+                      done < "$frameworksPath"
+                    fi
+                  done
+                else
+                  ln -s "$targetPath" "''${!outputName}/$targetName"
+                fi
+              done
+            done < "$pkgOutputsPath"
+          ''
+        else pkg;
+
+      # Remap a framework from one SDK version to another.
+      mapPackageToSDK = pkg:
+        let
+          name = lib.getName pkg;
+          framework = lib.removePrefix "apple-framework-" name;
+        in
+        if isSDKFramework pkg
+          then sdk.frameworks."${framework}"
+          else replacePropagatedFrameworks pkg;
+
+      mapInputsToSDK = inputs: args:
+        lib.genAttrs inputs (input: map mapPackageToSDK (args."${input}" or [ ]));
+
+      mkCC = cc: cc.override {
+        bintools = cc.bintools.override { libc = sdk.Libsystem; };
+        libc = sdk.Libsystem;
+      };
+    in
+    # TODO: make this work across all input types and not just propagatedBuildInputs
+    stdenv.override (old: {
+      buildPlatform = old.buildPlatform // { inherit darwinMinVersion darwinSdkVersion; };
+      hostPlatform = old.hostPlatform // { inherit darwinMinVersion darwinSdkVersion; };
+      targetPlatform = old.targetPlatform // { inherit darwinMinVersion darwinSdkVersion; };
+
+      allowedRequisites = null;
+      cc = mkCC old.cc;
+
+      extraBuildInputs = [sdk.frameworks.CoreFoundation ];
+      mkDerivationFromStdenv = extendMkDerivationArgs old (mapInputsToSDK [
+        "buildInputs"
+      ]);
+    });
 }