Properly error out when cross file is missing a compiler.
Codecov Report
All modified and coverable lines are covered by tests :white_check_mark:
Project coverage is 66.53%. Comparing base (
d082204) to head (f11c643). Report is 2666 commits behind head on master.
Additional details and impacted files
@@ Coverage Diff @@
## master #9969 +/- ##
==========================================
- Coverage 66.55% 66.53% -0.02%
==========================================
Files 400 400
Lines 85043 85043
Branches 18724 18724
==========================================
- Hits 56598 56586 -12
- Misses 24057 24072 +15
+ Partials 4388 4385 -3
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
Hard NAK, distros rely on this, and every other major build system implements this interface, they’ll just end up reverting this because that’s easier than working around it.
The only people who might conceivable benefit are those the start with their default native build enviroment (as a black box they don't know quite what it contains), and then add in some cross compilers (maybe installed in an ad-hoc way) and don't want to worry about whatever environment variables might have been set by the default native build environment.
I get it; this is perhaps everyone's first time experience trying to cross compile something. But anyone managing builds seriously quickly learns you shouldn't just "throw more stuff on your native environment" and call it finished, but rather construct the environment you need for the platform you are building for from first principles, native or cross.
It is much better to meet the needs of these serious cross users, than try to cushion the blow for the cross beginners --- beginners who are going to be beset with build failures anyways before long if they try to hastily throw together a build environment that way.
Since the very beginning the design has been that cross executables ONLY come from the cross file. Never, ever, ever, ever from envvars. The fact that they did was a bug. The code I changed very explicitly tried to do this and got it wrong.
The current way things work is incredibly broken. For example if you do this;
./meson.py --cross-file /dev/null test\ cases/common/1\ trivial build
Then the outcome is this:
C compiler for the host machine: ccache cc (gcc 11.2.0 "cc (Ubuntu 11.2.0-7ubuntu2) 11.2.0")
C linker for the host machine: cc ld.bfd 2.37
C compiler for the build machine: ccache cc (gcc 11.2.0 "cc (Ubuntu 11.2.0-7ubuntu2) 11.2.0")
C linker for the build machine: cc ld.bfd 2.37
There no possible case where that would be the right thing to do. It is wrong, confusing and just plain bad UX.
@jpakkane I recall we all talked about this many times. It's on the docs too https://mesonbuild.com/Reference-tables.html#environment-variables-per-machine
Your example that is supposed to be so egregious doesn't really rattle me. In general, we assume native, and your empty cross file doesn't override any assumptions. Why should it do anything different?
If is anything confusing, it's the basic flow (at least I checked) of both guessing compilers based on tentative platform description, and guessing platform description based on compiler choice.
In your example, because there there is no [machine], it assumes both are equal, and then (no env vars needed!) it is happy to use the default logic to find the compiler for the build and host machine the same way. If, say, we could specify a default tool prefix in the cross file, then we could at least force ourselves only to look up so-prefixed tools if there is no env vars or [binaries]. That would allow making meson to fail to find a host compiler as desired.
it is happy to use the default logic to find the compiler for the build and host machine the same way
It did not use to do that. When I originally wrote that I was very strict about it never accepting cross properties from anything except the cross file. Sadly this got broken by some refactoring.
This was not "broken by some refactoring" It was an explicit decision to make our usage of CC, CFLAGS, etc match what everyone else does, because implementing a standard interface in a non-standard way is worse than useless.
recall we all talked about this many times. It's on the docs too https://mesonbuild.com/Reference-tables.html#environment-variables-per-machine
There are two different cases here.
The first one is that if CC_FOR_BUILD is defined, then that is used for the native compiler. This is totally fine.
The second one is that then CC is used for cross compilation. This is not fine. It is wrong. I never approved this, only the first one of the two.
Also:
distros rely on this
Debian (and by extension any distro based on it) does not. It has used cross files exclusively since day one. One of the main reasons I became the maintainer of the Meson package in Debian was to ensure that they would actually do the right thing and not write a ton of custom monstrosity patches to make it pretend to be autotools.
There has been some desire to get the debcrossgen tool to Meson upstream so everyone can do something like meson env2cross to convert their env var mishmash soup into a cross file.
@jpakkane I actually have a similar script for VLCs contrib system too that produces a crossfile from env vars, so having something like that upstream would definitely be useful
NixOS 100% relies on this. For better or worse, we have many packages with "setup hook" that set env vars when used as dependecies. It is non-trivial to replicate this logic with cross files alone because our package dependencies jointly determine the host platform configuration.
@jpakkane I think a big underlying philosophical difference here is that you prefer to think in "native vs cross" terms, not "host vs target" terms. The former is simply impractical for cross compiling at scale. Debian, to my knowledge, doesn't really bother to test whether arbitrary cross compilation works to the extent NixOS/Nixpkgs does. If they did, they would soon realize it's a huge to do native vs cross differently.
In fewer words, I have no love for env vars either, but I can't think of any good reason to allow them for native but not for cross. If Meson forced me to put eveything in native and cross files, it would be consistent, and avoid duplication. Likewise if it forced everything to be via env vars. But by allowing env vars just for native, it fosters doing things two different ways.
Please consider what you wrote in https://nibblestew.blogspot.com/2020/03/its-not-what-programming-languages-do.html
Most people only care about native compilation. Most people also instinctively try env vars because it's what they already know. If you do this, you will doom me and maintainers of NixOS and other crowd-sourced distros / package repositories to constantly fixing cross breakage. Things will work natively with envars. Some one will merge a PR not realizing it breaks (possibly far downstream!) a Meson cross build, and months later one of us cross people will be confronted with a mysterious regression. That makes cross maintenance a sisyphean hell scape, and given Meson's increased promenance could kill our currently-realized dream of making whole-system cross compilation without a specialized distro like Yocto a reality.
Please, please do not undo our accomplishment with these perverse incentives.
If you must kill env vars, yes let's upstream that tool. Let's also just remove env vars from Meson entirely. env2cross should be called env2platform (or similar) so it works with native and cross files alike, which have the same structure. The debian packaging becomes simpler too, because it's the same code paths in both the native and cross case.
Voice your comments in #10018. Thanks.