Over the Easter holidays I spent some time on a little experiment: How hard is it to build a GStreamer plugin in Rust with meson instead of using the default Rust build system cargo?
meson is a community-developed, open-source, cross-platform (including Windows), multi-language build system that is supposed to be fast and easy to use. It’s nowadays used as a build system by a lot of components of the GNOME desktop, by GStreamer, systemd, Mesa, X.org, QEMU and many other pieces of Free Software. Mostly for building C or C++ code, but also for configuring and installing Python or JavaScript code, Vala, and other languages.
Wouldn’t it be nice if we could also build software in Rust with it, build it together with existing code in other languages and have a common build system for it all? What would be the advantages and disadvantages of that, and what’s the current status of Rust support in meson? How much effort is it to make use of all the existing 100k software packages (“crates”) that are available for Rust?
Especially as most the projects mentioned before are looking into adopting Rust more or less seriously as a safer and more modern successor of C, these seem like useful questions to investigate. Anecdotally, I also heard that a maintainer of one of these projects said that being able to use the same build system as the rest of the codebase would be a requirement to even consider the language. Another project is starting to write some components in Rust and building them with meson, but without depending on any external Rust dependencies for now.
Another reason for looking into this was that there seems to be the opinion that you can’t really use any build system apart from cargo for building Rust code, and using meson would be very hard to impossible and involve a lot of disadvantages. This has lead to currently all GNOME applications written in Rust having a chimera of a build system using both meson and cargo because neither of the two does everything these applications need. Such a setup is hard to maintain, debug and probably almost nobody really understands it. cargo’s design does not make embedding into another build system easy, and both cargo and meson have very specific, and to some degree incompatible, opinions about how things have to be done. Let’s see if that’s actually necessary and what’s missing to move away from that. As Facebook is apparently using buck to build part of their Rust code, and Google bazel, this shouldn’t really be impossible.
As I’m a GStreamer developer, the maintainer of its Rust bindings and the one who started writing plugins for it in Rust, trying to do build a GStreamer plugin in Rust with meson instead of cargo seemed like the obvious choice for this experiment.
However, everything here applies in the same way to building GTK applications with its Rust bindings or similarly to any of the software mentioned before for writing components of them in Rust.
EDIT: After publishing the first version I was told that meson actually supports a couple of things that I missed before. For example, running Rust tests is already supported just fine (but more verbose in the build definition than cargo), and meson can already install executables setuid root by itself. Also there is an equivalent to cargo init
, meson init
, which makes starting new projects a bit more convenient. Also I wrote that cargo clippy
is not really supported yet. While true, you can get around that by telling meson (or any other build system) to use clippy-driver
as compiler instead of using rustc
. I’ve updated the text below accordingly.
Summary
The code for my experiment can be found here, but at the point of writing it needs some changes to meson that are not merged yet. A list of those changes with some explanation can be found further below. The git repository also includes a cargo build system that gives the same build results for comparison purposes.
I should also make clear that this is only an experiment at this point and while it works fine, it is more manual work than necessary and if you depend on a lot of existing crates from crates.io then you probably want to wait a bit more before considering meson. Also more on that later. However, if you won’t have to depend on a lot of crates, your codebase is relatively self-contained and maybe even has to be built together with C code, then meson is already a viable alternative and has some advantages to offer compared to cargo. But also some disadvantages.
Almost all of the manual work I did as part of this experiment can be automated, and a big part of that is not going to be a lot of work either. I didn’t do that here to get an idea of the problems that would actually be encountered in practice when implementing such an automated system. I’ll get to that in more detail at the very end.
In summary I would say that
- meson is less convenient and less declarative than cargo, but in exchange more powerful and flexible
- meson’s Rust support is not very mature yet and there’s very little tooling integration
- cargo is great and easy to use if your project falls into the exact pattern it handles but easily becomes annoying for you and your users otherwise
- the developer experience is much better with cargo currently but the build and deployment experience is better with meson
More on each of these items below.
Procedure
As a goal I wanted to build one of the parts of the gst-plugins-rs tutorial, specifically an identity
-kind of element that simply passes through its input, and build that into a GStreamer plugin that can be loaded into any GStreamer process. For that it has to be built into cdylib
in Rust terms: a shared library that offers a C ABI. For this purpose, meson already has a big advantage over cargo in that it can actually install the build result in its correct place while cargo can only install executables right now. But more on that part later too.
The main task for this was translating all the Rust crate dependencies from cargo to meson, manually one by one. Overall 44 dependencies were needed, and I translated them into so-called meson wrap dependencies. The wrap dependency system of meson, similar to cargo, allows to download source code of dependencies from another location (in this case crates.io) and to extend it with a patch, in this case to add the meson-based build system for each.
In practice this meant creating a lot of meson.build
files based on the Cargo.toml
of each crate. The following following is the meson.build
for the toml_edit
crate.
project('toml_edit-rs', 'rust', version : '0.19.8', meson_version : '>= 1.0.0', default_options : ['buildtype=debugoptimized', 'rust_std=2021' ] ) rustc = meson.get_compiler('rust') toml_datetime_dep = dependency('toml_datetime-rs', version : ['>= 0.6', '< 0.7']) winnow_dep = dependency('winnow-rs', version : ['>= 0.4', '< 0.5']) indexmap_dep = dependency('indexmap-rs', version : ['>= 1.9.1', '< 2.0']) features = [] features += ['--cfg', 'feature="default"'] toml_edit = static_library('toml_edit', 'src/lib.rs', rust_args : features, rust_crate_type : 'rlib', dependencies : [toml_datetime_dep, winnow_dep, indexmap_dep], pic : true, ) toml_edit_dep = declare_dependency(link_with : toml_edit)
and the corresponding wrap file
[wrap-file] directory = toml_edit-0.19.8 source_url = https://crates.io/api/v1/crates/toml_edit/0.19.8/download source_filename = toml_edit-0.19.8.tar.gz source_hash = 239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13 diff_files = toml_edit-rs.meson.patch [provide] toml_edit-rs = toml_edit_dep
As can be seen from the above, this could all be autogenerated from the corresponding Cargo.toml
and that’s the case for a lot of crates. There are also some plans and ideas since quite a while in the meson community to actually develop such a tool, but so far this hasn’t materialized yet. Maybe my experiment can provide some motivation to actually start with that work.
For simplicity, when translating these by hand I didn’t consider including
- any optional dependencies unless needed for my tasks
- any tests, examples, executables as part of the crate
- any cargo feature configuration instead of exactly what I needed
All of this can be easily done with meson though, and an automated tool for translating Cargo.toml
into meson wraps should easily be able to handle that. For cargo features there are multiple ways of mapping them to meson, so some conventions have to be defined first of all. Similarly for naming Rust crates as meson dependencies it will be necessary to define some conventions to allow sharing between projects.
The hard part for translating some of the crates were the cargo build.rs build scripts. These build scripts allow running arbitrary Rust code as part of the build, which will also make automatic translation challenging. More on that later.
Once I had translated all the 44 dependencies, including the GStreamer Rust bindings, various procedural Rust macros and a lot of basic crates of the Rust ecosystem, I copied the plugin code into the new repository, changed some minor things and could then write a meson.build
file for it.
project('gst-plugin-meson-test', 'rust', version : '0.0.1', meson_version : '>= 1.0.0', default_options : ['buildtype=debugoptimized', 'rust_std=2021' ] ) plugins_install_dir = '@0@/gstreamer-1.0'.format(get_option('libdir')) rustc = meson.get_compiler('rust') add_global_arguments( '-C', 'embed-bitcode=no', language: 'rust' ) gst_dep = dependency('gstreamer-rs', version : ['>= 0.20', '< 0.21']) once_cell_dep = dependency('once_cell-rs', version : ['>= 1.0', '< 2.0']) gst_plugin_meson_test = dynamic_library('gstmesontest', 'src/lib.rs', rust_crate_type : 'cdylib', rust_dependency_map : { 'gstreamer' : 'gst', }, dependencies : [gst_dep, once_cell_dep], install : true, install_dir : plugins_install_dir, )
To get everything building like this with the latest meson version (1.1.0), at this point some additional changes are needed: 1, 2, 3 and 4. Also currently all of this only supports native compilation. Cross-compilation of proc-macro
in meson is currently broken but should be not too hard to fix in the future.
A careful reader will also notice that currently all crates with a dash (-
) in their name are named like that for the dependency name, but the library they’re building has the dash replaced by an underscore in its name. This is due to a rustc bug (or undocumented behaviour?), and meson will likely require this translation of forbidden characters in crate names for the foreseeable future.
With all that in place, building the project is a matter of running
$ meson builddir $ ninja -C builddir
compared to a single command with cargo
$ cargo build
Note that the meson build will be slower because by default meson already builds with optimizations (-C opt-level=2
) while cargo does not.
Comparison between cargo and meson
In the following section I’m going to compare some aspects of cargo and meson, and give my general impression of both. To take the conclusion ahead, my perfect build system would include aspects of both cargo and meson and currently both are lacking in their own way. Like with any other tool (or programming language, for that matter): if you don’t have anything to complain about it you don’t know it well enough yet or don’t know any of the alternatives.
To avoid that people focus on the negative aspects, I’m also going to try to describe all the shortcomings of one build system as a good feature of the other. This is no competition but both meson and cargo can learn a lot from each other.
Build Times
Above I shortly mentioned build times. And because that’s something everybody is interested in and a common complaint about Rust, let’s start with that topic even if it’s in my opinion the most boring one.
Overall you would expect both build systems to behave the same if they do the same work as they are both basically just sophisticated Rust compiler process spawners. If you want to improve build times then your time is probably spent better on the Rust compiler itself and LLVM.
All times below are measured on my system very unscientifically with time
. This is all only to give an idea of the general behaviour and to check if there are conceptual inefficiencies or problems. Also, when reproducing these results make sure to pass -Dbuildtype=debug
to meson for comparable results between meson and cargo.
- Running meson (build configuration): 1.4s (1.0s user, 0.4s system)
- Running ninja (actual build): 10.4s (23.5s user, 3.2s system)
- Running cargo: 11.0s (34.1s user, 6.6s system)
One thing that shows here immediately is that both need approximately the same time. The build alone takes slightly less than cargo, the configure and build steps together slightly more. So far what would be expected. However, cargo uses almost 45% more CPU time. I didn’t investigate this in great detail but the main two reasons for that are likely
- cargo is building and running a
build.rs
build script in 23 of the 44 dependencies, which takes a while and also pulls in some more dependencies that are not needed for the meson build - meson is currently parallelizing less well compared to cargo when building Rust code, or otherwise the build step would likely be 10% or more faster
cargo build scripts
Interestingly, the main pain point when translating the crate build systems from cargo to meson also seems to be the main factor for cargo being more inefficient than it could be. This also seems to be a known fact in the wider Rust community by now.
But in addition to being inefficient and painful to translate (especially automatically), it is in my opinion also a maintenance nightmare and literally the worst part of cargo. It’s not declarative in what the build script is actually trying to do, it’s very easy to write build scripts that don’t work correctly in other environments and two crates doing the same things in a build script are generally going to behave differently in non-obvious ways.
For all the crates that I translated, the reasons why the build scripts existed in 23 of 44 crates should really be features that cargo should provide directly and that meson can do directly:
- Checking which version of the Rust compiler is used and based on that enabling/disabling various features
- Checking features or versions of the underlying platform or operating system
- Checking for existence of native, external libraries or even building them
- Not in these cases: code generation
Especially the last two points are painful for build and deployment of Rust code, and that every crate has its own special way of solving it in a build script doesn’t make it better. And in the end both tasks are exactly what you have a build system for: building things, tracking dependencies between them and generating an ideal build plan or schedule.
The system-deps
crate is providing a way for expressing external dependencies in a declarative way as part of Cargo.toml
, and a similar system built into cargo and integrated with the platform’s mechanism for finding libraries would be a huge improvement. Similar approaches for the other aspects would also be helpful. And not just for making a different build system for crates, but also for developers using cargo.
I’m sure that once cargo gained features for handling the four items above there will still be a need for custom build scripts in some situations, but these four items should cover more than 95% of the currently existing build scripts. It’s a mystery to me why there are no apparent efforts being made to improve cargo in this regard.
Good Parts of meson
Now let’s focus on some of the good parts of meson in comparison to cargo.
More flexible and expressive
Generally, meson has a much more flexible and expressive build definition language. It looks more like a scripting language than the toml files used by cargo, and as such appears more complex.
However thanks to this approach, almost anything for which cargo requires custom build scripts, with the disadvantages listed above, can be written directly as part of the meson build definitions. Expressing many of these things in toml for cargo would likely become convoluted and not very straightforward, as can already be seen nowadays with e.g. platform-specific dependencies.
meson provides built-in modules with support for e.g.
- finding and checking versions of compilers of different languages and other build tools, e.g. for code generation, including the Rust bindgen tool
- testing compilation of code snippets
- finding external library dependencies and checking their versions
- defining shared/static library, excutable and code generation build targets together with how (and if) they should be installed later
- installing (and generating) data files, including specific support for e.g. library metadata (pkg-config), documentation, gobject-introspection, …
As an escape hatch, whenever something can’t be expressed by just meson, it is also possible to run external configuration/build/install scripts that could be written as a Python/shell script, C or Rust executable, or anything else really. This is rarely needed though and the meson project seems to add support for anything that people actually need in practice.
Build configuration system
meson provides an extensible configuration mechanism for the build, which allow the user building the software to customize the build process and its results.
- The built-in options allow for configuring things like switching between debug and release builds, defining toolchains and defining where to install build results.
-
The build options allow each project to extend the above with custom configuration, e.g. for enabling/disabling optional features of the project or generally selecting between different configurations. Apart from simple boolean flags this also allows for other types of configuration, including integers and strings.
cargo only provides one of the two in the form of fixed, non-extensible compiler profiles and configuration.
The second is not to be confused with cargo’s feature flags, which are more a mechanism for selecting configuration of dependencies by the developer of the software. The meson build configuration however is for the builder of the software to select different configurations. While for executables cargo feature flags are used in a similar way for boolean configurations, cargo does not provide anything for this in general.
As a workaround for this, a couple of Rust crates are using environment variables together with the env!
macro for build configuration but this is fragile and not discoverable, and more of a hack than a real solution.
Support for Rust and non-Rust code in the same project
meson supports mixing Rust and non-Rust code in the same project, and allows tracking dependencies between targets using different languages in the same way.
While it is not supported to mix Rust and e.g. C code in the same build target due to Rust’s compilation model, it is possible to e.g. build a static Rust library, a static C library and link both together into e.g. a D application or Python module. An example for this would be this Python module that combines C, C++, Rust and Fortran code.
Code generation can be handled in a similar way as in the end code generation is just another transformation from one format into another.
cargo doesn’t directly support anything but Rust code. As usual, build scripts provide a mechanism to get around this limitation. The cc crate for example is widely used to build C code and there are also crates for building meson or cmake based software as part of the build process.
All of this is completely opaque to cargo though and can’t be taken into account for defining an optimal build schedule, can’t be configured from the outside and regularly fails in non-standard build situations (e.g. cross-compilation).
Installation of other files than executables
meson allows every build result to be installed in a configurable location. This is especially useful for more complex applications that might have to provide various data files or come as an executable plus multiple libraries or plugins, or simply for projects that only provide a shared library. If any of the built-in installation mechanisms are not sufficient (e.g. the executable should be get specific process capabilities set via setcap
), meson also allows to customize the install process via scripts.
cargo only allows to install executables right now. There are cargo extensions that also allow for more complex tasks, e.g. cargo xtask but there is no standard mechanism. There once was an RFC to make cargo’s installation process extensible, but the way how this was proposed would also suffer from the same problems as the cargo build scripts.
External dependency and library support
In addition to mixing build targets with multiple languages in the same project, meson also has a mechanism to find external dependencies in different ways. If an external dependency is not found, it can be provided and built as part of the project via the wrap mechanism mentioned before. The latter is similar to how cargo handles dependencies, but the former is missing completely and currently implemented via build scripts instead, e.g. by using the pkg-config crate.
As Rust does not currently provide a stable ABI and provides no standard mechanism to locate library crates on the system, this mostly applies to library dependencies written in other languages. meson does support building Rust shared/static libraries and installing them too, but because of the lack of a stable ABI this has to be made use of very carefully.
On the other hand, Rust allows building shared/static libraries that provide the stable C ABI of the platform (cdylib
, staticlib
crate types). meson allows building these correctly too, and also offers mechanisms for installing them together with their (potentially autogenerated header files) and locating them again later in other projects via e.g. pkg-config.
For cargo this job can be taken care of by cargo-c, including actually building shared libraries correctly by setting e.g. the soname correctly and setting other kinds of versioning information.
Good Parts of cargo
After writing so much about meson and how great it is, let’s now look at some aspects of cargo that are better than what meson provides. Like I said before, both have their good sides.
Simpler and more declarative build definitions
The cargo manifest format is clearly a lot simpler and more declarative than the meson build definition format.
For a simple project it looks more like a project description than something written in a scripting language.
[package] name = "hello_world" version = "0.1.0" edition = "2021" [dependencies] anyhow = "1.0"
As long as a project stays in the boundaries of what cargo makes easy to express, which should be the case for the majority of existing Rust projects, it is going to be simpler than meson. The lack of various features in cargo that require the use of a build script prevent this currently for many crates, but that seems like something that could be easily improved.
meson on the other hand feels more like writing actual build scripts in some kind of scripting language, and information like “what dependencies does this have” are not as easily visible as from something like a Cargo.toml
.
Tooling integration
cargo provides a lot development tools that make development with it a very convenient and smooth experience. There are also dozens of cargo extension commands that provide additional features on top of cargo.
cargo init
creates a new project, cargo add
adds new dependencies, cargo check
type-checks code without full compilation, cargo clippy
runs a powerful linter, cargo doc
builds the documentation (incl. dependencies), cargo bench
and cargo test
allow running tests and benchmarks, cargo show-asm
shows the generated, annotated assembly for the code, cargo udeps
finds unused dependencies, …
All of this makes development of Rust project a smooth and well-integrated experience.
In addition rust-analyzer provides a lot of IDE features via the LSP protocol for various editors and IDEs.
Right now, IDEs and editors are assuming Rust projects to make use of cargo and offer integration with its features.
On the other hand, when using meson almost none of this is currently provided and development feels less well integrated. Right now the only features provided by meson for making Rust development easier is generation of a rust-project.json
to make use of rust-analyzer and being able to run tests in a similar way to cargo, and of course actually building the code. Building of documentation could be easily added to meson and is supported for other languages, something like cargo add
for wrap dependencies exists already and adding crates.io support to it would be possible, but it’s going to take a while and a bit of effort to handle crates with cargo build scripts. Making use of all the cargo extension commands without actually using cargo seems unrealistic.
In the end, cargo is the default build system for Rust and everything currently assumes usage of cargo so using cargo offers the best developer experience.
Rust dependencies
As shortly mentioned above, cargo add
makes it extremely easy to add new Rust dependencies to a project and build them as part of the project. This helps a lot with code reuse and modularity. That an average Rust project has dozens of direct dependencies and maybe a hundred or more indirect dependencies shows this quite clearly, as does the encapsulation of very small tasks in separate dependencies compared to huge multi-purpose libraries that are common with other languages.
cargo also directly handles updating of dependencies via cargo update
, including making sure that only semver compatible versions are automatically updated and allows including multiple incompatible versions of dependencies in the same build if necessary.
In addition to just adding dependencies, cargo features allow for conditional compilation and for defining which parts and features of a dependency should be enabled or not.
meson has some explicit handling of dependencies and the wrap system also allows building external dependencies as part of the project, but adding or updating dependencies is more manual process unless they are in the meson wrapdb. For now it is completely manual with regards to Rust crates. It is no different from adding dependencies in non-Rust languages though.
There is also no direct equivalent of the cargo feature flags, which potentially seems like a useful addition to meson.
Next steps
Considering all of the above, there is not really a simple answer to which of the two choices is the best for your project. As of now I would personally always use cargo for Rust projects if I can, especially if they will have other Rust dependencies. It’s a lot more convenient to develop with cargo.
However various features of meson might make it a better choice for some projects, maybe already now or at least in the future. For example the ability to handle multiple languages, to handle dependencies and shared libraries correctly or the ability to install data files together with the application. Or simply because the remainder of the project already uses meson for compiling e.g. C code, meson might be the more natural choice for adding Rust code to the mix.
As outlined above there are many areas of meson that could be improved and where Rust support is not very mature yet, and to make meson a more viable alternative to cargo these will have to happen sooner or later. Similarly, there are various areas where cargo also could be improved and learn from meson, and where improvements to cargo, in addition to making cargo more flexible and easier to use, would also make it easier to handle other build systems.
From a meson point of view, I would consider the following the next steps.
Various bugs and missing features
rustc and cargo
On the Rust compiler side, there are currently two minor issues that would need looking into.
- rustc#80792: Adding support for passing environment variables via the command-line instead of using actual environment variables. Environment variables are currently used for build configuration by many crates. Allowing to provide them via the command-line would allow for more clean and reliable build rules without accidentally leaking actual environment variables into the build.
- rustc#110460: Undocumented and maybe unintentional library filename requirement based on the crate name. This currently requires meson to disallow dashes in crate names and to have them explicitly replaced by underscore, which is something cargo does implicitly. Implicit conversion inside meson would also be feasible but probably not desireable because there would then be a mismatch between the name of the build target in the build definition and the actual name of the build target when building it. Similar to the mild confusion that some people ran into when noticing that a crate with a dash in the name can only be referenced with underscores from Rust code.
In addition it would be useful to look into moving various features from build scripts into proper cargo, as outlined above. This will probably need a lot of design and discussion effort, and will likely also take years after implementation until the important crates are moved to it due to very conservative Rust toolchain version requirement policies in various of these crates.
So on the cargo side that’s more something for the long run but also something that would greatly benefit users of cargo.
meson
On the meson side there are a couple of bugs of different severity that will have to be solved, and probably more that will show up once more people are starting to use meson to build Rust projects.
In addition to the ones I mentioned above and that are merged already into the meson git repository, at the time of this writing there were for example the following outstanding issues
- meson#11681: Add a feature to meson to allow renaming crates when using as a dependency. This is used throughout the Rust ecosystem for handling multiple versions of the same crate at once, or also simply for having a more convenient local name of a dependency.
- meson#11695: Parallelize the Rust build better by already starting to build the next Rust targets when the metadata of the dependencies is available. This should bring build time improvements of 10% or more on machines with enough cores, and the lack of it is the main reason why the meson build in my experiment was “only” as fast as the cargo build and not faster.
- meson#11702: Cross-compilation of
proc-macro
crates is currently using the wrong toolchain and simply doesn’t work. - meson#11694: Indirect dependencies of all dependencies are passed onwards on the later compiler invocations, which brings the risk of unnecessary name conflicts and simply causes more work for the compiler than necessary.
- meson#10030: Add support for passing environment variables to the Rust compiler. As mentioned above, many crates are currently using this for build configuration so this would have to be supported by meson in one way or another.
Apart from the second one in this list these should all be doable relatively fast and generally getting fixes and improvements required for Rust merged into meson was a fast and pleasant experience so far. I didn’t encounter any unnecessary bikeshedding or stop energy.
Tooling for managing cargo dependencies
During my experiment I wrote all the meson wrap files manually. This does not really scale, is inconvenient, and also makes it harder to update dependencies later.
The goal here would be to provide a tool in the shape of cargo add
and cargo update
that allows to automatically add cargo-based Rust dependencies to a meson project. This is something that was discussed a lot in the past and various people in the meson community have ideas and plans around this. meson already has something similar for the wrapdb, meson wrap add
and meson wrap update
, but the idea would be to have something similar (or integration into that) to directly support crates from crates.io so Rust dependencies can be added with as little effort to a meson project as they can currently to a cargo project.
Apart from the cargo build scripts this shouldn’t be a lot of effort and a project for an afternoon at most, so maybe I’ll give that a try one of these days if nobody beats me to it.
As part of such a tool, it will also be necessary to define conventions about naming, mapping of cargo features, versioning, etc. of Rust crates inside meson and this should ideally be done from early on to avoid unnecessary churn. The way how I did it as part of my experiment has various drawbacks with regards to versioning and needs improvements.
Handling cargo build scripts is a bigger issue though. As my experiment showed, about half of the crates had build scripts. While all of them were more or less trivial, automatically translating this into meson build definitions seems unrealistic to me.
It might be possible to have meson use the cargo build scripts directly in one way or another, or they would have to be translated manually to meson build definitions. The latter would considerably improve build times so seems like a better approach for common crates at least. And for those the meson build definitions could be stored in a central place, like the meson wrapdb or maybe even be included in the crates on crates.io if their maintainers feel like dealing with two build systems.
Together with all this, some thought will also have to be put into how to locate such Rust dependencies, similar to how pkg-config allows to locate shared libraries. For example, Linux distributions will want to package such dependencies and make sure that a project built for such a distribution is making use of the packaged dependencies instead of using any other version, or worse downloading some version from the Internet at build time. The way how this is currently handled by cargo is also not optimal for Linux distributions and a couple of other build and deployment scenarios.
Because of the lack of a stable Rust ABI this would mean locating Rust source code.
Tooling integration
And last, as mentioned above there is basically no tooling integration right now apart from being able to build Rust code and using rust-analyzer. meson should at least support the most basic tasks that cargo supports, and that meson already supports for other languages: running tests and benchmarks, running linters and building documentation.
Once those basic tasks are done, it might be worth investigating other tooling integration like the various cargo extension commands offer or extending those commands to handle other build systems, e.g. via the rust-project.json
that rust-analyzer uses for that purpose.