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

Clarify build.rs C compiler and linker configuration. #1697

Merged
merged 4 commits into from
Oct 6, 2023
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
53 changes: 24 additions & 29 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,6 @@ fn cpp_flags(compiler: &cc::Tool) -> &'static [&'static str] {
}
}

const LD_FLAGS: &[&str] = &[];

// None means "any OS" or "any target". The first match in sequence order is
// taken.
const ASM_TARGETS: &[AsmTarget] = &[
Expand Down Expand Up @@ -389,8 +387,9 @@ fn pregenerate_asm_main() {
force_warnings_into_errors: true,
};

let b = new_build(&target, &pregenerated_tmp);
for src in srcs {
compile(&src, &target, &pregenerated_tmp, &pregenerated);
compile(&b, &src, &target, &pregenerated_tmp, &pregenerated);
}
}
}
Expand Down Expand Up @@ -485,37 +484,31 @@ fn build_c_code(
);
}

fn new_build(target: &Target, include_dir: &Path) -> cc::Build {
let mut b = cc::Build::new();
configure_cc(&mut b, target, include_dir);
b
}

fn build_library(
target: &Target,
out_dir: &Path,
lib_name: &str,
srcs: &[PathBuf],
additional_srcs: &[PathBuf],
) {
let mut c = new_build(target, out_dir);

// Compile all the (dirty) source files into object files.
let objs = additional_srcs
.iter()
.chain(srcs.iter())
.map(|f| compile(f, target, out_dir, out_dir))
.map(|f| compile(&c, f, target, out_dir, out_dir))
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now all the calls to compile() share a single build configuration that is constructed once per library, instead of once per source file.

.collect::<Vec<_>>();

// Rebuild the library if necessary.
let lib_path = PathBuf::from(out_dir).join(format!("lib{}.a", lib_name));

let mut c = cc::Build::new();

for f in LD_FLAGS {
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LD_FLAGS was empty so this wasn't doing anything.

let _ = c.flag(f);
}
match target.os.as_str() {
"macos" => {
let _ = c.flag("-fPIC");
let _ = c.flag("-Wl,-dead_strip");
}
_ => {
let _ = c.flag("-Wl,--gc-sections");
briansmith marked this conversation as resolved.
Show resolved Hide resolved
}
}
for o in objs {
let _ = c.object(o);
}
Expand All @@ -535,14 +528,14 @@ fn build_library(
println!("cargo:rustc-link-lib=static={}", lib_name);
}

fn compile(p: &Path, target: &Target, include_dir: &Path, out_dir: &Path) -> String {
fn compile(b: &cc::Build, p: &Path, target: &Target, include_dir: &Path, out_dir: &Path) -> String {
let ext = p.extension().unwrap().to_str().unwrap();
if ext == "o" {
p.to_str().expect("Invalid path").into()
} else {
let out_file = obj_path(out_dir, p);
let cmd = if target.os != WINDOWS || ext != "asm" {
cc(p, ext, target, include_dir, &out_file)
cc(b, p, ext, &out_file)
} else {
nasm(p, &target.arch, include_dir, &out_file)
};
Expand All @@ -561,9 +554,7 @@ fn obj_path(out_dir: &Path, src: &Path) -> PathBuf {
out_path
}

fn cc(file: &Path, ext: &str, target: &Target, include_dir: &Path, out_file: &Path) -> Command {
let mut c = cc::Build::new();

fn configure_cc(c: &mut cc::Build, target: &Target, include_dir: &Path) {
// FIXME: On Windows AArch64 we currently must use Clang to compile C code
if target.os == WINDOWS && target.arch == AARCH64 && !c.get_compiler().is_like_clang() {
let _ = c.compiler("clang");
Expand All @@ -573,10 +564,6 @@ fn cc(file: &Path, ext: &str, target: &Target, include_dir: &Path, out_file: &Pa

let _ = c.include("include");
let _ = c.include(include_dir);
match ext {
"c" | "S" => (),
e => panic!("Unsupported file extension: {:?}", e),
};
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to the top of the new cc().

for f in cpp_flags(&compiler) {
let _ = c.flag(f);
}
Expand Down Expand Up @@ -635,9 +622,17 @@ fn cc(file: &Path, ext: &str, target: &Target, include_dir: &Path, out_file: &Pa
// http://www.openwall.com/lists/musl/2015/06/17/1
let _ = c.flag("-U_FORTIFY_SOURCE");
}
}

fn cc(b: &cc::Build, file: &Path, ext: &str, out_file: &Path) -> Command {
match ext {
"c" | "S" => (),
e => panic!("Unsupported file extension: {:?}", e),
};

let obj_opt = if compiler.is_like_msvc() { "/Fo" } else { "-o" };
let mut c = c.get_compiler().to_command();
let cc = b.get_compiler();
let obj_opt = if cc.is_like_msvc() { "/Fo" } else { "-o" };
let mut c = cc.to_command();
let _ = c
.arg("-c")
.arg(format!(
Expand Down
Loading