From 1a6496c9861be04d1f142318d8136ba65d224de9 Mon Sep 17 00:00:00 2001 From: Sander Date: Fri, 24 Jan 2025 19:52:40 +0400 Subject: [PATCH 1/7] macos: fix issues with macOS SDKs - Remove the default SDK from stdenv. This is currently not easy to do. - Ensure users can set their own SDK if necessary via `packages`. --- src/modules/top-level.nix | 45 ++++++++++++++++++------- tests/macos-custom-apple-sdk/devenv.nix | 15 +++++++++ tests/macos-no-default-sdk/devenv.nix | 18 ++++++++++ 3 files changed, 66 insertions(+), 12 deletions(-) create mode 100644 tests/macos-custom-apple-sdk/devenv.nix create mode 100644 tests/macos-no-default-sdk/devenv.nix diff --git a/src/modules/top-level.nix b/src/modules/top-level.nix index cc9a5732c..dab6f7c3b 100644 --- a/src/modules/top-level.nix +++ b/src/modules/top-level.nix @@ -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"; }; @@ -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); diff --git a/tests/macos-custom-apple-sdk/devenv.nix b/tests/macos-custom-apple-sdk/devenv.nix new file mode 100644 index 000000000..c2623cf69 --- /dev/null +++ b/tests/macos-custom-apple-sdk/devenv.nix @@ -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 + ''; +} diff --git a/tests/macos-no-default-sdk/devenv.nix b/tests/macos-no-default-sdk/devenv.nix new file mode 100644 index 000000000..9db111b13 --- /dev/null +++ b/tests/macos-no-default-sdk/devenv.nix @@ -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 + ''; +} From 88e417ac9d7025dcf8c3d607b4c33fdc385268dd Mon Sep 17 00:00:00 2001 From: Sander Date: Mon, 10 Mar 2025 22:16:42 +0100 Subject: [PATCH 2/7] apple: allow setting the sdk package --- src/modules/top-level.nix | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/modules/top-level.nix b/src/modules/top-level.nix index dab6f7c3b..5c8d6dbdf 100644 --- a/src/modules/top-level.nix +++ b/src/modules/top-level.nix @@ -75,7 +75,7 @@ in 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`. + # Allow users to specify an optional SDK in `apple.sdk`. extraBuildInputs = builtins.filter (x: !lib.hasPrefix "apple-sdk" x.pname) prev.extraBuildInputs; }) @@ -83,6 +83,19 @@ in defaultText = lib.literalExpression "pkgs.stdenv"; }; + apple = { + sdk = lib.mkOption { + type = types.nullOr types.package; + description = '' + The Apple SDK to use for the developer environment. + + If set to `null`, the system SDK will be used. + ''; + default = if pkgs.stdenv.isDarwin then pkgs.apple-sdk else null; + defaultText = lib.literalExpression "if pkgs.stdenv.isDarwin then pkgs.apple-sdk else null"; + }; + }; + unsetEnvVars = lib.mkOption { type = types.listOf types.str; description = "A list of removed environment variables to make the shell/direnv more lean."; @@ -268,7 +281,8 @@ in packages = [ # needed to make sure we can load libs pkgs.pkg-config - ]; + ] + ++ lib.optional (config.apple.sdk != null) config.apple.sdk; enterShell = lib.mkBefore '' export PS1="\[\e[0;34m\](devenv)\[\e[0m\] ''${PS1-}" @@ -311,8 +325,8 @@ in 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`. + # On macOS, the default apple-sdk is added to stdenv via `extraBuildInputs`. + # If we don't remove it from stdenv, then its 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; @@ -322,7 +336,8 @@ in (pkgs.mkShell.override { stdenv = config.stdenv; }) ({ name = "devenv-shell"; hardeningDisable = config.hardeningDisable; - inherit buildInputs nativeBuildInputs; + # inherit buildInputs nativeBuildInputs; + inherit (config) packages; shellHook = '' ${lib.optionalString config.devenv.debug "set -x"} ${config.enterShell} From 265bf05ff48cf4bb65fd8d02c9a1d0c7b0ea965c Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 10 Mar 2025 21:35:30 +0000 Subject: [PATCH 3/7] Auto generate docs/reference/options.md --- docs/reference/options.md | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/docs/reference/options.md b/docs/reference/options.md index 4a7be4f32..01636fa52 100644 --- a/docs/reference/options.md +++ b/docs/reference/options.md @@ -602,6 +602,29 @@ string +## apple.sdk + + + +The Apple SDK to use for the developer environment. + +If set to ` null `, the system SDK will be used. + + + +*Type:* +null or package + + + +*Default:* +` if pkgs.stdenv.isDarwin then pkgs.apple-sdk else null ` + +*Declared by:* + - [https://github.com/cachix/devenv/blob/main/src/modules/top-level.nix](https://github.com/cachix/devenv/blob/main/src/modules/top-level.nix) + + + ## aws-vault.enable @@ -2299,8 +2322,6 @@ list of (one of “commit-msg”, “post-checkout”, “post-commit”, “pos ## git-hooks.excludes - - Exclude files that were matched by these patterns. @@ -2320,6 +2341,8 @@ list of string ## git-hooks.gitPackage + + The ` git ` package to use. @@ -5136,8 +5159,6 @@ boolean ## git-hooks.hooks.autoflake.settings.binPath - - Path to autoflake binary. @@ -5161,6 +5182,8 @@ null or string ## git-hooks.hooks.autoflake.settings.flags + + Flags passed to autoflake. @@ -7009,8 +7032,6 @@ null or package ## git-hooks.hooks.clippy.packageOverrides.cargo - - The cargo package to use @@ -7025,6 +7046,8 @@ package ## git-hooks.hooks.clippy.packageOverrides.clippy + + The clippy package to use From e3371bb6b65743cbe939e0beb4de4202e9c5938a Mon Sep 17 00:00:00 2001 From: Sander Date: Mon, 10 Mar 2025 22:41:21 +0100 Subject: [PATCH 4/7] apple: fix sdk tests --- src/modules/top-level.nix | 3 +-- tests/macos-custom-apple-sdk/devenv.nix | 2 +- tests/macos-no-default-sdk/devenv.nix | 2 ++ 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/modules/top-level.nix b/src/modules/top-level.nix index 5c8d6dbdf..c49592925 100644 --- a/src/modules/top-level.nix +++ b/src/modules/top-level.nix @@ -336,8 +336,7 @@ in (pkgs.mkShell.override { stdenv = config.stdenv; }) ({ name = "devenv-shell"; hardeningDisable = config.hardeningDisable; - # inherit buildInputs nativeBuildInputs; - inherit (config) packages; + inherit buildInputs nativeBuildInputs; shellHook = '' ${lib.optionalString config.devenv.debug "set -x"} ${config.enterShell} diff --git a/tests/macos-custom-apple-sdk/devenv.nix b/tests/macos-custom-apple-sdk/devenv.nix index c2623cf69..082ccced7 100644 --- a/tests/macos-custom-apple-sdk/devenv.nix +++ b/tests/macos-custom-apple-sdk/devenv.nix @@ -1,7 +1,7 @@ { pkgs, ... }: { - packages = [ pkgs.apple-sdk ]; + apple.sdk = pkgs.apple-sdk; # Test that the above SDK is picked up by xcode-select. enterTest = '' diff --git a/tests/macos-no-default-sdk/devenv.nix b/tests/macos-no-default-sdk/devenv.nix index 9db111b13..ef8b797bd 100644 --- a/tests/macos-no-default-sdk/devenv.nix +++ b/tests/macos-no-default-sdk/devenv.nix @@ -1,4 +1,6 @@ { + apple.sdk = null; + # Test that there is no default SDK set on macOS. enterTest = '' variables_to_check=( From 1bca8041a731306d8dbadb4ee8844fe19b507fe8 Mon Sep 17 00:00:00 2001 From: Sander Date: Mon, 10 Mar 2025 22:47:16 +0100 Subject: [PATCH 5/7] apple: adjust docs --- src/modules/top-level.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/top-level.nix b/src/modules/top-level.nix index c49592925..9ac49065f 100644 --- a/src/modules/top-level.nix +++ b/src/modules/top-level.nix @@ -87,9 +87,9 @@ in sdk = lib.mkOption { type = types.nullOr types.package; description = '' - The Apple SDK to use for the developer environment. + The Apple SDK to add to the developer environment on macOS. - If set to `null`, the system SDK will be used. + If set to `null`, the system SDK can be used if the shell allows access to external environment variables. ''; default = if pkgs.stdenv.isDarwin then pkgs.apple-sdk else null; defaultText = lib.literalExpression "if pkgs.stdenv.isDarwin then pkgs.apple-sdk else null"; From 7b002ebec201fcb09bebefb0ee647cc0d24b5423 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 10 Mar 2025 21:51:23 +0000 Subject: [PATCH 6/7] Auto generate docs/reference/options.md --- docs/reference/options.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/reference/options.md b/docs/reference/options.md index 01636fa52..0b671f5e8 100644 --- a/docs/reference/options.md +++ b/docs/reference/options.md @@ -606,9 +606,9 @@ string -The Apple SDK to use for the developer environment. +The Apple SDK to add to the developer environment on macOS. -If set to ` null `, the system SDK will be used. +If set to ` null `, the system SDK can be used if the shell allows access to external environment variables. From 7d0c40b8193a2cbcee1aaba4f7715376a3e5c384 Mon Sep 17 00:00:00 2001 From: Sander Date: Tue, 11 Mar 2025 13:41:38 +0100 Subject: [PATCH 7/7] apple: apply the override to the stdenv --- src/modules/top-level.nix | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/modules/top-level.nix b/src/modules/top-level.nix index 9ac49065f..ecacfdeeb 100644 --- a/src/modules/top-level.nix +++ b/src/modules/top-level.nix @@ -69,18 +69,21 @@ in stdenv = lib.mkOption { type = types.package; description = "The stdenv to use for the developer environment."; - default = - if pkgs.stdenv.isDarwin + default = pkgs.stdenv; + defaultText = lib.literalExpression "pkgs.stdenv"; + + # Remove the default apple-sdk on macOS. + # Allow users to specify an optional SDK in `apple.sdk`. + apply = stdenv: + if stdenv.isDarwin then - pkgs.stdenv.override + stdenv.override (prev: { - # Remove the default apple-sdk on macOS. - # Allow users to specify an optional SDK in `apple.sdk`. extraBuildInputs = builtins.filter (x: !lib.hasPrefix "apple-sdk" x.pname) prev.extraBuildInputs; }) - else pkgs.stdenv; - defaultText = lib.literalExpression "pkgs.stdenv"; + else stdenv; + }; apple = {