Merge pull request #23 from jvff/split-off-secp256k1-build
Build the `secp256k1` C files separately
This commit is contained in:
commit
ffb4c0cb76
156
build.rs
156
build.rs
|
@ -46,26 +46,12 @@ fn bindgen_headers() -> Result<()> {
|
|||
fn main() -> Result<()> {
|
||||
bindgen_headers()?;
|
||||
|
||||
// Check whether we can use 64-bit compilation
|
||||
let use_64bit_compilation = if env::var("CARGO_CFG_TARGET_POINTER_WIDTH").unwrap() == "64" {
|
||||
let check = cc::Build::new()
|
||||
.file("depend/check_uint128_t.c")
|
||||
.cargo_metadata(false)
|
||||
.try_compile("check_uint128_t")
|
||||
.is_ok();
|
||||
if !check {
|
||||
println!("cargo:warning=Compiling in 32-bit mode on a 64-bit architecture due to lack of uint128_t support.");
|
||||
}
|
||||
check
|
||||
} else {
|
||||
false
|
||||
};
|
||||
let target = env::var("TARGET").expect("TARGET was not set");
|
||||
let is_big_endian = env::var("CARGO_CFG_TARGET_ENDIAN").expect("No endian is set") == "big";
|
||||
let mut base_config = cc::Build::new();
|
||||
|
||||
language_std(&mut base_config, "c++17");
|
||||
|
||||
base_config
|
||||
.cpp(true)
|
||||
.include("depend/zcash/src")
|
||||
.include("depend/zcash/src/rust/include/")
|
||||
.include("depend/zcash/src/secp256k1/include")
|
||||
|
@ -73,50 +59,15 @@ fn main() -> Result<()> {
|
|||
.flag_if_supported("-Wno-catch-value")
|
||||
.flag_if_supported("-Wno-reorder")
|
||||
.flag_if_supported("-Wno-deprecated-copy")
|
||||
.flag_if_supported("-Wno-unused-parameter")
|
||||
// when compiling using Microsoft Visual C++, ignore warnings about unused arguments
|
||||
.flag_if_supported("/wd4100")
|
||||
.define("HAVE_DECL_STRNLEN", "1")
|
||||
.define("__STDC_FORMAT_MACROS", None);
|
||||
|
||||
// **Secp256k1**
|
||||
if !cfg!(feature = "external-secp") {
|
||||
base_config
|
||||
.include("depend/zcash/src/secp256k1")
|
||||
.flag_if_supported("-Wno-unused-function") // some ecmult stuff is defined but not used upstream
|
||||
.flag_if_supported("-Wno-missing-field-initializers")
|
||||
.define("SECP256K1_BUILD", "1")
|
||||
// zcash core defines libsecp to *not* use libgmp.
|
||||
.define("USE_NUM_NONE", "1")
|
||||
.define("USE_FIELD_INV_BUILTIN", "1")
|
||||
.define("USE_SCALAR_INV_BUILTIN", "1")
|
||||
.define("ECMULT_WINDOW_SIZE", "15")
|
||||
.define("ECMULT_GEN_PREC_BITS", "4")
|
||||
// Use the endomorphism optimization now that the patents have expired.
|
||||
.define("USE_ENDOMORPHISM", "1")
|
||||
// Technically libconsensus doesn't require the recovery feature, but `pubkey.cpp` does.
|
||||
.define("ENABLE_MODULE_RECOVERY", "1")
|
||||
// The actual libsecp256k1 C code.
|
||||
.file("depend/zcash/src/secp256k1/src/secp256k1.c");
|
||||
|
||||
if is_big_endian {
|
||||
base_config.define("WORDS_BIGENDIAN", "1");
|
||||
}
|
||||
|
||||
if use_64bit_compilation {
|
||||
base_config
|
||||
.define("USE_FIELD_5X52", "1")
|
||||
.define("USE_SCALAR_4X64", "1")
|
||||
.define("HAVE___INT128", "1");
|
||||
} else {
|
||||
base_config
|
||||
.define("USE_FIELD_10X26", "1")
|
||||
.define("USE_SCALAR_8X32", "1");
|
||||
}
|
||||
}
|
||||
|
||||
let tool = base_config.get_compiler();
|
||||
if tool.is_like_msvc() {
|
||||
base_config.flag("/std:c++17").flag("/wd4100");
|
||||
} else if tool.is_like_clang() || tool.is_like_gnu() {
|
||||
base_config.flag("-std=c++17").flag("-Wno-unused-parameter");
|
||||
build_secp256k1();
|
||||
}
|
||||
|
||||
if target.contains("windows") {
|
||||
|
@ -142,3 +93,98 @@ fn main() -> Result<()> {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Build the `secp256k1` library.
|
||||
fn build_secp256k1() {
|
||||
let mut build = cc::Build::new();
|
||||
|
||||
// Compile C99 code
|
||||
language_std(&mut build, "c99");
|
||||
|
||||
// Define configuration constants
|
||||
build
|
||||
.define("SECP256K1_BUILD", "1")
|
||||
.define("USE_NUM_NONE", "1")
|
||||
.define("USE_FIELD_INV_BUILTIN", "1")
|
||||
.define("USE_SCALAR_INV_BUILTIN", "1")
|
||||
.define("ECMULT_WINDOW_SIZE", "15")
|
||||
.define("ECMULT_GEN_PREC_BITS", "4")
|
||||
// Use the endomorphism optimization now that the patents have expired.
|
||||
.define("USE_ENDOMORPHISM", "1")
|
||||
// Technically libconsensus doesn't require the recovery feature, but `pubkey.cpp` does.
|
||||
.define("ENABLE_MODULE_RECOVERY", "1")
|
||||
// The source files look for headers inside an `include` sub-directory
|
||||
.include("depend/zcash/src/secp256k1")
|
||||
// Some ecmult stuff is defined but not used upstream
|
||||
.flag_if_supported("-Wno-unused-function")
|
||||
.flag_if_supported("-Wno-unused-parameter");
|
||||
|
||||
if is_big_endian() {
|
||||
build.define("WORDS_BIGENDIAN", "1");
|
||||
}
|
||||
|
||||
if is_64bit_compilation() {
|
||||
build
|
||||
.define("USE_FIELD_5X52", "1")
|
||||
.define("USE_SCALAR_4X64", "1")
|
||||
.define("HAVE___INT128", "1");
|
||||
} else {
|
||||
build
|
||||
.define("USE_FIELD_10X26", "1")
|
||||
.define("USE_SCALAR_8X32", "1");
|
||||
}
|
||||
|
||||
build
|
||||
.file("depend/zcash/src/secp256k1/src/secp256k1.c")
|
||||
.compile("libsecp256k1.a");
|
||||
}
|
||||
|
||||
/// Checker whether the target architecture is big endian.
|
||||
fn is_big_endian() -> bool {
|
||||
let endianess = env::var("CARGO_CFG_TARGET_ENDIAN").expect("No endian is set");
|
||||
|
||||
endianess == "big"
|
||||
}
|
||||
|
||||
/// Check whether we can use 64-bit compilation.
|
||||
fn is_64bit_compilation() -> bool {
|
||||
let target_pointer_width =
|
||||
env::var("CARGO_CFG_TARGET_POINTER_WIDTH").expect("Target pointer width is not set");
|
||||
|
||||
if target_pointer_width == "64" {
|
||||
let check = cc::Build::new()
|
||||
.file("depend/check_uint128_t.c")
|
||||
.cargo_metadata(false)
|
||||
.try_compile("check_uint128_t")
|
||||
.is_ok();
|
||||
|
||||
if !check {
|
||||
println!(
|
||||
"cargo:warning=Compiling in 32-bit mode on a 64-bit architecture due to lack of \
|
||||
uint128_t support."
|
||||
);
|
||||
}
|
||||
|
||||
check
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Configure the language standard used in the build.
|
||||
///
|
||||
/// Configures the appropriate flag based on the compiler that's used.
|
||||
///
|
||||
/// This will also enable or disable the `cpp` flag if the standard is for C++. The code determines
|
||||
/// this based on whether `std` starts with `c++` or not.
|
||||
fn language_std(build: &mut cc::Build, std: &str) {
|
||||
build.cpp(std.starts_with("c++"));
|
||||
|
||||
let flag = if build.get_compiler().is_like_msvc() {
|
||||
"/std:"
|
||||
} else {
|
||||
"-std="
|
||||
};
|
||||
|
||||
build.flag(&[flag, std].concat());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue