From 63bd851e9554cdb1bd703a461443723fd057933d Mon Sep 17 00:00:00 2001 From: John Ericson Date: Sun, 24 Nov 2019 23:07:20 +0000 Subject: stdenv: Introduce hasCC attribute Before, we'd always use `cc = null`, and check for that. The problem is this breaks for cross compilation to platforms that don't support a C compiler. It's a very subtle issue. One might think there is no problem because we have `stdenvNoCC`, and presumably one would only build derivations that use that. The problem is that one still wants to use tools at build-time that are themselves built with a C compiler, and those are gotten via "splicing". The runtime version of those deps will explode, but the build time / `buildPackages` versions of those deps will be fine, and splicing attempts to work this by using `builtins.tryEval` to filter out any broken "higher priority" packages (runtime is the default and highest priority) so that both `foo` and `foo.nativeDrv` works. However, `tryEval` only catches certain evaluation failures (e.g. exceptions), and not arbitrary failures (such as `cc.attr` when `cc` is null). This means `tryEval` fails to let us use our build time deps, and everything comes apart. The right solution is, as usually, to get rid of splicing. Or, baring that, to make it so `foo` never works and one has to explicitly do `foo.*`. But that is a much larger change, and certaily one unsuitable to be backported to stable. Given that, we instead make an exception-throwing `cc` attribute, and create a `hasCC` attribute for those derivations which wish to condtionally use a C compiler: instead of doing `stdenv.cc or null == null` or something similar, one does `stdenv.hasCC`. This allows quering without "tripping" the exception, while also allowing `tryEval` to work. No platform without a C compiler is yet wired up by default. That will be done in a following commit. --- pkgs/stdenv/generic/default.nix | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'pkgs/stdenv') diff --git a/pkgs/stdenv/generic/default.nix b/pkgs/stdenv/generic/default.nix index 2f43db9cfc2..befeb450997 100644 --- a/pkgs/stdenv/generic/default.nix +++ b/pkgs/stdenv/generic/default.nix @@ -1,6 +1,15 @@ let lib = import ../../../lib; in lib.makeOverridable ( -{ name ? "stdenv", preHook ? "", initialPath, cc, shell +{ name ? "stdenv", preHook ? "", initialPath + +, # If we don't have a C compiler, we might either have `cc = null` or `cc = + # throw ...`, but if we do have a C compiler we should definiely have `cc != + # null`. + # + # TODO(@Ericson2314): Add assert without creating infinite recursion + hasCC ? cc != null, cc + +, shell , allowedRequisites ? null, extraAttrs ? {}, overrides ? (self: super: {}), config , # The `fetchurl' to use for downloading curl and its dependencies @@ -57,7 +66,8 @@ let ../../build-support/setup-hooks/move-sbin.sh ../../build-support/setup-hooks/move-lib64.sh ../../build-support/setup-hooks/set-source-date-epoch-to-latest.sh - cc + # TODO use lib.optional instead + (if hasCC then cc else null) ]; defaultBuildInputs = extraBuildInputs; @@ -145,7 +155,7 @@ let inherit overrides; - inherit cc; + inherit cc hasCC; } # Propagate any extra attributes. For instance, we use this to -- cgit 1.4.1 From c739c420db5b9d56c335414be1696c57f2dbbb6a Mon Sep 17 00:00:00 2001 From: John Ericson Date: Sun, 24 Nov 2019 23:07:20 +0000 Subject: Add support for cross compiling to `js-ghcjs` This platform doesn't have a C compiler, and so relies and the changes in the previous commit to work. --- lib/systems/doubles.nix | 2 ++ pkgs/stdenv/booter.nix | 9 ++++++--- pkgs/stdenv/cross/default.nix | 8 +++++++- 3 files changed, 15 insertions(+), 4 deletions(-) (limited to 'pkgs/stdenv') diff --git a/lib/systems/doubles.nix b/lib/systems/doubles.nix index 58cff18e648..f07e9da33bc 100644 --- a/lib/systems/doubles.nix +++ b/lib/systems/doubles.nix @@ -27,6 +27,8 @@ let "riscv32-linux" "riscv64-linux" "aarch64-none" "avr-none" "arm-none" "i686-none" "x86_64-none" "powerpc-none" "msp430-none" "riscv64-none" "riscv32-none" + + "js-ghcjs" ]; allParsed = map parse.mkSystemFromString all; diff --git a/pkgs/stdenv/booter.nix b/pkgs/stdenv/booter.nix index 1df05099fbf..8a574652204 100644 --- a/pkgs/stdenv/booter.nix +++ b/pkgs/stdenv/booter.nix @@ -121,9 +121,12 @@ stageFuns: let postStage = buildPackages: { __raw = true; stdenv.cc = - if buildPackages.stdenv.cc.isClang or false - then buildPackages.clang - else buildPackages.gcc; + if buildPackages.stdenv.hasCC + then + if buildPackages.stdenv.cc.isClang or false + then buildPackages.clang + else buildPackages.gcc + else buildPackages.stdenv.cc; }; in dfold folder postStage (_: {}) withAllowCustomOverrides diff --git a/pkgs/stdenv/cross/default.nix b/pkgs/stdenv/cross/default.nix index 4e5c4cc2e83..44d412e041b 100644 --- a/pkgs/stdenv/cross/default.nix +++ b/pkgs/stdenv/cross/default.nix @@ -51,12 +51,18 @@ in lib.init bootStages ++ [ extraBuildInputs = [ ]; # Old ones run on wrong platform allowedRequisites = null; + hasCC = !targetPlatform.isGhcjs; + cc = if crossSystem.useiOSPrebuilt or false then buildPackages.darwin.iosSdkPkgs.clang else if crossSystem.useAndroidPrebuilt or false then buildPackages."androidndkPkgs_${crossSystem.ndkVer}".clang else if targetPlatform.isGhcjs - then null + # Need to use `throw` so tryEval for splicing works, ugh. Using + # `null` or skipping the attribute would cause an eval failure + # `tryEval` wouldn't catch, wrecking accessing previous stages + # when there is a C compiler and everything should be fine. + then throw "no C compile provided for this platform" else if crossSystem.useLLVM or false then buildPackages.llvmPackages_8.lldClang else buildPackages.gcc; -- cgit 1.4.1 From 87379637357f362abe47cc8a86fd7f2735f6180a Mon Sep 17 00:00:00 2001 From: John Ericson Date: Mon, 25 Nov 2019 14:09:50 +0000 Subject: Fix lib tests js-ghcjs didn't fit in an existing categor. --- pkgs/stdenv/cross/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'pkgs/stdenv') diff --git a/pkgs/stdenv/cross/default.nix b/pkgs/stdenv/cross/default.nix index 44d412e041b..cc49af7de3b 100644 --- a/pkgs/stdenv/cross/default.nix +++ b/pkgs/stdenv/cross/default.nix @@ -62,7 +62,7 @@ in lib.init bootStages ++ [ # `null` or skipping the attribute would cause an eval failure # `tryEval` wouldn't catch, wrecking accessing previous stages # when there is a C compiler and everything should be fine. - then throw "no C compile provided for this platform" + then throw "no C compiler provided for this platform" else if crossSystem.useLLVM or false then buildPackages.llvmPackages_8.lldClang else buildPackages.gcc; -- cgit 1.4.1 From 6078f094c638faabc63cffe285dc91af4e04a741 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Mon, 30 Dec 2019 18:09:45 -0500 Subject: pkgs/stdenv/booter.nix: Add comment explaining hasCC trickery --- pkgs/stdenv/booter.nix | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'pkgs/stdenv') diff --git a/pkgs/stdenv/booter.nix b/pkgs/stdenv/booter.nix index 8a574652204..51d617354e8 100644 --- a/pkgs/stdenv/booter.nix +++ b/pkgs/stdenv/booter.nix @@ -126,7 +126,11 @@ stageFuns: let if buildPackages.stdenv.cc.isClang or false then buildPackages.clang else buildPackages.gcc - else buildPackages.stdenv.cc; + else + # This will blow up if anything uses it, but that's OK. The `if + # buildPackages.stdenv.cc.isClang then ... else ...` would blow up + # everything, so we make sure to avoid that. + buildPackages.stdenv.cc; }; in dfold folder postStage (_: {}) withAllowCustomOverrides -- cgit 1.4.1