authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-11-30 16:40:25-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-11-30 16:50:56-07:00
log791e38da8c416b62e4e30f4c9cb44fd6f26442a5
tree97bc088985627d86d3315821fc47d7c7ff0e17e5
parent1a61a9d4bf37183282de8a09431ed1baaf049999

Merge branch 'alexnask-bundle_compiler_rt' into master

Closes #7013 Closes #6817

5 files changed, 104 insertions(+), 33 deletions(-)

lib/std/build.zig+7-4
...@@ -1216,7 +1216,7 @@ pub const LibExeObjStep = struct {...@@ -1216,7 +1216,7 @@ pub const LibExeObjStep = struct {
1216 emit_bin: bool = true,1216 emit_bin: bool = true,
1217 emit_docs: bool = false,1217 emit_docs: bool = false,
1218 emit_h: bool = false,1218 emit_h: bool = false,
1219 bundle_compiler_rt: bool,1219 bundle_compiler_rt: ?bool = null,
1220 disable_stack_probing: bool,1220 disable_stack_probing: bool,
1221 disable_sanitize_c: bool,1221 disable_sanitize_c: bool,
1222 rdynamic: bool,1222 rdynamic: bool,
...@@ -1392,7 +1392,6 @@ pub const LibExeObjStep = struct {...@@ -1392,7 +1392,6 @@ pub const LibExeObjStep = struct {
1392 .exec_cmd_args = null,1392 .exec_cmd_args = null,
1393 .name_prefix = "",1393 .name_prefix = "",
1394 .filter = null,1394 .filter = null,
1395 .bundle_compiler_rt = false,
1396 .disable_stack_probing = false,1395 .disable_stack_probing = false,
1397 .disable_sanitize_c = false,1396 .disable_sanitize_c = false,
1398 .rdynamic = false,1397 .rdynamic = false,
...@@ -2117,8 +2116,12 @@ pub const LibExeObjStep = struct {...@@ -2117,8 +2116,12 @@ pub const LibExeObjStep = struct {
2117 if (self.is_dynamic) {2116 if (self.is_dynamic) {
2118 try zig_args.append("-dynamic");2117 try zig_args.append("-dynamic");
2119 }2118 }
2120 if (self.bundle_compiler_rt) {2119 if (self.bundle_compiler_rt) |x| {
2121 try zig_args.append("--bundle-compiler-rt");2120 if (x) {
2121 try zig_args.append("-fcompiler-rt");
2122 } else {
2123 try zig_args.append("-fno-compiler-rt");
2124 }
2122 }2125 }
2123 if (self.disable_stack_probing) {2126 if (self.disable_stack_probing) {
2124 try zig_args.append("-fno-stack-check");2127 try zig_args.append("-fno-stack-check");
src/Compilation.zig+57-20
...@@ -93,6 +93,9 @@ libc_static_lib: ?CRTFile = null,...@@ -93,6 +93,9 @@ libc_static_lib: ?CRTFile = null,
93/// Populated when we build the libcompiler_rt static library. A Job to build this is placed in the queue93/// Populated when we build the libcompiler_rt static library. A Job to build this is placed in the queue
94/// and resolved before calling linker.flush().94/// and resolved before calling linker.flush().
95compiler_rt_static_lib: ?CRTFile = null,95compiler_rt_static_lib: ?CRTFile = null,
96/// Populated when we build the compiler_rt_obj object. A Job to build this is placed in the queue
97/// and resolved before calling linker.flush().
98compiler_rt_obj: ?CRTFile = null,
9699
97glibc_so_files: ?glibc.BuiltSharedObjects = null,100glibc_so_files: ?glibc.BuiltSharedObjects = null,
98101
...@@ -164,8 +167,8 @@ const Job = union(enum) {...@@ -164,8 +167,8 @@ const Job = union(enum) {
164 libcxx: void,167 libcxx: void,
165 libcxxabi: void,168 libcxxabi: void,
166 libssp: void,169 libssp: void,
167 /// needed when producing a dynamic library or executable170 compiler_rt_lib: void,
168 libcompiler_rt: void,171 compiler_rt_obj: void,
169 /// needed when not linking libc and using LLVM for code generation because it generates172 /// needed when not linking libc and using LLVM for code generation because it generates
170 /// calls to, for example, memcpy and memset.173 /// calls to, for example, memcpy and memset.
171 zig_libc: void,174 zig_libc: void,
...@@ -346,6 +349,7 @@ pub const InitOptions = struct {...@@ -346,6 +349,7 @@ pub const InitOptions = struct {
346 want_sanitize_c: ?bool = null,349 want_sanitize_c: ?bool = null,
347 want_stack_check: ?bool = null,350 want_stack_check: ?bool = null,
348 want_valgrind: ?bool = null,351 want_valgrind: ?bool = null,
352 want_compiler_rt: ?bool = null,
349 use_llvm: ?bool = null,353 use_llvm: ?bool = null,
350 use_lld: ?bool = null,354 use_lld: ?bool = null,
351 use_clang: ?bool = null,355 use_clang: ?bool = null,
...@@ -405,6 +409,9 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -405,6 +409,9 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
405 .Lib => is_dyn_lib,409 .Lib => is_dyn_lib,
406 .Exe => true,410 .Exe => true,
407 };411 };
412 const needs_c_symbols = !options.is_compiler_rt_or_libc and
413 (is_exe_or_dyn_lib or (options.target.isWasm() and options.output_mode != .Obj));
414
408 const comp: *Compilation = comp: {415 const comp: *Compilation = comp: {
409 // For allocations that have the same lifetime as Compilation. This arena is used only during this416 // For allocations that have the same lifetime as Compilation. This arena is used only during this
410 // initialization and then is freed in deinit().417 // initialization and then is freed in deinit().
...@@ -568,6 +575,8 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -568,6 +575,8 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
568 break :b options.want_valgrind orelse (options.optimize_mode == .Debug);575 break :b options.want_valgrind orelse (options.optimize_mode == .Debug);
569 };576 };
570577
578 const include_compiler_rt = options.want_compiler_rt orelse needs_c_symbols;
579
571 const single_threaded = options.single_threaded or target_util.isSingleThreaded(options.target);580 const single_threaded = options.single_threaded or target_util.isSingleThreaded(options.target);
572581
573 const llvm_cpu_features: ?[*:0]const u8 = if (build_options.have_llvm and use_llvm) blk: {582 const llvm_cpu_features: ?[*:0]const u8 = if (build_options.have_llvm and use_llvm) blk: {
...@@ -803,6 +812,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -803,6 +812,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
803 .z_defs = options.linker_z_defs,812 .z_defs = options.linker_z_defs,
804 .stack_size_override = options.stack_size_override,813 .stack_size_override = options.stack_size_override,
805 .image_base_override = options.image_base_override,814 .image_base_override = options.image_base_override,
815 .include_compiler_rt = include_compiler_rt,
806 .linker_script = options.linker_script,816 .linker_script = options.linker_script,
807 .version_script = options.version_script,817 .version_script = options.version_script,
808 .gc_sections = options.linker_gc_sections,818 .gc_sections = options.linker_gc_sections,
...@@ -947,16 +957,31 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -947,16 +957,31 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
947 try comp.work_queue.writeItem(.libcxxabi);957 try comp.work_queue.writeItem(.libcxxabi);
948 }958 }
949959
950 const needs_compiler_rt_and_c = is_exe_or_dyn_lib or960 // The `is_stage1` condition is here only because stage2 cannot yet build compiler-rt.
951 (comp.getTarget().isWasm() and comp.bin_file.options.output_mode != .Obj);961 // Once it is capable this condition should be removed.
952 if (needs_compiler_rt_and_c and build_options.is_stage1) {962 if (build_options.is_stage1) {
953 try comp.work_queue.writeItem(.{ .libcompiler_rt = {} });963 if (comp.bin_file.options.include_compiler_rt) {
954 // MinGW provides no libssp, use our own implementation.964 if (is_exe_or_dyn_lib) {
955 if (comp.getTarget().isMinGW()) {965 try comp.work_queue.writeItem(.{ .compiler_rt_lib = {} });
956 try comp.work_queue.writeItem(.{ .libssp = {} });966 } else {
967 try comp.work_queue.writeItem(.{ .compiler_rt_obj = {} });
968 if (comp.bin_file.options.object_format != .elf) {
969 // For ELF we can rely on using -r to link multiple objects together into one,
970 // but to truly support `build-obj -fcompiler-rt` will require virtually
971 // injecting `_ = @import("compiler_rt.zig")` into the root source file of
972 // the compilation.
973 fatal("Embedding compiler-rt into non-ELF objects is not yet implemented.", .{});
974 }
975 }
957 }976 }
958 if (!comp.bin_file.options.link_libc) {977 if (needs_c_symbols) {
959 try comp.work_queue.writeItem(.{ .zig_libc = {} });978 // MinGW provides no libssp, use our own implementation.
979 if (comp.getTarget().isMinGW()) {
980 try comp.work_queue.writeItem(.{ .libssp = {} });
981 }
982 if (!comp.bin_file.options.link_libc) {
983 try comp.work_queue.writeItem(.{ .zig_libc = {} });
984 }
960 }985 }
961 }986 }
962 }987 }
...@@ -1354,20 +1379,26 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor...@@ -1354,20 +1379,26 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor
1354 fatal("unable to build libcxxabi: {}", .{@errorName(err)});1379 fatal("unable to build libcxxabi: {}", .{@errorName(err)});
1355 };1380 };
1356 },1381 },
1357 .libcompiler_rt => {1382 .compiler_rt_lib => {
1358 self.buildStaticLibFromZig("compiler_rt.zig", &self.compiler_rt_static_lib) catch |err| {1383 self.buildOutputFromZig("compiler_rt.zig", .Lib, &self.compiler_rt_static_lib) catch |err| {
1359 // TODO Expose this as a normal compile error rather than crashing here.1384 // TODO Expose this as a normal compile error rather than crashing here.
1360 fatal("unable to build compiler_rt: {}", .{@errorName(err)});1385 fatal("unable to build compiler_rt: {s}", .{@errorName(err)});
1386 };
1387 },
1388 .compiler_rt_obj => {
1389 self.buildOutputFromZig("compiler_rt.zig", .Obj, &self.compiler_rt_obj) catch |err| {
1390 // TODO Expose this as a normal compile error rather than crashing here.
1391 fatal("unable to build compiler_rt: {s}", .{@errorName(err)});
1361 };1392 };
1362 },1393 },
1363 .libssp => {1394 .libssp => {
1364 self.buildStaticLibFromZig("ssp.zig", &self.libssp_static_lib) catch |err| {1395 self.buildOutputFromZig("ssp.zig", .Lib, &self.libssp_static_lib) catch |err| {
1365 // TODO Expose this as a normal compile error rather than crashing here.1396 // TODO Expose this as a normal compile error rather than crashing here.
1366 fatal("unable to build libssp: {}", .{@errorName(err)});1397 fatal("unable to build libssp: {}", .{@errorName(err)});
1367 };1398 };
1368 },1399 },
1369 .zig_libc => {1400 .zig_libc => {
1370 self.buildStaticLibFromZig("c.zig", &self.libc_static_lib) catch |err| {1401 self.buildOutputFromZig("c.zig", .Lib, &self.libc_static_lib) catch |err| {
1371 // TODO Expose this as a normal compile error rather than crashing here.1402 // TODO Expose this as a normal compile error rather than crashing here.
1372 fatal("unable to build zig's multitarget libc: {}", .{@errorName(err)});1403 fatal("unable to build zig's multitarget libc: {}", .{@errorName(err)});
1373 };1404 };
...@@ -2531,10 +2562,16 @@ pub fn updateSubCompilation(sub_compilation: *Compilation) !void {...@@ -2531,10 +2562,16 @@ pub fn updateSubCompilation(sub_compilation: *Compilation) !void {
2531 }2562 }
2532}2563}
25332564
2534fn buildStaticLibFromZig(comp: *Compilation, src_basename: []const u8, out: *?CRTFile) !void {2565fn buildOutputFromZig(
2566 comp: *Compilation,
2567 src_basename: []const u8,
2568 output_mode: std.builtin.OutputMode,
2569 out: *?CRTFile,
2570) !void {
2535 const tracy = trace(@src());2571 const tracy = trace(@src());
2536 defer tracy.end();2572 defer tracy.end();
25372573
2574 std.debug.assert(output_mode != .Exe);
2538 const special_sub = "std" ++ std.fs.path.sep_str ++ "special";2575 const special_sub = "std" ++ std.fs.path.sep_str ++ "special";
2539 const special_path = try comp.zig_lib_directory.join(comp.gpa, &[_][]const u8{special_sub});2576 const special_path = try comp.zig_lib_directory.join(comp.gpa, &[_][]const u8{special_sub});
2540 defer comp.gpa.free(special_path);2577 defer comp.gpa.free(special_path);
...@@ -2551,11 +2588,11 @@ fn buildStaticLibFromZig(comp: *Compilation, src_basename: []const u8, out: *?CR...@@ -2551,11 +2588,11 @@ fn buildStaticLibFromZig(comp: *Compilation, src_basename: []const u8, out: *?CR
2551 };2588 };
2552 const root_name = mem.split(src_basename, ".").next().?;2589 const root_name = mem.split(src_basename, ".").next().?;
2553 const target = comp.getTarget();2590 const target = comp.getTarget();
2554 const output_mode: std.builtin.OutputMode = if (target.cpu.arch.isWasm()) .Obj else .Lib;2591 const fixed_output_mode = if (target.cpu.arch.isWasm()) .Obj else output_mode;
2555 const bin_basename = try std.zig.binNameAlloc(comp.gpa, .{2592 const bin_basename = try std.zig.binNameAlloc(comp.gpa, .{
2556 .root_name = root_name,2593 .root_name = root_name,
2557 .target = target,2594 .target = target,
2558 .output_mode = output_mode,2595 .output_mode = fixed_output_mode,
2559 });2596 });
2560 defer comp.gpa.free(bin_basename);2597 defer comp.gpa.free(bin_basename);
25612598
...@@ -2578,7 +2615,7 @@ fn buildStaticLibFromZig(comp: *Compilation, src_basename: []const u8, out: *?CR...@@ -2578,7 +2615,7 @@ fn buildStaticLibFromZig(comp: *Compilation, src_basename: []const u8, out: *?CR
2578 .target = target,2615 .target = target,
2579 .root_name = root_name,2616 .root_name = root_name,
2580 .root_pkg = &root_pkg,2617 .root_pkg = &root_pkg,
2581 .output_mode = output_mode,2618 .output_mode = fixed_output_mode,
2582 .rand = comp.rand,2619 .rand = comp.rand,
2583 .libc_installation = comp.bin_file.options.libc_installation,2620 .libc_installation = comp.bin_file.options.libc_installation,
2584 .emit_bin = emit_bin,2621 .emit_bin = emit_bin,
src/link.zig+11-1
...@@ -46,6 +46,7 @@ pub const Options = struct {...@@ -46,6 +46,7 @@ pub const Options = struct {
46 entry_addr: ?u64 = null,46 entry_addr: ?u64 = null,
47 stack_size_override: ?u64,47 stack_size_override: ?u64,
48 image_base_override: ?u64,48 image_base_override: ?u64,
49 include_compiler_rt: bool,
49 /// Set to `true` to omit debug info.50 /// Set to `true` to omit debug info.
50 strip: bool,51 strip: bool,
51 /// If this is true then this link code is responsible for outputting an object52 /// If this is true then this link code is responsible for outputting an object
...@@ -450,6 +451,11 @@ pub const File = struct {...@@ -450,6 +451,11 @@ pub const File = struct {
450 break :blk full_obj_path;451 break :blk full_obj_path;
451 } else null;452 } else null;
452453
454 const compiler_rt_path: ?[]const u8 = if (base.options.include_compiler_rt)
455 comp.compiler_rt_obj.?.full_object_path
456 else
457 null;
458
453 // This function follows the same pattern as link.Elf.linkWithLLD so if you want some459 // This function follows the same pattern as link.Elf.linkWithLLD so if you want some
454 // insight as to what's going on here you can read that function body which is more460 // insight as to what's going on here you can read that function body which is more
455 // well-commented.461 // well-commented.
...@@ -466,6 +472,7 @@ pub const File = struct {...@@ -466,6 +472,7 @@ pub const File = struct {
466 _ = try ch.addFile(entry.key.status.success.object_path, null);472 _ = try ch.addFile(entry.key.status.success.object_path, null);
467 }473 }
468 try ch.addOptionalFile(module_obj_path);474 try ch.addOptionalFile(module_obj_path);
475 try ch.addOptionalFile(compiler_rt_path);
469476
470 // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock.477 // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock.
471 _ = try ch.hit();478 _ = try ch.hit();
...@@ -495,7 +502,7 @@ pub const File = struct {...@@ -495,7 +502,7 @@ pub const File = struct {
495 var object_files = std.ArrayList([*:0]const u8).init(base.allocator);502 var object_files = std.ArrayList([*:0]const u8).init(base.allocator);
496 defer object_files.deinit();503 defer object_files.deinit();
497504
498 try object_files.ensureCapacity(base.options.objects.len + comp.c_object_table.items().len + 1);505 try object_files.ensureCapacity(base.options.objects.len + comp.c_object_table.items().len + 2);
499 for (base.options.objects) |obj_path| {506 for (base.options.objects) |obj_path| {
500 object_files.appendAssumeCapacity(try arena.dupeZ(u8, obj_path));507 object_files.appendAssumeCapacity(try arena.dupeZ(u8, obj_path));
501 }508 }
...@@ -505,6 +512,9 @@ pub const File = struct {...@@ -505,6 +512,9 @@ pub const File = struct {
505 if (module_obj_path) |p| {512 if (module_obj_path) |p| {
506 object_files.appendAssumeCapacity(try arena.dupeZ(u8, p));513 object_files.appendAssumeCapacity(try arena.dupeZ(u8, p));
507 }514 }
515 if (compiler_rt_path) |p| {
516 object_files.appendAssumeCapacity(try arena.dupeZ(u8, p));
517 }
508518
509 const full_out_path = try directory.join(arena, &[_][]const u8{base.options.emit.?.sub_path});519 const full_out_path = try directory.join(arena, &[_][]const u8{base.options.emit.?.sub_path});
510 const full_out_path_z = try arena.dupeZ(u8, full_out_path);520 const full_out_path_z = try arena.dupeZ(u8, full_out_path);
src/link/Elf.zig+17-6
...@@ -1260,6 +1260,13 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {...@@ -1260,6 +1260,13 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
1260 const gc_sections = self.base.options.gc_sections orelse !is_obj;1260 const gc_sections = self.base.options.gc_sections orelse !is_obj;
1261 const stack_size = self.base.options.stack_size_override orelse 16777216;1261 const stack_size = self.base.options.stack_size_override orelse 16777216;
1262 const allow_shlib_undefined = self.base.options.allow_shlib_undefined orelse !self.base.options.is_native_os;1262 const allow_shlib_undefined = self.base.options.allow_shlib_undefined orelse !self.base.options.is_native_os;
1263 const compiler_rt_path: ?[]const u8 = if (self.base.options.include_compiler_rt) blk: {
1264 if (is_exe_or_dyn_lib) {
1265 break :blk comp.compiler_rt_static_lib.?.full_object_path;
1266 } else {
1267 break :blk comp.compiler_rt_obj.?.full_object_path;
1268 }
1269 } else null;
12631270
1264 // Here we want to determine whether we can save time by not invoking LLD when the1271 // Here we want to determine whether we can save time by not invoking LLD when the
1265 // output is unchanged. None of the linker options or the object files that are being1272 // output is unchanged. None of the linker options or the object files that are being
...@@ -1289,6 +1296,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {...@@ -1289,6 +1296,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
1289 _ = try man.addFile(entry.key.status.success.object_path, null);1296 _ = try man.addFile(entry.key.status.success.object_path, null);
1290 }1297 }
1291 try man.addOptionalFile(module_obj_path);1298 try man.addOptionalFile(module_obj_path);
1299 try man.addOptionalFile(compiler_rt_path);
1300
1292 // We can skip hashing libc and libc++ components that we are in charge of building from Zig1301 // We can skip hashing libc and libc++ components that we are in charge of building from Zig
1293 // installation sources because they are always a product of the compiler version + target information.1302 // installation sources because they are always a product of the compiler version + target information.
1294 man.hash.add(stack_size);1303 man.hash.add(stack_size);
...@@ -1524,12 +1533,14 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {...@@ -1524,12 +1533,14 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
1524 try argv.append(p);1533 try argv.append(p);
1525 }1534 }
15261535
1527 // compiler-rt and libc1536 // libc
1528 if (is_exe_or_dyn_lib and !self.base.options.is_compiler_rt_or_libc) {1537 if (is_exe_or_dyn_lib and !self.base.options.is_compiler_rt_or_libc and !self.base.options.link_libc) {
1529 if (!self.base.options.link_libc) {1538 try argv.append(comp.libc_static_lib.?.full_object_path);
1530 try argv.append(comp.libc_static_lib.?.full_object_path);1539 }
1531 }1540
1532 try argv.append(comp.compiler_rt_static_lib.?.full_object_path);1541 // compiler-rt
1542 if (compiler_rt_path) |p| {
1543 try argv.append(p);
1533 }1544 }
15341545
1535 // Shared libraries.1546 // Shared libraries.
src/main.zig+12-2
...@@ -304,8 +304,12 @@ const usage_build_generic =...@@ -304,8 +304,12 @@ const usage_build_generic =
304 \\ --version-script [path] Provide a version .map file304 \\ --version-script [path] Provide a version .map file
305 \\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so)305 \\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so)
306 \\ --version [ver] Dynamic library semver306 \\ --version [ver] Dynamic library semver
307 \\ -fsoname[=name] (linux) Override the default SONAME value307 \\ -fsoname[=name] (Linux) Override the default SONAME value
308 \\ -fno-soname (linux) Disable emitting a SONAME308 \\ -fno-soname (Linux) Disable emitting a SONAME
309 \\ -fLLD Force using LLD as the linker
310 \\ -fno-LLD Prevent using LLD as the linker
311 \\ -fcompiler-rt Always include compiler-rt symbols in output
312 \\ -fno-compiler-rt Prevent including compiler-rt symbols in output
309 \\ -rdynamic Add all symbols to the dynamic symbol table313 \\ -rdynamic Add all symbols to the dynamic symbol table
310 \\ -rpath [path] Add directory to the runtime library search path314 \\ -rpath [path] Add directory to the runtime library search path
311 \\ -feach-lib-rpath Ensure adding rpath for each used dynamic library315 \\ -feach-lib-rpath Ensure adding rpath for each used dynamic library
...@@ -469,6 +473,7 @@ fn buildOutputType(...@@ -469,6 +473,7 @@ fn buildOutputType(
469 var want_sanitize_c: ?bool = null;473 var want_sanitize_c: ?bool = null;
470 var want_stack_check: ?bool = null;474 var want_stack_check: ?bool = null;
471 var want_valgrind: ?bool = null;475 var want_valgrind: ?bool = null;
476 var want_compiler_rt: ?bool = null;
472 var rdynamic: bool = false;477 var rdynamic: bool = false;
473 var linker_script: ?[]const u8 = null;478 var linker_script: ?[]const u8 = null;
474 var version_script: ?[]const u8 = null;479 var version_script: ?[]const u8 = null;
...@@ -785,6 +790,10 @@ fn buildOutputType(...@@ -785,6 +790,10 @@ fn buildOutputType(
785 if (i + 1 >= args.len) fatal("expected parameter after {}", .{arg});790 if (i + 1 >= args.len) fatal("expected parameter after {}", .{arg});
786 i += 1;791 i += 1;
787 override_lib_dir = args[i];792 override_lib_dir = args[i];
793 } else if (mem.eql(u8, arg, "-fcompiler-rt")) {
794 want_compiler_rt = true;
795 } else if (mem.eql(u8, arg, "-fno-compiler-rt")) {
796 want_compiler_rt = false;
788 } else if (mem.eql(u8, arg, "-feach-lib-rpath")) {797 } else if (mem.eql(u8, arg, "-feach-lib-rpath")) {
789 each_lib_rpath = true;798 each_lib_rpath = true;
790 } else if (mem.eql(u8, arg, "-fno-each-lib-rpath")) {799 } else if (mem.eql(u8, arg, "-fno-each-lib-rpath")) {
...@@ -1667,6 +1676,7 @@ fn buildOutputType(...@@ -1667,6 +1676,7 @@ fn buildOutputType(
1667 .want_sanitize_c = want_sanitize_c,1676 .want_sanitize_c = want_sanitize_c,
1668 .want_stack_check = want_stack_check,1677 .want_stack_check = want_stack_check,
1669 .want_valgrind = want_valgrind,1678 .want_valgrind = want_valgrind,
1679 .want_compiler_rt = want_compiler_rt,
1670 .use_llvm = use_llvm,1680 .use_llvm = use_llvm,
1671 .use_lld = use_lld,1681 .use_lld = use_lld,
1672 .use_clang = use_clang,1682 .use_clang = use_clang,