From db8eae65dece402438e5e48dd0d1c8c4fc8f5b1c Mon Sep 17 00:00:00 2001 From: Al Hoang <3811822-hoanga@users.noreply.gitlab.com> Date: Sat, 22 May 2021 00:56:30 -0500 Subject: [PATCH 1/6] avoid usage of execv on Haiku --- lib/std/process.zig | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/std/process.zig b/lib/std/process.zig index 8b49e84a8c..f026c640e0 100644 --- a/lib/std/process.zig +++ b/lib/std/process.zig @@ -800,7 +800,10 @@ pub fn getSelfExeSharedLibPaths(allocator: *Allocator) error{OutOfMemory}![][:0] } /// Tells whether calling the `execv` or `execve` functions will be a compile error. -pub const can_execv = std.builtin.os.tag != .windows; +pub const can_execv = switch (builtin.os.tag) { + .windows, .haiku => false, + else => true, +}; pub const ExecvError = std.os.ExecveError || error{OutOfMemory}; From 2be2c983cb17bd24e0f876f9e363f8342765273c Mon Sep 17 00:00:00 2001 From: Al Hoang <3811822-hoanga@users.noreply.gitlab.com> Date: Sat, 22 May 2021 01:01:35 -0500 Subject: [PATCH 2/6] enable symbol lookup for haiku --- lib/std/debug.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/debug.zig b/lib/std/debug.zig index bfaf6f0df4..8da1dbe673 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -1686,7 +1686,7 @@ pub const ModuleDebugInfo = switch (native_os) { }; } }, - .linux, .netbsd, .freebsd, .dragonfly, .openbsd => struct { + .linux, .netbsd, .freebsd, .dragonfly, .openbsd, .haiku => struct { base_address: usize, dwarf: DW.DwarfInfo, mapped_memory: []const u8, From c4a4330cc7a783ad188daedd05159b725128f69c Mon Sep 17 00:00:00 2001 From: Al Hoang <3811822-hoanga@users.noreply.gitlab.com> Date: Sat, 22 May 2021 01:05:18 -0500 Subject: [PATCH 3/6] haiku case for libc link flags --- src/target.zig | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/target.zig b/src/target.zig index b4e6123819..59be06f296 100644 --- a/src/target.zig +++ b/src/target.zig @@ -366,6 +366,12 @@ pub fn libcFullLinkFlags(target: std.Target) []const []const u8 { "-lc", "-lutil", }, + .haiku => &[_][]const u8{ + "-lm", + "-lroot", + "-lpthread", + "-lc", + }, else => switch (target.abi) { .android => &[_][]const u8{ "-lm", From 5280ea5d22687bf4939dd1807c8a711937239307 Mon Sep 17 00:00:00 2001 From: Al Hoang <3811822-hoanga@users.noreply.gitlab.com> Date: Sat, 22 May 2021 01:06:41 -0500 Subject: [PATCH 4/6] update compilation and elf link for haiku case * for some reason part of the linkable bits for the crt libraries are split in different locations for haiku. this changeset accomodates this situation (crtbegin_dir lookup) --- src/Compilation.zig | 7 +++++++ src/libc_installation.zig | 30 +++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/Compilation.zig b/src/Compilation.zig index 023a54ca8d..b3a01b3c9d 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -3286,6 +3286,13 @@ pub fn get_libc_crt_file(comp: *Compilation, arena: *Allocator, basename: []cons return full_path; } +pub fn get_libc_crtbegin_file(comp: *Compilation, arena: *Allocator, basename: []const u8) ![]const u8 { + const lci = comp.bin_file.options.libc_installation orelse return error.LibCInstallationNotAvailable; + const crtbegin_dir_path = lci.crtbegin_dir orelse return error.LibCInstallationMissingCRTDir; + const full_path = try std.fs.path.join(arena, &[_][]const u8{ crtbegin_dir_path, basename }); + return full_path; +} + fn addBuildingGLibCJobs(comp: *Compilation) !void { try comp.work_queue.write(&[_]Job{ .{ .glibc_crt_file = .crti_o }, diff --git a/src/libc_installation.zig b/src/libc_installation.zig index 66ff8f77fd..372caefc36 100644 --- a/src/libc_installation.zig +++ b/src/libc_installation.zig @@ -21,6 +21,7 @@ pub const LibCInstallation = struct { crt_dir: ?[]const u8 = null, msvc_lib_dir: ?[]const u8 = null, kernel32_lib_dir: ?[]const u8 = null, + crtbegin_dir: ?[]const u8 = null, pub const FindError = error{ OutOfMemory, @@ -113,6 +114,10 @@ pub const LibCInstallation = struct { }); return error.ParseError; } + if (self.crtbegin_dir == null and is_haiku) { + log.err("crtbegin_dir may not be empty for {s}\n", .{@tagName(Target.current.os.tag)}); + return error.ParseError; + } return self; } @@ -124,6 +129,7 @@ pub const LibCInstallation = struct { const crt_dir = self.crt_dir orelse ""; const msvc_lib_dir = self.msvc_lib_dir orelse ""; const kernel32_lib_dir = self.kernel32_lib_dir orelse ""; + const crtbegin_dir = self.crtbegin_dir orelse ""; try out.print( \\# The directory that contains `stdlib.h`. @@ -148,12 +154,17 @@ pub const LibCInstallation = struct { \\# Only needed when targeting MSVC on Windows. \\kernel32_lib_dir={s} \\ + \\# The directory that contains `crtbeginS.o` and `crtendS.o` + \\# Only needed when targeting Haiku. + \\crtbegin_dir={s} + \\ , .{ include_dir, sys_include_dir, crt_dir, msvc_lib_dir, kernel32_lib_dir, + crtbegin_dir, }); } @@ -188,6 +199,15 @@ pub const LibCInstallation = struct { .NotFound => return error.WindowsSdkNotFound, .PathTooLong => return error.WindowsSdkNotFound, } + } else if (is_haiku) { + try blk: { + var batch = Batch(FindError!void, 2, .auto_async).init(); + errdefer batch.wait() catch {}; + batch.add(&async self.findNativeIncludeDirPosix(args)); + batch.add(&async self.findNativeCrtBeginDirHaiku(args)); + self.crt_dir = try std.mem.dupeZ(args.allocator, u8, "/system/develop/lib"); + break :blk batch.wait(); + }; } else { try blk: { var batch = Batch(FindError!void, 2, .auto_async).init(); @@ -196,7 +216,6 @@ pub const LibCInstallation = struct { switch (Target.current.os.tag) { .freebsd, .netbsd, .openbsd, .dragonfly => self.crt_dir = try std.mem.dupeZ(args.allocator, u8, "/usr/lib"), .linux => batch.add(&async self.findNativeCrtDirPosix(args)), - .haiku => self.crt_dir = try std.mem.dupeZ(args.allocator, u8, "/system/develop/lib"), else => {}, } break :blk batch.wait(); @@ -422,6 +441,15 @@ pub const LibCInstallation = struct { }); } + fn findNativeCrtBeginDirHaiku(self: *LibCInstallation, args: FindNativeOptions) FindError!void { + self.crtbegin_dir = try ccPrintFileName(.{ + .allocator = args.allocator, + .search_basename = "crtbeginS.o", + .want_dirname = .only_dir, + .verbose = args.verbose, + }); + } + fn findNativeKernel32LibDir( self: *LibCInstallation, args: FindNativeOptions, From e8cf15236d3b3f6d337858ad076f3ed11fca626b Mon Sep 17 00:00:00 2001 From: Al Hoang <3811822-hoanga@users.noreply.gitlab.com> Date: Sun, 23 May 2021 20:32:39 -0500 Subject: [PATCH 5/6] add haiku case to csu --- src/link/Elf.zig | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 693ae3f83c..8e02f5d2c6 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -3319,6 +3319,15 @@ const CsuObjects = struct { .static_pie => result.set( "rcrt0.o", null, "crtbegin.o", "crtend.o", null ), // zig fmt: on }, + .haiku => switch (mode) { + // zig fmt: off + .dynamic_lib => result.set( null, "crti.o", "crtbeginS.o", "crtendS.o", "crtn.o" ), + .dynamic_exe => result.set( "start_dyn.o", "crti.o", "crtbegin.o", "crtend.o", "crtn.o" ), + .dynamic_pie => result.set( "start_dyn.o", "crti.o", "crtbeginS.o", "crtendS.o", "crtn.o" ), + .static_exe => result.set( "start_dyn.o", "crti.o", "crtbegin.o", "crtend.o", "crtn.o" ), + .static_pie => result.set( "start_dyn.o", "crti.o", "crtbeginS.o", "crtendS.o", "crtn.o" ), + // zig fmt: on + }, else => {}, } } @@ -3342,6 +3351,15 @@ const CsuObjects = struct { if (result.crtbegin) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, gccv, obj.* }); if (result.crtend) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, gccv, obj.* }); }, + .haiku => { + const crtbegin_dir_path = lci.crtbegin_dir orelse return error.LibCInstallationMissingCRTDir; + if (result.crt0) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, obj.* }); + if (result.crti) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, obj.* }); + if (result.crtn) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, obj.* }); + + if (result.crtbegin) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crtbegin_dir_path, obj.* }); + if (result.crtend) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crtbegin_dir_path, obj.* }); + }, else => { inline for (std.meta.fields(@TypeOf(result))) |f,i| { if (@field(result, f.name)) |*obj| { From 156b968ad85d6b2f6146d66f1a3a3c48b34193da Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 24 May 2021 10:41:59 -0700 Subject: [PATCH 6/6] stage2: remove dead code; rename crtbegin_dir to gcc_dir --- src/Compilation.zig | 7 ------- src/libc_installation.zig | 14 +++++++------- src/link/Elf.zig | 14 +++++++------- 3 files changed, 14 insertions(+), 21 deletions(-) diff --git a/src/Compilation.zig b/src/Compilation.zig index b3a01b3c9d..023a54ca8d 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -3286,13 +3286,6 @@ pub fn get_libc_crt_file(comp: *Compilation, arena: *Allocator, basename: []cons return full_path; } -pub fn get_libc_crtbegin_file(comp: *Compilation, arena: *Allocator, basename: []const u8) ![]const u8 { - const lci = comp.bin_file.options.libc_installation orelse return error.LibCInstallationNotAvailable; - const crtbegin_dir_path = lci.crtbegin_dir orelse return error.LibCInstallationMissingCRTDir; - const full_path = try std.fs.path.join(arena, &[_][]const u8{ crtbegin_dir_path, basename }); - return full_path; -} - fn addBuildingGLibCJobs(comp: *Compilation) !void { try comp.work_queue.write(&[_]Job{ .{ .glibc_crt_file = .crti_o }, diff --git a/src/libc_installation.zig b/src/libc_installation.zig index 372caefc36..b9f0f0ecc7 100644 --- a/src/libc_installation.zig +++ b/src/libc_installation.zig @@ -21,7 +21,7 @@ pub const LibCInstallation = struct { crt_dir: ?[]const u8 = null, msvc_lib_dir: ?[]const u8 = null, kernel32_lib_dir: ?[]const u8 = null, - crtbegin_dir: ?[]const u8 = null, + gcc_dir: ?[]const u8 = null, pub const FindError = error{ OutOfMemory, @@ -114,8 +114,8 @@ pub const LibCInstallation = struct { }); return error.ParseError; } - if (self.crtbegin_dir == null and is_haiku) { - log.err("crtbegin_dir may not be empty for {s}\n", .{@tagName(Target.current.os.tag)}); + if (self.gcc_dir == null and is_haiku) { + log.err("gcc_dir may not be empty for {s}\n", .{@tagName(Target.current.os.tag)}); return error.ParseError; } @@ -129,7 +129,7 @@ pub const LibCInstallation = struct { const crt_dir = self.crt_dir orelse ""; const msvc_lib_dir = self.msvc_lib_dir orelse ""; const kernel32_lib_dir = self.kernel32_lib_dir orelse ""; - const crtbegin_dir = self.crtbegin_dir orelse ""; + const gcc_dir = self.gcc_dir orelse ""; try out.print( \\# The directory that contains `stdlib.h`. @@ -156,7 +156,7 @@ pub const LibCInstallation = struct { \\ \\# The directory that contains `crtbeginS.o` and `crtendS.o` \\# Only needed when targeting Haiku. - \\crtbegin_dir={s} + \\gcc_dir={s} \\ , .{ include_dir, @@ -164,7 +164,7 @@ pub const LibCInstallation = struct { crt_dir, msvc_lib_dir, kernel32_lib_dir, - crtbegin_dir, + gcc_dir, }); } @@ -442,7 +442,7 @@ pub const LibCInstallation = struct { } fn findNativeCrtBeginDirHaiku(self: *LibCInstallation, args: FindNativeOptions) FindError!void { - self.crtbegin_dir = try ccPrintFileName(.{ + self.gcc_dir = try ccPrintFileName(.{ .allocator = args.allocator, .search_basename = "crtbeginS.o", .want_dirname = .only_dir, diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 8e02f5d2c6..599d6fa2bf 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -3310,7 +3310,7 @@ const CsuObjects = struct { .static_pie => result.set( "crt0.o", "crti.o", "crtbeginT.o", "crtendS.o", "crtn.o" ), // zig fmt: on }, - .openbsd => switch(mode) { + .openbsd => switch (mode) { // zig fmt: off .dynamic_lib => result.set( null, null, "crtbeginS.o", "crtendS.o", null ), .dynamic_exe, @@ -3352,24 +3352,24 @@ const CsuObjects = struct { if (result.crtend) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, gccv, obj.* }); }, .haiku => { - const crtbegin_dir_path = lci.crtbegin_dir orelse return error.LibCInstallationMissingCRTDir; + const gcc_dir_path = lci.gcc_dir orelse return error.LibCInstallationMissingCRTDir; if (result.crt0) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, obj.* }); if (result.crti) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, obj.* }); if (result.crtn) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, obj.* }); - if (result.crtbegin) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crtbegin_dir_path, obj.* }); - if (result.crtend) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crtbegin_dir_path, obj.* }); + if (result.crtbegin) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ gcc_dir_path, obj.* }); + if (result.crtend) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ gcc_dir_path, obj.* }); }, else => { - inline for (std.meta.fields(@TypeOf(result))) |f,i| { + inline for (std.meta.fields(@TypeOf(result))) |f, i| { if (@field(result, f.name)) |*obj| { obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, obj.* }); } } - } + }, } } else { - inline for (std.meta.fields(@TypeOf(result))) |f,i| { + inline for (std.meta.fields(@TypeOf(result))) |f, i| { if (@field(result, f.name)) |*obj| { if (comp.crt_files.get(obj.*)) |crtf| { obj.* = crtf.full_object_path;