Find out Rust crates' system library dependencies

I've been trying to get my CLI app, Ferium, to compile on the Homebrew CI. A lot of my dependencies/crates require manual installation of libraries (and their dependencies too) through the package manager for compilation. For example the onig crate requires the oniguruma library to be installed on the system compiling. But finding out which libraries I need to specify as build dependencies is a huge pain. This is my current process:

  1. Wait for 8-10mins for the CI build to fail due to a missing library
  2. Add the missing library as a dependency to the Homebrew formula
  3. Commit and push
  4. Repeat

This is taking an insane amount of time and I've been spending pretty much the whole day doing this. As far as I know there isn't a way to know exactly what external libraries a crate requires because they're all in an ambiguous build.rs file. Any recommendations on how to improve this supremely inefficient process?

Edit: Finding out online what the libraries required by 420 (nice) dependencies is not viable

Most builtin cargo commands have a --message-format=json argument which causes it to emit messages as JSON instead of normal text. Crates like cargo-metadata wrap this process and deserialize the JSON to give you normal Rust objects.

Using Message::from_stream() you can also consume normal output from cargo build --message-format=json and look for the Message::BuildScriptExecuted message. The BuildScript you get contains all the information a build script has communicated to cargo. The fields you probably care about are linked_libs and linked_paths.

This will give you a list of all external libraries that the build tries to link to, and from there you'll need to figure out whether they are installed/accessible (although a simple test would be to run locate foo if you have GNU locate installed).

1 Like

Unfortunately system dependencies are not visible to Rust/Cargo, so it can't really know what's needed until some build script fails, or even until the final linking step fails.

You can have a guess based on the *-sys crate naming convention. Run:

cargo tree

and search for -sys.

cargo tree --all-features --target=all | fgrep -- -sys
2 Likes