authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-24 13:45:47-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-05-24 13:45:47-04:00
log0a99898b984c1ed98486060129ab441849118d8a
treeeb180ea03fe2320cf94e3588f4cf773bad9ea14c
parent8cebbc352ab7ec324891fec222f317f02aba45d7
parent156b968ad85d6b2f6146d66f1a3a3c48b34193da
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #8862 from hoanga/haiku-support-linker

further haiku support initial compile and link

5 files changed, 62 insertions(+), 7 deletions(-)

lib/std/debug.zig+1-1
......@@ -1686,7 +1686,7 @@ pub const ModuleDebugInfo = switch (native_os) {
16861686 };
16871687 }
16881688 },
1689 .linux, .netbsd, .freebsd, .dragonfly, .openbsd => struct {
1689 .linux, .netbsd, .freebsd, .dragonfly, .openbsd, .haiku => struct {
16901690 base_address: usize,
16911691 dwarf: DW.DwarfInfo,
16921692 mapped_memory: []const u8,
lib/std/process.zig+4-1
......@@ -800,7 +800,10 @@ pub fn getSelfExeSharedLibPaths(allocator: *Allocator) error{OutOfMemory}![][:0]
800800}
801801
802802/// Tells whether calling the `execv` or `execve` functions will be a compile error.
803pub const can_execv = std.builtin.os.tag != .windows;
803pub const can_execv = switch (builtin.os.tag) {
804 .windows, .haiku => false,
805 else => true,
806};
804807
805808pub const ExecvError = std.os.ExecveError || error{OutOfMemory};
806809
src/libc_installation.zig+29-1
......@@ -21,6 +21,7 @@ pub const LibCInstallation = struct {
2121 crt_dir: ?[]const u8 = null,
2222 msvc_lib_dir: ?[]const u8 = null,
2323 kernel32_lib_dir: ?[]const u8 = null,
24 gcc_dir: ?[]const u8 = null,
2425
2526 pub const FindError = error{
2627 OutOfMemory,
......@@ -113,6 +114,10 @@ pub const LibCInstallation = struct {
113114 });
114115 return error.ParseError;
115116 }
117 if (self.gcc_dir == null and is_haiku) {
118 log.err("gcc_dir may not be empty for {s}\n", .{@tagName(Target.current.os.tag)});
119 return error.ParseError;
120 }
116121
117122 return self;
118123 }
......@@ -124,6 +129,7 @@ pub const LibCInstallation = struct {
124129 const crt_dir = self.crt_dir orelse "";
125130 const msvc_lib_dir = self.msvc_lib_dir orelse "";
126131 const kernel32_lib_dir = self.kernel32_lib_dir orelse "";
132 const gcc_dir = self.gcc_dir orelse "";
127133
128134 try out.print(
129135 \\# The directory that contains `stdlib.h`.
......@@ -148,12 +154,17 @@ pub const LibCInstallation = struct {
148154 \\# Only needed when targeting MSVC on Windows.
149155 \\kernel32_lib_dir={s}
150156 \\
157 \\# The directory that contains `crtbeginS.o` and `crtendS.o`
158 \\# Only needed when targeting Haiku.
159 \\gcc_dir={s}
160 \\
151161 , .{
152162 include_dir,
153163 sys_include_dir,
154164 crt_dir,
155165 msvc_lib_dir,
156166 kernel32_lib_dir,
167 gcc_dir,
157168 });
158169 }
159170
......@@ -188,6 +199,15 @@ pub const LibCInstallation = struct {
188199 .NotFound => return error.WindowsSdkNotFound,
189200 .PathTooLong => return error.WindowsSdkNotFound,
190201 }
202 } else if (is_haiku) {
203 try blk: {
204 var batch = Batch(FindError!void, 2, .auto_async).init();
205 errdefer batch.wait() catch {};
206 batch.add(&async self.findNativeIncludeDirPosix(args));
207 batch.add(&async self.findNativeCrtBeginDirHaiku(args));
208 self.crt_dir = try std.mem.dupeZ(args.allocator, u8, "/system/develop/lib");
209 break :blk batch.wait();
210 };
191211 } else {
192212 try blk: {
193213 var batch = Batch(FindError!void, 2, .auto_async).init();
......@@ -196,7 +216,6 @@ pub const LibCInstallation = struct {
196216 switch (Target.current.os.tag) {
197217 .freebsd, .netbsd, .openbsd, .dragonfly => self.crt_dir = try std.mem.dupeZ(args.allocator, u8, "/usr/lib"),
198218 .linux => batch.add(&async self.findNativeCrtDirPosix(args)),
199 .haiku => self.crt_dir = try std.mem.dupeZ(args.allocator, u8, "/system/develop/lib"),
200219 else => {},
201220 }
202221 break :blk batch.wait();
......@@ -422,6 +441,15 @@ pub const LibCInstallation = struct {
422441 });
423442 }
424443
444 fn findNativeCrtBeginDirHaiku(self: *LibCInstallation, args: FindNativeOptions) FindError!void {
445 self.gcc_dir = try ccPrintFileName(.{
446 .allocator = args.allocator,
447 .search_basename = "crtbeginS.o",
448 .want_dirname = .only_dir,
449 .verbose = args.verbose,
450 });
451 }
452
425453 fn findNativeKernel32LibDir(
426454 self: *LibCInstallation,
427455 args: FindNativeOptions,
src/link/Elf.zig+22-4
......@@ -3310,7 +3310,7 @@ const CsuObjects = struct {
33103310 .static_pie => result.set( "crt0.o", "crti.o", "crtbeginT.o", "crtendS.o", "crtn.o" ),
33113311 // zig fmt: on
33123312 },
3313 .openbsd => switch(mode) {
3313 .openbsd => switch (mode) {
33143314 // zig fmt: off
33153315 .dynamic_lib => result.set( null, null, "crtbeginS.o", "crtendS.o", null ),
33163316 .dynamic_exe,
......@@ -3319,6 +3319,15 @@ const CsuObjects = struct {
33193319 .static_pie => result.set( "rcrt0.o", null, "crtbegin.o", "crtend.o", null ),
33203320 // zig fmt: on
33213321 },
3322 .haiku => switch (mode) {
3323 // zig fmt: off
3324 .dynamic_lib => result.set( null, "crti.o", "crtbeginS.o", "crtendS.o", "crtn.o" ),
3325 .dynamic_exe => result.set( "start_dyn.o", "crti.o", "crtbegin.o", "crtend.o", "crtn.o" ),
3326 .dynamic_pie => result.set( "start_dyn.o", "crti.o", "crtbeginS.o", "crtendS.o", "crtn.o" ),
3327 .static_exe => result.set( "start_dyn.o", "crti.o", "crtbegin.o", "crtend.o", "crtn.o" ),
3328 .static_pie => result.set( "start_dyn.o", "crti.o", "crtbeginS.o", "crtendS.o", "crtn.o" ),
3329 // zig fmt: on
3330 },
33223331 else => {},
33233332 }
33243333 }
......@@ -3342,16 +3351,25 @@ const CsuObjects = struct {
33423351 if (result.crtbegin) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, gccv, obj.* });
33433352 if (result.crtend) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, gccv, obj.* });
33443353 },
3354 .haiku => {
3355 const gcc_dir_path = lci.gcc_dir orelse return error.LibCInstallationMissingCRTDir;
3356 if (result.crt0) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, obj.* });
3357 if (result.crti) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, obj.* });
3358 if (result.crtn) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, obj.* });
3359
3360 if (result.crtbegin) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ gcc_dir_path, obj.* });
3361 if (result.crtend) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ gcc_dir_path, obj.* });
3362 },
33453363 else => {
3346 inline for (std.meta.fields(@TypeOf(result))) |f,i| {
3364 inline for (std.meta.fields(@TypeOf(result))) |f, i| {
33473365 if (@field(result, f.name)) |*obj| {
33483366 obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, obj.* });
33493367 }
33503368 }
3351 }
3369 },
33523370 }
33533371 } else {
3354 inline for (std.meta.fields(@TypeOf(result))) |f,i| {
3372 inline for (std.meta.fields(@TypeOf(result))) |f, i| {
33553373 if (@field(result, f.name)) |*obj| {
33563374 if (comp.crt_files.get(obj.*)) |crtf| {
33573375 obj.* = crtf.full_object_path;
src/target.zig+6
......@@ -366,6 +366,12 @@ pub fn libcFullLinkFlags(target: std.Target) []const []const u8 {
366366 "-lc",
367367 "-lutil",
368368 },
369 .haiku => &[_][]const u8{
370 "-lm",
371 "-lroot",
372 "-lpthread",
373 "-lc",
374 },
369375 else => switch (target.abi) {
370376 .android => &[_][]const u8{
371377 "-lm",