Build crates in specific order. rust-zmq libsodium-sys

Hi,
libindy uses two crates zmq and sodiumoxide.
I want to cross-compile for Android and both zmq and sodiumoxide allow to be build from source.
sodiumoxide uses libsodium-sys (part of sodiumoxide) to build from source
zmq uses zeromq-src-rs

Problem is that now libsodium.a is build twice and linked twice which fails.

How do I tell cargo that it should build sodiumoxide first and then zmq?
zmq-src-rs can be told to use headers and lib built somewhere else.

So, it is not so that zmq has a dependency on sodiumoxide. If that were the case then cargo would just do the right thing. But introducing such a dependency would be wrong, I think.

An issue for libindy is here https://github.com/hyperledger/indy-sdk/pull/1672

Is there a Rust way to do this or are we doing this wrong?

Thank you
Axel




1 Like

You can’t. zeromq-src-rs should add libsodium-sys as a dependency instead.

Thanks, @jean-airoldie, the maintainer of zeromq-src-rs, says he will follow your suggestion.

Would be nice if building from source were somewhat supported by cargo. Currently the different build.rs of people adding support for this to their crate are … complicated. Everybody is reinventing the wheel in unzipping, untaring, platform handling, feature handling, cross-compilation handling.
Would be nice to have support for the most common build systems cmake and autoconf

Thanks again.

ps: I read https://kornel.ski/rust-sys-crate Still a lot of work and things to concider.

There is https://crates.io/crates/cmake for use in build.rs

Crates that link libraries should also set the links field in Cargo.toml, although it wouldn’t help this case if zeromq-src still declared a different links than libsodium-sys.

1 Like

Is there anything in libindy’s Cargo.toml I can do?
I know that whichever Rust sodium crate I choose (sodiumoxide or https://github.com/zonyitoo/libsodium-ffi) that in the end libindy will be linked against ‘sodium’. Either the one installed on my build system or the one that whichever created for the target platform.

Just out of curiosity I tried `links=[“ssl”, “crypt”, “zmq”, “sodium”] but cargo does not like this.
Is there a way to specify multiple libraries in ‘links’ or is this a stupid idea or un-idiomatic?

links doesn’t cause anything to be linked.

It’s a warning for cargo telling it that this is a sys crate and it already causes that library to be linked somehow. Because one sys crate should handle one library, having this declaration limited to one library is fine.

It’s an error to use this attribute in any crate that isn’t purely a sys crate.

libindy is the rather rare case of a c-callable library implemented in Rust.
The result of cargo build for libindy is a libindy.a/so which needs openssl’s libcrypt and libzmq and libsodium to be build.