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 ];
19 # Just in case we are using wine, get rid of that annoying extra
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:"
46 echo "instead it output:"
50 echo "${pkgName} test passed"
51 echo "both produced output:"
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;
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
67 platformFun = pkg: if crossPkgs.stdenv.hostPlatform.isWindows then
69 name = "${pkg.name}-winlinks";
70 paths = [pkg] ++ pkg.buildInputs;
76 file = {platformFun, crossPkgs, emulator}: compareTest {
77 inherit emulator crossPkgs;
81 "${pkgs.file}/share/man/man1/file.1.gz"
82 "${pkgs.dejavu_fonts}/share/fonts/truetype/DejaVuMathTeXGyre.ttf"
84 pkgFun = pkgs: platformFun pkgs.file;
87 hello = {platformFun, crossPkgs, emulator}: compareTest {
88 inherit emulator crossPkgs;
91 pkgFun = pkgs: pkgs.hello;
94 pkg-config = {platformFun, crossPkgs, emulator}: crossPkgs.runCommand
95 "test-pkg-config-${crossPkgs.stdenv.hostPlatform.config}"
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 ];
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"
110 # see https://github.com/NixOS/nixpkgs/issues/213453
111 # this is a good test of a lot of tricky glibc/libgcc corner cases
113 mbuffer = pkgs.pkgsCross.aarch64-multiplatform.mbuffer;
114 emulator = with lib.systems; (elaborate examples.aarch64-multiplatform).emulator pkgs;
116 pkgs.runCommand "test-mbuffer" {} ''
117 echo hello | ${emulator} ${mbuffer}/bin/mbuffer
121 # This is meant to be a carefully curated list of builds/packages
122 # that tend to break when refactoring our cross-compilation
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`
132 #pkgs.pkgsCross.gnu64.bash # https://github.com/NixOS/nixpkgs/issues/243164
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
167 gcc = (lib.mapAttrs (_: mapMultiPlatformTest (system: system // {useLLVM = false;})) tests);
168 llvm = (lib.mapAttrs (_: mapMultiPlatformTest (system: system // {useLLVM = true;})) tests);
170 inherit mbuffer sanity;