aboutsummaryrefslogtreecommitdiff
path: root/src/target.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/target.cpp')
-rw-r--r--src/target.cpp172
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;
+}