| author | |
| committer | |
| log | 75b6637d6013b735d36da0ab6e5655002a1b59e9 |
| tree | 76d3d25d4307138e34450da7ca30310f12197941 |
| parent | 7e76aab98abe94e01cfd8b01ce288360ed67dbc7 |
| parent | 5cde5f947fa12440463f684d9417ac00c8b9790a |
| signature |
zld: a couple of fixes which result in better rustc support9 files changed, 150 insertions(+), 32 deletions(-)
src/Compilation.zig+13-4| ... | ... | @@ -654,6 +654,11 @@ pub const ClangPreprocessorMode = enum { |
| 654 | 654 | pub const SystemLib = link.SystemLib; |
| 655 | 655 | pub const CacheMode = link.CacheMode; |
| 656 | 656 | |
| 657 | pub const LinkObject = struct { | |
| 658 | path: []const u8, | |
| 659 | must_link: bool = false, | |
| 660 | }; | |
| 661 | ||
| 657 | 662 | pub const InitOptions = struct { |
| 658 | 663 | zig_lib_directory: Directory, |
| 659 | 664 | local_cache_directory: Directory, |
| ... | ... | @@ -698,7 +703,7 @@ pub const InitOptions = struct { |
| 698 | 703 | lib_dirs: []const []const u8 = &[0][]const u8{}, |
| 699 | 704 | rpath_list: []const []const u8 = &[0][]const u8{}, |
| 700 | 705 | c_source_files: []const CSourceFile = &[0]CSourceFile{}, |
| 701 | link_objects: []const []const u8 = &[0][]const u8{}, | |
| 706 | link_objects: []LinkObject = &[0]LinkObject{}, | |
| 702 | 707 | framework_dirs: []const []const u8 = &[0][]const u8{}, |
| 703 | 708 | frameworks: []const []const u8 = &[0][]const u8{}, |
| 704 | 709 | system_lib_names: []const []const u8 = &.{}, |
| ... | ... | @@ -1056,7 +1061,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1056 | 1061 | if (options.system_lib_names.len != 0) |
| 1057 | 1062 | break :x true; |
| 1058 | 1063 | for (options.link_objects) |obj| { |
| 1059 | switch (classifyFileExt(obj)) { | |
| 1064 | switch (classifyFileExt(obj.path)) { | |
| 1060 | 1065 | .shared_library => break :x true, |
| 1061 | 1066 | else => continue, |
| 1062 | 1067 | } |
| ... | ... | @@ -1459,7 +1464,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1459 | 1464 | if (options.c_source_files.len >= 1) { |
| 1460 | 1465 | hash.addBytes(options.c_source_files[0].src_path); |
| 1461 | 1466 | } else if (options.link_objects.len >= 1) { |
| 1462 | hash.addBytes(options.link_objects[0]); | |
| 1467 | hash.addBytes(options.link_objects[0].path); | |
| 1463 | 1468 | } |
| 1464 | 1469 | |
| 1465 | 1470 | const digest = hash.final(); |
| ... | ... | @@ -2265,7 +2270,11 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes |
| 2265 | 2270 | |
| 2266 | 2271 | try man.addOptionalFile(comp.bin_file.options.linker_script); |
| 2267 | 2272 | try man.addOptionalFile(comp.bin_file.options.version_script); |
| 2268 | try man.addListOfFiles(comp.bin_file.options.objects); | |
| 2273 | ||
| 2274 | for (comp.bin_file.options.objects) |obj| { | |
| 2275 | _ = try man.addFile(obj.path, null); | |
| 2276 | man.hash.add(obj.must_link); | |
| 2277 | } | |
| 2269 | 2278 | |
| 2270 | 2279 | for (comp.c_object_table.keys()) |key| { |
| 2271 | 2280 | _ = try man.addFile(key.src.src_path, null); |
src/link.zig+7-4| ... | ... | @@ -155,7 +155,7 @@ pub const Options = struct { |
| 155 | 155 | soname: ?[]const u8, |
| 156 | 156 | llvm_cpu_features: ?[*:0]const u8, |
| 157 | 157 | |
| 158 | objects: []const []const u8, | |
| 158 | objects: []Compilation.LinkObject, | |
| 159 | 159 | framework_dirs: []const []const u8, |
| 160 | 160 | frameworks: []const []const u8, |
| 161 | 161 | system_libs: std.StringArrayHashMapUnmanaged(SystemLib), |
| ... | ... | @@ -755,7 +755,10 @@ pub const File = struct { |
| 755 | 755 | // We are about to obtain this lock, so here we give other processes a chance first. |
| 756 | 756 | base.releaseLock(); |
| 757 | 757 | |
| 758 | try man.addListOfFiles(base.options.objects); | |
| 758 | for (base.options.objects) |obj| { | |
| 759 | _ = try man.addFile(obj.path, null); | |
| 760 | man.hash.add(obj.must_link); | |
| 761 | } | |
| 759 | 762 | for (comp.c_object_table.keys()) |key| { |
| 760 | 763 | _ = try man.addFile(key.status.success.object_path, null); |
| 761 | 764 | } |
| ... | ... | @@ -792,8 +795,8 @@ pub const File = struct { |
| 792 | 795 | var object_files = try std.ArrayList([*:0]const u8).initCapacity(base.allocator, num_object_files); |
| 793 | 796 | defer object_files.deinit(); |
| 794 | 797 | |
| 795 | for (base.options.objects) |obj_path| { | |
| 796 | object_files.appendAssumeCapacity(try arena.dupeZ(u8, obj_path)); | |
| 798 | for (base.options.objects) |obj| { | |
| 799 | object_files.appendAssumeCapacity(try arena.dupeZ(u8, obj.path)); | |
| 797 | 800 | } |
| 798 | 801 | for (comp.c_object_table.keys()) |key| { |
| 799 | 802 | object_files.appendAssumeCapacity(try arena.dupeZ(u8, key.status.success.object_path)); |
src/link/Coff.zig+9-3| ... | ... | @@ -943,7 +943,10 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { |
| 943 | 943 | |
| 944 | 944 | comptime assert(Compilation.link_hash_implementation_version == 1); |
| 945 | 945 | |
| 946 | try man.addListOfFiles(self.base.options.objects); | |
| 946 | for (self.base.options.objects) |obj| { | |
| 947 | _ = try man.addFile(obj.path, null); | |
| 948 | man.hash.add(obj.must_link); | |
| 949 | } | |
| 947 | 950 | for (comp.c_object_table.keys()) |key| { |
| 948 | 951 | _ = try man.addFile(key.status.success.object_path, null); |
| 949 | 952 | } |
| ... | ... | @@ -1005,7 +1008,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { |
| 1005 | 1008 | // build-obj. See also the corresponding TODO in linkAsArchive. |
| 1006 | 1009 | const the_object_path = blk: { |
| 1007 | 1010 | if (self.base.options.objects.len != 0) |
| 1008 | break :blk self.base.options.objects[0]; | |
| 1011 | break :blk self.base.options.objects[0].path; | |
| 1009 | 1012 | |
| 1010 | 1013 | if (comp.c_object_table.count() != 0) |
| 1011 | 1014 | break :blk comp.c_object_table.keys()[0].status.success.object_path; |
| ... | ... | @@ -1110,7 +1113,10 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { |
| 1110 | 1113 | try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{lib_dir})); |
| 1111 | 1114 | } |
| 1112 | 1115 | |
| 1113 | try argv.appendSlice(self.base.options.objects); | |
| 1116 | try argv.ensureUnusedCapacity(self.base.options.objects.len); | |
| 1117 | for (self.base.options.objects) |obj| { | |
| 1118 | argv.appendAssumeCapacity(obj.path); | |
| 1119 | } | |
| 1114 | 1120 | |
| 1115 | 1121 | for (comp.c_object_table.keys()) |key| { |
| 1116 | 1122 | try argv.append(key.status.success.object_path); |
src/link/Elf.zig+9-3| ... | ... | @@ -1384,7 +1384,10 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1384 | 1384 | |
| 1385 | 1385 | try man.addOptionalFile(self.base.options.linker_script); |
| 1386 | 1386 | try man.addOptionalFile(self.base.options.version_script); |
| 1387 | try man.addListOfFiles(self.base.options.objects); | |
| 1387 | for (self.base.options.objects) |obj| { | |
| 1388 | _ = try man.addFile(obj.path, null); | |
| 1389 | man.hash.add(obj.must_link); | |
| 1390 | } | |
| 1388 | 1391 | for (comp.c_object_table.keys()) |key| { |
| 1389 | 1392 | _ = try man.addFile(key.status.success.object_path, null); |
| 1390 | 1393 | } |
| ... | ... | @@ -1469,7 +1472,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1469 | 1472 | // build-obj. See also the corresponding TODO in linkAsArchive. |
| 1470 | 1473 | const the_object_path = blk: { |
| 1471 | 1474 | if (self.base.options.objects.len != 0) |
| 1472 | break :blk self.base.options.objects[0]; | |
| 1475 | break :blk self.base.options.objects[0].path; | |
| 1473 | 1476 | |
| 1474 | 1477 | if (comp.c_object_table.count() != 0) |
| 1475 | 1478 | break :blk comp.c_object_table.keys()[0].status.success.object_path; |
| ... | ... | @@ -1678,7 +1681,10 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1678 | 1681 | } |
| 1679 | 1682 | |
| 1680 | 1683 | // Positional arguments to the linker such as object files. |
| 1681 | try argv.appendSlice(self.base.options.objects); | |
| 1684 | try argv.ensureUnusedCapacity(self.base.options.objects.len); | |
| 1685 | for (self.base.options.objects) |obj| { | |
| 1686 | argv.appendAssumeCapacity(obj.path); | |
| 1687 | } | |
| 1682 | 1688 | |
| 1683 | 1689 | for (comp.c_object_table.keys()) |key| { |
| 1684 | 1690 | try argv.append(key.status.success.object_path); |
src/link/MachO.zig+86-8| ... | ... | @@ -141,6 +141,9 @@ objc_selrefs_section_index: ?u16 = null, |
| 141 | 141 | objc_classrefs_section_index: ?u16 = null, |
| 142 | 142 | objc_data_section_index: ?u16 = null, |
| 143 | 143 | |
| 144 | rustc_section_index: ?u16 = null, | |
| 145 | rustc_section_size: u64 = 0, | |
| 146 | ||
| 144 | 147 | bss_file_offset: u32 = 0, |
| 145 | 148 | tlv_bss_file_offset: u32 = 0, |
| 146 | 149 | |
| ... | ... | @@ -496,7 +499,10 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { |
| 496 | 499 | |
| 497 | 500 | comptime assert(Compilation.link_hash_implementation_version == 1); |
| 498 | 501 | |
| 499 | try man.addListOfFiles(self.base.options.objects); | |
| 502 | for (self.base.options.objects) |obj| { | |
| 503 | _ = try man.addFile(obj.path, null); | |
| 504 | man.hash.add(obj.must_link); | |
| 505 | } | |
| 500 | 506 | for (comp.c_object_table.keys()) |key| { |
| 501 | 507 | _ = try man.addFile(key.status.success.object_path, null); |
| 502 | 508 | } |
| ... | ... | @@ -568,8 +574,9 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { |
| 568 | 574 | // here. TODO: think carefully about how we can avoid this redundant operation when doing |
| 569 | 575 | // build-obj. See also the corresponding TODO in linkAsArchive. |
| 570 | 576 | const the_object_path = blk: { |
| 571 | if (self.base.options.objects.len != 0) | |
| 572 | break :blk self.base.options.objects[0]; | |
| 577 | if (self.base.options.objects.len != 0) { | |
| 578 | break :blk self.base.options.objects[0].path; | |
| 579 | } | |
| 573 | 580 | |
| 574 | 581 | if (comp.c_object_table.count() != 0) |
| 575 | 582 | break :blk comp.c_object_table.keys()[0].status.success.object_path; |
| ... | ... | @@ -678,8 +685,19 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { |
| 678 | 685 | |
| 679 | 686 | // Positional arguments to the linker such as object files and static archives. |
| 680 | 687 | var positionals = std.ArrayList([]const u8).init(arena); |
| 688 | try positionals.ensureUnusedCapacity(self.base.options.objects.len); | |
| 681 | 689 | |
| 682 | try positionals.appendSlice(self.base.options.objects); | |
| 690 | var must_link_archives = std.StringArrayHashMap(void).init(arena); | |
| 691 | try must_link_archives.ensureUnusedCapacity(self.base.options.objects.len); | |
| 692 | ||
| 693 | for (self.base.options.objects) |obj| { | |
| 694 | if (must_link_archives.contains(obj.path)) continue; | |
| 695 | if (obj.must_link) { | |
| 696 | _ = must_link_archives.getOrPutAssumeCapacity(obj.path); | |
| 697 | } else { | |
| 698 | _ = positionals.appendAssumeCapacity(obj.path); | |
| 699 | } | |
| 700 | } | |
| 683 | 701 | |
| 684 | 702 | for (comp.c_object_table.keys()) |key| { |
| 685 | 703 | try positionals.append(key.status.success.object_path); |
| ... | ... | @@ -886,12 +904,17 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { |
| 886 | 904 | try argv.append("dynamic_lookup"); |
| 887 | 905 | } |
| 888 | 906 | |
| 907 | for (must_link_archives.keys()) |lib| { | |
| 908 | try argv.append(try std.fmt.allocPrint(arena, "-force_load {s}", .{lib})); | |
| 909 | } | |
| 910 | ||
| 889 | 911 | Compilation.dump_argv(argv.items); |
| 890 | 912 | } |
| 891 | 913 | |
| 892 | 914 | var dependent_libs = std.fifo.LinearFifo(Dylib.Id, .Dynamic).init(self.base.allocator); |
| 893 | 915 | defer dependent_libs.deinit(); |
| 894 | 916 | try self.parseInputFiles(positionals.items, self.base.options.sysroot, &dependent_libs); |
| 917 | try self.parseAndForceLoadStaticArchives(must_link_archives.keys()); | |
| 895 | 918 | try self.parseLibs(libs.items, self.base.options.sysroot, &dependent_libs); |
| 896 | 919 | try self.parseDependentLibs(self.base.options.sysroot, &dependent_libs); |
| 897 | 920 | } |
| ... | ... | @@ -993,6 +1016,11 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { |
| 993 | 1016 | try self.writeAtoms(); |
| 994 | 1017 | } |
| 995 | 1018 | |
| 1019 | if (self.rustc_section_index) |id| { | |
| 1020 | const seg = &self.load_commands.items[self.data_segment_cmd_index.?].segment; | |
| 1021 | const sect = &seg.sections.items[id]; | |
| 1022 | sect.size = self.rustc_section_size; | |
| 1023 | } | |
| 996 | 1024 | if (self.bss_section_index) |idx| { |
| 997 | 1025 | const seg = &self.load_commands.items[self.data_segment_cmd_index.?].segment; |
| 998 | 1026 | const sect = &seg.sections.items[idx]; |
| ... | ... | @@ -1195,7 +1223,7 @@ fn parseObject(self: *MachO, path: []const u8) !bool { |
| 1195 | 1223 | return true; |
| 1196 | 1224 | } |
| 1197 | 1225 | |
| 1198 | fn parseArchive(self: *MachO, path: []const u8) !bool { | |
| 1226 | fn parseArchive(self: *MachO, path: []const u8, force_load: bool) !bool { | |
| 1199 | 1227 | const file = fs.cwd().openFile(path, .{}) catch |err| switch (err) { |
| 1200 | 1228 | error.FileNotFound => return false, |
| 1201 | 1229 | else => |e| return e, |
| ... | ... | @@ -1218,7 +1246,23 @@ fn parseArchive(self: *MachO, path: []const u8) !bool { |
| 1218 | 1246 | else => |e| return e, |
| 1219 | 1247 | }; |
| 1220 | 1248 | |
| 1221 | try self.archives.append(self.base.allocator, archive); | |
| 1249 | if (force_load) { | |
| 1250 | defer archive.deinit(self.base.allocator); | |
| 1251 | // Get all offsets from the ToC | |
| 1252 | var offsets = std.AutoArrayHashMap(u32, void).init(self.base.allocator); | |
| 1253 | defer offsets.deinit(); | |
| 1254 | for (archive.toc.values()) |offs| { | |
| 1255 | for (offs.items) |off| { | |
| 1256 | _ = try offsets.getOrPut(off); | |
| 1257 | } | |
| 1258 | } | |
| 1259 | for (offsets.keys()) |off| { | |
| 1260 | const object = try self.objects.addOne(self.base.allocator); | |
| 1261 | object.* = try archive.parseObject(self.base.allocator, self.base.options.target, off); | |
| 1262 | } | |
| 1263 | } else { | |
| 1264 | try self.archives.append(self.base.allocator, archive); | |
| 1265 | } | |
| 1222 | 1266 | |
| 1223 | 1267 | return true; |
| 1224 | 1268 | } |
| ... | ... | @@ -1303,7 +1347,7 @@ fn parseInputFiles(self: *MachO, files: []const []const u8, syslibroot: ?[]const |
| 1303 | 1347 | log.debug("parsing input file path '{s}'", .{full_path}); |
| 1304 | 1348 | |
| 1305 | 1349 | if (try self.parseObject(full_path)) continue; |
| 1306 | if (try self.parseArchive(full_path)) continue; | |
| 1350 | if (try self.parseArchive(full_path, false)) continue; | |
| 1307 | 1351 | if (try self.parseDylib(full_path, .{ |
| 1308 | 1352 | .syslibroot = syslibroot, |
| 1309 | 1353 | .dependent_libs = dependent_libs, |
| ... | ... | @@ -1313,6 +1357,21 @@ fn parseInputFiles(self: *MachO, files: []const []const u8, syslibroot: ?[]const |
| 1313 | 1357 | } |
| 1314 | 1358 | } |
| 1315 | 1359 | |
| 1360 | fn parseAndForceLoadStaticArchives(self: *MachO, files: []const []const u8) !void { | |
| 1361 | for (files) |file_name| { | |
| 1362 | const full_path = full_path: { | |
| 1363 | var buffer: [fs.MAX_PATH_BYTES]u8 = undefined; | |
| 1364 | const path = try fs.realpath(file_name, &buffer); | |
| 1365 | break :full_path try self.base.allocator.dupe(u8, path); | |
| 1366 | }; | |
| 1367 | defer self.base.allocator.free(full_path); | |
| 1368 | log.debug("parsing and force loading static archive '{s}'", .{full_path}); | |
| 1369 | ||
| 1370 | if (try self.parseArchive(full_path, true)) continue; | |
| 1371 | log.warn("unknown filetype: expected static archive: '{s}'", .{file_name}); | |
| 1372 | } | |
| 1373 | } | |
| 1374 | ||
| 1316 | 1375 | fn parseLibs(self: *MachO, libs: []const []const u8, syslibroot: ?[]const u8, dependent_libs: anytype) !void { |
| 1317 | 1376 | for (libs) |lib| { |
| 1318 | 1377 | log.debug("parsing lib path '{s}'", .{lib}); |
| ... | ... | @@ -1320,7 +1379,7 @@ fn parseLibs(self: *MachO, libs: []const []const u8, syslibroot: ?[]const u8, de |
| 1320 | 1379 | .syslibroot = syslibroot, |
| 1321 | 1380 | .dependent_libs = dependent_libs, |
| 1322 | 1381 | })) continue; |
| 1323 | if (try self.parseArchive(lib)) continue; | |
| 1382 | if (try self.parseArchive(lib, false)) continue; | |
| 1324 | 1383 | |
| 1325 | 1384 | log.warn("unknown filetype for a library: '{s}'", .{lib}); |
| 1326 | 1385 | } |
| ... | ... | @@ -1886,6 +1945,24 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1886 | 1945 | .seg = self.data_segment_cmd_index.?, |
| 1887 | 1946 | .sect = self.objc_data_section_index.?, |
| 1888 | 1947 | }; |
| 1948 | } else if (mem.eql(u8, sectname, ".rustc")) { | |
| 1949 | if (self.rustc_section_index == null) { | |
| 1950 | self.rustc_section_index = try self.initSection( | |
| 1951 | self.data_segment_cmd_index.?, | |
| 1952 | ".rustc", | |
| 1953 | sect.size, | |
| 1954 | sect.@"align", | |
| 1955 | .{}, | |
| 1956 | ); | |
| 1957 | // We need to preserve the section size for rustc to properly | |
| 1958 | // decompress the metadata. | |
| 1959 | self.rustc_section_size = sect.size; | |
| 1960 | } | |
| 1961 | ||
| 1962 | break :blk .{ | |
| 1963 | .seg = self.data_segment_cmd_index.?, | |
| 1964 | .sect = self.rustc_section_index.?, | |
| 1965 | }; | |
| 1889 | 1966 | } else { |
| 1890 | 1967 | if (self.data_section_index == null) { |
| 1891 | 1968 | self.data_section_index = try self.initSection( |
| ... | ... | @@ -5212,6 +5289,7 @@ fn sortSections(self: *MachO) !void { |
| 5212 | 5289 | |
| 5213 | 5290 | // __DATA segment |
| 5214 | 5291 | const indices = &[_]*?u16{ |
| 5292 | &self.rustc_section_index, | |
| 5215 | 5293 | &self.la_symbol_ptr_section_index, |
| 5216 | 5294 | &self.objc_const_section_index, |
| 5217 | 5295 | &self.objc_selrefs_section_index, |
src/link/MachO/Atom.zig+2-1| ... | ... | @@ -419,6 +419,7 @@ pub fn parseRelocs(self: *Atom, relocs: []macho.relocation_info, context: RelocC |
| 419 | 419 | .X86_64_RELOC_BRANCH => { |
| 420 | 420 | // TODO rewrite relocation |
| 421 | 421 | try addStub(target, context); |
| 422 | addend = mem.readIntLittle(i32, self.code.items[offset..][0..4]); | |
| 422 | 423 | }, |
| 423 | 424 | .X86_64_RELOC_GOT, .X86_64_RELOC_GOT_LOAD => { |
| 424 | 425 | // TODO rewrite relocation |
| ... | ... | @@ -1003,7 +1004,7 @@ pub fn resolveRelocs(self: *Atom, macho_file: *MachO) !void { |
| 1003 | 1004 | .X86_64_RELOC_BRANCH => { |
| 1004 | 1005 | const displacement = try math.cast( |
| 1005 | 1006 | i32, |
| 1006 | @intCast(i64, target_addr) - @intCast(i64, source_addr) - 4, | |
| 1007 | @intCast(i64, target_addr) - @intCast(i64, source_addr) - 4 + rel.addend, | |
| 1007 | 1008 | ); |
| 1008 | 1009 | mem.writeIntLittle(u32, self.code.items[rel.offset..][0..4], @bitCast(u32, displacement)); |
| 1009 | 1010 | }, |
src/link/MachO/Object.zig+1-1| ... | ... | @@ -409,7 +409,7 @@ pub fn parseIntoAtoms(self: *Object, allocator: Allocator, macho_file: *MachO) ! |
| 409 | 409 | } else blk: { |
| 410 | 410 | var iundefsym: usize = sorted_all_nlists.items.len; |
| 411 | 411 | while (iundefsym > 0) : (iundefsym -= 1) { |
| 412 | const nlist = sorted_all_nlists.items[iundefsym]; | |
| 412 | const nlist = sorted_all_nlists.items[iundefsym - 1]; | |
| 413 | 413 | if (nlist.nlist.sect()) break; |
| 414 | 414 | } |
| 415 | 415 | break :blk iundefsym; |
src/link/Wasm.zig+9-3| ... | ... | @@ -1128,7 +1128,10 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { |
| 1128 | 1128 | |
| 1129 | 1129 | comptime assert(Compilation.link_hash_implementation_version == 1); |
| 1130 | 1130 | |
| 1131 | try man.addListOfFiles(self.base.options.objects); | |
| 1131 | for (self.base.options.objects) |obj| { | |
| 1132 | _ = try man.addFile(obj.path, null); | |
| 1133 | man.hash.add(obj.must_link); | |
| 1134 | } | |
| 1132 | 1135 | for (comp.c_object_table.keys()) |key| { |
| 1133 | 1136 | _ = try man.addFile(key.status.success.object_path, null); |
| 1134 | 1137 | } |
| ... | ... | @@ -1181,7 +1184,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { |
| 1181 | 1184 | // build-obj. See also the corresponding TODO in linkAsArchive. |
| 1182 | 1185 | const the_object_path = blk: { |
| 1183 | 1186 | if (self.base.options.objects.len != 0) |
| 1184 | break :blk self.base.options.objects[0]; | |
| 1187 | break :blk self.base.options.objects[0].path; | |
| 1185 | 1188 | |
| 1186 | 1189 | if (comp.c_object_table.count() != 0) |
| 1187 | 1190 | break :blk comp.c_object_table.keys()[0].status.success.object_path; |
| ... | ... | @@ -1346,7 +1349,10 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { |
| 1346 | 1349 | } |
| 1347 | 1350 | |
| 1348 | 1351 | // Positional arguments to the linker such as object files. |
| 1349 | try argv.appendSlice(self.base.options.objects); | |
| 1352 | try argv.ensureUnusedCapacity(self.base.options.objects.len); | |
| 1353 | for (self.base.options.objects) |obj| { | |
| 1354 | argv.appendAssumeCapacity(obj.path); | |
| 1355 | } | |
| 1350 | 1356 | |
| 1351 | 1357 | for (comp.c_object_table.keys()) |key| { |
| 1352 | 1358 | try argv.append(key.status.success.object_path); |
src/main.zig+14-5| ... | ... | @@ -705,7 +705,7 @@ fn buildOutputType( |
| 705 | 705 | var c_source_files = std.ArrayList(Compilation.CSourceFile).init(gpa); |
| 706 | 706 | defer c_source_files.deinit(); |
| 707 | 707 | |
| 708 | var link_objects = std.ArrayList([]const u8).init(gpa); | |
| 708 | var link_objects = std.ArrayList(Compilation.LinkObject).init(gpa); | |
| 709 | 709 | defer link_objects.deinit(); |
| 710 | 710 | |
| 711 | 711 | var framework_dirs = std.ArrayList([]const u8).init(gpa); |
| ... | ... | @@ -1238,7 +1238,7 @@ fn buildOutputType( |
| 1238 | 1238 | } |
| 1239 | 1239 | } else switch (Compilation.classifyFileExt(arg)) { |
| 1240 | 1240 | .object, .static_library, .shared_library => { |
| 1241 | try link_objects.append(arg); | |
| 1241 | try link_objects.append(.{ .path = arg }); | |
| 1242 | 1242 | }, |
| 1243 | 1243 | .assembly, .c, .cpp, .h, .ll, .bc, .m, .mm => { |
| 1244 | 1244 | try c_source_files.append(.{ |
| ... | ... | @@ -1309,7 +1309,7 @@ fn buildOutputType( |
| 1309 | 1309 | switch (file_ext) { |
| 1310 | 1310 | .assembly, .c, .cpp, .ll, .bc, .h, .m, .mm => try c_source_files.append(.{ .src_path = it.only_arg }), |
| 1311 | 1311 | .unknown, .shared_library, .object, .static_library => { |
| 1312 | try link_objects.append(it.only_arg); | |
| 1312 | try link_objects.append(.{ .path = it.only_arg }); | |
| 1313 | 1313 | }, |
| 1314 | 1314 | .zig => { |
| 1315 | 1315 | if (root_src_file) |other| { |
| ... | ... | @@ -1748,6 +1748,15 @@ fn buildOutputType( |
| 1748 | 1748 | fatal("expected linker arg after '{s}'", .{arg}); |
| 1749 | 1749 | } |
| 1750 | 1750 | install_name = linker_args.items[i]; |
| 1751 | } else if (mem.eql(u8, arg, "-force_load")) { | |
| 1752 | i += 1; | |
| 1753 | if (i >= linker_args.items.len) { | |
| 1754 | fatal("expected linker arg after '{s}'", .{arg}); | |
| 1755 | } | |
| 1756 | try link_objects.append(.{ | |
| 1757 | .path = linker_args.items[i], | |
| 1758 | .must_link = true, | |
| 1759 | }); | |
| 1751 | 1760 | } else { |
| 1752 | 1761 | warn("unsupported linker arg: {s}", .{arg}); |
| 1753 | 1762 | } |
| ... | ... | @@ -1842,7 +1851,7 @@ fn buildOutputType( |
| 1842 | 1851 | const basename = fs.path.basename(c_source_files.items[0].src_path); |
| 1843 | 1852 | break :blk basename[0 .. basename.len - fs.path.extension(basename).len]; |
| 1844 | 1853 | } else if (link_objects.items.len >= 1) { |
| 1845 | const basename = fs.path.basename(link_objects.items[0]); | |
| 1854 | const basename = fs.path.basename(link_objects.items[0].path); | |
| 1846 | 1855 | break :blk basename[0 .. basename.len - fs.path.extension(basename).len]; |
| 1847 | 1856 | } else if (emit_bin == .yes) { |
| 1848 | 1857 | const basename = fs.path.basename(emit_bin.yes); |
| ... | ... | @@ -2045,7 +2054,7 @@ fn buildOutputType( |
| 2045 | 2054 | test_path.items, @errorName(e), |
| 2046 | 2055 | }), |
| 2047 | 2056 | }; |
| 2048 | try link_objects.append(try arena.dupe(u8, test_path.items)); | |
| 2057 | try link_objects.append(.{ .path = try arena.dupe(u8, test_path.items) }); | |
| 2049 | 2058 | break; |
| 2050 | 2059 | } else { |
| 2051 | 2060 | var search_paths = std.ArrayList(u8).init(arena); |