Skip to content

Commit be62f4a

Browse files
authored
Fix caching of supported compiler flag (#1002)
1 parent bbae474 commit be62f4a

File tree

1 file changed

+43
-20
lines changed

1 file changed

+43
-20
lines changed

src/lib.rs

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,12 @@ use tool::ToolFamily;
250250
mod target_info;
251251
mod tempfile;
252252

253+
#[derive(Debug, Eq, PartialEq, Hash)]
254+
struct CompilerFlag {
255+
compiler: Box<Path>,
256+
flag: Box<str>,
257+
}
258+
253259
/// A builder for compilation of a native library.
254260
///
255261
/// A `Build` is the main type of the `cc` crate and is used to control all the
@@ -262,7 +268,7 @@ pub struct Build {
262268
objects: Vec<Arc<Path>>,
263269
flags: Vec<Arc<str>>,
264270
flags_supported: Vec<Arc<str>>,
265-
known_flag_support_status: Arc<Mutex<HashMap<String, bool>>>,
271+
known_flag_support_status_cache: Arc<Mutex<HashMap<CompilerFlag, bool>>>,
266272
ar_flags: Vec<Arc<str>>,
267273
asm_flags: Vec<Arc<str>>,
268274
no_default_flags: bool,
@@ -385,7 +391,7 @@ impl Build {
385391
objects: Vec::new(),
386392
flags: Vec::new(),
387393
flags_supported: Vec::new(),
388-
known_flag_support_status: Arc::new(Mutex::new(HashMap::new())),
394+
known_flag_support_status_cache: Arc::new(Mutex::new(HashMap::new())),
389395
ar_flags: Vec::new(),
390396
asm_flags: Vec::new(),
391397
no_default_flags: false,
@@ -595,29 +601,42 @@ impl Build {
595601
/// `known_flag_support` field. If `is_flag_supported(flag)`
596602
/// is called again, the result will be read from the hash table.
597603
pub fn is_flag_supported(&self, flag: &str) -> Result<bool, Error> {
598-
let mut known_status = self.known_flag_support_status.lock().unwrap();
599-
if let Some(is_supported) = known_status.get(flag).cloned() {
604+
let target = self.get_target()?;
605+
606+
let mut compiler = {
607+
let mut cfg = Build::new();
608+
cfg.flag(flag)
609+
.cargo_metadata(self.cargo_output.metadata)
610+
.target(&target)
611+
.opt_level(0)
612+
.host(&self.get_host()?)
613+
.debug(false)
614+
.cpp(self.cpp)
615+
.cuda(self.cuda);
616+
if let Some(ref c) = self.compiler {
617+
cfg.compiler(c.clone());
618+
}
619+
cfg.try_get_compiler()?
620+
};
621+
622+
let compiler_flag = CompilerFlag {
623+
compiler: compiler.path.clone().into(),
624+
flag: flag.into(),
625+
};
626+
627+
if let Some(is_supported) = self
628+
.known_flag_support_status_cache
629+
.lock()
630+
.unwrap()
631+
.get(&compiler_flag)
632+
.cloned()
633+
{
600634
return Ok(is_supported);
601635
}
602636

603637
let out_dir = self.get_out_dir()?;
604638
let src = self.ensure_check_file()?;
605639
let obj = out_dir.join("flag_check");
606-
let target = self.get_target()?;
607-
let host = self.get_host()?;
608-
let mut cfg = Build::new();
609-
cfg.flag(flag)
610-
.cargo_metadata(self.cargo_output.metadata)
611-
.target(&target)
612-
.opt_level(0)
613-
.host(&host)
614-
.debug(false)
615-
.cpp(self.cpp)
616-
.cuda(self.cuda);
617-
if let Some(ref c) = self.compiler {
618-
cfg.compiler(c.clone());
619-
}
620-
let mut compiler = cfg.try_get_compiler()?;
621640

622641
// Clang uses stderr for verbose output, which yields a false positive
623642
// result if the CFLAGS/CXXFLAGS include -v to aid in debugging.
@@ -653,7 +672,11 @@ impl Build {
653672
let output = cmd.output()?;
654673
let is_supported = output.status.success() && output.stderr.is_empty();
655674

656-
known_status.insert(flag.to_owned(), is_supported);
675+
self.known_flag_support_status_cache
676+
.lock()
677+
.unwrap()
678+
.insert(compiler_flag, is_supported);
679+
657680
Ok(is_supported)
658681
}
659682

0 commit comments

Comments
 (0)