diff options
Diffstat (limited to 'src/target.cpp')
| -rw-r--r-- | src/target.cpp | 172 |
1 files changed, 150 insertions, 22 deletions
diff --git a/src/target.cpp b/src/target.cpp index 7eb4998f57..a3bccabcc4 100644 --- a/src/target.cpp +++ b/src/target.cpp @@ -693,8 +693,8 @@ void get_target_triple(Buf *triple, const ZigTarget *target) { ZigLLVMGetEnvironmentTypeName(target->abi)); } -bool target_is_darwin(const ZigTarget *target) { - switch (target->os) { +bool target_os_is_darwin(Os os) { + switch (os) { case OsMacOSX: case OsIOS: case OsWatchOS: @@ -708,7 +708,7 @@ bool target_is_darwin(const ZigTarget *target) { ZigLLVM_ObjectFormatType target_object_format(const ZigTarget *target) { if (target->os == OsUefi || target->os == OsWindows) { return ZigLLVM_COFF; - } else if (target_is_darwin(target)) { + } else if (target_os_is_darwin(target->os)) { return ZigLLVM_MachO; } if (target->arch == ZigLLVM_wasm32 || @@ -942,7 +942,7 @@ const char *target_lib_file_ext(const ZigTarget *target, bool is_static, } else { if (is_static) { return ".a"; - } else if (target_is_darwin(target)) { + } else if (target_os_is_darwin(target->os)) { return buf_ptr(buf_sprintf(".%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".dylib", version_major, version_minor, version_patch)); } else { @@ -1093,22 +1093,8 @@ const char *target_dynamic_linker(const ZigTarget *target) { case OsWatchOS: case OsMacOSX: case OsUefi: - return nullptr; - case OsWindows: - switch (target->abi) { - case ZigLLVM_GNU: - case ZigLLVM_GNUABIN32: - case ZigLLVM_GNUABI64: - case ZigLLVM_GNUEABI: - case ZigLLVM_GNUEABIHF: - case ZigLLVM_GNUX32: - case ZigLLVM_Cygnus: - zig_panic("TODO implement target_dynamic_linker for mingw/cygwin"); - default: - return nullptr; - } - zig_unreachable(); + return nullptr; case OsAnanas: case OsCloudABI: @@ -1293,7 +1279,7 @@ bool target_has_valgrind_support(const ZigTarget *target) { case ZigLLVM_UnknownArch: zig_unreachable(); case ZigLLVM_x86_64: - return (target->os == OsLinux || target_is_darwin(target) || target->os == OsSolaris || + return (target->os == OsLinux || target_os_is_darwin(target->os) || target->os == OsSolaris || (target->os == OsWindows && target->abi != ZigLLVM_MSVC)); default: return false; @@ -1301,11 +1287,11 @@ bool target_has_valgrind_support(const ZigTarget *target) { zig_unreachable(); } -bool target_requires_libc(const ZigTarget *target) { +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_is_darwin(target) || target->os == OsFreeBSD || target->os == OsNetBSD); + return (target_os_is_darwin(os) || os == OsFreeBSD || os == OsNetBSD); } bool target_supports_fpic(const ZigTarget *target) { @@ -1314,6 +1300,20 @@ bool target_supports_fpic(const ZigTarget *target) { return target->os != OsWindows; } +bool target_requires_pic(const ZigTarget *target, bool linking_libc) { + // This function returns whether non-pic code is completely invalid on the given target. + return target->os == OsWindows || target_os_requires_libc(target->os) || + (linking_libc && target_is_glibc(target)); +} + +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); +} + ZigLLVM_EnvironmentType target_default_abi(ZigLLVM_ArchType arch, Os os) { switch (os) { case OsFreestanding: @@ -1370,3 +1370,131 @@ bool target_abi_is_gnu(ZigLLVM_EnvironmentType abi) { 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, OsLinux, ZigLLVM_GNU}, + {ZigLLVM_aarch64, OsLinux, ZigLLVM_MuslEABI}, + {ZigLLVM_armeb, OsLinux, ZigLLVM_GNUEABI}, + {ZigLLVM_armeb, OsLinux, ZigLLVM_GNUEABIHF}, + {ZigLLVM_armeb, OsLinux, ZigLLVM_MuslEABI}, + {ZigLLVM_armeb, OsLinux, ZigLLVM_MuslEABIHF}, + {ZigLLVM_arm, OsLinux, ZigLLVM_GNUEABI}, + {ZigLLVM_arm, OsLinux, ZigLLVM_GNUEABIHF}, + {ZigLLVM_arm, OsLinux, ZigLLVM_MuslEABI}, + {ZigLLVM_arm, OsLinux, ZigLLVM_MuslEABIHF}, + {ZigLLVM_x86, OsLinux, ZigLLVM_GNU}, + {ZigLLVM_x86, OsLinux, ZigLLVM_Musl}, + {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_nios2, OsLinux, ZigLLVM_GNU}, + {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_riscv32, 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_x86_64, OsLinux, ZigLLVM_GNU}, + {ZigLLVM_x86_64, OsLinux, ZigLLVM_GNUX32}, + {ZigLLVM_x86_64, OsLinux, ZigLLVM_Musl}, +}; + +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) { + assert(target->os == OsLinux); + switch (target->abi) { + case ZigLLVM_GNU: + case ZigLLVM_GNUABIN32: + case ZigLLVM_GNUABI64: + case ZigLLVM_GNUEABI: + case ZigLLVM_GNUEABIHF: + case ZigLLVM_GNUX32: + return "glibc"; + case ZigLLVM_Musl: + case ZigLLVM_MuslEABI: + case ZigLLVM_MuslEABIHF: + 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_UnknownEnvironment: + zig_unreachable(); + } + zig_unreachable(); +} + +bool target_is_libc_lib_name(const ZigTarget *target, const char *name) { + if (strcmp(name, "c") == 0) + return true; + + if (target_abi_is_gnu(target->abi) || target_abi_is_musl(target->abi) || target_os_is_darwin(target->os)) { + if (strcmp(name, "m") == 0) + return true; + if (strcmp(name, "rt") == 0) + return true; + if (strcmp(name, "pthread") == 0) + return true; + if (strcmp(name, "crypt") == 0) + return true; + if (strcmp(name, "util") == 0) + return true; + if (strcmp(name, "xnet") == 0) + return true; + if (strcmp(name, "resolv") == 0) + return true; + if (strcmp(name, "dl") == 0) + return true; + } + + return false; +} |
