mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
Merge pull request #21726 from alexrp/target-api
`std.Target`: Some miscellaneous API improvements
This commit is contained in:
commit
d38ed893c6
@ -492,11 +492,11 @@ pub fn linkSystemLibrary(
|
||||
const b = m.owner;
|
||||
|
||||
const target = m.requireKnownTarget();
|
||||
if (target.is_libc_lib_name(name)) {
|
||||
if (std.zig.target.isLibCLibName(target, name)) {
|
||||
m.link_libc = true;
|
||||
return;
|
||||
}
|
||||
if (target.is_libcpp_lib_name(name)) {
|
||||
if (std.zig.target.isLibCxxLibName(target, name)) {
|
||||
m.link_libcpp = true;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -611,11 +611,13 @@ pub fn dependsOnSystemLibrary(compile: *const Compile, name: []const u8) bool {
|
||||
is_linking_libcpp = is_linking_libcpp or module.link_libcpp == true;
|
||||
}
|
||||
|
||||
if (compile.rootModuleTarget().is_libc_lib_name(name)) {
|
||||
const target = compile.rootModuleTarget();
|
||||
|
||||
if (std.zig.target.isLibCLibName(target, name)) {
|
||||
return is_linking_libc;
|
||||
}
|
||||
|
||||
if (compile.rootModuleTarget().is_libcpp_lib_name(name)) {
|
||||
if (std.zig.target.isLibCxxLibName(target, name)) {
|
||||
return is_linking_libcpp;
|
||||
}
|
||||
|
||||
|
||||
@ -157,7 +157,7 @@ pub const Os = struct {
|
||||
};
|
||||
}
|
||||
|
||||
pub inline fn getVersionRangeTag(tag: Tag) @typeInfo(TaggedVersionRange).@"union".tag_type.? {
|
||||
pub inline fn versionRangeTag(tag: Tag) @typeInfo(TaggedVersionRange).@"union".tag_type.? {
|
||||
return switch (tag) {
|
||||
.freestanding,
|
||||
.fuchsia,
|
||||
@ -545,8 +545,8 @@ pub const Os = struct {
|
||||
|
||||
/// Provides a tagged union. `Target` does not store the tag because it is
|
||||
/// redundant with the OS tag; this function abstracts that part away.
|
||||
pub inline fn getVersionRange(os: Os) TaggedVersionRange {
|
||||
return switch (os.tag.getVersionRangeTag()) {
|
||||
pub inline fn versionRange(os: Os) TaggedVersionRange {
|
||||
return switch (os.tag.versionRangeTag()) {
|
||||
.none => .{ .none = {} },
|
||||
.semver => .{ .semver = os.version_range.semver },
|
||||
.linux => .{ .linux = os.version_range.linux },
|
||||
@ -556,12 +556,12 @@ pub const Os = struct {
|
||||
|
||||
/// Checks if system is guaranteed to be at least `version` or older than `version`.
|
||||
/// Returns `null` if a runtime check is required.
|
||||
pub inline fn isAtLeast(os: Os, comptime tag: Tag, ver: switch (tag.getVersionRangeTag()) {
|
||||
pub inline fn isAtLeast(os: Os, comptime tag: Tag, ver: switch (tag.versionRangeTag()) {
|
||||
.none => void,
|
||||
.semver, .linux => std.SemanticVersion,
|
||||
.windows => WindowsVersion,
|
||||
}) ?bool {
|
||||
return if (os.tag != tag) false else switch (tag.getVersionRangeTag()) {
|
||||
return if (os.tag != tag) false else switch (tag.versionRangeTag()) {
|
||||
.none => true,
|
||||
inline .semver,
|
||||
.linux,
|
||||
@ -925,8 +925,6 @@ pub const ObjectFormat = enum {
|
||||
};
|
||||
|
||||
pub fn toElfMachine(target: Target) std.elf.EM {
|
||||
if (target.os.tag == .elfiamcu) return .IAMCU;
|
||||
|
||||
return switch (target.cpu.arch) {
|
||||
.amdgcn => .AMDGPU,
|
||||
.arc => .ARC_COMPACT,
|
||||
@ -950,7 +948,7 @@ pub fn toElfMachine(target: Target) std.elf.EM {
|
||||
.sparc64 => .SPARCV9,
|
||||
.spu_2 => .SPU_2,
|
||||
.ve => .VE,
|
||||
.x86 => .@"386",
|
||||
.x86 => if (target.os.tag == .elfiamcu) .IAMCU else .@"386",
|
||||
.x86_64 => .X86_64,
|
||||
.xcore => .XCORE,
|
||||
.xtensa => .XTENSA,
|
||||
@ -1756,10 +1754,6 @@ pub inline fn isBSD(target: Target) bool {
|
||||
return target.os.tag.isBSD();
|
||||
}
|
||||
|
||||
pub inline fn isBpfFreestanding(target: Target) bool {
|
||||
return target.cpu.arch.isBpf() and target.os.tag == .freestanding;
|
||||
}
|
||||
|
||||
pub inline fn isGnuLibC(target: Target) bool {
|
||||
return target.os.tag.isGnuLibC(target.abi);
|
||||
}
|
||||
@ -2870,141 +2864,6 @@ pub fn cTypePreferredAlignment(target: Target, c_type: CType) u16 {
|
||||
);
|
||||
}
|
||||
|
||||
pub fn is_libc_lib_name(target: std.Target, name: []const u8) bool {
|
||||
const ignore_case = target.os.tag == .macos or target.os.tag == .windows;
|
||||
|
||||
if (eqlIgnoreCase(ignore_case, name, "c"))
|
||||
return true;
|
||||
|
||||
if (target.isMinGW()) {
|
||||
if (eqlIgnoreCase(ignore_case, name, "m"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "mingw32"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "msvcrt-os"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "mingwex"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "uuid"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "bits"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "dmoguids"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "dxerr8"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "dxerr9"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "mfuuid"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "msxml2"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "msxml6"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "amstrmid"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "wbemuuid"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "wmcodecdspuuid"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "dxguid"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "ksguid"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "locationapi"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "portabledeviceguids"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "mfuuid"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "dloadhelper"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "strmiids"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "mfuuid"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "adsiid"))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (target.abi.isGnu() or target.abi.isMusl()) {
|
||||
if (eqlIgnoreCase(ignore_case, name, "m"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "rt"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "pthread"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "util"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "xnet"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "resolv"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "dl"))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (target.abi.isMusl()) {
|
||||
if (eqlIgnoreCase(ignore_case, name, "crypt"))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (target.os.tag.isDarwin()) {
|
||||
if (eqlIgnoreCase(ignore_case, name, "System"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "c"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "dbm"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "dl"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "info"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "m"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "poll"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "proc"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "pthread"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "rpcsvc"))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (target.os.isAtLeast(.macos, .{ .major = 10, .minor = 8, .patch = 0 }) orelse false) {
|
||||
if (eqlIgnoreCase(ignore_case, name, "mx"))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (target.os.tag == .haiku) {
|
||||
if (eqlIgnoreCase(ignore_case, name, "root"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "network"))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
pub fn is_libcpp_lib_name(target: std.Target, name: []const u8) bool {
|
||||
const ignore_case = target.os.tag.isDarwin() or target.os.tag == .windows;
|
||||
|
||||
return eqlIgnoreCase(ignore_case, name, "c++") or
|
||||
eqlIgnoreCase(ignore_case, name, "stdc++") or
|
||||
eqlIgnoreCase(ignore_case, name, "c++abi");
|
||||
}
|
||||
|
||||
fn eqlIgnoreCase(ignore_case: bool, a: []const u8, b: []const u8) bool {
|
||||
if (ignore_case) {
|
||||
return std.ascii.eqlIgnoreCase(a, b);
|
||||
} else {
|
||||
return std.mem.eql(u8, a, b);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn osArchName(target: std.Target) [:0]const u8 {
|
||||
return target.os.tag.archName(target.cpu.arch);
|
||||
}
|
||||
|
||||
@ -124,7 +124,7 @@ pub fn fromTarget(target: Target) Query {
|
||||
}
|
||||
|
||||
fn updateOsVersionRange(self: *Query, os: Target.Os) void {
|
||||
self.os_version_min, self.os_version_max = switch (os.tag.getVersionRangeTag()) {
|
||||
self.os_version_min, self.os_version_max = switch (os.tag.versionRangeTag()) {
|
||||
.none => .{ .{ .none = {} }, .{ .none = {} } },
|
||||
.semver => .{
|
||||
.{ .semver = os.version_range.semver.min },
|
||||
@ -523,7 +523,7 @@ fn parseOs(result: *Query, diags: *ParseOptions.Diagnostics, text: []const u8) !
|
||||
diags.os_tag = tag;
|
||||
|
||||
const version_text = it.rest();
|
||||
if (version_text.len > 0) switch (tag.getVersionRangeTag()) {
|
||||
if (version_text.len > 0) switch (tag.versionRangeTag()) {
|
||||
.none => return error.InvalidOperatingSystemVersion,
|
||||
.semver, .linux => range: {
|
||||
var range_it = mem.splitSequence(u8, version_text, "...");
|
||||
|
||||
@ -124,4 +124,139 @@ pub fn muslArchName(arch: std.Target.Cpu.Arch) [:0]const u8 {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn isLibCLibName(target: std.Target, name: []const u8) bool {
|
||||
const ignore_case = target.os.tag.isDarwin() or target.os.tag == .windows;
|
||||
|
||||
if (eqlIgnoreCase(ignore_case, name, "c"))
|
||||
return true;
|
||||
|
||||
if (target.isMinGW()) {
|
||||
if (eqlIgnoreCase(ignore_case, name, "m"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "mingw32"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "msvcrt-os"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "mingwex"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "uuid"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "bits"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "dmoguids"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "dxerr8"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "dxerr9"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "mfuuid"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "msxml2"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "msxml6"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "amstrmid"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "wbemuuid"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "wmcodecdspuuid"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "dxguid"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "ksguid"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "locationapi"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "portabledeviceguids"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "mfuuid"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "dloadhelper"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "strmiids"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "mfuuid"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "adsiid"))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (target.abi.isGnu() or target.abi.isMusl()) {
|
||||
if (eqlIgnoreCase(ignore_case, name, "m"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "rt"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "pthread"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "util"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "resolv"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "dl"))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (target.abi.isMusl()) {
|
||||
if (eqlIgnoreCase(ignore_case, name, "crypt"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "xnet"))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (target.os.tag.isDarwin()) {
|
||||
if (eqlIgnoreCase(ignore_case, name, "System"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "c"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "dbm"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "dl"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "info"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "m"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "poll"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "proc"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "pthread"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "rpcsvc"))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (target.os.isAtLeast(.macos, .{ .major = 10, .minor = 8, .patch = 0 }) orelse false) {
|
||||
if (eqlIgnoreCase(ignore_case, name, "mx"))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (target.os.tag == .haiku) {
|
||||
if (eqlIgnoreCase(ignore_case, name, "root"))
|
||||
return true;
|
||||
if (eqlIgnoreCase(ignore_case, name, "network"))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
pub fn isLibCxxLibName(target: std.Target, name: []const u8) bool {
|
||||
const ignore_case = target.os.tag.isDarwin() or target.os.tag == .windows;
|
||||
|
||||
return eqlIgnoreCase(ignore_case, name, "c++") or
|
||||
eqlIgnoreCase(ignore_case, name, "stdc++") or
|
||||
eqlIgnoreCase(ignore_case, name, "c++abi");
|
||||
}
|
||||
|
||||
fn eqlIgnoreCase(ignore_case: bool, a: []const u8, b: []const u8) bool {
|
||||
if (ignore_case) {
|
||||
return std.ascii.eqlIgnoreCase(a, b);
|
||||
} else {
|
||||
return std.mem.eql(u8, a, b);
|
||||
}
|
||||
}
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
@ -80,7 +80,7 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {
|
||||
.{std.zig.fmtId(@tagName(target.os.tag))},
|
||||
);
|
||||
|
||||
switch (target.os.getVersionRange()) {
|
||||
switch (target.os.versionRange()) {
|
||||
.none => try buffer.appendSlice(" .none = {} },\n"),
|
||||
.semver => |semver| try buffer.writer().print(
|
||||
\\ .semver = .{{
|
||||
|
||||
@ -877,7 +877,7 @@ pub const cache_helpers = struct {
|
||||
hh.addBytes(target.cpu.model.name);
|
||||
hh.add(target.cpu.features.ints);
|
||||
hh.add(target.os.tag);
|
||||
hh.add(target.os.getVersionRange());
|
||||
hh.add(target.os.versionRange());
|
||||
hh.add(target.abi);
|
||||
hh.add(target.ofmt);
|
||||
hh.add(resolved_target.is_native_os);
|
||||
@ -5412,7 +5412,7 @@ pub fn addCCArgs(
|
||||
|
||||
switch (ext) {
|
||||
.c, .cpp, .m, .mm, .h, .hpp, .hm, .hmm, .cu, .rc, .assembly, .assembly_with_cpp => {
|
||||
const minver: u16 = @truncate(@intFromEnum(target.os.getVersionRange().windows.min) >> 16);
|
||||
const minver: u16 = @truncate(@intFromEnum(target.os.versionRange().windows.min) >> 16);
|
||||
try argv.append(
|
||||
try std.fmt.allocPrint(arena, "-D_WIN32_WINNT=0x{x:0>4}", .{minver}),
|
||||
);
|
||||
|
||||
@ -9606,7 +9606,7 @@ fn handleExternLibName(
|
||||
const comp = zcu.comp;
|
||||
const target = zcu.getTarget();
|
||||
log.debug("extern fn symbol expected in lib '{s}'", .{lib_name});
|
||||
if (target.is_libc_lib_name(lib_name)) {
|
||||
if (std.zig.target.isLibCLibName(target, lib_name)) {
|
||||
if (!comp.config.link_libc) {
|
||||
return sema.fail(
|
||||
block,
|
||||
@ -9617,7 +9617,7 @@ fn handleExternLibName(
|
||||
}
|
||||
break :blk;
|
||||
}
|
||||
if (target.is_libcpp_lib_name(lib_name)) {
|
||||
if (std.zig.target.isLibCxxLibName(target, lib_name)) {
|
||||
if (!comp.config.link_libcpp) return sema.fail(
|
||||
block,
|
||||
src_loc,
|
||||
|
||||
@ -2045,9 +2045,7 @@ fn linkWithLLD(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: s
|
||||
// copy when generating relocatables. Normally, we would expect `lld -r` to work.
|
||||
// However, because LLD wants to resolve BPF relocations which it shouldn't, it fails
|
||||
// before even generating the relocatable.
|
||||
if (output_mode == .Obj and
|
||||
(comp.config.lto or target.isBpfFreestanding()))
|
||||
{
|
||||
if (output_mode == .Obj and (comp.config.lto or target.cpu.arch.isBpf())) {
|
||||
// In this case we must do a simple file copy
|
||||
// here. TODO: think carefully about how we can avoid this redundant operation when doing
|
||||
// build-obj. See also the corresponding TODO in linkAsArchive.
|
||||
|
||||
@ -3765,11 +3765,11 @@ fn createModule(
|
||||
info: SystemLib,
|
||||
}) = .{};
|
||||
for (create_module.system_libs.keys(), create_module.system_libs.values()) |lib_name, info| {
|
||||
if (target.is_libc_lib_name(lib_name)) {
|
||||
if (std.zig.target.isLibCLibName(target, lib_name)) {
|
||||
create_module.opts.link_libc = true;
|
||||
continue;
|
||||
}
|
||||
if (target.is_libcpp_lib_name(lib_name)) {
|
||||
if (std.zig.target.isLibCxxLibName(target, lib_name)) {
|
||||
create_module.opts.link_libcpp = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user