Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 5 additions & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -708,21 +708,15 @@ target_link_libraries(zigcpp LINK_PUBLIC
${CMAKE_THREAD_LIBS_INIT}
)

if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "AMD64")
string(TOLOWER "${CMAKE_HOST_SYSTEM_PROCESSOR}" HOST_TARGET_ARCH)
if(HOST_TARGET_ARCH STREQUAL "amd64")
set(HOST_TARGET_ARCH "x86_64")
elseif(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "amd64")
set(HOST_TARGET_ARCH "x86_64")
elseif(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "arm64")
set(HOST_TARGET_ARCH "aarch64")
elseif(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "ARM64")
elseif(HOST_TARGET_ARCH STREQUAL "arm64")
set(HOST_TARGET_ARCH "aarch64")
else()
string(TOLOWER "${CMAKE_HOST_SYSTEM_PROCESSOR}" HOST_TARGET_ARCH)
endif()
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
string(TOLOWER "${CMAKE_HOST_SYSTEM_NAME}" HOST_TARGET_OS)
if(HOST_TARGET_OS STREQUAL "darwin")
set(HOST_TARGET_OS "macos")
else()
string(TOLOWER "${CMAKE_HOST_SYSTEM_NAME}" HOST_TARGET_OS)
endif()
set(HOST_TARGET_TRIPLE "${HOST_TARGET_ARCH}-${HOST_TARGET_OS}")

Expand Down
50 changes: 32 additions & 18 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -560,24 +560,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 => {},
}
}

Expand Down
11 changes: 6 additions & 5 deletions lib/libcxx/include/__config
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand All @@ -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

Expand Down Expand Up @@ -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__) || \
Expand Down
6 changes: 3 additions & 3 deletions lib/libcxx/include/__locale
Original file line number Diff line number Diff line change
Expand Up @@ -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 <xlocale.h>
#elif defined(__Fuchsia__)
# include <__support/fuchsia/xlocale.h>
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion lib/libcxx/include/locale
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion lib/libcxx/src/locale.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1190,7 +1190,7 @@ ctype<char>::classic_table() noexcept
const ctype<char>::mask*
ctype<char>::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;
Expand Down
2 changes: 2 additions & 0 deletions lib/std/c/dragonfly.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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 = *const 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;
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions lib/std/c/freebsd.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
9 changes: 7 additions & 2 deletions lib/std/c/netbsd.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions lib/std/c/openbsd.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
6 changes: 3 additions & 3 deletions lib/std/fs.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions lib/std/fs/test.zig
Original file line number Diff line number Diff line change
Expand Up @@ -446,8 +446,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 => {},
Expand Down
89 changes: 80 additions & 9 deletions lib/std/os.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2696,6 +2696,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),
}
}
Expand Down Expand Up @@ -5098,6 +5100,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),
Expand Down Expand Up @@ -5130,19 +5133,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"),
Expand Down Expand Up @@ -6528,6 +6597,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,
Expand Down
Loading