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) {...@@ -1686,7 +1686,7 @@ pub const ModuleDebugInfo = switch (native_os) {
1686 };1686 };
1687 }1687 }
1688 },1688 },
1689 .linux, .netbsd, .freebsd, .dragonfly, .openbsd => struct {1689 .linux, .netbsd, .freebsd, .dragonfly, .openbsd, .haiku => struct {
1690 base_address: usize,1690 base_address: usize,
1691 dwarf: DW.DwarfInfo,1691 dwarf: DW.DwarfInfo,
1692 mapped_memory: []const u8,1692 mapped_memory: []const u8,
lib/std/process.zig+4-1
...@@ -800,7 +800,10 @@ pub fn getSelfExeSharedLibPaths(allocator: *Allocator) error{OutOfMemory}![][:0]...@@ -800,7 +800,10 @@ pub fn getSelfExeSharedLibPaths(allocator: *Allocator) error{OutOfMemory}![][:0]
800}800}
801801
802/// Tells whether calling the `execv` or `execve` functions will be a compile error.802/// 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
805pub const ExecvError = std.os.ExecveError || error{OutOfMemory};808pub const ExecvError = std.os.ExecveError || error{OutOfMemory};
806809
src/libc_installation.zig+29-1
...@@ -21,6 +21,7 @@ pub const LibCInstallation = struct {...@@ -21,6 +21,7 @@ pub const LibCInstallation = struct {
21 crt_dir: ?[]const u8 = null,21 crt_dir: ?[]const u8 = null,
22 msvc_lib_dir: ?[]const u8 = null,22 msvc_lib_dir: ?[]const u8 = null,
23 kernel32_lib_dir: ?[]const u8 = null,23 kernel32_lib_dir: ?[]const u8 = null,
24 gcc_dir: ?[]const u8 = null,
2425
25 pub const FindError = error{26 pub const FindError = error{
26 OutOfMemory,27 OutOfMemory,
...@@ -113,6 +114,10 @@ pub const LibCInstallation = struct {...@@ -113,6 +114,10 @@ pub const LibCInstallation = struct {
113 });114 });
114 return error.ParseError;115 return error.ParseError;
115 }116 }
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
117 return self;122 return self;
118 }123 }
...@@ -124,6 +129,7 @@ pub const LibCInstallation = struct {...@@ -124,6 +129,7 @@ pub const LibCInstallation = struct {
124 const crt_dir = self.crt_dir orelse "";129 const crt_dir = self.crt_dir orelse "";
125 const msvc_lib_dir = self.msvc_lib_dir orelse "";130 const msvc_lib_dir = self.msvc_lib_dir orelse "";
126 const kernel32_lib_dir = self.kernel32_lib_dir orelse "";131 const kernel32_lib_dir = self.kernel32_lib_dir orelse "";
132 const gcc_dir = self.gcc_dir orelse "";
127133
128 try out.print(134 try out.print(
129 \\# The directory that contains `stdlib.h`.135 \\# The directory that contains `stdlib.h`.
...@@ -148,12 +154,17 @@ pub const LibCInstallation = struct {...@@ -148,12 +154,17 @@ pub const LibCInstallation = struct {
148 \\# Only needed when targeting MSVC on Windows.154 \\# Only needed when targeting MSVC on Windows.
149 \\kernel32_lib_dir={s}155 \\kernel32_lib_dir={s}
150 \\156 \\
157 \\# The directory that contains `crtbeginS.o` and `crtendS.o`
158 \\# Only needed when targeting Haiku.
159 \\gcc_dir={s}
160 \\
151 , .{161 , .{
152 include_dir,162 include_dir,
153 sys_include_dir,163 sys_include_dir,
154 crt_dir,164 crt_dir,
155 msvc_lib_dir,165 msvc_lib_dir,
156 kernel32_lib_dir,166 kernel32_lib_dir,
167 gcc_dir,
157 });168 });
158 }169 }
159170
...@@ -188,6 +199,15 @@ pub const LibCInstallation = struct {...@@ -188,6 +199,15 @@ pub const LibCInstallation = struct {
188 .NotFound => return error.WindowsSdkNotFound,199 .NotFound => return error.WindowsSdkNotFound,
189 .PathTooLong => return error.WindowsSdkNotFound,200 .PathTooLong => return error.WindowsSdkNotFound,
190 }201 }
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 };
191 } else {211 } else {
192 try blk: {212 try blk: {
193 var batch = Batch(FindError!void, 2, .auto_async).init();213 var batch = Batch(FindError!void, 2, .auto_async).init();
...@@ -196,7 +216,6 @@ pub const LibCInstallation = struct {...@@ -196,7 +216,6 @@ pub const LibCInstallation = struct {
196 switch (Target.current.os.tag) {216 switch (Target.current.os.tag) {
197 .freebsd, .netbsd, .openbsd, .dragonfly => self.crt_dir = try std.mem.dupeZ(args.allocator, u8, "/usr/lib"),217 .freebsd, .netbsd, .openbsd, .dragonfly => self.crt_dir = try std.mem.dupeZ(args.allocator, u8, "/usr/lib"),
198 .linux => batch.add(&async self.findNativeCrtDirPosix(args)),218 .linux => batch.add(&async self.findNativeCrtDirPosix(args)),
199 .haiku => self.crt_dir = try std.mem.dupeZ(args.allocator, u8, "/system/develop/lib"),
200 else => {},219 else => {},
201 }220 }
202 break :blk batch.wait();221 break :blk batch.wait();
...@@ -422,6 +441,15 @@ pub const LibCInstallation = struct {...@@ -422,6 +441,15 @@ pub const LibCInstallation = struct {
422 });441 });
423 }442 }
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
425 fn findNativeKernel32LibDir(453 fn findNativeKernel32LibDir(
426 self: *LibCInstallation,454 self: *LibCInstallation,
427 args: FindNativeOptions,455 args: FindNativeOptions,
src/link/Elf.zig+22-4
...@@ -3310,7 +3310,7 @@ const CsuObjects = struct {...@@ -3310,7 +3310,7 @@ const CsuObjects = struct {
3310 .static_pie => result.set( "crt0.o", "crti.o", "crtbeginT.o", "crtendS.o", "crtn.o" ),3310 .static_pie => result.set( "crt0.o", "crti.o", "crtbeginT.o", "crtendS.o", "crtn.o" ),
3311 // zig fmt: on3311 // zig fmt: on
3312 },3312 },
3313 .openbsd => switch(mode) {3313 .openbsd => switch (mode) {
3314 // zig fmt: off3314 // zig fmt: off
3315 .dynamic_lib => result.set( null, null, "crtbeginS.o", "crtendS.o", null ),3315 .dynamic_lib => result.set( null, null, "crtbeginS.o", "crtendS.o", null ),
3316 .dynamic_exe,3316 .dynamic_exe,
...@@ -3319,6 +3319,15 @@ const CsuObjects = struct {...@@ -3319,6 +3319,15 @@ const CsuObjects = struct {
3319 .static_pie => result.set( "rcrt0.o", null, "crtbegin.o", "crtend.o", null ),3319 .static_pie => result.set( "rcrt0.o", null, "crtbegin.o", "crtend.o", null ),
3320 // zig fmt: on3320 // zig fmt: on
3321 },3321 },
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 },
3322 else => {},3331 else => {},
3323 }3332 }
3324 }3333 }
...@@ -3342,16 +3351,25 @@ const CsuObjects = struct {...@@ -3342,16 +3351,25 @@ const CsuObjects = struct {
3342 if (result.crtbegin) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, gccv, obj.* });3351 if (result.crtbegin) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, gccv, obj.* });
3343 if (result.crtend) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, gccv, obj.* });3352 if (result.crtend) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, gccv, obj.* });
3344 },3353 },
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 },
3345 else => {3363 else => {
3346 inline for (std.meta.fields(@TypeOf(result))) |f,i| {3364 inline for (std.meta.fields(@TypeOf(result))) |f, i| {
3347 if (@field(result, f.name)) |*obj| {3365 if (@field(result, f.name)) |*obj| {
3348 obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, obj.* });3366 obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, obj.* });
3349 }3367 }
3350 }3368 }
3351 }3369 },
3352 }3370 }
3353 } else {3371 } else {
3354 inline for (std.meta.fields(@TypeOf(result))) |f,i| {3372 inline for (std.meta.fields(@TypeOf(result))) |f, i| {
3355 if (@field(result, f.name)) |*obj| {3373 if (@field(result, f.name)) |*obj| {
3356 if (comp.crt_files.get(obj.*)) |crtf| {3374 if (comp.crt_files.get(obj.*)) |crtf| {
3357 obj.* = crtf.full_object_path;3375 obj.* = crtf.full_object_path;
src/target.zig+6
...@@ -366,6 +366,12 @@ pub fn libcFullLinkFlags(target: std.Target) []const []const u8 {...@@ -366,6 +366,12 @@ pub fn libcFullLinkFlags(target: std.Target) []const []const u8 {
366 "-lc",366 "-lc",
367 "-lutil",367 "-lutil",
368 },368 },
369 .haiku => &[_][]const u8{
370 "-lm",
371 "-lroot",
372 "-lpthread",
373 "-lc",
374 },
369 else => switch (target.abi) {375 else => switch (target.abi) {
370 .android => &[_][]const u8{376 .android => &[_][]const u8{
371 "-lm",377 "-lm",