Commit 9394d14815

Vexu <15308111+Vexu@users.noreply.github.com>
2019-11-06 23:14:15
self hosted compiler: unify Target and std.Target
1 parent 6dd4a27
src-self-hosted/c_int.zig
@@ -1,3 +1,5 @@
+const Target = @import("std").Target;
+
 pub const CInt = struct {
     id: Id,
     zig_name: []const u8,
@@ -65,4 +67,104 @@ pub const CInt = struct {
             .is_signed = false,
         },
     };
+
+    pub fn sizeInBits(id: CInt.Id, self: Target) u32 {
+        const arch = self.getArch();
+        switch (self.getOs()) {
+            .freestanding => switch (self.getArch()) {
+                .msp430 => switch (id) {
+                    .Short,
+                    .UShort,
+                    .Int,
+                    .UInt,
+                    => return 16,
+                    .Long,
+                    .ULong,
+                    => return 32,
+                    .LongLong,
+                    .ULongLong,
+                    => return 64,
+                },
+                else => switch (id) {
+                    .Short,
+                    .UShort,
+                    => return 16,
+                    .Int,
+                    .UInt,
+                    => return 32,
+                    .Long,
+                    .ULong,
+                    => return self.getArchPtrBitWidth(),
+                    .LongLong,
+                    .ULongLong,
+                    => return 64,
+                },
+            },
+
+            .linux,
+            .macosx,
+            .freebsd,
+            .openbsd,
+            .zen,
+            => switch (id) {
+                .Short,
+                .UShort,
+                => return 16,
+                .Int,
+                .UInt,
+                => return 32,
+                .Long,
+                .ULong,
+                => return self.getArchPtrBitWidth(),
+                .LongLong,
+                .ULongLong,
+                => return 64,
+            },
+
+            .windows, .uefi => switch (id) {
+                .Short,
+                .UShort,
+                => return 16,
+                .Int,
+                .UInt,
+                => return 32,
+                .Long,
+                .ULong,
+                .LongLong,
+                .ULongLong,
+                => return 64,
+            },
+
+            .ananas,
+            .cloudabi,
+            .dragonfly,
+            .fuchsia,
+            .ios,
+            .kfreebsd,
+            .lv2,
+            .netbsd,
+            .solaris,
+            .haiku,
+            .minix,
+            .rtems,
+            .nacl,
+            .cnk,
+            .aix,
+            .cuda,
+            .nvcl,
+            .amdhsa,
+            .ps4,
+            .elfiamcu,
+            .tvos,
+            .watchos,
+            .mesa3d,
+            .contiki,
+            .amdpal,
+            .hermit,
+            .hurd,
+            .wasi,
+            .emscripten,
+            => @panic("TODO specify the C integer type sizes for this OS"),
+        }
+    }
 };
src-self-hosted/compilation.zig
@@ -6,7 +6,7 @@ const Buffer = std.Buffer;
 const llvm = @import("llvm.zig");
 const c = @import("c.zig");
 const builtin = @import("builtin");
-const Target = @import("target.zig").Target;
+const Target = std.Target;
 const warn = std.debug.warn;
 const Token = std.zig.Token;
 const ArrayList = std.ArrayList;
