1
1
use std:: env;
2
- use std:: path:: PathBuf ;
2
+ use std:: path:: { Path , PathBuf } ;
3
3
4
4
const MAINNET_FIELD_ELEMENTS_PER_BLOB : usize = 4096 ;
5
5
const MINIMAL_FIELD_ELEMENTS_PER_BLOB : usize = 4 ;
6
6
7
+ /// Compiles blst.
8
+ //
9
+ // NOTE: This code is taken from https://github.com/supranational/blst `build.rs` `main`. The crate
10
+ // is not used as a depedency to avoid double link issues on dependants.
11
+ fn compile_blst ( blst_base_dir : PathBuf ) {
12
+ // account for cross-compilation [by examining environment variables]
13
+ let target_os = env:: var ( "CARGO_CFG_TARGET_OS" ) . unwrap ( ) ;
14
+ let target_arch = env:: var ( "CARGO_CFG_TARGET_ARCH" ) . unwrap ( ) ;
15
+
16
+ if target_os. ne ( "none" ) && !env:: var ( "BLST_TEST_NO_STD" ) . is_ok ( ) {
17
+ println ! ( "cargo:rustc-cfg=feature=\" std\" " ) ;
18
+ if target_arch. eq ( "wasm32" ) {
19
+ println ! ( "cargo:rustc-cfg=feature=\" no-threads\" " ) ;
20
+ }
21
+ }
22
+ println ! ( "cargo:rerun-if-env-changed=BLST_TEST_NO_STD" ) ;
23
+
24
+ println ! ( "Using blst source directory {}" , blst_base_dir. display( ) ) ;
25
+
26
+ // Set CC environment variable to choose alternative C compiler.
27
+ // Optimization level depends on whether or not --release is passed
28
+ // or implied.
29
+
30
+ #[ cfg( target_env = "msvc" ) ]
31
+ if env:: var ( "CARGO_CFG_TARGET_POINTER_WIDTH" ) . unwrap ( ) . eq ( "32" ) && !env:: var ( "CC" ) . is_ok ( ) {
32
+ match std:: process:: Command :: new ( "clang-cl" )
33
+ . arg ( "--version" )
34
+ . output ( )
35
+ {
36
+ Ok ( out) => {
37
+ if String :: from_utf8 ( out. stdout )
38
+ . unwrap_or ( "unintelligible" . to_string ( ) )
39
+ . contains ( "Target: i686-" )
40
+ {
41
+ env:: set_var ( "CC" , "clang-cl" ) ;
42
+ }
43
+ }
44
+ Err ( _) => { /* no clang-cl in sight, just ignore the error */ }
45
+ }
46
+ }
47
+
48
+ let mut cc = cc:: Build :: new ( ) ;
49
+
50
+ let c_src_dir = blst_base_dir. join ( "src" ) ;
51
+ println ! ( "cargo:rerun-if-changed={}" , c_src_dir. display( ) ) ;
52
+ let mut file_vec = vec ! [ c_src_dir. join( "server.c" ) ] ;
53
+
54
+ if target_arch. eq ( "x86_64" ) || target_arch. eq ( "aarch64" ) {
55
+ let asm_dir = blst_base_dir. join ( "build" ) ;
56
+ println ! ( "cargo:rerun-if-changed={}" , asm_dir. display( ) ) ;
57
+ blst_assembly ( & mut file_vec, & asm_dir, & target_arch) ;
58
+ } else {
59
+ cc. define ( "__BLST_NO_ASM__" , None ) ;
60
+ }
61
+ match ( cfg ! ( feature = "portable" ) , cfg ! ( feature = "force-adx" ) ) {
62
+ ( true , false ) => {
63
+ println ! ( "Compiling in portable mode without ISA extensions" ) ;
64
+ cc. define ( "__BLST_PORTABLE__" , None ) ;
65
+ }
66
+ ( false , true ) => {
67
+ if target_arch. eq ( "x86_64" ) {
68
+ println ! ( "Enabling ADX support via `force-adx` feature" ) ;
69
+ cc. define ( "__ADX__" , None ) ;
70
+ } else {
71
+ println ! ( "`force-adx` is ignored for non-x86_64 targets" ) ;
72
+ }
73
+ }
74
+ ( false , false ) =>
75
+ {
76
+ #[ cfg( target_arch = "x86_64" ) ]
77
+ if target_arch. eq ( "x86_64" ) && std:: is_x86_feature_detected!( "adx" ) {
78
+ println ! ( "Enabling ADX because it was detected on the host" ) ;
79
+ cc. define ( "__ADX__" , None ) ;
80
+ }
81
+ }
82
+ ( true , true ) => panic ! ( "Cannot compile with both `portable` and `force-adx` features" ) ,
83
+ }
84
+ if env:: var ( "CARGO_CFG_TARGET_ENV" ) . unwrap ( ) . eq ( "msvc" ) {
85
+ cc. flag ( "-Zl" ) ;
86
+ }
87
+ cc. flag_if_supported ( "-mno-avx" ) // avoid costly transitions
88
+ . flag_if_supported ( "-fno-builtin" )
89
+ . flag_if_supported ( "-Wno-unused-function" )
90
+ . flag_if_supported ( "-Wno-unused-command-line-argument" ) ;
91
+ if target_arch. eq ( "wasm32" ) {
92
+ cc. flag_if_supported ( "-ffreestanding" ) ;
93
+ }
94
+ if !cfg ! ( debug_assertions) {
95
+ cc. opt_level ( 2 ) ;
96
+ }
97
+ cc. files ( & file_vec) . compile ( "blst" ) ;
98
+ }
99
+
100
+ /// Adds assembly files for blst compilation.
101
+ fn blst_assembly ( file_vec : & mut Vec < PathBuf > , base_dir : & Path , _arch : & String ) {
102
+ #[ cfg( target_env = "msvc" ) ]
103
+ if env:: var ( "CARGO_CFG_TARGET_ENV" ) . unwrap ( ) . eq ( "msvc" ) {
104
+ let sfx = match _arch. as_str ( ) {
105
+ "x86_64" => "x86_64" ,
106
+ "aarch64" => "armv8" ,
107
+ _ => "unknown" ,
108
+ } ;
109
+ let files = glob:: glob ( & format ! ( "{}/win64/*-{}.asm" , base_dir. display( ) , sfx) )
110
+ . expect ( "unable to collect assembly files" ) ;
111
+ for file in files {
112
+ file_vec. push ( file. unwrap ( ) ) ;
113
+ }
114
+ return ;
115
+ }
116
+
117
+ file_vec. push ( base_dir. join ( "assembly.S" ) ) ;
118
+ }
119
+
7
120
fn main ( ) {
8
121
let cargo_dir = PathBuf :: from ( env:: var ( "CARGO_MANIFEST_DIR" ) . unwrap ( ) ) ;
9
122
let root_dir = cargo_dir
@@ -20,9 +133,11 @@ fn main() {
20
133
21
134
eprintln ! ( "Using FIELD_ELEMENTS_PER_BLOB={}" , field_elements_per_blob) ;
22
135
23
- // Obtain the header files exposed by blst-bindings' crate.
24
- let blst_headers_dir =
25
- std:: env:: var_os ( "DEP_BLST_BINDINGS" ) . expect ( "BLST exposes header files for bindings" ) ;
136
+ let blst_base_dir = root_dir. join ( "blst" ) ;
137
+ compile_blst ( blst_base_dir. clone ( ) ) ;
138
+
139
+ // Obtain the header files of blst
140
+ let blst_headers_dir = blst_base_dir. join ( "bindings" ) ;
26
141
27
142
let c_src_dir = root_dir. join ( "src" ) ;
28
143
0 commit comments