Skip to content

Commit

Permalink
Improve alignment of CC and CMake builds
Browse files Browse the repository at this point in the history
  • Loading branch information
justsmth committed Sep 25, 2024
1 parent baccbed commit 465ffdc
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 65 deletions.
120 changes: 83 additions & 37 deletions aws-lc-sys/builder/cc_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ mod x86_64_unknown_linux_gnu;
mod x86_64_unknown_linux_musl;

use crate::{
cargo_env, emit_warning, env_var_to_bool, execute_command, get_cflags, out_dir,
requested_c_std, target, target_arch, target_os, target_vendor, CStdRequested, OutputLibType,
cargo_env, emit_warning, env_var_to_bool, execute_command, get_cflags, is_no_asm, option_env,
out_dir, requested_c_std, target, target_arch, target_env, target_os, target_vendor,
CStdRequested, OutputLibType,
};
use std::path::PathBuf;

Expand Down Expand Up @@ -96,30 +97,54 @@ impl CcBuilder {
}
}

fn apply_c_std(cc_build: &mut cc::Build) {
match requested_c_std() {
CStdRequested::C99 => cc_build.std("c99"),
_ => cc_build.std("c11"),
};
}

fn create_builder(&self) -> cc::Build {
pub(crate) fn create_builder(&self) -> cc::Build {
let mut cc_build = cc::Build::default();
cc_build
.out_dir(&self.out_dir)
.flag("-Wno-unused-parameter")
.cpp(false)
.shared_flag(false)
.static_flag(true);
CcBuilder::apply_c_std(&mut cc_build);
if target_os() == "linux" {
cc_build.define("_XOPEN_SOURCE", "700").flag("-lpthread");
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_env() == "gnu" {
cc_build.define("_XOPEN_SOURCE", "700").flag("-lpthread");
}
}

if let Some(prefix) = &self.build_prefix {
cc_build
.define("BORINGSSL_IMPLEMENTATION", "1")
.define("BORINGSSL_PREFIX", prefix.as_str());
}
self.add_includes(&mut cc_build);

cc_build
}

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");
}
CStdRequested::C11 => {
cc_build.std("c11");
}
CStdRequested::None => {
if target_env() == "msvc" && target_arch() == "aarch64" {
// clang-cl (not "clang") will be used.
} else if self.compiler_check(&mut cc_build, "c11", "") {
cc_build.std("c11");
} else {
cc_build.std("c99");
}
}
};

if let Some(cc) = option_env("CC") {
emit_warning(&format!("CC environment variable set: {}", cc.clone()));
}
if let Some(cxx) = option_env("CXX") {
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()) {
Expand All @@ -128,17 +153,28 @@ impl CcBuilder {

let opt_level = cargo_env("OPT_LEVEL");
match opt_level.as_str() {
"0" | "1" | "2" => {}
"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");
}
}
_ => {
let file_prefix_map_option =
format!("-ffile-prefix-map={}=", self.manifest_dir.display());
if let Ok(true) = cc_build.is_flag_supported(&file_prefix_map_option) {
cc_build.flag(file_prefix_map_option);
} else {
cc_build.flag_if_supported(format!(
"-fdebug-prefix-map={}=",
self.manifest_dir.display()
));
assert!(
!is_no_asm(),
"AWS_LC_SYS_NO_ASM only allowed for debug builds!"
);
if compiler.is_like_gnu() || compiler.is_like_clang() {
let file_prefix_map_option =
format!("-ffile-prefix-map={}=", self.manifest_dir.display());
if let Ok(true) = cc_build.is_flag_supported(&file_prefix_map_option) {
cc_build.flag(file_prefix_map_option);
} else {
cc_build.flag_if_supported(format!(
"-fdebug-prefix-map={}=",
self.manifest_dir.display()
));
}
}
}
}
Expand All @@ -151,7 +187,6 @@ impl CcBuilder {
env::set_var("CFLAGS", cflags);
}

self.add_includes(&mut cc_build);
cc_build
}

Expand Down Expand Up @@ -194,7 +229,7 @@ impl CcBuilder {
}

