| ... | @@ -1001,7 +1001,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1001,7 +1001,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1001 | // --verbose-link | 1001 | // --verbose-link |
| 1002 | if (self.base.comp.verbose_link) try self.dumpArgv(comp); | 1002 | if (self.base.comp.verbose_link) try self.dumpArgv(comp); |
| 1003 | | 1003 | |
| 1004 | const csu = try CsuObjects.init(arena, self.base.options, comp); | 1004 | const csu = try CsuObjects.init(arena, comp); |
| 1005 | const compiler_rt_path: ?[]const u8 = blk: { | 1005 | const compiler_rt_path: ?[]const u8 = blk: { |
| 1006 | if (comp.compiler_rt_lib) |x| break :blk x.full_object_path; | 1006 | if (comp.compiler_rt_lib) |x| break :blk x.full_object_path; |
| 1007 | if (comp.compiler_rt_obj) |x| break :blk x.full_object_path; | 1007 | if (comp.compiler_rt_obj) |x| break :blk x.full_object_path; |
| ... | @@ -1021,8 +1021,8 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1021,8 +1021,8 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1021 | if (csu.crti) |v| try positionals.append(.{ .path = v }); | 1021 | if (csu.crti) |v| try positionals.append(.{ .path = v }); |
| 1022 | if (csu.crtbegin) |v| try positionals.append(.{ .path = v }); | 1022 | if (csu.crtbegin) |v| try positionals.append(.{ .path = v }); |
| 1023 | | 1023 | |
| 1024 | try positionals.ensureUnusedCapacity(self.base.options.objects.len); | 1024 | try positionals.ensureUnusedCapacity(self.base.comp.objects.len); |
| 1025 | positionals.appendSliceAssumeCapacity(self.base.options.objects); | 1025 | positionals.appendSliceAssumeCapacity(self.base.comp.objects); |
| 1026 | | 1026 | |
| 1027 | // This is a set of object files emitted by clang in a single `build-exe` invocation. | 1027 | // This is a set of object files emitted by clang in a single `build-exe` invocation. |
| 1028 | // For instance, the implicit `a.o` as compiled by `zig build-exe a.c` will end up | 1028 | // For instance, the implicit `a.o` as compiled by `zig build-exe a.c` will end up |
| ... | @@ -1051,7 +1051,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1051,7 +1051,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1051 | _ = try rpath_table.put(lib_dir_path, {}); | 1051 | _ = try rpath_table.put(lib_dir_path, {}); |
| 1052 | } | 1052 | } |
| 1053 | } | 1053 | } |
| 1054 | for (self.base.options.objects) |obj| { | 1054 | for (self.base.comp.objects) |obj| { |
| 1055 | if (Compilation.classifyFileExt(obj.path) == .shared_library) { | 1055 | if (Compilation.classifyFileExt(obj.path) == .shared_library) { |
| 1056 | const lib_dir_path = std.fs.path.dirname(obj.path) orelse continue; | 1056 | const lib_dir_path = std.fs.path.dirname(obj.path) orelse continue; |
| 1057 | if (obj.loption) continue; | 1057 | if (obj.loption) continue; |
| ... | @@ -1061,7 +1061,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1061,7 +1061,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1061 | } | 1061 | } |
| 1062 | | 1062 | |
| 1063 | // TSAN | 1063 | // TSAN |
| 1064 | if (self.base.options.tsan) { | 1064 | if (self.base.comp.config.any_sanitize_thread) { |
| 1065 | try positionals.append(.{ .path = comp.tsan_static_lib.?.full_object_path }); | 1065 | try positionals.append(.{ .path = comp.tsan_static_lib.?.full_object_path }); |
| 1066 | } | 1066 | } |
| 1067 | | 1067 | |
| ... | @@ -1093,21 +1093,21 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1093,21 +1093,21 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1093 | } | 1093 | } |
| 1094 | | 1094 | |
| 1095 | // libc++ dep | 1095 | // libc++ dep |
| 1096 | if (self.base.options.link_libcpp) { | 1096 | if (self.base.comp.config.link_libcpp) { |
| 1097 | try system_libs.ensureUnusedCapacity(2); | 1097 | try system_libs.ensureUnusedCapacity(2); |
| 1098 | system_libs.appendAssumeCapacity(.{ .path = comp.libcxxabi_static_lib.?.full_object_path }); | 1098 | system_libs.appendAssumeCapacity(.{ .path = comp.libcxxabi_static_lib.?.full_object_path }); |
| 1099 | system_libs.appendAssumeCapacity(.{ .path = comp.libcxx_static_lib.?.full_object_path }); | 1099 | system_libs.appendAssumeCapacity(.{ .path = comp.libcxx_static_lib.?.full_object_path }); |
| 1100 | } | 1100 | } |
| 1101 | | 1101 | |
| 1102 | // libunwind dep | 1102 | // libunwind dep |
| 1103 | if (self.base.options.link_libunwind) { | 1103 | if (self.base.comp.config.link_libunwind) { |
| 1104 | try system_libs.append(.{ .path = comp.libunwind_static_lib.?.full_object_path }); | 1104 | try system_libs.append(.{ .path = comp.libunwind_static_lib.?.full_object_path }); |
| 1105 | } | 1105 | } |
| 1106 | | 1106 | |
| 1107 | // libc dep | 1107 | // libc dep |
| 1108 | self.error_flags.missing_libc = false; | 1108 | self.error_flags.missing_libc = false; |
| 1109 | if (self.base.options.link_libc) { | 1109 | if (self.base.comp.config.link_libc) { |
| 1110 | if (self.base.options.libc_installation) |lc| { | 1110 | if (self.base.comp.libc_installation) |lc| { |
| 1111 | const flags = target_util.libcFullLinkFlags(target); | 1111 | const flags = target_util.libcFullLinkFlags(target); |
| 1112 | try system_libs.ensureUnusedCapacity(flags.len); | 1112 | try system_libs.ensureUnusedCapacity(flags.len); |
| 1113 | | 1113 | |
| ... | @@ -1246,7 +1246,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1246,7 +1246,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1246 | // Look for entry address in objects if not set by the incremental compiler. | 1246 | // Look for entry address in objects if not set by the incremental compiler. |
| 1247 | if (self.entry_index == null) { | 1247 | if (self.entry_index == null) { |
| 1248 | const entry: ?[]const u8 = entry: { | 1248 | const entry: ?[]const u8 = entry: { |
| 1249 | if (self.base.options.entry) |entry| break :entry entry; | 1249 | if (self.base.comp.config.entry) |entry| break :entry entry; |
| 1250 | if (!self.base.isDynLib()) break :entry "_start"; | 1250 | if (!self.base.isDynLib()) break :entry "_start"; |
| 1251 | break :entry null; | 1251 | break :entry null; |
| 1252 | }; | 1252 | }; |
| ... | @@ -1571,7 +1571,7 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { | ... | @@ -1571,7 +1571,7 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { |
| 1571 | } | 1571 | } |
| 1572 | } else null; | 1572 | } else null; |
| 1573 | | 1573 | |
| 1574 | const csu = try CsuObjects.init(arena, self.base.options, comp); | 1574 | const csu = try CsuObjects.init(arena, comp); |
| 1575 | const compiler_rt_path: ?[]const u8 = blk: { | 1575 | const compiler_rt_path: ?[]const u8 = blk: { |
| 1576 | if (comp.compiler_rt_lib) |x| break :blk x.full_object_path; | 1576 | if (comp.compiler_rt_lib) |x| break :blk x.full_object_path; |
| 1577 | if (comp.compiler_rt_obj) |x| break :blk x.full_object_path; | 1577 | if (comp.compiler_rt_obj) |x| break :blk x.full_object_path; |
| ... | @@ -1713,7 +1713,7 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { | ... | @@ -1713,7 +1713,7 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { |
| 1713 | } | 1713 | } |
| 1714 | | 1714 | |
| 1715 | if (self.base.options.link_libc) { | 1715 | if (self.base.options.link_libc) { |
| 1716 | if (self.base.options.libc_installation) |libc_installation| { | 1716 | if (self.base.comp.libc_installation) |libc_installation| { |
| 1717 | try argv.append("-L"); | 1717 | try argv.append("-L"); |
| 1718 | try argv.append(libc_installation.crt_dir.?); | 1718 | try argv.append(libc_installation.crt_dir.?); |
| 1719 | } | 1719 | } |
| ... | @@ -1803,7 +1803,7 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { | ... | @@ -1803,7 +1803,7 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { |
| 1803 | | 1803 | |
| 1804 | // libc dep | 1804 | // libc dep |
| 1805 | if (self.base.options.link_libc) { | 1805 | if (self.base.options.link_libc) { |
| 1806 | if (self.base.options.libc_installation != null) { | 1806 | if (self.base.comp.libc_installation != null) { |
| 1807 | const needs_grouping = link_mode == .Static; | 1807 | const needs_grouping = link_mode == .Static; |
| 1808 | if (needs_grouping) try argv.append("--start-group"); | 1808 | if (needs_grouping) try argv.append("--start-group"); |
| 1809 | try argv.appendSlice(target_util.libcFullLinkFlags(target)); | 1809 | try argv.appendSlice(target_util.libcFullLinkFlags(target)); |
| ... | @@ -2405,8 +2405,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -2405,8 +2405,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2405 | man.hash.add(self.base.options.hash_style); | 2405 | man.hash.add(self.base.options.hash_style); |
| 2406 | // strip does not need to go into the linker hash because it is part of the hash namespace | 2406 | // strip does not need to go into the linker hash because it is part of the hash namespace |
| 2407 | if (self.base.options.link_libc) { | 2407 | if (self.base.options.link_libc) { |
| 2408 | man.hash.add(self.base.options.libc_installation != null); | 2408 | man.hash.add(self.base.comp.libc_installation != null); |
| 2409 | if (self.base.options.libc_installation) |libc_installation| { | 2409 | if (self.base.comp.libc_installation) |libc_installation| { |
| 2410 | man.hash.addBytes(libc_installation.crt_dir.?); | 2410 | man.hash.addBytes(libc_installation.crt_dir.?); |
| 2411 | } | 2411 | } |
| 2412 | if (have_dynamic_linker) { | 2412 | if (have_dynamic_linker) { |
| ... | @@ -2669,7 +2669,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -2669,7 +2669,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2669 | try argv.append(full_out_path); | 2669 | try argv.append(full_out_path); |
| 2670 | | 2670 | |
| 2671 | // csu prelude | 2671 | // csu prelude |
| 2672 | const csu = try CsuObjects.init(arena, self.base.options, comp); | 2672 | const csu = try CsuObjects.init(arena, comp); |
| 2673 | if (csu.crt0) |v| try argv.append(v); | 2673 | if (csu.crt0) |v| try argv.append(v); |
| 2674 | if (csu.crti) |v| try argv.append(v); | 2674 | if (csu.crti) |v| try argv.append(v); |
| 2675 | if (csu.crtbegin) |v| try argv.append(v); | 2675 | if (csu.crtbegin) |v| try argv.append(v); |
| ... | @@ -2719,7 +2719,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -2719,7 +2719,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2719 | } | 2719 | } |
| 2720 | | 2720 | |
| 2721 | if (self.base.options.link_libc) { | 2721 | if (self.base.options.link_libc) { |
| 2722 | if (self.base.options.libc_installation) |libc_installation| { | 2722 | if (self.base.comp.libc_installation) |libc_installation| { |
| 2723 | try argv.append("-L"); | 2723 | try argv.append("-L"); |
| 2724 | try argv.append(libc_installation.crt_dir.?); | 2724 | try argv.append(libc_installation.crt_dir.?); |
| 2725 | } | 2725 | } |
| ... | @@ -2839,7 +2839,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v | ... | @@ -2839,7 +2839,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 2839 | // libc dep | 2839 | // libc dep |
| 2840 | self.error_flags.missing_libc = false; | 2840 | self.error_flags.missing_libc = false; |
| 2841 | if (self.base.options.link_libc) { | 2841 | if (self.base.options.link_libc) { |
| 2842 | if (self.base.options.libc_installation != null) { | 2842 | if (self.base.comp.libc_installation != null) { |
| 2843 | const needs_grouping = link_mode == .Static; | 2843 | const needs_grouping = link_mode == .Static; |
| 2844 | if (needs_grouping) try argv.append("--start-group"); | 2844 | if (needs_grouping) try argv.append("--start-group"); |
| 2845 | try argv.appendSlice(target_util.libcFullLinkFlags(target)); | 2845 | try argv.appendSlice(target_util.libcFullLinkFlags(target)); |
| ... | @@ -5444,9 +5444,11 @@ const CsuObjects = struct { | ... | @@ -5444,9 +5444,11 @@ const CsuObjects = struct { |
| 5444 | crtend: ?[]const u8 = null, | 5444 | crtend: ?[]const u8 = null, |
| 5445 | crtn: ?[]const u8 = null, | 5445 | crtn: ?[]const u8 = null, |
| 5446 | | 5446 | |
| 5447 | fn init(arena: mem.Allocator, link_options: link.Options, comp: *const Compilation) !CsuObjects { | 5447 | const InitArgs = struct {}; |
| | 5448 | |
| | 5449 | fn init(arena: Allocator, comp: *const Compilation) !CsuObjects { |
| 5448 | // crt objects are only required for libc. | 5450 | // crt objects are only required for libc. |
| 5449 | if (!link_options.link_libc) return CsuObjects{}; | 5451 | if (!comp.config.link_libc) return .{}; |
| 5450 | | 5452 | |
| 5451 | var result: CsuObjects = .{}; | 5453 | var result: CsuObjects = .{}; |
| 5452 | | 5454 | |
| ... | @@ -5457,19 +5459,21 @@ const CsuObjects = struct { | ... | @@ -5457,19 +5459,21 @@ const CsuObjects = struct { |
| 5457 | dynamic_pie, | 5459 | dynamic_pie, |
| 5458 | static_exe, | 5460 | static_exe, |
| 5459 | static_pie, | 5461 | static_pie, |
| 5460 | } = switch (link_options.output_mode) { | 5462 | } = switch (comp.config.output_mode) { |
| 5461 | .Obj => return CsuObjects{}, | 5463 | .Obj => return CsuObjects{}, |
| 5462 | .Lib => switch (link_options.link_mode) { | 5464 | .Lib => switch (comp.config.link_mode) { |
| 5463 | .Dynamic => .dynamic_lib, | 5465 | .Dynamic => .dynamic_lib, |
| 5464 | .Static => return CsuObjects{}, | 5466 | .Static => return CsuObjects{}, |
| 5465 | }, | 5467 | }, |
| 5466 | .Exe => switch (link_options.link_mode) { | 5468 | .Exe => switch (comp.config.link_mode) { |
| 5467 | .Dynamic => if (link_options.pie) .dynamic_pie else .dynamic_exe, | 5469 | .Dynamic => if (comp.config.pie) .dynamic_pie else .dynamic_exe, |
| 5468 | .Static => if (link_options.pie) .static_pie else .static_exe, | 5470 | .Static => if (comp.config.pie) .static_pie else .static_exe, |
| 5469 | }, | 5471 | }, |
| 5470 | }; | 5472 | }; |
| 5471 | | 5473 | |
| 5472 | if (link_options.target.isAndroid()) { | 5474 | const target = comp.root_mod.resolved_target.result; |
| | 5475 | |
| | 5476 | if (target.isAndroid()) { |
| 5473 | switch (mode) { | 5477 | switch (mode) { |
| 5474 | // zig fmt: off | 5478 | // zig fmt: off |
| 5475 | .dynamic_lib => result.set( null, null, "crtbegin_so.o", "crtend_so.o", null ), | 5479 | .dynamic_lib => result.set( null, null, "crtbegin_so.o", "crtend_so.o", null ), |
| ... | @@ -5480,7 +5484,7 @@ const CsuObjects = struct { | ... | @@ -5480,7 +5484,7 @@ const CsuObjects = struct { |
| 5480 | // zig fmt: on | 5484 | // zig fmt: on |
| 5481 | } | 5485 | } |
| 5482 | } else { | 5486 | } else { |
| 5483 | switch (link_options.target.os.tag) { | 5487 | switch (target.os.tag) { |
| 5484 | .linux => { | 5488 | .linux => { |
| 5485 | switch (mode) { | 5489 | switch (mode) { |
| 5486 | // zig fmt: off | 5490 | // zig fmt: off |
| ... | @@ -5491,7 +5495,7 @@ const CsuObjects = struct { | ... | @@ -5491,7 +5495,7 @@ const CsuObjects = struct { |
| 5491 | .static_pie => result.set( "rcrt1.o", "crti.o", "crtbeginS.o", "crtendS.o", "crtn.o" ), | 5495 | .static_pie => result.set( "rcrt1.o", "crti.o", "crtbeginS.o", "crtendS.o", "crtn.o" ), |
| 5492 | // zig fmt: on | 5496 | // zig fmt: on |
| 5493 | } | 5497 | } |
| 5494 | if (link_options.libc_installation) |_| { | 5498 | if (comp.libc_installation) |_| { |
| 5495 | // hosted-glibc provides crtbegin/end objects in platform/compiler-specific dirs | 5499 | // hosted-glibc provides crtbegin/end objects in platform/compiler-specific dirs |
| 5496 | // and they are not known at comptime. For now null-out crtbegin/end objects; | 5500 | // and they are not known at comptime. For now null-out crtbegin/end objects; |
| 5497 | // there is no feature loss, zig has never linked those objects in before. | 5501 | // there is no feature loss, zig has never linked those objects in before. |
| ... | @@ -5499,7 +5503,7 @@ const CsuObjects = struct { | ... | @@ -5499,7 +5503,7 @@ const CsuObjects = struct { |
| 5499 | result.crtend = null; | 5503 | result.crtend = null; |
| 5500 | } else { | 5504 | } else { |
| 5501 | // Bundled glibc only has Scrt1.o . | 5505 | // Bundled glibc only has Scrt1.o . |
| 5502 | if (result.crt0 != null and link_options.target.isGnuLibC()) result.crt0 = "Scrt1.o"; | 5506 | if (result.crt0 != null and target.isGnuLibC()) result.crt0 = "Scrt1.o"; |
| 5503 | } | 5507 | } |
| 5504 | }, | 5508 | }, |
| 5505 | .dragonfly => switch (mode) { | 5509 | .dragonfly => switch (mode) { |
| ... | @@ -5561,16 +5565,16 @@ const CsuObjects = struct { | ... | @@ -5561,16 +5565,16 @@ const CsuObjects = struct { |
| 5561 | } | 5565 | } |
| 5562 | | 5566 | |
| 5563 | // Convert each object to a full pathname. | 5567 | // Convert each object to a full pathname. |
| 5564 | if (link_options.libc_installation) |lci| { | 5568 | if (comp.libc_installation) |lci| { |
| 5565 | const crt_dir_path = lci.crt_dir orelse return error.LibCInstallationMissingCRTDir; | 5569 | const crt_dir_path = lci.crt_dir orelse return error.LibCInstallationMissingCRTDir; |
| 5566 | switch (link_options.target.os.tag) { | 5570 | switch (target.os.tag) { |
| 5567 | .dragonfly => { | 5571 | .dragonfly => { |
| 5568 | if (result.crt0) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, obj.* }); | 5572 | if (result.crt0) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, obj.* }); |
| 5569 | if (result.crti) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, obj.* }); | 5573 | if (result.crti) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, obj.* }); |
| 5570 | if (result.crtn) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, obj.* }); | 5574 | if (result.crtn) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, obj.* }); |
| 5571 | | 5575 | |
| 5572 | var gccv: []const u8 = undefined; | 5576 | var gccv: []const u8 = undefined; |
| 5573 | if (link_options.target.os.version_range.semver.isAtLeast(.{ .major = 5, .minor = 4, .patch = 0 }) orelse true) { | 5577 | if (target.os.version_range.semver.isAtLeast(.{ .major = 5, .minor = 4, .patch = 0 }) orelse true) { |
| 5574 | gccv = "gcc80"; | 5578 | gccv = "gcc80"; |
| 5575 | } else { | 5579 | } else { |
| 5576 | gccv = "gcc54"; | 5580 | gccv = "gcc54"; |