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:
https://github.com/NixOS/nixpkgs/pull/205689#issuecomment-1366588238
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.