From 8dad51a2e27d49db65d51277e57af595792e6613 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Tue, 12 Mar 2024 18:16:56 +0100 Subject: [PATCH] make-derivation.nix: Split makeDerivationArgument, mkDerivation with duplicate functionality --- pkgs/build-support/lib/cmake.nix | 30 +++++++++ pkgs/build-support/lib/meson.nix | 35 ++++++++++ pkgs/stdenv/generic/make-derivation.nix | 89 ++++++++++++++++++++++++- 3 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 pkgs/build-support/lib/cmake.nix create mode 100644 pkgs/build-support/lib/meson.nix diff --git a/pkgs/build-support/lib/cmake.nix b/pkgs/build-support/lib/cmake.nix new file mode 100644 index 000000000000..eff7bbca61a2 --- /dev/null +++ b/pkgs/build-support/lib/cmake.nix @@ -0,0 +1,30 @@ +{ stdenv, lib }: + +let + inherit (lib) findFirst isString optional optionals; + + makeCMakeFlags = { cmakeFlags ? [], ... }: + cmakeFlags + ++ optionals (stdenv.hostPlatform != stdenv.buildPlatform) ([ + "-DCMAKE_SYSTEM_NAME=${findFirst isString "Generic" (optional (!stdenv.hostPlatform.isRedox) stdenv.hostPlatform.uname.system)}" + ] ++ optionals (stdenv.hostPlatform.uname.processor != null) [ + "-DCMAKE_SYSTEM_PROCESSOR=${stdenv.hostPlatform.uname.processor}" + ] ++ optionals (stdenv.hostPlatform.uname.release != null) [ + "-DCMAKE_SYSTEM_VERSION=${stdenv.hostPlatform.uname.release}" + ] ++ optionals (stdenv.hostPlatform.isDarwin) [ + "-DCMAKE_OSX_ARCHITECTURES=${stdenv.hostPlatform.darwinArch}" + ] ++ optionals (stdenv.buildPlatform.uname.system != null) [ + "-DCMAKE_HOST_SYSTEM_NAME=${stdenv.buildPlatform.uname.system}" + ] ++ optionals (stdenv.buildPlatform.uname.processor != null) [ + "-DCMAKE_HOST_SYSTEM_PROCESSOR=${stdenv.buildPlatform.uname.processor}" + ] ++ optionals (stdenv.buildPlatform.uname.release != null) [ + "-DCMAKE_HOST_SYSTEM_VERSION=${stdenv.buildPlatform.uname.release}" + ] ++ optionals (stdenv.buildPlatform.canExecute stdenv.hostPlatform) [ + "-DCMAKE_CROSSCOMPILING_EMULATOR=env" + ] ++ optionals stdenv.hostPlatform.isStatic [ + "-DCMAKE_LINK_SEARCH_START_STATIC=ON" + ]); +in +{ + inherit makeCMakeFlags; +} diff --git a/pkgs/build-support/lib/meson.nix b/pkgs/build-support/lib/meson.nix new file mode 100644 index 000000000000..395b573f8587 --- /dev/null +++ b/pkgs/build-support/lib/meson.nix @@ -0,0 +1,35 @@ +{ stdenv, lib }: + +let + inherit (lib) boolToString optionals; + + # See https://mesonbuild.com/Reference-tables.html#cpu-families + cpuFamily = platform: with platform; + /**/ if isAarch32 then "arm" + else if isx86_32 then "x86" + else platform.uname.processor; + + makeMesonFlags = { mesonFlags ? [], ... }: + let + crossFile = builtins.toFile "cross-file.conf" '' + [properties] + bindgen_clang_arguments = ['-target', '${stdenv.targetPlatform.config}'] + needs_exe_wrapper = ${boolToString (!stdenv.buildPlatform.canExecute stdenv.hostPlatform)} + + [host_machine] + system = '${stdenv.targetPlatform.parsed.kernel.name}' + cpu_family = '${cpuFamily stdenv.targetPlatform}' + cpu = '${stdenv.targetPlatform.parsed.cpu.name}' + endian = ${if stdenv.targetPlatform.isLittleEndian then "'little'" else "'big'"} + + [binaries] + llvm-config = 'llvm-config-native' + rust = ['rustc', '--target', '${stdenv.targetPlatform.rust.rustcTargetSpec}'] + ''; + crossFlags = optionals (stdenv.hostPlatform != stdenv.buildPlatform) [ "--cross-file=${crossFile}" ]; + in crossFlags ++ mesonFlags; + +in +{ + inherit makeMesonFlags; +} diff --git a/pkgs/stdenv/generic/make-derivation.nix b/pkgs/stdenv/generic/make-derivation.nix index 8d1dc6bdeab7..7a3521c5153c 100644 --- a/pkgs/stdenv/generic/make-derivation.nix +++ b/pkgs/stdenv/generic/make-derivation.nix @@ -40,6 +40,9 @@ let unique ; + inherit (import ../../build-support/lib/cmake.nix { inherit lib stdenv; }) makeCMakeFlags; + inherit (import ../../build-support/lib/meson.nix { inherit lib stdenv; }) makeMesonFlags; + mkDerivation = fnOrAttrs: if builtins.isFunction fnOrAttrs @@ -108,7 +111,7 @@ let makeDerivationExtensible (self: attrs // (if builtins.isFunction f0 || f0?__functor then f self attrs else f0))) attrs; - mkDerivationSimple = overrideAttrs: + makeDerivationArgument = # `mkDerivation` wraps the builtin `derivation` function to @@ -555,6 +558,90 @@ else let "The ‘env’ attribute set can only contain derivation, string, boolean or integer attributes. The ‘${n}’ attribute is of type ${builtins.typeOf v}."; v) env; +in + derivationArg; + +mkDerivationSimple = overrideAttrs: + +# `mkDerivation` wraps the builtin `derivation` function to +# produce derivations that use this stdenv and its shell. +# +# See also: +# +# * https://nixos.org/nixpkgs/manual/#sec-using-stdenv +# Details on how to use this mkDerivation function +# +# * https://nixos.org/manual/nix/stable/expressions/derivations.html#derivations +# Explanation about derivations in general +{ + +# Configure Phase + cmakeFlags ? [] +, mesonFlags ? [] + +, meta ? {} +, passthru ? {} +, pos ? # position used in error messages and for meta.position + (if attrs.meta.description or null != null + then builtins.unsafeGetAttrPos "description" attrs.meta + else if attrs.version or null != null + then builtins.unsafeGetAttrPos "version" attrs + else builtins.unsafeGetAttrPos "name" attrs) + +# Experimental. For simple packages mostly just works, +# but for anything complex, be prepared to debug if enabling. +, __structuredAttrs ? config.structuredAttrsByDefault or false + +, env ? { } + +, ... } @ attrs: + +# Policy on acceptable hash types in nixpkgs +assert attrs ? outputHash -> ( + let algo = + attrs.outputHashAlgo or (head (splitString "-" attrs.outputHash)); + in + if algo == "md5" then + throw "Rejected insecure ${algo} hash '${attrs.outputHash}'" + else + true +); + +let + envIsExportable = isAttrs env && !isDerivation env; + + derivationArg = makeDerivationArgument + (removeAttrs + attrs + (["meta" "passthru" "pos"] + ++ optional (__structuredAttrs || envIsExportable) "env" + ) + // optionalAttrs __structuredAttrs { env = checkedEnv; } + // { + cmakeFlags = makeCMakeFlags attrs; + mesonFlags = makeMesonFlags attrs; + }); + + meta = checkMeta.commonMeta { + inherit validity attrs pos; + references = attrs.nativeBuildInputs ++ attrs.buildInputs + ++ attrs.propagatedNativeBuildInputs ++ attrs.propagatedBuildInputs; + }; + validity = checkMeta.assertValidity { inherit meta attrs; }; + + checkedEnv = + let + overlappingNames = attrNames (builtins.intersectAttrs env derivationArg); + in + assert assertMsg envIsExportable + "When using structured attributes, `env` must be an attribute set of environment variables."; + assert assertMsg (overlappingNames == [ ]) + "The ‘env’ attribute set cannot contain any attributes passed to derivation. The following attributes are overlapping: ${concatStringsSep ", " overlappingNames}"; + mapAttrs + (n: v: assert assertMsg (isString v || isBool v || isInt v || isDerivation v) + "The ‘env’ attribute set can only contain derivation, string, boolean or integer attributes. The ‘${n}’ attribute is of type ${builtins.typeOf v}."; v) + env; + in extendDerivation