Skip to content

Commit

Permalink
macos: fix issues with macOS SDKs
Browse files Browse the repository at this point in the history
- Remove the default SDK from stdenv.
  This is currently not easy to do.
- Ensure users can set their own SDK if necessary via `packages`.
  • Loading branch information
sandydoo committed Jan 24, 2025
1 parent 68a6d54 commit 6ad5630
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 12 deletions.
45 changes: 33 additions & 12 deletions src/modules/top-level.nix
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,17 @@ in
stdenv = lib.mkOption {
type = types.package;
description = "The stdenv to use for the developer environment.";
default = pkgs.stdenv;
default =
if pkgs.stdenv.isDarwin
then
pkgs.stdenv.override
(prev: {
# Remove the default apple-sdk on macOS.
# Prefer to expose the system SDK, or let the user specify the SDK in `packages`.
extraBuildInputs =
builtins.filter (x: !lib.hasPrefix "apple-sdk" x.pname) prev.extraBuildInputs;
})
else pkgs.stdenv;
defaultText = lib.literalExpression "pkgs.stdenv";
};

Expand Down Expand Up @@ -297,17 +307,28 @@ in
ln -snf ${lib.escapeShellArg config.devenv.runtime} ${lib.escapeShellArg config.devenv.dotfile}/run
'';

shell = performAssertions (
(pkgs.mkShell.override { stdenv = config.stdenv; }) ({
hardeningDisable = config.hardeningDisable;
name = "devenv-shell";
packages = config.packages;
shellHook = ''
${lib.optionalString config.devenv.debug "set -x"}
${config.enterShell}
'';
} // config.env)
);
shell =
let
# `mkShell` merges `packages` into `nativeBuildInputs`.
# This distinction is generally not important for devShells, except when it comes to setup hooks and their run order.
# On macOS, the default apple-sdk is added the stdenv via `extraBuildInputs`.
# If we don't remove it from stdenv, then it's setup hooks will clobber any SDK added to `packages`.
isAppleSDK = pkg: builtins.match ".*apple-sdk.*" (pkg.pname or "") != null;
partitionedPkgs = builtins.partition isAppleSDK config.packages;
buildInputs = partitionedPkgs.right;
nativeBuildInputs = partitionedPkgs.wrong;
in
performAssertions (
(pkgs.mkShell.override { stdenv = config.stdenv; }) ({
name = "devenv-shell";
hardeningDisable = config.hardeningDisable;
inherit buildInputs nativeBuildInputs;
shellHook = ''
${lib.optionalString config.devenv.debug "set -x"}
${config.enterShell}
'';
} // config.env)
);

infoSections."env" = lib.mapAttrsToList (name: value: "${name}: ${toString value}") config.env;
infoSections."packages" = builtins.map (package: package.name) (builtins.filter (package: !(builtins.elem package.name (builtins.attrNames config.scripts))) config.packages);
Expand Down
15 changes: 15 additions & 0 deletions tests/macos-custom-apple-sdk/devenv.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{ pkgs, ... }:

{
packages = [ pkgs.apple-sdk ];

# Test that the above SDK is picked up by xcode-select.
enterTest = ''
if [ -v "$DEVELOPER_DIR" ]; then
echo "DEVELOPER_DIR is not set."
exit 1
fi
xcode-select -p | grep -q /nix/store
'';
}
18 changes: 18 additions & 0 deletions tests/macos-no-default-sdk/devenv.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
# Test that there is no default SDK set on macOS.
enterTest = ''
variables_to_check=(
"DEVELOPER_DIR"
"DEVELOPER_DIR_FOR_BUILD"
"SDKROOT"
"NIX_APPLE_SDK_VERSION"
)
for var in "''${variables_to_check[@]}"; do
if [ -v "$var" ]; then
echo "$var is set. Expected no default Apple SDK." >&2
exit 1
fi
done
'';
}

0 comments on commit 6ad5630

Please sign in to comment.