fn build_library(&self, lib: &Library) {
let mut cc_build = self.create_builder();
let mut cc_build = self.prepare_builder();

self.add_all_files(lib, &mut cc_build);

Expand All @@ -213,9 +248,10 @@ 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, cc_build: &mut cc::Build, basename: &str, flag: &str) {
let output_path = self.out_dir.join(format!("{basename}.o"));
if let Ok(()) = cc::Build::default()
fn compiler_check(&self, cc_build: &mut cc::Build, basename: &str, flag: &str) -> bool {
let mut ret_val = false;
let output_path = format!("{basename}.o");
let result = cc::Build::default()
.file(
self.manifest_dir
.join("aws-lc")
Expand All @@ -225,11 +261,21 @@ impl CcBuilder {
)
.flag("-Wno-unused-parameter")
.warnings_into_errors(true)
.try_compile(output_path.as_os_str().to_str().unwrap())
{
cc_build.define(flag, "1");
.try_compile(output_path.as_str());

if let Ok(()) = result {
if !flag.is_empty() {
cc_build.define(flag, "1");
}
ret_val = true;
}
let _ = fs::remove_file(output_path);
emit_warning(&format!(
"Compilation of '{basename}.c' {} - {:?}.",
if ret_val { "succeeded" } else { "failed" },
&result
));
ret_val
}

// This checks whether the compiler contains a critical bug that causes `memcmp` to erroneously
Expand Down
48 changes: 20 additions & 28 deletions aws-lc-sys/builder/cmake_builder.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 OR ISC

use crate::cc_builder::CcBuilder;
use crate::OutputLib::{Crypto, RustWrapper, Ssl};
use crate::{
allow_prebuilt_nasm, cargo_env, emit_warning, execute_command, get_cflags, is_crt_static,
is_no_asm, option_env, requested_c_std, target, target_arch, target_env, target_family,
target_os, target_underscored, target_vendor, test_nasm_command, use_prebuilt_nasm,
CStdRequested, OutputLibType,
is_no_asm, option_env, requested_c_std, target, target_arch, target_env, target_os,
target_underscored, target_vendor, test_nasm_command, use_prebuilt_nasm, CStdRequested,
OutputLibType,
};
use std::env;
use std::ffi::OsString;
Expand Down Expand Up @@ -89,19 +90,27 @@ impl CmakeBuilder {
cmake_cfg.define("CMAKE_BUILD_TYPE", "relwithdebinfo");
} else {
cmake_cfg.define("CMAKE_BUILD_TYPE", "release");
if target_family() == "unix" || target_env() == "gnu" {
// This flag is not supported on GCC < v8.1
// TODO: re-enable this
// cmake_cfg.cflag(format!(
// "-ffile-prefix-map={}=",
// self.manifest_dir.display()
// ));
}
}
} else {
cmake_cfg.define("CMAKE_BUILD_TYPE", "debug");
}

// 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();
cflags.push(cc_builder.prepare_builder().get_compiler().cflags_env());
if !get_cflags().is_empty() {
cflags.push(" ");
cflags.push(get_cflags());
}
emit_warning(&format!("Setting CFLAGS: {cflags:?}"));
env::set_var("CFLAGS", cflags);

if let Some(prefix) = &self.build_prefix {
cmake_cfg.define("BORINGSSL_PREFIX", format!("{prefix}_"));
let include_path = self.manifest_dir.join("generated-include");
Expand Down Expand Up @@ -148,14 +157,6 @@ impl CmakeBuilder {
CStdRequested::None => {}
}

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

// Allow environment to specify CMake toolchain.
if let Some(toolchain) = option_env("CMAKE_TOOLCHAIN_FILE").or(option_env(format!(
"CMAKE_TOOLCHAIN_FILE_{}",
Expand All @@ -167,15 +168,6 @@ impl CmakeBuilder {
return cmake_cfg;
}

if let Some(cc) = option_env("CC") {
emit_warning(&format!("CC environment variable set: {}", cc.clone()));
cmake_cfg.define("CMAKE_C_COMPILER", cc);
}
if let Some(cxx) = option_env("CXX") {
emit_warning(&format!("CXX environment variable set: {}", cxx.clone()));
cmake_cfg.define("CMAKE_CXX_COMPILER", cxx);
}

// See issue: https://github.com/aws/aws-lc-rs/issues/453
if target_os() == "windows" {
self.configure_windows(&mut cmake_cfg);
Expand Down
2 changes: 2 additions & 0 deletions aws-lc-sys/builder/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ fn emit_warning(message: &str) {
println!("cargo:warning={message}");
}

#[allow(dead_code)]
fn target_family() -> String {
cargo_env("CARGO_CFG_TARGET_FAMILY")
}
Expand Down Expand Up @@ -424,6 +425,7 @@ fn is_no_asm() -> bool {
unsafe { AWS_LC_SYS_NO_ASM }
}

#[allow(static_mut_refs)]
fn get_cflags() -> &'static str {
unsafe { AWS_LC_SYS_CFLAGS.as_str() }
}
Expand Down

0 comments on commit 465ffdc

Please sign in to comment.