Skip to content

Commit 0649772

Browse files
authored
Merge pull request #444 from Amanieu/lse_o
2 parents 95b5211 + eaab9d2 commit 0649772

File tree

1 file changed

+28
-23
lines changed

1 file changed

+28
-23
lines changed

build.rs

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ mod c {
9595

9696
use std::collections::{BTreeMap, HashSet};
9797
use std::env;
98+
use std::fs::File;
99+
use std::io::Write;
98100
use std::path::{Path, PathBuf};
99101

100102
struct Sources {
@@ -523,20 +525,13 @@ mod c {
523525
cfg.compile("libcompiler-rt.a");
524526
}
525527

526-
fn build_aarch64_out_of_line_atomics_libraries(builtins_dir: &Path, cfg: &cc::Build) {
527-
// NOTE: because we're recompiling the same source file in N different ways, building
528-
// serially is necessary. If we want to lift this restriction, we can either:
529-
// - create symlinks to lse.S and build those_(though we'd still need to pass special
530-
// #define-like flags to each of these), or
531-
// - synthesizing tiny .S files in out/ with the proper #defines, which ultimately #include
532-
// lse.S.
533-
// That said, it's unclear how useful this added complexity will be, so just do the simple
534-
// thing for now.
528+
fn build_aarch64_out_of_line_atomics_libraries(builtins_dir: &Path, cfg: &mut cc::Build) {
529+
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
535530
let outlined_atomics_file = builtins_dir.join("aarch64/lse.S");
536531
println!("cargo:rerun-if-changed={}", outlined_atomics_file.display());
537532

538-
// Ideally, this would be a Vec of object files, but cc doesn't make it *entirely*
539-
// trivial to build an individual object.
533+
cfg.include(&builtins_dir);
534+
540535
for instruction_type in &["cas", "swp", "ldadd", "ldclr", "ldeor", "ldset"] {
541536
for size in &[1, 2, 4, 8, 16] {
542537
if *size == 16 && *instruction_type != "cas" {
@@ -546,20 +541,30 @@ mod c {
546541
for (model_number, model_name) in
547542
&[(1, "relax"), (2, "acq"), (3, "rel"), (4, "acq_rel")]
548543
{
549-
let library_name = format!(
550-
"liboutline_atomic_helper_{}{}_{}.a",
551-
instruction_type, size, model_name
544+
// The original compiler-rt build system compiles the same
545+
// source file multiple times with different compiler
546+
// options. Here we do something slightly different: we
547+
// create multiple .S files with the proper #defines and
548+
// then include the original file.
549+
//
550+
// This is needed because the cc crate doesn't allow us to
551+
// override the name of object files and libtool requires
552+
// all objects in an archive to have unique names.
553+
let path =
554+
out_dir.join(format!("lse_{}{}_{}.S", instruction_type, size, model_name));
555+
let mut file = File::create(&path).unwrap();
556+
writeln!(file, "#define L_{}", instruction_type).unwrap();
557+
writeln!(file, "#define SIZE {}", size).unwrap();
558+
writeln!(file, "#define MODEL {}", model_number).unwrap();
559+
writeln!(
560+
file,
561+
"#include \"{}\"",
562+
outlined_atomics_file.canonicalize().unwrap().display()
552563
);
553-
let sym = format!("__aarch64_{}{}_{}", instruction_type, size, model_name);
554-
let mut cfg = cfg.clone();
555-
556-
cfg.include(&builtins_dir)
557-
.define(&format!("L_{}", instruction_type), None)
558-
.define("SIZE", size.to_string().as_str())
559-
.define("MODEL", model_number.to_string().as_str())
560-
.file(&outlined_atomics_file);
561-
cfg.compile(&library_name);
564+
drop(file);
565+
cfg.file(path);
562566

567+
let sym = format!("__aarch64_{}{}_{}", instruction_type, size, model_name);
563568
println!("cargo:rustc-cfg={}=\"optimized-c\"", sym);
564569
}
565570
}

0 commit comments

Comments
 (0)