Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tool: Expose family() in favour of incomplete is_like_xxx() wrappers #1358

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions dev-tools/cc-test/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ fn main() {
run_forked_capture_output(&out, "metadata-off");

run_forked_capture_output(&out, "warnings-off");
if cc::Build::new().get_compiler().is_like_msvc() {
if matches!(
cc::Build::new().get_compiler().family(),
cc::ToolFamily::Msvc { .. }
) {
// MSVC doesn't output warnings to stderr, so we can't capture them.
// the test will use this env var to know whether to run the test.
println!("cargo:rustc-env=TEST_WARNINGS_ON=0");
Expand Down Expand Up @@ -86,12 +89,12 @@ fn main() {
}

if target.contains("msvc") {
let cc_frontend = if compiler.is_like_msvc() {
"MSVC"
} else if compiler.is_like_clang() {
"CLANG"
} else {
unimplemented!("Unknown compiler that targets msvc but isn't clang-like or msvc-like")
let cc_frontend = match compiler.family() {
cc::ToolFamily::Clang { .. } => "CLANG",
cc::ToolFamily::Msvc { .. } => "MSVC",
f => unimplemented!(
"Unknown compiler `{f:?}` that targets msvc but isn't clang-like or msvc-like"
),
};

// Test that the `windows_registry` module will set PATH by looking for
Expand Down
38 changes: 20 additions & 18 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,7 @@ mod command_helpers;
use command_helpers::*;

mod tool;
pub use tool::Tool;
use tool::ToolFamily;
pub use tool::{Tool, ToolFamily};

mod tempfile;

Expand Down Expand Up @@ -701,25 +700,25 @@ impl Build {
if compiler.family.verbose_stderr() {
compiler.remove_arg("-v".into());
}
if compiler.is_like_clang() {
let clang = matches!(compiler.family(), ToolFamily::Clang { .. });
if clang {
// Avoid reporting that the arg is unsupported just because the
// compiler complains that it wasn't used.
compiler.push_cc_arg("-Wno-unused-command-line-argument".into());
}

let mut cmd = compiler.to_command();
let is_arm = matches!(target.arch, "aarch64" | "arm");
let clang = compiler.is_like_clang();
let gnu = compiler.family == ToolFamily::Gnu;
let msvc = matches!(compiler.family(), ToolFamily::Msvc { .. });
command_add_output_file(
&mut cmd,
&obj,
CmdAddOutputFileArgs {
cuda: self.cuda,
is_assembler_msvc: false,
msvc: compiler.is_like_msvc(),
msvc,
clang,
gnu,
gnu: matches!(compiler.family(), ToolFamily::Gnu),
is_asm: false,
is_arm,
},
Expand All @@ -733,7 +732,7 @@ impl Build {

// On MSVC skip the CRT by setting the entry point to `main`.
// This way we don't need to add the default library paths.
if compiler.is_like_msvc() {
if msvc {
// Flags from _LINK_ are appended to the linker arguments.
cmd.env("_LINK_", "-entry:main");
}
Expand Down Expand Up @@ -1753,8 +1752,6 @@ impl Build {
let target = self.get_target()?;
let msvc = target.env == "msvc";
let compiler = self.try_get_compiler()?;
let clang = compiler.is_like_clang();
let gnu = compiler.family == ToolFamily::Gnu;

let is_assembler_msvc = msvc && asm_ext == Some(AsmFileExt::DotAsm);
let (mut cmd, name) = if is_assembler_msvc {
Expand Down Expand Up @@ -1782,9 +1779,9 @@ impl Build {
CmdAddOutputFileArgs {
cuda: self.cuda,
is_assembler_msvc,
msvc: compiler.is_like_msvc(),
clang,
gnu,
msvc: matches!(compiler.family(), ToolFamily::Msvc { .. }),
clang: matches!(compiler.family(), ToolFamily::Clang { .. }),
gnu: matches!(compiler.family(), ToolFamily::Gnu),
is_asm,
is_arm,
},
Expand Down Expand Up @@ -2036,15 +2033,16 @@ impl Build {
}
}
ToolFamily::Gnu | ToolFamily::Clang { .. } => {
let clang = matches!(cmd.family, ToolFamily::Clang { .. });
// arm-linux-androideabi-gcc 4.8 shipped with Android NDK does
// not support '-Oz'
if opt_level == "z" && !cmd.is_like_clang() {
if opt_level == "z" && !clang {
cmd.push_opt_unless_duplicate("-Os".into());
} else {
cmd.push_opt_unless_duplicate(format!("-O{}", opt_level).into());
}

if cmd.is_like_clang() && target.os == "android" {
if clang && target.os == "android" {
// For compatibility with code that doesn't use pre-defined `__ANDROID__` macro.
// If compiler used via ndk-build or cmake (officially supported build methods)
// this macros is defined.
Expand Down Expand Up @@ -2141,7 +2139,9 @@ impl Build {
family.add_force_frame_pointer(cmd);
}

if !cmd.is_like_msvc() {
let msvc = matches!(cmd.family, ToolFamily::Msvc { .. });

if !msvc {
if target.arch == "x86" {
cmd.args.push("-m32".into());
} else if target.abi == "x32" {
Expand Down Expand Up @@ -2653,7 +2653,8 @@ impl Build {
// it does not support iOS in general), but we specify them anyhow in
// case we actually have a Clang-like compiler disguised as a GNU-like
// compiler, or in case GCC adds support for these in the future.
if !cmd.is_like_clang() {
let clang = matches!(cmd.family, ToolFamily::Clang { .. });
if !clang {
let min_version = self.apple_deployment_target(&target);
cmd.args
.push(target.apple_version_flag(&min_version).into());
Expand Down Expand Up @@ -3225,7 +3226,8 @@ impl Build {
// And even extend it to gcc targets by searching for "ar" instead
// of "llvm-ar"...
let compiler = self.get_base_compiler().ok()?;
if compiler.is_like_clang() {
let clang = matches!(compiler.family, ToolFamily::Clang { .. });
if clang {
name = format!("llvm-{}", tool).into();
self.search_programs(
&mut self.cmd(&compiler.path),
Expand Down
36 changes: 23 additions & 13 deletions src/tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,11 +281,11 @@ impl Tool {
let mut chars = flag.chars();

// Only duplicate check compiler flags
if self.is_like_msvc() {
if chars.next() != Some('/') {
return false;
}
} else if (self.is_like_gnu() || self.is_like_clang()) && chars.next() != Some('-') {
let flag_start = match self.family {
ToolFamily::Msvc { .. } => '/',
ToolFamily::Gnu | ToolFamily::Clang { .. } => '-',
};
if chars.next() != Some(flag_start) {
return false;
}

Expand Down Expand Up @@ -395,6 +395,11 @@ impl Tool {
flags
}

/// The family of this tool, representing convention of arguments etc.
pub fn family(&self) -> ToolFamily {
self.family
}

/// Whether the tool is GNU Compiler Collection-like.
pub fn is_like_gnu(&self) -> bool {
self.family == ToolFamily::Gnu
Expand All @@ -421,11 +426,6 @@ impl Tool {
matches!(self.family, ToolFamily::Msvc { .. })
}

/// Whether the tool is `clang-cl`-based MSVC-like.
pub fn is_like_clang_cl(&self) -> bool {
matches!(self.family, ToolFamily::Msvc { clang_cl: true })
}

/// Supports using `--` delimiter to separate arguments and path to source files.
pub(crate) fn supports_path_delimiter(&self) -> bool {
matches!(
Expand All @@ -441,14 +441,24 @@ impl Tool {
///
/// Detection of a family is done on best-effort basis and may not accurately reflect the tool.
#[derive(Copy, Clone, Debug, PartialEq)]
#[non_exhaustive]
pub enum ToolFamily {
/// Tool is GNU Compiler Collection-like.
#[non_exhaustive]
NobodyXu marked this conversation as resolved.
Show resolved Hide resolved
Gnu,
/// Tool is Clang-like. It differs from the GCC in a sense that it accepts superset of flags
/// and its cross-compilation approach is different.
Clang { zig_cc: bool },
/// Tool is the MSVC cl.exe.
Msvc { clang_cl: bool },
#[non_exhaustive]
Clang {
/// Tool provided by zig
zig_cc: bool,
},
/// Tool is the MSVC `cl.exe`.
#[non_exhaustive]
Msvc {
/// Whether this is `clang-cl` provided by LLVM
clang_cl: bool,
},
}

impl ToolFamily {
Expand Down
Loading