Skip to content

Commit cf8d36d

Browse files
committed
feat(build): move to cmake crate for building script in build.rs
`libbitcoinkernel-sys/build.rs` was executing a cmake binary from the environment and doing some manual flag and path configuration. The presented changes delegate the same job to the cmake crate which also handles dependencies accross environments.
1 parent 18d643a commit cf8d36d

2 files changed

Lines changed: 41 additions & 57 deletions

File tree

libbitcoinkernel-sys/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,6 @@ exclude = [
5151
publish = true
5252

5353
[build-dependencies]
54+
cmake = "0.1"
5455
cc = "1.2"
5556
bindgen = "0.72"

libbitcoinkernel-sys/build.rs

Lines changed: 40 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2,82 +2,66 @@ use bindgen::RustEdition;
22
use std::env;
33
use std::path::Path;
44
use std::path::PathBuf;
5-
use std::process::Command;
65

76
fn main() {
87
let bitcoin_dir = Path::new("bitcoin");
9-
let out_dir = env::var("OUT_DIR").unwrap();
10-
let build_dir = Path::new(&out_dir).join("bitcoin");
11-
let install_dir = Path::new(&out_dir).join("install");
12-
13-
println!("{} {}", bitcoin_dir.display(), build_dir.display());
148

159
// Iterate through all files in the Bitcoin Core submodule directory
1610
println!("cargo:rerun-if-changed={}", bitcoin_dir.display());
1711

1812
let build_config = "RelWithDebInfo";
1913

20-
Command::new("cmake")
21-
.arg("-B")
22-
.arg(&build_dir)
23-
.arg("-S")
24-
.arg(bitcoin_dir)
25-
.arg(format!("-DCMAKE_BUILD_TYPE={build_config}"))
26-
.arg("-DBUILD_KERNEL_LIB=ON")
27-
.arg("-DBUILD_TESTS=OFF")
28-
.arg("-DBUILD_BENCH=OFF")
29-
.arg("-DBUILD_KERNEL_TEST=OFF")
30-
.arg("-DBUILD_TX=OFF")
31-
.arg("-DBUILD_WALLET_TOOL=OFF")
32-
.arg("-DENABLE_WALLET=OFF")
33-
.arg("-DENABLE_EXTERNAL_SIGNER=OFF")
34-
.arg("-DBUILD_UTIL=OFF")
35-
.arg("-DBUILD_BITCOIN_BIN=OFF")
36-
.arg("-DBUILD_DAEMON=OFF")
37-
.arg("-DBUILD_UTIL_CHAINSTATE=OFF")
38-
.arg("-DBUILD_CLI=OFF")
39-
.arg("-DBUILD_FUZZ_BINARY=OFF")
40-
.arg("-DBUILD_SHARED_LIBS=OFF")
41-
.arg("-DCMAKE_INSTALL_LIBDIR=lib")
42-
.arg("-DENABLE_IPC=OFF")
43-
.arg(format!("-DCMAKE_INSTALL_PREFIX={}", install_dir.display()))
44-
.status()
45-
.expect("cmake is required to build libbitcoinkernel. Please install cmake and ensure it is in your PATH.");
46-
47-
let num_jobs = env::var("NUM_JOBS")
48-
.ok()
49-
.and_then(|v| v.parse::<u32>().ok())
50-
.unwrap_or(1); // Default to 1 if not set
14+
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();
5115

52-
Command::new("cmake")
53-
.arg("--build")
54-
.arg(&build_dir)
55-
.arg("--config")
56-
.arg(build_config)
57-
.arg(format!("--parallel={num_jobs}"))
58-
.status()
59-
.expect("Failed to run cmake build");
16+
// On Windows/MSVC, CMake normally adds /DWIN32 and /D_WINDOWS via
17+
// CMAKE_CXX_FLAGS_INIT, but setting CMAKE_CXX_FLAGS to empty overrides
18+
// that. We must restore these definitions so that code guarded by
19+
// #if defined(WIN32) (e.g. cleanse.cpp's SecureZeroMemory path) compiles
20+
// correctly instead of falling through to GCC-style inline assembly.
21+
let (c_flags, cxx_flags) = if target_os == "windows" {
22+
("/DWIN32 /D_WINDOWS", "/DWIN32 /D_WINDOWS")
23+
} else {
24+
("", "")
25+
};
6026

61-
Command::new("cmake")
62-
.arg("--install")
63-
.arg(&build_dir)
64-
.arg("--config")
65-
.arg(build_config)
66-
.status()
67-
.expect("Failed to run cmake install");
27+
let output_dir = cmake::Config::new("bitcoin")
28+
.profile(build_config)
29+
.no_default_flags(true)
30+
.define("CMAKE_C_FLAGS", c_flags)
31+
.define("CMAKE_CXX_FLAGS", cxx_flags)
32+
.define("CMAKE_ASM_FLAGS", "")
33+
.define("BUILD_KERNEL_LIB", "ON")
34+
.define("BUILD_TESTS", "OFF")
35+
.define("BUILD_BENCH", "OFF")
36+
.define("BUILD_KERNEL_TEST", "OFF")
37+
.define("BUILD_TX", "OFF")
38+
.define("BUILD_WALLET_TOOL", "OFF")
39+
.define("ENABLE_WALLET", "OFF")
40+
.define("ENABLE_EXTERNAL_SIGNER", "OFF")
41+
.define("BUILD_UTIL", "OFF")
42+
.define("BUILD_BITCOIN_BIN", "OFF")
43+
.define("BUILD_DAEMON", "OFF")
44+
.define("BUILD_UTIL_CHAINSTATE", "OFF")
45+
.define("BUILD_CLI", "OFF")
46+
.define("BUILD_FUZZ_BINARY", "OFF")
47+
.define("BUILD_SHARED_LIBS", "OFF")
48+
.define("CMAKE_INSTALL_LIBDIR", "lib")
49+
.define("ENABLE_IPC", "OFF")
50+
.build();
6851

6952
// Check if the build system used a multi-config generator
70-
let lib_dir = if install_dir.join("lib").join(build_config).exists() {
71-
install_dir.join("lib").join(build_config)
53+
let lib_dir = if output_dir.join("lib").join(build_config).exists() {
54+
output_dir.join("lib").join(build_config)
7255
} else {
73-
install_dir.join("lib")
56+
output_dir.join("lib")
7457
};
58+
7559
println!("cargo:rustc-link-search=native={}", lib_dir.display());
7660

7761
println!("cargo:rustc-link-lib=static=bitcoinkernel");
7862

7963
// Header path for bindgen
80-
let include_path = install_dir.join("include");
64+
let include_path = output_dir.join("include");
8165
let header = include_path.join("bitcoinkernel.h");
8266

8367
#[allow(deprecated)]
@@ -97,7 +81,6 @@ fn main() {
9781
.expect("Couldn't write bindings!");
9882

9983
let compiler = cc::Build::new().get_compiler();
100-
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();
10184

10285
if target_os == "windows" {
10386
println!("cargo:rustc-link-lib=bcrypt");

0 commit comments

Comments
 (0)