• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Additional parameters for Android build of BoringSSL.
2 //
3 // Android NDK < 18 with GCC.
4 const CMAKE_PARAMS_ANDROID_NDK_OLD_GCC: &[(&str, &[(&str, &str)])] = &[
5     ("aarch64", &[(
6         "ANDROID_TOOLCHAIN_NAME",
7         "aarch64-linux-android-4.9",
8     )]),
9     ("arm", &[(
10         "ANDROID_TOOLCHAIN_NAME",
11         "arm-linux-androideabi-4.9",
12     )]),
13     ("x86", &[(
14         "ANDROID_TOOLCHAIN_NAME",
15         "x86-linux-android-4.9",
16     )]),
17     ("x86_64", &[(
18         "ANDROID_TOOLCHAIN_NAME",
19         "x86_64-linux-android-4.9",
20     )]),
21 ];
22 
23 // Android NDK >= 19.
24 const CMAKE_PARAMS_ANDROID_NDK: &[(&str, &[(&str, &str)])] = &[
25     ("aarch64", &[("ANDROID_ABI", "arm64-v8a")]),
26     ("arm", &[("ANDROID_ABI", "armeabi-v7a")]),
27     ("x86", &[("ANDROID_ABI", "x86")]),
28     ("x86_64", &[("ANDROID_ABI", "x86_64")]),
29 ];
30 
31 // iOS.
32 const CMAKE_PARAMS_IOS: &[(&str, &[(&str, &str)])] = &[
33     ("aarch64", &[
34         ("CMAKE_OSX_ARCHITECTURES", "arm64"),
35         ("CMAKE_OSX_SYSROOT", "iphoneos"),
36     ]),
37     ("x86_64", &[
38         ("CMAKE_OSX_ARCHITECTURES", "x86_64"),
39         ("CMAKE_OSX_SYSROOT", "iphonesimulator"),
40     ]),
41 ];
42 
43 // ARM Linux.
44 const CMAKE_PARAMS_ARM_LINUX: &[(&str, &[(&str, &str)])] = &[
45     ("aarch64", &[("CMAKE_SYSTEM_PROCESSOR", "aarch64")]),
46     ("arm", &[("CMAKE_SYSTEM_PROCESSOR", "arm")]),
47 ];
48 
49 /// Returns the platform-specific output path for lib.
50 ///
51 /// MSVC generator on Windows place static libs in a target sub-folder,
52 /// so adjust library location based on platform and build target.
53 /// See issue: https://github.com/alexcrichton/cmake-rs/issues/18
get_boringssl_platform_output_path() -> String54 fn get_boringssl_platform_output_path() -> String {
55     if cfg!(windows) {
56         // Code under this branch should match the logic in cmake-rs
57         let debug_env_var =
58             std::env::var("DEBUG").expect("DEBUG variable not defined in env");
59 
60         let deb_info = match &debug_env_var[..] {
61             "false" => false,
62             "true" => true,
63             unknown => panic!("Unknown DEBUG={} env var.", unknown),
64         };
65 
66         let opt_env_var = std::env::var("OPT_LEVEL")
67             .expect("OPT_LEVEL variable not defined in env");
68 
69         let subdir = match &opt_env_var[..] {
70             "0" => "Debug",
71             "1" | "2" | "3" =>
72                 if deb_info {
73                     "RelWithDebInfo"
74                 } else {
75                     "Release"
76                 },
77             "s" | "z" => "MinSizeRel",
78             unknown => panic!("Unknown OPT_LEVEL={} env var.", unknown),
79         };
80 
81         subdir.to_string()
82     } else {
83         "".to_string()
84     }
85 }
86 
87 /// Returns a new cmake::Config for building BoringSSL.
88 ///
89 /// It will add platform-specific parameters if needed.
get_boringssl_cmake_config() -> cmake::Config90 fn get_boringssl_cmake_config() -> cmake::Config {
91     let arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap();
92     let os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();
93     let pwd = std::env::current_dir().unwrap();
94 
95     let mut boringssl_cmake = cmake::Config::new("deps/boringssl");
96 
97     // Add platform-specific parameters.
98     match os.as_ref() {
99         "android" => {
100             let cmake_params_android = if cfg!(feature = "ndk-old-gcc") {
101                 CMAKE_PARAMS_ANDROID_NDK_OLD_GCC
102             } else {
103                 CMAKE_PARAMS_ANDROID_NDK
104             };
105 
106             // We need ANDROID_NDK_HOME to be set properly.
107             let android_ndk_home = std::env::var("ANDROID_NDK_HOME")
108                 .expect("Please set ANDROID_NDK_HOME for Android build");
109             let android_ndk_home = std::path::Path::new(&android_ndk_home);
110             for (android_arch, params) in cmake_params_android {
111                 if *android_arch == arch {
112                     for (name, value) in *params {
113                         boringssl_cmake.define(name, value);
114                     }
115                 }
116             }
117             let toolchain_file =
118                 android_ndk_home.join("build/cmake/android.toolchain.cmake");
119             let toolchain_file = toolchain_file.to_str().unwrap();
120             boringssl_cmake.define("CMAKE_TOOLCHAIN_FILE", toolchain_file);
121 
122             // 21 is the minimum level tested. You can give higher value.
123             boringssl_cmake.define("ANDROID_NATIVE_API_LEVEL", "21");
124             boringssl_cmake.define("ANDROID_STL", "c++_shared");
125 
126             boringssl_cmake
127         },
128 
129         "ios" => {
130             for (ios_arch, params) in CMAKE_PARAMS_IOS {
131                 if *ios_arch == arch {
132                     for (name, value) in *params {
133                         boringssl_cmake.define(name, value);
134                     }
135                 }
136             }
137 
138             // Bitcode is always on.
139             let bitcode_cflag = "-fembed-bitcode";
140 
141             // Hack for Xcode 10.1.
142             let target_cflag = if arch == "x86_64" {
143                 "-target x86_64-apple-ios-simulator"
144             } else {
145                 ""
146             };
147 
148             let cflag = format!("{} {}", bitcode_cflag, target_cflag);
149 
150             boringssl_cmake.define("CMAKE_ASM_FLAGS", &cflag);
151             boringssl_cmake.cflag(&cflag);
152 
153             boringssl_cmake
154         },
155 
156         "linux" => match arch.as_ref() {
157             "aarch64" | "arm" => {
158                 for (arm_arch, params) in CMAKE_PARAMS_ARM_LINUX {
159                     if *arm_arch == arch {
160                         for (name, value) in *params {
161                             boringssl_cmake.define(name, value);
162                         }
163                     }
164                 }
165                 boringssl_cmake.define("CMAKE_SYSTEM_NAME", "Linux");
166                 boringssl_cmake.define("CMAKE_SYSTEM_VERSION", "1");
167 
168                 boringssl_cmake
169             },
170 
171             "x86" => {
172                 boringssl_cmake.define(
173                     "CMAKE_TOOLCHAIN_FILE",
174                     pwd.join("deps/boringssl/src/util/32-bit-toolchain.cmake")
175                         .as_os_str(),
176                 );
177 
178                 boringssl_cmake
179             },
180 
181             _ => boringssl_cmake,
182         },
183 
184         _ => {
185             // Configure BoringSSL for building on 32-bit non-windows platforms.
186             if arch == "x86" && os != "windows" {
187                 boringssl_cmake.define(
188                     "CMAKE_TOOLCHAIN_FILE",
189                     pwd.join("deps/boringssl/src/util/32-bit-toolchain.cmake")
190                         .as_os_str(),
191                 );
192             }
193 
194             boringssl_cmake
195         },
196     }
197 }
198 
write_pkg_config()199 fn write_pkg_config() {
200     use std::io::prelude::*;
201 
202     let profile = std::env::var("PROFILE").unwrap();
203     let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
204     let target_dir = format!("{}/target/{}", manifest_dir, profile);
205 
206     let out_path = std::path::Path::new(&target_dir).join("quiche.pc");
207     let mut out_file = std::fs::File::create(&out_path).unwrap();
208 
209     let include_dir = format!("{}/include", manifest_dir);
210     let version = std::env::var("CARGO_PKG_VERSION").unwrap();
211 
212     let output = format!(
213         "# quiche
214 
215 includedir={}
216 libdir={}
217 
218 Name: quiche
219 Description: quiche library
220 URL: https://github.com/cloudflare/quiche
221 Version: {}
222 Libs: -Wl,-rpath,${{libdir}} -L${{libdir}} -lquiche
223 Cflags: -I${{includedir}}
224 ",
225         include_dir, target_dir, version
226     );
227 
228     out_file.write_all(output.as_bytes()).unwrap();
229 }
230 
main()231 fn main() {
232     if cfg!(feature = "boringssl-vendored") && !cfg!(feature = "boring-sys") {
233         let bssl_dir = std::env::var("QUICHE_BSSL_PATH").unwrap_or_else(|_| {
234             let mut cfg = get_boringssl_cmake_config();
235 
236             if cfg!(feature = "fuzzing") {
237                 cfg.cxxflag("-DBORINGSSL_UNSAFE_DETERMINISTIC_MODE")
238                     .cxxflag("-DBORINGSSL_UNSAFE_FUZZER_MODE");
239             }
240 
241             cfg.build_target("bssl").build().display().to_string()
242         });
243 
244         let build_path = get_boringssl_platform_output_path();
245         let build_dir = format!("{}/build/{}", bssl_dir, build_path);
246         println!("cargo:rustc-link-search=native={}", build_dir);
247 
248         println!("cargo:rustc-link-lib=static=crypto");
249         println!("cargo:rustc-link-lib=static=ssl");
250     }
251 
252     if cfg!(feature = "boring-sys") {
253         println!("cargo:rustc-link-lib=static=crypto");
254         println!("cargo:rustc-link-lib=static=ssl");
255     }
256 
257     // MacOS: Allow cdylib to link with undefined symbols
258     if cfg!(target_os = "macos") {
259         println!("cargo:rustc-cdylib-link-arg=-Wl,-undefined,dynamic_lookup");
260     }
261 
262     if cfg!(feature = "pkg-config-meta") {
263         write_pkg_config();
264     }
265 }
266