build.rs
1 // Copyright (c) 2019-2025 Alpha-Delta Network Inc. 2 // This file is part of the deltavm library. 3 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at: 7 8 // http://www.apache.org/licenses/LICENSE-2.0 9 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 use std::{env, path::PathBuf}; 17 18 fn main() { 19 let curve = "FEATURE_BLS12_377"; 20 21 // Set CC environment variable to choose an alternative C compiler. 22 // Optimization level depends on whether or not --release is passed 23 // or implied. 24 let mut cc = cc::Build::new(); 25 26 let c_src_dir = PathBuf::from("src"); 27 let files = vec![c_src_dir.join("lib.c")]; 28 let mut cc_opt = None; 29 30 match cfg!(feature = "portable") { 31 true => { 32 println!("Compiling in portable mode without ISA extensions"); 33 cc_opt = Some("__BLST_PORTABLE__"); 34 } 35 false => { 36 #[cfg(target_arch = "x86_64")] 37 { 38 // account for cross-compilation [by examining environment variable] 39 let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap_or_default(); 40 if target_arch.eq("x86_64") && std::is_x86_feature_detected!("adx") { 41 println!("Enabling ADX because it was detected on the host"); 42 cc_opt = Some("__ADX__"); 43 } 44 } 45 } 46 } 47 48 cc.flag_if_supported("-mno-avx") // avoid costly transitions 49 .flag_if_supported("-fno-builtin") 50 .flag_if_supported("-Wno-unused-command-line-argument"); 51 if !cfg!(debug_assertions) { 52 cc.opt_level(2); 53 } 54 if let Some(def) = cc_opt { 55 cc.define(def, None); 56 } 57 if let Some(include) = env::var_os("DEP_BLST_C_SRC") { 58 cc.include(include); 59 } 60 cc.files(&files).compile("blst_msm"); 61 62 if cfg!(target_os = "windows") && !cfg!(target_env = "msvc") { 63 return; 64 } 65 // Detect if there is CUDA compiler and engage "cuda" feature accordingly 66 let nvcc = match env::var("NVCC") { 67 Ok(var) => which::which(var), 68 Err(_) => which::which("nvcc"), 69 }; 70 71 if nvcc.is_ok() { 72 let mut nvcc = cc::Build::new(); 73 nvcc.cuda(true); 74 nvcc.flag("-g"); 75 nvcc.flag("-arch=sm_70"); 76 nvcc.flag("-maxrregcount=255"); 77 nvcc.flag("-Xcompiler").flag("-Wno-unused-function"); 78 nvcc.flag("-Xcompiler").flag("-Wno-subobject-linkage"); 79 nvcc.define("TAKE_RESPONSIBILITY_FOR_ERROR_MESSAGE", None); 80 nvcc.define(curve, None); 81 if let Some(def) = cc_opt { 82 nvcc.define(def, None); 83 } 84 if let Some(include) = env::var_os("DEP_BLST_C_SRC") { 85 nvcc.include(include); 86 } 87 if let Some(include) = env::var_os("DEP_SPPARK_ROOT") { 88 nvcc.include(include); 89 } 90 nvcc.file("cuda/deltavm_api.cu").compile("deltavm_algorithms_cuda"); 91 92 println!("cargo:rustc-cfg=feature=\"cuda\""); 93 println!("cargo:rerun-if-changed=cuda"); 94 println!("cargo:rerun-if-env-changed=CXXFLAGS"); 95 } else { 96 println!("nvcc must be in the path. Consider adding /usr/local/cuda/bin."); 97 // panic!(); 98 } 99 }