Skip to content

Commit

Permalink
Add Build::asm_flag
Browse files Browse the repository at this point in the history
The method allows flags to be specified that are only applied to
assembly input files, not C files. This is helpful with clang, which
only accepts certain assembly options if the input file is asm, not C.
  • Loading branch information
nicholasbishop committed Nov 17, 2022
1 parent 0fff25a commit b377da7
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 1 deletion.
38 changes: 37 additions & 1 deletion src/lib.rs
Expand Up @@ -97,6 +97,7 @@ pub struct Build {
flags_supported: Vec<String>,
known_flag_support_status: Arc<Mutex<HashMap<String, bool>>>,
ar_flags: Vec<String>,
asm_flags: Vec<String>,
no_default_flags: bool,
files: Vec<PathBuf>,
cpp: bool,
Expand Down Expand Up @@ -299,6 +300,7 @@ impl Build {
flags_supported: Vec::new(),
known_flag_support_status: Arc::new(Mutex::new(HashMap::new())),
ar_flags: Vec::new(),
asm_flags: Vec::new(),
no_default_flags: false,
files: Vec::new(),
shared_flag: None,
Expand Down Expand Up @@ -434,6 +436,25 @@ impl Build {
self
}

/// Add a flag that will only be used with assembly files.
///
/// The flag will be applied to input files with either a `.s` or
/// `.asm` extension (case insensitive).
///
/// # Example
///
/// ```no_run
/// cc::Build::new()
/// .asm_flag("-Wa,-defsym,abc=1")
/// .file("src/foo.S") // The asm flag will be applied here
/// .file("src/bar.c") // The asm flag will not be applied here
/// .compile("foo");
/// ```
pub fn asm_flag(&mut self, flag: &str) -> &mut Build {
self.asm_flags.push(flag.to_string());
self
}

fn ensure_check_file(&self) -> Result<PathBuf, Error> {
let out_dir = self.get_out_dir()?;
let src = if self.cuda {
Expand Down Expand Up @@ -1318,7 +1339,7 @@ impl Build {
}

fn compile_object(&self, obj: &Object) -> Result<(), Error> {
let is_asm = obj.src.extension().and_then(|s| s.to_str()) == Some("asm");
let is_asm = is_asm(&obj.src);
let target = self.get_target()?;
let msvc = target.contains("msvc");
let compiler = self.try_get_compiler()?;
Expand Down Expand Up @@ -1349,6 +1370,9 @@ impl Build {
if self.cuda && self.files.len() > 1 {
cmd.arg("--device-c");
}
if is_asm {
cmd.args(&self.asm_flags);
}
if compiler.family == (ToolFamily::Msvc { clang_cl: true }) && !is_asm {
// #513: For `clang-cl`, separate flags/options from the input file.
// When cross-compiling macOS -> Windows, this avoids interpreting
Expand Down Expand Up @@ -3471,3 +3495,15 @@ fn which(tool: &Path) -> Option<PathBuf> {
return if check_exe(&mut exe) { Some(exe) } else { None };
})
}

/// Check if the file's extension is either "asm" or "s", case insensitive.
fn is_asm(file: &Path) -> bool {
if let Some(ext) = file.extension() {
if let Some(ext) = ext.to_str() {
let ext = ext.to_lowercase();
return ext == "asm" || ext == "s";
}
}

false
}
17 changes: 17 additions & 0 deletions tests/test.rs
Expand Up @@ -442,3 +442,20 @@ fn msvc_no_dash_dash() {

test.cmd(0).must_not_have("--");
}

// Disable this test with the parallel feature because the execution
// order is not deterministic.
#[cfg(not(feature = "parallel"))]
#[test]
fn asm_flags() {
let test = Test::gnu();
test.gcc()
.file("foo.c")
.file("x86_64.asm")
.file("x86_64.S")
.asm_flag("--abc")
.compile("foo");
test.cmd(0).must_not_have("--abc");
test.cmd(1).must_have("--abc");
test.cmd(2).must_have("--abc");
}

0 comments on commit b377da7

Please sign in to comment.