at 23.11-beta 169 lines 6.0 kB view raw
1{ pkgs, lib }: 2 3let 4 5 testedSystems = lib.filterAttrs (name: value: let 6 platform = lib.systems.elaborate value; 7 in platform.isLinux || platform.isWindows 8 ) lib.systems.examples; 9 10 getExecutable = pkgs: pkgFun: exec: 11 "${pkgFun pkgs}${exec}${pkgs.stdenv.hostPlatform.extensions.executable}"; 12 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 22 23 HOME=$(pwd) 24 mkdir -p $out 25 26 # We need to remove whitespace, unfortunately 27 # Windows programs use \r but Unix programs use \n 28 29 echo Running native-built program natively 30 31 # find expected value natively 32 ${getExecutable hostPkgs pkgFun exec} ${args'} \ 33 | dos2unix > $out/expected 34 35 echo Running cross-built program in emulator 36 37 # run emulator to get actual value 38 ${emulator} ${getExecutable crossPkgs pkgFun exec} ${args'} \ 39 | dos2unix > $out/actual 40 41 echo Comparing results... 42 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 ''; 55 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 }; 61 62 emulator = crossPkgs.stdenv.hostPlatform.emulator pkgs; 63 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; 73 74 tests = { 75 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 }; 86 87 hello = {platformFun, crossPkgs, emulator}: compareTest { 88 inherit emulator crossPkgs; 89 hostPkgs = pkgs; 90 exec = "/bin/hello"; 91 pkgFun = pkgs: pkgs.hello; 92 }; 93 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 }; 109 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 ''; 120 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 150 ] ++ lib.optionals (with pkgs.stdenv.buildPlatform; isx86_64 && isLinux) [ 151 # Musl-to-glibc cross on the same architecture tends to turn up 152 # lots of interesting corner cases. Only expected to work for 153 # x86_64-linux buildPlatform. 154 pkgs.pkgsMusl.pkgsCross.gnu64.hello 155 156 # Two web browsers -- exercises almost the entire packageset 157 pkgs.pkgsCross.aarch64-multiplatform.qt5.qutebrowser 158 pkgs.pkgsCross.aarch64-multiplatform.firefox 159 160 # Uses pkgsCross.riscv64-embedded; see https://github.com/NixOS/nixpkgs/issues/267859 161 pkgs.spike 162 ]; 163 164in { 165 gcc = (lib.mapAttrs (_: mapMultiPlatformTest (system: system // {useLLVM = false;})) tests); 166 llvm = (lib.mapAttrs (_: mapMultiPlatformTest (system: system // {useLLVM = true;})) tests); 167 168 inherit mbuffer sanity; 169}