From 99e2ac1dbb3cf0ba130af6388c53579f52e133e7 Mon Sep 17 00:00:00 2001 From: Colin Date: Mon, 6 Mar 2023 11:20:24 +0000 Subject: [PATCH] cross compilation: push ccache into every build -> host package --- hosts/common/cross/default.nix | 59 ++++++++++++++++++++ nixpatches/2023-03-04-ccache-cross-fix.patch | 9 ++- overlays/optimizations.nix | 19 ++++--- 3 files changed, 76 insertions(+), 11 deletions(-) diff --git a/hosts/common/cross/default.nix b/hosts/common/cross/default.nix index 0fca46c5..7889ab3b 100644 --- a/hosts/common/cross/default.nix +++ b/hosts/common/cross/default.nix @@ -57,6 +57,7 @@ # """ # TODO: +# - fix firefox build so that it doesn't invoke clang w/o the ccache # - qt6.qtbase. cross compiling documented in upstream # - `nix build '.#host-pkgs.moby.qgnomeplatform-qt6'` FAILS # - `nix build '.#host-pkgs.moby.qt6Packages.qtwayland'` FAILS @@ -108,11 +109,13 @@ let (import ./../../../overlays/pins.nix) ] ++ crossOnlyUniversalOverlays; + # TODO: can we grab this more directly from pkgs? mkEmulated = pkgs: import pkgs.path { # system = pkgs.stdenv.hostPlatform.system; localSystem = pkgs.stdenv.hostPlatform.system; inherit (config.nixpkgs) config; + # config = builtins.removeAttrs config.nixpkgs.config [ "replaceStdenv" ]; overlays = universalOverlays; }; in @@ -187,10 +190,57 @@ in # Testutf8 # ; }); + # XXX: replaceStdenv only affects non-cross stages + # nixpkgs.config.replaceStdenv = { pkgs }: pkgs.ccacheStdenv; nixpkgs.overlays = crossOnlyUniversalOverlays ++ [ (next: prev: { emulated = mkEmulated prev; }) + + (next: prev: lib.optionalAttrs ( + # we want to affect only the final bootstrap stage, identified by: + # - buildPlatform = local, + # - targetPlatform = cross, + # - hostPlatform = cross + # and specifically in the event of `pkgsCross` sets -- e.g. the `pkgsCross.wasi32` used by firefox + # -- we want to *not* override the stdenv. it's theoretically possible, but doing so breaks firefox. + prev.stdenv.buildPlatform != prev.stdenv.hostPlatform && + prev.stdenv.hostPlatform == prev.stdenv.targetPlatform && + prev.stdenv.hostPlatform == config.nixpkgs.hostPlatform + ) { + # stdenv = prev.stdenv.override { + # cc = next.buildPackages.ccacheWrapper.overrideAttrs (orig: { + # passthru = orig.passthru // { + # # cc = orig.passthru.unwrappedCC; + # cc = prev.stdenv.cc.cc; + # }; + # # passthru = next.buildPackages.stdenv.cc.passthru // orig.passthru; + # }); + # # cc = prev.stdenv.__bootPackages.ccacheWrapper; + # }; + # stdenv = prev.stdenv.__bootPackages.ccacheStdenv; + # stdenv = prev.stdenv.override { + # cc = prev.buildPackages.ccacheWrapper; + # }; + + # XXX: stdenv.cc is the cc-wrapper, from . + # always the same. + # stdenv.cc.cc is either the real gcc (for buildPackages.stdenv), or the ccache (for normal stdenv). + stdenv = prev.stdenv.override { + cc = prev.stdenv.cc.override { + # cc = prev.buildPackages.ccacheWrapper; + cc = (prev.buildPackages.ccacheWrapper.override { + cc = prev.stdenv.cc; + }).overrideAttrs (_orig: { + # some things query stdenv.cc.cc.version, etc (rarely), so pass those through + passthru = prev.stdenv.cc.cc; + }); + }; + }; + # stdenv = prev.buildPackages.ccacheStdenv; + # stdenv = prev.ccacheStdenv.override { inherit (prev) stdenv; }; + }) + # (next: prev: # let # emulated = prev.emulated; @@ -1209,6 +1259,15 @@ in # fixes "Checking whether the C compiler works... no" inherit (emulated) stdenv; }; + samba = prev.samba.overrideAttrs (_upstream: { + # we get "cannot find C preprocessor: aarch64-unknown-linux-gnu-cpp", but ONLY when building with the ccache stdenv. + # this solves that, but `CPP` must be a *single* path -- not an expression. + # i do not understand how the original error arises, as my ccacheStdenv should match the API of the base stdenv (except for cpp being a symlink??). + # but oh well, this fixes it. + CPP = next.buildPackages.writeShellScript "cpp" '' + exec ${lib.getBin next.stdenv.cc}/bin/${next.stdenv.cc.targetPrefix}cc -E $@; + ''; + }); # sequoia = prev.sequoia.override { # # fails to fix original error # inherit (emulated) stdenv; diff --git a/nixpatches/2023-03-04-ccache-cross-fix.patch b/nixpatches/2023-03-04-ccache-cross-fix.patch index 5248d7c5..22c11560 100644 --- a/nixpatches/2023-03-04-ccache-cross-fix.patch +++ b/nixpatches/2023-03-04-ccache-cross-fix.patch @@ -20,7 +20,7 @@ index cad25a942d6..9130097ab07 100644 }) ]; -@@ -71,7 +71,7 @@ let ccache = stdenv.mkDerivation rec { +@@ -71,11 +71,12 @@ let ccache = stdenv.mkDerivation rec { passthru = { # A derivation that provides gcc and g++ commands, but that # will end up calling ccache for the given cacheDir @@ -29,7 +29,12 @@ index cad25a942d6..9130097ab07 100644 name = "ccache-links"; passthru = { isClang = unwrappedCC.isClang or false; -@@ -83,7 +83,7 @@ let ccache = stdenv.mkDerivation rec { + isGNU = unwrappedCC.isGNU or false; ++ cc = unwrappedCC; + }; + inherit (unwrappedCC) lib; + nativeBuildInputs = [ makeWrapper ]; +@@ -83,7 +84,7 @@ let ccache = stdenv.mkDerivation rec { mkdir -p $out/bin wrap() { diff --git a/overlays/optimizations.nix b/overlays/optimizations.nix index e143544f..cc966d2d 100644 --- a/overlays/optimizations.nix +++ b/overlays/optimizations.nix @@ -19,13 +19,14 @@ in { # firefox-esr = ccache-able super.firefox-esr; # firefox/librewolf distribution is wacky: it grabs the stdenv off of `rustc.llvmPackages`, and really wants those to match. # buildMozillaMach = opts: ccache-able (super.buildMozillaMach opts); - webkitgtk = ccache-able super.webkitgtk; - mesa = ccache-able super.mesa; - # webkitgtk = (ccache-able super.webkitgtk).overrideAttrs (_upstream: { - # # means we drop debug info when linking. - # # this is a trade-off to require less memory when linking, since - # # building `webkitgtk` otherwise requires about 40G+ of RAM. - # # - # separateDebugInfo = false; - # }); + # webkitgtk = ccache-able super.webkitgtk; + # mesa = ccache-able super.mesa; + + webkitgtk = super.webkitgtk.overrideAttrs (_upstream: { + # means we drop debug info when linking. + # this is a trade-off to require less memory when linking, since + # building `webkitgtk` otherwise requires about 40G+ of RAM. + # + separateDebugInfo = false; + }); })