114 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			114 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
| { pkgs, lib }:
 | ||
| 
 | ||
| let
 | ||
| 
 | ||
|   testedSystems = lib.filterAttrs (name: value: let
 | ||
|     platform = lib.systems.elaborate value;
 | ||
|   in platform.isLinux || platform.isWindows
 | ||
|   ) lib.systems.examples;
 | ||
| 
 | ||
|   getExecutable = pkgs: pkgFun: exec:
 | ||
|     "${pkgFun pkgs}${exec}${pkgs.hostPlatform.extensions.executable}";
 | ||
| 
 | ||
|   compareTest = { emulator, pkgFun, hostPkgs, crossPkgs, exec, args ? [] }: let
 | ||
|     pkgName = (pkgFun hostPkgs).name;
 | ||
|     args' = lib.concatStringsSep " " args;
 | ||
|   in crossPkgs.runCommand "test-${pkgName}-${crossPkgs.hostPlatform.config}" {
 | ||
|     nativeBuildInputs = [ pkgs.dos2unix ];
 | ||
|   } ''
 | ||
|     # Just in case we are using wine, get rid of that annoying extra
 | ||
|     # stuff.
 | ||
|     export WINEDEBUG=-all
 | ||
| 
 | ||
|     HOME=$(pwd)
 | ||
|     mkdir -p $out
 | ||
| 
 | ||
|     # We need to remove whitespace, unfortunately
 | ||
|     # Windows programs use \r but Unix programs use \n
 | ||
| 
 | ||
|     echo Running native-built program natively
 | ||
| 
 | ||
|     # find expected value natively
 | ||
|     ${getExecutable hostPkgs pkgFun exec} ${args'} \
 | ||
|       | dos2unix > $out/expected
 | ||
| 
 | ||
|     echo Running cross-built program in emulator
 | ||
| 
 | ||
|     # run emulator to get actual value
 | ||
|     ${emulator} ${getExecutable crossPkgs pkgFun exec} ${args'} \
 | ||
|       | dos2unix > $out/actual
 | ||
| 
 | ||
|     echo Comparing results...
 | ||
| 
 | ||
|     if [ "$(cat $out/actual)" != "$(cat $out/expected)" ]; then
 | ||
|       echo "${pkgName} did not output expected value:"
 | ||
|       cat $out/expected
 | ||
|       echo "instead it output:"
 | ||
|       cat $out/actual
 | ||
|       exit 1
 | ||
|     else
 | ||
|       echo "${pkgName} test passed"
 | ||
|       echo "both produced output:"
 | ||
|       cat $out/actual
 | ||
|     fi
 | ||
|   '';
 | ||
| 
 | ||
|   mapMultiPlatformTest = crossSystemFun: test: lib.mapAttrs (name: system: test rec {
 | ||
|     crossPkgs = import pkgs.path {
 | ||
|       localSystem = { inherit (pkgs.hostPlatform) config; };
 | ||
|       crossSystem = crossSystemFun system;
 | ||
|     };
 | ||
| 
 | ||
|     emulator = crossPkgs.hostPlatform.emulator pkgs;
 | ||
| 
 | ||
|     # Apply some transformation on windows to get dlls in the right
 | ||
|     # place. Unfortunately mingw doesn’t seem to be able to do linking
 | ||
|     # properly.
 | ||
|     platformFun = pkg: if crossPkgs.hostPlatform.isWindows then
 | ||
|       pkgs.buildEnv {
 | ||
|         name = "${pkg.name}-winlinks";
 | ||
|         paths = [pkg] ++ pkg.buildInputs;
 | ||
|       } else pkg;
 | ||
|   }) testedSystems;
 | ||
| 
 | ||
|   tests = {
 | ||
| 
 | ||
|     file = {platformFun, crossPkgs, emulator}: compareTest {
 | ||
|       inherit emulator crossPkgs;
 | ||
|       hostPkgs = pkgs;
 | ||
|       exec = "/bin/file";
 | ||
|       args = [
 | ||
|         "${pkgs.file}/share/man/man1/file.1.gz"
 | ||
|         "${pkgs.dejavu_fonts}/share/fonts/truetype/DejaVuMathTeXGyre.ttf"
 | ||
|       ];
 | ||
|       pkgFun = pkgs: platformFun pkgs.file;
 | ||
|     };
 | ||
| 
 | ||
|     hello = {platformFun, crossPkgs, emulator}: compareTest {
 | ||
|       inherit emulator crossPkgs;
 | ||
|       hostPkgs = pkgs;
 | ||
|       exec = "/bin/hello";
 | ||
|       pkgFun = pkgs: pkgs.hello;
 | ||
|     };
 | ||
| 
 | ||
|     pkg-config = {platformFun, crossPkgs, emulator}: crossPkgs.runCommand
 | ||
|       "test-pkg-config-${crossPkgs.hostPlatform.config}"
 | ||
|     {
 | ||
|       depsBuildBuild = [ crossPkgs.pkgsBuildBuild.pkg-config ];
 | ||
|       nativeBuildInputs = [ crossPkgs.pkgsBuildHost.pkg-config crossPkgs.buildPackages.zlib ];
 | ||
|       depsBuildTarget = [ crossPkgs.pkgsBuildTarget.pkg-config ];
 | ||
|       buildInputs = [ crossPkgs.zlib ];
 | ||
|       NIX_DEBUG = 7;
 | ||
|     } ''
 | ||
|        mkdir $out
 | ||
|        ${crossPkgs.pkgsBuildBuild.pkg-config.targetPrefix}pkg-config --cflags zlib > "$out/for-build"
 | ||
|        ${crossPkgs.pkgsBuildHost.pkg-config.targetPrefix}pkg-config --cflags zlib > "$out/for-host"
 | ||
|        ! diff "$out/for-build" "$out/for-host"
 | ||
|     '';
 | ||
|   };
 | ||
| 
 | ||
| in {
 | ||
|   gcc = (lib.mapAttrs (_: mapMultiPlatformTest (system: system // {useLLVM = false;})) tests);
 | ||
|   llvm = (lib.mapAttrs (_: mapMultiPlatformTest (system: system // {useLLVM = true;})) tests);
 | ||
| }
 | 
