Bindgen's build failing in docsrs
I have been trying to publish my crate's version on docs.rs but bindgen's build script fails in there but not locally, I am getting the following error
Compiling nu-ansi-term v0.46.0
Compiling addr2line v0.24.2
warning: pam-sys-fork@1.0.2-alpha5: Skipping PAM bindgen for [docs.rs](http://docs.rs)
error: failed to run custom build command for \`pam-sys-fork v1.0.2-alpha5\`
Caused by:
process didn't exit successfully: \`/home/ramayen/Documents/projects/Spell/target/package/spell-framework-0.1.5/target/debug/build/pam-sys-fork-a860873abd45d4fc/build-script-build\` (exit status: 101)
\--- stdout
cargo:rustc-link-lib=pam
cargo:rustc-link-lib=pam\_misc
cargo:rerun-if-changed=wrapper.h
cargo:warning=Skipping PAM bindgen for [docs.rs](http://docs.rs)
\--- stderr
thread 'main' panicked at /home/ramayen/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/clang-sys-1.8.1/src/lib.rs:1859:1:
a \`libclang\` shared library is not loaded on this thread
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
My crate is using a dependency(say A) which uses another dependency (say B). It is B which has the C-bindings. I have tried the following:-
- Primary approch was to feature gate dep A with
#[cfg(docsrs)]and#[cfg(not(docsrs))]flags and custom feature flags by making dep A optional and adding the custom flags in default and disabling default for docs.rs like following:-
[package.metadata.docs.rs]
no-default-features = true
features = ["docs-only"]
[features]
default = ["i-slint-renderer-skia", "pam"]
docs-only = []
pam = ["pam-client2-fork"] # This is dep A.
- The above point didn't fix the issue. So, I forked both A and B dep to fix the issue in B's
build.rs. I haven't worked with bindgen previously so my knowledge in ffi's are limited, yet I configured the build.rs with cfg docsrs flags in the build.rs along with putting the contents inside and if statement which only runs if docs.rs' env variable is set. Here is the modifiedbuild.rs.
fn main() {
println!("cargo:rustc-link-lib=pam");
if cfg!(target_os = "linux") {
println!("cargo:rustc-link-lib=pam_misc");
}
println!("cargo:rerun-if-changed=wrapper.h");
#[cfg(not(docsrs))]
if std::env::var("DOCS_RS").is_err() {
#[cfg(not(docsrs))]
extern crate bindgen;
use std::env;
use std::path::PathBuf;
println!("cargo:warning=Skipping PAM bindgen for docs.rs");
// Prepare bindgen builder
let mut builder = bindgen::Builder::default()
.header("wrapper.h")
.ctypes_prefix("libc")
.opaque_type("pam_handle_t")
.blocklist_type("va_list")
.blocklist_type("__va_list")
.blocklist_type("__builtin_va_list")
.blocklist_type("__gnuc_va_list")
.blocklist_type("__va_list_tag")
.blocklist_function("pam_v.*")
.blocklist_function("pam_syslog")
.blocklist_function("pam_prompt")
// Allow all PAM constants
.allowlist_var("PAM_.*")
// Allow all PAM functions..
.allowlist_function("pam_.*")
// ..except module related functions (pam_sm_*)
.blocklist_function("pam_sm_.*");
// Platform-specific adaptions
if cfg!(target_os = "linux") {
builder = builder
.default_macro_constant_type(bindgen::MacroTypeVariation::Signed)
.raw_line("use libc::{uid_t, gid_t, group, passwd, spwd};")
.blocklist_type(".*gid_t")
.blocklist_type(".*uid_t")
.blocklist_type("group")
.blocklist_type("passwd")
.blocklist_type("spwd");
} else if cfg!(target_os = "freebsd") || cfg!(target_os = "netbsd") {
// XXX: this should include all OS that use openPAM
builder = builder
// Use libc types so our signatures are slightly nicer
.raw_line("use libc::passwd;")
.blocklist_type("passwd");
}
#[cfg(not(docsrs))]
let bindings = builder
// Finish the builder and generate the bindings.
.generate()
// Unwrap the Result and panic on failure.
.expect("Unable to generate bindings");
// Write the bindings to the $OUT_DIR/bindings.rs file.
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
#[cfg(not(docsrs))]
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings!");
}
}
I have 2 questions:
- How can this issue is resolved?
- Since
cargo publishrecompiles everything every time. It becomes difficult to reiterate over the issue, any possible setup by which I can test these issues locally before pushing the docs.