-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Cargo integration in Meson via an "unstable-cargo" module (try 2) #2617
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
Conversation
mesonbuild/backend/ninjabackend.py
Outdated
def custom_target_needs_serialization(self, target, cmd): | ||
if target.capture or target.envvars or any('\n' in c for c in cmd) or \ | ||
((mesonlib.is_windows() or mesonlib.is_cygwin()) and | ||
self.determine_windows_extra_paths(target.command[0])): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Flake8]
visually indented line with same indent as next logical line
@jpakkane I think this is failing because there's no cargo; not sure why the error message is getting eaten up. Could you please add cargo to the docker image? |
CI image updated. |
58f8ae0
to
dca4019
Compare
Besides the one style change in the review, is anything blocking this? Is there something that I can do to help? I'm not excited to give all of my GitHub profile and repo data to SideCI just to see why it fails, but I assume it is the style change too. |
This relies on the unstable-cargo module, which has yet to be upstreamed. See: mesonbuild/meson#2617
The bigger question here is how to join together Rust and other languages. Specifically something like this:
This is the minimal set of things we'd need to be able to speak about true interoperability rather than each system working on its own in an isolated universe. |
Linking to a C library from Rust is something that is not implemented in this PR right now, but it is possible to add. I am just hesitant to add it till I try to port a project that works like that (will happen when I try to build gstreamer rust plugins with meson, but I can't spend time on that if the effort will go nowhere). This PR implements one-way integration: compiling Rust-only code as a static library which exposes a C API that is used by other code. It was written specifically for librsvg's use-case, and I expect other GNOME projects that are slowly porting their codebases internally to Rust to be able to use this too. I think this is a good start, and the rest can grow organically as mixed Rust and C projects start using Meson. Currently, they all use hand-rolled makefiles or Autotools because it is impossible to mix Cargo and C with Meson. You have to start somewhere. |
But unless I'm missing something the result of those is not actually used to link, they are just installed and presumed working. But the bigger issue is that the proposed approach breaks the file layout contract we have with users and developers and internally. The most important one of these is that all temporary and work files must go in the target private directory. Scattering them about the build dir is not acceptable. In this vein the contract is also that if you do, say, an The proper solution to this ties in with this message from above:
this would mean being able to do something like this:
putting all the internal temporary stuff to the private dir and final outputs to the build tree. |
That's what the test does (because I don't know enough Rust yet), but I tested this with librsvg which does indeed implement a C API from Rust and uses it from C examples and that worked just fine. I'll improve the test.
The temporary directory is set with the Ideally we should also be able to set the workdir with an argument instead of using an env var, and that will improve things for all build systems.
Good point, this would cause issues with shared libraries built with Rust. However, this module only supports static libs and executables (rust cdylibs don't work well right now), does that also cause issues? The implementation is with a |
This is not exposed to build files and should not be. However, it is useful for modules that want to run external commands that only take certain inputs via environment variables.
It is better to send it to stdout so that the user sees progress on long-running commands. It also gives better feedback to users, f.ex. when a command requires capture: true and the user forgets to pass it.
Change the check for `/` to checking for `..` to prevent custom targets from fetching outputs from outside the target directory, but allow fetching outputs from arbitrarily-nested subdirs. Also disallow absolute paths for outputs for similar reasons.
Long-running commands such as `cargo build` would show no output at all without this. This feature is precisely for this use-case, so expose it. Of course, build files do not have access to this yet.
Currently only supports building staticlib libraries and binaries with Cargo. All configuration must be in the Cargo.toml file. You should use cargo 0.23 because it fixes a bug in emitting dep-info FIXMEs: * Cross compilation is broken. We do not pass the `--target TRIPLE` flag to cargo, so it always builds targetting the build machine. * tests and benches are currently not supported, but can be added * cdylibs are not supported because it is not clear if anyone uses them and if they even work properly in Rust * `ninja dist` does not yet run `cargo vendor` to add crate sources * `cargo clean` is not called on `ninja clean` * We cannot handle adding system libraries that are needed by the staticlib while linking because it's outputted at build time by `cargo build`. You must handle that yourself. * We do not pass on RUSTFLAGS from the env during configure to cargo build.
dca4019
to
580c851
Compare
# If the target requires capturing stdout, then use the serialized | ||
# executable wrapper to capture that output and save it to a file. | ||
if target.capture: | ||
if target.capture or target.envvars: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Flake8]
trailing whitespace
Every plugin generate an autostart desktop file, except `common` and `dummy` that are special cases. This desktop file generation is duplicated among the different plugin's build files. This code has been moved to the build file in the `plugins` directory, avoiding any code duplication. The downside of this is that meson is not able to generate files in a different directory, so all the files will be generated in the `plugin` directory, outside of the each plugin's directory. This is something that it's worked on in a different feature and it might be merged in the future. See mesonbuild/meson#2617 https://bugzilla.gnome.org/show_bug.cgi?id=793087
Every plugin generate an autostart desktop file, except `common` and `dummy` that are special cases. This desktop file generation is duplicated among the different plugin's build files. This code has been moved to the build file in the `plugins` directory, avoiding any code duplication. The downside of this is that meson is not able to generate files in a different directory, so all the files will be generated in the `plugin` directory, outside of the each plugin's directory. This is something that it's worked on in a different feature and it might be merged in the future. See mesonbuild/meson#2617 https://bugzilla.gnome.org/show_bug.cgi?id=793087
FWIW,
|
That module could be great. We are building Fractal with meson with a custom script [1] and it could be great to have a native support for cargo. [1] https://gitlab.gnome.org/danigm/fractal/blob/master/meson.build |
I am also using a custom script, pretty much identical to Fractal's, for building gnome-podcasts. Would be nice to have upstream support and not rely on hacky configs! |
METOO 😄 We are about to move librsvg to meson, and any changes to make it easier to combine C and Rust code will be much appreciated. I'm making a little diagram of our current build process, and where we want to get to. It's a bit convoluted since we are integrating rsvg-rs (the Rust bindings for librsvg) into librsvg's own source tree, so that things like the integration tests and the binaries for utilities can be redone in Rust. |
If you want to see progress on this issue, please get some comments from Cargo developers on the path issue discussed above. |
I think this is a profoundly unhelpful comment to make. Upstream cargo has no reason to care about Meson, and an approach like this will ensure that they won't, because people will just use some other build system or continue to use ugly hacks till their entire codebase is ported over to Rust and Meson is unnecessary. Realistically, we need to improve our integration so we get some buy-in for Meson in non-trivial Rust projects, which will lead to pressure on Cargo to make changes. Having something that works for a specific subset of use-cases is how you improve the state of things for all the other cases. I will be updating this PR by rebasing it on top of current master. That's all I can do. |
Another thing I forgot to mention: every project is shipping similar hacks, and having a module with a central location for these hacks is useful in general. We can ensure that these projects keep building once the hacks become unnecessary, which is even more useful. I also don't see any technical objections to this PR, it's literally just wrapping a custom target that does the necessary setup. |
@jpakkane From what I understood, @nirbheek answered your questions/concerns related to this PR in his replies to your specific questions/concerns and there is an unanswered questions to you as well. I agree with @nirbheek completely that by blocking cargo integration on cargo devs caring about meson, isn't a very pragmatic approach here. |
Just to be clear, I do agree with @jpakkane that Cargo needs to have better support for controlling where it places build outputs (at the very least). My point is that merging this and having projects use it will actually place us in a better position for working towards that with upstream. Note that this is exactly what happened with glib tools: gdbus-codegen, glib-compile-resources, gtk-doc, etc. They are much better now after we added hacky support for them in the beginning. |
On this I disagree. Cargo developers have stated that integrating better with other build systems is an official goal and something they will be willing to spend resources on. Getting them to comment on this issue (does not need to be exhaustive, but should have at least something) is a good way to test how that works in practice.
We have very limited resources. It would seem more prudent to use them to improve the development experience of people who are using Meson rather than on those who are only using it as a temporary crutch and plan to dump it as soon as possible. And just to be clear: it is the goal of Meson to provide native support for Rust as a first class language and have it work just like any other language even in mixed-language projects without needing any external tooling, even Cargo. The same goes for every other programming language as well. Supporting mixed language projects natively from a single build definition is at the core of what Meson is. |
There is a WIP Cargo PR for implementing |
Btw the PR mentioned above implementing |
command line proposed by @jpakkane would look like this:
The Note that currently there's no ability to control the names of the artifacts, only the output directory. This is because there's no single name to control: depending on the platform, the same crate may produce different-named artifacts ( |
I guess that is not a problem as long as the naming scheme is stable (enough) and meson can easily predict the files that will be generated for each specific target? |
The naming scheme is absolutely stable. The base name is roughly the name of the package, and prefixes/suffixes depend on the target and crate-type. So, manually running It's also rather straightforward to just look at the crate's manifest, predict which files are going to be produced, and put that into meson. However, building a fully automated solution, which parses Cargo.toml mechanically and derives the output artifacts name would be doable, but tricky. |
I have never liked this approach for combining projects. This latest discussion is exactly the reason why. The only way this will ever work is if you have a full serialisation for everything between the two build systems. The internal state of things is inherently unstable, nondocumented and liable to change on a whim, because that is the exact thing you need to have in a build system. No build system developer is ever going to commit to it.
Except no. That list needs to be known beforehand, before anything is built due to the way Ninja and Meson work. This would require us changing everything which is a massive maintenance burden.
Except no. This would require us to build a parser and all that stuff which is a maintenance burden.
This would be a massive development and maintenance burden on us again. The more time I spend on this the more convinced I become that having two build systems live inside the same build directory is a terrible , unworkable and just plain bad design. |
I disagree, and I don't think this is too much of a burden. We know where the output will be placed now, and the filenames are predictable. That's enough for us. If cargo changes the names, I expect it will not be a backwards-incompatible change, so it won't be an undue burden on us. We have a similar situation with pdb files too, and I am sure there are many other instances where we can't control the output of a command but know what it will be.
That's not not needed for this PR. This PR requires people to keep the Cargo.toml in sync with meson.build manually, and that's fine for now.
I agree that this is too error-prone. Let's not do this.
I completely disagree, of course. Perfect is the enemy of shipping solutions. :) I am sure that we will get to that point eventually; there are plenty of other people who want that. But in the meantime, we should get something in that doesn't block GNOME and GStreamer from using Rust with Meson. I expect that more people will send patches to Cargo for improvements once they hit the restrictions that the current command-line syntax place on what people can do from meson build files. That is, after all, how FOSS works, and is what we have observed in the past with other toolchains such as D and GNOME tools. |
Shipping solutions that are known to be unworkable in the long run is not good either. To clarify, let's state what we are and are not committed to do. We will:
What we will not do is do some hacky integration thingy between the two, especially one that relies, in any way, on undocumented internals or any API or ABI that is not guaranteed to be stable and supported for the foreseeable future. This is not limited to Rust. We will provide the same integration and support for every language that wants to work together with us. If we did every language the same way as Rust then Meson would compile Java just by calling to Maven because it is the standard, C# just by calling msbuild because it is the standard, D just by calling to dub because it is the standard, C++ just by calling into CMake because it is the standard, C just by calling into Autotools because it is the standard and so on. |
@jpakkane could elaborate a bit which current aspects of Cargo make it difficult to integrate it with meson? That is, why can't meson treat Cargo as a compiler, and not as a build system? Regardless of the direction of Rust support in meson, it would be very useful for Cargo team to know constraints of the current Cargo which prevent seamless integration with other build systems! Re-reading this thread, I've seen the following specific points being raised:
I'd be delighted to hear about and fix more build system integration problems :) |
If this needed to be summarized into one sentence, it would be this:
They probably aren't, but that is an easy impression to get. Perhaps the biggest issue is that everything in Cargo is tightly coupled. Everything must be built in one invocation. There is no way of getting dependencies from the system via a mechanism such as, but not necessarily, pkg-config. When combined with the fact that Rust has no standard library to speak of, every package depends on tens of other crates that depend on other crates and so on. This is perhaps the worst thing about NPM and Cargo chose to copy it blindly. If you wish to use any one single crate, pretty soon you find yourself downloading dozens of them. This by itself could be tolerable, but let's look at Cargo.lock of librsvg. Some crates are there multiple times (these include rand, syn and winapi) with different versions. This is bad and directly against coding requirements and standards in many organizations. Let's take Google as an example. Obviously I can't and don't speak for them so the following is analysis based on publicly released information. As far as I know Google does not have Rust in their list of approved languages so they would not be using it in any case. Google has a requirement that any third party dependency they have must be imported in their monorepo. Further, they have a requirement that there can only be one version of any dependency and that everyone in the entire organization must use the same version. In practice this means that Cargo (and by extension the crates it provides) can not be used in such an environment. Trying to tell them to change their entire workflow just to be able to use Cargo (and, by extension, Rust, if Cargo is to be The Only Way to compile Rust) is a losing battle. The situation is similar in Debian. Embedded dependencies (vendored in Cargo terms) must not be used but instead any shared dependencies must be provided individually by the system. Let's assume that this would be technically possible today. Every new source package that is added to Debian must be placed in the new queue and manually reviewed by a human. When Meson was added to Debian it consisted of one single package and the review took on the order of a few weeks. For comparison librsvg has ~50 crates it depends on. Thus if we were to do things properly, simply getting the dependencies into Debian would take one year. I don't have personal experience with how e.g. Red Hat Enterprise Linux does things but based on things I have been told the situation is roughly similar. I've also been lead to believe that the people doing these reviews are very much not happy with the dependency explosion that Cargo has wrought upon them. These are not problems with Meson integration with Rust as such. However they are extremely important points that should be considered when designing such a build and dependency system. As an example having an extensive, high quality standard library would help tremendously because the amount of crates needed for most programs would go down a lot. This is what Python does, for example, and it has worked for them extremely well.
Because that only works under very simple circumstances and even then is not reliable or performant. The first thing is that there needs to be more metadata available than is exposed currently. In fact all of it to make things actually work. Let's take the simple case like this:
Even in the simplest case of static libraries it is not enough to link the exe against the rustlib. You also need to have plainlib on the link line. Thus saying "here is my output library" is worthless on its own. The build system of exe can not know about plainlib unless Cargo explicitly tells about it. For extra challenge note that plainlib might be built by rustlib using Let's now assume that both rustlib and plainclib need to be built as shared libraries. I know Rust does not do shared libraries well currently, but let's assume that it is only implemented in Rust but exposes (and imports) only a plain C interface. Say a drop-in Rust replacement of You can't unless you set up rpaths properly. The exe and the two libraries are scattered about the build tree in some way. The only way to make it work is to set rpaths correctly in all of these. Even more importantly those rpath entries must be cleaned out when doing an install (which is a distro requirement) (but not others). You might need to specify an rpath that will be in effect after install. It can't be done only during install, there is some magic that needs to happen beforehand. As an extra challenge this also needs to work on OSX, which does everything in a weird way including It is left as an exercise to the reader to calculate the amount of integration points and lines of code needed to make all this work. The end result is that on the boundary of any two build systems there must be a standardised data serialisation roughly in scope with pkg-config and in practice more since pkg-config does not deal with rpath or any of the other stuff. This immediately brings up two questions:
Multiple build systems in one are also a performance problem. If you have only one build system, it has a global understanding of all work that needs to be done and can schedule work accordingly. With multiple build systems this is no longer possible. You have to split things into chunks. First you build everything using build system 1 that does not depend on anything built with build system 2. Then those things that build with build system 2 that have their dependencies currently met. Then system 1 again and so on until convergence. This is equivalent to ye olden Makefile days where Make first goes into one directory, builds everything there, then goes to the next and so on. This is incredibly slow, you can easily get 2x build time speedups merely by having one scheduler that works with global information. Given that Rust is slow to compile, adding extra perf bottlenecks is not a great design. Then there is Cargo's vendoring approach. It works fine for single self-contained projects but falls down the second you have two vendored subprojects within one superproject. I wrote a long blog post about this.. In this case not only do Cargo bundles contain multiple versions of the same libraries, they get multiplied by every single dependency used in the "just call into Cargo" method. The final thing is the fact that Cargo as a build system does so very little. Anything that is not a simple "build library or exe" gets shunted to In closing, the reason why Meson does not call Cargo and treat it as a compiler is that it is a fundamentally broken concept. It might work for simple cases but becomes unwieldy when things get more complicated. The goal of Meson is that it should be simple to combine projects written in different programming languages in any combination and get a result out reliably with good performance. Farming work out to other tools without cohesion is not a good way of achieving that goal. Extra footnote: note that all of the above is only an issue if you want to build all of these things in a single invocation in a single build directory. There are other ways of achieving all this. As an example if there was a "pkg-config for Rust" [1] then building could be done by compiling and installing the components one by one into a staging directory like, for example, Flatpak building works.
Now you have heard. I make no guarantees as to how delighted it made you feel. [1] For getting Rust dependencies, not for getting C library flags for building sys crates. At least it did not exist the last time I looked, Google does not immediately find anything and it's 3 AM now so forgive me for not doing more thorough research. |
While these points have nothing to do with meson/cargo integration, you brought them up here as arguments.
Did you ever install a Perl (the language used by most Debian infrastructure) package on Debian? That usually pulls in a few dozen other dependencies too, thanks to the popularity of CPAN. Similarly with Haskell, and probably other languages (JS/NPM? C#/.NET also has a huge amount of packages, and you can load different versions of the same library just fine there too) but those are the two I can think of right now. While not optimal for the way how Debian works, this is not even close to a new problem. (Also with regards to Haskell/GHC: dynamic linking situation is more or less the same, even for more or less the same reasons).
I assume Go is a language Google is using. While Go does not have an official tool for handling dependencies like Rust, making the situation even worse/more manual, generally all Go code out there is vendoring its dependencies. Which leads to exactly the same situation they would be in with Rust, just that in the case of Rust there is a tool and this tool easily gets you the latest compatible/latest version: everything might be using different versions of dependencies and you have to port software to the latest/a common version to following those requirements.
While Flatpak does not encourage vendoring of sources, it certainly does for binaries (for every dependency not part of platform). Which is a different problem but has many of the same problem, just that Flatpak does not give you a tool to manage these dependencies bundled with the binaries. Generally these are problems with any modern language that values a big ecosystem over a monolithic standard library and making usage of dependencies easy (which arguably at this point, but not historically, also includes the most enterprise of all enterprise languages: C# with nuget and Java with maven/gradle). As compared to C where people often implement things on their own or copy code because using dependencies is hard, resulting in an even worse situation: multiple more or less bad implementations for the same thing, or copied and possibly modified versions without a tool to track them. We need to find solutions to these problems, so much is clear, but they're not only problems that exists with Rust and especially it's not something that meson can fix alone. For the actual points related to meson/cargo integration, they are all taken into account in the Cargo build system integration RFC already that was mentioned here a few times. That takes time, and until then providing a imperfect solution to make it easy for people to use meson in a mixed C/Rust project would be useful. Otherwise people would just not use meson for this, which is probably also not what you want. |
I am very confused as to how you got the impression of any hostility from a "Can you please tell us how we can do better to cooperate with you?" gesture. |
There has obviously been a communication error. The comment I made has nothing, I repeat nothing to do with people participating in this thread. It is merely about technical decisions made by Rust and Cargo several years ago. As far as I know nobody on this discussion has had anything to do with them, nor would it even matter if they did. The point was only and specifically about choices such as:
If anyone has gotten the impression that this is some sort of an attack against people on this thread, then obviously I have miscommuncated. I most sincerely apologize for this and try to be clearer in my communication in the future. |
That's very great to hear. Thanks for explaining and apologizing. Hopefully, I was the only one who misunderstood you. |
Thanks a lot for a thorough reply @jpakkane! That was a lot to think about. There are a lot to be said about relative advantages of various approaches to code resue, including "I'll just write my own hash-map" of C, "urllib2 definitely will solve all the problems of urllib" of Python and "who doesn't want a package to left-pad a string" of JavaScript; neither of them is ideal. The sheer number of packages to manage in Rust is definitelyly a drawback, and occasional version duplication is a necessary evil to make huge dependency graphs work out in practice. However, Rust has chosen to rely heavely on dependencies, and at this point this is a constraint, and not something which can be realistically changed. Any build system for Rust probably needs to support crates.io package format and dependencies, otherwise it would likely be only marginally useful for Rust development. And let's not forget about the benefits of dependencies as well! The librsvg case is actually an interesting example in this respect. Looks like some of duplication comes from The point of version duplication across packages is very interesting! I've filed rust-lang/cargo#5332 about it. Today it is sort-of possible to avoid duplication by pretending that all packages are a part of a single workspace, and that's what Google & Facebook are doing. The funniest thing is that Rust itself employs similar hacks to deduplicate dependencies between rustc, Cargo and RLS. We definitely need a first-class solution here. The build scripts are definitelyly a pain-point of integrating Rust projects into absolutely anything! However, I don't fully agree with
It is true that build.rs itself is Turing complete. However, the effects of build.rs are extremely restricted, and amount to two things:
My understanding is that code-generation use-case is not actually problematic here. And, for native-libraries, Cargo includes a mechanism to completely bypass the build-script and just provide the information about native libraries directly, via build overrides. So, I believe
is perhaps not actually necessary? By the same token, Also, I'd like to assure you that
is not the current state of things! Dropbox and Facebook don't use Cargo for building their internal code, and the build system integration RFC specifically includes a path (build plans) to hand all of the work of building the code over to the main build system. However, it is very important that users do have access to crates.io packages, and implementing that without Cargo will be a lot of work. |
Sure. And if the definition was more declarative (as in without the current heavy dependency on
Having this sort of deduplication as a first class concept is what Meson has been doing for several years now. And we want to do it for all supported languages, and even multi-language projects.
You can not be "just a little bit Turing complete" like you can't be "just a little bit pregnant". If Turing completeness is exposed, people will use it for all sorts of nasty things you did not think of. Especially if they are not given "proper" building blocks and tools to solve their problems.
I read through the Cargo manual and based on that (not actual experimentation) it would seem that Cargo's support of code generation during build seems to be lacking. It only supports generating some Rust files statically and providing some compiler flags. This seems a bit inadequate for common and complex code generation steps needed for real world projects such as Protocol Buffers. Especially if you don't get the dependencies from the system but instead want to build them in the same build directory at the same time (for extra points: in a different programming language or mixture thereof).
Which only works if the only thing the
But at what level is that information? If it has anything like compiler flags or arguments, then it is at the wrong semantic level. What every build system developer wants is basically what is in
But the message that Rust developers publicly state is that this should not be done. And that if you do, then you are on your own and nothing is supported. This is important mindset issue.
Having an "as declarative as possible" definition for dependencies is what Meson was designed for: a minimal non-turing complete declaration good enough to support almost all use cases that modern SW development has.
If one ignores the |
Since this PR is not going to be merged, I am closing it. Future work can happen on new PRs. The code in this PR is archived in: https://github.com/nirbheek/meson/tree/cargo-module In the meantime, the workaround for people wanting to do this is to use the wrapper script noted above. |
I haven't fully read the proposed code, but something along those lines is definitely needed. It's sad that this initiative has been shutdown. A few points:
I'm not reopening this PR, but I strongly encourage @jpakkane to state he would accept a rust/cargo module if someone steps in and propose a new PR as well as dedicating themself to maintain it. Unless this is accepted beforehand, I don't think anyone will want to waste his time like @nirbheek sadly did. |
Would it possible to merge here in this repo just enough hooks and changes to make meson's "core" a bit more modular and allow My 2 cents, pardon the noise if I'm being too naive and underestimating the minimal, "meson core" changes required. BTW https://lwn.net/Articles/805840/ (very long thread)
|
That would mean committing to a stable API, which is even more difficult, especially in Python, IMHO. Also it means that when you build a project you have to find/install all those "meson plugins" it uses... I think it's opening a can of worms. I personally think "unstable" disclaimers are useless. If it's useful, people will use it regardless, and if they have issues/regressions/improvements they submit patches. The wonderful world of Open Source :-)
I'm not actually a big fan of Rust, I agree it has some serious flaws like that one. Mostly not the language, but all the ecosystem around it. From Meson PoV, cargo is not that different from any other external build system, it "just" has to know the configure/build commands, and where to find built libraries/executable. I would love to see a Meson module that would do just that, and cargo would just be a special case of it. |
No, I meant this only for experimental/staging modules. Think "out of tree" Linux drivers which regularly get broken by internal API changes.
Yes - even core Python developers don't seem sure what is a stable Python API and what is not. From https://lwn.net/Articles/795019/
This confusion is probably the main reason why Python developers seem generally cautious and don't assume an API is stable unless clearly stated/documented.
Again I meant this only for experimental modules, so having to find extra stuff is "The Feature". It's a the "unstable" disclaimer that you cannot pretend you didn't notice. |
This was made primarily so we can build librsvg with Meson, which now works: https://git.gnome.org/browse/librsvg/log/?h=wip/meson, and it actually required fewer hacks than I expected it to.
The integration can and should definitely be better, but I think the best way to get there is to have something that works right now and slowly improve Cargo till we have everything we need. Cargo is not going to magically grow API for giving greater control to build systems; we have to work towards it.
I have been talking to @alexcrichton about the things that Meson would need to integrate better with Cargo, and he has been very receptive and encouraging of our efforts, and in the need for adding features to Cargo that allow Meson to control what it does a bit better.
Here's what you can do right now:
'Extract' build outputs from
Cargo.toml
files in your source tree with theunstable-cargo
module and mostly use them like you would any other target. For example:You can also specify the list of sources if you wish:
The sources list is optional because cargo will output a nice
depfile
for us and ninja can then keep track of when to rebuild the target.Meson TODO:
ninja dist
does not support vendoring crate sources yet (needed for librsvg)Cargo TODO:
CARGO_TARGET_DIR
should be an argument--target-dir
Cargo.toml
cargo vendor
so we can ship a list of files instead of the sources themselves (cc @alexlarsson)Cargo long-term TODO:
rustc
invocations needed to build a crate so we can run everything ourselvesrustc
flags that we want.