built
built copied to clipboard
Build error when using depencies during `cargo publish` for lack of Cargo.lock
When a built-dependent crate that uses .set_dependencies(true) is published, the cargo publish process builds it in an environment where the Cargo.lock file is not found. This produces mysterious-looking output like:
Compiling verdigris v0.1.1 (/home/chrysn/git/crates/verdigris/target/package/verdigris-0.1.1)
error: failed to run custom build command for `verdigris v0.1.1 (/home/chrysn/git/crates/verdigris/target/package/verdigris-0.1.1)`
Caused by:
process didn't exit successfully: `/home/chrysn/git/crates/verdigris/target/package/verdigris-0.1.1/target/debug/build/verdigris-44f3c0cf9af4093c/build-script-build` (exit code: 101)
--- stderr
thread 'main' panicked at 'Failed to acquire build-time information: Os { code: 2, kind: NotFound, message: "No such file or directory" }', build.rs:9:10
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
warning: build failed, waiting for other jobs to finish...
error: failed to verify package tarball
Caused by:
build failed
Enabling the backtrace doesn't help -- the information where inside the write_built_file_with_opts function the error occurred gets lost; it took me a strace -o .. -ff to find out which system call in the build script caused the failure.
I'm not done with this, still looking into where the file is more precisely; will keep this updated and possibly provide a patch.
As far as I can see this is expected behavior, as verdigris is a library. Only top-level crates (read: executables) get a lockfile of their own. That is, when verdigris is built as a dependency somewhere, it doesn't get to see its own dependency-tree.
The particular crate itself is more of an application practically, but the ecosystem (WASM) for which it is built practically requires it to be declared as a library.
When a library (I only tested it with verdigris being used nonsentically included into a bin crate, but should be all the same) requests to see depenencies, one of two things can happen:
- If the library is included from a path location, built dependencies do work but show just what's in that crate's Cargo.lock which is inapplicable here. This may easily pass for working for some time during development.
- Otherwise, it fails.
The steps I'd like to take (but check with you first) are:
- [x] If the Cargo.lock is not found, ensure a sensible error message is shown.
- [ ] Alter the Cargo.lock discovery process to look in the current directory rather than the manifest dir. As I understand Cargo, this will work for the cases where it already works, and change for the above case where it works and provides the wrong results / start working in the cases where it doesn't. Documentation is updated to say that unlike PKG_* and FEATURES (which always relate to the crate whose built script this is run in), DEPENDENCIES lists all the crates that are depended on in the current build (and thus, in non-leaf crates, will also list crates the current one does not depend on).
Hm, doing the second is a lot harder than anticipated -- during build time, the working directory is the crate-being-built (be it in its specified path, or if downloaded in ~/.cargo/registry/src/...). The only way to Cargo.lock would be taking OUT_PATH and stripping it down to above its target part -- not something I'd consider desirable. (There's PWD still set to the directory in which the build happens, but that's probably an artifact of my shell, and not reliable).
On the other hand, this really only seems to affect library crates (or those which Cargo treats as such). Given one can get the impression during testing that dependencies work for them, it may be a good idea to break the dependencies feature deliberately in such situations, as it will break later on anyway (when publishing or when used from a different crate that uses it without a local path); I don't know yet how that would be detected reliably. (That would also break things for my actual use case -- not sure yet how to best deal with that).