2018-11-13 23:54:08 +01:00
|
|
|
|
{ pkgs, lib }:
|
2018-07-21 04:43:55 +02:00
|
|
|
|
|
|
|
|
|
let
|
|
|
|
|
|
2018-11-13 23:54:08 +01:00
|
|
|
|
testedSystems = lib.filterAttrs (name: value: let
|
|
|
|
|
platform = lib.systems.elaborate value;
|
|
|
|
|
in platform.isLinux || platform.isWindows
|
|
|
|
|
) lib.systems.examples;
|
2018-07-21 04:43:55 +02:00
|
|
|
|
|
|
|
|
|
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 pkgs.runCommand "test-${pkgName}-${crossPkgs.hostPlatform.config}" {
|
|
|
|
|
nativeBuildInputs = [ pkgs.dos2unix ];
|
|
|
|
|
} ''
|
2018-11-13 23:54:08 +01:00
|
|
|
|
# Just in case we are using wine, get rid of that annoying extra
|
|
|
|
|
# stuff.
|
|
|
|
|
export WINEDEBUG=-all
|
|
|
|
|
|
2018-07-21 04:43:55 +02:00
|
|
|
|
HOME=$(pwd)
|
|
|
|
|
mkdir -p $out
|
|
|
|
|
|
|
|
|
|
# We need to remove whitespace, unfortunately
|
|
|
|
|
# Windows programs use \r but Unix programs use \n
|
|
|
|
|
|
2019-02-14 07:17:10 +01:00
|
|
|
|
echo Running native-built program natively
|
|
|
|
|
|
2018-07-21 04:43:55 +02:00
|
|
|
|
# find expected value natively
|
|
|
|
|
${getExecutable hostPkgs pkgFun exec} ${args'} \
|
|
|
|
|
| dos2unix > $out/expected
|
|
|
|
|
|
2019-02-14 07:17:10 +01:00
|
|
|
|
echo Running cross-built program in emulator
|
|
|
|
|
|
2018-07-21 04:43:55 +02:00
|
|
|
|
# run emulator to get actual value
|
|
|
|
|
${emulator} ${getExecutable crossPkgs pkgFun exec} ${args'} \
|
|
|
|
|
| dos2unix > $out/actual
|
|
|
|
|
|
2019-02-14 07:17:10 +01:00
|
|
|
|
echo Comparing results...
|
|
|
|
|
|
2018-07-21 04:43:55 +02:00
|
|
|
|
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
|
|
|
|
|
'';
|
|
|
|
|
|
2019-02-26 04:54:40 +01:00
|
|
|
|
mapMultiPlatformTest = crossSystemFun: test: lib.mapAttrs (name: system: test rec {
|
2018-11-13 23:54:08 +01:00
|
|
|
|
crossPkgs = import pkgs.path {
|
|
|
|
|
localSystem = { inherit (pkgs.hostPlatform) config; };
|
2019-02-26 04:54:40 +01:00
|
|
|
|
crossSystem = crossSystemFun system;
|
2018-11-13 23:54:08 +01:00
|
|
|
|
};
|
2018-07-21 04:43:55 +02:00
|
|
|
|
|
2018-11-13 23:54:08 +01:00
|
|
|
|
emulator = crossPkgs.hostPlatform.emulator pkgs;
|
2018-07-21 04:43:55 +02:00
|
|
|
|
|
2018-11-13 23:54:08 +01:00
|
|
|
|
# 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;
|
2018-07-21 04:43:55 +02:00
|
|
|
|
|
2019-02-26 04:54:40 +01:00
|
|
|
|
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;
|
|
|
|
|
};
|
2018-07-21 04:43:55 +02:00
|
|
|
|
|
2019-02-26 04:54:40 +01:00
|
|
|
|
hello = {platformFun, crossPkgs, emulator}: compareTest {
|
|
|
|
|
inherit emulator crossPkgs;
|
|
|
|
|
hostPkgs = pkgs;
|
|
|
|
|
exec = "/bin/hello";
|
|
|
|
|
pkgFun = pkgs: pkgs.hello;
|
|
|
|
|
};
|
2018-07-21 04:43:55 +02:00
|
|
|
|
|
2018-11-13 23:54:08 +01:00
|
|
|
|
};
|
|
|
|
|
|
2019-01-30 03:01:24 +01:00
|
|
|
|
in {
|
|
|
|
|
gcc = (lib.mapAttrs (_: mapMultiPlatformTest (system: system // {useLLVM = false;})) tests);
|
|
|
|
|
llvm = (lib.mapAttrs (_: mapMultiPlatformTest (system: system // {useLLVM = true;})) tests);
|
|
|
|
|
}
|