|
1 | | -// Copyright 2019 Contributors to the Parsec project. |
2 | | -// SPDX-License-Identifier: Apache-2.0 |
3 | | - |
4 | | -#![deny( |
5 | | - nonstandard_style, |
6 | | - const_err, |
7 | | - dead_code, |
8 | | - improper_ctypes, |
9 | | - non_shorthand_field_patterns, |
10 | | - no_mangle_generic_items, |
11 | | - overflowing_literals, |
12 | | - path_statements, |
13 | | - patterns_in_fns_without_body, |
14 | | - private_in_public, |
15 | | - unconditional_recursion, |
16 | | - unused, |
17 | | - unused_allocation, |
18 | | - unused_comparisons, |
19 | | - unused_parens, |
20 | | - while_true, |
21 | | - missing_debug_implementations, |
22 | | - trivial_casts, |
23 | | - trivial_numeric_casts, |
24 | | - unused_extern_crates, |
25 | | - unused_import_braces, |
26 | | - unused_qualifications, |
27 | | - unused_results, |
28 | | - missing_copy_implementations |
29 | | -)] |
30 | | -// This one is hard to avoid. |
31 | 1 | #![allow(clippy::multiple_crate_versions)] |
32 | 2 |
|
33 | | -use cargo_toml::{Manifest, Value}; |
34 | | -use serde::Deserialize; |
35 | | -use std::env; |
36 | | -use std::io::{Error, ErrorKind, Result}; |
37 | | -use std::path::{Path, PathBuf}; |
38 | | - |
39 | | -const CONFIG_TABLE_NAME: &str = "config"; |
40 | | -const MBED_CRYPTO_VERSION_KEY: &str = "mbed-crypto-version"; |
41 | | - |
42 | | -const SETUP_MBED_SCRIPT_PATH: &str = "./setup_mbed_crypto.sh"; |
43 | | -const BUILD_CONFIG_FILE_PATH: &str = "./build-conf.toml"; |
44 | | - |
45 | | -const DEFAULT_NATIVE_MBED_COMPILER: &str = "clang"; |
46 | | -const DEFAULT_NATIVE_MBED_ARCHIVER: &str = "ar"; |
47 | | -const DEFAULT_ARM64_MBED_COMPILER: &str = "aarch64-linux-gnu-gcc"; |
48 | | -const DEFAULT_ARM64_MBED_ARCHIVER: &str = "aarch64-linux-gnu-ar"; |
49 | | - |
50 | | -#[derive(Debug, Deserialize)] |
51 | | -struct Configuration { |
52 | | - mbed_config: Option<MbedConfig>, |
53 | | -} |
54 | | - |
55 | | -#[derive(Debug, Deserialize)] |
56 | | -struct MbedConfig { |
57 | | - mbed_path: Option<String>, |
58 | | - native: Option<Toolchain>, |
59 | | - aarch64_unknown_linux_gnu: Option<Toolchain>, |
60 | | -} |
61 | | - |
62 | | -#[derive(Debug, Deserialize)] |
63 | | -struct Toolchain { |
64 | | - mbed_compiler: Option<String>, |
65 | | - mbed_archiver: Option<String>, |
66 | | -} |
67 | | - |
68 | | -fn get_configuration_string(parsec_config: &Value, key: &str) -> Result<String> { |
69 | | - let config_value = get_value_from_table(parsec_config, key)?; |
70 | | - match config_value { |
71 | | - Value::String(string) => Ok(string.clone()), |
72 | | - _ => Err(Error::new( |
73 | | - ErrorKind::InvalidInput, |
74 | | - "Configuration key missing", |
75 | | - )), |
76 | | - } |
77 | | -} |
78 | | - |
79 | | -fn get_value_from_table<'a>(table: &'a Value, key: &str) -> Result<&'a Value> { |
80 | | - match table { |
81 | | - Value::Table(table) => table.get(key).ok_or_else(|| { |
82 | | - println!("Config table does not contain configuration key: {}", key); |
83 | | - Error::new(ErrorKind::InvalidInput, "Configuration key missing.") |
84 | | - }), |
85 | | - _ => Err(Error::new( |
86 | | - ErrorKind::InvalidInput, |
87 | | - "Value provided is not a TOML table", |
88 | | - )), |
89 | | - } |
90 | | -} |
91 | | - |
92 | | -// Get the Mbed Crypto version to branch on from Cargo.toml file. Use that and MbedConfig to pass |
93 | | -// parameters to the setup_mbed_crypto.sh script which clones and builds Mbed Crypto and create |
94 | | -// a static library. |
95 | | -fn setup_mbed_crypto(mbed_config: &MbedConfig, mbed_version: &str) -> Result<()> { |
96 | | - let (mbed_compiler, mbed_archiver) = |
97 | | - if std::env::var("TARGET").unwrap() == "aarch64-unknown-linux-gnu" { |
98 | | - let toolchain; |
99 | | - toolchain = mbed_config |
100 | | - .aarch64_unknown_linux_gnu |
101 | | - .as_ref() |
102 | | - .ok_or_else(|| { |
103 | | - Error::new( |
104 | | - ErrorKind::InvalidInput, |
105 | | - "The aarch64_unknown_linux_gnu subtable of mbed_config should exist", |
106 | | - ) |
107 | | - })?; |
108 | | - ( |
109 | | - toolchain |
110 | | - .mbed_compiler |
111 | | - .clone() |
112 | | - .unwrap_or_else(|| DEFAULT_ARM64_MBED_COMPILER.to_string()), |
113 | | - toolchain |
114 | | - .mbed_archiver |
115 | | - .clone() |
116 | | - .unwrap_or_else(|| DEFAULT_ARM64_MBED_ARCHIVER.to_string()), |
117 | | - ) |
118 | | - } else { |
119 | | - let toolchain; |
120 | | - toolchain = mbed_config.native.as_ref().ok_or_else(|| { |
121 | | - Error::new( |
122 | | - ErrorKind::InvalidInput, |
123 | | - "The native subtable of mbed_config should exist", |
124 | | - ) |
125 | | - })?; |
126 | | - ( |
127 | | - toolchain |
128 | | - .mbed_compiler |
129 | | - .clone() |
130 | | - .unwrap_or_else(|| DEFAULT_NATIVE_MBED_COMPILER.to_string()), |
131 | | - toolchain |
132 | | - .mbed_archiver |
133 | | - .clone() |
134 | | - .unwrap_or_else(|| DEFAULT_NATIVE_MBED_ARCHIVER.to_string()), |
135 | | - ) |
136 | | - }; |
137 | | - |
138 | | - let script_fail = |_| { |
139 | | - Err(Error::new( |
140 | | - ErrorKind::Other, |
141 | | - "setup_mbed_crypto.sh script failed", |
142 | | - )) |
143 | | - }; |
144 | | - |
145 | | - if !::std::process::Command::new(SETUP_MBED_SCRIPT_PATH) |
146 | | - .arg(mbed_version) |
147 | | - .arg( |
148 | | - mbed_config |
149 | | - .mbed_path |
150 | | - .clone() |
151 | | - .unwrap_or_else(|| env::var("OUT_DIR").unwrap()), |
152 | | - ) |
153 | | - .arg(format!("CC={}", mbed_compiler)) |
154 | | - .arg(format!("AR={}", mbed_archiver)) |
155 | | - .status() |
156 | | - .or_else(script_fail)? |
157 | | - .success() |
158 | | - { |
159 | | - Err(Error::new( |
160 | | - ErrorKind::Other, |
161 | | - "setup_mbed_crypto.sh returned an error status.", |
162 | | - )) |
163 | | - } else { |
164 | | - Ok(()) |
165 | | - } |
166 | | -} |
167 | | - |
168 | | -fn generate_mbed_bindings(mbed_config: &MbedConfig, mbed_version: &str) -> Result<()> { |
169 | | - let mbed_include_dir = mbed_config |
170 | | - .mbed_path |
171 | | - .clone() |
172 | | - .unwrap_or_else(|| env::var("OUT_DIR").unwrap()) |
173 | | - + "/mbed-crypto-" |
174 | | - + mbed_version |
175 | | - + "/include"; |
176 | | - let header = mbed_include_dir.clone() + "/psa/crypto.h"; |
177 | | - |
178 | | - println!("cargo:rerun-if-changed={}", header); |
179 | | - |
180 | | - let bindings = bindgen::Builder::default() |
181 | | - .clang_arg(format!("-I{}", mbed_include_dir)) |
182 | | - .rustfmt_bindings(true) |
183 | | - .header(header) |
184 | | - .generate_comments(false) |
185 | | - .generate() |
186 | | - .or_else(|_| { |
187 | | - Err(Error::new( |
188 | | - ErrorKind::Other, |
189 | | - "Unable to generate bindings to mbed crypto", |
190 | | - )) |
191 | | - })?; |
192 | | - |
193 | | - let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); |
194 | | - bindings.write_to_file(out_path.join("psa_crypto_bindings.rs")) |
195 | | -} |
196 | | - |
197 | | -// Get the compiler, the archiver and the location where to clone the Mbed Crypto repository. |
198 | | -fn parse_config_file() -> Result<Configuration> { |
199 | | - let config_str = ::std::fs::read_to_string(Path::new(BUILD_CONFIG_FILE_PATH))?; |
200 | | - Ok(toml::from_str(&config_str).or_else(|e| { |
201 | | - println!("Error parsing build configuration file ({}).", e); |
202 | | - Err(Error::new( |
203 | | - ErrorKind::InvalidInput, |
204 | | - "Could not parse build configuration file.", |
205 | | - )) |
206 | | - })?) |
207 | | -} |
208 | | - |
209 | | -fn main() -> Result<()> { |
210 | | - // Parsing build-conf.toml |
211 | | - let config = parse_config_file()?; |
212 | | - |
213 | | - // Parsing Cargo.toml |
214 | | - let toml_path = std::path::Path::new("./Cargo.toml"); |
215 | | - if !toml_path.exists() { |
216 | | - return Err(Error::new( |
217 | | - ErrorKind::InvalidInput, |
218 | | - "Could not find Cargo.toml.", |
219 | | - )); |
220 | | - } |
221 | | - let manifest = Manifest::from_path(&toml_path).or_else(|e| { |
222 | | - println!("Error parsing Cargo.toml ({}).", e); |
223 | | - Err(Error::new( |
224 | | - ErrorKind::InvalidInput, |
225 | | - "Could not parse Cargo.toml.", |
226 | | - )) |
227 | | - })?; |
228 | | - |
229 | | - let package = manifest.package.ok_or_else(|| { |
230 | | - Error::new( |
231 | | - ErrorKind::InvalidInput, |
232 | | - "Cargo.toml does not contain package information.", |
233 | | - ) |
234 | | - })?; |
235 | | - let metadata = package.metadata.ok_or_else(|| { |
236 | | - Error::new( |
237 | | - ErrorKind::InvalidInput, |
238 | | - "Cargo.toml does not contain package metadata.", |
239 | | - ) |
240 | | - })?; |
241 | | - let parsec_config = get_value_from_table(&metadata, CONFIG_TABLE_NAME)?; |
242 | | - |
243 | | - if cfg!(feature = "mbed-crypto-provider") { |
244 | | - let mbed_config = config.mbed_config.ok_or_else(|| { |
245 | | - Error::new( |
246 | | - ErrorKind::InvalidInput, |
247 | | - "Could not find mbed_config table in the config file.", |
248 | | - ) |
249 | | - })?; |
250 | | - |
251 | | - let mbed_version = get_configuration_string(&parsec_config, MBED_CRYPTO_VERSION_KEY)?; |
252 | | - |
253 | | - setup_mbed_crypto(&mbed_config, &mbed_version)?; |
254 | | - generate_mbed_bindings(&mbed_config, &mbed_version)?; |
255 | | - |
256 | | - // Request rustc to link the Mbed Crypto static library |
257 | | - println!( |
258 | | - "cargo:rustc-link-search=native={}/mbed-crypto-{}/library/", |
259 | | - mbed_config |
260 | | - .mbed_path |
261 | | - .unwrap_or_else(|| env::var("OUT_DIR").unwrap()), |
262 | | - mbed_version, |
263 | | - ); |
264 | | - println!("cargo:rustc-link-lib=static=mbedcrypto"); |
265 | | - } |
266 | | - |
267 | | - Ok(()) |
268 | | -} |
| 3 | +fn main() {} |
0 commit comments