mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 14:25:16 +00:00
self-host dynamic linker detection
This commit is contained in:
parent
c784c52819
commit
2f9c5c0644
@ -2974,18 +2974,26 @@ pub fn nanosleep(seconds: u64, nanoseconds: u64) void {
|
||||
}
|
||||
|
||||
pub fn dl_iterate_phdr(
|
||||
comptime T: type,
|
||||
callback: extern fn (info: *dl_phdr_info, size: usize, data: ?*T) i32,
|
||||
data: ?*T,
|
||||
) isize {
|
||||
context: var,
|
||||
comptime Error: type,
|
||||
comptime callback: fn (info: *dl_phdr_info, size: usize, context: @TypeOf(context)) Error!void,
|
||||
) Error!void {
|
||||
const Context = @TypeOf(context);
|
||||
|
||||
if (builtin.object_format != .elf)
|
||||
@compileError("dl_iterate_phdr is not available for this target");
|
||||
|
||||
if (builtin.link_libc) {
|
||||
return system.dl_iterate_phdr(
|
||||
@ptrCast(std.c.dl_iterate_phdr_callback, callback),
|
||||
@ptrCast(?*c_void, data),
|
||||
);
|
||||
switch (system.dl_iterate_phdr(struct {
|
||||
fn callbackC(info: *dl_phdr_info, size: usize, data: ?*c_void) callconv(.C) c_int {
|
||||
const context_ptr = @ptrCast(*const Context, @alignCast(@alignOf(*const Context), data));
|
||||
callback(info, size, context_ptr.*) catch |err| return @errorToInt(err);
|
||||
return 0;
|
||||
}
|
||||
}.callbackC, @intToPtr(?*c_void, @ptrToInt(&context)))) {
|
||||
0 => return,
|
||||
else => |err| return @errSetCast(Error, @intToError(@intCast(u16, err))), // TODO don't hardcode u16
|
||||
}
|
||||
}
|
||||
|
||||
const elf_base = std.process.getBaseAddress();
|
||||
@ -3007,11 +3015,10 @@ pub fn dl_iterate_phdr(
|
||||
.dlpi_phnum = ehdr.e_phnum,
|
||||
};
|
||||
|
||||
return callback(&info, @sizeOf(dl_phdr_info), data);
|
||||
return callback(&info, @sizeOf(dl_phdr_info), context);
|
||||
}
|
||||
|
||||
// Last return value from the callback function
|
||||
var last_r: isize = 0;
|
||||
while (it.next()) |entry| {
|
||||
var dlpi_phdr: [*]elf.Phdr = undefined;
|
||||
var dlpi_phnum: u16 = undefined;
|
||||
@ -3033,11 +3040,8 @@ pub fn dl_iterate_phdr(
|
||||
.dlpi_phnum = dlpi_phnum,
|
||||
};
|
||||
|
||||
last_r = callback(&info, @sizeOf(dl_phdr_info), data);
|
||||
if (last_r != 0) break;
|
||||
try callback(&info, @sizeOf(dl_phdr_info), context);
|
||||
}
|
||||
|
||||
return last_r;
|
||||
}
|
||||
|
||||
pub const ClockGetTimeError = error{UnsupportedClock} || UnexpectedError;
|
||||
|
||||
@ -613,3 +613,59 @@ pub fn getBaseAddress() usize {
|
||||
else => @compileError("Unsupported OS"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Caller owns the result value and each inner slice.
|
||||
pub fn getSelfExeSharedLibPaths(allocator: *Allocator) error{OutOfMemory}![][:0]u8 {
|
||||
switch (builtin.link_mode) {
|
||||
.Static => return &[_][:0]u8{},
|
||||
.Dynamic => {},
|
||||
}
|
||||
const List = std.ArrayList([:0]u8);
|
||||
switch (builtin.os) {
|
||||
.linux,
|
||||
.freebsd,
|
||||
.netbsd,
|
||||
.dragonfly,
|
||||
=> {
|
||||
var paths = List.init(allocator);
|
||||
errdefer {
|
||||
const slice = paths.toOwnedSlice();
|
||||
for (slice) |item| {
|
||||
allocator.free(item);
|
||||
}
|
||||
allocator.free(slice);
|
||||
}
|
||||
try os.dl_iterate_phdr(&paths, error{OutOfMemory}, struct {
|
||||
fn callback(info: *os.dl_phdr_info, size: usize, list: *List) !void {
|
||||
const name = info.dlpi_name orelse return;
|
||||
if (name[0] == '/') {
|
||||
const item = try mem.dupeZ(list.allocator, u8, mem.toSliceConst(u8, name));
|
||||
errdefer list.allocator.free(item);
|
||||
try list.append(item);
|
||||
}
|
||||
}
|
||||
}.callback);
|
||||
return paths.toOwnedSlice();
|
||||
},
|
||||
.macosx, .ios, .watchos, .tvos => {
|
||||
var paths = List.init(allocator);
|
||||
errdefer {
|
||||
const slice = paths.toOwnedSlice();
|
||||
for (slice) |item| {
|
||||
allocator.free(item);
|
||||
}
|
||||
allocator.free(slice);
|
||||
}
|
||||
const img_count = std.c._dyld_image_count();
|
||||
var i: u32 = 0;
|
||||
while (i < img_count) : (i += 1) {
|
||||
const name = std.c._dyld_get_image_name(i);
|
||||
const item = try mem.dupeZ(allocator, u8, mem.toSliceConst(u8, name));
|
||||
errdefer allocator.free(item);
|
||||
try paths.append(item);
|
||||
}
|
||||
return paths.toOwnedSlice();
|
||||
},
|
||||
else => return error.UnimplementedSelfExeSharedPaths,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1037,6 +1037,13 @@ pub const Target = union(enum) {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn isAndroid(self: Target) bool {
|
||||
return switch (self.getAbi()) {
|
||||
.android => true,
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn isDragonFlyBSD(self: Target) bool {
|
||||
return switch (self.getOs()) {
|
||||
.dragonfly => true,
|
||||
@ -1196,6 +1203,136 @@ pub const Target = union(enum) {
|
||||
|
||||
return .unavailable;
|
||||
}
|
||||
|
||||
pub const FloatAbi = enum {
|
||||
hard,
|
||||
soft,
|
||||
soft_fp,
|
||||
};
|
||||
|
||||
pub fn getFloatAbi(self: Target) FloatAbi {
|
||||
return switch (self.getAbi()) {
|
||||
.gnueabihf,
|
||||
.eabihf,
|
||||
.musleabihf,
|
||||
=> .hard,
|
||||
else => .soft,
|
||||
};
|
||||
}
|
||||
|
||||
/// Caller owns returned memory.
|
||||
pub fn getStandardDynamicLinkerPath(
|
||||
self: Target,
|
||||
allocator: *mem.Allocator,
|
||||
) error{
|
||||
OutOfMemory,
|
||||
UnknownDynamicLinkerPath,
|
||||
}![:0]u8 {
|
||||
const a = allocator;
|
||||
if (self.isAndroid()) {
|
||||
return mem.dupeZ(a, u8, if (self.getArchPtrBitWidth() == 64)
|
||||
"/system/bin/linker64"
|
||||
else
|
||||
"/system/bin/linker");
|
||||
}
|
||||
|
||||
if (self.isMusl()) {
|
||||
var result = try std.Buffer.init(allocator, "/lib/ld-musl-");
|
||||
defer result.deinit();
|
||||
|
||||
var is_arm = false;
|
||||
switch (self.getArch()) {
|
||||
.arm, .thumb => {
|
||||
try result.append("arm");
|
||||
is_arm = true;
|
||||
},
|
||||
.armeb, .thumbeb => {
|
||||
try result.append("armeb");
|
||||
is_arm = true;
|
||||
},
|
||||
else => |arch| try result.append(@tagName(arch)),
|
||||
}
|
||||
if (is_arm and self.getFloatAbi() == .hard) {
|
||||
try result.append("hf");
|
||||
}
|
||||
try result.append(".so.1");
|
||||
return result.toOwnedSlice();
|
||||
}
|
||||
|
||||
switch (self.getOs()) {
|
||||
.freebsd => return mem.dupeZ(a, u8, "/libexec/ld-elf.so.1"),
|
||||
.netbsd => return mem.dupeZ(a, u8, "/libexec/ld.elf_so"),
|
||||
.dragonfly => return mem.dupeZ(a, u8, "/libexec/ld-elf.so.2"),
|
||||
.linux => switch (self.getArch()) {
|
||||
.i386,
|
||||
.sparc,
|
||||
.sparcel,
|
||||
=> return mem.dupeZ(a, u8, "/lib/ld-linux.so.2"),
|
||||
|
||||
.aarch64 => return mem.dupeZ(a, u8, "/lib/ld-linux-aarch64.so.1"),
|
||||
.aarch64_be => return mem.dupeZ(a, u8, "/lib/ld-linux-aarch64_be.so.1"),
|
||||
.aarch64_32 => return mem.dupeZ(a, u8, "/lib/ld-linux-aarch64_32.so.1"),
|
||||
|
||||
.arm,
|
||||
.armeb,
|
||||
.thumb,
|
||||
.thumbeb,
|
||||
=> return mem.dupeZ(a, u8, switch (self.getFloatAbi()) {
|
||||
.hard => "/lib/ld-linux-armhf.so.3",
|
||||
else => "/lib/ld-linux.so.3",
|
||||
}),
|
||||
|
||||
.mips,
|
||||
.mipsel,
|
||||
.mips64,
|
||||
.mips64el,
|
||||
=> return error.UnknownDynamicLinkerPath,
|
||||
|
||||
.powerpc => return mem.dupeZ(a, u8, "/lib/ld.so.1"),
|
||||
.powerpc64, .powerpc64le => return mem.dupeZ(a, u8, "/lib64/ld64.so.2"),
|
||||
.s390x => return mem.dupeZ(a, u8, "/lib64/ld64.so.1"),
|
||||
.sparcv9 => return mem.dupeZ(a, u8, "/lib64/ld-linux.so.2"),
|
||||
.x86_64 => return mem.dupeZ(a, u8, switch (self.getAbi()) {
|
||||
.gnux32 => "/libx32/ld-linux-x32.so.2",
|
||||
else => "/lib64/ld-linux-x86-64.so.2",
|
||||
}),
|
||||
|
||||
.riscv32 => return mem.dupeZ(a, u8, "/lib/ld-linux-riscv32-ilp32.so.1"),
|
||||
.riscv64 => return mem.dupeZ(a, u8, "/lib/ld-linux-riscv64-lp64.so.1"),
|
||||
|
||||
.arc,
|
||||
.avr,
|
||||
.bpfel,
|
||||
.bpfeb,
|
||||
.hexagon,
|
||||
.msp430,
|
||||
.r600,
|
||||
.amdgcn,
|
||||
.tce,
|
||||
.tcele,
|
||||
.xcore,
|
||||
.nvptx,
|
||||
.nvptx64,
|
||||
.le32,
|
||||
.le64,
|
||||
.amdil,
|
||||
.amdil64,
|
||||
.hsail,
|
||||
.hsail64,
|
||||
.spir,
|
||||
.spir64,
|
||||
.kalimba,
|
||||
.shave,
|
||||
.lanai,
|
||||
.wasm32,
|
||||
.wasm64,
|
||||
.renderscript32,
|
||||
.renderscript64,
|
||||
=> return error.UnknownDynamicLinkerPath,
|
||||
},
|
||||
else => return error.UnknownDynamicLinkerPath,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
test "parseCpuFeatureSet" {
|
||||
|
||||
@ -6,6 +6,14 @@ const fs = std.fs;
|
||||
|
||||
const warn = std.debug.warn;
|
||||
|
||||
pub fn detectDynamicLinker(allocator: *mem.Allocator, target: std.Target) ![:0]u8 {
|
||||
if (target == .Native) {
|
||||
return @import("libc_installation.zig").detectNativeDynamicLinker(allocator);
|
||||
} else {
|
||||
return target.getStandardDynamicLinkerPath(allocator);
|
||||
}
|
||||
}
|
||||
|
||||
/// Caller must free result
|
||||
pub fn testZigInstallPrefix(allocator: *mem.Allocator, test_path: []const u8) ![]u8 {
|
||||
const test_zig_dir = try fs.path.join(allocator, &[_][]const u8{ test_path, "lib", "zig" });
|
||||
|
||||
@ -492,7 +492,7 @@ pub const LibCInstallation = struct {
|
||||
const default_cc_exe = if (is_windows) "cc.exe" else "cc";
|
||||
|
||||
/// caller owns returned memory
|
||||
pub fn ccPrintFileName(
|
||||
fn ccPrintFileName(
|
||||
allocator: *Allocator,
|
||||
o_file: []const u8,
|
||||
want_dirname: enum { full_path, only_dir },
|
||||
@ -535,6 +535,43 @@ pub fn ccPrintFileName(
|
||||
}
|
||||
}
|
||||
|
||||
/// Caller owns returned memory.
|
||||
pub fn detectNativeDynamicLinker(allocator: *Allocator) ![:0]u8 {
|
||||
const standard_ld_path = try std.Target.current.getStandardDynamicLinkerPath(allocator);
|
||||
var standard_ld_path_resource: ?[:0]u8 = standard_ld_path; // Set to null to avoid freeing it.
|
||||
defer if (standard_ld_path_resource) |s| allocator.free(s);
|
||||
|
||||
const standard_ld_basename = fs.path.basename(standard_ld_path);
|
||||
|
||||
{
|
||||
// Best case scenario: the current executable is dynamically linked, and we can iterate
|
||||
// over our own shared objects and find a dynamic linker.
|
||||
const lib_paths = try std.process.getSelfExeSharedLibPaths(allocator);
|
||||
defer allocator.free(lib_paths);
|
||||
|
||||
for (lib_paths) |lib_path| {
|
||||
if (std.mem.endsWith(u8, lib_path, standard_ld_basename)) {
|
||||
return std.mem.dupeZ(allocator, u8, lib_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If Zig is statically linked, such as via distributed binary static builds, the above
|
||||
// trick won't work. What are we left with? Try to run the system C compiler and get
|
||||
// it to tell us the dynamic linker path.
|
||||
return ccPrintFileName(allocator, standard_ld_basename, .full_path) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
error.LibCRuntimeNotFound,
|
||||
error.CCompilerExitCode,
|
||||
error.CCompilerCrashed,
|
||||
error.UnableToSpawnCCompiler,
|
||||
=> {
|
||||
standard_ld_path_resource = null; // Prevent freeing standard_ld_path.
|
||||
return standard_ld_path;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const Search = struct {
|
||||
path: []const u8,
|
||||
version: []const u8,
|
||||
|
||||
@ -109,6 +109,7 @@ const Error = extern enum {
|
||||
LibCKernel32LibNotFound,
|
||||
UnsupportedArchitecture,
|
||||
WindowsSdkNotFound,
|
||||
UnknownDynamicLinkerPath,
|
||||
};
|
||||
|
||||
const FILE = std.c.FILE;
|
||||
@ -1012,24 +1013,100 @@ export fn stage2_libc_render(stage1_libc: *Stage2LibCInstallation, output_file:
|
||||
}
|
||||
|
||||
// ABI warning
|
||||
export fn stage2_libc_cc_print_file_name(
|
||||
out_ptr: *[*:0]u8,
|
||||
out_len: *usize,
|
||||
o_file: [*:0]const u8,
|
||||
want_dirname: bool,
|
||||
) Error {
|
||||
const result = @import("libc_installation.zig").ccPrintFileName(
|
||||
const Stage2Target = extern struct {
|
||||
arch: c_int,
|
||||
sub_arch: c_int,
|
||||
vendor: c_int,
|
||||
os: c_int,
|
||||
abi: c_int,
|
||||
glibc_version: ?*Stage2GLibCVersion, // null means default
|
||||
cpu_features: *Stage2CpuFeatures,
|
||||
is_native: bool,
|
||||
};
|
||||
|
||||
// ABI warning
|
||||
const Stage2GLibCVersion = extern struct {
|
||||
major: u32,
|
||||
minor: u32,
|
||||
patch: u32,
|
||||
};
|
||||
|
||||
// ABI warning
|
||||
export fn stage2_detect_dynamic_linker(in_target: *const Stage2Target, out_ptr: *[*:0]u8, out_len: *usize) Error {
|
||||
const target: Target = if (in_target.is_native) .Native else .{
|
||||
.Cross = .{
|
||||
.arch = switch (enumInt(@TagType(Target.Arch), in_target.arch)) {
|
||||
.arm => .{ .arm = enumInt(Target.Arch.Arm32, in_target.sub_arch) },
|
||||
.armeb => .{ .armeb = enumInt(Target.Arch.Arm32, in_target.sub_arch) },
|
||||
.thumb => .{ .thumb = enumInt(Target.Arch.Arm32, in_target.sub_arch) },
|
||||
.thumbeb => .{ .thumbeb = enumInt(Target.Arch.Arm32, in_target.sub_arch) },
|
||||
|
||||
.aarch64 => .{ .aarch64 = enumInt(Target.Arch.Arm64, in_target.sub_arch) },
|
||||
.aarch64_be => .{ .aarch64_be = enumInt(Target.Arch.Arm64, in_target.sub_arch) },
|
||||
.aarch64_32 => .{ .aarch64_32 = enumInt(Target.Arch.Arm64, in_target.sub_arch) },
|
||||
|
||||
.kalimba => .{ .kalimba = enumInt(Target.Arch.Kalimba, in_target.sub_arch) },
|
||||
|
||||
.arc => .arc,
|
||||
.avr => .avr,
|
||||
.bpfel => .bpfel,
|
||||
.bpfeb => .bpfeb,
|
||||
.hexagon => .hexagon,
|
||||
.mips => .mips,
|
||||
.mipsel => .mipsel,
|
||||
.mips64 => .mips64,
|
||||
.mips64el => .mips64el,
|
||||
.msp430 => .msp430,
|
||||
.powerpc => .powerpc,
|
||||
.powerpc64 => .powerpc64,
|
||||
.powerpc64le => .powerpc64le,
|
||||
.r600 => .r600,
|
||||
.amdgcn => .amdgcn,
|
||||
.riscv32 => .riscv32,
|
||||
.riscv64 => .riscv64,
|
||||
.sparc => .sparc,
|
||||
.sparcv9 => .sparcv9,
|
||||
.sparcel => .sparcel,
|
||||
.s390x => .s390x,
|
||||
.tce => .tce,
|
||||
.tcele => .tcele,
|
||||
.i386 => .i386,
|
||||
.x86_64 => .x86_64,
|
||||
.xcore => .xcore,
|
||||
.nvptx => .nvptx,
|
||||
.nvptx64 => .nvptx64,
|
||||
.le32 => .le32,
|
||||
.le64 => .le64,
|
||||
.amdil => .amdil,
|
||||
.amdil64 => .amdil64,
|
||||
.hsail => .hsail,
|
||||
.hsail64 => .hsail64,
|
||||
.spir => .spir,
|
||||
.spir64 => .spir64,
|
||||
.shave => .shave,
|
||||
.lanai => .lanai,
|
||||
.wasm32 => .wasm32,
|
||||
.wasm64 => .wasm64,
|
||||
.renderscript32 => .renderscript32,
|
||||
.renderscript64 => .renderscript64,
|
||||
},
|
||||
.os = enumInt(Target.Os, in_target.os),
|
||||
.abi = enumInt(Target.Abi, in_target.abi),
|
||||
.cpu_features = in_target.cpu_features.cpu_features,
|
||||
},
|
||||
};
|
||||
const result = @import("introspect.zig").detectDynamicLinker(
|
||||
std.heap.c_allocator,
|
||||
mem.toSliceConst(u8, o_file),
|
||||
if (want_dirname) .only_dir else .full_path,
|
||||
target,
|
||||
) catch |err| switch (err) {
|
||||
error.OutOfMemory => return .OutOfMemory,
|
||||
error.LibCRuntimeNotFound => return .FileNotFound,
|
||||
error.CCompilerExitCode => return .CCompilerExitCode,
|
||||
error.CCompilerCrashed => return .CCompilerCrashed,
|
||||
error.UnableToSpawnCCompiler => return .UnableToSpawnCCompiler,
|
||||
error.UnknownDynamicLinkerPath => return .UnknownDynamicLinkerPath,
|
||||
};
|
||||
out_ptr.* = result.ptr;
|
||||
out_len.* = result.len;
|
||||
return .None;
|
||||
}
|
||||
|
||||
fn enumInt(comptime Enum: type, int: c_int) Enum {
|
||||
return @intToEnum(Enum, @intCast(@TagType(Enum), int));
|
||||
}
|
||||
|
||||
@ -2,143 +2,6 @@ const std = @import("std");
|
||||
const Target = std.Target;
|
||||
const llvm = @import("llvm.zig");
|
||||
|
||||
pub const FloatAbi = enum {
|
||||
Hard,
|
||||
Soft,
|
||||
SoftFp,
|
||||
};
|
||||
|
||||
/// 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 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 (self.getArchPtrBitWidth() == 64) {
|
||||
return "/system/bin/linker64";
|
||||
} else {
|
||||
return "/system/bin/linker";
|
||||
}
|
||||
},
|
||||
.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",
|
||||
},
|
||||
|
||||
.armeb,
|
||||
.thumbeb,
|
||||
=> return switch (getFloatAbi(self)) {
|
||||
.Hard => return "/lib/ld-linux-armhf.so.3",
|
||||
else => return "/lib/ld-linux.so.3",
|
||||
},
|
||||
|
||||
.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) [:0]const u8 {
|
||||
const arch = self.getArch();
|
||||
switch (arch) {
|
||||
|
||||
@ -8624,7 +8624,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
|
||||
break;
|
||||
}
|
||||
buf_appendf(contents, "pub const output_mode = OutputMode.%s;\n", out_type);
|
||||
const char *link_type = g->is_dynamic ? "Dynamic" : "Static";
|
||||
const char *link_type = g->have_dynamic_link ? "Dynamic" : "Static";
|
||||
buf_appendf(contents, "pub const link_mode = LinkMode.%s;\n", link_type);
|
||||
buf_appendf(contents, "pub const is_test = %s;\n", bool_to_str(g->is_test_build));
|
||||
buf_appendf(contents, "pub const single_threaded = %s;\n", bool_to_str(g->is_single_threaded));
|
||||
@ -8731,7 +8731,7 @@ static Error define_builtin_compile_vars(CodeGen *g) {
|
||||
cache_int(&cache_hash, g->build_mode);
|
||||
cache_bool(&cache_hash, g->strip_debug_symbols);
|
||||
cache_int(&cache_hash, g->out_type);
|
||||
cache_bool(&cache_hash, g->is_dynamic);
|
||||
cache_bool(&cache_hash, detect_dynamic_link(g));
|
||||
cache_bool(&cache_hash, g->is_test_build);
|
||||
cache_bool(&cache_hash, g->is_single_threaded);
|
||||
cache_bool(&cache_hash, g->test_is_evented);
|
||||
@ -8957,6 +8957,8 @@ static void init(CodeGen *g) {
|
||||
}
|
||||
|
||||
static void detect_dynamic_linker(CodeGen *g) {
|
||||
Error err;
|
||||
|
||||
if (g->dynamic_linker_path != nullptr)
|
||||
return;
|
||||
if (!g->have_dynamic_link)
|
||||
@ -8964,45 +8966,15 @@ static void detect_dynamic_linker(CodeGen *g) {
|
||||
if (g->out_type == OutTypeObj || (g->out_type == OutTypeLib && !g->is_dynamic))
|
||||
return;
|
||||
|
||||
const char *standard_ld_path = target_dynamic_linker(g->zig_target);
|
||||
if (standard_ld_path == nullptr)
|
||||
return;
|
||||
|
||||
if (g->zig_target->is_native) {
|
||||
// target_dynamic_linker is usually correct. However on some systems, such as NixOS
|
||||
// it will be incorrect. See if we can do better by looking at what zig's own
|
||||
// dynamic linker path is.
|
||||
g->dynamic_linker_path = get_self_dynamic_linker_path();
|
||||
if (g->dynamic_linker_path != nullptr)
|
||||
return;
|
||||
|
||||
// If Zig is statically linked, such as via distributed binary static builds, the above
|
||||
// trick won't work. What are we left with? Try to run the system C compiler and get
|
||||
// it to tell us the dynamic linker path
|
||||
#if defined(ZIG_OS_LINUX)
|
||||
{
|
||||
Error err;
|
||||
for (size_t i = 0; possible_ld_names[i] != NULL; i += 1) {
|
||||
const char *lib_name = possible_ld_names[i];
|
||||
char *result_ptr;
|
||||
size_t result_len;
|
||||
if ((err = stage2_libc_cc_print_file_name(&result_ptr, &result_len, lib_name, false))) {
|
||||
if (err != ErrorCCompilerCannotFindFile && err != ErrorNoCCompilerInstalled) {
|
||||
fprintf(stderr, "Unable to detect native dynamic linker: %s\n", err_str(err));
|
||||
exit(1);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
g->dynamic_linker_path = buf_create_from_mem(result_ptr, result_len);
|
||||
// Skips heap::c_allocator because the memory is allocated by stage2 library.
|
||||
free(result_ptr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
char *dynamic_linker_ptr;
|
||||
size_t dynamic_linker_len;
|
||||
if ((err = stage2_detect_dynamic_linker(g->zig_target, &dynamic_linker_ptr, &dynamic_linker_len))) {
|
||||
fprintf(stderr, "Unable to detect dynamic linker: %s\n", err_str(err));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
g->dynamic_linker_path = buf_create_from_str(standard_ld_path);
|
||||
g->dynamic_linker_path = buf_create_from_mem(dynamic_linker_ptr, dynamic_linker_len);
|
||||
// Skips heap::c_allocator because the memory is allocated by stage2 library.
|
||||
free(dynamic_linker_ptr);
|
||||
}
|
||||
|
||||
static void detect_libc(CodeGen *g) {
|
||||
|
||||
@ -4,20 +4,6 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static Buf saved_dynamic_linker_path = BUF_INIT;
|
||||
static bool searched_for_dyn_linker = false;
|
||||
|
||||
static void detect_dynamic_linker(Buf *lib_path) {
|
||||
#if defined(ZIG_OS_LINUX)
|
||||
for (size_t i = 0; possible_ld_names[i] != NULL; i += 1) {
|
||||
if (buf_ends_with_str(lib_path, possible_ld_names[i])) {
|
||||
buf_init_from_buf(&saved_dynamic_linker_path, lib_path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Buf *get_self_libc_path(void) {
|
||||
static Buf saved_libc_path = BUF_INIT;
|
||||
static bool searched_for_libc = false;
|
||||
@ -43,25 +29,6 @@ Buf *get_self_libc_path(void) {
|
||||
}
|
||||
}
|
||||
|
||||
Buf *get_self_dynamic_linker_path(void) {
|
||||
for (;;) {
|
||||
if (saved_dynamic_linker_path.list.length != 0) {
|
||||
return &saved_dynamic_linker_path;
|
||||
}
|
||||
if (searched_for_dyn_linker)
|
||||
return nullptr;
|
||||
ZigList<Buf *> lib_paths = {};
|
||||
Error err;
|
||||
if ((err = os_self_exe_shared_libs(lib_paths)))
|
||||
return nullptr;
|
||||
for (size_t i = 0; i < lib_paths.length; i += 1) {
|
||||
Buf *lib_path = lib_paths.at(i);
|
||||
detect_dynamic_linker(lib_path);
|
||||
}
|
||||
searched_for_dyn_linker = true;
|
||||
}
|
||||
}
|
||||
|
||||
Error get_compiler_id(Buf **result) {
|
||||
static Buf saved_compiler_id = BUF_INIT;
|
||||
|
||||
@ -98,7 +65,6 @@ Error get_compiler_id(Buf **result) {
|
||||
return err;
|
||||
for (size_t i = 0; i < lib_paths.length; i += 1) {
|
||||
Buf *lib_path = lib_paths.at(i);
|
||||
detect_dynamic_linker(lib_path);
|
||||
if ((err = cache_add_file(ch, lib_path)))
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -12,7 +12,6 @@
|
||||
#include "error.hpp"
|
||||
|
||||
Error get_compiler_id(Buf **result);
|
||||
Buf *get_self_dynamic_linker_path(void);
|
||||
Buf *get_self_libc_path(void);
|
||||
|
||||
Buf *get_zig_lib_dir(void);
|
||||
|
||||
@ -80,6 +80,7 @@ const char *err_str(Error err) {
|
||||
case ErrorLibCKernel32LibNotFound: return "kernel32 library not found";
|
||||
case ErrorUnsupportedArchitecture: return "unsupported architecture";
|
||||
case ErrorWindowsSdkNotFound: return "Windows SDK not found";
|
||||
case ErrorUnknownDynamicLinkerPath: return "Windows SDK not found";
|
||||
}
|
||||
return "(invalid error)";
|
||||
}
|
||||
|
||||
18
src/os.cpp
18
src/os.cpp
@ -2129,21 +2129,3 @@ void os_file_close(OsFile *file) {
|
||||
*file = -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ZIG_OS_LINUX
|
||||
const char *possible_ld_names[] = {
|
||||
#if defined(ZIG_ARCH_X86_64)
|
||||
"ld-linux-x86-64.so.2",
|
||||
"ld-musl-x86_64.so.1",
|
||||
#elif defined(ZIG_ARCH_ARM64)
|
||||
"ld-linux-aarch64.so.1",
|
||||
"ld-musl-aarch64.so.1",
|
||||
#elif defined(ZIG_ARCH_ARM)
|
||||
"ld-linux-armhf.so.3",
|
||||
"ld-musl-armhf.so.1",
|
||||
"ld-linux.so.3",
|
||||
"ld-musl-arm.so.1",
|
||||
#endif
|
||||
NULL,
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -43,10 +43,6 @@
|
||||
#define ZIG_ARCH_UNKNOWN
|
||||
#endif
|
||||
|
||||
#ifdef ZIG_OS_LINUX
|
||||
extern const char *possible_ld_names[];
|
||||
#endif
|
||||
|
||||
#if defined(ZIG_OS_WINDOWS)
|
||||
#define ZIG_PRI_usize "I64u"
|
||||
#define ZIG_PRI_i64 "I64d"
|
||||
|
||||
@ -171,9 +171,7 @@ enum Error stage2_libc_find_native(struct Stage2LibCInstallation *libc) {
|
||||
stage2_panic(msg, strlen(msg));
|
||||
}
|
||||
|
||||
enum Error stage2_libc_cc_print_file_name(char **out_ptr, size_t *out_len,
|
||||
const char *o_file, bool want_dirname)
|
||||
{
|
||||
const char *msg = "stage0 called stage2_libc_cc_print_file_name";
|
||||
enum Error stage2_detect_dynamic_linker(const struct ZigTarget *target, char **out_ptr, size_t *out_len) {
|
||||
const char *msg = "stage0 called stage2_detect_dynamic_linker";
|
||||
stage2_panic(msg, strlen(msg));
|
||||
}
|
||||
|
||||
69
src/stage2.h
69
src/stage2.h
@ -12,6 +12,8 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "zig_llvm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define ZIG_EXTERN_C extern "C"
|
||||
#else
|
||||
@ -100,6 +102,7 @@ enum Error {
|
||||
ErrorLibCKernel32LibNotFound,
|
||||
ErrorUnsupportedArchitecture,
|
||||
ErrorWindowsSdkNotFound,
|
||||
ErrorUnknownDynamicLinkerPath,
|
||||
};
|
||||
|
||||
// ABI warning
|
||||
@ -242,8 +245,70 @@ ZIG_EXTERN_C enum Error stage2_libc_parse(struct Stage2LibCInstallation *libc, c
|
||||
ZIG_EXTERN_C enum Error stage2_libc_render(struct Stage2LibCInstallation *self, FILE *file);
|
||||
// ABI warning
|
||||
ZIG_EXTERN_C enum Error stage2_libc_find_native(struct Stage2LibCInstallation *libc);
|
||||
|
||||
// ABI warning
|
||||
ZIG_EXTERN_C enum Error stage2_libc_cc_print_file_name(char **out_ptr, size_t *out_len,
|
||||
const char *o_file, bool want_dirname);
|
||||
// Synchronize with target.cpp::os_list
|
||||
enum Os {
|
||||
OsFreestanding,
|
||||
OsAnanas,
|
||||
OsCloudABI,
|
||||
OsDragonFly,
|
||||
OsFreeBSD,
|
||||
OsFuchsia,
|
||||
OsIOS,
|
||||
OsKFreeBSD,
|
||||
OsLinux,
|
||||
OsLv2, // PS3
|
||||
OsMacOSX,
|
||||
OsNetBSD,
|
||||
OsOpenBSD,
|
||||
OsSolaris,
|
||||
OsWindows,
|
||||
OsHaiku,
|
||||
OsMinix,
|
||||
OsRTEMS,
|
||||
OsNaCl, // Native Client
|
||||
OsCNK, // BG/P Compute-Node Kernel
|
||||
OsAIX,
|
||||
OsCUDA, // NVIDIA CUDA
|
||||
OsNVCL, // NVIDIA OpenCL
|
||||
OsAMDHSA, // AMD HSA Runtime
|
||||
OsPS4,
|
||||
OsELFIAMCU,
|
||||
OsTvOS, // Apple tvOS
|
||||
OsWatchOS, // Apple watchOS
|
||||
OsMesa3D,
|
||||
OsContiki,
|
||||
OsAMDPAL,
|
||||
OsHermitCore,
|
||||
OsHurd,
|
||||
OsWASI,
|
||||
OsEmscripten,
|
||||
OsUefi,
|
||||
OsOther,
|
||||
};
|
||||
|
||||
// ABI warning
|
||||
struct ZigGLibCVersion {
|
||||
uint32_t major; // always 2
|
||||
uint32_t minor;
|
||||
uint32_t patch;
|
||||
};
|
||||
|
||||
// ABI warning
|
||||
struct ZigTarget {
|
||||
enum ZigLLVM_ArchType arch;
|
||||
enum ZigLLVM_SubArchType sub_arch;
|
||||
enum ZigLLVM_VendorType vendor;
|
||||
Os os;
|
||||
enum ZigLLVM_EnvironmentType abi;
|
||||
struct ZigGLibCVersion *glibc_version; // null means default
|
||||
struct Stage2CpuFeatures *cpu_features;
|
||||
bool is_native;
|
||||
};
|
||||
|
||||
// ABI warning
|
||||
ZIG_EXTERN_C enum Error stage2_detect_dynamic_linker(const struct ZigTarget *target,
|
||||
char **out_ptr, size_t *out_len);
|
||||
|
||||
#endif
|
||||
|
||||
203
src/target.cpp
203
src/target.cpp
@ -1204,213 +1204,10 @@ const char *target_lib_file_ext(const ZigTarget *target, bool is_static,
|
||||
}
|
||||
}
|
||||
|
||||
enum FloatAbi {
|
||||
FloatAbiHard,
|
||||
FloatAbiSoft,
|
||||
FloatAbiSoftFp,
|
||||
};
|
||||
|
||||
static FloatAbi get_float_abi(const ZigTarget *target) {
|
||||
const ZigLLVM_EnvironmentType env = target->abi;
|
||||
if (env == ZigLLVM_GNUEABIHF ||
|
||||
env == ZigLLVM_EABIHF ||
|
||||
env == ZigLLVM_MuslEABIHF)
|
||||
{
|
||||
return FloatAbiHard;
|
||||
} else {
|
||||
return FloatAbiSoft;
|
||||
}
|
||||
}
|
||||
|
||||
static bool is_64_bit(ZigLLVM_ArchType arch) {
|
||||
return target_arch_pointer_bit_width(arch) == 64;
|
||||
}
|
||||
|
||||
bool target_is_android(const ZigTarget *target) {
|
||||
return target->abi == ZigLLVM_Android;
|
||||
}
|
||||
|
||||
const char *target_dynamic_linker(const ZigTarget *target) {
|
||||
if (target_is_android(target)) {
|
||||
return is_64_bit(target->arch) ? "/system/bin/linker64" : "/system/bin/linker";
|
||||
}
|
||||
|
||||
if (target_is_musl(target)) {
|
||||
Buf buf = BUF_INIT;
|
||||
buf_init_from_str(&buf, "/lib/ld-musl-");
|
||||
bool is_arm = false;
|
||||
switch (target->arch) {
|
||||
case ZigLLVM_arm:
|
||||
case ZigLLVM_thumb:
|
||||
buf_append_str(&buf, "arm");
|
||||
is_arm = true;
|
||||
break;
|
||||
case ZigLLVM_armeb:
|
||||
case ZigLLVM_thumbeb:
|
||||
buf_append_str(&buf, "armeb");
|
||||
is_arm = true;
|
||||
break;
|
||||
default:
|
||||
buf_append_str(&buf, target_arch_name(target->arch));
|
||||
}
|
||||
if (is_arm && get_float_abi(target) == FloatAbiHard) {
|
||||
buf_append_str(&buf, "hf");
|
||||
}
|
||||
buf_append_str(&buf, ".so.1");
|
||||
return buf_ptr(&buf);
|
||||
}
|
||||
|
||||
switch (target->os) {
|
||||
case OsFreeBSD:
|
||||
return "/libexec/ld-elf.so.1";
|
||||
case OsNetBSD:
|
||||
return "/libexec/ld.elf_so";
|
||||
case OsDragonFly:
|
||||
return "/libexec/ld-elf.so.2";
|
||||
case OsLinux: {
|
||||
const ZigLLVM_EnvironmentType abi = target->abi;
|
||||
switch (target->arch) {
|
||||
case ZigLLVM_UnknownArch:
|
||||
zig_unreachable();
|
||||
case ZigLLVM_x86:
|
||||
case ZigLLVM_sparc:
|
||||
case ZigLLVM_sparcel:
|
||||
return "/lib/ld-linux.so.2";
|
||||
|
||||
case ZigLLVM_aarch64:
|
||||
return "/lib/ld-linux-aarch64.so.1";
|
||||
|
||||
case ZigLLVM_aarch64_be:
|
||||
return "/lib/ld-linux-aarch64_be.so.1";
|
||||
|
||||
case ZigLLVM_aarch64_32:
|
||||
return "/lib/ld-linux-aarch64_32.so.1";
|
||||
|
||||
case ZigLLVM_arm:
|
||||
case ZigLLVM_thumb:
|
||||
if (get_float_abi(target) == FloatAbiHard) {
|
||||
return "/lib/ld-linux-armhf.so.3";
|
||||
} else {
|
||||
return "/lib/ld-linux.so.3";
|
||||
}
|
||||
|
||||
case ZigLLVM_armeb:
|
||||
case ZigLLVM_thumbeb:
|
||||
if (get_float_abi(target) == FloatAbiHard) {
|
||||
return "/lib/ld-linux-armhf.so.3";
|
||||
} else {
|
||||
return "/lib/ld-linux.so.3";
|
||||
}
|
||||
|
||||
case ZigLLVM_mips:
|
||||
case ZigLLVM_mipsel:
|
||||
case ZigLLVM_mips64:
|
||||
case ZigLLVM_mips64el:
|
||||
zig_panic("TODO implement target_dynamic_linker for mips");
|
||||
|
||||
case ZigLLVM_ppc:
|
||||
return "/lib/ld.so.1";
|
||||
|
||||
case ZigLLVM_ppc64:
|
||||
return "/lib64/ld64.so.2";
|
||||
|
||||
case ZigLLVM_ppc64le:
|
||||
return "/lib64/ld64.so.2";
|
||||
|
||||
case ZigLLVM_systemz:
|
||||
return "/lib64/ld64.so.1";
|
||||
|
||||
case ZigLLVM_sparcv9:
|
||||
return "/lib64/ld-linux.so.2";
|
||||
|
||||
case ZigLLVM_x86_64:
|
||||
if (abi == ZigLLVM_GNUX32) {
|
||||
return "/libx32/ld-linux-x32.so.2";
|
||||
}
|
||||
if (abi == ZigLLVM_Musl || abi == ZigLLVM_MuslEABI || abi == ZigLLVM_MuslEABIHF) {
|
||||
return "/lib/ld-musl-x86_64.so.1";
|
||||
}
|
||||
return "/lib64/ld-linux-x86-64.so.2";
|
||||
|
||||
case ZigLLVM_wasm32:
|
||||
case ZigLLVM_wasm64:
|
||||
return nullptr;
|
||||
|
||||
case ZigLLVM_riscv32:
|
||||
return "/lib/ld-linux-riscv32-ilp32.so.1";
|
||||
case ZigLLVM_riscv64:
|
||||
return "/lib/ld-linux-riscv64-lp64.so.1";
|
||||
|
||||
case ZigLLVM_arc:
|
||||
case ZigLLVM_avr:
|
||||
case ZigLLVM_bpfel:
|
||||
case ZigLLVM_bpfeb:
|
||||
case ZigLLVM_hexagon:
|
||||
case ZigLLVM_msp430:
|
||||
case ZigLLVM_r600:
|
||||
case ZigLLVM_amdgcn:
|
||||
case ZigLLVM_tce:
|
||||
case ZigLLVM_tcele:
|
||||
case ZigLLVM_xcore:
|
||||
case ZigLLVM_nvptx:
|
||||
case ZigLLVM_nvptx64:
|
||||
case ZigLLVM_le32:
|
||||
case ZigLLVM_le64:
|
||||
case ZigLLVM_amdil:
|
||||
case ZigLLVM_amdil64:
|
||||
case ZigLLVM_hsail:
|
||||
case ZigLLVM_hsail64:
|
||||
case ZigLLVM_spir:
|
||||
case ZigLLVM_spir64:
|
||||
case ZigLLVM_kalimba:
|
||||
case ZigLLVM_shave:
|
||||
case ZigLLVM_lanai:
|
||||
case ZigLLVM_renderscript32:
|
||||
case ZigLLVM_renderscript64:
|
||||
zig_panic("TODO implement target_dynamic_linker for this arch");
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
case OsFreestanding:
|
||||
case OsIOS:
|
||||
case OsTvOS:
|
||||
case OsWatchOS:
|
||||
case OsMacOSX:
|
||||
case OsUefi:
|
||||
case OsWindows:
|
||||
case OsEmscripten:
|
||||
case OsOther:
|
||||
return nullptr;
|
||||
|
||||
case OsAnanas:
|
||||
case OsCloudABI:
|
||||
case OsFuchsia:
|
||||
case OsKFreeBSD:
|
||||
case OsLv2:
|
||||
case OsOpenBSD:
|
||||
case OsSolaris:
|
||||
case OsHaiku:
|
||||
case OsMinix:
|
||||
case OsRTEMS:
|
||||
case OsNaCl:
|
||||
case OsCNK:
|
||||
case OsAIX:
|
||||
case OsCUDA:
|
||||
case OsNVCL:
|
||||
case OsAMDHSA:
|
||||
case OsPS4:
|
||||
case OsELFIAMCU:
|
||||
case OsMesa3D:
|
||||
case OsContiki:
|
||||
case OsAMDPAL:
|
||||
case OsHermitCore:
|
||||
case OsHurd:
|
||||
case OsWASI:
|
||||
zig_panic("TODO implement target_dynamic_linker for this OS");
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target) {
|
||||
assert(host_target != nullptr);
|
||||
|
||||
|
||||
@ -8,51 +8,10 @@
|
||||
#ifndef ZIG_TARGET_HPP
|
||||
#define ZIG_TARGET_HPP
|
||||
|
||||
#include <zig_llvm.h>
|
||||
#include "stage2.h"
|
||||
|
||||
struct Buf;
|
||||
|
||||
// Synchronize with target.cpp::os_list
|
||||
enum Os {
|
||||
OsFreestanding,
|
||||
OsAnanas,
|
||||
OsCloudABI,
|
||||
OsDragonFly,
|
||||
OsFreeBSD,
|
||||
OsFuchsia,
|
||||
OsIOS,
|
||||
OsKFreeBSD,
|
||||
OsLinux,
|
||||
OsLv2, // PS3
|
||||
OsMacOSX,
|
||||
OsNetBSD,
|
||||
OsOpenBSD,
|
||||
OsSolaris,
|
||||
OsWindows,
|
||||
OsHaiku,
|
||||
OsMinix,
|
||||
OsRTEMS,
|
||||
OsNaCl, // Native Client
|
||||
OsCNK, // BG/P Compute-Node Kernel
|
||||
OsAIX,
|
||||
OsCUDA, // NVIDIA CUDA
|
||||
OsNVCL, // NVIDIA OpenCL
|
||||
OsAMDHSA, // AMD HSA Runtime
|
||||
OsPS4,
|
||||
OsELFIAMCU,
|
||||
OsTvOS, // Apple tvOS
|
||||
OsWatchOS, // Apple watchOS
|
||||
OsMesa3D,
|
||||
OsContiki,
|
||||
OsAMDPAL,
|
||||
OsHermitCore,
|
||||
OsHurd,
|
||||
OsWASI,
|
||||
OsEmscripten,
|
||||
OsUefi,
|
||||
OsOther,
|
||||
};
|
||||
|
||||
// Synchronize with target.cpp::subarch_list_list
|
||||
enum SubArchList {
|
||||
SubArchListNone,
|
||||
@ -78,23 +37,6 @@ enum TargetSubsystem {
|
||||
TargetSubsystemAuto
|
||||
};
|
||||
|
||||
struct ZigGLibCVersion {
|
||||
uint32_t major; // always 2
|
||||
uint32_t minor;
|
||||
uint32_t patch;
|
||||
};
|
||||
|
||||
struct ZigTarget {
|
||||
ZigLLVM_ArchType arch;
|
||||
ZigLLVM_SubArchType sub_arch;
|
||||
ZigLLVM_VendorType vendor;
|
||||
Os os;
|
||||
ZigLLVM_EnvironmentType abi;
|
||||
ZigGLibCVersion *glibc_version; // null means default
|
||||
Stage2CpuFeatures *cpu_features;
|
||||
bool is_native;
|
||||
};
|
||||
|
||||
enum CIntType {
|
||||
CIntTypeShort,
|
||||
CIntTypeUShort,
|
||||
@ -168,8 +110,6 @@ const char *target_lib_file_prefix(const ZigTarget *target);
|
||||
const char *target_lib_file_ext(const ZigTarget *target, bool is_static,
|
||||
size_t version_major, size_t version_minor, size_t version_patch);
|
||||
|
||||
const char *target_dynamic_linker(const ZigTarget *target);
|
||||
|
||||
bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target);
|
||||
ZigLLVM_OSType get_llvm_os_type(Os os_type);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user