diff --git a/src/toolchains/c.rs b/src/toolchains/c.rs index 61e31c1..ca73e58 100644 --- a/src/toolchains/c.rs +++ b/src/toolchains/c.rs @@ -31,6 +31,7 @@ enum CCFlavor { Clang, Gcc, Msvc, + Zigcc, } #[derive(PartialEq)] @@ -87,6 +88,7 @@ impl Toolchain for CcToolchain { "gcc" => self.compile_gcc(src_path, out_dir, lib_name), "clang" => self.compile_clang(src_path, out_dir, lib_name), "msvc" => self.compile_msvc(src_path, out_dir, lib_name), + "zigcc" => self.compile_zigcc(src_path, out_dir, lib_name), _ => unimplemented!("unknown c compiler"), } } @@ -102,6 +104,7 @@ impl Toolchain for CcToolchain { "gcc" => self.compile_gcc(src_path, out_dir, lib_name), "clang" => self.compile_clang(src_path, out_dir, lib_name), "msvc" => self.compile_msvc(src_path, out_dir, lib_name), + "zigcc" => self.compile_zigcc(src_path, out_dir, lib_name), _ => unimplemented!("unknown c compiler"), } } @@ -273,6 +276,7 @@ impl CcToolchain { TOOLCHAIN_GCC => CCFlavor::Gcc, TOOLCHAIN_CLANG => CCFlavor::Clang, TOOLCHAIN_MSVC => CCFlavor::Msvc, + TOOLCHAIN_ZIGCC => CCFlavor::Zigcc, TOOLCHAIN_CC => { let compiler = cc::Build::new() .cargo_metadata(false) @@ -369,6 +373,36 @@ impl CcToolchain { Ok(String::from(lib_name)) } + fn compile_zigcc( + &self, + src_path: &Utf8Path, + out_dir: &Utf8Path, + lib_name: &str, + ) -> Result { + let obj_path = out_dir.join(format!("{lib_name}.o")); + let lib_path = out_dir.join(format!("lib{lib_name}.a")); + let mut cmd = Command::new("zig"); + cmd.arg("cc"); + for flag in self.extra_flags() { + cmd.arg(flag); + } + cmd.arg("-ffunction-sections") + .arg("-fdata-sections") + .arg("-fPIC") + .arg("-o") + .arg(&obj_path) + .arg("-c") + .arg(src_path) + .status()?; + Command::new("ar") + .arg("cq") + .arg(&lib_path) + .arg(&obj_path) + .status()?; + Command::new("ar").arg("s").arg(&lib_path).status()?; + Ok(String::from(lib_name)) + } + fn compile_gcc( &self, src_path: &Utf8Path, diff --git a/src/toolchains/c/declare.rs b/src/toolchains/c/declare.rs index 697de2b..67638ad 100644 --- a/src/toolchains/c/declare.rs +++ b/src/toolchains/c/declare.rs @@ -94,7 +94,7 @@ impl CcToolchain { CCFlavor::Gcc => Err(UnsupportedError::Other( "GCC isn't known to support f16 on this target".to_owned(), ))?, - CCFlavor::Clang + CCFlavor::Clang | CCFlavor::Zigcc if cfg!(any( all(target_arch = "x86", target_feature = "sse2"), target_arch = "x86_64", @@ -106,7 +106,7 @@ impl CcToolchain { { "_Float16 " } - CCFlavor::Clang => Err(UnsupportedError::Other( + CCFlavor::Clang | CCFlavor::Zigcc => Err(UnsupportedError::Other( "Clang isn't known to support f16 on this target".to_owned(), ))?, CCFlavor::Msvc => Err(UnsupportedError::Other( @@ -134,7 +134,7 @@ impl CcToolchain { CCFlavor::Gcc => Err(UnsupportedError::Other( "GCC isn't known to support f128 on this target".to_owned(), ))?, - CCFlavor::Clang + CCFlavor::Clang | CCFlavor::Zigcc if cfg!(any( target_arch = "x86", target_arch = "x86_64", @@ -152,7 +152,7 @@ impl CcToolchain { { "__float128 " } - CCFlavor::Clang => Err(UnsupportedError::Other( + CCFlavor::Clang | CCFlavor::Zigcc => Err(UnsupportedError::Other( "Clang isn't known to support f128 on this target".to_owned(), ))?, CCFlavor::Msvc => Err(UnsupportedError::Other( @@ -555,7 +555,7 @@ impl CcToolchain { if self.platform == Windows { match self.cc_flavor { Msvc => "__cdecl ", - Gcc | Clang => "__attribute__((cdecl)) ", + Gcc | Clang | Zigcc => "__attribute__((cdecl)) ", } } else { return Err(self.unsupported_convention(&convention))?; @@ -565,7 +565,7 @@ impl CcToolchain { if self.platform == Windows { match self.cc_flavor { Msvc => "__stdcall ", - Gcc | Clang => "__attribute__((stdcall)) ", + Gcc | Clang | Zigcc => "__attribute__((stdcall)) ", } } else { return Err(self.unsupported_convention(&convention))?; @@ -575,7 +575,7 @@ impl CcToolchain { if self.platform == Windows { match self.cc_flavor { Msvc => "__fastcall ", - Gcc | Clang => "__attribute__((fastcall)) ", + Gcc | Clang | Zigcc => "__attribute__((fastcall)) ", } } else { return Err(self.unsupported_convention(&convention))?; @@ -585,7 +585,7 @@ impl CcToolchain { if self.platform == Windows { match self.cc_flavor { Msvc => "__vectorcall ", - Gcc | Clang => "__attribute__((vectorcall)) ", + Gcc | Clang | Zigcc => "__attribute__((vectorcall)) ", } } else { return Err(self.unsupported_convention(&convention))?; diff --git a/src/toolchains/mod.rs b/src/toolchains/mod.rs index 69cd852..38a7477 100644 --- a/src/toolchains/mod.rs +++ b/src/toolchains/mod.rs @@ -18,8 +18,15 @@ pub const TOOLCHAIN_CC: &str = "cc"; pub const TOOLCHAIN_GCC: &str = "gcc"; pub const TOOLCHAIN_CLANG: &str = "clang"; pub const TOOLCHAIN_MSVC: &str = "msvc"; +pub const TOOLCHAIN_ZIGCC: &str = "zigcc"; -const C_TOOLCHAINS: &[&str] = &[TOOLCHAIN_CC, TOOLCHAIN_GCC, TOOLCHAIN_CLANG, TOOLCHAIN_MSVC]; +const C_TOOLCHAINS: &[&str] = &[ + TOOLCHAIN_CC, + TOOLCHAIN_GCC, + TOOLCHAIN_CLANG, + TOOLCHAIN_MSVC, + TOOLCHAIN_ZIGCC, +]; /// A compiler/language toolchain! pub trait Toolchain {