Skip to content

Commit 581bcea

Browse files
committed
Add prefix feature
The prefix feature adds a psa_crypto_(version) prefix to the library names and all the symbols. By default it is disabled. Signed-off-by: Gowtham Suresh Kumar <gowtham.sureshkumar@arm.com>
1 parent 6f32a51 commit 581bcea

File tree

3 files changed

+105
-4
lines changed

3 files changed

+105
-4
lines changed

psa-crypto-sys/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,4 @@ default = ["operations"]
2323
static = []
2424
interface = ["bindgen"]
2525
operations = ["interface"]
26+
prefix = []

psa-crypto-sys/build.rs

Lines changed: 103 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@
3535
#![allow(clippy::multiple_crate_versions)]
3636

3737
fn main() -> std::io::Result<()> {
38+
// If the prefix feature is not enabled then set the "CARGO_PKG_LINKS"
39+
// parameter to mbedcrypto to avoid any duplicate symbols from any other
40+
// crate. "CARGO_PKG_LINKS" overrides the "links" field in the manifest.
41+
#[cfg(not(feature = "prefix"))]
42+
{
43+
use std::env;
44+
let cargo_pkg_links = "CARGO_PKG_LINKS";
45+
env::set_var(cargo_pkg_links, "mbedcrypto");
46+
}
47+
3848
#[cfg(feature = "operations")]
3949
return operations::script_operations();
4050

@@ -47,7 +57,9 @@ fn main() -> std::io::Result<()> {
4757

4858
#[cfg(any(feature = "interface", feature = "operations"))]
4959
mod common {
60+
#[cfg(feature = "prefix")]
5061
use bindgen::callbacks::{ItemInfo, ParseCallbacks};
62+
5163
use std::env;
5264
use std::io::{Error, ErrorKind, Result};
5365
use std::path::{Path, PathBuf};
@@ -87,17 +99,21 @@ mod common {
8799
Ok(())
88100
}
89101

102+
#[cfg(feature = "prefix")]
90103
// Cargo provides the crate version from Cargo.toml in the environment.
91104
const VERSION: &str = env!("CARGO_PKG_VERSION");
92105

106+
#[cfg(feature = "prefix")]
93107
// Return a prefix that we hope is globally unique.
94108
pub fn prefix() -> String {
95109
format!("psa_crypto_{}_", VERSION.replace('.', "_"))
96110
}
97111

112+
#[cfg(feature = "prefix")]
98113
#[derive(Debug)]
99114
struct RenameCallbacks {}
100115

116+
#[cfg(feature = "prefix")]
101117
impl ParseCallbacks for RenameCallbacks {
102118
fn generated_link_name_override(&self, info: ItemInfo<'_>) -> Option<String> {
103119
Some(prefix() + info.name)
@@ -111,6 +127,24 @@ mod common {
111127

112128
let out_dir = env::var("OUT_DIR").unwrap();
113129

130+
#[cfg(not(feature = "prefix"))]
131+
let shim_bindings = bindgen::Builder::default()
132+
.clang_arg(format!("-I{}", out_dir))
133+
.clang_arg("-DMBEDTLS_CONFIG_FILE=<config.h>")
134+
.clang_arg(format!("-I{}", mbed_include_dir))
135+
.header("src/c/shim.h")
136+
.blocklist_type("max_align_t")
137+
.generate_comments(false)
138+
.size_t_is_usize(true)
139+
.generate()
140+
.map_err(|_| {
141+
Error::new(
142+
ErrorKind::Other,
143+
"Unable to generate bindings to mbed crypto",
144+
)
145+
})?;
146+
147+
#[cfg(feature = "prefix")]
114148
let shim_bindings = bindgen::Builder::default()
115149
.clang_arg(format!("-I{}", out_dir))
116150
.clang_arg("-DMBEDTLS_CONFIG_FILE=<config.h>")
@@ -127,6 +161,7 @@ mod common {
127161
"Unable to generate bindings to mbed crypto",
128162
)
129163
})?;
164+
130165
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
131166
shim_bindings.write_to_file(out_path.join("shim_bindings.rs"))?;
132167

@@ -136,6 +171,8 @@ mod common {
136171
pub fn compile_shim_library(include_dir: String, metadata: bool) -> Result<PathBuf> {
137172
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
138173

174+
let shimlib_name = "libmbedcryptoshim.a";
175+
139176
// Compile and package the shim library
140177
cc::Build::new()
141178
.include(&out_dir)
@@ -146,10 +183,19 @@ mod common {
146183
.flag("-Werror")
147184
.opt_level(2)
148185
.cargo_metadata(metadata)
149-
.try_compile("libmbedcryptoshim.a")
186+
.try_compile(shimlib_name)
150187
.map_err(|_| Error::new(ErrorKind::Other, "compiling shim.c failed"))?;
151188

152-
Ok(out_dir.join("libmbedcryptoshim.a"))
189+
// Also link shim library
190+
#[cfg(not(feature = "prefix"))]
191+
{
192+
println!(
193+
"cargo:rustc-link-search=native={}",
194+
env::var("OUT_DIR").unwrap()
195+
);
196+
println!("cargo:rustc-link-lib=static=mbedcryptoshim");
197+
}
198+
Ok(out_dir.join(shimlib_name))
153199
}
154200
}
155201

@@ -178,10 +224,13 @@ mod interface {
178224
#[cfg(feature = "operations")]
179225
mod operations {
180226
use super::common;
227+
#[cfg(feature = "prefix")]
181228
use super::common::prefix;
182229
use cmake::Config;
183230
use std::env;
184-
use std::io::{Error, ErrorKind, Result, Write};
231+
#[cfg(feature = "prefix")]
232+
use std::io::Write;
233+
use std::io::{Error, ErrorKind, Result};
185234
use std::path::PathBuf;
186235
use walkdir::WalkDir;
187236

@@ -212,17 +261,66 @@ mod operations {
212261
Ok(mbed_build_path)
213262
}
214263

264+
#[cfg(not(feature = "prefix"))]
265+
fn link_to_lib(lib_path: String, link_statically: bool) {
266+
let link_type = if link_statically { "static" } else { "dylib" };
267+
268+
// Request rustc to link the Mbed Crypto library
269+
println!("cargo:rustc-link-search=native={}", lib_path,);
270+
println!("cargo:rustc-link-lib={}=mbedcrypto", link_type);
271+
}
272+
273+
#[cfg(not(feature = "prefix"))]
215274
// Build script when the operations feature is on
216275
pub fn script_operations() -> Result<()> {
276+
let lib;
277+
let statically;
278+
let include;
279+
217280
if env::var("MBEDTLS_LIB_DIR").is_err() ^ env::var("MBEDTLS_INCLUDE_DIR").is_err() {
218281
return Err(Error::new(
219282
ErrorKind::Other,
220283
"both environment variables MBEDTLS_LIB_DIR and MBEDTLS_INCLUDE_DIR need to be set for operations feature",
221284
));
222285
}
223-
224286
common::configure_mbed_crypto()?;
287+
if let (Ok(lib_dir), Ok(include_dir)) =
288+
(env::var("MBEDTLS_LIB_DIR"), env::var("MBEDTLS_INCLUDE_DIR"))
289+
{
290+
lib = lib_dir;
291+
include = include_dir;
292+
statically = cfg!(feature = "static") || env::var("MBEDCRYPTO_STATIC").is_ok();
293+
} else {
294+
println!("Did not find environment variables, building MbedTLS!");
295+
let mut mbed_lib_dir = compile_mbed_crypto()?;
296+
let mut mbed_include_dir = mbed_lib_dir.clone();
297+
mbed_lib_dir.push("lib");
298+
mbed_include_dir.push("include");
299+
300+
lib = mbed_lib_dir.to_str().unwrap().to_owned();
301+
include = mbed_include_dir.to_str().unwrap().to_owned();
302+
statically = true;
303+
}
304+
305+
// Linking to PSA Crypto library is only needed for the operations.
306+
link_to_lib(lib, statically);
307+
common::generate_mbed_crypto_bindings(include.clone())?;
308+
match common::compile_shim_library(include, false) {
309+
Ok(_) => Ok(()),
310+
Err(e) => Err(e),
311+
}
312+
}
225313

314+
#[cfg(feature = "prefix")]
315+
// Build script when the operations feature is on
316+
pub fn script_operations() -> Result<()> {
317+
if env::var("MBEDTLS_LIB_DIR").is_err() ^ env::var("MBEDTLS_INCLUDE_DIR").is_err() {
318+
return Err(Error::new(
319+
ErrorKind::Other,
320+
"both environment variables MBEDTLS_LIB_DIR and MBEDTLS_INCLUDE_DIR need to be set for operations feature",
321+
));
322+
}
323+
common::configure_mbed_crypto()?;
226324
if let (Ok(lib_dir), Ok(include_dir)) =
227325
(env::var("MBEDTLS_LIB_DIR"), env::var("MBEDTLS_INCLUDE_DIR"))
228326
{
@@ -265,6 +363,7 @@ mod operations {
265363
Ok(())
266364
}
267365

366+
#[cfg(feature = "prefix")]
268367
pub fn objcopy(liblist: Vec<(PathBuf, PathBuf)>) -> Result<()> {
269368
// Run nm on the source libraries.
270369
let mut args = vec![];

psa-crypto/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,5 @@ base64 = "0.12.3"
2626
default = ["operations"]
2727
operations = ["psa-crypto-sys/operations", "interface"]
2828
interface = ["psa-crypto-sys/interface"]
29+
prefix = ["psa-crypto-sys/prefix"]
2930
std = []

0 commit comments

Comments
 (0)