Describe the problem you are trying to solve
I'm writing a project that uses zmq
and zmq-sys
which need to be cross-compiled for arm-unknown-linux-gnueabi
.
zmq-sys
doesn't compile libzmq on its own but we can specify the lib and include directories by using LIBZMQ_LIB_DIR
and LIBZMQ_INCLUDE_DIR
. However zmq
's build.rs requires zmq-sys
, which means I also need a compiled binary for x86_64-unknown-linux-gnu
target too. So I can not just use the environment variables of zmq-sys
since LIBZMQ_LIB_DIR
will point to a wrong directory.
I did the following workaround:
[target.arm-unknown-linux-gnueabi]
linker = "arm-none-linux-gnueabi-gcc"
[target.arm-unknown-linux-gnueabi.zmq]
rustc-link-search = ["native=/home/user/zmq-example/vendor/libzmq/lib/arm"]
rustc-link-lib = ["static=zmq", "dylib=stdc++"]
[target.x86_64-unknown-linux-gnu.zmq]
rustc-link-search = ["native=/home/user/zmq-example/vendor/libzmq/lib/x86_64"]
rustc-link-lib = ["static=zmq", "dylib=stdc++"]
The problem with the above workaround is that all developers need to have the same absolute path to the compiled binaries.
Describe the solution you'd like
I would like to have a way to define a relative path in rustc-link-search
.
Another solution could be a way to define a environment variables per target.
I'm a little confused about the request for relative paths. The paths should support being relative to the package root. Is that not working for you?
You are correct, so let me rephrase: Is there a way to provide paths that are relative to my project's root (/home/user/zmq-example
) instead of zmq-sys
package's root (/home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/zmq-sys-0.9.0
).
I don't want to have absolute paths of my project's root in .cargo/config
since it restricts other developers.
So I have a workaround for this problem. I am cross-compiling DBus and have the same problem as you: I have to point the rustc-link-search
to some place inside my repository, relative to the root of the repository, not relative to where Cargo extracted the package.
In short, you have to use a build.rs
build script to set rustc-link-search
.
This is my Cargo config
file:
[build]
target = "armv7-unknown-linux-gnueabihf"
[target.armv7-unknown-linux-gnueabihf.dbus]
rustc-link-search = [
# Provided by the build script.
]
rustc-link-lib = [
"dbus-1",
"gcrypt",
"gpg-error",
"lz4",
"lzma",
"pcre",
"selinux",
"systemd",
]
And this is my build.rs
build script:
use std::env::var;
fn main() {
let manifest_dir = var("CARGO_MANIFEST_DIR").unwrap();
println!("cargo:rustc-link-search={}/libraries/lib/arm-linux-gnueabihf", manifest_dir);
println!("cargo:rustc-link-search={}/libraries/usr/lib/arm-linux-gnueabihf", manifest_dir);
}
The CARGO_MANIFEST_DIR
environment variable points to the crate with the build script, and I placed the external libraries into a libraries
folder there. After doing this the build works again, no more hard-coded absolute paths.
Furthermore in your case you would also have to read the TARGET
environment variable and set the paths according to it.
Most helpful comment
So I have a workaround for this problem. I am cross-compiling DBus and have the same problem as you: I have to point the
rustc-link-search
to some place inside my repository, relative to the root of the repository, not relative to where Cargo extracted the package.In short, you have to use a
build.rs
build script to setrustc-link-search
.This is my Cargo
config
file:And this is my
build.rs
build script:The
CARGO_MANIFEST_DIR
environment variable points to the crate with the build script, and I placed the external libraries into alibraries
folder there. After doing this the build works again, no more hard-coded absolute paths.Furthermore in your case you would also have to read the
TARGET
environment variable and set the paths according to it.