use super::super::super::*;
pub(super) struct SystemIncludesOutcome {
pub(super) includes: Vec<NormalizedPath>,
pub(super) system_includes_ns: u64,
pub(super) system_watch_ns: u64,
}
pub(super) async fn discover_system_includes(
state: &SharedState,
compiler: &NormalizedPath,
lineage: &crate::daemon::lineage::Lineage,
compiler_priority: CompilePriority,
want_rust_miss_profile: bool,
) -> SystemIncludesOutcome {
let t_system_includes = want_rust_miss_profile.then(std::time::Instant::now);
let compiler_family = crate::compiler::detect_family(&compiler.to_string_lossy());
let needs_discovery = compiler_family.needs_system_include_discovery();
let system_includes = if !needs_discovery {
Vec::new()
} else {
let use_fast = matches!(compiler_family, crate::compiler::CompilerFamily::Clang);
let mut cache = state.system_includes.lock().await;
let lineage_for_probe = lineage.clone();
cache
.get_or_discover(compiler, |c| {
let disc_args = if use_fast {
crate::depgraph::discovery_args_fast()
} else {
crate::depgraph::discovery_args()
};
let output = {
let mut cmd = std::process::Command::new(c);
cmd.args(&disc_args);
lineage_for_probe.apply_to_sync(&mut cmd, None);
crate::daemon::process::command_output_with_priority(
&mut cmd,
compiler_priority,
)
};
match output {
Ok(out) => {
let stderr = String::from_utf8_lossy(&out.stderr);
let mut paths = if use_fast {
crate::depgraph::parse_cc1_system_include_output(&stderr)
} else {
crate::depgraph::parse_system_include_output(&stderr)
};
if use_fast && paths.is_empty() {
let slow_args = crate::depgraph::discovery_args();
let mut cmd = std::process::Command::new(c);
cmd.args(&slow_args);
lineage_for_probe.apply_to_sync(&mut cmd, None);
if let Ok(out) = crate::daemon::process::command_output_with_priority(
&mut cmd,
compiler_priority,
) {
let stderr = String::from_utf8_lossy(&out.stderr);
paths = crate::depgraph::parse_system_include_output(&stderr);
}
}
paths
}
Err(e) => {
tracing::warn!("failed to run compiler for include discovery: {e}");
Vec::new()
}
}
})
.to_vec()
};
let system_includes_ns = t_system_includes
.map(|t| t.elapsed().as_nanos() as u64)
.unwrap_or(0);
let t_system_watch = want_rust_miss_profile.then(std::time::Instant::now);
watch_directories(state, &system_includes).await;
let system_watch_ns = t_system_watch
.map(|t| t.elapsed().as_nanos() as u64)
.unwrap_or(0);
SystemIncludesOutcome {
includes: system_includes,
system_includes_ns,
system_watch_ns,
}
}