diff --git a/Cargo.toml b/Cargo.toml index 1552302..a129872 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,8 @@ once_cell = "1" cc = { version = "1.0", features = ["parallel"] } [features] +default = ["link_libfuzzer"] +link_libfuzzer = [] arbitrary-derive = ["arbitrary/derive"] [workspace] diff --git a/README.md b/README.md index 8bdba6e..db6f7f5 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,29 @@ And finally, run the fuzzer: $ ./target/debug/fuzzed ``` +### Linking to a local libfuzzer + +When using `libfuzzer-sys`, you can provide your own `libfuzzer` runtime in two ways. + +If you are developing a fuzzer, you can set the `CUSTOM_LIBFUZZER_PATH` environment variable to the path of your local +`libfuzzer` runtime, which will then be linked instead of building libfuzzer as part of the build stage of `libfuzzer-sys`. +For an example, to link to a prebuilt LLVM 16 `libfuzzer`, you could use: + +```bash +$ export CUSTOM_LIBFUZZER_PATH=/usr/lib64/clang/16/lib/libclang_rt.fuzzer-x86_64.a +$ cargo fuzz run ... +``` + +Alternatively, you may also disable the default `link_libfuzzer` feature: + +In `Cargo.toml`: +```toml +[dependencies] +libfuzzer-sys = { path = "../../libfuzzer", default-features = false } +``` + +Then link to your own runtime in your `build.rs`. + ## Updating libfuzzer from upstream ``` diff --git a/build.rs b/build.rs index ab1bbc5..e549e3f 100644 --- a/build.rs +++ b/build.rs @@ -1,4 +1,4 @@ -fn main() { +fn build_and_link_libfuzzer() { println!("cargo:rerun-if-env-changed=CUSTOM_LIBFUZZER_PATH"); if let Ok(custom) = ::std::env::var("CUSTOM_LIBFUZZER_PATH") { println!("cargo:rerun-if-changed={custom}"); @@ -38,3 +38,9 @@ fn main() { build.compile("libfuzzer.a"); } } + +fn main() { + if cfg!(feature = "link_libfuzzer") { + build_and_link_libfuzzer(); + } +}