Open bobbens opened 1 month ago
We don't support build.rs, and it's basically impossible for us to do so in an automated way because build.rs is an escape hatch, you can programmatically do anything you want in it: generate code, emit new arguments to rust and/or cargo, completely rewrite source files, find dependencies. If you need to use a crate that has a build.rs there is not choice but to hand write a meson.build to replace the build.rs file.
Which reminds me, I really need to get back to my crate to allow putting some stuff in the cargo.toml instead of the build.rs...
We don't support build.rs, and it's basically impossible for us to do so in an automated way because build.rs is an escape hatch, you can programmatically do anything you want in it: generate code, emit new arguments to rust and/or cargo, completely rewrite source files, find dependencies. If you need to use a crate that has a build.rs there is not choice but to hand write a meson.build to replace the build.rs file.
I perfectly understand not wanting to write a full replacement for cargo and the likes, however, I would strongly recommend at least setting some of the environment variables, as that would likely get quite good coverage over most build.rs
packages. In particular, for sdl2 and likely many others, just adding OUT_DIR
would be enough as doing OUT_DIR='..' meson compile
is enough to get it working. This would save a lot of effort having to rewrite meson.builds given that meson gives no way to set environment variables directly.
Except it isn't. Because Meson has no idea that build.rs is writing files, what their names are, where they'll be located, when then need to be updated, and whether they need to be installed.
Where you're going to run into problems in that path is the sdl-sys crate, it's 1000 LOC, it makes decisions like whether to invoke pkg-config, vcpkg, or invoke cmake to get sdl2; it calls bindgen to generate rust sources, and it emits linker and compiler flags. the sdl2 crate itself only sets a linker search path on some of the BSDs, which Meson would ignore.
That crate in particular is the sort that you need a hand written meson.build, because there is no way that we would be able to handle everything there. build.rs is the thing that we simply cannot solve, because it is so deeply integrated into cargo implementation details. The only real solutions we have are to either provide tools to offload some of the information from build.rs into the cargo.toml (which would could then handle), or simply re-implement build.rs files as meson.build files.
Because Meson has no idea that build.rs is writing files, what their names are, where they'll be located, when then need to be updated, and whether they need to be installed.
Would it make sense to support describing the output of build.rs in a way that answers these questions for Meson? This type of approach to external scripts is already supported for things like custom_target
Except it isn't. Because Meson has no idea that build.rs is writing files, what their names are, where they'll be located, when then need to be updated, and whether they need to be installed.
I understand that writing a custom meson.build would be the ideal solution for dependency tracking and the likes, However, I may be naive, but shouldn't meson understand OUT_DIR
and have some sort of idea where the package output should go? Alternatively, if meson just does not want to support build.rs
, refusing to work with the package when detected would be another potential solution. It just feels rather weird that it tries to compile with build.rs
yet doesn't define OUT_DIR
which seems to be quite prevalent.
Currently, given that it is not possible to set env vars with meson in general or for build_targets, it is not even possible to write a custom meson.build
to solve this package, short of using custom_targets
or an auxiliary script to do it. Even assuming that setting OUT_DIR
fails, it is unlikely something would break because it is defined, while if it isn't defined, anything that relies on it will fail to compile.
Would it make sense to support describing the output of build.rs in a way that answers these questions for Meson? This type of approach to external scripts is already supported for things like custom_target
No, custom_target doesn't operate the same way at all.
custom_target allows you to exit the meson build graph, enter an external command, and expect that external command to produce predefined output artifacts. Some people use this today with rust: they run cargo build
as a custom_target. There are various shortcomings to this approach, e.g. you cannot tie artifacts together, but running cargo will, indeed, set OUT_DIR. And run build.rs exactly as-is.
custom targets cannot "answer questions for meson". Meson knows the custom_target command, the input files, and the output files -- all of them are written in meson.build
itself. That command line then acts similar to the gcc/clang compiler command line from an executable()
. It is precomputed, written into the build graph, has meson-defined inputs and meson-defined outputs, and is expected to keep quiet and do what it is told.
There is exactly one question that a custom_target command can be asked and respond with an answer to -- and it is the same question that gcc / clang can be asked, and which rustc can be asked. It is: "can you provide a depfile containing a list of headers that when modified should trigger a recompile".
I understand that writing a custom meson.build would be the ideal solution for dependency tracking and the likes, However, I may be naive, but shouldn't meson understand
OUT_DIR
and have some sort of idea where the package output should go? Alternatively, if meson just does not want to supportbuild.rs
, refusing to work with the package when detected would be another potential solution. It just feels rather weird that it tries to compile withbuild.rs
yet doesn't defineOUT_DIR
which seems to be quite prevalent.
Does it indeed try to compile with build.rs
? ;)
It's difficult to know when a source file contains OUT_DIR without opening every source file for scanning, which isn't actually possible to do on every git pull
.
Also note that setting environment variables at all will cause every single compiler invocation to become really really slow. That's why in the linked PR, the discussion became linked to the proposal to stabilize --env-set
in rust itself. Which unfortunately appears to have died on the rustc side of things.
If it was low-cost to set environment variables with rust then it might be practical to set OUT_DIR automatically. There is simply no way whatsoever we are going to make every single rustc invocation in meson go through a python wrapper to set environment variables just on the off chance that they are needed. Even if we merge the PR to add an env:
kwarg to rust executables that does use a python wrapper, it would have to be opt-in precisely because of that performance hit.
Describe the bug Meson can wrap Rust cargo files, however, it does not provide the same environment variables that cargo does. In particular, for my case (compiling sdl2),
OUT_DIR
is not provided and thebuild.rs
which usesOUT_DIR
fails to compile.Although this is related to #10030 , it is a bit different as it focuses on cargo wraps which should be able compile like with
cargo
itself, and thus the environment variables shouldn't necessarily be set in the mainmeson.build
. If #10030 is merged, whatever solution is used there at the end could be used when generating themeson.build
from theCargo.toml
.To Reproduce Either use the small provided project cargo-fail.tar.gz or using the following file as
subprojects/sdl2-rs.wrap
, it will fail to company when used asdependency('sdl2-0.37-rs')
:The
meson.build
would be:and
main.rs
would be:Expected behavior It should compile like it does when compiled with
OUT_DIR='..' meson compile
. By default it will error out with:system parameters