Open davepacheco opened 3 years ago
For what it's worth, this is still a problem, but I don't think there's a great way to solve it from pq-sys. The problem with the suggestion I had above (implemented in #37) is that these linker args aren't passed up to the builds of dependencies. So while this causes cargo test
to work on the pq-sys repo, programs that use pq-sys still can't find the library.
I experimented with a different approach where pq-sys would emit Cargo metadata saying where it found the library. You can see this in this branch. Then, in the crate that uses pq-sys, I have a build script that looks like this:
fn main() {
if let Some(rpaths) = std::env::var_os("DEP_PQ_LIBDIRS") {
for p in std::env::split_paths(&rpaths) {
println!("cargo:rustc-link-arg=-Wl,-R{}", p.to_string_lossy());
}
}
}
This works except for two caveats: first, that metadata is only available to immediate dependents. In my case, my crate depends on diesel, which depends on pq-sys. So I had to add a dummy dependency from my crate on pq-sys just so that my build script could get this metadata. This is only correct because Cargo will dedup them and only build pq-sys once. The second caveat is that it doesn't work for doctests. I hope this is just an oversight.
Ultimately, I decided to try linking statically instead. I ran into other problems with this that I'll mention in #27.
The binaries generated by
cargo
don't set RPATH, which means they don't work unless you happen to have libpq installed in a location that's on the runtime linker's default search path. That happens to be true for lots of people but definitely isn't everyone.To give you an example, in my case, I've got
pg_config
and the libraries are here:If I run
cargo test
from a clean checkout (looking at 3e367d53019a2740054d5dc6946e07931f1fb70b, the tip of master right now), it builds okay but fails at runtime:The reason is that the built binary depends on libpq (which is correct) but the RPATH does not include /opt/ooce/pgsql-13.
Cargo does not have great support for setting the RPATH -- see rust-lang/cargo#5077. I can work around this on my system using the
cargo:rustc-link-arg
instruction to pass-Wl,-R/the/library/path
to the compiler driver at build time. I will test this out on a few systems and send a PR shortly!