authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-10-18 22:29:50-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-10-23 16:27:38-07:00
logc2898c436f0c858d10367b7631091f5a52cce76f
treebf2ca1d0dd9b02b530cb70545111091c916727b5
parent5ca54036ca0bc292ead681c03c8ac57e27a127db

branch fixes


10 files changed, 282 insertions(+), 425 deletions(-)

lib/std/zig/target.zig+2-2
......@@ -25,7 +25,7 @@ pub const available_libcs = [_]ArchOsAbi{
2525 .{ .arch = .thumbeb, .os = .linux, .abi = .musleabihf },
2626 .{ .arch = .aarch64, .os = .linux, .abi = .gnu, .glibc_min = .{ .major = 2, .minor = 17, .patch = 0 } },
2727 .{ .arch = .aarch64, .os = .linux, .abi = .musl },
28 .{ .arch = .aarch64, .os = .macos, .abi = .none, .os_ver = .{ .major = 11, .minor = 0, .patch = 0 } },
28 .{ .arch = .aarch64, .os = .macos, .abi = .none, .os_ver = .{ .major = 13, .minor = 0, .patch = 0 } },
2929 .{ .arch = .aarch64, .os = .windows, .abi = .gnu },
3030 .{ .arch = .aarch64_be, .os = .linux, .abi = .gnu, .glibc_min = .{ .major = 2, .minor = 17, .patch = 0 } },
3131 .{ .arch = .aarch64_be, .os = .linux, .abi = .musl },
......@@ -74,7 +74,7 @@ pub const available_libcs = [_]ArchOsAbi{
7474 .{ .arch = .x86_64, .os = .linux, .abi = .gnu },
7575 .{ .arch = .x86_64, .os = .linux, .abi = .gnux32 },
7676 .{ .arch = .x86_64, .os = .linux, .abi = .musl },
77 .{ .arch = .x86_64, .os = .macos, .abi = .none, .os_ver = .{ .major = 10, .minor = 7, .patch = 0 } },
77 .{ .arch = .x86_64, .os = .macos, .abi = .none, .os_ver = .{ .major = 13, .minor = 0, .patch = 0 } },
7878 .{ .arch = .x86_64, .os = .windows, .abi = .gnu },
7979};
8080
src/Compilation.zig+148-152
......@@ -49,6 +49,8 @@ pub const Config = @import("Compilation/Config.zig");
4949gpa: Allocator,
5050/// Arena-allocated memory, mostly used during initialization. However, it can
5151/// be used for other things requiring the same lifetime as the `Compilation`.
52/// Not thread-safe - lock `mutex` if potentially accessing from multiple
53/// threads at once.
5254arena: Allocator,
5355/// Not every Compilation compiles .zig code! For example you could do `zig build-exe foo.o`.
5456zcu: ?*Zcu,
......@@ -1760,172 +1762,166 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
17601762 .incremental => comp.bin_file != null,
17611763 };
17621764
1763 if (have_bin_emit and !comp.skip_linker_dependencies and target.ofmt != .c) {
1764 if (target.isDarwin()) {
1765 switch (target.abi) {
1766 .none,
1767 .simulator,
1768 .macabi,
1769 => {},
1770 else => return error.LibCUnavailable,
1771 }
1772 }
1773 // If we need to build glibc for the target, add work items for it.
1774 // We go through the work queue so that building can be done in parallel.
1775 // If linking against host libc installation, instead queue up jobs
1776 // for loading those files in the linker.
1777 if (comp.config.link_libc and is_exe_or_dyn_lib and target.ofmt != .c) {
1778 if (comp.libc_installation) |lci| {
1779 const basenames = LibCInstallation.CrtBasenames.get(.{
1780 .target = target,
1781 .link_libc = comp.config.link_libc,
1782 .output_mode = comp.config.output_mode,
1783 .link_mode = comp.config.link_mode,
1784 .pie = comp.config.pie,
1785 });
1786 const paths = try lci.resolveCrtPaths(arena, basenames, target);
1765 if (have_bin_emit and target.ofmt != .c) {
1766 if (!comp.skip_linker_dependencies) {
1767 // If we need to build libc for the target, add work items for it.
1768 // We go through the work queue so that building can be done in parallel.
1769 // If linking against host libc installation, instead queue up jobs
1770 // for loading those files in the linker.
1771 if (comp.config.link_libc and is_exe_or_dyn_lib) {
1772 if (comp.libc_installation) |lci| {
1773 const basenames = LibCInstallation.CrtBasenames.get(.{
1774 .target = target,
1775 .link_libc = comp.config.link_libc,
1776 .output_mode = comp.config.output_mode,
1777 .link_mode = comp.config.link_mode,
1778 .pie = comp.config.pie,
1779 });
1780 const paths = try lci.resolveCrtPaths(arena, basenames, target);
17871781
1788 const fields = @typeInfo(@TypeOf(paths)).@"struct".fields;
1789 try comp.link_task_queue.shared.ensureUnusedCapacity(gpa, fields.len);
1790 inline for (fields) |field| {
1791 if (@field(paths, field.name)) |path| {
1792 comp.link_task_queue.shared.appendAssumeCapacity(.{ .load_object = path });
1782 const fields = @typeInfo(@TypeOf(paths)).@"struct".fields;
1783 try comp.link_task_queue.shared.ensureUnusedCapacity(gpa, fields.len);
1784 inline for (fields) |field| {
1785 if (@field(paths, field.name)) |path| {
1786 comp.link_task_queue.shared.appendAssumeCapacity(.{ .load_object = path });
1787 }
17931788 }
1794 }
17951789
1796 const flags = target_util.libcFullLinkFlags(target);
1797 try comp.link_task_queue.shared.ensureUnusedCapacity(gpa, flags.len);
1798 for (flags) |flag| {
1799 assert(mem.startsWith(u8, flag, "-l"));
1800 const lib_name = flag["-l".len..];
1801 const suffix = switch (comp.config.link_mode) {
1802 .static => target.staticLibSuffix(),
1803 .dynamic => target.dynamicLibSuffix(),
1804 };
1805 const sep = std.fs.path.sep_str;
1806 const lib_path = try std.fmt.allocPrint(arena, "{s}" ++ sep ++ "lib{s}{s}", .{
1807 lci.crt_dir.?, lib_name, suffix,
1808 });
1809 const resolved_path = Path.initCwd(lib_path);
1810 comp.link_task_queue.shared.appendAssumeCapacity(switch (comp.config.link_mode) {
1811 .static => .{ .load_archive = resolved_path },
1812 .dynamic => .{ .load_dso = resolved_path },
1790 const flags = target_util.libcFullLinkFlags(target);
1791 try comp.link_task_queue.shared.ensureUnusedCapacity(gpa, flags.len);
1792 for (flags) |flag| {
1793 assert(mem.startsWith(u8, flag, "-l"));
1794 const lib_name = flag["-l".len..];
1795 const suffix = switch (comp.config.link_mode) {
1796 .static => target.staticLibSuffix(),
1797 .dynamic => target.dynamicLibSuffix(),
1798 };
1799 const sep = std.fs.path.sep_str;
1800 const lib_path = try std.fmt.allocPrint(arena, "{s}" ++ sep ++ "lib{s}{s}", .{
1801 lci.crt_dir.?, lib_name, suffix,
1802 });
1803 const resolved_path = Path.initCwd(lib_path);
1804 comp.link_task_queue.shared.appendAssumeCapacity(switch (comp.config.link_mode) {
1805 .static => .{ .load_archive = resolved_path },
1806 .dynamic => .{ .load_dso = resolved_path },
1807 });
1808 }
1809 } else if (target.isMusl() and !target.isWasm()) {
1810 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;
1811
1812 if (musl.needsCrtiCrtn(target)) {
1813 try comp.queueJobs(&[_]Job{
1814 .{ .musl_crt_file = .crti_o },
1815 .{ .musl_crt_file = .crtn_o },
1816 });
1817 }
1818 try comp.queueJobs(&[_]Job{
1819 .{ .musl_crt_file = .crt1_o },
1820 .{ .musl_crt_file = .scrt1_o },
1821 .{ .musl_crt_file = .rcrt1_o },
1822 switch (comp.config.link_mode) {
1823 .static => .{ .musl_crt_file = .libc_a },
1824 .dynamic => .{ .musl_crt_file = .libc_so },
1825 },
18131826 });
1814 }
1815 } else if (target.isMusl() and !target.isWasm()) {
1816 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;
1817
1818 if (musl.needsCrtiCrtn(target)) {
1827 } else if (target.isGnuLibC()) {
1828 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;
1829
1830 if (glibc.needsCrtiCrtn(target)) {
1831 try comp.queueJobs(&[_]Job{
1832 .{ .glibc_crt_file = .crti_o },
1833 .{ .glibc_crt_file = .crtn_o },
1834 });
1835 }
18191836 try comp.queueJobs(&[_]Job{
1820 .{ .musl_crt_file = .crti_o },
1821 .{ .musl_crt_file = .crtn_o },
1837 .{ .glibc_crt_file = .scrt1_o },
1838 .{ .glibc_crt_file = .libc_nonshared_a },
1839 .{ .glibc_shared_objects = {} },
18221840 });
1823 }
1824 try comp.queueJobs(&[_]Job{
1825 .{ .musl_crt_file = .crt1_o },
1826 .{ .musl_crt_file = .scrt1_o },
1827 .{ .musl_crt_file = .rcrt1_o },
1828 switch (comp.config.link_mode) {
1829 .static => .{ .musl_crt_file = .libc_a },
1830 .dynamic => .{ .musl_crt_file = .libc_so },
1831 },
1832 });
1833 } else if (target.isGnuLibC()) {
1834 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;
1841 } else if (target.isWasm() and target.os.tag == .wasi) {
1842 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;
18351843
1836 if (glibc.needsCrtiCrtn(target)) {
1844 for (comp.wasi_emulated_libs) |crt_file| {
1845 try comp.queueJob(.{
1846 .wasi_libc_crt_file = crt_file,
1847 });
1848 }
18371849 try comp.queueJobs(&[_]Job{
1838 .{ .glibc_crt_file = .crti_o },
1839 .{ .glibc_crt_file = .crtn_o },
1850 .{ .wasi_libc_crt_file = wasi_libc.execModelCrtFile(comp.config.wasi_exec_model) },
1851 .{ .wasi_libc_crt_file = .libc_a },
18401852 });
1841 }
1842 try comp.queueJobs(&[_]Job{
1843 .{ .glibc_crt_file = .scrt1_o },
1844 .{ .glibc_crt_file = .libc_nonshared_a },
1845 .{ .glibc_shared_objects = {} },
1846 });
1847 } else if (target.isWasm() and target.os.tag == .wasi) {
1848 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;
1853 } else if (target.isMinGW()) {
1854 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;
18491855
1850 for (comp.wasi_emulated_libs) |crt_file| {
1851 try comp.queueJob(.{
1852 .wasi_libc_crt_file = crt_file,
1856 const crt_job: Job = .{ .mingw_crt_file = if (is_dyn_lib) .dllcrt2_o else .crt2_o };
1857 try comp.queueJobs(&.{
1858 .{ .mingw_crt_file = .mingw32_lib },
1859 crt_job,
18531860 });
1854 }
1855 try comp.queueJobs(&[_]Job{
1856 .{ .wasi_libc_crt_file = wasi_libc.execModelCrtFile(comp.config.wasi_exec_model) },
1857 .{ .wasi_libc_crt_file = .libc_a },
1858 });
1859 } else if (target.isMinGW()) {
1860 if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable;
18611861
1862 const crt_job: Job = .{ .mingw_crt_file = if (is_dyn_lib) .dllcrt2_o else .crt2_o };
1863 try comp.queueJobs(&.{
1864 .{ .mingw_crt_file = .mingw32_lib },
1865 crt_job,
1866 });
1867
1868 // When linking mingw-w64 there are some import libs we always need.
1869 try comp.windows_libs.ensureUnusedCapacity(gpa, mingw.always_link_libs.len);
1870 for (mingw.always_link_libs) |name| comp.windows_libs.putAssumeCapacity(name, {});
1871 } else {
1872 return error.LibCUnavailable;
1862 // When linking mingw-w64 there are some import libs we always need.
1863 try comp.windows_libs.ensureUnusedCapacity(gpa, mingw.always_link_libs.len);
1864 for (mingw.always_link_libs) |name| comp.windows_libs.putAssumeCapacity(name, {});
1865 } else if (target.isDarwin()) {
1866 switch (target.abi) {
1867 .none, .simulator, .macabi => {},
1868 else => return error.LibCUnavailable,
1869 }
1870 } else if (target.os.tag == .freestanding and capable_of_building_zig_libc) {
1871 try comp.queueJob(.{ .zig_libc = {} });
1872 } else {
1873 return error.LibCUnavailable;
1874 }
18731875 }
1874 }
18751876
1876 // Generate Windows import libs.
1877 if (target.os.tag == .windows) {
1878 const count = comp.windows_libs.count();
1879 for (0..count) |i| {
1880 try comp.queueJob(.{ .windows_import_lib = i });
1877 // Generate Windows import libs.
1878 if (target.os.tag == .windows) {
1879 const count = comp.windows_libs.count();
1880 for (0..count) |i| {
1881 try comp.queueJob(.{ .windows_import_lib = i });
1882 }
1883 }
1884 if (comp.wantBuildLibUnwindFromSource()) {
1885 try comp.queueJob(.{ .libunwind = {} });
1886 }
1887 if (build_options.have_llvm and is_exe_or_dyn_lib and comp.config.link_libcpp) {
1888 try comp.queueJob(.libcxx);
1889 try comp.queueJob(.libcxxabi);
1890 }
1891 if (build_options.have_llvm and comp.config.any_sanitize_thread) {
1892 try comp.queueJob(.libtsan);
18811893 }
1882 }
1883 if (comp.wantBuildLibUnwindFromSource()) {
1884 try comp.queueJob(.{ .libunwind = {} });
1885 }
1886 if (build_options.have_llvm and is_exe_or_dyn_lib and comp.config.link_libcpp) {
1887 try comp.queueJob(.libcxx);
1888 try comp.queueJob(.libcxxabi);
1889 }
1890 if (build_options.have_llvm and comp.config.any_sanitize_thread) {
1891 try comp.queueJob(.libtsan);
1892 }
1893
1894 if (target.isMinGW() and comp.config.any_non_single_threaded) {
1895 // LLD might drop some symbols as unused during LTO and GCing, therefore,
1896 // we force mark them for resolution here.
18971894
1898 const tls_index_sym = switch (target.cpu.arch) {
1899 .x86 => "__tls_index",
1900 else => "_tls_index",
1901 };
1895 if (target.isMinGW() and comp.config.any_non_single_threaded) {
1896 // LLD might drop some symbols as unused during LTO and GCing, therefore,
1897 // we force mark them for resolution here.
19021898
1903 try comp.force_undefined_symbols.put(comp.gpa, tls_index_sym, {});
1904 }
1899 const tls_index_sym = switch (target.cpu.arch) {
1900 .x86 => "__tls_index",
1901 else => "_tls_index",
1902 };
19051903
1906 if (comp.include_compiler_rt and capable_of_building_compiler_rt) {
1907 if (is_exe_or_dyn_lib) {
1908 log.debug("queuing a job to build compiler_rt_lib", .{});
1909 comp.job_queued_compiler_rt_lib = true;
1910 } else if (output_mode != .Obj) {
1911 log.debug("queuing a job to build compiler_rt_obj", .{});
1912 // In this case we are making a static library, so we ask
1913 // for a compiler-rt object to put in it.
1914 comp.job_queued_compiler_rt_obj = true;
1904 try comp.force_undefined_symbols.put(comp.gpa, tls_index_sym, {});
19151905 }
1916 }
19171906
1918 if (comp.config.any_fuzz and capable_of_building_compiler_rt) {
1919 if (is_exe_or_dyn_lib) {
1920 log.debug("queuing a job to build libfuzzer", .{});
1921 comp.job_queued_fuzzer_lib = true;
1907 if (comp.include_compiler_rt and capable_of_building_compiler_rt) {
1908 if (is_exe_or_dyn_lib) {
1909 log.debug("queuing a job to build compiler_rt_lib", .{});
1910 comp.job_queued_compiler_rt_lib = true;
1911 } else if (output_mode != .Obj) {
1912 log.debug("queuing a job to build compiler_rt_obj", .{});
1913 // In this case we are making a static library, so we ask
1914 // for a compiler-rt object to put in it.
1915 comp.job_queued_compiler_rt_obj = true;
1916 }
19221917 }
1923 }
19241918
1925 if (!comp.skip_linker_dependencies and is_exe_or_dyn_lib and
1926 !comp.config.link_libc and capable_of_building_zig_libc)
1927 {
1928 try comp.queueJob(.{ .zig_libc = {} });
1919 if (comp.config.any_fuzz and capable_of_building_compiler_rt) {
1920 if (is_exe_or_dyn_lib) {
1921 log.debug("queuing a job to build libfuzzer", .{});
1922 comp.job_queued_fuzzer_lib = true;
1923 }
1924 }
19291925 }
19301926
19311927 try comp.link_task_queue.shared.append(gpa, .load_explicitly_provided);
......@@ -3521,7 +3517,7 @@ fn performAllTheWorkInner(
35213517 defer work_queue_wait_group.wait();
35223518
35233519 if (comp.bin_file) |lf| {
3524 if (try comp.link_task_queue.enqueue(comp.gpa, &.{.load_explicitly_provided})) {
3520 if (comp.link_task_queue.start()) {
35253521 comp.thread_pool.spawnWg(work_queue_wait_group, link.File.flushTaskQueue, .{ lf, main_progress_node });
35263522 }
35273523 }
......@@ -4980,7 +4976,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr
49804976 },
49814977 };
49824978
4983 comp.enqueueLinkTasks(&.{.{ .load_object = c_object.status.success.object_path }});
4979 comp.queueLinkTasks(&.{.{ .load_object = c_object.status.success.object_path }});
49844980}
49854981
49864982fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32_resource_prog_node: std.Progress.Node) !void {
......@@ -6114,7 +6110,7 @@ fn wantBuildLibUnwindFromSource(comp: *Compilation) bool {
61146110 return is_exe_or_dyn_lib and comp.config.link_libunwind and ofmt != .c;
61156111}
61166112
6117fn setAllocFailure(comp: *Compilation) void {
6113pub fn setAllocFailure(comp: *Compilation) void {
61186114 @branchHint(.cold);
61196115 log.debug("memory allocation failure", .{});
61206116 comp.alloc_failure_occurred = true;
......@@ -6355,7 +6351,7 @@ fn buildOutputFromZig(
63556351 assert(out.* == null);
63566352 out.* = crt_file;
63576353
6358 comp.enqueueLinkTaskMode(crt_file.full_object_path, output_mode);
6354 comp.queueLinkTaskMode(crt_file.full_object_path, output_mode);
63596355}
63606356
63616357pub fn build_crt_file(
......@@ -6463,7 +6459,7 @@ pub fn build_crt_file(
64636459 try comp.updateSubCompilation(sub_compilation, misc_task_tag, prog_node);
64646460
64656461 const crt_file = try sub_compilation.toCrtFile();
6466 comp.enqueueLinkTaskMode(crt_file.full_object_path, output_mode);
6462 comp.queueLinkTaskMode(crt_file.full_object_path, output_mode);
64676463
64686464 {
64696465 comp.mutex.lock();
......@@ -6473,8 +6469,8 @@ pub fn build_crt_file(
64736469 }
64746470}
64756471
6476pub fn enqueueLinkTaskMode(comp: *Compilation, path: Path, output_mode: std.builtin.OutputMode) void {
6477 comp.enqueueLinkTasks(switch (output_mode) {
6472pub fn queueLinkTaskMode(comp: *Compilation, path: Path, output_mode: std.builtin.OutputMode) void {
6473 comp.queueLinkTasks(switch (output_mode) {
64786474 .Exe => unreachable,
64796475 .Obj => &.{.{ .load_object = path }},
64806476 .Lib => &.{.{ .load_archive = path }},
......@@ -6483,7 +6479,7 @@ pub fn enqueueLinkTaskMode(comp: *Compilation, path: Path, output_mode: std.buil
64836479
64846480/// Only valid to call during `update`. Automatically handles queuing up a
64856481/// linker worker task if there is not already one.
6486fn enqueueLinkTasks(comp: *Compilation, tasks: []const link.File.Task) void {
6482pub fn queueLinkTasks(comp: *Compilation, tasks: []const link.File.Task) void {
64876483 const use_lld = build_options.have_llvm and comp.config.use_lld;
64886484 if (use_lld) return;
64896485 const target = comp.root_mod.resolved_target.result;
src/ThreadSafeQueue.zig+8
......@@ -59,5 +59,13 @@ pub fn ThreadSafeQueue(comptime T: type) type {
5959 self.state = .run;
6060 return was_waiting;
6161 }
62
63 /// Safe only to call exactly once when initially starting the worker.
64 pub fn start(self: *Self) bool {
65 assert(self.state == .wait);
66 if (self.shared.items.len == 0) return false;
67 self.state = .run;
68 return true;
69 }
6270 };
6371}
src/glibc.zig+54-17
......@@ -6,12 +6,14 @@ const fs = std.fs;
66const path = fs.path;
77const assert = std.debug.assert;
88const Version = std.SemanticVersion;
9const Path = std.Build.Cache.Path;
910
1011const Compilation = @import("Compilation.zig");
1112const build_options = @import("build_options");
1213const trace = @import("tracy.zig").trace;
1314const Cache = std.Build.Cache;
1415const Module = @import("Package/Module.zig");
16const link = @import("link.zig");
1517
1618pub const Lib = struct {
1719 name: []const u8,
......@@ -717,11 +719,11 @@ fn lib_path(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const
717719
718720pub const BuiltSharedObjects = struct {
719721 lock: Cache.Lock,
720 dir_path: []u8,
722 dir_path: Path,
721723
722724 pub fn deinit(self: *BuiltSharedObjects, gpa: Allocator) void {
723725 self.lock.release();
724 gpa.free(self.dir_path);
726 gpa.free(self.dir_path.sub_path);
725727 self.* = undefined;
726728 }
727729};
......@@ -742,7 +744,9 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi
742744 return error.ZigCompilerNotBuiltWithLLVMExtensions;
743745 }
744746
745 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
747 const gpa = comp.gpa;
748
749 var arena_allocator = std.heap.ArenaAllocator.init(gpa);
746750 defer arena_allocator.deinit();
747751 const arena = arena_allocator.allocator();
748752
......@@ -751,7 +755,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi
751755
752756 // Use the global cache directory.
753757 var cache: Cache = .{
754 .gpa = comp.gpa,
758 .gpa = gpa,
755759 .manifest_dir = try comp.global_cache_directory.handle.makeOpenPath("h", .{}),
756760 };
757761 cache.addPrefix(.{ .path = null, .handle = fs.cwd() });
......@@ -772,12 +776,13 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi
772776 if (try man.hit()) {
773777 const digest = man.final();
774778
775 assert(comp.glibc_so_files == null);
776 comp.glibc_so_files = BuiltSharedObjects{
779 return queueSharedObjects(comp, .{
777780 .lock = man.toOwnedLock(),
778 .dir_path = try comp.global_cache_directory.join(comp.gpa, &.{ "o", &digest }),
779 };
780 return;
781 .dir_path = .{
782 .root_dir = comp.global_cache_directory,
783 .sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest),
784 },
785 });
781786 }
782787
783788 const digest = man.final();
......@@ -790,8 +795,8 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi
790795 defer o_directory.handle.close();
791796
792797 const abilists_contents = man.files.keys()[abilists_index].contents.?;
793 const metadata = try loadMetaData(comp.gpa, abilists_contents);
794 defer metadata.destroy(comp.gpa);
798 const metadata = try loadMetaData(gpa, abilists_contents);
799 defer metadata.destroy(gpa);
795800
796801 const target_targ_index = for (metadata.all_targets, 0..) |targ, i| {
797802 if (targ.arch == target.cpu.arch and
......@@ -835,7 +840,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi
835840 map_contents.deinit(); // The most recent allocation of an arena can be freed :)
836841 }
837842
838 var stubs_asm = std.ArrayList(u8).init(comp.gpa);
843 var stubs_asm = std.ArrayList(u8).init(gpa);
839844 defer stubs_asm.deinit();
840845
841846 for (libs, 0..) |lib, lib_i| {
......@@ -1195,7 +1200,6 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi
11951200 var lib_name_buf: [32]u8 = undefined; // Larger than each of the names "c", "pthread", etc.
11961201 const asm_file_basename = std.fmt.bufPrint(&lib_name_buf, "{s}.s", .{lib.name}) catch unreachable;
11971202 try o_directory.handle.writeFile(.{ .sub_path = asm_file_basename, .data = stubs_asm.items });
1198
11991203 try buildSharedLib(comp, arena, comp.global_cache_directory, o_directory, asm_file_basename, lib, prog_node);
12001204 }
12011205
......@@ -1203,11 +1207,44 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi
12031207 log.warn("failed to write cache manifest for glibc stubs: {s}", .{@errorName(err)});
12041208 };
12051209
1206 assert(comp.glibc_so_files == null);
1207 comp.glibc_so_files = .{
1210 return queueSharedObjects(comp, .{
12081211 .lock = man.toOwnedLock(),
1209 .dir_path = try comp.global_cache_directory.join(comp.gpa, &.{ "o", &digest }),
1210 };
1212 .dir_path = .{
1213 .root_dir = comp.global_cache_directory,
1214 .sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest),
1215 },
1216 });
1217}
1218
1219fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void {
1220 const target_version = comp.getTarget().os.version_range.linux.glibc;
1221
1222 assert(comp.glibc_so_files == null);
1223 comp.glibc_so_files = so_files;
1224
1225 var task_buffer: [libs.len]link.File.Task = undefined;
1226 var task_buffer_i: usize = 0;
1227
1228 {
1229 comp.mutex.lock(); // protect comp.arena
1230 defer comp.mutex.unlock();
1231
1232 for (libs) |lib| {
1233 if (lib.removed_in) |rem_in| {
1234 if (target_version.order(rem_in) != .lt) continue;
1235 }
1236 const so_path: Path = .{
1237 .root_dir = so_files.dir_path.root_dir,
1238 .sub_path = std.fmt.allocPrint(comp.arena, "{s}{c}lib{s}.so.{d}", .{
1239 so_files.dir_path.sub_path, fs.path.sep, lib.name, lib.sover,
1240 }) catch return comp.setAllocFailure(),
1241 };
1242 task_buffer[task_buffer_i] = .{ .load_dso = so_path };
1243 task_buffer_i += 1;
1244 }
1245 }
1246
1247 comp.queueLinkTasks(task_buffer[0..task_buffer_i]);
12111248}
12121249
12131250fn buildSharedLib(
src/libcxx.zig+2-2
......@@ -357,7 +357,7 @@ pub fn buildLibCXX(comp: *Compilation, prog_node: std.Progress.Node) BuildError!
357357 assert(comp.libcxx_static_lib == null);
358358 const crt_file = try sub_compilation.toCrtFile();
359359 comp.libcxx_static_lib = crt_file;
360 comp.enqueueLinkTaskMode(crt_file.full_object_path, output_mode);
360 comp.queueLinkTaskMode(crt_file.full_object_path, output_mode);
361361}
362362
363363pub fn buildLibCXXABI(comp: *Compilation, prog_node: std.Progress.Node) BuildError!void {
......@@ -588,7 +588,7 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
588588 assert(comp.libcxxabi_static_lib == null);
589589 const crt_file = try sub_compilation.toCrtFile();
590590 comp.libcxxabi_static_lib = crt_file;
591 comp.enqueueLinkTaskMode(crt_file.full_object_path, output_mode);
591 comp.queueLinkTaskMode(crt_file.full_object_path, output_mode);
592592}
593593
594594pub fn hardeningModeFlag(optimize_mode: std.builtin.OptimizeMode) []const u8 {
src/libtsan.zig+1-1
......@@ -343,7 +343,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
343343 };
344344
345345 const crt_file = try sub_compilation.toCrtFile();
346 comp.enqueueLinkTaskMode(crt_file.full_object_path, output_mode);
346 comp.queueLinkTaskMode(crt_file.full_object_path, output_mode);
347347 assert(comp.tsan_lib == null);
348348 comp.tsan_lib = crt_file;
349349}
src/libunwind.zig+1-1
......@@ -200,7 +200,7 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
200200 };
201201
202202 const crt_file = try sub_compilation.toCrtFile();
203 comp.enqueueLinkTaskMode(crt_file.full_object_path, output_mode);
203 comp.queueLinkTaskMode(crt_file.full_object_path, output_mode);
204204 assert(comp.libunwind_static_lib == null);
205205 comp.libunwind_static_lib = crt_file;
206206}
src/link.zig+5-27
......@@ -1349,12 +1349,14 @@ pub const File = struct {
13491349 /// Does all the tasks in the queue. Runs in exactly one separate thread
13501350 /// from the rest of compilation. All tasks performed here are
13511351 /// single-threaded with respect to one another.
1352 pub fn flushTaskQueue(base: *File, prog_node: std.Progress.Node) void {
1352 pub fn flushTaskQueue(base: *File, parent_prog_node: std.Progress.Node) void {
13531353 const comp = base.comp;
13541354 base.task_queue_safety.lock();
13551355 defer base.task_queue_safety.unlock();
1356 const prog_node = parent_prog_node.start("Parse Linker Inputs", 0);
1357 defer prog_node.end();
13561358 while (comp.link_task_queue.check()) |tasks| {
1357 for (tasks) |task| doTask(base, prog_node, task);
1359 for (tasks) |task| doTask(base, task);
13581360 }
13591361 }
13601362
......@@ -1374,16 +1376,11 @@ pub const File = struct {
13741376 load_input: Input,
13751377 };
13761378
1377 fn doTask(base: *File, parent_prog_node: std.Progress.Node, task: Task) void {
1379 fn doTask(base: *File, task: Task) void {
13781380 const comp = base.comp;
13791381 switch (task) {
13801382 .load_explicitly_provided => {
1381 const prog_node = parent_prog_node.start("Linker Parse Input", comp.link_inputs.len);
1382 defer prog_node.end();
1383
13841383 for (comp.link_inputs) |input| {
1385 const sub_node = prog_node.start(input.taskName(), 0);
1386 defer sub_node.end();
13871384 base.loadInput(input) catch |err| switch (err) {
13881385 error.LinkFailure => return, // error reported via link_diags
13891386 else => |e| {
......@@ -1397,33 +1394,18 @@ pub const File = struct {
13971394 }
13981395 },
13991396 .load_object => |path| {
1400 const prog_node = parent_prog_node.start("Linker Parse Object", 0);
1401 defer prog_node.end();
1402 const sub_node = prog_node.start(path.basename(), 0);
1403 defer sub_node.end();
1404
14051397 base.openLoadObject(path) catch |err| switch (err) {
14061398 error.LinkFailure => return, // error reported via link_diags
14071399 else => |e| comp.link_diags.addParseError(path, "failed to parse object: {s}", .{@errorName(e)}),
14081400 };
14091401 },
14101402 .load_archive => |path| {
1411 const prog_node = parent_prog_node.start("Linker Parse Archive", 0);
1412 defer prog_node.end();
1413 const sub_node = prog_node.start(path.basename(), 0);
1414 defer sub_node.end();
1415
14161403 base.openLoadArchive(path) catch |err| switch (err) {
14171404 error.LinkFailure => return, // error reported via link_diags
14181405 else => |e| comp.link_diags.addParseError(path, "failed to parse archive: {s}", .{@errorName(e)}),
14191406 };
14201407 },
14211408 .load_dso => |path| {
1422 const prog_node = parent_prog_node.start("Linker Parse Shared Library", 0);
1423 defer prog_node.end();
1424 const sub_node = prog_node.start(path.basename(), 0);
1425 defer sub_node.end();
1426
14271409 base.openLoadDso(path, .{
14281410 .preferred_mode = .dynamic,
14291411 .search_strategy = .paths_first,
......@@ -1433,10 +1415,6 @@ pub const File = struct {
14331415 };
14341416 },
14351417 .load_input => |input| {
1436 const prog_node = parent_prog_node.start("Linker Parse Input", 0);
1437 defer prog_node.end();
1438 const sub_node = prog_node.start(input.taskName(), 0);
1439 defer sub_node.end();
14401418 base.loadInput(input) catch |err| switch (err) {
14411419 error.LinkFailure => return, // error reported via link_diags
14421420 else => |e| {
src/link/Elf.zig+60-222
......@@ -114,6 +114,10 @@ comment_merge_section_index: ?Merge.Section.Index = null,
114114
115115first_eflags: ?elf.Word = null,
116116
117/// `--verbose-link` output.
118/// Initialized on creation, appended to as inputs are added, printed during `flush`.
119dump_argv_list: std.ArrayListUnmanaged([]const u8),
120
117121const SectionIndexes = struct {
118122 copy_rel: ?u32 = null,
119123 dynamic: ?u32 = null,
......@@ -338,6 +342,7 @@ pub fn createEmpty(
338342 .enable_new_dtags = options.enable_new_dtags,
339343 .print_icf_sections = options.print_icf_sections,
340344 .print_map = options.print_map,
345 .dump_argv_list = .empty,
341346 };
342347 if (use_llvm and comp.config.have_zcu) {
343348 self.llvm_object = try LlvmObject.create(arena, comp);
......@@ -350,7 +355,7 @@ pub fn createEmpty(
350355 }
351356
352357 // --verbose-link
353 if (comp.verbose_link) try self.dumpArgv(comp);
358 if (comp.verbose_link) try dumpArgvInit(self, arena);
354359
355360 const is_obj = output_mode == .Obj;
356361 const is_obj_or_ar = is_obj or (output_mode == .Lib and link_mode == .static);
......@@ -501,6 +506,7 @@ pub fn deinit(self: *Elf) void {
501506 self.rela_dyn.deinit(gpa);
502507 self.rela_plt.deinit(gpa);
503508 self.comdat_group_sections.deinit(gpa);
509 self.dump_argv_list.deinit(gpa);
504510}
505511
506512pub fn getNavVAddr(self: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, reloc_info: link.File.RelocInfo) !u64 {
......@@ -753,12 +759,23 @@ pub fn allocateChunk(self: *Elf, args: struct {
753759}
754760
755761pub fn loadInput(self: *Elf, input: link.Input) !void {
756 const gpa = self.base.comp.gpa;
757 const diags = &self.base.comp.link_diags;
762 const comp = self.base.comp;
763 const gpa = comp.gpa;
764 const diags = &comp.link_diags;
758765 const target = self.getTarget();
759 const debug_fmt_strip = self.base.comp.config.debug_format == .strip;
766 const debug_fmt_strip = comp.config.debug_format == .strip;
760767 const default_sym_version = self.default_sym_version;
761768
769 if (comp.verbose_link) {
770 const argv = &self.dump_argv_list;
771 switch (input) {
772 .res => unreachable,
773 .dso_exact => |dso_exact| try argv.appendSlice(gpa, &.{ "-l", dso_exact.name }),
774 .object, .archive => |obj| try argv.append(gpa, try obj.path.toString(comp.arena)),
775 .dso => |dso| try argv.append(gpa, try dso.path.toString(comp.arena)),
776 }
777 }
778
762779 switch (input) {
763780 .res => unreachable,
764781 .dso_exact => @panic("TODO"),
......@@ -790,6 +807,8 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod
790807 if (use_lld) return;
791808 }
792809
810 if (comp.verbose_link) Compilation.dump_argv(self.dump_argv_list.items);
811
793812 const sub_prog_node = prog_node.start("ELF Flush", 0);
794813 defer sub_prog_node.end();
795814
......@@ -965,291 +984,110 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod
965984 if (diags.hasErrors()) return error.FlushFailure;
966985}
967986
968/// --verbose-link output
969fn dumpArgv(self: *Elf, comp: *Compilation) !void {
970 const gpa = self.base.comp.gpa;
971 var arena_allocator = std.heap.ArenaAllocator.init(gpa);
972 defer arena_allocator.deinit();
973 const arena = arena_allocator.allocator();
974
987fn dumpArgvInit(self: *Elf, arena: Allocator) !void {
988 const comp = self.base.comp;
989 const gpa = comp.gpa;
975990 const target = self.getTarget();
976 const link_mode = self.base.comp.config.link_mode;
977 const directory = self.base.emit.root_dir; // Just an alias to make it shorter to type.
978 const full_out_path = try directory.join(arena, &[_][]const u8{self.base.emit.sub_path});
979 const module_obj_path: ?[]const u8 = if (self.base.zcu_object_sub_path) |path| blk: {
980 if (fs.path.dirname(full_out_path)) |dirname| {
981 break :blk try fs.path.join(arena, &.{ dirname, path });
982 } else {
983 break :blk path;
984 }
985 } else null;
991 const full_out_path = try self.base.emit.root_dir.join(arena, &[_][]const u8{self.base.emit.sub_path});
986992
987 const crt_basenames = std.zig.LibCInstallation.CrtBasenames.get(.{
988 .target = target,
989 .link_libc = comp.config.link_libc,
990 .output_mode = comp.config.output_mode,
991 .link_mode = link_mode,
992 .pie = comp.config.pie,
993 });
994 const crt_paths: std.zig.LibCInstallation.CrtPaths = if (comp.libc_installation) |lci|
995 try lci.resolveCrtPaths(arena, crt_basenames, target)
996 else
997 .{};
998 const compiler_rt_path: ?[]const u8 = blk: {
999 if (comp.compiler_rt_lib) |x| break :blk try x.full_object_path.toString(arena);
1000 if (comp.compiler_rt_obj) |x| break :blk try x.full_object_path.toString(arena);
1001 break :blk null;
1002 };
993 const argv = &self.dump_argv_list;
1003994
1004 var argv = std.ArrayList([]const u8).init(arena);
1005
1006 try argv.append("zig");
995 try argv.append(gpa, "zig");
1007996
1008997 if (self.base.isStaticLib()) {
1009 try argv.append("ar");
998 try argv.append(gpa, "ar");
1010999 } else {
1011 try argv.append("ld");
1000 try argv.append(gpa, "ld");
10121001 }
10131002
10141003 if (self.base.isObject()) {
1015 try argv.append("-r");
1004 try argv.append(gpa, "-r");
10161005 }
10171006
1018 try argv.append("-o");
1019 try argv.append(full_out_path);
1020
1021 if (self.base.isRelocatable()) {
1022 for (self.base.comp.link_inputs) |link_input| switch (link_input) {
1023 .res => unreachable,
1024 .dso => |dso| try argv.append(try dso.path.toString(arena)),
1025 .object, .archive => |obj| try argv.append(try obj.path.toString(arena)),
1026 .dso_exact => |dso_exact| {
1027 assert(dso_exact.name[0] == ':');
1028 try argv.appendSlice(&.{ "-l", dso_exact.name });
1029 },
1030 };
1031
1032 for (comp.c_object_table.keys()) |key| {
1033 try argv.append(try key.status.success.object_path.toString(arena));
1034 }
1007 try argv.append(gpa, "-o");
1008 try argv.append(gpa, full_out_path);
10351009
1036 if (module_obj_path) |p| {
1037 try argv.append(p);
1038 }
1039 } else {
1010 if (!self.base.isRelocatable()) {
10401011 if (!self.base.isStatic()) {
10411012 if (target.dynamic_linker.get()) |path| {
1042 try argv.append("-dynamic-linker");
1043 try argv.append(path);
1013 try argv.appendSlice(gpa, &.{ "-dynamic-linker", try arena.dupe(u8, path) });
10441014 }
10451015 }
10461016
10471017 if (self.base.isDynLib()) {
10481018 if (self.soname) |name| {
1049 try argv.append("-soname");
1050 try argv.append(name);
1019 try argv.append(gpa, "-soname");
1020 try argv.append(gpa, name);
10511021 }
10521022 }
10531023
10541024 if (self.entry_name) |name| {
1055 try argv.appendSlice(&.{ "--entry", name });
1025 try argv.appendSlice(gpa, &.{ "--entry", name });
10561026 }
10571027
10581028 for (self.rpath_table.keys()) |rpath| {
1059 try argv.appendSlice(&.{ "-rpath", rpath });
1029 try argv.appendSlice(gpa, &.{ "-rpath", rpath });
10601030 }
10611031
1062 try argv.appendSlice(&.{
1032 try argv.appendSlice(gpa, &.{
10631033 "-z",
10641034 try std.fmt.allocPrint(arena, "stack-size={d}", .{self.base.stack_size}),
10651035 });
10661036
1067 try argv.append(try std.fmt.allocPrint(arena, "--image-base={d}", .{self.image_base}));
1037 try argv.append(gpa, try std.fmt.allocPrint(arena, "--image-base={d}", .{self.image_base}));
10681038
10691039 if (self.base.gc_sections) {
1070 try argv.append("--gc-sections");
1040 try argv.append(gpa, "--gc-sections");
10711041 }
10721042
10731043 if (self.base.print_gc_sections) {
1074 try argv.append("--print-gc-sections");
1044 try argv.append(gpa, "--print-gc-sections");
10751045 }
10761046
10771047 if (comp.link_eh_frame_hdr) {
1078 try argv.append("--eh-frame-hdr");
1048 try argv.append(gpa, "--eh-frame-hdr");
10791049 }
10801050
10811051 if (comp.config.rdynamic) {
1082 try argv.append("--export-dynamic");
1052 try argv.append(gpa, "--export-dynamic");
10831053 }
10841054
10851055 if (self.z_notext) {
1086 try argv.append("-z");
1087 try argv.append("notext");
1056 try argv.append(gpa, "-z");
1057 try argv.append(gpa, "notext");
10881058 }
10891059
10901060 if (self.z_nocopyreloc) {
1091 try argv.append("-z");
1092 try argv.append("nocopyreloc");
1061 try argv.append(gpa, "-z");
1062 try argv.append(gpa, "nocopyreloc");
10931063 }
10941064
10951065 if (self.z_now) {
1096 try argv.append("-z");
1097 try argv.append("now");
1066 try argv.append(gpa, "-z");
1067 try argv.append(gpa, "now");
10981068 }
10991069
11001070 if (self.base.isStatic()) {
1101 try argv.append("-static");
1071 try argv.append(gpa, "-static");
11021072 } else if (self.isEffectivelyDynLib()) {
1103 try argv.append("-shared");
1073 try argv.append(gpa, "-shared");
11041074 }
11051075
11061076 if (comp.config.pie and self.base.isExe()) {
1107 try argv.append("-pie");
1077 try argv.append(gpa, "-pie");
11081078 }
11091079
11101080 if (comp.config.debug_format == .strip) {
1111 try argv.append("-s");
1081 try argv.append(gpa, "-s");
11121082 }
11131083
1114 if (crt_paths.crt0) |path| try argv.append(try path.toString(arena));
1115 if (crt_paths.crti) |path| try argv.append(try path.toString(arena));
1116 if (crt_paths.crtbegin) |path| try argv.append(try path.toString(arena));
1117
11181084 if (comp.config.link_libc) {
1119 if (self.base.comp.libc_installation) |libc_installation| {
1120 try argv.append("-L");
1121 try argv.append(libc_installation.crt_dir.?);
1085 if (self.base.comp.libc_installation) |lci| {
1086 try argv.append(gpa, "-L");
1087 try argv.append(gpa, lci.crt_dir.?);
11221088 }
11231089 }
1124
1125 var whole_archive = false;
1126
1127 for (self.base.comp.link_inputs) |link_input| switch (link_input) {
1128 .res => unreachable,
1129 .dso => continue,
1130 .object, .archive => |obj| {
1131 if (obj.must_link and !whole_archive) {
1132 try argv.append("-whole-archive");
1133 whole_archive = true;
1134 } else if (!obj.must_link and whole_archive) {
1135 try argv.append("-no-whole-archive");
1136 whole_archive = false;
1137 }
1138 try argv.append(try obj.path.toString(arena));
1139 },
1140 .dso_exact => |dso_exact| {
1141 assert(dso_exact.name[0] == ':');
1142 try argv.appendSlice(&.{ "-l", dso_exact.name });
1143 },
1144 };
1145
1146 if (whole_archive) {
1147 try argv.append("-no-whole-archive");
1148 whole_archive = false;
1149 }
1150
1151 for (comp.c_object_table.keys()) |key| {
1152 try argv.append(try key.status.success.object_path.toString(arena));
1153 }
1154
1155 if (module_obj_path) |p| {
1156 try argv.append(p);
1157 }
1158
1159 if (comp.config.any_sanitize_thread) {
1160 try argv.append(try comp.tsan_lib.?.full_object_path.toString(arena));
1161 }
1162
1163 if (comp.config.any_fuzz) {
1164 try argv.append(try comp.fuzzer_lib.?.full_object_path.toString(arena));
1165 }
1166
1167 // libc
1168 if (!comp.skip_linker_dependencies and !comp.config.link_libc) {
1169 if (comp.libc_static_lib) |lib| {
1170 try argv.append(try lib.full_object_path.toString(arena));
1171 }
1172 }
1173
1174 // Shared libraries.
1175 // Worst-case, we need an --as-needed argument for every lib, as well
1176 // as one before and one after.
1177 argv.appendAssumeCapacity("--as-needed");
1178 var as_needed = true;
1179
1180 for (self.base.comp.link_inputs) |link_input| switch (link_input) {
1181 .object, .archive, .dso_exact => continue,
1182 .dso => |dso| {
1183 const lib_as_needed = !dso.needed;
1184 switch ((@as(u2, @intFromBool(lib_as_needed)) << 1) | @intFromBool(as_needed)) {
1185 0b00, 0b11 => {},
1186 0b01 => {
1187 try argv.append("--no-as-needed");
1188 as_needed = false;
1189 },
1190 0b10 => {
1191 try argv.append("--as-needed");
1192 as_needed = true;
1193 },
1194 }
1195 argv.appendAssumeCapacity(try dso.path.toString(arena));
1196 },
1197 .res => unreachable,
1198 };
1199
1200 if (!as_needed) {
1201 argv.appendAssumeCapacity("--as-needed");
1202 as_needed = true;
1203 }
1204
1205 // libc++ dep
1206 if (comp.config.link_libcpp) {
1207 try argv.append(try comp.libcxxabi_static_lib.?.full_object_path.toString(arena));
1208 try argv.append(try comp.libcxx_static_lib.?.full_object_path.toString(arena));
1209 }
1210
1211 // libunwind dep
1212 if (comp.config.link_libunwind) {
1213 try argv.append(try comp.libunwind_static_lib.?.full_object_path.toString(arena));
1214 }
1215
1216 // libc dep
1217 if (comp.config.link_libc) {
1218 if (self.base.comp.libc_installation != null) {
1219 const needs_grouping = link_mode == .static;
1220 if (needs_grouping) try argv.append("--start-group");
1221 try argv.appendSlice(target_util.libcFullLinkFlags(target));
1222 if (needs_grouping) try argv.append("--end-group");
1223 } else if (target.isGnuLibC()) {
1224 for (glibc.libs) |lib| {
1225 if (lib.removed_in) |rem_in| {
1226 if (target.os.version_range.linux.glibc.order(rem_in) != .lt) continue;
1227 }
1228
1229 const lib_path = try std.fmt.allocPrint(arena, "{s}{c}lib{s}.so.{d}", .{
1230 comp.glibc_so_files.?.dir_path, fs.path.sep, lib.name, lib.sover,
1231 });
1232 try argv.append(lib_path);
1233 }
1234 try argv.append(try comp.crtFileAsString(arena, "libc_nonshared.a"));
1235 } else if (target.isMusl()) {
1236 try argv.append(try comp.crtFileAsString(arena, switch (link_mode) {
1237 .static => "libc.a",
1238 .dynamic => "libc.so",
1239 }));
1240 }
1241 }
1242
1243 // compiler-rt
1244 if (compiler_rt_path) |p| {
1245 try argv.append(p);
1246 }
1247
1248 if (crt_paths.crtend) |path| try argv.append(try path.toString(arena));
1249 if (crt_paths.crtn) |path| try argv.append(try path.toString(arena));
12501090 }
1251
1252 Compilation.dump_argv(argv.items);
12531091}
12541092
12551093pub const ParseError = error{
......@@ -2177,7 +2015,7 @@ fn linkWithLLD(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: s
21772015 if (target.os.version_range.linux.glibc.order(rem_in) != .lt) continue;
21782016 }
21792017
2180 const lib_path = try std.fmt.allocPrint(arena, "{s}{c}lib{s}.so.{d}", .{
2018 const lib_path = try std.fmt.allocPrint(arena, "{}{c}lib{s}.so.{d}", .{
21812019 comp.glibc_so_files.?.dir_path, fs.path.sep, lib.name, lib.sover,
21822020 });
21832021 try argv.append(lib_path);
src/musl.zig+1-1
......@@ -281,7 +281,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro
281281 errdefer comp.gpa.free(basename);
282282
283283 const crt_file = try sub_compilation.toCrtFile();
284 comp.enqueueLinkTaskMode(crt_file.full_object_path, output_mode);
284 comp.queueLinkTaskMode(crt_file.full_object_path, output_mode);
285285 {
286286 comp.mutex.lock();
287287 defer comp.mutex.unlock();