How to import crates using Meson?

Hi, I'm trying to port a fairly complex project to Rust, and since I need to heavily interface with existing C/C++ libraries, I'm trying to use a polyglot build system, in this case Meson. I managed to make it compile Rust, and link against one of the C libraries I'm using. Now, I want to use an external crate (for the sake of MWE, let's say rand). How can I make Meson automatically download and compile the crate and its dependencies, like Cargo does?

I managed to write a rand.wrap file

[wrap-git]
url = https://github.com/rust-random/rand.git
revision = 0.8.5
depth = 1
method = cargo

[provide]
dependency_names = rand-0.8-rs

and my relevant meson.build is

project('meson-test', ['rust', 'c'],
  version : '0.1',
  default_options : ['warning_level=3'],
  meson_version: '>=1.0.0')

c_lib = static_library('utils', 'utils.c')

# build cJSON lib with CMake
cjson = dependency('cJSON')

# generate cJSON Rust bindings
rust = import('rust')

generated = rust.bindgen(
    input : 'cJSON/cJSON.h',
    output : 'generated-cJSON.rs',
    dependencies : cjson,
    args : ['--no-rustfmt-bindings'],
)

rand = dependency('rand')

exe = executable('meson_test',
                 'main.rs', generated,
                 link_with: [c_lib],
                 dependencies: [cjson])

but I get the error

Run-time dependency rand found: NO (tried pkgconfig and cmake)
Looking for a fallback subproject for the dependency rand
WARNING: Subproject rand's revision may be out of date; its wrap file has changed since it was first configured

Executing subproject rand method cargo

meson.build:21: WARNING: Project targets '>=1.0.0' but uses feature introduced in '1.3.0': Cargo subproject.
meson.build:21: WARNING: Cargo subproject is an experimental feature and has no backwards compatibility guarantees.
rand| Generated Meson AST: /home/abertulli/meson-test/build/subprojects/rand/meson.build
rand| Project name: rand
rand| Project version: 0.8.5
rand| Rust compiler for the host machine: rustc -C linker=cc (rustc 1.83.0)
rand| Rust linker for the host machine: rustc -C linker=cc ld.bfd 2.38
rand| Message: Enabled features: ['alloc', 'default', 'getrandom', 'libc', 'rand_chacha', 'std', 'std_rng']
rand| Run-time dependency rand_core-0.6-rs found: NO (tried pkgconfig and cmake)

subprojects/rand/meson.build:77:-1: ERROR: Dependency "rand_core-0.6-rs" not found, tried pkgconfig and cmake

A full log can be found at /home/abertulli/meson-test/build/meson-logs/meson-log.txt

and in case it's useful, the complete log is

Determining dependency 'rand' with pkg-config executable '/usr/bin/pkg-config'
env[PKG_CONFIG_PATH]: 
env[PKG_CONFIG]: /usr/bin/pkg-config
-----------
Called: `/usr/bin/pkg-config --modversion rand` -> 1
stderr:
Package rand was not found in the pkg-config search path.
Perhaps you should add the directory containing `rand.pc'
to the PKG_CONFIG_PATH environment variable
No package 'rand' found
-----------
CMake binary for host machine is cached.
Preliminary CMake check failed. Aborting.
Run-time dependency rand found: NO (tried pkgconfig and cmake)
Looking for a fallback subproject for the dependency rand
WARNING: Subproject rand's revision may be out of date; its wrap file has changed since it was first configured

Executing subproject rand method cargo 

meson.build:21: WARNING: Project targets '>=1.0.0' but uses feature introduced in '1.3.0': Cargo subproject.
meson.build:21: WARNING: Cargo subproject is an experimental feature and has no backwards compatibility guarantees.
Generated Meson AST: /home/abertulli/meson-test/build/subprojects/rand/meson.build
Project name: rand
Project version: 0.8.5
Rust compiler for the host machine: rustc -C linker=cc (rustc 1.83.0)
Rust linker for the host machine: rustc -C linker=cc ld.bfd 2.38
Rust compiler for the build machine: rustc -C linker=cc (rustc 1.83.0)
Rust linker for the build machine: rustc -C linker=cc ld.bfd 2.38
Message: Enabled features: ['alloc', 'default', 'getrandom', 'libc', 'rand_chacha', 'std', 'std_rng']
Determining dependency 'rand_core-0.6-rs' with pkg-config executable '/usr/bin/pkg-config'
env[PKG_CONFIG_PATH]: 
env[PKG_CONFIG]: /usr/bin/pkg-config
-----------
Called: `/usr/bin/pkg-config --modversion rand_core-0.6-rs` -> 1
stderr:
Package rand_core-0.6-rs was not found in the pkg-config search path.
Perhaps you should add the directory containing `rand_core-0.6-rs.pc'
to the PKG_CONFIG_PATH environment variable
No package 'rand_core-0.6-rs' found
-----------
CMake binary for host machine is cached.
Preliminary CMake check failed. Aborting.
Run-time dependency rand_core-0.6-rs found: NO (tried pkgconfig and cmake)

subprojects/rand/meson.build:77:-1: ERROR: Dependency "rand_core-0.6-rs" not found, tried pkgconfig and cmake

What am doing wrong? Thanks!

I’m not familiar with Meson, but I would guess that the way you have configured it doesn’t process transitive dependencies of rand. Perhaps you need to write wrap files for all of them, or perhaps doing it this way will help:

Since 1.5.0 Cargo wraps can also be provided with Cargo.lock file at the root of (sub)project source tree. Meson will automatically load that file and convert it into a series of wraps definitions.

https://mesonbuild.com/Wrap-dependency-system-manual.html#cargo-wraps

That sounds like it will handle all of the dependencies in https://github.com/rust-random/rand/blob/master/Cargo.lock.msrv if you can convince it to read that file.

1 Like

Apparently, I misread: Meson will read Cargo.lock, not Cargo.toml. So I cd into the dependent package, I did a cargo build, and now it can read and download the dependencies. I don't know if it makes a difference, but I changed the crate from rand to humansize as a MWE, because the dependencies of rand are taken from the same repository, and I wanted to focus on a problem at a time. Now, however, the Meson parser seems to be broken, I'm currently investigating it

I can confirm it works, the parser error is a bug present in 1.6.0, upgrading to 1.6.1 solved the issue. Thanks! This means, for now, that for "top level" dependencies we need to provide a wrap file for each one, iiuc