From be6a81d3a70818ed143d004727d352f552384af5 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 3 Jan 2023 00:57:25 -0500 Subject: [PATCH] Merge pull request #13699 from mikdusan/bsd give BSDs some attention --- build.zig | 50 +++++++++++++-------- lib/libcxx/include/__config | 11 ++--- lib/libcxx/include/__locale | 6 +-- lib/libcxx/include/locale | 2 +- lib/libcxx/src/locale.cpp | 2 +- lib/std/c/dragonfly.zig | 2 + lib/std/c/freebsd.zig | 3 ++ lib/std/c/netbsd.zig | 9 +++- lib/std/c/openbsd.zig | 1 + lib/std/fs.zig | 6 +-- lib/std/fs/test.zig | 4 +- lib/std/os.zig | 89 +++++++++++++++++++++++++++++++++---- lib/std/os/test.zig | 9 +++- lib/std/target.zig | 8 ++-- src/link/Elf.zig | 18 +++----- 15 files changed, 159 insertions(+), 61 deletions(-) diff --git a/build.zig b/build.zig index fee6e4885a..8bacb6937f 100644 --- a/build.zig +++ b/build.zig @@ -593,24 +593,38 @@ fn addCmakeCfgOptionsToExe( // System -lc++ must be used because in this code path we are attempting to link // against system-provided LLVM, Clang, LLD. - if (exe.target.getOsTag() == .linux) { - // First we try to link against gcc libstdc++. If that doesn't work, we fall - // back to -lc++ and cross our fingers. - addCxxKnownPath(b, cfg, exe, b.fmt("libstdc++.{s}", .{lib_suffix}), "", need_cpp_includes) catch |err| switch (err) { - error.RequiredLibraryNotFound => { - exe.linkSystemLibrary("c++"); - }, - else => |e| return e, - }; - exe.linkSystemLibrary("unwind"); - } else if (exe.target.isFreeBSD()) { - try addCxxKnownPath(b, cfg, exe, b.fmt("libc++.{s}", .{lib_suffix}), null, need_cpp_includes); - exe.linkSystemLibrary("pthread"); - } else if (exe.target.getOsTag() == .openbsd) { - try addCxxKnownPath(b, cfg, exe, b.fmt("libc++.{s}", .{lib_suffix}), null, need_cpp_includes); - try addCxxKnownPath(b, cfg, exe, b.fmt("libc++abi.{s}", .{lib_suffix}), null, need_cpp_includes); - } else if (exe.target.isDarwin()) { - exe.linkSystemLibrary("c++"); + switch (exe.target.getOsTag()) { + .linux => { + // First we try to link against gcc libstdc++. If that doesn't work, we fall + // back to -lc++ and cross our fingers. + addCxxKnownPath(b, cfg, exe, b.fmt("libstdc++.{s}", .{lib_suffix}), "", need_cpp_includes) catch |err| switch (err) { + error.RequiredLibraryNotFound => { + exe.linkSystemLibrary("c++"); + }, + else => |e| return e, + }; + exe.linkSystemLibrary("unwind"); + }, + .ios, .macos, .watchos, .tvos => { + exe.linkSystemLibrary("c++"); + }, + .freebsd => { + try addCxxKnownPath(b, cfg, exe, b.fmt("libc++.{s}", .{lib_suffix}), null, need_cpp_includes); + try addCxxKnownPath(b, cfg, exe, b.fmt("libgcc_eh.{s}", .{lib_suffix}), null, need_cpp_includes); + }, + .openbsd => { + try addCxxKnownPath(b, cfg, exe, b.fmt("libc++.{s}", .{lib_suffix}), null, need_cpp_includes); + try addCxxKnownPath(b, cfg, exe, b.fmt("libc++abi.{s}", .{lib_suffix}), null, need_cpp_includes); + }, + .netbsd => { + try addCxxKnownPath(b, cfg, exe, b.fmt("libstdc++.{s}", .{lib_suffix}), null, need_cpp_includes); + try addCxxKnownPath(b, cfg, exe, b.fmt("libgcc_eh.{s}", .{lib_suffix}), null, need_cpp_includes); + }, + .dragonfly => { + try addCxxKnownPath(b, cfg, exe, b.fmt("libstdc++.{s}", .{lib_suffix}), null, need_cpp_includes); + try addCxxKnownPath(b, cfg, exe, b.fmt("libgcc_eh.{s}", .{lib_suffix}), null, need_cpp_includes); + }, + else => {}, } } diff --git a/lib/libcxx/include/__config b/lib/libcxx/include/__config index d9a47343da..0aab23b9b4 100644 --- a/lib/libcxx/include/__config +++ b/lib/libcxx/include/__config @@ -148,7 +148,7 @@ # endif // Feature macros for disabling pre ABI v1 features. All of these options // are deprecated. -# if defined(__FreeBSD__) +# if defined(__FreeBSD__) || defined(__DragonFly__) # define _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR # endif # endif @@ -726,11 +726,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD # endif // _LIBCPP_CXX03_LANG # if defined(__APPLE__) || defined(__FreeBSD__) || defined(_LIBCPP_MSVCRT_LIKE) || defined(__sun__) || \ - defined(__NetBSD__) + defined(__NetBSD__) || defined(__DragonFly__) # define _LIBCPP_LOCALE__L_EXTENSIONS 1 # endif -# ifdef __FreeBSD__ +# if defined(__FreeBSD__) || defined(__DragonFly__) # define _DECLARE_C99_LDBL_MATH 1 # endif @@ -750,11 +750,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD # define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION # endif -# if defined(__APPLE__) || defined(__FreeBSD__) +# if defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__) # define _LIBCPP_HAS_DEFAULTRUNELOCALE # endif -# if defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun__) +# if defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun__) || defined(__DragonFly__) # define _LIBCPP_WCTYPE_IS_MASK # endif @@ -901,6 +901,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD # if defined(__FreeBSD__) || \ defined(__wasi__) || \ + defined(__DragonFly__) || \ defined(__NetBSD__) || \ defined(__OpenBSD__) || \ defined(__NuttX__) || \ diff --git a/lib/libcxx/include/__locale b/lib/libcxx/include/__locale index 40f9a3ff57..62a439b979 100644 --- a/lib/libcxx/include/__locale +++ b/lib/libcxx/include/__locale @@ -33,7 +33,7 @@ # include <__support/newlib/xlocale.h> #elif defined(__OpenBSD__) # include <__support/openbsd/xlocale.h> -#elif (defined(__APPLE__) || defined(__FreeBSD__)) +#elif (defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__)) # include #elif defined(__Fuchsia__) # include <__support/fuchsia/xlocale.h> @@ -453,10 +453,10 @@ public: static const mask __regex_word = 0x4000; // 0x8000 and 0x0100 and 0x00ff are used # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA -#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) +#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(__DragonFly__) # ifdef __APPLE__ typedef __uint32_t mask; -# elif defined(__FreeBSD__) +# elif defined(__FreeBSD__) || defined(__DragonFly__) typedef unsigned long mask; # elif defined(__EMSCRIPTEN__) || defined(__NetBSD__) typedef unsigned short mask; diff --git a/lib/libcxx/include/locale b/lib/libcxx/include/locale index b01c66d043..de37d35a69 100644 --- a/lib/libcxx/include/locale +++ b/lib/libcxx/include/locale @@ -239,7 +239,7 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -#if defined(__APPLE__) || defined(__FreeBSD__) +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__) # define _LIBCPP_GET_C_LOCALE 0 #elif defined(__NetBSD__) # define _LIBCPP_GET_C_LOCALE LC_C_LOCALE diff --git a/lib/libcxx/src/locale.cpp b/lib/libcxx/src/locale.cpp index 6b454274e1..dc4ee7cbd9 100644 --- a/lib/libcxx/src/locale.cpp +++ b/lib/libcxx/src/locale.cpp @@ -1190,7 +1190,7 @@ ctype::classic_table() noexcept const ctype::mask* ctype::classic_table() noexcept { -#if defined(__APPLE__) || defined(__FreeBSD__) +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__) return _DefaultRuneLocale.__runetype; #elif defined(__NetBSD__) return _C_ctype_tab_ + 1; diff --git a/lib/std/c/dragonfly.zig b/lib/std/c/dragonfly.zig index 8c6ecb653f..aeece851a5 100644 --- a/lib/std/c/dragonfly.zig +++ b/lib/std/c/dragonfly.zig @@ -12,6 +12,7 @@ pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize; pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int; pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize; pub extern "c" fn pipe2(fds: *[2]fd_t, flags: u32) c_int; +pub extern "c" fn arc4random_buf(buf: [*]u8, len: usize) void; pub const dl_iterate_phdr_callback = std.meta.FnPtr(fn (info: *dl_phdr_info, size: usize, data: ?*anyopaque) callconv(.C) c_int); pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*anyopaque) c_int; @@ -419,6 +420,7 @@ pub const F = struct { pub const DUP2FD = 10; pub const DUPFD_CLOEXEC = 17; pub const DUP2FD_CLOEXEC = 18; + pub const GETPATH = 19; }; pub const FD_CLOEXEC = 1; diff --git a/lib/std/c/freebsd.zig b/lib/std/c/freebsd.zig index 24fce4af6e..1cf1ed18a1 100644 --- a/lib/std/c/freebsd.zig +++ b/lib/std/c/freebsd.zig @@ -15,12 +15,15 @@ pub extern "c" fn pthread_getthreadid_np() c_int; pub extern "c" fn pthread_set_name_np(thread: std.c.pthread_t, name: [*:0]const u8) void; pub extern "c" fn pthread_get_name_np(thread: std.c.pthread_t, name: [*:0]u8, len: usize) void; pub extern "c" fn pipe2(fds: *[2]fd_t, flags: u32) c_int; +pub extern "c" fn arc4random_buf(buf: [*]u8, len: usize) void; pub extern "c" fn posix_memalign(memptr: *?*anyopaque, alignment: usize, size: usize) c_int; pub extern "c" fn malloc_usable_size(?*const anyopaque) usize; pub extern "c" fn getpid() pid_t; +pub extern "c" fn kinfo_getfile(pid: pid_t, cntp: *c_int) ?[*]kinfo_file; + pub const sf_hdtr = extern struct { headers: [*]const iovec_const, hdr_cnt: c_int, diff --git a/lib/std/c/netbsd.zig b/lib/std/c/netbsd.zig index 132c9a6065..adf828c9a1 100644 --- a/lib/std/c/netbsd.zig +++ b/lib/std/c/netbsd.zig @@ -537,6 +537,7 @@ pub const KERN = struct { }; pub const PATH_MAX = 1024; +pub const NAME_MAX = 255; pub const IOV_MAX = KERN.IOV_MAX; pub const STDIN_FILENO = 0; @@ -689,13 +690,17 @@ pub const F = struct { pub const SETFD = 2; pub const GETFL = 3; pub const SETFL = 4; - pub const GETOWN = 5; pub const SETOWN = 6; - pub const GETLK = 7; pub const SETLK = 8; pub const SETLKW = 9; + pub const CLOSEM = 10; + pub const MAXFD = 11; + pub const DUPFD_CLOEXEC = 12; + pub const GETNOSIGPIPE = 13; + pub const SETNOSIGPIPE = 14; + pub const GETPATH = 15; pub const RDLCK = 1; pub const WRLCK = 3; diff --git a/lib/std/c/openbsd.zig b/lib/std/c/openbsd.zig index 3aea81f469..6c3663a926 100644 --- a/lib/std/c/openbsd.zig +++ b/lib/std/c/openbsd.zig @@ -417,6 +417,7 @@ pub const AI = struct { }; pub const PATH_MAX = 1024; +pub const NAME_MAX = 255; pub const IOV_MAX = 1024; pub const STDIN_FILENO = 0; diff --git a/lib/std/fs.zig b/lib/std/fs.zig index 573e3b17a8..c6ba24bd38 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -34,7 +34,7 @@ pub const Watch = @import("fs/watch.zig").Watch; /// fit into a UTF-8 encoded array of this length. /// The byte count includes room for a null sentinel byte. pub const MAX_PATH_BYTES = switch (builtin.os.tag) { - .linux, .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd, .haiku, .solaris => os.PATH_MAX, + .linux, .macos, .ios, .freebsd, .openbsd, .netbsd, .dragonfly, .haiku, .solaris => os.PATH_MAX, // Each UTF-16LE character may be expanded to 3 UTF-8 bytes. // If it would require 4 UTF-8 bytes, then there would be a surrogate // pair in the UTF-16LE, and we (over)account 3 bytes for it that way. @@ -54,10 +54,10 @@ pub const MAX_PATH_BYTES = switch (builtin.os.tag) { /// (depending on the platform) this assumption may not hold for every configuration. /// The byte count does not include a null sentinel byte. pub const MAX_NAME_BYTES = switch (builtin.os.tag) { - .linux, .macos, .ios, .freebsd, .dragonfly => os.NAME_MAX, + .linux, .macos, .ios, .freebsd, .openbsd, .netbsd, .dragonfly => os.NAME_MAX, // Haiku's NAME_MAX includes the null terminator, so subtract one. .haiku => os.NAME_MAX - 1, - .netbsd, .openbsd, .solaris => os.MAXNAMLEN, + .solaris => os.system.MAXNAMLEN, // Each UTF-16LE character may be expanded to 3 UTF-8 bytes. // If it would require 4 UTF-8 bytes, then there would be a surrogate // pair in the UTF-16LE, and we (over)account 3 bytes for it that way. diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index f085d3c2ed..fd8ca5d60c 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -451,8 +451,8 @@ test "file operations on directories" { try testing.expectError(error.IsDir, tmp_dir.dir.createFile(test_dir_name, .{})); try testing.expectError(error.IsDir, tmp_dir.dir.deleteFile(test_dir_name)); switch (builtin.os.tag) { - // NetBSD does not error when reading a directory. - .netbsd => {}, + // no error when reading a directory. + .dragonfly, .netbsd => {}, // Currently, WASI will return error.Unexpected (via ENOTCAPABLE) when attempting fd_read on a directory handle. // TODO: Re-enable on WASI once https://github.com/bytecodealliance/wasmtime/issues/1935 is resolved. .wasi => {}, diff --git a/lib/std/os.zig b/lib/std/os.zig index 7406562f6a..4ba93ace88 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -2818,6 +2818,8 @@ pub fn mkdiratZ(dir_fd: fd_t, sub_dir_path: [*:0]const u8, mode: u32) MakeDirErr .NOSPC => return error.NoSpaceLeft, .NOTDIR => return error.NotDir, .ROFS => return error.ReadOnlyFileSystem, + // dragonfly: when dir_fd is unlinked from filesystem + .NOTCONN => return error.FileNotFound, else => |err| return unexpectedErrno(err), } } @@ -5258,6 +5260,7 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 { switch (errno(system.fcntl(fd, F.GETPATH, out_buffer))) { .SUCCESS => {}, .BADF => return error.FileNotFound, + .NOSPC => return error.NameTooLong, // TODO man pages for fcntl on macOS don't really tell you what // errno values to expect when command is F.GETPATH... else => |err| return unexpectedErrno(err), @@ -5290,19 +5293,85 @@ pub fn getFdPath(fd: fd_t, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 { return target; }, .freebsd => { - comptime if (builtin.os.version_range.semver.max.order(.{ .major = 13, .minor = 0 }) == .lt) - @compileError("querying for canonical path of a handle is unsupported on FreeBSD 12 and below"); - - var kfile: system.kinfo_file = undefined; - kfile.structsize = system.KINFO_FILE_SIZE; - switch (errno(system.fcntl(fd, system.F.KINFO, @ptrToInt(&kfile)))) { + if (comptime builtin.os.version_range.semver.max.order(.{ .major = 13, .minor = 0 }) == .gt) { + var kfile: system.kinfo_file = undefined; + kfile.structsize = system.KINFO_FILE_SIZE; + switch (errno(system.fcntl(fd, system.F.KINFO, @ptrToInt(&kfile)))) { + .SUCCESS => {}, + .BADF => return error.FileNotFound, + else => |err| return unexpectedErrno(err), + } + const len = mem.indexOfScalar(u8, &kfile.path, 0) orelse MAX_PATH_BYTES; + if (len == 0) return error.NameTooLong; + mem.copy(u8, out_buffer, kfile.path[0..len]); + return out_buffer[0..len]; + } else { + // This fallback implementation reimplements libutil's `kinfo_getfile()`. + // The motivation is to avoid linking -lutil when building zig or general + // user executables. + var mib = [4]c_int{ CTL.KERN, KERN.PROC, KERN.PROC_FILEDESC, system.getpid() }; + var len: usize = undefined; + sysctl(&mib, null, &len, null, 0) catch |err| switch (err) { + error.PermissionDenied => unreachable, + error.SystemResources => return error.SystemResources, + error.NameTooLong => unreachable, + error.UnknownName => unreachable, + else => return error.Unexpected, + }; + len = len * 4 / 3; + const buf = std.heap.c_allocator.alloc(u8, len) catch return error.SystemResources; + defer std.heap.c_allocator.free(buf); + len = buf.len; + sysctl(&mib, &buf[0], &len, null, 0) catch |err| switch (err) { + error.PermissionDenied => unreachable, + error.SystemResources => return error.SystemResources, + error.NameTooLong => unreachable, + error.UnknownName => unreachable, + else => return error.Unexpected, + }; + var i: usize = 0; + while (i < len) { + const kf: *align(1) system.kinfo_file = @ptrCast(*align(1) system.kinfo_file, &buf[i]); + if (kf.fd == fd) { + len = mem.indexOfScalar(u8, &kf.path, 0) orelse MAX_PATH_BYTES; + if (len == 0) return error.NameTooLong; + mem.copy(u8, out_buffer, kf.path[0..len]); + return out_buffer[0..len]; + } + i += @intCast(usize, kf.structsize); + } + return error.InvalidHandle; + } + }, + .dragonfly => { + if (comptime builtin.os.version_range.semver.max.order(.{ .major = 6, .minor = 0 }) == .lt) { + @compileError("querying for canonical path of a handle is unsupported on this host"); + } + @memset(out_buffer, 0, MAX_PATH_BYTES); + switch (errno(system.fcntl(fd, F.GETPATH, out_buffer))) { .SUCCESS => {}, .BADF => return error.FileNotFound, + .RANGE => return error.NameTooLong, else => |err| return unexpectedErrno(err), } - - const len = mem.indexOfScalar(u8, &kfile.path, 0) orelse MAX_PATH_BYTES; - mem.copy(u8, out_buffer, kfile.path[0..len]); + const len = mem.indexOfScalar(u8, out_buffer[0..], @as(u8, 0)) orelse MAX_PATH_BYTES; + return out_buffer[0..len]; + }, + .netbsd => { + if (comptime builtin.os.version_range.semver.max.order(.{ .major = 10, .minor = 0 }) == .lt) { + @compileError("querying for canonical path of a handle is unsupported on this host"); + } + @memset(out_buffer, 0, MAX_PATH_BYTES); + switch (errno(system.fcntl(fd, F.GETPATH, out_buffer))) { + .SUCCESS => {}, + .ACCES => return error.AccessDenied, + .BADF => return error.FileNotFound, + .NOENT => return error.FileNotFound, + .NOMEM => return error.SystemResources, + .RANGE => return error.NameTooLong, + else => |err| return unexpectedErrno(err), + } + const len = mem.indexOfScalar(u8, out_buffer[0..], @as(u8, 0)) orelse MAX_PATH_BYTES; return out_buffer[0..len]; }, else => @compileError("querying for canonical path of a handle is unsupported on this host"), @@ -6675,6 +6744,8 @@ pub fn memfd_createZ(name: [*:0]const u8, flags: u32) MemFdCreateError!fd_t { } }, .freebsd => { + if (comptime builtin.os.version_range.semver.max.order(.{ .major = 13, .minor = 0 }) == .lt) + @compileError("memfd_create is unavailable on FreeBSD < 13.0"); const rc = system.memfd_create(name, flags); switch (errno(rc)) { .SUCCESS => return rc, diff --git a/lib/std/os/test.zig b/lib/std/os/test.zig index 24ca02da81..e1d20b2053 100644 --- a/lib/std/os/test.zig +++ b/lib/std/os/test.zig @@ -523,7 +523,14 @@ test "argsAlloc" { test "memfd_create" { // memfd_create is only supported by linux and freebsd. - if (native_os != .linux and native_os != .freebsd) return error.SkipZigTest; + switch (native_os) { + .linux => {}, + .freebsd => { + if (comptime builtin.os.version_range.semver.max.order(.{ .major = 13, .minor = 0 }) == .lt) + return error.SkipZigTest; + }, + else => return error.SkipZigTest, + } const fd = std.os.memfd_create("test", 0) catch |err| switch (err) { // Related: https://github.com/ziglang/zig/issues/4019 diff --git a/lib/std/target.zig b/lib/std/target.zig index 34bae7cda2..fabc82bd4a 100644 --- a/lib/std/target.zig +++ b/lib/std/target.zig @@ -271,7 +271,7 @@ pub const Target = struct { .freebsd => return .{ .semver = Version.Range{ .min = .{ .major = 12, .minor = 0 }, - .max = .{ .major = 13, .minor = 0 }, + .max = .{ .major = 13, .minor = 1 }, }, }, .macos => return switch (arch) { @@ -310,19 +310,19 @@ pub const Target = struct { .netbsd => return .{ .semver = .{ .min = .{ .major = 8, .minor = 0 }, - .max = .{ .major = 9, .minor = 1 }, + .max = .{ .major = 10, .minor = 0 }, }, }, .openbsd => return .{ .semver = .{ .min = .{ .major = 6, .minor = 8 }, - .max = .{ .major = 6, .minor = 9 }, + .max = .{ .major = 7, .minor = 2 }, }, }, .dragonfly => return .{ .semver = .{ .min = .{ .major = 5, .minor = 8 }, - .max = .{ .major = 6, .minor = 0 }, + .max = .{ .major = 6, .minor = 4 }, }, }, .solaris => return .{ diff --git a/src/link/Elf.zig b/src/link/Elf.zig index e55af7f211..cb09fd3359 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -3074,27 +3074,22 @@ const CsuObjects = struct { var result: CsuObjects = .{}; - // TODO: https://github.com/ziglang/zig/issues/4629 - // - use inline enum type - // - reduce to enum-literals for values - const Mode = enum { + // Flatten crt cases. + const mode: enum { dynamic_lib, dynamic_exe, dynamic_pie, static_exe, static_pie, - }; - - // Flatten crt case types. - const mode: Mode = switch (link_options.output_mode) { + } = switch (link_options.output_mode) { .Obj => return CsuObjects{}, .Lib => switch (link_options.link_mode) { - .Dynamic => Mode.dynamic_lib, + .Dynamic => .dynamic_lib, .Static => return CsuObjects{}, }, .Exe => switch (link_options.link_mode) { - .Dynamic => if (link_options.pie) Mode.dynamic_pie else Mode.dynamic_exe, - .Static => if (link_options.pie) Mode.static_pie else Mode.static_exe, + .Dynamic => if (link_options.pie) .dynamic_pie else .dynamic_exe, + .Static => if (link_options.pie) .static_pie else .static_exe, }, }; @@ -3124,7 +3119,6 @@ const CsuObjects = struct { // hosted-glibc provides crtbegin/end objects in platform/compiler-specific dirs // and they are not known at comptime. For now null-out crtbegin/end objects; // there is no feature loss, zig has never linked those objects in before. - // TODO: probe for paths, ie. `cc -print-file-name` result.crtbegin = null; result.crtend = null; } else {