Bindgen: ld returned exit code 1

Hey! I'm trying to link to the C library wkhtmltopdf with bindgen. My build.rs looks like this

extern crate bindgen;

use std::env;
use std::path::PathBuf;

fn main() {
    // Tell cargo to tell rustc to link the system wkhtmltopdf
    // shared library.
    println!("cargo:rustc-link-search=native=./libwkhtmltopdf");
    println!("cargo:rustc-link-lib=libwkhtmltopdf");

    // Tell cargo to invalidate the built crate whenever the wrapper changes
    println!("cargo:rerun-if-changed=./libwkhtmltopdf/src/lib/pdf.h");

    // The bindgen::Builder is the main entry point
    // to bindgen, and lets you build up options for
    // the resulting bindings.
    let bindings = bindgen::Builder::default()
        // The input header we would like to generate
        // bindings for.
        .header("wrapper.h")
        // Tell cargo to invalidate the built crate whenever any of the
        // included header files changed.
        .parse_callbacks(Box::new(bindgen::CargoCallbacks))
        // 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());
    bindings
        .write_to_file(out_path.join("bindings.rs"))
        .expect("Couldn't write bindings!");
}

The library source is located in the projects directory in ./libwkhtmltopdf and the bindings are created. cargo build compiles, but since the lib is not linked to until the executable gets called thats obvious. However cargo test fails with the following error message:

/usr/bin/ld: cannot find -llibwkhtmltopdf
          collect2: error: ld returned 1 exit status

Any ideas?

Try changing to println!("cargo:rustc-link-lib=wkhtmltopdf");

I did that. Didn't solve the problem.

I feel like this is caused by not linking against the compiled version of the library. I have the source of this library in my project directory and tried using cc to compile a libwkhtmltopdf.a file that I can use later on. Is this even the right approach?

My knowledge in the C library environment is pretty narrow so I think this is mainly the source of the error.

Use cargo:rustc-link-lib=wkhtmltopdf without the lib prefix. Otherwise it will look for liblib….

If that doesn't help, also try using absolute path for the search path (either fs::canonicalize("libwkhtmltopdf") or join with CARGO_MANIFEST_DIR)

This sadly didnt work. The error message persists.

I'm gonna try to elaborate on my current state:

I'm now usin cc to compile after the bindings are created in build.rs.
Since I really only import one header called pdf.h but compiling just that into a object is not possible I wrapped it into a .c file that just evokes #include "pathToPdf/pdf.h"

Is that a valid approach or am I doing this whole thing wrong?

You can't use "just a header". Headers don't compile to executable code, they usually only contain declarations. You will need to compile the C files in the library as well.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.