Skip to content

Commit

Permalink
feat: export sys variables from aws-lc-rs crate (#335)
Browse files Browse the repository at this point in the history
* feat: export sys variables from aws-lc-rs crate

* pr feedback
  • Loading branch information
camshaft committed Feb 13, 2024
1 parent 3e194ee commit 5838973
Show file tree
Hide file tree
Showing 11 changed files with 151 additions and 73 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,15 @@ jobs:
run: |
./scripts/run-rustls-integration.sh
sys-crate-tests:
links-crate-tests:
if: github.repository == 'aws/aws-lc-rs'
name: sys crate tests
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ ubuntu-latest, macos-12, macos-13-xlarge, windows-latest ]
features: [ aws-lc-sys, aws-lc-fips-sys ]
features: [ aws-lc-rs, aws-lc-rs-fips, aws-lc-sys, aws-lc-fips-sys ]
steps:
- uses: actions/checkout@v3
with:
Expand All @@ -85,10 +85,10 @@ jobs:
- name: Install ninja-build tool
uses: seanmiddleditch/gha-setup-ninja@v4
- name: Run cargo test
working-directory: ./sys-testing
working-directory: ./links-testing
run: cargo test --features ${{ matrix.features }} --no-default-features
- name: Run cargo run
working-directory: ./sys-testing
working-directory: ./links-testing
run: cargo run --features ${{ matrix.features }} --no-default-features

publish-dry-run:
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ members = [
"aws-lc-sys",
"aws-lc-fips-sys",
"aws-lc-rs-testing",
"sys-testing"
"links-testing"
]
resolver = "2"

Expand Down
6 changes: 6 additions & 0 deletions aws-lc-fips-sys/builder/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,12 @@ fn main() {
setup_include_paths(&out_dir, &manifest_dir).display()
);

// export the artifact names
println!("cargo:libcrypto={}_crypto", prefix_string());
if cfg!(feature = "ssl") {
println!("cargo:libssl={}_ssl", prefix_string());
}

println!("cargo:rerun-if-changed=builder/");
println!("cargo:rerun-if-changed=aws-lc/");
println!("cargo:rerun-if-env-changed=AWS_LC_FIPS_SYS_STATIC");
Expand Down
2 changes: 2 additions & 0 deletions aws-lc-rs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
name = "aws-lc-rs"
authors = ["AWS-LibCrypto"]
version = "1.6.1"
# this crate re-exports whatever sys crate that was selected
links = "aws_lc_rs_1_6_1_sys"
edition = "2021"
rust-version = "1.60"
keywords = ["crypto", "cryptography", "security"]
Expand Down
84 changes: 65 additions & 19 deletions aws-lc-rs/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,74 @@
// SPDX-License-Identifier: Apache-2.0 OR ISC

