Issues with checkInputs and cross-compilation

It seems to me that the current checkInputs has too coarse granularity when combined with cross-compilation. It does not differentiate between run time/host platform check inputs and build time/build platform check inputs, for example there are no checkNativeInputs and checkBuildInputs attributes.

I’m repeating mostly from the observations in this PR/comment:

If doCheck is true and the build platform can execute the host platform (link), checkInputs are added to nativeBuildInputs (link). When cross-compiling, the nativeBuildInputs are mapped to use the build platform’s packages, while buildInputs use the host platform’s.

pkgsStatic is implemented as cross-compilation (it uses musl instead of glibc) and the build platform (e.g. x86_64-linux) can execute the host platform (e.g. x86_64-unknown-linux-musl). This is a special case, as (so far) usually the build platform cannot run the host platform and it is no cross-compilation when it can (build == host platform, as for pkgs686Linux on x86_64-linux).

Consider for instance checkInputs = [ gtest ] and pkgsStatic:
gtest is added to nativeBuildInputs, which means that the build platform’s gtest is used in the end. The package being built, however, requires the host platform’s gtest to link against.

It is generally correct that nativeBuildInputs are mapped to the build platforms packages (e.g. cmake needs to be run on the build platform). But with checkInputs one cannot differentiate which dependency is needed for execution (nativeBuildInputs) and which for building (buildInputs).

How is this situation usually resolved? Is there a common workaound?

There are several packages in Nixpkgs that use gtest among their buildInputs. Maybe they are affected by the same issue. Adding to buildInputs resolves the splicing issue: gtest is taken from the host platform. Unfortunately, gtest is then also added to the runtime closure of the result (not always, but it is for pkgsStatic).

Another way is to doCheck = stdenv.buildPlatform == stdenv.hostPlatform, i.e. run the check phase only if not cross-compiling. However, this defeats the purpose of the canExecute check, i.e. tests are not run although it would technically be possible.

Fix in nativeCheckInputs by symphorien · Pull Request #206742 · NixOS/nixpkgs · GitHub

1 Like