build_and_link_libfuzzer()1 fn build_and_link_libfuzzer() {
2     println!("cargo:rerun-if-env-changed=CUSTOM_LIBFUZZER_PATH");
3     if let Ok(custom) = ::std::env::var("CUSTOM_LIBFUZZER_PATH") {
4         println!("cargo:rerun-if-changed={custom}");
5 
6         let custom_lib_path = ::std::path::PathBuf::from(&custom);
7         let custom_lib_dir = custom_lib_path.parent().unwrap().to_string_lossy();
8 
9         let custom_lib_name = custom_lib_path.file_stem().unwrap().to_string_lossy();
10         let custom_lib_name = custom_lib_name
11             .strip_prefix("lib")
12             .unwrap_or(custom_lib_name.as_ref());
13 
14         println!("cargo:rustc-link-search=native={}", custom_lib_dir);
15         println!("cargo:rustc-link-lib=static={}", custom_lib_name);
16 
17         match std::env::var("CUSTOM_LIBFUZZER_STD_CXX") {
18             // Default behavior for backwards compat.
19             Err(_) => println!("cargo:rustc-link-lib=stdc++"),
20             Ok(s) if s == "none" => (),
21             Ok(s) => println!("cargo:rustc-link-lib={}", s),
22         }
23     } else {
24         let mut build = cc::Build::new();
25         let sources = ::std::fs::read_dir("libfuzzer")
26             .expect("listable source directory")
27             .map(|de| de.expect("file in directory").path())
28             .filter(|p| p.extension().map(|ext| ext == "cpp") == Some(true))
29             .collect::<Vec<_>>();
30         for source in sources.iter() {
31             println!("cargo:rerun-if-changed={}", source.display());
32             build.file(source.to_str().unwrap());
33         }
34         build.flag("-std=c++17");
35         build.flag("-fno-omit-frame-pointer");
36         build.flag("-w");
37         build.cpp(true);
38         build.compile("libfuzzer.a");
39     }
40 }
41 
main()42 fn main() {
43     if cfg!(feature = "link_libfuzzer") {
44         build_and_link_libfuzzer();
45     }
46 }
47