112a9d9c8Sopenharmony_ci# Create a `build.rs` File
212a9d9c8Sopenharmony_ci
312a9d9c8Sopenharmony_ciWe create a `build.rs` file in our crate's root. Cargo will pick up on the existence of this file, then compile and execute it before the rest of the crate is built.
412a9d9c8Sopenharmony_ciThis can be used to generate code at compile time.
512a9d9c8Sopenharmony_ciAnd of course in our case, we will be generating Rust FFI
612a9d9c8Sopenharmony_cibindings to `bzip2` at compile time. The resulting bindings will be written to
712a9d9c8Sopenharmony_ci`$OUT_DIR/bindings.rs` where `$OUT_DIR` is chosen by `cargo` and is something
812a9d9c8Sopenharmony_cilike `./target/debug/build/bindgen-tutorial-bzip2-sys-afc7747d7eafd720/out/`.
912a9d9c8Sopenharmony_ci
1012a9d9c8Sopenharmony_ciNote that the associated shared object to `bz2` is `libbz2.so`. In general, a `lib<name>.so` should be referenced in the build file by `<name>`.
1112a9d9c8Sopenharmony_ci
1212a9d9c8Sopenharmony_ci```rust,ignore
1312a9d9c8Sopenharmony_ciextern crate bindgen;
1412a9d9c8Sopenharmony_ci
1512a9d9c8Sopenharmony_ciuse std::env;
1612a9d9c8Sopenharmony_ciuse std::path::PathBuf;
1712a9d9c8Sopenharmony_ci
1812a9d9c8Sopenharmony_cifn main() {
1912a9d9c8Sopenharmony_ci    // Tell cargo to look for shared libraries in the specified directory
2012a9d9c8Sopenharmony_ci    println!("cargo:rustc-link-search=/path/to/lib");
2112a9d9c8Sopenharmony_ci
2212a9d9c8Sopenharmony_ci    // Tell cargo to tell rustc to link the system bzip2
2312a9d9c8Sopenharmony_ci    // shared library.
2412a9d9c8Sopenharmony_ci    println!("cargo:rustc-link-lib=bz2");
2512a9d9c8Sopenharmony_ci
2612a9d9c8Sopenharmony_ci    // Tell cargo to invalidate the built crate whenever the wrapper changes
2712a9d9c8Sopenharmony_ci    println!("cargo:rerun-if-changed=wrapper.h");
2812a9d9c8Sopenharmony_ci
2912a9d9c8Sopenharmony_ci    // The bindgen::Builder is the main entry point
3012a9d9c8Sopenharmony_ci    // to bindgen, and lets you build up options for
3112a9d9c8Sopenharmony_ci    // the resulting bindings.
3212a9d9c8Sopenharmony_ci    let bindings = bindgen::Builder::default()
3312a9d9c8Sopenharmony_ci        // The input header we would like to generate
3412a9d9c8Sopenharmony_ci        // bindings for.
3512a9d9c8Sopenharmony_ci        .header("wrapper.h")
3612a9d9c8Sopenharmony_ci        // Tell cargo to invalidate the built crate whenever any of the
3712a9d9c8Sopenharmony_ci        // included header files changed.
3812a9d9c8Sopenharmony_ci        .parse_callbacks(Box::new(bindgen::CargoCallbacks))
3912a9d9c8Sopenharmony_ci        // Finish the builder and generate the bindings.
4012a9d9c8Sopenharmony_ci        .generate()
4112a9d9c8Sopenharmony_ci        // Unwrap the Result and panic on failure.
4212a9d9c8Sopenharmony_ci        .expect("Unable to generate bindings");
4312a9d9c8Sopenharmony_ci
4412a9d9c8Sopenharmony_ci    // Write the bindings to the $OUT_DIR/bindings.rs file.
4512a9d9c8Sopenharmony_ci    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
4612a9d9c8Sopenharmony_ci    bindings
4712a9d9c8Sopenharmony_ci        .write_to_file(out_path.join("bindings.rs"))
4812a9d9c8Sopenharmony_ci        .expect("Couldn't write bindings!");
4912a9d9c8Sopenharmony_ci}
5012a9d9c8Sopenharmony_ci```
5112a9d9c8Sopenharmony_ci
5212a9d9c8Sopenharmony_ciNow, when we run `cargo build`, our bindings to `bzip2` are generated on the
5312a9d9c8Sopenharmony_cifly!
5412a9d9c8Sopenharmony_ci
5512a9d9c8Sopenharmony_ci[There's more info about `build.rs` files in the crates.io documentation.][build-rs]
5612a9d9c8Sopenharmony_ci
5712a9d9c8Sopenharmony_ci[build-rs]: http://doc.crates.io/build-script.html
58