oxedyne/fe2o3/fe2o3_crypto/build.rs
5.0 KiB, 14 runs
created by r1870400018:146, which is this file's identity for as long as the history lasts, whatever it is later renamed to
download · who wrote it · its history
| 1 | #[cfg(feature = "pq")] |
| 2 | extern crate bindgen; |
| 3 | |
| 4 | #[cfg(feature = "pq")] |
| 5 | use std::{ |
| 6 | env, |
| 7 | fs::File, |
| 8 | io::Write, |
| 9 | path::{ |
| 10 | Path, |
| 11 | PathBuf, |
| 12 | }, |
| 13 | process::Command, |
| 14 | }; |
| 15 | |
| 16 | /// Without the `pq` feature there is no C to compile and nothing to bind, so the build script does |
| 17 | /// nothing at all. This is what lets the crate be built for a target that has no C toolchain, which |
| 18 | /// is to say for a browser. |
| 19 | #[cfg(not(feature = "pq"))] |
| 20 | fn main() { |
| 21 | println!("cargo:rerun-if-changed=build.rs"); |
| 22 | } |
| 23 | |
| 24 | #[cfg(feature = "pq")] |
| 25 | #[allow(dead_code)] // for unused Scheme variants |
| 26 | fn main() { |
| 27 | |
| 28 | enum Scheme { |
| 29 | LightSaber, |
| 30 | Saber, |
| 31 | FireSaber, |
| 32 | } |
| 33 | // Single point to select which C library to use: |
| 34 | let scheme = Scheme::FireSaber; //<<<<<<<<<< YOU SET THIS |
| 35 | |
| 36 | let scheme_lib = match scheme { |
| 37 | Scheme::LightSaber => "liblightsaber.a", |
| 38 | Scheme::Saber => "libsaber.a", |
| 39 | Scheme::FireSaber => "libfiresaber.a", |
| 40 | }; |
| 41 | |
| 42 | // Tell cargo to only rerun when the C source dir or build.rs |
| 43 | // itself change. Without these directives cargo reruns this |
| 44 | // build script on every invocation, which would re-trigger the |
| 45 | // ./build_all shell script below every single time. |
| 46 | println!("cargo:rerun-if-changed=src/c"); |
| 47 | println!("cargo:rerun-if-changed=build.rs"); |
| 48 | |
| 49 | // Run the C build only if the selected static library is |
| 50 | // missing. The `rerun-if-changed` directive above covers the |
| 51 | // "C source changed" case; this existence check is a belt-and- |
| 52 | // braces defence for the case where the tree still has a |
| 53 | // previous clean build's artefacts present. |
| 54 | let c_dir = Path::new("src/c"); |
| 55 | let lib_path = c_dir.join(scheme_lib); |
| 56 | if !lib_path.exists() { |
| 57 | env::set_current_dir(c_dir).expect("Could not change to C directory"); |
| 58 | |
| 59 | let output = Command::new("./build_all") |
| 60 | .output() |
| 61 | .expect("Failed to execute script to generate SABER C static libraries."); |
| 62 | |
| 63 | env::set_current_dir(Path::new("../..")).expect("Could not change back to workspace directory"); |
| 64 | |
| 65 | println!("status: {}", output.status); |
| 66 | let mut file = File::create("build.log").expect("Creation of build.log file failed."); |
| 67 | file.write_all(b"Stdout>>>>>>>>>>>>>\n").expect("Write to build.log failed."); |
| 68 | file.write_all(output.stdout.as_slice()).expect("Write to build.log failed."); |
| 69 | file.write_all(b"Stderr>>>>>>>>>>>>>\n").expect("Write to build.log failed."); |
| 70 | file.write_all(output.stderr.as_slice()).expect("Write to build.log failed."); |
| 71 | |
| 72 | if !lib_path.exists() { |
| 73 | panic!( |
| 74 | "SABER C build did not produce {} -- check fe2o3_crypto/build.log. \ |
| 75 | Common cause: libssl-dev is not installed.", |
| 76 | lib_path.display(), |
| 77 | ); |
| 78 | } |
| 79 | } |
| 80 | |
| 81 | println!("cargo:rustc-link-search=/usr/lib/x86_64-linux-gnu"); |
| 82 | println!("cargo:rustc-link-lib=static=crypto"); |
| 83 | // libcrypto.a pulls in compression-library symbols (zlib + zstd) |
| 84 | // via its c_zlib.o / c_zstd.o wrappers. Link them dynamically so |
| 85 | // the test binary can resolve them. Downstream binaries that link |
| 86 | // this crate as a lib usually pick these up transitively from |
| 87 | // another dependency, so the failure only surfaces for |
| 88 | // `cargo test -p fe2o3_crypto`. |
| 89 | println!("cargo:rustc-link-lib=z"); |
| 90 | println!("cargo:rustc-link-lib=zstd"); |
| 91 | |
| 92 | let dir = env::var("CARGO_MANIFEST_DIR").unwrap(); |
| 93 | println!( |
| 94 | "cargo:rustc-link-search={}", |
| 95 | Path::new(&dir).join("src/c").display(), |
| 96 | ); |
| 97 | match scheme { |
| 98 | Scheme::LightSaber => { |
| 99 | println!("cargo:rustc-env=SABER_SCHEME=LIGHTSABER"); |
| 100 | println!("cargo:rustc-cfg=SABER_SCHEME=\"LIGHTSABER\""); |
| 101 | println!("cargo:rustc-link-lib=static=lightsaber"); |
| 102 | }, |
| 103 | Scheme::Saber => { |
| 104 | println!("cargo:rustc-env=SABER_SCHEME=SABER"); |
| 105 | println!("cargo:rustc-cfg=SABER_SCHEME=\"SABER\""); |
| 106 | println!("cargo:rustc-link-lib=static=saber"); |
| 107 | }, |
| 108 | Scheme::FireSaber => { |
| 109 | println!("cargo:rustc-env=SABER_SCHEME=FIRESABER"); |
| 110 | println!("cargo:rustc-cfg=SABER_SCHEME=\"FIRESABER\""); |
| 111 | println!("cargo:rustc-link-lib=static=firesaber"); |
| 112 | }, |
| 113 | } |
| 114 | |
| 115 | println!("cargo:rustc-check-cfg=cfg(SABER_SCHEME, \ |
| 116 | values(\"LIGHTSABER\", \"SABER\", \"FIRESABER\"))"); |
| 117 | |
| 118 | println!("cargo:rustc-link-lib=ssl"); |
| 119 | println!("cargo:rustc-link-lib=crypto"); |
| 120 | |
| 121 | let wrapper_path = Path::new(&dir).join("src/c/bindgen_wrapper.h"); |
| 122 | println!( |
| 123 | "cargo:rerun-if-changed={}", |
| 124 | wrapper_path.display(), |
| 125 | ); |
| 126 | |
| 127 | let bindings = bindgen::Builder::default() |
| 128 | .header(wrapper_path.to_str().unwrap()) |
| 129 | .parse_callbacks(Box::new(bindgen::CargoCallbacks)) |
| 130 | .generate() |
| 131 | .expect("Unable to generate bindings"); |
| 132 | |
| 133 | // Write the bindings to the $OUT_DIR/bindings.rs file. |
| 134 | let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); |
| 135 | bindings |
| 136 | .write_to_file(out_path.join("bindings.rs")) |
| 137 | .expect("Couldn't write bindings!"); |
| 138 | |
| 139 | } |