227 lines
6.7 KiB
Nix
227 lines
6.7 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.stdenv.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.stdenv.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.dontRecurseIntoAttrs (
|
|||
|
|
lib.mapAttrs (
|
|||
|
|
name: system:
|
|||
|
|
lib.recurseIntoAttrs (test rec {
|
|||
|
|
crossPkgs = import pkgs.path {
|
|||
|
|
localSystem = { inherit (pkgs.stdenv.hostPlatform) config; };
|
|||
|
|
crossSystem = crossSystemFun system;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
emulator = crossPkgs.stdenv.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.stdenv.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.stdenv.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"
|
|||
|
|
'';
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
# see https://github.com/NixOS/nixpkgs/issues/213453
|
|||
|
|
# this is a good test of a lot of tricky glibc/libgcc corner cases
|
|||
|
|
mbuffer =
|
|||
|
|
let
|
|||
|
|
mbuffer = pkgs.pkgsCross.aarch64-multiplatform.mbuffer;
|
|||
|
|
emulator = with lib.systems; (elaborate examples.aarch64-multiplatform).emulator pkgs;
|
|||
|
|
in
|
|||
|
|
pkgs.runCommand "test-mbuffer" { } ''
|
|||
|
|
echo hello | ${emulator} ${mbuffer}/bin/mbuffer
|
|||
|
|
touch $out
|
|||
|
|
'';
|
|||
|
|
|
|||
|
|
# This is meant to be a carefully curated list of builds/packages
|
|||
|
|
# that tend to break when refactoring our cross-compilation
|
|||
|
|
# infrastructure.
|
|||
|
|
#
|
|||
|
|
# It should strike a balance between being small enough to fit in
|
|||
|
|
# a single eval (i.e. not so large that hydra-eval-jobs is needed)
|
|||
|
|
# so we can ask @ofborg to check it, yet should have good examples
|
|||
|
|
# of things that often break. So, no buckshot `mapTestOnCross`
|
|||
|
|
# calls here.
|
|||
|
|
sanity = [
|
|||
|
|
mbuffer
|
|||
|
|
#pkgs.pkgsCross.gnu64.bash # https://github.com/NixOS/nixpkgs/issues/243164
|
|||
|
|
pkgs.gcc_multi.cc
|
|||
|
|
pkgs.pkgsMusl.stdenv
|
|||
|
|
pkgs.pkgsLLVM.stdenv
|
|||
|
|
pkgs.pkgsStatic.bash
|
|||
|
|
#pkgs.pkgsCross.gnu64_simplekernel.bash # https://github.com/NixOS/nixpkgs/issues/264989
|
|||
|
|
pkgs.pkgsCross.arm-embedded.stdenv
|
|||
|
|
pkgs.pkgsCross.sheevaplug.stdenv # for armv5tel
|
|||
|
|
pkgs.pkgsCross.raspberryPi.stdenv # for armv6l
|
|||
|
|
pkgs.pkgsCross.armv7l-hf-multiplatform.stdenv
|
|||
|
|
pkgs.pkgsCross.m68k.stdenv
|
|||
|
|
pkgs.pkgsCross.aarch64-multiplatform.pkgsBuildTarget.gcc
|
|||
|
|
pkgs.pkgsCross.powernv.pkgsBuildTarget.gcc
|
|||
|
|
pkgs.pkgsCross.s390.stdenv
|
|||
|
|
pkgs.pkgsCross.mips64el-linux-gnuabi64.stdenv
|
|||
|
|
pkgs.pkgsCross.mips64el-linux-gnuabin32.stdenv
|
|||
|
|
pkgs.pkgsCross.mingwW64.stdenv
|
|||
|
|
# Uses the expression that is used by the most cross-compiled GHCs
|
|||
|
|
pkgs.pkgsCross.riscv64.haskell.compiler.native-bignum.ghc948
|
|||
|
|
|
|||
|
|
]
|
|||
|
|
++ lib.optionals (with pkgs.stdenv.buildPlatform; isx86_64 && isLinux) [
|
|||
|
|
# Musl-to-glibc cross on the same architecture tends to turn up
|
|||
|
|
# lots of interesting corner cases. Only expected to work for
|
|||
|
|
# x86_64-linux buildPlatform.
|
|||
|
|
pkgs.pkgsMusl.pkgsCross.gnu64.hello
|
|||
|
|
|
|||
|
|
# Two web browsers -- exercises almost the entire packageset
|
|||
|
|
pkgs.pkgsCross.aarch64-multiplatform.qutebrowser
|
|||
|
|
pkgs.pkgsCross.aarch64-multiplatform.firefox
|
|||
|
|
|
|||
|
|
# Uses pkgsCross.riscv64-embedded; see https://github.com/NixOS/nixpkgs/issues/267859
|
|||
|
|
pkgs.spike
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
in
|
|||
|
|
{
|
|||
|
|
gcc = lib.recurseIntoAttrs (
|
|||
|
|
lib.mapAttrs (_: mapMultiPlatformTest (system: system // { useLLVM = false; })) tests
|
|||
|
|
);
|
|||
|
|
llvm = lib.recurseIntoAttrs (
|
|||
|
|
lib.mapAttrs (_: mapMultiPlatformTest (system: system // { useLLVM = true; })) tests
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
inherit mbuffer sanity;
|
|||
|
|
}
|