authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-18 00:34:42-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-18 17:43:36-04:00
logaa3b41247f297b4fd8b3bdb7920cb479f5aa004b
tree3e8bc66c275175cabe3f0a6fb6b8febd2c34c8bd
parent3e4a3fa5b7faadaae0a57088baa392e2bb52fe38

self-hosted: linking against libc

also introduce `zig libc` command to display paths `zig libc file.txt` will parse equivalent text and use that for libc paths.

8 files changed, 709 insertions(+), 172 deletions(-)

src-self-hosted/codegen.zig+1-1
......@@ -15,7 +15,7 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code)
1515 defer fn_val.base.deref(comp);
1616 defer code.destroy(comp.gpa());
1717
18 var output_path = try await (async comp.createRandomOutputPath(comp.target.oFileExt()) catch unreachable);
18 var output_path = try await (async comp.createRandomOutputPath(comp.target.objFileExt()) catch unreachable);
1919 errdefer output_path.deinit();
2020
2121 const llvm_handle = try comp.event_loop_local.getAnyLlvmContext();
src-self-hosted/compilation.zig+37-14
......@@ -120,7 +120,6 @@ pub const Compilation = struct {
120120
121121 linker_script: ?[]const u8,
122122 cache_dir: []const u8,
123 dynamic_linker: ?[]const u8,
124123 out_h_path: ?[]const u8,
125124
126125 is_test: bool,
......@@ -201,6 +200,13 @@ pub const Compilation = struct {
201200 root_package: *Package,
202201 std_package: *Package,
203202
203 override_libc: ?*LibCInstallation,
204
205 /// need to wait on this group before deinitializing
206 deinit_group: event.Group(void),
207
208 destroy_handle: promise,
209
204210 const CompileErrList = std.ArrayList(*errmsg.Msg);
205211
206212 // TODO handle some of these earlier and report them in a way other than error codes
......@@ -246,6 +252,8 @@ pub const Compilation = struct {
246252 EnvironmentVariableNotFound,
247253 AppDataDirUnavailable,
248254 LinkFailed,
255 LibCRequiredButNotProvidedOrFound,
256 LibCMissingDynamicLinker,
249257 };
250258
251259 pub const Event = union(enum) {
......@@ -324,7 +332,6 @@ pub const Compilation = struct {
324332 .verbose_link = false,
325333
326334 .linker_script = null,
327 .dynamic_linker = null,
328335 .out_h_path = null,
329336 .is_test = false,
330337 .each_lib_rpath = false,
......@@ -351,6 +358,7 @@ pub const Compilation = struct {
351358 .link_out_file = null,
352359 .exported_symbol_names = event.Locked(Decl.Table).init(loop, Decl.Table.init(loop.allocator)),
353360 .prelink_group = event.Group(BuildError!void).init(loop),
361 .deinit_group = event.Group(void).init(loop),
354362 .compile_errors = event.Locked(CompileErrList).init(loop, CompileErrList.init(loop.allocator)),
355363
356364 .meta_type = undefined,
......@@ -368,6 +376,9 @@ pub const Compilation = struct {
368376
369377 .root_package = undefined,
370378 .std_package = undefined,
379
380 .override_libc = null,
381 .destroy_handle = undefined,
371382 });
372383 errdefer {
373384 comp.arena_allocator.deinit();
......@@ -431,6 +442,9 @@ pub const Compilation = struct {
431442 }
432443
433444 try comp.initTypes();
445 errdefer comp.derefTypes();
446
447 comp.destroy_handle = try async<loop.allocator> comp.internalDeinit();
434448
435449 return comp;
436450 }
......@@ -526,11 +540,7 @@ pub const Compilation = struct {
526540 errdefer comp.gpa().destroy(comp.noreturn_value);
527541 }
528542
529 pub fn destroy(self: *Compilation) void {
530 if (self.tmp_dir.getOrNull()) |tmp_dir_result| if (tmp_dir_result.*) |tmp_dir| {
531 os.deleteTree(self.arena(), tmp_dir) catch {};
532 } else |_| {};
533
543 fn derefTypes(self: *Compilation) void {
534544 self.noreturn_value.base.deref(self);
535545 self.void_value.base.deref(self);
536546 self.false_value.base.deref(self);
......@@ -538,6 +548,17 @@ pub const Compilation = struct {
538548 self.noreturn_type.base.base.deref(self);
539549 self.void_type.base.base.deref(self);
540550 self.meta_type.base.base.deref(self);
551 }
552
553 async fn internalDeinit(self: *Compilation) void {
554 suspend;
555 await (async self.deinit_group.wait() catch unreachable);
556 if (self.tmp_dir.getOrNull()) |tmp_dir_result| if (tmp_dir_result.*) |tmp_dir| {
557 // TODO evented I/O?
558 os.deleteTree(self.arena(), tmp_dir) catch {};
559 } else |_| {};
560
561 self.derefTypes();
541562
542563 self.events.destroy();
543564
......@@ -549,6 +570,10 @@ pub const Compilation = struct {
549570 self.gpa().destroy(self);
550571 }
551572
573 pub fn destroy(self: *Compilation) void {
574 resume self.destroy_handle;
575 }
576
552577 pub fn build(self: *Compilation) !void {
553578 if (self.llvm_argv.len != 0) {
554579 var c_compatible_args = try std.cstr.NullTerminated2DArray.fromSlices(self.arena(), [][]const []const u8{
......@@ -680,7 +705,7 @@ pub const Compilation = struct {
680705 };
681706
682707 if (!any_prelink_errors) {
683 try link(self);
708 try await (async link(self) catch unreachable);
684709 }
685710 }
686711
......@@ -765,8 +790,8 @@ pub const Compilation = struct {
765790 self.libc_link_lib = link_lib;
766791
767792 // get a head start on looking for the native libc
768 if (self.target == Target.Native) {
769 try async<self.loop.allocator> self.startFindingNativeLibC();
793 if (self.target == Target.Native and self.override_libc == null) {
794 try self.deinit_group.call(startFindingNativeLibC, self);
770795 }
771796 }
772797 return link_lib;
......@@ -774,11 +799,9 @@ pub const Compilation = struct {
774799
775800 /// cancels itself so no need to await or cancel the promise.
776801 async fn startFindingNativeLibC(self: *Compilation) void {
802 await (async self.loop.yield() catch unreachable);
777803 // we don't care if it fails, we're just trying to kick off the future resolution
778 _ = (await (async self.loop.call(EventLoopLocal.getNativeLibC, self.event_loop_local) catch unreachable)) catch {};
779 suspend |p| {
780 cancel p;
781 }
804 _ = (await (async self.event_loop_local.getNativeLibC() catch unreachable)) catch return;
782805 }
783806
784807 /// General Purpose Allocator. Must free when done.
src-self-hosted/libc_installation.zig+187-35
......@@ -1,31 +1,18 @@
11const std = @import("std");
22const builtin = @import("builtin");
33const event = std.event;
4const Target = @import("target.zig").Target;
45
6/// See the render function implementation for documentation of the fields.
57pub const LibCInstallation = struct {
6 /// The directory that contains `stdlib.h`.
7 /// On Linux, can be found with: `cc -E -Wp,-v -xc /dev/null`
88 include_dir: []const u8,
9
10 /// The directory that contains `crt1.o`.
11 /// On Linux, can be found with `cc -print-file-name=crt1.o`.
12 /// Not needed when targeting MacOS.
139 lib_dir: ?[]const u8,
14
15 /// The directory that contains `crtbegin.o`.
16 /// On Linux, can be found with `cc -print-file-name=crt1.o`.
17 /// Not needed when targeting MacOS or Windows.
1810 static_lib_dir: ?[]const u8,
19
20 /// The directory that contains `vcruntime.lib`.
21 /// Only needed when targeting Windows.
2211 msvc_lib_dir: ?[]const u8,
23
24 /// The directory that contains `kernel32.lib`.
25 /// Only needed when targeting Windows.
2612 kernel32_lib_dir: ?[]const u8,
13 dynamic_linker_path: ?[]const u8,
2714
28 pub const Error = error{
15 pub const FindError = error{
2916 OutOfMemory,
3017 FileSystem,
3118 UnableToSpawnCCompiler,
......@@ -36,16 +23,124 @@ pub const LibCInstallation = struct {
3623 LibCStdLibHeaderNotFound,
3724 };
3825
26 pub fn parse(
27 self: *LibCInstallation,
28 allocator: *std.mem.Allocator,
29 libc_file: []const u8,
30 stderr: *std.io.OutStream(std.io.FileOutStream.Error),
31 ) !void {
32 self.initEmpty();
33
34 const keys = []const []const u8{
35 "include_dir",
36 "lib_dir",
37 "static_lib_dir",
38 "msvc_lib_dir",
39 "kernel32_lib_dir",
40 "dynamic_linker_path",
41 };
42 const FoundKey = struct {
43 found: bool,
44 allocated: ?[]u8,
45 };
46 var found_keys = [1]FoundKey{FoundKey{ .found = false, .allocated = null }} ** keys.len;
47 errdefer {
48 self.initEmpty();
49 for (found_keys) |found_key| {
50 if (found_key.allocated) |s| allocator.free(s);
51 }
52 }
53
54 const contents = try std.io.readFileAlloc(allocator, libc_file);
55 defer allocator.free(contents);
56
57 var it = std.mem.split(contents, "\n");
58 while (it.next()) |line| {
59 if (line.len == 0 or line[0] == '#') continue;
60 var line_it = std.mem.split(line, "=");
61 const name = line_it.next() orelse {
62 try stderr.print("missing equal sign after field name\n");
63 return error.ParseError;
64 };
65 const value = line_it.rest();
66 inline for (keys) |key, i| {
67 if (std.mem.eql(u8, name, key)) {
68 found_keys[i].found = true;
69 switch (@typeInfo(@typeOf(@field(self, key)))) {
70 builtin.TypeId.Optional => {
71 if (value.len == 0) {
72 @field(self, key) = null;
73 } else {
74 found_keys[i].allocated = try std.mem.dupe(allocator, u8, value);
75 @field(self, key) = found_keys[i].allocated;
76 }
77 },
78 else => {
79 if (value.len == 0) {
80 try stderr.print("field cannot be empty: {}\n", key);
81 return error.ParseError;
82 }
83 const dupe = try std.mem.dupe(allocator, u8, value);
84 found_keys[i].allocated = dupe;
85 @field(self, key) = dupe;
86 },
87 }
88 break;
89 }
90 }
91 }
92 for (found_keys) |found_key, i| {
93 if (!found_key.found) {
94 try stderr.print("missing field: {}\n", keys[i]);
95 return error.ParseError;
96 }
97 }
98 }
99
100 pub fn render(self: *const LibCInstallation, out: *std.io.OutStream(std.io.FileOutStream.Error)) !void {
101 @setEvalBranchQuota(4000);
102 try out.print(
103 \\# The directory that contains `stdlib.h`.
104 \\# On Linux, can be found with: `cc -E -Wp,-v -xc /dev/null`
105 \\include_dir={}
106 \\
107 \\# The directory that contains `crt1.o`.
108 \\# On Linux, can be found with `cc -print-file-name=crt1.o`.
109 \\# Not needed when targeting MacOS.
110 \\lib_dir={}
111 \\
112 \\# The directory that contains `crtbegin.o`.
113 \\# On Linux, can be found with `cc -print-file-name=crt1.o`.
114 \\# Not needed when targeting MacOS or Windows.
115 \\static_lib_dir={}
116 \\
117 \\# The directory that contains `vcruntime.lib`.
118 \\# Only needed when targeting Windows.
119 \\msvc_lib_dir={}
120 \\
121 \\# The directory that contains `kernel32.lib`.
122 \\# Only needed when targeting Windows.
123 \\kernel32_lib_dir={}
124 \\
125 \\# The full path to the dynamic linker.
126 \\# Only needed when targeting Linux.
127 \\dynamic_linker_path={}
128 \\
129 ,
130 self.include_dir,
131 self.lib_dir orelse "",
132 self.static_lib_dir orelse "",
133 self.msvc_lib_dir orelse "",
134 self.kernel32_lib_dir orelse "",
135 self.dynamic_linker_path orelse Target(Target.Native).getDynamicLinkerPath(),
136 );
137 }
138
39139 /// Finds the default, native libc.
40140 pub async fn findNative(self: *LibCInstallation, loop: *event.Loop) !void {
41 self.* = LibCInstallation{
42 .lib_dir = null,
43 .include_dir = ([*]const u8)(undefined)[0..0],
44 .static_lib_dir = null,
45 .msvc_lib_dir = null,
46 .kernel32_lib_dir = null,
47 };
48 var group = event.Group(Error!void).init(loop);
141 self.initEmpty();
142 var group = event.Group(FindError!void).init(loop);
143 errdefer group.cancelAll();
49144 switch (builtin.os) {
50145 builtin.Os.windows => {
51146 try group.call(findNativeIncludeDirWindows, self, loop);
......@@ -57,6 +152,7 @@ pub const LibCInstallation = struct {
57152 try group.call(findNativeIncludeDirLinux, self, loop);
58153 try group.call(findNativeLibDirLinux, self, loop);
59154 try group.call(findNativeStaticLibDir, self, loop);
155 try group.call(findNativeDynamicLinker, self, loop);
60156 },
61157 builtin.Os.macosx => {
62158 try group.call(findNativeIncludeDirMacOS, self, loop);
......@@ -147,7 +243,7 @@ pub const LibCInstallation = struct {
147243 self.include_dir = try std.mem.dupe(loop.allocator, u8, "/usr/include");
148244 }
149245
150 async fn findNativeLibDirWindows(self: *LibCInstallation, loop: *event.Loop) Error!void {
246 async fn findNativeLibDirWindows(self: *LibCInstallation, loop: *event.Loop) FindError!void {
151247 // TODO
152248 //ZigWindowsSDK *sdk = get_windows_sdk(g);
153249
......@@ -180,31 +276,83 @@ pub const LibCInstallation = struct {
180276 @panic("TODO");
181277 }
182278
183 async fn findNativeLibDirLinux(self: *LibCInstallation, loop: *event.Loop) Error!void {
184 self.lib_dir = try await (async ccPrintFileNameDir(loop, "crt1.o") catch unreachable);
279 async fn findNativeLibDirLinux(self: *LibCInstallation, loop: *event.Loop) FindError!void {
280 self.lib_dir = try await (async ccPrintFileName(loop, "crt1.o", true) catch unreachable);
281 }
282
283 async fn findNativeStaticLibDir(self: *LibCInstallation, loop: *event.Loop) FindError!void {
284 self.static_lib_dir = try await (async ccPrintFileName(loop, "crtbegin.o", true) catch unreachable);
285 }
286
287 async fn findNativeDynamicLinker(self: *LibCInstallation, loop: *event.Loop) FindError!void {
288 var dyn_tests = []DynTest{
289 DynTest{
290 .name = "ld-linux-x86-64.so.2",
291 .result = null,
292 },
293 DynTest{
294 .name = "ld-musl-x86_64.so.1",
295 .result = null,
296 },
297 };
298 var group = event.Group(FindError!void).init(loop);
299 errdefer group.cancelAll();
300 for (dyn_tests) |*dyn_test| {
301 try group.call(testNativeDynamicLinker, self, loop, dyn_test);
302 }
303 try await (async group.wait() catch unreachable);
304 for (dyn_tests) |*dyn_test| {
305 if (dyn_test.result) |result| {
306 self.dynamic_linker_path = result;
307 return;
308 }
309 }
185310 }
186311
187 async fn findNativeStaticLibDir(self: *LibCInstallation, loop: *event.Loop) Error!void {
188 self.static_lib_dir = try await (async ccPrintFileNameDir(loop, "crtbegin.o") catch unreachable);
312 const DynTest = struct {
313 name: []const u8,
314 result: ?[]const u8,
315 };
316
317 async fn testNativeDynamicLinker(self: *LibCInstallation, loop: *event.Loop, dyn_test: *DynTest) FindError!void {
318 if (await (async ccPrintFileName(loop, dyn_test.name, false) catch unreachable)) |result| {
319 dyn_test.result = result;
320 return;
321 } else |err| switch (err) {
322 error.CCompilerCannotFindCRuntime => return,
323 else => return err,
324 }
189325 }
190326
191 async fn findNativeMsvcLibDir(self: *LibCInstallation, loop: *event.Loop) Error!void {
327 async fn findNativeMsvcLibDir(self: *LibCInstallation, loop: *event.Loop) FindError!void {
192328 @panic("TODO");
193329 }
194330
195 async fn findNativeKernel32LibDir(self: *LibCInstallation, loop: *event.Loop) Error!void {
331 async fn findNativeKernel32LibDir(self: *LibCInstallation, loop: *event.Loop) FindError!void {
196332 @panic("TODO");
197333 }
334
335 fn initEmpty(self: *LibCInstallation) void {
336 self.* = LibCInstallation{
337 .include_dir = ([*]const u8)(undefined)[0..0],
338 .lib_dir = null,
339 .static_lib_dir = null,
340 .msvc_lib_dir = null,
341 .kernel32_lib_dir = null,
342 .dynamic_linker_path = null,
343 };
344 }
198345};
199346
200347/// caller owns returned memory
201async fn ccPrintFileNameDir(loop: *event.Loop, o_file: []const u8) ![]u8 {
348async fn ccPrintFileName(loop: *event.Loop, o_file: []const u8, want_dirname: bool) ![]u8 {
202349 const cc_exe = std.os.getEnvPosix("CC") orelse "cc";
203350 const arg1 = try std.fmt.allocPrint(loop.allocator, "-print-file-name={}", o_file);
204351 defer loop.allocator.free(arg1);
205352 const argv = []const []const u8{ cc_exe, arg1 };
206353
207 // TODO evented I/O
354 // TODO This simulates evented I/O for the child process exec
355 await (async loop.yield() catch unreachable);
208356 const errorable_result = std.os.ChildProcess.exec(loop.allocator, argv, null, null, 1024 * 1024);
209357 const exec_result = if (std.debug.runtime_safety) blk: {
210358 break :blk errorable_result catch unreachable;
......@@ -230,5 +378,9 @@ async fn ccPrintFileNameDir(loop: *event.Loop, o_file: []const u8) ![]u8 {
230378 const line = it.next() orelse return error.CCompilerCannotFindCRuntime;
231379 const dirname = std.os.path.dirname(line) orelse return error.CCompilerCannotFindCRuntime;
232380
233 return std.mem.dupe(loop.allocator, u8, dirname);
381 if (want_dirname) {
382 return std.mem.dupe(loop.allocator, u8, dirname);
383 } else {
384 return std.mem.dupe(loop.allocator, u8, line);
385 }
234386}
src-self-hosted/link.zig+113-84
......@@ -3,6 +3,8 @@ const c = @import("c.zig");
33const builtin = @import("builtin");
44const ObjectFormat = builtin.ObjectFormat;
55const Compilation = @import("compilation.zig").Compilation;
6const Target = @import("target.zig").Target;
7const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
68
79const Context = struct {
810 comp: *Compilation,
......@@ -12,9 +14,12 @@ const Context = struct {
1214
1315 link_err: error{OutOfMemory}!void,
1416 link_msg: std.Buffer,
17
18 libc: *LibCInstallation,
19 out_file_path: std.Buffer,
1520};
1621
17pub fn link(comp: *Compilation) !void {
22pub async fn link(comp: *Compilation) !void {
1823 var ctx = Context{
1924 .comp = comp,
2025 .arena = std.heap.ArenaAllocator.init(comp.gpa()),
......@@ -22,15 +27,45 @@ pub fn link(comp: *Compilation) !void {
2227 .link_in_crt = comp.haveLibC() and comp.kind == Compilation.Kind.Exe,
2328 .link_err = {},
2429 .link_msg = undefined,
30 .libc = undefined,
31 .out_file_path = undefined,
2532 };
2633 defer ctx.arena.deinit();
2734 ctx.args = std.ArrayList([*]const u8).init(&ctx.arena.allocator);
2835 ctx.link_msg = std.Buffer.initNull(&ctx.arena.allocator);
2936
37 if (comp.link_out_file) |out_file| {
38 ctx.out_file_path = try std.Buffer.init(&ctx.arena.allocator, out_file);
39 } else {
40 ctx.out_file_path = try std.Buffer.init(&ctx.arena.allocator, comp.name.toSliceConst());
41 switch (comp.kind) {
42 Compilation.Kind.Exe => {
43 try ctx.out_file_path.append(comp.target.exeFileExt());
44 },
45 Compilation.Kind.Lib => {
46 try ctx.out_file_path.append(comp.target.libFileExt(comp.is_static));
47 },
48 Compilation.Kind.Obj => {
49 try ctx.out_file_path.append(comp.target.objFileExt());
50 },
51 }
52 }
53
3054 // even though we're calling LLD as a library it thinks the first
3155 // argument is its own exe name
3256 try ctx.args.append(c"lld");
3357
58 if (comp.haveLibC()) {
59 ctx.libc = ctx.comp.override_libc orelse blk: {
60 switch (comp.target) {
61 Target.Native => {
62 break :blk (await (async comp.event_loop_local.getNativeLibC() catch unreachable)) catch return error.LibCRequiredButNotProvidedOrFound;
63 },
64 else => return error.LibCRequiredButNotProvidedOrFound,
65 }
66 };
67 }
68
3469 try constructLinkerArgs(&ctx);
3570
3671 if (comp.verbose_link) {
......@@ -43,6 +78,7 @@ pub fn link(comp: *Compilation) !void {
4378
4479 const extern_ofmt = toExternObjectFormatType(comp.target.getObjectFormat());
4580 const args_slice = ctx.args.toSlice();
81 // Not evented I/O. LLD does its own multithreading internally.
4682 if (!ZigLLDLink(extern_ofmt, args_slice.ptr, args_slice.len, linkDiagCallback, @ptrCast(*c_void, &ctx))) {
4783 if (!ctx.link_msg.isNull()) {
4884 // TODO capture these messages and pass them through the system, reporting them through the
......@@ -95,10 +131,7 @@ fn constructLinkerArgs(ctx: *Context) !void {
95131}
96132
97133fn constructLinkerArgsElf(ctx: *Context) !void {
98 //if (g->libc_link_lib != nullptr) {
99 // find_libc_lib_path(g);
100 //}
101
134 // TODO commented out code in this function
102135 //if (g->linker_script) {
103136 // lj->args.append("-T");
104137 // lj->args.append(g->linker_script);
......@@ -107,7 +140,7 @@ fn constructLinkerArgsElf(ctx: *Context) !void {
107140 //if (g->no_rosegment_workaround) {
108141 // lj->args.append("--no-rosegment");
109142 //}
110 //lj->args.append("--gc-sections");
143 try ctx.args.append(c"--gc-sections");
111144
112145 //lj->args.append("-m");
113146 //lj->args.append(getLDMOption(&g->zig_target));
......@@ -115,14 +148,13 @@ fn constructLinkerArgsElf(ctx: *Context) !void {
115148 //bool is_lib = g->out_type == OutTypeLib;
116149 //bool shared = !g->is_static && is_lib;
117150 //Buf *soname = nullptr;
118 //if (g->is_static) {
119 // if (g->zig_target.arch.arch == ZigLLVM_arm || g->zig_target.arch.arch == ZigLLVM_armeb ||
120 // g->zig_target.arch.arch == ZigLLVM_thumb || g->zig_target.arch.arch == ZigLLVM_thumbeb)
121 // {
122 // lj->args.append("-Bstatic");
123 // } else {
124 // lj->args.append("-static");
125 // }
151 if (ctx.comp.is_static) {
152 if (ctx.comp.target.isArmOrThumb()) {
153 try ctx.args.append(c"-Bstatic");
154 } else {
155 try ctx.args.append(c"-static");
156 }
157 }
126158 //} else if (shared) {
127159 // lj->args.append("-shared");
128160
......@@ -133,23 +165,16 @@ fn constructLinkerArgsElf(ctx: *Context) !void {
133165 // soname = buf_sprintf("lib%s.so.%" ZIG_PRI_usize "", buf_ptr(g->root_out_name), g->version_major);
134166 //}
135167
136 //lj->args.append("-o");
137 //lj->args.append(buf_ptr(&lj->out_file));
168 try ctx.args.append(c"-o");
169 try ctx.args.append(ctx.out_file_path.ptr());
138170
139 //if (lj->link_in_crt) {
140 // const char *crt1o;
141 // const char *crtbegino;
142 // if (g->is_static) {
143 // crt1o = "crt1.o";
144 // crtbegino = "crtbeginT.o";
145 // } else {
146 // crt1o = "Scrt1.o";
147 // crtbegino = "crtbegin.o";
148 // }
149 // lj->args.append(get_libc_file(g, crt1o));
150 // lj->args.append(get_libc_file(g, "crti.o"));
151 // lj->args.append(get_libc_static_file(g, crtbegino));
152 //}
171 if (ctx.link_in_crt) {
172 const crt1o = if (ctx.comp.is_static) "crt1.o" else "Scrt1.o";
173 const crtbegino = if (ctx.comp.is_static) "crtbeginT.o" else "crtbegin.o";
174 try addPathJoin(ctx, ctx.libc.lib_dir.?, crt1o);
175 try addPathJoin(ctx, ctx.libc.lib_dir.?, "crti.o");
176 try addPathJoin(ctx, ctx.libc.static_lib_dir.?, crtbegino);
177 }
153178
154179 //for (size_t i = 0; i < g->rpath_list.length; i += 1) {
155180 // Buf *rpath = g->rpath_list.at(i);
......@@ -182,25 +207,23 @@ fn constructLinkerArgsElf(ctx: *Context) !void {
182207 // lj->args.append(lib_dir);
183208 //}
184209
185 //if (g->libc_link_lib != nullptr) {
186 // lj->args.append("-L");
187 // lj->args.append(buf_ptr(g->libc_lib_dir));
188
189 // lj->args.append("-L");
190 // lj->args.append(buf_ptr(g->libc_static_lib_dir));
191 //}
192
193 //if (!g->is_static) {
194 // if (g->dynamic_linker != nullptr) {
195 // assert(buf_len(g->dynamic_linker) != 0);
196 // lj->args.append("-dynamic-linker");
197 // lj->args.append(buf_ptr(g->dynamic_linker));
198 // } else {
199 // Buf *resolved_dynamic_linker = get_dynamic_linker_path(g);
200 // lj->args.append("-dynamic-linker");
201 // lj->args.append(buf_ptr(resolved_dynamic_linker));
202 // }
203 //}
210 if (ctx.comp.haveLibC()) {
211 try ctx.args.append(c"-L");
212 try ctx.args.append((try std.cstr.addNullByte(&ctx.arena.allocator, ctx.libc.lib_dir.?)).ptr);
213
214 try ctx.args.append(c"-L");
215 try ctx.args.append((try std.cstr.addNullByte(&ctx.arena.allocator, ctx.libc.static_lib_dir.?)).ptr);
216
217 if (!ctx.comp.is_static) {
218 const dl = blk: {
219 if (ctx.libc.dynamic_linker_path) |dl| break :blk dl;
220 if (ctx.comp.target.getDynamicLinkerPath()) |dl| break :blk dl;
221 return error.LibCMissingDynamicLinker;
222 };
223 try ctx.args.append(c"-dynamic-linker");
224 try ctx.args.append((try std.cstr.addNullByte(&ctx.arena.allocator, dl)).ptr);
225 }
226 }
204227
205228 //if (shared) {
206229 // lj->args.append("-soname");
......@@ -241,45 +264,51 @@ fn constructLinkerArgsElf(ctx: *Context) !void {
241264 // lj->args.append(buf_ptr(arg));
242265 //}
243266
244 //// libc dep
245 //if (g->libc_link_lib != nullptr) {
246 // if (g->is_static) {
247 // lj->args.append("--start-group");
248 // lj->args.append("-lgcc");
249 // lj->args.append("-lgcc_eh");
250 // lj->args.append("-lc");
251 // lj->args.append("-lm");
252 // lj->args.append("--end-group");
253 // } else {
254 // lj->args.append("-lgcc");
255 // lj->args.append("--as-needed");
256 // lj->args.append("-lgcc_s");
257 // lj->args.append("--no-as-needed");
258 // lj->args.append("-lc");
259 // lj->args.append("-lm");
260 // lj->args.append("-lgcc");
261 // lj->args.append("--as-needed");
262 // lj->args.append("-lgcc_s");
263 // lj->args.append("--no-as-needed");
264 // }
265 //}
267 // libc dep
268 if (ctx.comp.haveLibC()) {
269 if (ctx.comp.is_static) {
270 try ctx.args.append(c"--start-group");
271 try ctx.args.append(c"-lgcc");
272 try ctx.args.append(c"-lgcc_eh");
273 try ctx.args.append(c"-lc");
274 try ctx.args.append(c"-lm");
275 try ctx.args.append(c"--end-group");
276 } else {
277 try ctx.args.append(c"-lgcc");
278 try ctx.args.append(c"--as-needed");
279 try ctx.args.append(c"-lgcc_s");
280 try ctx.args.append(c"--no-as-needed");
281 try ctx.args.append(c"-lc");
282 try ctx.args.append(c"-lm");
283 try ctx.args.append(c"-lgcc");
284 try ctx.args.append(c"--as-needed");
285 try ctx.args.append(c"-lgcc_s");
286 try ctx.args.append(c"--no-as-needed");
287 }
288 }
266289
267 //// crt end
268 //if (lj->link_in_crt) {
269 // lj->args.append(get_libc_static_file(g, "crtend.o"));
270 // lj->args.append(get_libc_file(g, "crtn.o"));
271 //}
290 // crt end
291 if (ctx.link_in_crt) {
292 try addPathJoin(ctx, ctx.libc.static_lib_dir.?, "crtend.o");
293 try addPathJoin(ctx, ctx.libc.lib_dir.?, "crtn.o");
294 }
272295
273 //if (!g->is_native_target) {
274 // lj->args.append("--allow-shlib-undefined");
275 //}
296 if (ctx.comp.target != Target.Native) {
297 try ctx.args.append(c"--allow-shlib-undefined");
298 }
276299
277 //if (g->zig_target.os == OsZen) {
278 // lj->args.append("-e");
279 // lj->args.append("_start");
300 if (ctx.comp.target.getOs() == builtin.Os.zen) {
301 try ctx.args.append(c"-e");
302 try ctx.args.append(c"_start");
280303
281 // lj->args.append("--image-base=0x10000000");
282 //}
304 try ctx.args.append(c"--image-base=0x10000000");
305 }
306}
307
308fn addPathJoin(ctx: *Context, dirname: []const u8, basename: []const u8) !void {
309 const full_path = try std.os.path.join(&ctx.arena.allocator, dirname, basename);
310 const full_path_with_null = try std.cstr.addNullByte(&ctx.arena.allocator, full_path);
311 try ctx.args.append(full_path_with_null.ptr);
283312}
284313
285314fn constructLinkerArgsCoff(ctx: *Context) void {
src-self-hosted/main.zig+53-34
......@@ -18,6 +18,7 @@ const EventLoopLocal = @import("compilation.zig").EventLoopLocal;
1818const Compilation = @import("compilation.zig").Compilation;
1919const Target = @import("target.zig").Target;
2020const errmsg = @import("errmsg.zig");
21const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
2122
2223var stderr_file: os.File = undefined;
2324var stderr: *io.OutStream(io.FileOutStream.Error) = undefined;
......@@ -28,14 +29,14 @@ const usage =
2829 \\
2930 \\Commands:
3031 \\
31 \\ build-exe [source] Create executable from source or object files
32 \\ build-lib [source] Create library from source or object files
33 \\ build-obj [source] Create object from source or assembly
34 \\ find-libc Show native libc installation paths
35 \\ fmt [source] Parse file and render in canonical zig format
36 \\ targets List available compilation targets
37 \\ version Print version number and exit
38 \\ zen Print zen of zig and exit
32 \\ build-exe [source] Create executable from source or object files
33 \\ build-lib [source] Create library from source or object files
34 \\ build-obj [source] Create object from source or assembly
35 \\ fmt [source] Parse file and render in canonical zig format
36 \\ libc [paths_file] Display native libc paths file or validate one
37 \\ targets List available compilation targets
38 \\ version Print version number and exit
39 \\ zen Print zen of zig and exit
3940 \\
4041 \\
4142;
......@@ -82,14 +83,14 @@ pub fn main() !void {
8283 .name = "build-obj",
8384 .exec = cmdBuildObj,
8485 },
85 Command{
86 .name = "find-libc",
87 .exec = cmdFindLibc,
88 },
8986 Command{
9087 .name = "fmt",
9188 .exec = cmdFmt,
9289 },
90 Command{
91 .name = "libc",
92 .exec = cmdLibC,
93 },
9394 Command{
9495 .name = "targets",
9596 .exec = cmdTargets,
......@@ -135,6 +136,7 @@ const usage_build_generic =
135136 \\ --color [auto|off|on] Enable or disable colored error messages
136137 \\
137138 \\Compile Options:
139 \\ --libc [file] Provide a file which specifies libc paths
138140 \\ --assembly [source] Add assembly file to build
139141 \\ --cache-dir [path] Override the cache directory
140142 \\ --emit [filetype] Emit a specific file format as compilation output
......@@ -167,7 +169,6 @@ const usage_build_generic =
167169 \\
168170 \\Link Options:
169171 \\ --ar-path [path] Set the path to ar
170 \\ --dynamic-linker [path] Set the path to ld.so
171172 \\ --each-lib-rpath Add rpath for each used dynamic library
172173 \\ --library [lib] Link against lib
173174 \\ --forbid-library [lib] Make it an error to link against lib
......@@ -210,6 +211,7 @@ const args_build_generic = []Flag{
210211 "llvm-ir",
211212 }),
212213 Flag.Bool("--enable-timing-info"),
214 Flag.Arg1("--libc"),
213215 Flag.Arg1("--name"),
214216 Flag.Arg1("--output"),
215217 Flag.Arg1("--output-h"),
......@@ -233,7 +235,6 @@ const args_build_generic = []Flag{
233235 Flag.Arg1("-mllvm"),
234236
235237 Flag.Arg1("--ar-path"),
236 Flag.Arg1("--dynamic-linker"),
237238 Flag.Bool("--each-lib-rpath"),
238239 Flag.ArgMergeN("--library", 1),
239240 Flag.ArgMergeN("--forbid-library", 1),
......@@ -382,6 +383,8 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co
382383 const zig_lib_dir = introspect.resolveZigLibDir(allocator) catch os.exit(1);
383384 defer allocator.free(zig_lib_dir);
384385
386 var override_libc: LibCInstallation = undefined;
387
385388 var loop: event.Loop = undefined;
386389 try loop.initMultiThreaded(allocator);
387390 defer loop.deinit();
......@@ -402,6 +405,15 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co
402405 );
403406 defer comp.destroy();
404407
408 if (flags.single("libc")) |libc_path| {
409 parseLibcPaths(loop.allocator, &override_libc, libc_path);
410 comp.override_libc = &override_libc;
411 }
412
413 for (flags.many("library")) |lib| {
414 _ = try comp.addLinkLib(lib, true);
415 }
416
405417 comp.version_major = try std.fmt.parseUnsigned(u32, flags.single("ver-major") orelse "0", 10);
406418 comp.version_minor = try std.fmt.parseUnsigned(u32, flags.single("ver-minor") orelse "0", 10);
407419 comp.version_patch = try std.fmt.parseUnsigned(u32, flags.single("ver-patch") orelse "0", 10);
......@@ -425,10 +437,6 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co
425437
426438 comp.strip = flags.present("strip");
427439
428 if (flags.single("dynamic-linker")) |dynamic_linker| {
429 comp.dynamic_linker = dynamic_linker;
430 }
431
432440 comp.verbose_tokenize = flags.present("verbose-tokenize");
433441 comp.verbose_ast_tree = flags.present("verbose-ast-tree");
434442 comp.verbose_ast_fmt = flags.present("verbose-ast-fmt");
......@@ -479,7 +487,6 @@ async fn processBuildEvents(comp: *Compilation, color: errmsg.Color) void {
479487
480488 switch (build_event) {
481489 Compilation.Event.Ok => {
482 std.debug.warn("Build succeeded\n");
483490 return;
484491 },
485492 Compilation.Event.Error => |err| {
......@@ -559,7 +566,32 @@ const Fmt = struct {
559566 }
560567};
561568
562fn cmdFindLibc(allocator: *Allocator, args: []const []const u8) !void {
569fn parseLibcPaths(allocator: *Allocator, libc: *LibCInstallation, libc_paths_file: []const u8) void {
570 libc.parse(allocator, libc_paths_file, stderr) catch |err| {
571 stderr.print(
572 "Unable to parse libc path file '{}': {}.\n" ++
573 "Try running `zig libc` to see an example for the native target.\n",
574 libc_paths_file,
575 @errorName(err),
576 ) catch os.exit(1);
577 os.exit(1);
578 };
579}
580
581fn cmdLibC(allocator: *Allocator, args: []const []const u8) !void {
582 switch (args.len) {
583 0 => {},
584 1 => {
585 var libc_installation: LibCInstallation = undefined;
586 parseLibcPaths(allocator, &libc_installation, args[0]);
587 return;
588 },
589 else => {
590 try stderr.print("unexpected extra parameter: {}\n", args[1]);
591 os.exit(1);
592 },
593 }
594
563595 var loop: event.Loop = undefined;
564596 try loop.initMultiThreaded(allocator);
565597 defer loop.deinit();
......@@ -578,20 +610,7 @@ async fn findLibCAsync(event_loop_local: *EventLoopLocal) void {
578610 stderr.print("unable to find libc: {}\n", @errorName(err)) catch os.exit(1);
579611 os.exit(1);
580612 };
581 stderr.print(
582 \\include_dir={}
583 \\lib_dir={}
584 \\static_lib_dir={}
585 \\msvc_lib_dir={}
586 \\kernel32_lib_dir={}
587 \\
588 ,
589 libc.include_dir,
590 libc.lib_dir,
591 libc.static_lib_dir orelse "",
592 libc.msvc_lib_dir orelse "",
593 libc.kernel32_lib_dir orelse "",
594 ) catch os.exit(1);
613 libc.render(stdout) catch os.exit(1);
595614}
596615
597616fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {
src-self-hosted/target.zig+315-1
......@@ -2,6 +2,12 @@ const std = @import("std");
22const builtin = @import("builtin");
33const llvm = @import("llvm.zig");
44
5pub const FloatAbi = enum {
6 Hard,
7 Soft,
8 SoftFp,
9};
10
511pub const Target = union(enum) {
612 Native,
713 Cross: Cross,
......@@ -13,7 +19,7 @@ pub const Target = union(enum) {
1319 object_format: builtin.ObjectFormat,
1420 };
1521
16 pub fn oFileExt(self: Target) []const u8 {
22 pub fn objFileExt(self: Target) []const u8 {
1723 return switch (self.getObjectFormat()) {
1824 builtin.ObjectFormat.coff => ".obj",
1925 else => ".o",
......@@ -27,6 +33,13 @@ pub const Target = union(enum) {
2733 };
2834 }
2935
36 pub fn libFileExt(self: Target, is_static: bool) []const u8 {
37 return switch (self.getOs()) {
38 builtin.Os.windows => if (is_static) ".lib" else ".dll",
39 else => if (is_static) ".a" else ".so",
40 };
41 }
42
3043 pub fn getOs(self: Target) builtin.Os {
3144 return switch (self) {
3245 Target.Native => builtin.os,
......@@ -76,6 +89,56 @@ pub const Target = union(enum) {
7689 };
7790 }
7891
92 /// TODO expose the arch and subarch separately
93 pub fn isArmOrThumb(self: Target) bool {
94 return switch (self.getArch()) {
95 builtin.Arch.armv8_3a,
96 builtin.Arch.armv8_2a,
97 builtin.Arch.armv8_1a,
98 builtin.Arch.armv8,
99 builtin.Arch.armv8r,
100 builtin.Arch.armv8m_baseline,
101 builtin.Arch.armv8m_mainline,
102 builtin.Arch.armv7,
103 builtin.Arch.armv7em,
104 builtin.Arch.armv7m,
105 builtin.Arch.armv7s,
106 builtin.Arch.armv7k,
107 builtin.Arch.armv7ve,
108 builtin.Arch.armv6,
109 builtin.Arch.armv6m,
110 builtin.Arch.armv6k,
111 builtin.Arch.armv6t2,
112 builtin.Arch.armv5,
113 builtin.Arch.armv5te,
114 builtin.Arch.armv4t,
115 builtin.Arch.armebv8_3a,
116 builtin.Arch.armebv8_2a,
117 builtin.Arch.armebv8_1a,
118 builtin.Arch.armebv8,
119 builtin.Arch.armebv8r,
120 builtin.Arch.armebv8m_baseline,
121 builtin.Arch.armebv8m_mainline,
122 builtin.Arch.armebv7,
123 builtin.Arch.armebv7em,
124 builtin.Arch.armebv7m,
125 builtin.Arch.armebv7s,
126 builtin.Arch.armebv7k,
127 builtin.Arch.armebv7ve,
128 builtin.Arch.armebv6,
129 builtin.Arch.armebv6m,
130 builtin.Arch.armebv6k,
131 builtin.Arch.armebv6t2,
132 builtin.Arch.armebv5,
133 builtin.Arch.armebv5te,
134 builtin.Arch.armebv4t,
135 builtin.Arch.thumb,
136 builtin.Arch.thumbeb,
137 => true,
138 else => false,
139 };
140 }
141
79142 pub fn initializeAll() void {
80143 llvm.InitializeAllTargets();
81144 llvm.InitializeAllTargetInfos();
......@@ -106,6 +169,257 @@ pub const Target = union(enum) {
106169 return result;
107170 }
108171
172 pub fn is64bit(self: Target) bool {
173 return self.getArchPtrBitWidth() == 64;
174 }
175
176 pub fn getArchPtrBitWidth(self: Target) u8 {
177 switch (self.getArch()) {
178 builtin.Arch.avr,
179 builtin.Arch.msp430,
180 => return 16,
181
182 builtin.Arch.arc,
183 builtin.Arch.armv8_3a,
184 builtin.Arch.armv8_2a,
185 builtin.Arch.armv8_1a,
186 builtin.Arch.armv8,
187 builtin.Arch.armv8r,
188 builtin.Arch.armv8m_baseline,
189 builtin.Arch.armv8m_mainline,
190 builtin.Arch.armv7,
191 builtin.Arch.armv7em,
192 builtin.Arch.armv7m,
193 builtin.Arch.armv7s,
194 builtin.Arch.armv7k,
195 builtin.Arch.armv7ve,
196 builtin.Arch.armv6,
197 builtin.Arch.armv6m,
198 builtin.Arch.armv6k,
199 builtin.Arch.armv6t2,
200 builtin.Arch.armv5,
201 builtin.Arch.armv5te,
202 builtin.Arch.armv4t,
203 builtin.Arch.armebv8_3a,
204 builtin.Arch.armebv8_2a,
205 builtin.Arch.armebv8_1a,
206 builtin.Arch.armebv8,
207 builtin.Arch.armebv8r,
208 builtin.Arch.armebv8m_baseline,
209 builtin.Arch.armebv8m_mainline,
210 builtin.Arch.armebv7,
211 builtin.Arch.armebv7em,
212 builtin.Arch.armebv7m,
213 builtin.Arch.armebv7s,
214 builtin.Arch.armebv7k,
215 builtin.Arch.armebv7ve,
216 builtin.Arch.armebv6,
217 builtin.Arch.armebv6m,
218 builtin.Arch.armebv6k,
219 builtin.Arch.armebv6t2,
220 builtin.Arch.armebv5,
221 builtin.Arch.armebv5te,
222 builtin.Arch.armebv4t,
223 builtin.Arch.hexagon,
224 builtin.Arch.le32,
225 builtin.Arch.mips,
226 builtin.Arch.mipsel,
227 builtin.Arch.nios2,
228 builtin.Arch.powerpc,
229 builtin.Arch.r600,
230 builtin.Arch.riscv32,
231 builtin.Arch.sparc,
232 builtin.Arch.sparcel,
233 builtin.Arch.tce,
234 builtin.Arch.tcele,
235 builtin.Arch.thumb,
236 builtin.Arch.thumbeb,
237 builtin.Arch.i386,
238 builtin.Arch.xcore,
239 builtin.Arch.nvptx,
240 builtin.Arch.amdil,
241 builtin.Arch.hsail,
242 builtin.Arch.spir,
243 builtin.Arch.kalimbav3,
244 builtin.Arch.kalimbav4,
245 builtin.Arch.kalimbav5,
246 builtin.Arch.shave,
247 builtin.Arch.lanai,
248 builtin.Arch.wasm32,
249 builtin.Arch.renderscript32,
250 => return 32,
251
252 builtin.Arch.aarch64,
253 builtin.Arch.aarch64_be,
254 builtin.Arch.mips64,
255 builtin.Arch.mips64el,
256 builtin.Arch.powerpc64,
257 builtin.Arch.powerpc64le,
258 builtin.Arch.riscv64,
259 builtin.Arch.x86_64,
260 builtin.Arch.nvptx64,
261 builtin.Arch.le64,
262 builtin.Arch.amdil64,
263 builtin.Arch.hsail64,
264 builtin.Arch.spir64,
265 builtin.Arch.wasm64,
266 builtin.Arch.renderscript64,
267 builtin.Arch.amdgcn,
268 builtin.Arch.bpfel,
269 builtin.Arch.bpfeb,
270 builtin.Arch.sparcv9,
271 builtin.Arch.s390x,
272 => return 64,
273 }
274 }
275
276 pub fn getFloatAbi(self: Target) FloatAbi {
277 return switch (self.getEnviron()) {
278 builtin.Environ.gnueabihf,
279 builtin.Environ.eabihf,
280 builtin.Environ.musleabihf,
281 => FloatAbi.Hard,
282 else => FloatAbi.Soft,
283 };
284 }
285
286 pub fn getDynamicLinkerPath(self: Target) ?[]const u8 {
287 const env = self.getEnviron();
288 const arch = self.getArch();
289 switch (env) {
290 builtin.Environ.android => {
291 if (self.is64bit()) {
292 return "/system/bin/linker64";
293 } else {
294 return "/system/bin/linker";
295 }
296 },
297 builtin.Environ.gnux32 => {
298 if (arch == builtin.Arch.x86_64) {
299 return "/libx32/ld-linux-x32.so.2";
300 }
301 },
302 builtin.Environ.musl,
303 builtin.Environ.musleabi,
304 builtin.Environ.musleabihf,
305 => {
306 if (arch == builtin.Arch.x86_64) {
307 return "/lib/ld-musl-x86_64.so.1";
308 }
309 },
310 else => {},
311 }
312 switch (arch) {
313 builtin.Arch.i386,
314 builtin.Arch.sparc,
315 builtin.Arch.sparcel,
316 => return "/lib/ld-linux.so.2",
317
318 builtin.Arch.aarch64 => return "/lib/ld-linux-aarch64.so.1",
319 builtin.Arch.aarch64_be => return "/lib/ld-linux-aarch64_be.so.1",
320
321 builtin.Arch.armv8_3a,
322 builtin.Arch.armv8_2a,
323 builtin.Arch.armv8_1a,
324 builtin.Arch.armv8,
325 builtin.Arch.armv8r,
326 builtin.Arch.armv8m_baseline,
327 builtin.Arch.armv8m_mainline,
328 builtin.Arch.armv7,
329 builtin.Arch.armv7em,
330 builtin.Arch.armv7m,
331 builtin.Arch.armv7s,
332 builtin.Arch.armv7k,
333 builtin.Arch.armv7ve,
334 builtin.Arch.armv6,
335 builtin.Arch.armv6m,
336 builtin.Arch.armv6k,
337 builtin.Arch.armv6t2,
338 builtin.Arch.armv5,
339 builtin.Arch.armv5te,
340 builtin.Arch.armv4t,
341 builtin.Arch.thumb,
342 => return switch (self.getFloatAbi()) {
343 FloatAbi.Hard => return "/lib/ld-linux-armhf.so.3",
344 else => return "/lib/ld-linux.so.3",
345 },
346
347 builtin.Arch.armebv8_3a,
348 builtin.Arch.armebv8_2a,
349 builtin.Arch.armebv8_1a,
350 builtin.Arch.armebv8,
351 builtin.Arch.armebv8r,
352 builtin.Arch.armebv8m_baseline,
353 builtin.Arch.armebv8m_mainline,
354 builtin.Arch.armebv7,
355 builtin.Arch.armebv7em,
356 builtin.Arch.armebv7m,
357 builtin.Arch.armebv7s,
358 builtin.Arch.armebv7k,
359 builtin.Arch.armebv7ve,
360 builtin.Arch.armebv6,
361 builtin.Arch.armebv6m,
362 builtin.Arch.armebv6k,
363 builtin.Arch.armebv6t2,
364 builtin.Arch.armebv5,
365 builtin.Arch.armebv5te,
366 builtin.Arch.armebv4t,
367 builtin.Arch.thumbeb,
368 => return switch (self.getFloatAbi()) {
369 FloatAbi.Hard => return "/lib/ld-linux-armhf.so.3",
370 else => return "/lib/ld-linux.so.3",
371 },
372
373 builtin.Arch.mips,
374 builtin.Arch.mipsel,
375 builtin.Arch.mips64,
376 builtin.Arch.mips64el,
377 => return null,
378
379 builtin.Arch.powerpc => return "/lib/ld.so.1",
380 builtin.Arch.powerpc64 => return "/lib64/ld64.so.2",
381 builtin.Arch.powerpc64le => return "/lib64/ld64.so.2",
382 builtin.Arch.s390x => return "/lib64/ld64.so.1",
383 builtin.Arch.sparcv9 => return "/lib64/ld-linux.so.2",
384 builtin.Arch.x86_64 => return "/lib64/ld-linux-x86-64.so.2",
385
386 builtin.Arch.arc,
387 builtin.Arch.avr,
388 builtin.Arch.bpfel,
389 builtin.Arch.bpfeb,
390 builtin.Arch.hexagon,
391 builtin.Arch.msp430,
392 builtin.Arch.nios2,
393 builtin.Arch.r600,
394 builtin.Arch.amdgcn,
395 builtin.Arch.riscv32,
396 builtin.Arch.riscv64,
397 builtin.Arch.tce,
398 builtin.Arch.tcele,
399 builtin.Arch.xcore,
400 builtin.Arch.nvptx,
401 builtin.Arch.nvptx64,
402 builtin.Arch.le32,
403 builtin.Arch.le64,
404 builtin.Arch.amdil,
405 builtin.Arch.amdil64,
406 builtin.Arch.hsail,
407 builtin.Arch.hsail64,
408 builtin.Arch.spir,
409 builtin.Arch.spir64,
410 builtin.Arch.kalimbav3,
411 builtin.Arch.kalimbav4,
412 builtin.Arch.kalimbav5,
413 builtin.Arch.shave,
414 builtin.Arch.lanai,
415 builtin.Arch.wasm32,
416 builtin.Arch.wasm64,
417 builtin.Arch.renderscript32,
418 builtin.Arch.renderscript64,
419 => return null,
420 }
421 }
422
109423 pub fn llvmTargetFromTriple(triple: std.Buffer) !llvm.TargetRef {
110424 var result: llvm.TargetRef = undefined;
111425 var err_msg: [*]u8 = undefined;
std/event/group.zig+2-2
......@@ -6,7 +6,7 @@ const AtomicRmwOp = builtin.AtomicRmwOp;
66const AtomicOrder = builtin.AtomicOrder;
77const assert = std.debug.assert;
88
9/// ReturnType should be `void` or `E!void`
9/// ReturnType must be `void` or `E!void`
1010pub fn Group(comptime ReturnType: type) type {
1111 return struct {
1212 coro_stack: Stack,
......@@ -39,7 +39,7 @@ pub fn Group(comptime ReturnType: type) type {
3939 }
4040
4141 /// This is equivalent to an async call, but the async function is added to the group, instead
42 /// of returning a promise. func must be async and have return type void.
42 /// of returning a promise. func must be async and have return type ReturnType.
4343 /// Thread-safe.
4444 pub fn call(self: *Self, comptime func: var, args: ...) (error{OutOfMemory}!void) {
4545 const S = struct {
std/event/loop.zig+1-1
......@@ -444,7 +444,7 @@ pub const Loop = struct {
444444 .next = undefined,
445445 .data = p,
446446 };
447 loop.onNextTick(&my_tick_node);
447 self.onNextTick(&my_tick_node);
448448 }
449449 }
450450