Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve handling of CFLAGS #712

Merged
merged 11 commits into from
Mar 10, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions .github/docker_images/cmake_build_versions/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0 OR ISC

FROM ubuntu:24.04

ARG CMAKE_VERSION
ARG CMAKE_DOWNLOAD_URL
ARG CMAKE_SHA256

VOLUME ["/awslc"]

RUN apt-get update && \
apt-get install -y ca-certificates build-essential cmake git wget curl jq unzip clang sudo golang zlib1g-dev libcurl4-openssl-dev libarchive-dev liblzma-dev xz-utils && \
apt-get autoremove --purge -y && \
apt-get clean && \
apt-get autoclean && \
rm -rf /var/lib/apt/lists/* && \
rm -rf /tmp/*

RUN mkdir /cmake

COPY cmake_build.sh /
COPY aws_lc_rs_build.sh /
COPY entry.sh /

WORKDIR /cmake

RUN curl -L -o source.tar.gz "${CMAKE_DOWNLOAD_URL}" && \
echo "${CMAKE_SHA256} source.tar.gz" | sha256sum -c - && \
mkdir source && \
tar -x -f source.tar.gz -v --strip-components=1 -C source

WORKDIR /cmake/source

RUN /cmake_build.sh

RUN useradd -m docker
USER docker
RUN cd "${HOME}" && \
git config --global --add safe.directory '*' && \
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > ./rustup.sh && \
chmod +x ./rustup.sh && \
./rustup.sh -y && \
. "${HOME}/.cargo/env" && \
cargo install --locked bindgen-cli && \
rustup component add rustfmt clippy && \
rm ./rustup.sh

ENV AWS_LC_SYS_CMAKE_BUILDER=1

ENTRYPOINT ["/entry.sh"]
35 changes: 35 additions & 0 deletions .github/docker_images/cmake_build_versions/aws_lc_rs_build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/env bash

# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0 OR ISC

set -ex -o pipefail

echo "Building with CMake Version: $(cmake --version)"
FIPS_BUILD=1
if cmake --version | grep -q " 4."; then
echo "CMake version is 4.x, skipping FIPS build"
FIPS_BUILD=0
fi

. "${HOME}/.cargo/env"
SRC_DIR="${SRC_DIR:-/aws_lc_rs}"


pushd "${SRC_DIR}"
cargo clean
cargo test -p aws-lc-rs --features=unstable
cargo clean
if [ ${FIPS_BUILD} -eq 1 ]; then
cargo test -p aws-lc-rs --features=unstable,fips
cargo clean
fi
cargo test -p aws-lc-rs --release --features=unstable
cargo clean
if [ ${FIPS_BUILD} -eq 1 ]; then
cargo test -p aws-lc-rs --release --features=unstable,fips
cargo clean
fi


popd # ${BUILD_DIR}
16 changes: 16 additions & 0 deletions .github/docker_images/cmake_build_versions/cmake_build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env bash

# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0 OR ISC

set -ex -o pipefail

echo "Building CMake Version: ${CMAKE_VERSION:-unknown}"

NUM_CPU_THREADS=$(grep -c ^processor /proc/cpuinfo)

# At the moment this works fine for all versions, in the future build logic can be modified to
# look at it ${CMAKE_VERSION}.
./configure --prefix=/opt/cmake --system-curl --system-libarchive
make -j"${NUM_CPU_THREADS}"
make install
10 changes: 10 additions & 0 deletions .github/docker_images/cmake_build_versions/entry.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env bash

# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0 OR ISC

set -ex -o pipefail

export PATH="/opt/cmake/bin:${PATH}"

/aws_lc_rs_build.sh "${argv[@]}"
37 changes: 37 additions & 0 deletions .github/workflows/cmake.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: CMake Compatability
on:
push:
branches: [ '*' ]
pull_request:
branches: [ '*' ]
concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}
cancel-in-progress: true
env:
DOCKER_BUILDKIT: 1
GOPROXY: https://proxy.golang.org,direct
jobs:
cmake:
if: github.repository_owner == 'aws'
name: CMake ${{ matrix.cmake.version}} build with ${{ matrix.generator}}
strategy:
fail-fast: false
matrix:
cmake:
- { version: "3.5", url: "https://cmake.org/files/v3.5/cmake-3.5.0.tar.gz", hash: "92c83ad8a4fd6224cf6319a60b399854f55b38ebe9d297c942408b792b1a9efa" }
- { version: "3.28", url: "https://cmake.org/files/v3.28/cmake-3.28.1.tar.gz", hash: "15e94f83e647f7d620a140a7a5da76349fc47a1bfed66d0f5cdee8e7344079ad" }
- { version: "4.0", url: "https://cmake.org/files/v4.0/cmake-4.0.0-rc3.tar.gz", hash: "d1ae66637fb083efde5c12b45a76ab9bcd419970979c93b14a0d0d21eb8c6c08" }
runs-on: ubuntu-latest
env:
DOCKER_BUILDKIT: 1
steps:
- uses: actions/checkout@v4
with:
submodules: "recursive"
- name: Build Docker Image
working-directory: .github/docker_images/cmake_build_versions
run: |
docker build -t "cmake-${{ matrix.cmake.version }}" --build-arg CMAKE_VERSION=${{ matrix.cmake.version }} --build-arg CMAKE_DOWNLOAD_URL=${{ matrix.cmake.url }} --build-arg CMAKE_SHA256=${{ matrix.cmake.hash }} .
- name: Test
run: |
docker run -v "${{ github.workspace }}:/aws_lc_rs" "cmake-${{ matrix.cmake.version }}"
22 changes: 22 additions & 0 deletions .github/workflows/integration.yml
Original file line number Diff line number Diff line change
@@ -65,6 +65,28 @@ jobs:
run: |
./scripts/run-rustls-integration.sh
windows-debug-crt-static-test:
if: github.repository_owner == 'aws'
name: "Windows debug w/ crt-static Test"
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
os: [ windows-latest ]
steps:
- uses: actions/checkout@v3
with:
submodules: 'recursive'
- uses: dtolnay/rust-toolchain@stable
id: toolchain
- name: Set Rust toolchain override
run: rustup override set ${{ steps.toolchain.outputs.name }}
- name: run-windows-debug-crt-static-test
working-directory: ./aws-lc-rs
shell: bash
run: |
./scripts/run-windows-debug-crt-static-test.sh
links-crate-tests:
if: github.repository_owner == 'aws'
name: sys crate tests
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -5,4 +5,4 @@
[submodule "aws-lc-fips-sys/aws-lc"]
path = aws-lc-fips-sys/aws-lc
url = https://github.com/aws/aws-lc.git
branch = fips-2022-11-02
branch = fips-2024-09-27
9 changes: 8 additions & 1 deletion aws-lc-fips-sys/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0 OR ISC

cmake_minimum_required(VERSION 3.0)
cmake_minimum_required(VERSION 3.5...3.31)

if(CMAKE_VERSION VERSION_GREATER "3.14")
# https://cmake.org/cmake/help/latest/policy/CMP0091.html
# In CMake 3.14 and below, MSVC runtime library selection flags are added to the default CMAKE_<LANG>_FLAGS_<CONFIG>
# cache entries by CMake automatically.
cmake_policy(SET CMP0091 OLD)
endif()

project(AWS_LC_RUST NONE)
enable_language(C)
39 changes: 39 additions & 0 deletions aws-lc-rs/scripts/run-windows-debug-crt-static-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/bash -exu
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0 OR ISC

SRC_ROOT="${GITHUB_WORKSPACE:-$(git rev-parse --show-toplevel)}/aws-lc-rs"

case `uname -s` in
CYGWIN*) echo Cygwin;;
MINGW*) echo MinGw;;
MSYS_NT*) echo MSys;;
*) echo Unknown OS: `uname -s`; exit 1;;
esac

TMP_DIR=`mktemp -d`

pushd "${TMP_DIR}"
cargo new --bin aws-lc-rs-test
pushd aws-lc-rs-test

cargo add aws-lc-rs rustls rustls-platform-verifier
cat << EOF >> Cargo.toml
[profile.release]
debug = "limited"
[patch.crates-io]
"aws-lc-rs" = { path = "${SRC_ROOT//\\/\/}" }
EOF

mkdir -p .cargo
cat << EOF > .cargo/config.toml
[target.'cfg(target_os = "windows")']
rustflags = ["-C", "target-feature=+crt-static"]
EOF

cargo update
cargo build --release

popd
popd
9 changes: 8 additions & 1 deletion aws-lc-sys/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0 OR ISC

cmake_minimum_required(VERSION 3.0)
cmake_minimum_required(VERSION 3.5...3.31)

if(CMAKE_VERSION VERSION_GREATER "3.14")
# https://cmake.org/cmake/help/latest/policy/CMP0091.html
# In CMake 3.14 and below, MSVC runtime library selection flags are added to the default CMAKE_<LANG>_FLAGS_<CONFIG>
# cache entries by CMake automatically.
cmake_policy(SET CMP0091 OLD)
endif()

project(AWS_LC_RUST NONE)
enable_language(C)
256 changes: 180 additions & 76 deletions aws-lc-sys/builder/cc_builder.rs
Original file line number Diff line number Diff line change
@@ -82,6 +82,74 @@ impl Default for PlatformConfig {
}
}

#[allow(clippy::upper_case_acronyms)]
pub(crate) enum BuildOption {
STD(String),
FLAG(String),
DEFINE(String, String),
INCLUDE(PathBuf),
}
impl BuildOption {
fn std<T: ToString + ?Sized>(val: &T) -> Self {
Self::STD(val.to_string())
}
fn flag<T: ToString + ?Sized>(val: &T) -> Self {
Self::FLAG(val.to_string())
}
fn flag_if_supported<T: ToString + ?Sized>(cc_build: &cc::Build, flag: &T) -> Option<Self> {
if let Ok(true) = cc_build.is_flag_supported(flag.to_string()) {
Some(Self::FLAG(flag.to_string()))
} else {
None
}
}

fn define<K: ToString + ?Sized, V: ToString + ?Sized>(key: &K, val: &V) -> Self {
Self::DEFINE(key.to_string(), val.to_string())
}

fn include<P: Into<PathBuf>>(path: P) -> Self {
Self::INCLUDE(path.into())
}

fn apply_cc<'a>(&self, cc_build: &'a mut cc::Build) -> &'a mut cc::Build {
match self {
BuildOption::STD(val) => cc_build.std(val),
BuildOption::FLAG(val) => cc_build.flag(val),
BuildOption::DEFINE(key, val) => cc_build.define(key, Some(val.as_str())),
BuildOption::INCLUDE(path) => cc_build.include(path.as_path()),
}
}

pub(crate) fn apply_cmake<'a>(
&self,
cmake_cfg: &'a mut cmake::Config,
is_like_msvc: bool,
) -> &'a mut cmake::Config {
if is_like_msvc {
match self {
BuildOption::STD(val) => cmake_cfg.define(
"CMAKE_C_STANDARD",
val.to_ascii_lowercase().strip_prefix('c').unwrap_or("11"),
),
BuildOption::FLAG(val) => cmake_cfg.cflag(val),
BuildOption::DEFINE(key, val) => cmake_cfg.cflag(format!("/D{key}={val}")),
BuildOption::INCLUDE(path) => cmake_cfg.cflag(format!("/I{}", path.display())),
}
} else {
match self {
BuildOption::STD(val) => cmake_cfg.define(
"CMAKE_C_STANDARD",
val.to_ascii_lowercase().strip_prefix('c').unwrap_or("11"),
),
BuildOption::FLAG(val) => cmake_cfg.cflag(val),
BuildOption::DEFINE(key, val) => cmake_cfg.cflag(format!("-D{key}={val}")),
BuildOption::INCLUDE(path) => cmake_cfg.cflag(format!("-I{}", path.display())),
}
}
}
}

impl CcBuilder {
pub(crate) fn new(
manifest_dir: PathBuf,
@@ -97,43 +165,29 @@ impl CcBuilder {
}
}

pub(crate) fn create_builder(&self) -> cc::Build {
let mut cc_build = cc::Build::default();
cc_build.out_dir(&self.out_dir).cpp(false);

let compiler = cc_build.get_compiler();
if compiler.is_like_gnu() || compiler.is_like_clang() {
cc_build.flag("-Wno-unused-parameter");
if target_os() == "linux"
|| target_os().ends_with("bsd")
|| target_env() == "gnu"
|| target_env() == "musl"
{
cc_build.define("_XOPEN_SOURCE", "700").flag("-pthread");
}
}

self.add_includes(&mut cc_build);
pub(crate) fn collect_universal_build_options(
&self,
cc_build: &cc::Build,
) -> (bool, Vec<BuildOption>) {
let mut build_options: Vec<BuildOption> = Vec::new();

cc_build
}
let compiler_is_msvc = {
let compiler = cc_build.get_compiler();
!compiler.is_like_gnu() && !compiler.is_like_clang()
};

pub(crate) fn prepare_builder(&self) -> cc::Build {
let mut cc_build = self.create_builder();
match requested_c_std() {
CStdRequested::C99 => {
cc_build.std("c99");
build_options.push(BuildOption::std("c99"));
}
CStdRequested::C11 => {
cc_build.std("c11");
build_options.push(BuildOption::std("c11"));
}
CStdRequested::None => {
if target_env() == "msvc" && target_arch() == "aarch64" {
// clang-cl (not "clang") will be used.
} else if self.compiler_check("c11", "") {
cc_build.std("c11");
if self.compiler_check("c11") {
build_options.push(BuildOption::std("c11"));
} else {
cc_build.std("c99");
build_options.push(BuildOption::std("c99"));
}
}
}
@@ -145,86 +199,135 @@ impl CcBuilder {
emit_warning(&format!("CXX environment variable set: {}", cxx.clone()));
}

let compiler = cc_build.get_compiler();
if target_arch() == "x86" && (compiler.is_like_clang() || compiler.is_like_gnu()) {
cc_build.flag_if_supported("-msse2");
if target_arch() == "x86" && !compiler_is_msvc {
if let Some(option) = BuildOption::flag_if_supported(cc_build, "-msse2") {
build_options.push(option);
}
}

let opt_level = cargo_env("OPT_LEVEL");
match opt_level.as_str() {
"0" | "1" | "2" => {
if is_no_asm() {
emit_warning("AWS_LC_SYS_NO_ASM found. Disabling assembly code usage.");
cc_build.define("OPENSSL_NO_ASM", "1");
build_options.push(BuildOption::define("OPENSSL_NO_ASM", "1"));
}
}
_ => {
assert!(
!is_no_asm(),
"AWS_LC_SYS_NO_ASM only allowed for debug builds!"
);
if compiler.is_like_gnu() || compiler.is_like_clang() {
if !compiler_is_msvc {
let flag = format!("-ffile-prefix-map={}=", self.manifest_dir.display());
if let Ok(true) = cc_build.is_flag_supported(&flag) {
emit_warning(&format!("Using flag: {}", &flag));
cc_build.flag(flag);
build_options.push(BuildOption::flag(&flag));
} else {
emit_warning("NOTICE: Build environment source paths might be visible in release binary.");
let flag = format!("-fdebug-prefix-map={}=", self.manifest_dir.display());
if let Ok(true) = cc_build.is_flag_supported(&flag) {
emit_warning(&format!("Using flag: {}", &flag));
cc_build.flag(flag);
build_options.push(BuildOption::flag(&flag));
}
}
}
}
}

if !get_crate_cflags().is_empty() {
let cflags = get_crate_cflags();
emit_warning(&format!(
"AWS_LC_SYS_CFLAGS found. Setting CFLAGS: '{cflags}'"
));
env::set_var("CFLAGS", cflags);
}

if target_os() == "macos" {
// This compiler error has only been seen on MacOS x86_64:
// ```
// clang: error: overriding '-mmacosx-version-min=13.7' option with '--target=x86_64-apple-macosx14.2' [-Werror,-Woverriding-t-option]
// ```
cc_build.flag_if_supported("-Wno-overriding-t-option");
cc_build.flag_if_supported("-Wno-overriding-option");
if let Some(option) =
BuildOption::flag_if_supported(cc_build, "-Wno-overriding-t-option")
{
build_options.push(option);
}
if let Some(option) = BuildOption::flag_if_supported(cc_build, "-Wno-overriding-option")
{
build_options.push(option);
}
}
(compiler_is_msvc, build_options)
}

cc_build
pub fn collect_cc_only_build_options(&self, cc_build: &cc::Build) -> Vec<BuildOption> {
let mut build_options: Vec<BuildOption> = Vec::new();
let is_like_msvc = {
let compiler = cc_build.get_compiler();
!compiler.is_like_gnu() && !compiler.is_like_clang()
};
if !is_like_msvc {
build_options.push(BuildOption::flag("-Wno-unused-parameter"));
if target_os() == "linux"
|| target_os().ends_with("bsd")
|| target_env() == "gnu"
|| target_env() == "musl"
{
build_options.push(BuildOption::define("_XOPEN_SOURCE", "700"));
build_options.push(BuildOption::flag("-pthread"));
}
}

self.add_includes(&mut build_options);

build_options
}

fn add_includes(&self, cc_build: &mut cc::Build) {
fn add_includes(&self, build_options: &mut Vec<BuildOption>) {
// The order of includes matters
if let Some(prefix) = &self.build_prefix {
cc_build
.define("BORINGSSL_IMPLEMENTATION", "1")
.define("BORINGSSL_PREFIX", prefix.as_str());
cc_build.include(self.manifest_dir.join("generated-include"));
build_options.push(BuildOption::define("BORINGSSL_IMPLEMENTATION", "1"));
build_options.push(BuildOption::define("BORINGSSL_PREFIX", prefix.as_str()));
build_options.push(BuildOption::include(
self.manifest_dir.join("generated-include"),
));
}
build_options.push(BuildOption::include(self.manifest_dir.join("include")));
build_options.push(BuildOption::include(
self.manifest_dir.join("aws-lc").join("include"),
));
build_options.push(BuildOption::include(
self.manifest_dir
.join("aws-lc")
.join("third_party")
.join("s2n-bignum")
.join("include"),
));
build_options.push(BuildOption::include(
self.manifest_dir
.join("aws-lc")
.join("third_party")
.join("jitterentropy")
.join("jitterentropy-library"),
));
}

pub fn create_builder(&self) -> cc::Build {
let mut cc_build = cc::Build::new();
let build_options = self.collect_cc_only_build_options(&cc_build);
for option in build_options {
option.apply_cc(&mut cc_build);
}
cc_build
}

pub fn prepare_builder(&self) -> cc::Build {
let mut cc_build = self.create_builder();
let (_, build_options) = self.collect_universal_build_options(&cc_build);
for option in build_options {
option.apply_cc(&mut cc_build);
}
let cflags = get_crate_cflags();
if !cflags.is_empty() {
emit_warning(&format!(
"AWS_LC_SYS_CFLAGS found. Setting CFLAGS: '{cflags}'"
));
env::set_var("CFLAGS", cflags);
}
cc_build
.include(self.manifest_dir.join("include"))
.include(self.manifest_dir.join("aws-lc").join("include"))
.include(
self.manifest_dir
.join("aws-lc")
.join("third_party")
.join("s2n-bignum")
.join("include"),
)
.include(
self.manifest_dir
.join("aws-lc")
.join("third_party")
.join("jitterentropy")
.join("jitterentropy-library"),
);
}

fn add_all_files(&self, lib: &Library, cc_build: &mut cc::Build) {
@@ -259,7 +362,7 @@ impl CcBuilder {
for flag in lib.flags {
cc_build.flag(flag);
}
self.run_compiler_checks();
self.run_compiler_checks(&mut cc_build);

if let Some(prefix) = &self.build_prefix {
cc_build.compile(format!("{}_crypto", prefix.as_str()).as_str());
@@ -271,10 +374,9 @@ impl CcBuilder {
// This performs basic checks of compiler capabilities and sets an appropriate flag on success.
// This should be kept in alignment with the checks performed by AWS-LC's CMake build.
// See: https://github.com/search?q=repo%3Aaws%2Faws-lc%20check_compiler&type=code
fn compiler_check(&self, basename: &str, flag: &str) -> bool {
fn compiler_check(&self, basename: &str) -> bool {
let mut ret_val = false;
let output_dir = self.out_dir.join(format!("out-{basename}"));
let mut cc_build = self.create_builder();
let source_file = self
.manifest_dir
.join("aws-lc")
@@ -292,6 +394,7 @@ impl CcBuilder {
emit_warning("######");
emit_warning("######");
}
let mut cc_build = cc::Build::default();
cc_build
.file(source_file)
.warnings_into_errors(true)
@@ -304,9 +407,6 @@ impl CcBuilder {
let result = cc_build.try_compile_intermediates();

if result.is_ok() {
if !flag.is_empty() {
cc_build.define(flag, "1");
}
ret_val = true;
}
if fs::remove_dir_all(&output_dir).is_err() {
@@ -388,9 +488,13 @@ impl CcBuilder {
}
let _ = fs::remove_file(exec_path);
}
fn run_compiler_checks(&self) {
self.compiler_check("stdalign_check", "AWS_LC_STDALIGN_AVAILABLE");
self.compiler_check("builtin_swap_check", "AWS_LC_BUILTIN_SWAP_SUPPORTED");
fn run_compiler_checks(&self, cc_build: &mut cc::Build) {
if self.compiler_check("stdalign_check") {
cc_build.define("AWS_LC_STDALIGN_AVAILABLE", Some("1"));
}
if self.compiler_check("builtin_swap_check") {
cc_build.define("AWS_LC_BUILTIN_SWAP_SUPPORTED", Some("1"));
}
self.memcmp_check();
}
}
115 changes: 61 additions & 54 deletions aws-lc-sys/builder/cmake_builder.rs
Original file line number Diff line number Diff line change
@@ -5,9 +5,8 @@ use crate::cc_builder::CcBuilder;
use crate::OutputLib::{Crypto, RustWrapper, Ssl};
use crate::{
allow_prebuilt_nasm, cargo_env, effective_target, emit_warning, execute_command,
get_crate_cflags, is_crt_static, is_no_asm, option_env, requested_c_std, target_arch,
target_env, target_os, target_underscored, target_vendor, test_nasm_command, use_prebuilt_nasm,
CStdRequested, OutputLibType,
get_crate_cflags, is_crt_static, is_no_asm, option_env, target_arch, target_env, target_os,
target_underscored, target_vendor, test_nasm_command, use_prebuilt_nasm, OutputLibType,
};
use std::env;
use std::ffi::OsString;
@@ -67,35 +66,23 @@ impl CmakeBuilder {
cmake::Config::new(&self.manifest_dir)
}

fn collect_compiler_cflags(&self) -> OsString {
fn apply_universal_build_options<'a>(
&self,
cmake_cfg: &'a mut cmake::Config,
) -> &'a cmake::Config {
// Use the compiler options identified by CcBuilder
let cc_builder = CcBuilder::new(
self.manifest_dir.clone(),
self.out_dir.clone(),
self.build_prefix.clone(),
self.output_lib_type,
);
let mut cflags = OsString::new();
let compiler = cc_builder.prepare_builder().get_compiler();
let args = compiler.args();
for (i, arg) in args.iter().enumerate() {
if i > 0 {
cflags.push(" ");
}
if let Some(arg) = arg.to_str() {
if arg.contains(' ') {
cflags.push("\"");
cflags.push(arg);
cflags.push("\"");
} else {
cflags.push(arg);
}
} else {
cflags.push(arg);
}
let cc_build = cc::Build::new();
let (is_like_msvc, build_options) = cc_builder.collect_universal_build_options(&cc_build);
for option in &build_options {
option.apply_cmake(cmake_cfg, is_like_msvc);
}

cflags
cmake_cfg
}

#[allow(clippy::too_many_lines)]
@@ -108,19 +95,6 @@ impl CmakeBuilder {
cmake_cfg.define("BUILD_SHARED_LIBS", "0");
}

let opt_level = cargo_env("OPT_LEVEL");
if opt_level.ne("0") {
if opt_level.eq("1") || opt_level.eq("2") {
cmake_cfg.define("CMAKE_BUILD_TYPE", "relwithdebinfo");
} else if opt_level.eq("s") || opt_level.eq("z") {
cmake_cfg.define("CMAKE_BUILD_TYPE", "minsizerel");
} else {
cmake_cfg.define("CMAKE_BUILD_TYPE", "release");
}
} else {
cmake_cfg.define("CMAKE_BUILD_TYPE", "debug");
}

if let Some(prefix) = &self.build_prefix {
cmake_cfg.define("BORINGSSL_PREFIX", format!("{prefix}_"));
let include_path = self.manifest_dir.join("generated-include");
@@ -157,22 +131,25 @@ impl CmakeBuilder {

cmake_cfg.define("ASAN", "1");
}
match requested_c_std() {
CStdRequested::C99 => {
cmake_cfg.define("CMAKE_C_STANDARD", "99");
}
CStdRequested::C11 => {
cmake_cfg.define("CMAKE_C_STANDARD", "11");
}
CStdRequested::None => {}
}

if target_env() == "ohos" {
Self::configure_open_harmony(&mut cmake_cfg, get_crate_cflags());
return cmake_cfg;
}

let mut cflags = OsString::from(get_crate_cflags());
let cflags = get_crate_cflags();
if !cflags.is_empty() {
emit_warning(&format!(
"AWS_LC_SYS_CFLAGS found. Setting CFLAGS: '{cflags}'"
));
env::set_var("CFLAGS", cflags);
}

// cmake-rs has logic that strips Optimization/Debug options that are passed via CFLAGS:
// https://github.com/rust-lang/cmake-rs/issues/240
// This breaks build configurations that generate warnings when optimizations
// are disabled.
Self::preserve_cflag_optimization_flags(&mut cmake_cfg);

// Allow environment to specify CMake toolchain.
let toolchain_var_name = format!("CMAKE_TOOLCHAIN_FILE_{}", target_underscored());
@@ -182,16 +159,10 @@ impl CmakeBuilder {
emit_warning(&format!(
"CMAKE_TOOLCHAIN_FILE environment variable set: {toolchain}"
));
emit_warning(&format!("Setting CFLAGS: {cflags:?}"));
env::set_var("CFLAGS", cflags);
return cmake_cfg;
}
// We only consider compiler CFLAGS when no cmake toolchain is set
let compiler_cflags = self.collect_compiler_cflags();
cflags.push(" ");
cflags.push(&compiler_cflags);
emit_warning(&format!("Setting CFLAGS: {cflags:?}"));
env::set_var("CFLAGS", cflags);
self.apply_universal_build_options(&mut cmake_cfg);

// See issue: https://github.com/aws/aws-lc-rs/issues/453
if target_os() == "windows" {
@@ -228,6 +199,18 @@ impl CmakeBuilder {
cmake_cfg
}

fn preserve_cflag_optimization_flags(cmake_cfg: &mut cmake::Config) {
if let Ok(cflags) = env::var("CFLAGS") {
let split = cflags.split_whitespace();
for arg in split {
if arg.starts_with("-O") || arg.starts_with("/O") {
emit_warning(&format!("Preserving optimization flag: {arg}"));
cmake_cfg.cflag(arg);
}
}
}
}

#[allow(clippy::unused_self)]
fn configure_android(&self, _cmake_cfg: &mut cmake::Config) {
// If we leave CMAKE_SYSTEM_PROCESSOR unset, then cmake-rs should handle properly setting
@@ -302,6 +285,30 @@ impl CmakeBuilder {
let script_path = script_path.replace('\\', "/");

cmake_cfg.define("CMAKE_ASM_NASM_COMPILER", script_path.as_str());
// Without the following definition, the build fails with a message similar to the one
// reported here: https://gitlab.kitware.com/cmake/cmake/-/issues/19453
// The variables below were found in the associated fix:
// https://gitlab.kitware.com/cmake/cmake/-/merge_requests/4257/diffs
cmake_cfg.define(
"CMAKE_ASM_NASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded",
"",
);
cmake_cfg.define(
"CMAKE_ASM_NASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL",
"",
);
cmake_cfg.define(
"CMAKE_ASM_NASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug",
"",
);
cmake_cfg.define(
"CMAKE_ASM_NASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL",
"",
);
cmake_cfg.define(
"CMAKE_ASM_NASM_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_ProgramDatabase",
"",
);
}
}