In a crate I made, the build.rs tells the compiler to add the path and name of the necessary shared library.
When I build, a file target/debug/build/vzense-rust-.../ouput is created and contains exactly the information build.rs generated with the correct paths
Ok, one step forward.
According to the Cargo reference regarding dynamic library paths
Paths outside of the target directory are removed.
So that's why the paths were not accepted. So I followed this hack from another crate and copy the shared libraries to target/<buildType>/deps/ in build.rs.
If there is a better way to do this, that would be great though.
At least now when I use the crate in another project and do cargo run, it finds the libraries. Yay!
But... the executable is not self contained. It only works if Cargo sets the LD_LIBRARY_PATH. I do all the rustc-link-arg and -rpath stuff in build.rs, and if I build the example included in the crate itself, the executable is self-contained. What's the difference?
Then again, I ask myself why I really have to do all of this copying to deps?
Should the -rpath not work for ANY path? It should inject the path info into the executable and has nothing to do with Cargo, right? Could somebody please confirm this?
Then the actual question is, if I set an -rpath in the build.rs of a crate, should this info not be forwarded to the executable build in a project which uses the crate?
Dusting off my somewhat aged knowledge about linking here. You create a dynamically linked binary, linking against the .so version of the library. That's the traditional way of linking on Unix, as it allows using one library for many binaries, keeping binary sizes small. One can even update the library without recompiling the binary.
Now times have changed, people no longer care about binary sizes and update-ability, they want self-contained binaries. One achieves this by static linking. This is done by adding the .a version of the library like any other compiled object file to the linking process. My best guess is something like
Thanks @Traumflug. Yes, this makes all good sense.
Unfortunately, the dynamic library (.so) is all I have. The sdk of the camera vendor provides only the dynamic library and there is no way of creating a static one from a dynamic one.
I'm not sure about this, but I think static libraries can somehow be reverse engineered to read the source, so many companies would not share those for intellectual property concerns.
IIRC, dynamic libraries contain the same as static libraries, plus some info to allow this linking at runtime. Maybe that vendor isn't up to the latest fashion, yet (this new fashion makes no sense to me either, still it exists).
Converting a dynamic to a static one should be possible, it's just rarely needed. A quick googling brings up ELF Statifier.
That said, having only a dynamic library your other options are to a) bundle your app somehow and b) depend on that dynamic library. It should be possible to link against the version copied into the Rust project and later use the system-wide version, with an appropriate LD_LIBRARY_PATH each time. The dynamic linker has a number of built in paths, on a plain Debian installation LD_LIBRARY_PATH isn't set at all. See ldconfig(8).
The worrying thing is lack of licence on the library.
That's right, thanks for pointing that out @jonh! I totally missed that.
I asked the ppl at the Vzense SDK repo if it would be possible to add a license. Other recent Vzense repos have a BSD 3-Clause license, so I hope it is possible.
I also yanked the crates and wrote to crates.io.