fn main() {
let mutually_exclusives_count = [cfg!(feature = "non-fips"), cfg!(feature = "fips")]
.iter()
.filter(|x| **x)
.count();

if mutually_exclusives_count > 1 {
eprint!("fips and non-fips are mutually exclusive crate features.");
std::process::exit(1);
}
let has_mutually_exclusive_features = cfg!(feature = "non-fips") && cfg!(feature = "fips");
assert!(
!has_mutually_exclusive_features,
"`fips` and `non-fips` are mutually exclusive crate features."
);

// This appears asymmetric, but it reflects the `cfg` statements in lib.rs that
// require `aws-lc-sys` to be present when "fips" is not enabled.
let at_least_one_count = [cfg!(feature = "aws-lc-sys"), cfg!(feature = "fips")]
.iter()
.filter(|x| **x)
.count();

if at_least_one_count < 1 {
eprint!(
"one of the following features must be specified: \
aws-lc-sys, non-fips, or fips."
// if `fips` is enabled, then use that
let sys_crate = if cfg!(feature = "fips") {
"aws-lc-fips-sys"
} else if cfg!(feature = "aws-lc-sys") {
"aws-lc-sys"
} else {
panic!(
"one of the following features must be specified: `aws-lc-sys`, `non-fips`, or `fips`."
);
std::process::exit(1);
};

export_sys_vars(sys_crate);
}

fn export_sys_vars(sys_crate: &str) {
let prefix = if sys_crate == "aws-lc-fips-sys" {
"DEP_AWS_LC_FIPS_"
} else {
"DEP_AWS_LC_"
};

let mut selected = String::default();
let mut candidates = vec![];

// search through the DEP vars and find the selected sys crate version
for (name, value) in std::env::vars() {
// if we've selected a prefix then we can go straight to exporting it
if !selected.is_empty() {
try_export_var(&selected, &name, &value);
continue;
}

// we're still looking for a selected prefix
if let Some(version) = name.strip_prefix(prefix) {
if let Some(version) = version.strip_suffix("_INCLUDE") {
// we've found the selected version so update it and export it
selected = format!("{prefix}{version}_");
try_export_var(&selected, &name, &value);
} else {
// it started with the expected prefix, but we don't know what the version is yet
// so save it for later
candidates.push((name, value));
}
}
}

assert!(!selected.is_empty(), "missing {prefix} include");

// process all of the remaining candidates
for (name, value) in candidates {
try_export_var(&selected, &name, &value);
}
}

fn try_export_var(selected: &str, name: &str, value: &str) {
assert!(!selected.is_empty(), "missing selected prefix");

if let Some(var) = name.strip_prefix(selected) {
eprintln!("cargo:rerun-if-env-changed={name}");
let var = var.to_lowercase();
println!("cargo:{var}={value}");
}
}
6 changes: 6 additions & 0 deletions aws-lc-sys/builder/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,12 @@ fn main() {
setup_include_paths(&out_dir, &manifest_dir).display()
);

// export the artifact names
println!("cargo:libcrypto={}_crypto", prefix_string());
if cfg!(feature = "ssl") {
println!("cargo:libssl={}_ssl", prefix_string());
}

println!("cargo:rerun-if-changed=builder/");
println!("cargo:rerun-if-changed=aws-lc/");
println!("cargo:rerun-if-env-changed=AWS_LC_SYS_STATIC");
Expand Down
7 changes: 5 additions & 2 deletions sys-testing/Cargo.toml → links-testing/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
[package]
name = "sys-testing"
name = "links-testing"
version = "0.1.0"
edition = "2021"
publish = false

[features]
default = ["aws-lc-sys"]
aws-lc-rs = ["dep:aws-lc-rs"]
aws-lc-rs-fips = ["aws-lc-rs", "aws-lc-rs/fips"]
aws-lc-sys = ["dep:aws-lc-sys"]
aws-lc-fips-sys = ["dep:aws-lc-fips-sys"]

[dependencies]
aws-lc-rs = { path = "../aws-lc-rs", optional = true }
aws-lc-sys = { path = "../aws-lc-sys", optional = true }
aws-lc-fips-sys = { path = "../aws-lc-fips-sys", optional = true }

Expand All @@ -18,4 +21,4 @@ cc = "1"
toml_edit = "0.21"

[package.metadata.cargo-udeps.ignore]
normal = [ "aws-lc-sys", "aws-lc-fips-sys" ] # the sys crate is only used through a C library build
normal = [ "aws-lc-rs", "aws-lc-sys", "aws-lc-fips-sys" ] # the sys crate is only used through a C library build
62 changes: 62 additions & 0 deletions links-testing/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 OR ISC

use toml_edit::Document;

fn main() {
let mut deps = vec![];

macro_rules! select_dep {
($dep:literal) => {
if cfg!(feature = $dep) {
deps.push($dep);
}
};
}

select_dep!("aws-lc-rs");
select_dep!("aws-lc-sys");
select_dep!("aws-lc-fips-sys");

assert_eq!(
deps.len(),
1,
"exactly one dependency is allowed at a time, got {deps:?}"
);

let dep = deps.pop().unwrap();
let dep_links = get_package_links_property(&format!("../{dep}/Cargo.toml"));
let dep_snake_case = dep.replace('-', "_");
build_and_link(dep_links.as_ref(), &dep_snake_case);
}

fn build_and_link(links: &str, target_name: &str) {
// ensure that the include path is exported and set up correctly
cc::Build::new()
.include(env(format!("DEP_{}_INCLUDE", links.to_uppercase())))
.file("src/testing.c")
.compile(&format!("testing_{target_name}"));

// make sure the root was exported
let root = env(format!("DEP_{}_ROOT", links.to_uppercase()));
println!("cargo:rustc-link-search={root}");

// ensure the libcrypto artifact is linked
let libcrypto = env(format!("DEP_{}_LIBCRYPTO", links.to_uppercase()));
println!("cargo:rustc-link-lib={libcrypto}");
}

fn get_package_links_property(cargo_toml_path: &str) -> String {
let cargo_toml = std::fs::read_to_string(cargo_toml_path).unwrap();
let cargo_toml = cargo_toml.parse::<Document>().unwrap();

let links = cargo_toml["package"]["links"].as_str().unwrap();

String::from(links)
}

fn env<S: AsRef<str>>(s: S) -> String {
let s = s.as_ref();
println!("cargo:rerun-if-env-changed={s}");
std::env::var(s).unwrap_or_else(|_| panic!("missing env var {s}"))
}
File renamed without changes.
File renamed without changes.
47 changes: 0 additions & 47 deletions sys-testing/build.rs

This file was deleted.

0 comments on commit 5838973

Please sign in to comment.