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