From fc3d3b80edb10ba31fe24c910498f784eca1a7d6 Mon Sep 17 00:00:00 2001 From: Ivan Nikulin Date: Tue, 1 Aug 2023 16:50:02 +0100 Subject: [PATCH] Fix builds for features that require git patches Previously we were building from the deps directory with submodules. For publishing we were copying files in sumbodules into the package. With this we were making the package directory dirty with build artifacts and applied patches. This commit change the build script's behaviour: sources are now copied to the output directory and then boringssl is built from there. In addition, this commit adds files that were missing from the package for building with patches. --- Cargo.toml | 3 +- boring-sys/Cargo.toml | 14 ++- boring-sys/build.rs | 121 ++++++++++++++++---------- boring-sys/scripts/apply_pq_patch.sh | 5 -- boring-sys/scripts/apply_rpk_patch.sh | 5 -- 5 files changed, 86 insertions(+), 62 deletions(-) delete mode 100755 boring-sys/scripts/apply_pq_patch.sh delete mode 100755 boring-sys/scripts/apply_rpk_patch.sh diff --git a/Cargo.toml b/Cargo.toml index ce0d62fec..b42a8ae1b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ members = [ resolver = "2" [workspace.package] -version = "3.0.0" +version = "3.0.1" repository = "https://github.com/cloudflare/boring" edition = "2021" @@ -19,6 +19,7 @@ tokio-boring = { version = "3.0", path = "./tokio-boring" } bindgen = { version = "0.66.1", default-features = false, features = ["runtime"] } cmake = "0.1" +fs_extra = "1.3.0" fslock = "0.2" bitflags = "1.0" foreign-types = "0.5" diff --git a/boring-sys/Cargo.toml b/boring-sys/Cargo.toml index 204c78b5c..58b04d65a 100644 --- a/boring-sys/Cargo.toml +++ b/boring-sys/Cargo.toml @@ -18,20 +18,27 @@ include = [ "/LICENSE-MIT", "/deps/boringssl/**/*.[chS]", "/deps/boringssl/**/*.asm", - "/deps/boringssl/src/**/*.cc", + "/deps/boringssl/**/*.json", + "/deps/boringssl/**/*.num", + "/deps/boringssl/**/*.txt", + "/deps/boringssl/**/*.bzl", + "/deps/boringssl/**/*.cc", "/deps/boringssl/**/CMakeLists.txt", "/deps/boringssl/**/sources.cmake", "/deps/boringssl/LICENSE", "/deps/boringssl-fips/**/*.[chS]", "/deps/boringssl-fips/**/*.asm", - "/deps/boringssl-fips/src/**/*.cc", + "/deps/boringssl/**/*.json", + "/deps/boringssl/**/*.num", + "/deps/boringssl/**/*.txt", + "/deps/boringssl-fips/**/*.bzl", + "/deps/boringssl-fips/**/*.cc", "/deps/boringssl-fips/**/CMakeLists.txt", "/deps/boringssl-fips/**/sources.cmake", "/deps/boringssl/LICENSE", "/build.rs", "/src", "/patches", - "/scripts" ] [package.metadata.docs.rs] @@ -54,4 +61,5 @@ pq-experimental = [] [build-dependencies] bindgen = { workspace = true } cmake = { workspace = true } +fs_extra = { workspace = true } fslock = { workspace = true } diff --git a/boring-sys/build.rs b/boring-sys/build.rs index 94acc1e42..cd2161ba3 100644 --- a/boring-sys/build.rs +++ b/boring-sys/build.rs @@ -6,6 +6,7 @@ use std::io; use std::io::Write; use std::path::{Path, PathBuf}; use std::process::{Command, Output}; +use std::sync::Once; // NOTE: this build script is adopted from quiche (https://github.com/cloudflare/quiche) @@ -117,12 +118,48 @@ fn get_apple_sdk_name() -> &'static str { /// Returns an absolute path to the BoringSSL source. fn get_boringssl_source_path() -> String { #[cfg(all(feature = "fips", not(feature = "fips-link-precompiled")))] - const BORING_SSL_SOURCE_PATH: &str = "deps/boringssl-fips"; + const SUBMODULE_DIR: &str = "boringssl-fips"; #[cfg(any(not(feature = "fips"), feature = "fips-link-precompiled"))] - const BORING_SSL_SOURCE_PATH: &str = "deps/boringssl"; + const SUBMODULE_DIR: &str = "boringssl"; - env::var("BORING_BSSL_SOURCE_PATH") - .unwrap_or(env!("CARGO_MANIFEST_DIR").to_owned() + "/" + BORING_SSL_SOURCE_PATH) + static COPY_SOURCES: Once = Once::new(); + + if let Ok(src_path) = env::var("BORING_BSSL_SOURCE_PATH") { + return src_path; + } + + let out_dir = env::var("OUT_DIR").unwrap(); + let src_path = Path::new(&out_dir).join(SUBMODULE_DIR); + + COPY_SOURCES.call_once(|| { + let submodule_path = Path::new(env!("CARGO_MANIFEST_DIR")) + .join("deps") + .join(SUBMODULE_DIR); + + if !submodule_path.join("CMakeLists.txt").exists() { + println!("cargo:warning=fetching boringssl git submodule"); + + run_command(Command::new("git").args([ + "submodule", + "update", + "--init", + "--recursive", + &submodule_path.display().to_string(), + ])) + .unwrap(); + } + + let _ = fs::remove_dir_all(&src_path); + fs_extra::dir::copy(submodule_path, &out_dir, &Default::default()).unwrap(); + + // NOTE: .git can be both file and dir, depening on whether it was copied from a submodule + // or created by the patches code. + let src_git_path = src_path.join(".git"); + let _ = fs::remove_file(&src_git_path); + let _ = fs::remove_dir_all(&src_git_path); + }); + + src_path.display().to_string() } /// Returns the platform-specific output path for lib. @@ -409,44 +446,58 @@ fn ensure_patches_applied() -> io::Result<()> { let out_dir = env::var("OUT_DIR").unwrap(); let mut lock_file = LockFile::open(&PathBuf::from(&out_dir).join(".patch_lock"))?; let src_path = get_boringssl_source_path(); - let is_in_submodule = Path::new(&src_path).join(".git").exists(); + let has_git = Path::new(&src_path).join(".git").exists(); lock_file.lock()?; - // NOTE: check that we are not in files copied for publishing, otherwise we will reset - // the upper level git repo which is the workspace itself. - if is_in_submodule { - println!("cargo:warning=cleaning up boringssl git submodule dir"); + // NOTE: init git in the copied files, so we can apply patches + if !has_git { + println!("cargo:warning=initing git in boringssl sources to apply patches"); - let mut cmd = Command::new("git"); - - cmd.args(["reset", "--hard"]).current_dir(&src_path); - - run_command(&mut cmd)?; - - let mut cmd = Command::new("git"); - - cmd.args(["clean", "-fdx"]).current_dir(&src_path); - - run_command(&mut cmd)?; + run_command(Command::new("git").args(["init"]).current_dir(&src_path))?; } if cfg!(feature = "pq-experimental") { println!("cargo:warning=applying experimental post quantum crypto patch to boringssl"); - run_apply_patch_script("scripts/apply_pq_patch.sh")?; + apply_patch("boring-pq.patch")?; } if cfg!(feature = "rpk") { println!("cargo:warning=applying RPK patch to boringssl"); - run_apply_patch_script("scripts/apply_rpk_patch.sh")?; + apply_patch("rpk.patch")?; } Ok(()) } +fn apply_patch(patch_name: &str) -> io::Result<()> { + let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let src_path = get_boringssl_source_path(); + let cmd_path = manifest_dir + .join("patches") + .join(patch_name) + .canonicalize()?; + + run_command( + Command::new("git") + .args([ + "apply", + "-v", + "--whitespace=fix", + &cmd_path.display().to_string(), + ]) + .current_dir(src_path), + )?; + + Ok(()) +} + fn run_command(command: &mut Command) -> io::Result { let out = command.output()?; + println!("{}", std::str::from_utf8(&out.stdout).unwrap()); + eprintln!("{}", std::str::from_utf8(&out.stderr).unwrap()); + if !out.status.success() { let err = match out.status.code() { Some(code) => format!("{:?} exited with status: {}", command, code), @@ -459,33 +510,7 @@ fn run_command(command: &mut Command) -> io::Result { Ok(out) } -fn run_apply_patch_script(script_path: impl AsRef) -> io::Result<()> { - let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - let src_path = get_boringssl_source_path(); - let cmd_path = manifest_dir.join(script_path).canonicalize()?; - - let mut cmd = Command::new(cmd_path); - cmd.current_dir(src_path); - run_command(&mut cmd)?; - - Ok(()) -} - fn build_boring_from_sources() -> String { - let src_path = get_boringssl_source_path(); - - if !Path::new(&src_path).join("CMakeLists.txt").exists() { - println!("cargo:warning=fetching boringssl git submodule"); - // fetch the boringssl submodule - let status = Command::new("git") - .args(["submodule", "update", "--init", "--recursive", &src_path]) - .status(); - - if !status.map_or(false, |status| status.success()) { - panic!("failed to fetch submodule - consider running `git submodule update --init --recursive deps/boringssl` yourself"); - } - } - ensure_patches_applied().unwrap(); let mut cfg = get_boringssl_cmake_config(); diff --git a/boring-sys/scripts/apply_pq_patch.sh b/boring-sys/scripts/apply_pq_patch.sh deleted file mode 100755 index cc4b73c0b..000000000 --- a/boring-sys/scripts/apply_pq_patch.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -git apply -v --whitespace=fix ../../patches/boring-pq.patch diff --git a/boring-sys/scripts/apply_rpk_patch.sh b/boring-sys/scripts/apply_rpk_patch.sh deleted file mode 100755 index c9f6d6114..000000000 --- a/boring-sys/scripts/apply_rpk_patch.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -git apply -v --whitespace=fix ../../patches/rpk.patch