From 609207801a570508e58d9e02b6ce551fbf1dca30 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 23 May 2021 16:01:41 -0700 Subject: [PATCH] make "gnu" (mingw-w64) the default C ABI on Windows Closes #6565 --- lib/std/target.zig | 35 +++-- lib/std/zig/cross_target.zig | 6 +- src/Compilation.zig | 2 +- src/libc_installation.zig | 5 +- src/link/Coff.zig | 4 +- src/stage1/target.cpp | 269 +---------------------------------- src/stage1/target.hpp | 15 -- 7 files changed, 31 insertions(+), 305 deletions(-) diff --git a/lib/std/target.zig b/lib/std/target.zig index 153d80f198..14420d5290 100644 --- a/lib/std/target.zig +++ b/lib/std/target.zig @@ -498,8 +498,8 @@ pub const Target = struct { .netbsd, .hurd, .haiku, - => return .gnu, .windows, + => return .gnu, .uefi, => return .msvc, .linux, @@ -1258,15 +1258,18 @@ pub const Target = struct { return linuxTripleSimple(allocator, self.cpu.arch, self.os.tag, self.abi); } - pub fn oFileExt_cpu_arch_abi(cpu_arch: Cpu.Arch, abi: Abi) [:0]const u8 { - switch (abi) { - .msvc => return ".obj", + pub fn oFileExt_os_abi(os_tag: Os.Tag, abi: Abi) [:0]const u8 { + if (abi == .msvc) { + return ".obj"; + } + switch (os_tag) { + .windows, .uefi => return ".obj", else => return ".o", } } pub fn oFileExt(self: Target) [:0]const u8 { - return oFileExt_cpu_arch_abi(self.cpu.arch, self.abi); + return oFileExt_os_abi(self.os.tag, self.abi); } pub fn exeFileExtSimple(cpu_arch: Cpu.Arch, os_tag: Os.Tag) [:0]const u8 { @@ -1285,30 +1288,36 @@ pub const Target = struct { return exeFileExtSimple(self.cpu.arch, self.os.tag); } - pub fn staticLibSuffix_cpu_arch_abi(cpu_arch: Cpu.Arch, abi: Abi) [:0]const u8 { - switch (abi) { - .msvc => return ".lib", + pub fn staticLibSuffix_os_abi(os_tag: Os.Tag, abi: Abi) [:0]const u8 { + if (abi == .msvc) { + return ".lib"; + } + switch (os_tag) { + .windows, .uefi => return ".lib", else => return ".a", } } pub fn staticLibSuffix(self: Target) [:0]const u8 { - return staticLibSuffix_cpu_arch_abi(self.cpu.arch, self.abi); + return staticLibSuffix_os_abi(self.os.tag, self.abi); } pub fn dynamicLibSuffix(self: Target) [:0]const u8 { return self.os.tag.dynamicLibSuffix(); } - pub fn libPrefix_cpu_arch_abi(cpu_arch: Cpu.Arch, abi: Abi) [:0]const u8 { - switch (abi) { - .msvc => return "", + pub fn libPrefix_os_abi(os_tag: Os.Tag, abi: Abi) [:0]const u8 { + if (abi == .msvc) { + return ""; + } + switch (os_tag) { + .windows, .uefi => return "", else => return "lib", } } pub fn libPrefix(self: Target) [:0]const u8 { - return libPrefix_cpu_arch_abi(self.cpu.arch, self.abi); + return libPrefix_os_abi(self.os.tag, self.abi); } pub fn getObjectFormatSimple(os_tag: Os.Tag, cpu_arch: Cpu.Arch) ObjectFormat { diff --git a/lib/std/zig/cross_target.zig b/lib/std/zig/cross_target.zig index e724be17ae..488707f113 100644 --- a/lib/std/zig/cross_target.zig +++ b/lib/std/zig/cross_target.zig @@ -473,7 +473,7 @@ pub const CrossTarget = struct { } pub fn oFileExt(self: CrossTarget) [:0]const u8 { - return Target.oFileExt_cpu_arch_abi(self.getCpuArch(), self.getAbi()); + return Target.oFileExt_os_abi(self.getOsTag(), self.getAbi()); } pub fn exeFileExt(self: CrossTarget) [:0]const u8 { @@ -481,7 +481,7 @@ pub const CrossTarget = struct { } pub fn staticLibSuffix(self: CrossTarget) [:0]const u8 { - return Target.staticLibSuffix_cpu_arch_abi(self.getCpuArch(), self.getAbi()); + return Target.staticLibSuffix_os_abi(self.getOsTag(), self.getAbi()); } pub fn dynamicLibSuffix(self: CrossTarget) [:0]const u8 { @@ -489,7 +489,7 @@ pub const CrossTarget = struct { } pub fn libPrefix(self: CrossTarget) [:0]const u8 { - return Target.libPrefix_cpu_arch_abi(self.getCpuArch(), self.getAbi()); + return Target.libPrefix_os_abi(self.getOsTag(), self.getAbi()); } pub fn isNativeCpu(self: CrossTarget) bool { diff --git a/src/Compilation.zig b/src/Compilation.zig index 9ac8dfcc41..405066331f 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -3164,7 +3164,7 @@ fn detectLibCIncludeDirs( // If linking system libraries and targeting the native abi, default to // using the system libc installation. - if (link_system_libs and is_native_abi) { + if (link_system_libs and is_native_abi and !target.isMinGW()) { const libc = try arena.create(LibCInstallation); libc.* = try LibCInstallation.findNative(.{ .allocator = arena, .verbose = true }); return detectLibCFromLibCInstallation(arena, target, libc); diff --git a/src/libc_installation.zig b/src/libc_installation.zig index f9fb0cdb01..66ff8f77fd 100644 --- a/src/libc_installation.zig +++ b/src/libc_installation.zig @@ -8,7 +8,6 @@ const build_options = @import("build_options"); const is_darwin = Target.current.isDarwin(); const is_windows = Target.current.os.tag == .windows; -const is_gnu = Target.current.isGnu(); const is_haiku = Target.current.os.tag == .haiku; const log = std.log.scoped(.libc_installation); @@ -100,14 +99,14 @@ pub const LibCInstallation = struct { log.err("crt_dir may not be empty for {s}\n", .{@tagName(Target.current.os.tag)}); return error.ParseError; } - if (self.msvc_lib_dir == null and is_windows and !is_gnu) { + if (self.msvc_lib_dir == null and is_windows) { log.err("msvc_lib_dir may not be empty for {s}-{s}\n", .{ @tagName(Target.current.os.tag), @tagName(Target.current.abi), }); return error.ParseError; } - if (self.kernel32_lib_dir == null and is_windows and !is_gnu) { + if (self.kernel32_lib_dir == null and is_windows) { log.err("kernel32_lib_dir may not be empty for {s}-{s}\n", .{ @tagName(Target.current.os.tag), @tagName(Target.current.abi), diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 374f37858e..611250c943 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -1137,14 +1137,14 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { } if (is_dyn_lib) { - try argv.append(try comp.get_libc_crt_file(arena, "dllcrt2.o")); + try argv.append(try comp.get_libc_crt_file(arena, "dllcrt2.obj")); if (target.cpu.arch == .i386) { try argv.append("-ALTERNATENAME:__DllMainCRTStartup@12=_DllMainCRTStartup@12"); } else { try argv.append("-ALTERNATENAME:_DllMainCRTStartup=DllMainCRTStartup"); } } else { - try argv.append(try comp.get_libc_crt_file(arena, "crt2.o")); + try argv.append(try comp.get_libc_crt_file(arena, "crt2.obj")); } try argv.append(try comp.get_libc_crt_file(arena, "mingw32.lib")); diff --git a/src/stage1/target.cpp b/src/stage1/target.cpp index 5a1e18e152..7e66d42c46 100644 --- a/src/stage1/target.cpp +++ b/src/stage1/target.cpp @@ -756,8 +756,7 @@ bool target_allows_addr_zero(const ZigTarget *target) { const char *target_o_file_ext(const ZigTarget *target) { if (target->abi == ZigLLVM_MSVC || - (target->os == OsWindows && !target_abi_is_gnu(target->abi)) || - target->os == OsUefi) + target->os == OsWindows || target->os == OsUefi) { return ".obj"; } else { @@ -777,29 +776,6 @@ bool target_is_android(const ZigTarget *target) { return target->abi == ZigLLVM_Android; } -bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target) { - assert(host_target != nullptr); - - if (guest_target == nullptr) { - // null guest target means that the guest target is native - return true; - } - - if (guest_target->os == host_target->os && guest_target->arch == host_target->arch) { - // OS and arch match - return true; - } - - if (guest_target->os == OsWindows && host_target->os == OsWindows && - host_target->arch == ZigLLVM_x86_64 && guest_target->arch == ZigLLVM_x86) - { - // 64-bit windows can run 32-bit programs - return true; - } - - return false; -} - const char *arch_stack_pointer_register_name(ZigLLVM_ArchType arch) { switch (arch) { case ZigLLVM_UnknownArch: @@ -946,21 +922,6 @@ bool target_has_valgrind_support(const ZigTarget *target) { zig_unreachable(); } -bool target_os_requires_libc(Os os) { - // On Darwin, we always link libSystem which contains libc. - // Similarly on FreeBSD and NetBSD we always link system libc - // since this is the stable syscall interface. - return (target_os_is_darwin(os) || os == OsFreeBSD || os == OsNetBSD || os == OsDragonFly); -} - -bool target_is_glibc(const ZigTarget *target) { - return target->os == OsLinux && target_abi_is_gnu(target->abi); -} - -bool target_is_musl(const ZigTarget *target) { - return target->os == OsLinux && target_abi_is_musl(target->abi); -} - bool target_is_wasm(const ZigTarget *target) { return target->arch == ZigLLVM_wasm32 || target->arch == ZigLLVM_wasm64; } @@ -1019,238 +980,10 @@ ZigLLVM_EnvironmentType target_default_abi(ZigLLVM_ArchType arch, Os os) { zig_unreachable(); } -bool target_abi_is_gnu(ZigLLVM_EnvironmentType abi) { - switch (abi) { - case ZigLLVM_GNU: - case ZigLLVM_GNUABIN32: - case ZigLLVM_GNUABI64: - case ZigLLVM_GNUEABI: - case ZigLLVM_GNUEABIHF: - case ZigLLVM_GNUX32: - return true; - default: - return false; - } -} - -bool target_abi_is_musl(ZigLLVM_EnvironmentType abi) { - switch (abi) { - case ZigLLVM_Musl: - case ZigLLVM_MuslEABI: - case ZigLLVM_MuslEABIHF: - return true; - default: - return false; - } -} - -struct AvailableLibC { - ZigLLVM_ArchType arch; - Os os; - ZigLLVM_EnvironmentType abi; -}; - -static const AvailableLibC libcs_available[] = { - {ZigLLVM_aarch64_be, OsLinux, ZigLLVM_GNU}, - {ZigLLVM_aarch64_be, OsLinux, ZigLLVM_Musl}, - {ZigLLVM_aarch64_be, OsWindows, ZigLLVM_GNU}, - {ZigLLVM_aarch64, OsLinux, ZigLLVM_GNU}, - {ZigLLVM_aarch64, OsLinux, ZigLLVM_Musl}, - {ZigLLVM_aarch64, OsWindows, ZigLLVM_GNU}, - {ZigLLVM_armeb, OsLinux, ZigLLVM_GNUEABI}, - {ZigLLVM_armeb, OsLinux, ZigLLVM_GNUEABIHF}, - {ZigLLVM_armeb, OsLinux, ZigLLVM_MuslEABI}, - {ZigLLVM_armeb, OsLinux, ZigLLVM_MuslEABIHF}, - {ZigLLVM_armeb, OsWindows, ZigLLVM_GNU}, - {ZigLLVM_arm, OsLinux, ZigLLVM_GNUEABI}, - {ZigLLVM_arm, OsLinux, ZigLLVM_GNUEABIHF}, - {ZigLLVM_arm, OsLinux, ZigLLVM_MuslEABI}, - {ZigLLVM_arm, OsLinux, ZigLLVM_MuslEABIHF}, - {ZigLLVM_arm, OsWindows, ZigLLVM_GNU}, - {ZigLLVM_csky, OsLinux, ZigLLVM_GNUEABI}, - {ZigLLVM_csky, OsLinux, ZigLLVM_GNUEABIHF}, - {ZigLLVM_x86, OsLinux, ZigLLVM_GNU}, - {ZigLLVM_x86, OsLinux, ZigLLVM_Musl}, - {ZigLLVM_x86, OsWindows, ZigLLVM_GNU}, - {ZigLLVM_mips64el, OsLinux, ZigLLVM_GNUABI64}, - {ZigLLVM_mips64el, OsLinux, ZigLLVM_GNUABIN32}, - {ZigLLVM_mips64el, OsLinux, ZigLLVM_Musl}, - {ZigLLVM_mips64, OsLinux, ZigLLVM_GNUABI64}, - {ZigLLVM_mips64, OsLinux, ZigLLVM_GNUABIN32}, - {ZigLLVM_mips64, OsLinux, ZigLLVM_Musl}, - {ZigLLVM_mipsel, OsLinux, ZigLLVM_GNU}, - {ZigLLVM_mipsel, OsLinux, ZigLLVM_Musl}, - {ZigLLVM_mips, OsLinux, ZigLLVM_GNU}, - {ZigLLVM_mips, OsLinux, ZigLLVM_Musl}, - {ZigLLVM_ppc64le, OsLinux, ZigLLVM_GNU}, - {ZigLLVM_ppc64le, OsLinux, ZigLLVM_Musl}, - {ZigLLVM_ppc64, OsLinux, ZigLLVM_GNU}, - {ZigLLVM_ppc64, OsLinux, ZigLLVM_Musl}, - {ZigLLVM_ppc, OsLinux, ZigLLVM_GNU}, - {ZigLLVM_ppc, OsLinux, ZigLLVM_Musl}, - {ZigLLVM_riscv64, OsLinux, ZigLLVM_GNU}, - {ZigLLVM_riscv64, OsLinux, ZigLLVM_Musl}, - {ZigLLVM_systemz, OsLinux, ZigLLVM_GNU}, - {ZigLLVM_systemz, OsLinux, ZigLLVM_Musl}, - {ZigLLVM_sparc, OsLinux, ZigLLVM_GNU}, - {ZigLLVM_sparcv9, OsLinux, ZigLLVM_GNU}, - {ZigLLVM_wasm32, OsFreestanding, ZigLLVM_Musl}, - {ZigLLVM_x86_64, OsLinux, ZigLLVM_GNU}, - {ZigLLVM_x86_64, OsLinux, ZigLLVM_GNUX32}, - {ZigLLVM_x86_64, OsLinux, ZigLLVM_Musl}, - {ZigLLVM_x86_64, OsWindows, ZigLLVM_GNU}, -}; - -bool target_can_build_libc(const ZigTarget *target) { - for (size_t i = 0; i < array_length(libcs_available); i += 1) { - if (target->arch == libcs_available[i].arch && - target->os == libcs_available[i].os && - target->abi == libcs_available[i].abi) - { - return true; - } - } - return false; -} - -const char *target_libc_generic_name(const ZigTarget *target) { - if (target->os == OsWindows) { - return "mingw"; - } - switch (target->abi) { - case ZigLLVM_GNU: - case ZigLLVM_GNUABIN32: - case ZigLLVM_GNUABI64: - case ZigLLVM_GNUEABI: - case ZigLLVM_GNUEABIHF: - case ZigLLVM_GNUX32: - case ZigLLVM_GNUILP32: - return "glibc"; - case ZigLLVM_Musl: - case ZigLLVM_MuslEABI: - case ZigLLVM_MuslEABIHF: - case ZigLLVM_UnknownEnvironment: - return "musl"; - case ZigLLVM_CODE16: - case ZigLLVM_EABI: - case ZigLLVM_EABIHF: - case ZigLLVM_Android: - case ZigLLVM_MSVC: - case ZigLLVM_Itanium: - case ZigLLVM_Cygnus: - case ZigLLVM_CoreCLR: - case ZigLLVM_Simulator: - case ZigLLVM_MacABI: - zig_unreachable(); - } - zig_unreachable(); -} - -bool target_is_libc_lib_name(const ZigTarget *target, const char *name) { - auto equal = str_eql_str; - if (target->os == OsMacOSX) - equal = str_eql_str_ignore_case; - - if (equal(name, "c")) - return true; - - if (target_abi_is_gnu(target->abi) && target->os == OsWindows) { - // mingw-w64 - - if (equal(name, "m")) - return true; - - return false; - } - - if (target_abi_is_gnu(target->abi) || target_abi_is_musl(target->abi) || target_os_is_darwin(target->os)) { - if (equal(name, "m")) - return true; - if (equal(name, "rt")) - return true; - if (equal(name, "pthread")) - return true; - if (equal(name, "crypt")) - return true; - if (equal(name, "util")) - return true; - if (equal(name, "xnet")) - return true; - if (equal(name, "resolv")) - return true; - if (equal(name, "dl")) - return true; - } - - if (target_os_is_darwin(target->os) && equal(name, "System")) - return true; - - return false; -} - -bool target_is_libcpp_lib_name(const ZigTarget *target, const char *name) { - if (strcmp(name, "c++") == 0 || strcmp(name, "c++abi") == 0) - return true; - - return false; -} - -size_t target_libc_count(void) { - return array_length(libcs_available); -} - -void target_libc_enum(size_t index, ZigTarget *out_target) { - assert(index < array_length(libcs_available)); - out_target->arch = libcs_available[index].arch; - out_target->os = libcs_available[index].os; - out_target->abi = libcs_available[index].abi; - out_target->is_native_os = false; - out_target->is_native_cpu = false; -} - bool target_has_debug_info(const ZigTarget *target) { return !target_is_wasm(target); } -const char *target_arch_musl_name(ZigLLVM_ArchType arch) { - switch (arch) { - case ZigLLVM_aarch64: - case ZigLLVM_aarch64_be: - return "aarch64"; - case ZigLLVM_arm: - case ZigLLVM_armeb: - return "arm"; - case ZigLLVM_mips: - case ZigLLVM_mipsel: - return "mips"; - case ZigLLVM_mips64el: - case ZigLLVM_mips64: - return "mips64"; - case ZigLLVM_ppc: - return "powerpc"; - case ZigLLVM_ppc64: - case ZigLLVM_ppc64le: - return "powerpc64"; - case ZigLLVM_systemz: - return "s390x"; - case ZigLLVM_x86: - return "i386"; - case ZigLLVM_x86_64: - return "x86_64"; - case ZigLLVM_riscv64: - return "riscv64"; - default: - zig_unreachable(); - } -} - -bool target_libc_needs_crti_crtn(const ZigTarget *target) { - if (target->arch == ZigLLVM_riscv32 || target->arch == ZigLLVM_riscv64 || target_is_android(target)) { - return false; - } - return true; -} - bool target_is_riscv(const ZigTarget *target) { return target->arch == ZigLLVM_riscv32 || target->arch == ZigLLVM_riscv64; } diff --git a/src/stage1/target.hpp b/src/stage1/target.hpp index 362d63eb32..115c27a8ef 100644 --- a/src/stage1/target.hpp +++ b/src/stage1/target.hpp @@ -66,7 +66,6 @@ const char *target_o_file_ext(const ZigTarget *target); const char *target_asm_file_ext(const ZigTarget *target); const char *target_llvm_ir_file_ext(const ZigTarget *target); -bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target); ZigLLVM_OSType get_llvm_os_type(Os os_type); bool target_is_arm(const ZigTarget *target); @@ -75,29 +74,15 @@ bool target_is_ppc(const ZigTarget *target); bool target_allows_addr_zero(const ZigTarget *target); bool target_has_valgrind_support(const ZigTarget *target); bool target_os_is_darwin(Os os); -bool target_os_requires_libc(Os os); -bool target_can_build_libc(const ZigTarget *target); -const char *target_libc_generic_name(const ZigTarget *target); -bool target_is_libc_lib_name(const ZigTarget *target, const char *name); -bool target_is_libcpp_lib_name(const ZigTarget *target, const char *name); -bool target_abi_is_gnu(ZigLLVM_EnvironmentType abi); -bool target_abi_is_musl(ZigLLVM_EnvironmentType abi); -bool target_is_glibc(const ZigTarget *target); -bool target_is_musl(const ZigTarget *target); bool target_is_wasm(const ZigTarget *target); bool target_is_riscv(const ZigTarget *target); bool target_is_sparc(const ZigTarget *target); bool target_is_android(const ZigTarget *target); bool target_has_debug_info(const ZigTarget *target); -const char *target_arch_musl_name(ZigLLVM_ArchType arch); uint32_t target_arch_pointer_bit_width(ZigLLVM_ArchType arch); uint32_t target_arch_largest_atomic_bits(ZigLLVM_ArchType arch); -size_t target_libc_count(void); -void target_libc_enum(size_t index, ZigTarget *out_target); -bool target_libc_needs_crti_crtn(const ZigTarget *target); - unsigned target_fn_ptr_align(const ZigTarget *target); unsigned target_fn_align(const ZigTarget *target);