@@ -48,7 +48,7 @@ pub const ZigCompiler = struct {
 
     pub fn init(allocator: *Allocator) !ZigCompiler {
         lazy_init_targets.get() orelse {
-            Target.initializeAll();
+            llvm.initializeAllTargets();
             lazy_init_targets.resolve();
         };
 
@@ -476,8 +476,8 @@ pub const Compilation = struct {
         }
 
         comp.name = try Buffer.init(comp.arena(), name);
-        comp.llvm_triple = try target.getTriple(comp.arena());
-        comp.llvm_target = try Target.llvmTargetFromTriple(comp.llvm_triple);
+        comp.llvm_triple = try llvm.getTriple(comp.arena(), target);
+        comp.llvm_target = try llvm.targetFromTriple(comp.llvm_triple);
         comp.zig_std_dir = try std.fs.path.join(comp.arena(), [_][]const u8{ zig_lib_dir, "std" });
 
         const opt_level = switch (build_mode) {
@@ -720,7 +720,7 @@ pub const Compilation = struct {
                 },
                 .key = Type.Int.Key{
                     .is_signed = cint.is_signed,
-                    .bit_count = comp.target.cIntTypeSizeInBits(cint.id),
+                    .bit_count = cint.sizeInBits(comp.target),
                 },
                 .garbage_node = undefined,
             };
src-self-hosted/libc_installation.zig
@@ -1,7 +1,8 @@
 const std = @import("std");
 const builtin = @import("builtin");
 const event = std.event;
-const Target = @import("target.zig").Target;
+const target = @import("target.zig");
+const Target = target.Target;
 const c = @import("c.zig");
 const fs = std.fs;
 const Allocator = std.mem.Allocator;
@@ -137,7 +138,7 @@ pub const LibCInstallation = struct {
             self.static_lib_dir orelse "",
             self.msvc_lib_dir orelse "",
             self.kernel32_lib_dir orelse "",
-            self.dynamic_linker_path orelse Target(Target.Native).getDynamicLinkerPath(),
+            self.dynamic_linker_path orelse target.getDynamicLinkerPath(Target(Target.Native)),
         );
     }
 
src-self-hosted/link.zig
@@ -4,7 +4,7 @@ const c = @import("c.zig");
 const builtin = @import("builtin");
 const ObjectFormat = builtin.ObjectFormat;
 const Compilation = @import("compilation.zig").Compilation;
-const Target = @import("target.zig").Target;
+const Target = std.Target;
 const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
 const assert = std.debug.assert;
 
src-self-hosted/llvm.zig
@@ -1,6 +1,7 @@
 const builtin = @import("builtin");
 const c = @import("c.zig");
-const assert = @import("std").debug.assert;
+const std = @import("std");
+const assert = std.debug.assert;
 
 // we wrap the c module for 3 reasons:
 // 1. to avoid accidentally calling the non-thread-safe functions
@@ -290,3 +291,43 @@ pub const BuildCall = ZigLLVMBuildCall;
 extern fn ZigLLVMBuildCall(B: *Builder, Fn: *Value, Args: [*]*Value, NumArgs: c_uint, CC: c_uint, fn_inline: FnInline, Name: [*]const u8) ?*Value;
 
 pub const PrivateLinkage = c.LLVMLinkage.LLVMPrivateLinkage;
+
+pub fn targetFromTriple(triple: std.Buffer) !*Target {
+    var result: *Target = undefined;
+    var err_msg: [*]u8 = undefined;
+    if (GetTargetFromTriple(triple.ptr(), &result, &err_msg) != 0) {
+        std.debug.warn("triple: {s} error: {s}\n", triple.ptr(), err_msg);
+        return error.UnsupportedTarget;
+    }
+    return result;
+}
+
+pub fn initializeAllTargets() void {
+    InitializeAllTargets();
+    InitializeAllTargetInfos();
+    InitializeAllTargetMCs();
+    InitializeAllAsmPrinters();
+    InitializeAllAsmParsers();
+}
+
+pub fn getTriple(allocator: *std.mem.Allocator, self: Target) !std.Buffer {
+    var result = try std.Buffer.initSize(allocator, 0);
+    errdefer result.deinit();
+
+    // LLVM WebAssembly output support requires the target to be activated at
+    // build type with -DCMAKE_LLVM_EXPIERMENTAL_TARGETS_TO_BUILD=WebAssembly.
+    //
+    // LLVM determines the output format based on the abi suffix,
+    // defaulting to an object based on the architecture. The default format in
+    // LLVM 6 sets the wasm arch output incorrectly to ELF. We need to
+    // explicitly set this ourself in order for it to work.
+    //
+    // This is fixed in LLVM 7 and you will be able to get wasm output by
+    // using the target triple `wasm32-unknown-unknown-unknown`.
+    const env_name = if (self.isWasm()) "wasm" else @tagName(self.getAbi());
+
+    var out = &std.io.BufferOutStream.init(&result).stream;
+    try out.print("{}-unknown-{}-{}", @tagName(self.getArch()), @tagName(self.getOs()), env_name);
+
+    return result;
+}
\ No newline at end of file
src-self-hosted/main.zig
@@ -18,7 +18,7 @@ const Args = arg.Args;
 const Flag = arg.Flag;
 const ZigCompiler = @import("compilation.zig").ZigCompiler;
 const Compilation = @import("compilation.zig").Compilation;
-const Target = @import("target.zig").Target;
+const Target = std.Target;
 const errmsg = @import("errmsg.zig");
 const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
 
src-self-hosted/target.zig
@@ -1,9 +1,4 @@
-const std = @import("std");
-const builtin = @import("builtin");
-const llvm = @import("llvm.zig");
-const CInt = @import("c_int.zig").CInt;
-
-// TODO delete this file and use std.Target
+// const builtin = @import("builtin");
 
 pub const FloatAbi = enum {
     Hard,
@@ -11,430 +6,161 @@ pub const FloatAbi = enum {
     SoftFp,
 };
 
-pub const Target = union(enum) {
-    Native,
-    Cross: Cross,
-
-    pub const Cross = struct {
-        arch: builtin.Arch,
-        os: builtin.Os,
-        abi: builtin.Abi,
-        object_format: builtin.ObjectFormat,
+// pub const Cross = struct {
+//     arch: Target.Arch,
+//     os: Target.Os,
+//     abi: Target.Abi,
+//     object_format: builtin.ObjectFormat,
+// };
+
+// pub fn getObjectFormat(self: Target) builtin.ObjectFormat {
+//     return switch (self) {
+//         .Native => builtin.object_format,
+//         .Cross => |t| t.object_format,
+//     };
+// }
+
+/// TODO expose the arch and subarch separately
+pub fn isArmOrThumb(self: Target) bool {
+    return switch (self.getArch()) {
+        .arm,
+        .armeb,
+        .aarch64,
+        .aarch64_be,
+        .thumb,
+        .thumbeb,
+        => true,
+        else => false,
     };
-
-    pub fn objFileExt(self: Target) []const u8 {
-        return switch (self.getObjectFormat()) {
-            builtin.ObjectFormat.coff => ".obj",
-            else => ".o",
-        };
-    }
-
-    pub fn exeFileExt(self: Target) []const u8 {
-        return switch (self.getOs()) {
-            builtin.Os.windows => ".exe",
-            else => "",
-        };
-    }
-
-    pub fn libFileExt(self: Target, is_static: bool) []const u8 {
-        return switch (self.getOs()) {
-            builtin.Os.windows => if (is_static) ".lib" else ".dll",
-            else => if (is_static) ".a" else ".so",
-        };
-    }
-
-    pub fn getOs(self: Target) builtin.Os {
-        return switch (self) {
-            Target.Native => builtin.os,
-            @TagType(Target).Cross => |t| t.os,
-        };
-    }
-
-    pub fn getArch(self: Target) builtin.Arch {
-        switch (self) {
-            Target.Native => return builtin.arch,
-            @TagType(Target).Cross => |t| return t.arch,
-        }
-    }
-
-    pub fn getAbi(self: Target) builtin.Abi {
-        return switch (self) {
-            Target.Native => builtin.abi,
-            @TagType(Target).Cross => |t| t.abi,
-        };
-    }
-
-    pub fn getObjectFormat(self: Target) builtin.ObjectFormat {
-        return switch (self) {
-            Target.Native => builtin.object_format,
-            @TagType(Target).Cross => |t| t.object_format,
-        };
-    }
-
-    pub fn isWasm(self: Target) bool {
-        return switch (self.getArch()) {
-            builtin.Arch.wasm32, builtin.Arch.wasm64 => true,
-            else => false,
-        };
-    }
-
-    pub fn isDarwin(self: Target) bool {
-        return switch (self.getOs()) {
-            builtin.Os.ios, builtin.Os.macosx => true,
-            else => false,
-        };
-    }
-
-    pub fn isWindows(self: Target) bool {
-        return switch (self.getOs()) {
-            builtin.Os.windows => true,
-            else => false,
-        };
-    }
-
-    /// TODO expose the arch and subarch separately
-    pub fn isArmOrThumb(self: Target) bool {
-        return switch (self.getArch()) {
-            builtin.Arch.arm,
-            builtin.Arch.armeb,
-            builtin.Arch.aarch64,
-            builtin.Arch.aarch64_be,
-            builtin.Arch.thumb,
-            builtin.Arch.thumbeb,
-            => true,
-            else => false,
-        };
-    }
-
-    pub fn initializeAll() void {
-        llvm.InitializeAllTargets();
-        llvm.InitializeAllTargetInfos();
-        llvm.InitializeAllTargetMCs();
-        llvm.InitializeAllAsmPrinters();
-        llvm.InitializeAllAsmParsers();
-    }
-
-    pub fn getTriple(self: Target, allocator: *std.mem.Allocator) !std.Buffer {
-        var result = try std.Buffer.initSize(allocator, 0);
-        errdefer result.deinit();
-
-        // LLVM WebAssembly output support requires the target to be activated at
-        // build type with -DCMAKE_LLVM_EXPIERMENTAL_TARGETS_TO_BUILD=WebAssembly.
-        //
-        // LLVM determines the output format based on the abi suffix,
-        // defaulting to an object based on the architecture. The default format in
-        // LLVM 6 sets the wasm arch output incorrectly to ELF. We need to
-        // explicitly set this ourself in order for it to work.
-        //
-        // This is fixed in LLVM 7 and you will be able to get wasm output by
-        // using the target triple `wasm32-unknown-unknown-unknown`.
-        const env_name = if (self.isWasm()) "wasm" else @tagName(self.getAbi());
-
-        var out = &std.io.BufferOutStream.init(&result).stream;
-        try out.print("{}-unknown-{}-{}", @tagName(self.getArch()), @tagName(self.getOs()), env_name);
-
-        return result;
-    }
-
-    pub fn is64bit(self: Target) bool {
-        return self.getArchPtrBitWidth() == 64;
-    }
-
-    pub fn getArchPtrBitWidth(self: Target) u32 {
-        switch (self.getArch()) {
-            builtin.Arch.avr,
-            builtin.Arch.msp430,
-            => return 16,
-
-            builtin.Arch.arc,
-            builtin.Arch.arm,
-            builtin.Arch.armeb,
-            builtin.Arch.hexagon,
-            builtin.Arch.le32,
-            builtin.Arch.mips,
-            builtin.Arch.mipsel,
-            builtin.Arch.powerpc,
-            builtin.Arch.r600,
-            builtin.Arch.riscv32,
-            builtin.Arch.sparc,
-            builtin.Arch.sparcel,
-            builtin.Arch.tce,
-            builtin.Arch.tcele,
-            builtin.Arch.thumb,
-            builtin.Arch.thumbeb,
-            builtin.Arch.i386,
-            builtin.Arch.xcore,
-            builtin.Arch.nvptx,
-            builtin.Arch.amdil,
-            builtin.Arch.hsail,
-            builtin.Arch.spir,
-            builtin.Arch.kalimba,
-            builtin.Arch.shave,
-            builtin.Arch.lanai,
-            builtin.Arch.wasm32,
-            builtin.Arch.renderscript32,
-            => return 32,
-
-            builtin.Arch.aarch64,
-            builtin.Arch.aarch64_be,
-            builtin.Arch.mips64,
-            builtin.Arch.mips64el,
-            builtin.Arch.powerpc64,
-            builtin.Arch.powerpc64le,
-            builtin.Arch.riscv64,
-            builtin.Arch.x86_64,
-            builtin.Arch.nvptx64,
-            builtin.Arch.le64,
-            builtin.Arch.amdil64,
-            builtin.Arch.hsail64,
-            builtin.Arch.spir64,
-            builtin.Arch.wasm64,
-            builtin.Arch.renderscript64,
-            builtin.Arch.amdgcn,
-            builtin.Arch.bpfel,
-            builtin.Arch.bpfeb,
-            builtin.Arch.sparcv9,
-            builtin.Arch.s390x,
-            => return 64,
-        }
-    }
-
-    pub fn getFloatAbi(self: Target) FloatAbi {
-        return switch (self.getAbi()) {
-            builtin.Abi.gnueabihf,
-            builtin.Abi.eabihf,
-            builtin.Abi.musleabihf,
-            => FloatAbi.Hard,
-            else => FloatAbi.Soft,
-        };
-    }
-
-    pub fn getDynamicLinkerPath(self: Target) ?[]const u8 {
-        const env = self.getAbi();
-        const arch = self.getArch();
-        const os = self.getOs();
-        switch (os) {
-            builtin.Os.freebsd => {
-                return "/libexec/ld-elf.so.1";
-            },
-            builtin.Os.linux => {
-                switch (env) {
-                    builtin.Abi.android => {
-                        if (self.is64bit()) {
-                            return "/system/bin/linker64";
-                        } else {
-                            return "/system/bin/linker";
-                        }
-                    },
-                    builtin.Abi.gnux32 => {
-                        if (arch == builtin.Arch.x86_64) {
-                            return "/libx32/ld-linux-x32.so.2";
-                        }
-                    },
-                    builtin.Abi.musl,
-                    builtin.Abi.musleabi,
-                    builtin.Abi.musleabihf,
-                    => {
-                        if (arch == builtin.Arch.x86_64) {
-                            return "/lib/ld-musl-x86_64.so.1";
-                        }
-                    },
-                    else => {},
-                }
-                switch (arch) {
-                    builtin.Arch.i386,
-                    builtin.Arch.sparc,
-                    builtin.Arch.sparcel,
-                    => return "/lib/ld-linux.so.2",
-
-                    builtin.Arch.aarch64 => return "/lib/ld-linux-aarch64.so.1",
-
-                    builtin.Arch.aarch64_be => return "/lib/ld-linux-aarch64_be.so.1",
-
-                    builtin.Arch.arm,
-                    builtin.Arch.thumb,
-                    => return switch (self.getFloatAbi()) {
-                        FloatAbi.Hard => return "/lib/ld-linux-armhf.so.3",
-                        else => return "/lib/ld-linux.so.3",
-                    },
-
-                    builtin.Arch.armeb,
-                    builtin.Arch.thumbeb,
-                    => return switch (self.getFloatAbi()) {
-                        FloatAbi.Hard => return "/lib/ld-linux-armhf.so.3",
-                        else => return "/lib/ld-linux.so.3",
-                    },
-
-                    builtin.Arch.mips,
-                    builtin.Arch.mipsel,
-                    builtin.Arch.mips64,
-                    builtin.Arch.mips64el,
-                    => return null,
-
-                    builtin.Arch.powerpc => return "/lib/ld.so.1",
-                    builtin.Arch.powerpc64 => return "/lib64/ld64.so.2",
-                    builtin.Arch.powerpc64le => return "/lib64/ld64.so.2",
-                    builtin.Arch.s390x => return "/lib64/ld64.so.1",
-                    builtin.Arch.sparcv9 => return "/lib64/ld-linux.so.2",
-                    builtin.Arch.x86_64 => return "/lib64/ld-linux-x86-64.so.2",
-
-                    builtin.Arch.arc,
-                    builtin.Arch.avr,
-                    builtin.Arch.bpfel,
-                    builtin.Arch.bpfeb,
-                    builtin.Arch.hexagon,
-                    builtin.Arch.msp430,
-                    builtin.Arch.r600,
-                    builtin.Arch.amdgcn,
-                    builtin.Arch.riscv32,
-                    builtin.Arch.riscv64,
-                    builtin.Arch.tce,
-                    builtin.Arch.tcele,
-                    builtin.Arch.xcore,
-                    builtin.Arch.nvptx,
-                    builtin.Arch.nvptx64,
-                    builtin.Arch.le32,
-                    builtin.Arch.le64,
-                    builtin.Arch.amdil,
-                    builtin.Arch.amdil64,
-                    builtin.Arch.hsail,
-                    builtin.Arch.hsail64,
-                    builtin.Arch.spir,
-                    builtin.Arch.spir64,
-                    builtin.Arch.kalimba,
-                    builtin.Arch.shave,
-                    builtin.Arch.lanai,
-                    builtin.Arch.wasm32,
-                    builtin.Arch.wasm64,
-                    builtin.Arch.renderscript32,
-                    builtin.Arch.renderscript64,
-                    => return null,
-                }
-            },
-            else => return null,
-        }
-    }
-
-    pub fn llvmTargetFromTriple(triple: std.Buffer) !*llvm.Target {
-        var result: *llvm.Target = undefined;
-        var err_msg: [*]u8 = undefined;
-        if (llvm.GetTargetFromTriple(triple.ptr(), &result, &err_msg) != 0) {
-            std.debug.warn("triple: {s} error: {s}\n", triple.ptr(), err_msg);
-            return error.UnsupportedTarget;
-        }
-        return result;
-    }
-
-    pub fn cIntTypeSizeInBits(self: Target, id: CInt.Id) u32 {
-        const arch = self.getArch();
-        switch (self.getOs()) {
-            builtin.Os.freestanding => switch (self.getArch()) {
-                builtin.Arch.msp430 => switch (id) {
-                    CInt.Id.Short,
-                    CInt.Id.UShort,
-                    CInt.Id.Int,
-                    CInt.Id.UInt,
-                    => return 16,
-                    CInt.Id.Long,
-                    CInt.Id.ULong,
-                    => return 32,
-                    CInt.Id.LongLong,
-                    CInt.Id.ULongLong,
-                    => return 64,
+}
+
+pub fn getFloatAbi(self: Target) FloatAbi {
+    return switch (self.getAbi()) {
+        .gnueabihf,
+        .eabihf,
+        .musleabihf,
+        => .Hard,
+        else => .Soft,
+    };
+}
+
+pub fn getDynamicLinkerPath(self: Target) ?[]const u8 {
+    const env = self.getAbi();
+    const arch = self.getArch();
+    const os = self.getOs();
+    switch (os) {
+        .freebsd => {
+            return "/libexec/ld-elf.so.1";
+        },
+        .linux => {
+            switch (env) {
+                .android => {
+                    if (is64bit(self)) {
+                        return "/system/bin/linker64";
+                    } else {
+                        return "/system/bin/linker";
+                    }
                 },
-                else => switch (id) {
-                    CInt.Id.Short,
-                    CInt.Id.UShort,
-                    => return 16,
-                    CInt.Id.Int,
-                    CInt.Id.UInt,
-                    => return 32,
-                    CInt.Id.Long,
-                    CInt.Id.ULong,
-                    => return self.getArchPtrBitWidth(),
-                    CInt.Id.LongLong,
-                    CInt.Id.ULongLong,
-                    => return 64,
+                .gnux32 => {
+                    if (arch == .x86_64) {
+                        return "/libx32/ld-linux-x32.so.2";
+                    }
+                },
+                .musl,
+                .musleabi,
+                .musleabihf,
+                => {
+                    if (arch == .x86_64) {
+                        return "/lib/ld-musl-x86_64.so.1";
+                    }
+                },
+                else => {},
+            }
+            switch (arch) {
+                .i386,
+                .sparc,
+                .sparcel,
+                => return "/lib/ld-linux.so.2",
+
+                .aarch64 => return "/lib/ld-linux-aarch64.so.1",
+
+                .aarch64_be => return "/lib/ld-linux-aarch64_be.so.1",
+
+                .arm,
+                .thumb,
+                => return switch (getFloatAbi(self)) {
+                    .Hard => return "/lib/ld-linux-armhf.so.3",
+                    else => return "/lib/ld-linux.so.3",
                 },
-            },
-
-            builtin.Os.linux,
-            builtin.Os.macosx,
-            builtin.Os.freebsd,
-            builtin.Os.openbsd,
-            builtin.Os.zen,
-            => switch (id) {
-                CInt.Id.Short,
-                CInt.Id.UShort,
-                => return 16,
-                CInt.Id.Int,
-                CInt.Id.UInt,
-                => return 32,
-                CInt.Id.Long,
-                CInt.Id.ULong,
-                => return self.getArchPtrBitWidth(),
-                CInt.Id.LongLong,
-                CInt.Id.ULongLong,
-                => return 64,
-            },
-
-            builtin.Os.windows, builtin.Os.uefi => switch (id) {
-                CInt.Id.Short,
-                CInt.Id.UShort,
-                => return 16,
-                CInt.Id.Int,
-                CInt.Id.UInt,
-                => return 32,
-                CInt.Id.Long,
-                CInt.Id.ULong,
-                CInt.Id.LongLong,
-                CInt.Id.ULongLong,
-                => return 64,
-            },
 
-            builtin.Os.ananas,
-            builtin.Os.cloudabi,
-            builtin.Os.dragonfly,
-            builtin.Os.fuchsia,
-            builtin.Os.ios,
-            builtin.Os.kfreebsd,
-            builtin.Os.lv2,
-            builtin.Os.netbsd,
-            builtin.Os.solaris,
-            builtin.Os.haiku,
-            builtin.Os.minix,
-            builtin.Os.rtems,
-            builtin.Os.nacl,
-            builtin.Os.cnk,
-            builtin.Os.aix,
-            builtin.Os.cuda,
-            builtin.Os.nvcl,
-            builtin.Os.amdhsa,
-            builtin.Os.ps4,
-            builtin.Os.elfiamcu,
-            builtin.Os.tvos,
-            builtin.Os.watchos,
-            builtin.Os.mesa3d,
-            builtin.Os.contiki,
-            builtin.Os.amdpal,
-            builtin.Os.hermit,
-            builtin.Os.hurd,
-            builtin.Os.wasi,
-            => @panic("TODO specify the C integer type sizes for this OS"),
-        }
-    }
+                .armeb,
+                .thumbeb,
+                => return switch (getFloatAbi(self)) {
+                    .Hard => return "/lib/ld-linux-armhf.so.3",
+                    else => return "/lib/ld-linux.so.3",
+                },
 
-    pub fn getDarwinArchString(self: Target) []const u8 {
-        const arch = self.getArch();
-        switch (arch) {
-            builtin.Arch.aarch64 => return "arm64",
-            builtin.Arch.thumb,
-            builtin.Arch.arm,
-            => return "arm",
-            builtin.Arch.powerpc => return "ppc",
-            builtin.Arch.powerpc64 => return "ppc64",
-            builtin.Arch.powerpc64le => return "ppc64le",
-            else => return @tagName(arch),
-        }
-    }
-};
+                .mips,
+                .mipsel,
+                .mips64,
+                .mips64el,
+                => return null,
+
+                .powerpc => return "/lib/ld.so.1",
+                .powerpc64 => return "/lib64/ld64.so.2",
+                .powerpc64le => return "/lib64/ld64.so.2",
+                .s390x => return "/lib64/ld64.so.1",
+                .sparcv9 => return "/lib64/ld-linux.so.2",
+                .x86_64 => return "/lib64/ld-linux-x86-64.so.2",
+
+                .arc,
+                .avr,
+                .bpfel,
+                .bpfeb,
+                .hexagon,
+                .msp430,
+                .r600,
+                .amdgcn,
+                .riscv32,
+                .riscv64,
+                .tce,
+                .tcele,
+                .xcore,
+                .nvptx,
+                .nvptx64,
+                .le32,
+                .le64,
+                .amdil,
+                .amdil64,
+                .hsail,
+                .hsail64,
+                .spir,
+                .spir64,
+                .kalimba,
+                .shave,
+                .lanai,
+                .wasm32,
+                .wasm64,
+                .renderscript32,
+                .renderscript64,
+                .aarch64_32,
+                => return null,
+            }
+        },
+        else => return null,
+    }
+}
+
+pub fn getDarwinArchString(self: Target) []const u8 {
+    const arch = self.getArch();
+    switch (arch) {
+        .aarch64 => return "arm64",
+        .thumb,
+        .arm,
+        => return "arm",
+        .powerpc => return "ppc",
+        .powerpc64 => return "ppc64",
+        .powerpc64le => return "ppc64le",
+        else => return @tagName(arch),
+    }
+}
src-self-hosted/test.zig
@@ -1,7 +1,7 @@
 const std = @import("std");
 const mem = std.mem;
 const builtin = @import("builtin");
-const Target = @import("target.zig").Target;
+const Target = std.Target;
 const Compilation = @import("compilation.zig").Compilation;
 const introspect = @import("introspect.zig");
 const testing = std.testing;