splice.nix: improve performance with early cut-off
[NixPkgs.git] / pkgs / test / cross / default.nix
blobf07e9c6220de7be194b07bcc336dc7ea9e31c1e9
1 { pkgs, lib }:
3 let
5   testedSystems = lib.filterAttrs (name: value: let
6     platform = lib.systems.elaborate value;
7   in platform.isLinux || platform.isWindows
8   ) lib.systems.examples;
10   getExecutable = pkgs: pkgFun: exec:
11     "${pkgFun pkgs}${exec}${pkgs.stdenv.hostPlatform.extensions.executable}";
13   compareTest = { emulator, pkgFun, hostPkgs, crossPkgs, exec, args ? [] }: let
14     pkgName = (pkgFun hostPkgs).name;
15     args' = lib.concatStringsSep " " args;
16   in crossPkgs.runCommand "test-${pkgName}-${crossPkgs.stdenv.hostPlatform.config}" {
17     nativeBuildInputs = [ pkgs.dos2unix ];
18   } ''
19     # Just in case we are using wine, get rid of that annoying extra
20     # stuff.
21     export WINEDEBUG=-all
23     HOME=$(pwd)
24     mkdir -p $out
26     # We need to remove whitespace, unfortunately
27     # Windows programs use \r but Unix programs use \n
29     echo Running native-built program natively
31     # find expected value natively
32     ${getExecutable hostPkgs pkgFun exec} ${args'} \
33       | dos2unix > $out/expected
35     echo Running cross-built program in emulator
37     # run emulator to get actual value
38     ${emulator} ${getExecutable crossPkgs pkgFun exec} ${args'} \
39       | dos2unix > $out/actual
41     echo Comparing results...
43     if [ "$(cat $out/actual)" != "$(cat $out/expected)" ]; then
44       echo "${pkgName} did not output expected value:"
45       cat $out/expected
46       echo "instead it output:"
47       cat $out/actual
48       exit 1
49     else
50       echo "${pkgName} test passed"
51       echo "both produced output:"
52       cat $out/actual
53     fi
54   '';
56   mapMultiPlatformTest = crossSystemFun: test: lib.mapAttrs (name: system: test rec {
57     crossPkgs = import pkgs.path {
58       localSystem = { inherit (pkgs.stdenv.hostPlatform) config; };
59       crossSystem = crossSystemFun system;
60     };
62     emulator = crossPkgs.stdenv.hostPlatform.emulator pkgs;
64     # Apply some transformation on windows to get dlls in the right
65     # place. Unfortunately mingw doesn’t seem to be able to do linking
66     # properly.
67     platformFun = pkg: if crossPkgs.stdenv.hostPlatform.isWindows then
68       pkgs.buildEnv {
69         name = "${pkg.name}-winlinks";
70         paths = [pkg] ++ pkg.buildInputs;
71       } else pkg;
72   }) testedSystems;
74   tests = {
76     file = {platformFun, crossPkgs, emulator}: compareTest {
77       inherit emulator crossPkgs;
78       hostPkgs = pkgs;
79       exec = "/bin/file";
80       args = [
81         "${pkgs.file}/share/man/man1/file.1.gz"
82         "${pkgs.dejavu_fonts}/share/fonts/truetype/DejaVuMathTeXGyre.ttf"
83       ];
84       pkgFun = pkgs: platformFun pkgs.file;
85     };
87     hello = {platformFun, crossPkgs, emulator}: compareTest {
88       inherit emulator crossPkgs;
89       hostPkgs = pkgs;
90       exec = "/bin/hello";
91       pkgFun = pkgs: pkgs.hello;
92     };
94     pkg-config = {platformFun, crossPkgs, emulator}: crossPkgs.runCommand
95       "test-pkg-config-${crossPkgs.stdenv.hostPlatform.config}"
96     {
97       depsBuildBuild = [ crossPkgs.pkgsBuildBuild.pkg-config ];
98       nativeBuildInputs = [ crossPkgs.pkgsBuildHost.pkg-config crossPkgs.buildPackages.zlib ];
99       depsBuildTarget = [ crossPkgs.pkgsBuildTarget.pkg-config ];
100       buildInputs = [ crossPkgs.zlib ];
101       NIX_DEBUG = 7;
102     } ''
103        mkdir $out
104        ${crossPkgs.pkgsBuildBuild.pkg-config.targetPrefix}pkg-config --cflags zlib > "$out/for-build"
105        ${crossPkgs.pkgsBuildHost.pkg-config.targetPrefix}pkg-config --cflags zlib > "$out/for-host"
106        ! diff "$out/for-build" "$out/for-host"
107     '';
108   };
110   # see https://github.com/NixOS/nixpkgs/issues/213453
111   # this is a good test of a lot of tricky glibc/libgcc corner cases
112   mbuffer = let
113     mbuffer = pkgs.pkgsCross.aarch64-multiplatform.mbuffer;
114     emulator = with lib.systems; (elaborate examples.aarch64-multiplatform).emulator pkgs;
115   in
116     pkgs.runCommand "test-mbuffer" {} ''
117       echo hello | ${emulator} ${mbuffer}/bin/mbuffer
118       touch $out
119     '';
121   # This is meant to be a carefully curated list of builds/packages
122   # that tend to break when refactoring our cross-compilation
123   # infrastructure.
124   #
125   # It should strike a balance between being small enough to fit in
126   # a single eval (i.e. not so large that hydra-eval-jobs is needed)
127   # so we can ask @ofborg to check it, yet should have good examples
128   # of things that often break.  So, no buckshot `mapTestOnCross`
129   # calls here.
130   sanity = [
131     mbuffer
132     #pkgs.pkgsCross.gnu64.bash # https://github.com/NixOS/nixpkgs/issues/243164
133     pkgs.gcc_multi.cc
134     pkgs.pkgsMusl.stdenv
135     pkgs.pkgsLLVM.stdenv
136     pkgs.pkgsStatic.bash
137     #pkgs.pkgsCross.gnu64_simplekernel.bash   # https://github.com/NixOS/nixpkgs/issues/264989
138     pkgs.pkgsCross.arm-embedded.stdenv
139     pkgs.pkgsCross.sheevaplug.stdenv  # for armv5tel
140     pkgs.pkgsCross.raspberryPi.stdenv  # for armv6l
141     pkgs.pkgsCross.armv7l-hf-multiplatform.stdenv
142     pkgs.pkgsCross.m68k.stdenv
143     pkgs.pkgsCross.aarch64-multiplatform.pkgsBuildTarget.gcc
144     pkgs.pkgsCross.powernv.pkgsBuildTarget.gcc
145     pkgs.pkgsCross.s390.stdenv
146     pkgs.pkgsCross.mips64el-linux-gnuabi64.stdenv
147     pkgs.pkgsCross.mips64el-linux-gnuabin32.stdenv
148     pkgs.pkgsCross.mingwW64.stdenv
149     # Uses the expression that is used by the most cross-compil_ed_ GHCs
150     pkgs.pkgsCross.riscv64.haskell.compiler.native-bignum.ghc948
152   ] ++ lib.optionals (with pkgs.stdenv.buildPlatform; isx86_64 && isLinux) [
153     # Musl-to-glibc cross on the same architecture tends to turn up
154     # lots of interesting corner cases.  Only expected to work for
155     # x86_64-linux buildPlatform.
156     pkgs.pkgsMusl.pkgsCross.gnu64.hello
158     # Two web browsers -- exercises almost the entire packageset
159     pkgs.pkgsCross.aarch64-multiplatform.qutebrowser-qt5
160     pkgs.pkgsCross.aarch64-multiplatform.firefox
162     # Uses pkgsCross.riscv64-embedded; see https://github.com/NixOS/nixpkgs/issues/267859
163     pkgs.spike
164   ];
166 in {
167   gcc = (lib.mapAttrs (_: mapMultiPlatformTest (system: system // {useLLVM = false;})) tests);
168   llvm = (lib.mapAttrs (_: mapMultiPlatformTest (system: system // {useLLVM = true;})) tests);
170   inherit mbuffer sanity;