Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Can not run test applications in this cross environment" not consistent with meson.can_run_host_binaries() #13841

Open
smcv opened this issue Oct 30, 2024 · 2 comments · May be fixed by #13930

Comments

@smcv
Copy link
Contributor

smcv commented Oct 30, 2024

Describe the bug
Similar to #12017, when doing a native build in a Debian armhf chroot (32-bit arm-linux-gnueabihf with ARMv7 baseline) on an aarch64 machine, compiler.run() can fail with Can not run test applications in this cross environment, even though meson.can_run_host_binaries() previously returned true.

https://tests.reproducible-builds.org/debian/logs/unstable/armhf/accountsservice_23.13.9-7.build2.log.gz is an example of this causing a build failure during automated testing.

To Reproduce
In an armhf chroot/container on an an aarch64 machine, without using linux32 or similar personality wrapper:

project('foo', 'c')
if meson.is_cross_build()
    warning('cross build detected')
endif
if meson.can_run_host_binaries()
    meson.get_compiler('c').run('whatever')
endif

(Or set up the above with linux64 meson setup _build)

Workaround (1)
Set a personality so that the kernel pretends to be running on a 32-bit machine, for example:

linux32 meson setup _build

The 32-bit chroots on Debian porterboxes and official Debian buildds do this automatically, but it is not guaranteed, and in particular https://tests.reproducible-builds.org/debian does not guarantee to do so.

Workaround (2)

$ cat > workaround.txt <<EOF
[properties]
needs_exe_wrapper = false
EOF
$ meson setup --native-file workaround.txt _build

Expected behavior
I expected the sample project to configure successfully. (Obviously the invalid C code whatever fails to compile, but in this minimal reproducer that has no practical effect.)

It would also be understandable, although considerably less good, if meson.is_cross_build() returned true and meson.can_run_host_binaries() returned false.

system parameters

  • Is this a cross build or just a plain native build (for the same computer)? .. that depends on precisely how you define a cross build, but meson.is_cross_build() returns false
  • what operating system: Debian testing/unstable
  • what Python version: 3.12.5, 3.12.7
  • what meson --version: 1.5.1, 1.6.0
  • what ninja --version: setup fails before this becomes relevant
@smcv
Copy link
Contributor Author

smcv commented Oct 30, 2024

I don't think the equivalent of #12080 would be a correct fix for this in the case of aarch64 and arm, because most aarch64 CPUs support 32-bit ARM instructions, but unlike their equivalents in the x86 and mips worlds, that is not an architectural guarantee and according to Wikipedia, the ARM Cortex-A34 is an example of an aarch64-only CPU that is not backward compatible with 32-bit ARM instructions.

@smcv
Copy link
Contributor Author

smcv commented Oct 30, 2024

Another workaround for this issue is to use a --native-file containing:

[properties]
needs_exe_wrapper = false

Could Meson perhaps automatically behave as if needs_exe_wrapper = false whenever it is doing a native build?

smcv added a commit to smcv/meson that referenced this issue Nov 20, 2024
It is possible to run a container or chroot with one ABI on a CPU and
kernel that would normally have a different ABI, most commonly by
running a 32-bit container on a 64-bit CPU and kernel. When we do a
native build in such an environment, the build and host architectures
are both equal to the architecture of the container, and it is safe to
assume that we can run executables from that architecture, because if
we could not, we wouldn't be running Python successfully.

Until now, we have been handling this by adding explicit special cases
in `machine_info_can_run()`: every x86_64 can run x86 binaries, and
every mips64 is assumed to be able to run 32-bit mips binaries. However,
the equivalent would not be true on ARM systems: *most* aarch64 CPUs can
run arm binaries, but not all (according to Wikipedia, ARM Cortex-A34 is
an example of a purely 64-bit CPU that cannot execute 32-bit
instructions).

Instead, we can assume that if we are doing a native build (not a cross
build), by definition we can run build-architecture executables, and
since the host architecture is equal to the build architecture during
a native build, this implies that we can run host-architecture
executables too.

This makes the behaviour of `need_exe_wrapper()` consistent with
`meson.can_run_host_binaries()`, which in turn avoids `Compiler.run()`
failing with error message "Can not run test applications in this
cross environment during native builds.

Resolves: mesonbuild#13841
Signed-off-by: Simon McVittie <smcv@debian.org>
smcv added a commit to smcv/meson that referenced this issue Nov 20, 2024
It is possible to run a container or chroot with one ABI on a CPU and
kernel that would normally have a different ABI, most commonly by
running a 32-bit container on a 64-bit CPU and kernel. When we do a
native build in such an environment, the build and host architectures
are both equal to the architecture of the container, and it is safe to
assume that we can run executables from that architecture, because if
we could not, we wouldn't be running Python successfully.

Until now, we have been handling this by adding explicit special
cases in `machine_info_can_run()` for each known-good combination of
the detected CPU and the host architecture: every x86_64 can run x86
binaries, and every mips64 is assumed to be able to run 32-bit mips
binaries. However, the equivalent would not be true on ARM systems: *most*
aarch64 CPUs can run arm binaries, but not all (according to Wikipedia,
ARM Cortex-A34 is an example of a purely 64-bit CPU that cannot execute
32-bit instructions).

Instead, assume that if we are doing a native build (not a cross build),
by definition we can run build-architecture executables, and since the
host architecture is equal to the build architecture during a native
build, this implies that we can run host-architecture executables too.

This makes the behaviour of `need_exe_wrapper()` consistent with
`meson.can_run_host_binaries()`, which in turn avoids `Compiler.run()`
failing with error message "Can not run test applications
in this cross environment" during native builds even though
`meson.can_run_host_binaries()` has previously succeeded.

Resolves: mesonbuild#13841
Signed-off-by: Simon McVittie <smcv@debian.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant