Skip to content

Commit 4008959

Browse files
nicholasbishopthomcc
authored andcommitted
Add Build::asm_flag
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.
1 parent 0fff25a commit 4008959

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

src/lib.rs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ pub struct Build {
9797
flags_supported: Vec<String>,
9898
known_flag_support_status: Arc<Mutex<HashMap<String, bool>>>,
9999
ar_flags: Vec<String>,
100+
asm_flags: Vec<String>,
100101
no_default_flags: bool,
101102
files: Vec<PathBuf>,
102103
cpp: bool,
@@ -299,6 +300,7 @@ impl Build {
299300
flags_supported: Vec::new(),
300301
known_flag_support_status: Arc::new(Mutex::new(HashMap::new())),
301302
ar_flags: Vec::new(),
303+
asm_flags: Vec::new(),
302304
no_default_flags: false,
303305
files: Vec::new(),
304306
shared_flag: None,
@@ -434,6 +436,25 @@ impl Build {
434436
self
435437
}
436438

439+
/// Add a flag that will only be used with assembly files.
440+
///
441+
/// The flag will be applied to input files with either a `.s` or
442+
/// `.asm` extension (case insensitive).
443+
///
444+
/// # Example
445+
///
446+
/// ```no_run
447+
/// cc::Build::new()
448+
/// .asm_flag("-Wa,-defsym,abc=1")
449+
/// .file("src/foo.S") // The asm flag will be applied here
450+
/// .file("src/bar.c") // The asm flag will not be applied here
451+
/// .compile("foo");
452+
/// ```
453+
pub fn asm_flag(&mut self, flag: &str) -> &mut Build {
454+
self.asm_flags.push(flag.to_string());
455+
self
456+
}
457+
437458
fn ensure_check_file(&self) -> Result<PathBuf, Error> {
438459
let out_dir = self.get_out_dir()?;
439460
let src = if self.cuda {
@@ -1318,7 +1339,7 @@ impl Build {
13181339
}
13191340

13201341
fn compile_object(&self, obj: &Object) -> Result<(), Error> {
1321-
let is_asm = obj.src.extension().and_then(|s| s.to_str()) == Some("asm");
1342+
let is_asm = is_asm(&obj.src);
13221343
let target = self.get_target()?;
13231344
let msvc = target.contains("msvc");
13241345
let compiler = self.try_get_compiler()?;
@@ -1349,6 +1370,9 @@ impl Build {
13491370
if self.cuda && self.files.len() > 1 {
13501371
cmd.arg("--device-c");
13511372
}
1373+
if is_asm {
1374+
cmd.args(&self.asm_flags);
1375+
}
13521376
if compiler.family == (ToolFamily::Msvc { clang_cl: true }) && !is_asm {
13531377
// #513: For `clang-cl`, separate flags/options from the input file.
13541378
// When cross-compiling macOS -> Windows, this avoids interpreting
@@ -3471,3 +3495,15 @@ fn which(tool: &Path) -> Option<PathBuf> {
34713495
return if check_exe(&mut exe) { Some(exe) } else { None };
34723496
})
34733497
}
3498+
3499+
/// Check if the file's extension is either "asm" or "s", case insensitive.
3500+
fn is_asm(file: &Path) -> bool {
3501+
if let Some(ext) = file.extension() {
3502+
if let Some(ext) = ext.to_str() {
3503+
let ext = ext.to_lowercase();
3504+
return ext == "asm" || ext == "s";
3505+
}
3506+
}
3507+
3508+
false
3509+
}

tests/test.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,3 +442,20 @@ fn msvc_no_dash_dash() {
442442

443443
test.cmd(0).must_not_have("--");
444444
}
445+
446+
// Disable this test with the parallel feature because the execution
447+
// order is not deterministic.
448+
#[cfg(not(feature = "parallel"))]
449+
#[test]
450+
fn asm_flags() {
451+
let test = Test::gnu();
452+
test.gcc()
453+
.file("foo.c")
454+
.file("x86_64.asm")
455+
.file("x86_64.S")
456+
.asm_flag("--abc")
457+
.compile("foo");
458+
test.cmd(0).must_not_have("--abc");
459+
test.cmd(1).must_have("--abc");
460+
test.cmd(2).must_have("--abc");
461+
}

0 commit comments

Comments
 (0)