1#![allow(clippy::uninlined_format_args)] 2 3use std::env; 4 5#[allow(clippy::inconsistent_digit_grouping, clippy::unusual_byte_groupings)] 6#[path = "../openssl-sys/build/cfgs.rs"] 7mod cfgs; 8 9fn main() { 10 let mut cfg = ctest2::TestGenerator::new(); 11 let target = env::var("TARGET").unwrap(); 12 13 if let Ok(out) = env::var("DEP_OPENSSL_INCLUDE") { 14 cfg.include(&out); 15 } 16 17 // Needed to get OpenSSL to correctly undef symbols that are already on 18 // Windows like X509_NAME 19 if target.contains("windows") { 20 cfg.header("windows.h"); 21 22 // weird "different 'const' qualifiers" error on Windows, maybe a cl.exe 23 // thing? 24 if target.contains("msvc") { 25 cfg.flag("/wd4090"); 26 } 27 28 // https://github.com/sfackler/rust-openssl/issues/889 29 cfg.define("WIN32_LEAN_AND_MEAN", None); 30 } 31 32 let openssl_version = env::var("DEP_OPENSSL_VERSION_NUMBER") 33 .ok() 34 .map(|v| u64::from_str_radix(&v, 16).unwrap()); 35 let libressl_version = env::var("DEP_OPENSSL_LIBRESSL_VERSION_NUMBER") 36 .ok() 37 .map(|v| u64::from_str_radix(&v, 16).unwrap()); 38 39 cfg.cfg("openssl", None); 40 41 for c in cfgs::get(openssl_version, libressl_version) { 42 cfg.cfg(c, None); 43 } 44 45 if let Ok(vars) = env::var("DEP_OPENSSL_CONF") { 46 for var in vars.split(',') { 47 cfg.cfg("osslconf", Some(var)); 48 } 49 } 50 51 cfg.header("openssl/comp.h") 52 .header("openssl/dh.h") 53 .header("openssl/ossl_typ.h") 54 .header("openssl/stack.h") 55 .header("openssl/x509.h") 56 .header("openssl/bio.h") 57 .header("openssl/x509v3.h") 58 .header("openssl/safestack.h") 59 .header("openssl/cmac.h") 60 .header("openssl/hmac.h") 61 .header("openssl/obj_mac.h") 62 .header("openssl/ssl.h") 63 .header("openssl/err.h") 64 .header("openssl/rand.h") 65 .header("openssl/pkcs12.h") 66 .header("openssl/bn.h") 67 .header("openssl/aes.h") 68 .header("openssl/ocsp.h") 69 .header("openssl/evp.h") 70 .header("openssl/x509_vfy.h"); 71 72 if libressl_version.is_some() { 73 cfg.header("openssl/poly1305.h"); 74 } 75 76 if let Some(version) = openssl_version { 77 cfg.header("openssl/cms.h"); 78 if version >= 0x10100000 { 79 cfg.header("openssl/kdf.h"); 80 } 81 82 if version >= 0x30000000 { 83 cfg.header("openssl/provider.h"); 84 } 85 } 86 87 #[allow(clippy::if_same_then_else)] 88 cfg.type_name(|s, is_struct, _is_union| { 89 // Add some `*` on some callback parameters to get function pointer to 90 // typecheck in C, especially on MSVC. 91 if s == "PasswordCallback" { 92 "pem_password_cb*".to_string() 93 } else if s == "bio_info_cb" { 94 "bio_info_cb*".to_string() 95 } else if s == "_STACK" { 96 "struct stack_st".to_string() 97 // This logic should really be cleaned up 98 } else if is_struct 99 && s != "point_conversion_form_t" 100 && s.chars().next().unwrap().is_lowercase() 101 { 102 format!("struct {}", s) 103 } else if s.starts_with("stack_st_") { 104 format!("struct {}", s) 105 } else { 106 s.to_string() 107 } 108 }); 109 cfg.skip_type(|s| { 110 // function pointers are declared without a `*` in openssl so their 111 // sizeof is 1 which isn't what we want. 112 s == "PasswordCallback" 113 || s == "pem_password_cb" 114 || s == "bio_info_cb" 115 || s.starts_with("CRYPTO_EX_") 116 }); 117 cfg.skip_struct(|s| { 118 s == "ProbeResult" || 119 s == "X509_OBJECT_data" || // inline union 120 s == "DIST_POINT_NAME_st_anon_union" || // inline union 121 s == "PKCS7_data" || 122 s == "ASN1_TYPE_value" 123 }); 124 cfg.skip_fn(move |s| { 125 s == "CRYPTO_memcmp" || // uses volatile 126 127 // Skip some functions with function pointers on windows, not entirely 128 // sure how to get them to work out... 129 (target.contains("windows") && { 130 s.starts_with("PEM_read_bio_") || 131 (s.starts_with("PEM_write_bio_") && s.ends_with("PrivateKey")) || 132 s == "d2i_PKCS8PrivateKey_bio" || 133 s == "i2d_PKCS8PrivateKey_bio" || 134 s == "SSL_get_ex_new_index" || 135 s == "SSL_CTX_get_ex_new_index" || 136 s == "CRYPTO_get_ex_new_index" 137 }) 138 }); 139 cfg.skip_field_type(|s, field| { 140 (s == "EVP_PKEY" && field == "pkey") || // union 141 (s == "GENERAL_NAME" && field == "d") || // union 142 (s == "DIST_POINT_NAME" && field == "name") || // union 143 (s == "X509_OBJECT" && field == "data") || // union 144 (s == "PKCS7" && field == "d") || // union 145 (s == "ASN1_TYPE" && field == "value") // union 146 }); 147 cfg.skip_signededness(|s| { 148 s.ends_with("_cb") 149 || s.ends_with("_CB") 150 || s.ends_with("_cb_fn") 151 || s.starts_with("CRYPTO_") 152 || s == "PasswordCallback" 153 || s.ends_with("_cb_func") 154 || s.ends_with("_cb_ex") 155 }); 156 cfg.field_name(|_s, field| { 157 if field == "type_" { 158 "type".to_string() 159 } else { 160 field.to_string() 161 } 162 }); 163 cfg.fn_cname(|rust, link_name| link_name.unwrap_or(rust).to_string()); 164 cfg.generate("../openssl-sys/src/lib.rs", "all.rs"); 165} 166