Integrating meson and cargo

999 views
Skip to first unread message

Aaron Paden

unread,
Jun 11, 2017, 2:17:49 AM6/11/17
to The Meson Build System
Meson can compile rust just fine, but unfortunately it seems that until the Rust ecosystem stabilizes a bit and it becomes practical to distribute dynamic libraries you really need something like cargo to pull in and link all of the dependencies from crates.io.

I've looked and asked around, and it looks like Cargo can't actually do the deployment step, though. A lot of projects are using ad-hoc scripts with hardcoded paths and I think meson would fit nicely here to bring a little order to the situation.

There are some limitations in meson, though, and I can't see a way to integrate cargo and rust without having to write some intermediary scripts anyway. Here's what I've got so far. I've been toying with several iterations of this, but I'm stuck:

project('project', 'rust', version: '0.1', license: 'GPLv2')
subdir
('data')
#set_variable('CARGO_TARGET_DIR', join_paths(meson.build_root(), 'target'))
build_type
= get_option('buildtype')
bin_path
= join_paths(join_paths('target', build_type, meson.project_name()))
cargo_command
= [ find_program('cargo'),
   
'rustc', '--'.join([build_type]),
   
'--', '--cfg', 'datadir='.join([get_option('datadir')]) ]
build
= run_command(cargo_command)
custom_target
(meson.project_name(),
    input
: bin_path,
    output
: meson.project_name(),
    command
: [ 'cp', '-al', '@INPUT@', '@OUTPUT@' ],
    install
: true,
    install_dir
: 'bin',
    build_by_default
: true)


The reason the cargo command is using run_command here is that you can't reliably set the output path of an executable with cargo from the command-line. They like to use Cargo.toml for everything. You'd think that you could use `cargo rustc -- -o $filename` but that doesn't do what you expect. It puts what looks like a hash at the end of the filename. This is maybe a bug, but may also from skimming through the issue tracker it may also be because Cargo can have multiple outputs and outputting to a single file doesn't always make sense in a cargo context.

Unfortunately, this doesn't work, because custom_target cannot depend on a run_command or a run_target. Ideally, Meson would have a Cargo plugin that would just read the Cargo.toml file and Do The Right Thing™, but that seems like it would be a lot of work. More simply, perhaps custom_target could be extended to be able to depend on a run_command, insuring that it is always run first. I know you'd want to avoid that in most cases, but it shouldn't effect build performance too much here because Cargo itself can determine whether or not files need to be rebuilt.

I may have just overlooked some capability in meson that will do what I want, but for now it looks like the solution is to write a wrapper script around cargo that will put the executables in a place meson can find. This is something I can do, but I'm sure all of you will agree that writing a fragile shell script is to be avoided when possible. :)

acfo...@galois.com

unread,
Jun 30, 2017, 4:56:32 PM6/30/17
to The Meson Build System
I'm stuck on the same, after hitting the limits of what I could do just with the `std` crate on my current polyglot C++/Rust project.

 
Ideally, Meson would have a Cargo plugin that would just read the Cargo.toml file and Do The Right Thing™, but that seems like it would be a lot of work.

This sounds more appealing to me than relying on `custom_target`, because I will want to subsequently `link_with` the resulting artifacts against the C++ portions of the code.

From a design perspective, it would be odd to have one build system calling out to another, and might be against the philosophy of Meson. From a practical perspective, though, it would be very useful.

Concretely, what might such a target look like? I could imagine pulling target info out of `cargo metadata`, but how would we represent in Meson a target that builds multiple artifacts?

Regards,
Adam
Reply all
Reply to author
Forward
0 new messages