You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
1.2 regression: thinks an exe wrapper is needed on mips64 #12017
Describe the bug
When doing a native build on mips64 Linux (build = mips64, host = mips64), compiler.run() fails with Can not run test applications in this cross environment.
To Reproduce
project('foo', 'c')
if meson.can_run_host_binaries()
meson.get_compiler('c').run('whatever')
endif
Expected behavior
On amd64, or on mips64 with 1.1.1, this project configures successfully. (Obviously the invalid C code whatever fails to compile, but in this minimal reproducer that has no practical effect.)
Actual behaviour
On mips64 with 1.2.0, can_run_host_binaries returns true, but then run fails with Can not run test applications in this cross environment.
system parameters
Is this a cross build or just a plain native build (for the same computer)? native
When detecting the host and build architectures, Meson knows that this is a C project, so it can check whether the C compiler defines __mips64 (it does), and correctly decides that it is compiling for a mips64 host on a mips64 build system.
However, when mesonbuild.environment.machine_info_can_run calls detect_cpu_family({}), the parameter is an empty CompilersDict, therefore none of the compilers in that dict define __mips64, and detect_cpu_family detects the true_build_cpu_family as mips. This doesn't match mips64, so machine_info_can_run returns false, therefore need_exe_wrapper returns true.
A workaround (I think) would be to provide a native-file that explicitly sets needs_exe_wrapper to false.
in detect_cpu_family, if mips64 was initially detected and the compilers dict is empty, believe uname instead of rewriting it to mips;
in machine_info_can_run, assume that a mips64 build machine can run mips code (to the best of my knowledge it can, assuming the endianness is the same, because the relationship between mips64 and mips is similar to x86_64 and x86)
I think probably the answer here is that we shouldn't change the outcome of detect_cpu_family because there is no compiler. Every other check is if any_compiler_has_define(...): trial = 'xxx' but this one is if not ...: which means that rather than fine-tuning our results based on a positive compiler match, we fine-tune our results based on a negative.
My suggestion in #12017 (comment) was to do both things, rather than them being options from which to choose one. I think only doing the first bullet point would make machine_info_can_run return false when running 32-bit mips userspace on a mips64 kernel and asking Meson to do a native build ([edited] mips host on mips build), effectively reopening #11671.
A real-world situation where we would expect Meson to be using build = mips, host = mips on a mips64 kernel:
Debian has a "porterbox" available to developers for testing what Debian calls mips64el and mipsel, which are little-endian 64- and 32-bit mips; because Meson doesn't consider endianness to be part of the CPU family, those are mips64 and mips in Meson terms. The porterbox is running on a 64-bit mips hardware, with a 64-bit mips64el Linux kernel, and it has a set of chroot environments with mips64el user-space (so python3 is a mips64el binary, and Meson would usually have build = mips64, host = mips64) and a second set of chroot environments with mipsel user-space (so python3 is a mipsel binary, and Meson would usually have build = mips, host = mips).
This doesn't necessarily arise in practice because while entering the 32-bit chroots, the chroot infrastructure uses linux32 to ask the kernel to set its "personality" to report uname() as though it was a 32-bit kernel; that's another way to avoid #11671 in such environments.
Sure, it seems reasonable to also add a quirk if we know it's reliable, the same way we have a quirk for x86_64 since it can always run i686 binaries unless that support was intentionally switched off in (kernel) software.
~I think this issue is also affecting my MinGW-w64 cross builds from Debian. I have wine64 configured as the exe_wrapper in my cross file, and despite meson.can_run_host_binaries() returning true, when doing cc.run() where cc is the C compiler I get meson.build:29:17: ERROR: Can not run test applications in this cross environment.
Obviously if we can't run test applications in the cross environment, meson.can_run_host_binaries() should return false. Rolling back Meson to 1.1.1 works around the issue.
EDIT: Nevermind, my issue was due to the location of the exe_wrapper moving.
#12080 hopefully fixes this. I don't have any mips hardware myself, but I tried it on a remotely-accessible Debian machine (64- and 32-bit chroots on a 64-bit CPU and kernel) with this test project:
project('test', 'c')
message('Host: @0@'.format(host_machine.cpu()))
message('Build: @0@'.format(build_machine.cpu()))
if meson.can_run_host_binaries()
meson.get_compiler('c').run('whatever')
message('Can run host binaries')
else
message('Cannot run host binaries')
endif
which seems to do the right thing in all combinations of linux32, linux64 or nothing, in a 32- or 64-bit chroot.
Activity
smcv commentedon Jul 19, 2023
I think this is a regression caused by #11672.
When detecting the host and build architectures, Meson knows that this is a C project, so it can check whether the C compiler defines
__mips64(it does), and correctly decides that it is compiling for amips64host on amips64build system.However, when
mesonbuild.environment.machine_info_can_runcallsdetect_cpu_family({}), the parameter is an empty CompilersDict, therefore none of the compilers in that dict define__mips64, anddetect_cpu_familydetects thetrue_build_cpu_familyasmips. This doesn't matchmips64, somachine_info_can_runreturns false, thereforeneed_exe_wrapperreturns true.A workaround (I think) would be to provide a native-file that explicitly sets
needs_exe_wrapperto false.smcv commentedon Jul 19, 2023
Perhaps this would work?
detect_cpu_family, ifmips64was initially detected and the compilers dict is empty, believeunameinstead of rewriting it tomips;machine_info_can_run, assume that amips64build machine can runmipscode (to the best of my knowledge it can, assuming the endianness is the same, because the relationship betweenmips64andmipsis similar tox86_64andx86)eli-schwartz commentedon Jul 21, 2023
I think probably the answer here is that we shouldn't change the outcome of detect_cpu_family because there is no compiler. Every other check is
if any_compiler_has_define(...): trial = 'xxx'but this one isif not ...:which means that rather than fine-tuning our results based on a positive compiler match, we fine-tune our results based on a negative.So, option 1.
smcv commentedon Jul 22, 2023
My suggestion in #12017 (comment) was to do both things, rather than them being options from which to choose one. I think only doing the first bullet point would make
machine_info_can_runreturn false when running 32-bit mips userspace on a mips64 kernel and asking Meson to do a native build ([edited] mips host on mips build), effectively reopening #11671.smcv commentedon Jul 22, 2023
A real-world situation where we would expect Meson to be using build = mips, host = mips on a mips64 kernel:
Debian has a "porterbox" available to developers for testing what Debian calls mips64el and mipsel, which are little-endian 64- and 32-bit mips; because Meson doesn't consider endianness to be part of the CPU family, those are mips64 and mips in Meson terms. The porterbox is running on a 64-bit mips hardware, with a 64-bit mips64el Linux kernel, and it has a set of chroot environments with mips64el user-space (so python3 is a mips64el binary, and Meson would usually have build = mips64, host = mips64) and a second set of chroot environments with mipsel user-space (so python3 is a mipsel binary, and Meson would usually have build = mips, host = mips).
This doesn't necessarily arise in practice because while entering the 32-bit chroots, the chroot infrastructure uses
linux32to ask the kernel to set its "personality" to report uname() as though it was a 32-bit kernel; that's another way to avoid #11671 in such environments.eli-schwartz commentedon Jul 23, 2023
Sure, it seems reasonable to also add a quirk if we know it's reliable, the same way we have a quirk for x86_64 since it can always run i686 binaries unless that support was intentionally switched off in (kernel) software.
ermshiperete commentedon Jul 25, 2023
I get the same error when my
meson.buildfile containscompiler.sizeof(...)and building on mips64el.eli-schwartz commentedon Jul 25, 2023
So to confirm -- on a mips64 system, the
test cases/common/30 sizeof/directory in the meson source code fails to configure? e.g.reports an error?
AdrianBunk commentedon Jul 25, 2023
Yes:
Complete log is attached.
LOG.common_30.txt
jscott0 commentedon Jul 29, 2023
~I think this issue is also affecting my MinGW-w64 cross builds from Debian. I have
wine64configured as theexe_wrapperin my cross file, and despitemeson.can_run_host_binaries()returningtrue, when doingcc.run()whereccis the C compiler I getmeson.build:29:17: ERROR: Can not run test applications in this cross environment.Obviously if we can't run test applications in the cross environment,
meson.can_run_host_binaries()should return false. Rolling back Meson to 1.1.1 works around the issue.EDIT: Nevermind, my issue was due to the location of the exe_wrapper moving.
eli-schwartz commentedon Aug 3, 2023
@smcv any chance for a PR implementing these changes?
environment: Don't override mips64 to mips if no compilers are available
3 remaining items
environment: Don't override mips64 to mips if no compilers are available
tests: Assert that mips64 kernel is detected as mips64 with no compilers
smcv commentedon Aug 5, 2023
#12080 hopefully fixes this. I don't have any mips hardware myself, but I tried it on a remotely-accessible Debian machine (64- and 32-bit chroots on a 64-bit CPU and kernel) with this test project:
which seems to do the right thing in all combinations of linux32, linux64 or nothing, in a 32- or 64-bit chroot.
environment: Don't override mips64 to mips if no compilers are available
tests: Assert that mips64 kernel is detected as mips64 with no compilers
environment: Don't override mips64 to mips if no compilers are available
tests: Assert that mips64 kernel is detected as mips64 with no compilers
environment: Don't override mips64 to mips if no compilers are available
tests: Assert that mips64 kernel is detected as mips64 with no compilers
chore(linux): Remove workaround for mips64el
environment: Don't override mips64 to mips if no compilers are available
tests: Assert that mips64 kernel is detected as mips64 with no compilers
environment: Don't override mips64 to mips if no compilers are available
tests: Assert that mips64 kernel is detected as mips64 with no compilers