cbindgen icon indicating copy to clipboard operation
cbindgen copied to clipboard

Cannot publish a crate if its build.rs generates a header file

Open xnuter opened this issue 3 years ago • 8 comments

My project has the following build.rs:

extern crate cbindgen;

fn main() {
    let crate_dir = env::var("CARGO_MANIFEST_DIR")
                                 .expect("CARGO_MANIFEST_DIR variable is not set");
    let out_dir = env::var("OUT_DIR")
                                 .expect("OUT_DIR variable is not set");
    cbindgen::generate(&crate_dir)
        .unwrap()
        .write_to_file(format!("{}/my_header_file.h", out_dir));
}

Cargo.toml:

[package]
name = "my_project"
version = "0.1.0"
...
build = "build.rs"

[build-dependencies]
cbindgen = "0.14"

When I try to publish the crate, it gives me an error:

➜  my_project git:(initial-commit) cargo publish --dry-run 
.....
Caused by:
  Source directory was modified by build.rs during cargo publish. 
  Build scripts should not modify anything outside of OUT_DIR.
  Added: /Users/...../target/package/my_project-0.1.0/Cargo.lock

The Rust version:

➜  my_project git:(initial-commit) rustc --version --verbose
rustc 1.45.2 (d3fb005a3 2020-07-31)
binary: rustc
commit-hash: d3fb005a39e62501b8b0b356166e515ae24e2e54
commit-date: 2020-07-31
host: x86_64-apple-darwin
release: 1.45.2
LLVM version: 10.0

xnuter avatar Aug 05 '20 16:08 xnuter

Ah, this is because cbindgen calls cargo to generate crate graph metadata information, so in your case it creates a Cargo.lock file.

Checking the file into the repository may work. Alternatively maybe remove it from the build script? Though that's not ideal :(

emilio avatar Aug 07 '20 20:08 emilio

Ah, this is because cbindgen calls cargo to generate crate graph metadata information, so in your case it creates a Cargo.lock file.

Thanks for the explanation.

Checking the file into the repository may work. Alternatively maybe remove it from the build script? Though that's not ideal :(

For now, I switched to manual header file generation and removed the build script. At least it would be a good idea to document this limitation of the build script. I followed this blog https://blog.eqrion.net/announcing-cbindgen/ and spent some time figuring out that it was the cbindgen behavior, not something wrong with my configuration, when I tried to publish my crate.

xnuter avatar Aug 08 '20 16:08 xnuter

(To be clear, above I meant "checking Cargo.lock into the repository". I believe that would fix it.

emilio avatar Aug 09 '20 09:08 emilio

If you want to produce a C-API library from your crate you might prefer to use cargo-c instead of using cbindgen from build.rs on a crate you would also publish to crates.io.

lu-zero avatar Aug 10 '20 11:08 lu-zero

I am also being bitten by this, with the variation that my crate is in a multi-crate workspace, so that there is a Cargo.lock at the toplevel, but when I try to package/publish the crate, I get this error.

edit: For now, I'm modifying my build.rs to delete the Cargo.lock file (ignoring the error if it didn't exist), and it seems like that is fixing the problem. Not ideal, but effective.

pkgw avatar Jan 02 '21 21:01 pkgw

@pkgw please use cargo-c, this kind of custom solution is a nightmare for distributions.

lu-zero avatar Jan 03 '21 07:01 lu-zero

@lu-zero I'm aware of cargo-c but it's not the right fit for my use case. I have a set of crates that must, for historical reasons, plug together using both C and Rust APIs, but they're all internal — the end result is a single rlib.

pkgw avatar Jan 03 '21 19:01 pkgw

I assumed you wanted to have the actual library installed on the system, sorry for the noise.

lu-zero avatar Jan 03 '21 19:01 lu-zero