• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #![allow(clippy::uninlined_format_args)]
2 
3 use std::env;
4 
5 #[allow(clippy::inconsistent_digit_grouping, clippy::unusual_byte_groupings)]
6 #[path = "../openssl-sys/build/cfgs.rs"]
7 mod cfgs;
8 
main()9 fn 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