Continuing the discussion from Current solutions for key value stores:
This made me wonder whether it's good (and/or common) practice to copy source code of other libraries (e.g. C libraries) into a Rust crate, or whether it's better to automatically search for installed "native" libraries when building the crate.
I found this post by @kornel, which supposes both variants are used. This part explains how a crate searches an already installed library and links with the already installed library during building:
To make a sys crate:
[…]
- In
Cargo.toml
addlinks = <library name>
. This informs Cargo that this crate links with the given C library, and Cargo will ensure that only one copy of the library is linked. Use names without any prefix/suffix (e.g.florp
, notlibflorp.so
). Note thatlinks
is only informational and it does not actually link to anything.- Create
build.rs
file in the root of the project (or specifybuild = "<path to build.rs>"
inCargo.toml
).For the
build.rs
script the general approach is:
- Find the library.
- Select static or dynamic linking.
- Optionally build the library from source.
- Expose C headers.
Later the post also mentions a different practice where the source code is copied into the crate and the (native) library is then built from source:
If the library is unlikely to be installed on the system by default, especially when you support Windows, it's nice to automatically build it from source (and link statically).
It's a massive usability improvement for users, because they can always run
cargo build
and get something working, instead of getting errors, searching for packages, installing dependencies, setting up search paths, etc.Downloading of the source is tricky, so it's best to avoid it. The build script would need to depend on libraries for HTTP + TLS + unarchving, which itself may be bigger and more problematic to build than just bundling sources with the sys crate. Some users require builds to work off-line. So unless the library's sources are really huge, just copy them to the Rust crate (and make sure to use a compatible license for your sys crate).
Which of these variants do you prefer?
I've been quite frustrated to see the lmdb-sys
and liblmdb-sys
crates including a copy of the original source code that is now several years old and doesn't get updated. (It does get updated in the upstream, but these updates aren't merged into the crate!)
This actually reminds me of the bad practice to use outdated Docker images with software that is years old . Well, of course I can choose not to choose these crates.
P.S.: This isn't supposed to be criticizing the authors/maintainers. Nobody is really required to update their published software forever. I'm always happy for anything published as Open Source, also when it is published "as is" or doesn't get updated.