| author | |
| committer | |
| log | 5cde5f947fa12440463f684d9417ac00c8b9790a |
| tree | 4cc1ba8e54327060e7009a923e2c79faddf5d29e |
| parent | a8564df9ed510f572732b8179844299fc3d3c11b |
7 files changed, 74 insertions(+), 43 deletions(-)
src/Compilation.zig+13-6| ... | ... | @@ -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,8 +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{}, | |
| 702 | must_link_objects: []const []const u8 = &[0][]const u8{}, | |
| 706 | link_objects: []LinkObject = &[0]LinkObject{}, | |
| 703 | 707 | framework_dirs: []const []const u8 = &[0][]const u8{}, |
| 704 | 708 | frameworks: []const []const u8 = &[0][]const u8{}, |
| 705 | 709 | system_lib_names: []const []const u8 = &.{}, |
| ... | ... | @@ -1057,7 +1061,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1057 | 1061 | if (options.system_lib_names.len != 0) |
| 1058 | 1062 | break :x true; |
| 1059 | 1063 | for (options.link_objects) |obj| { |
| 1060 | switch (classifyFileExt(obj)) { | |
| 1064 | switch (classifyFileExt(obj.path)) { | |
| 1061 | 1065 | .shared_library => break :x true, |
| 1062 | 1066 | else => continue, |
| 1063 | 1067 | } |
| ... | ... | @@ -1460,7 +1464,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1460 | 1464 | if (options.c_source_files.len >= 1) { |
| 1461 | 1465 | hash.addBytes(options.c_source_files[0].src_path); |
| 1462 | 1466 | } else if (options.link_objects.len >= 1) { |
| 1463 | hash.addBytes(options.link_objects[0]); | |
| 1467 | hash.addBytes(options.link_objects[0].path); | |
| 1464 | 1468 | } |
| 1465 | 1469 | |
| 1466 | 1470 | const digest = hash.final(); |
| ... | ... | @@ -1536,7 +1540,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1536 | 1540 | .link_libcpp = link_libcpp, |
| 1537 | 1541 | .link_libunwind = link_libunwind, |
| 1538 | 1542 | .objects = options.link_objects, |
| 1539 | .must_link_objects = options.must_link_objects, | |
| 1540 | 1543 | .frameworks = options.frameworks, |
| 1541 | 1544 | .framework_dirs = options.framework_dirs, |
| 1542 | 1545 | .system_libs = system_libs, |
| ... | ... | @@ -2267,7 +2270,11 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes |
| 2267 | 2270 | |
| 2268 | 2271 | try man.addOptionalFile(comp.bin_file.options.linker_script); |
| 2269 | 2272 | try man.addOptionalFile(comp.bin_file.options.version_script); |
| 2270 | 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 | } | |
| 2271 | 2278 | |
| 2272 | 2279 | for (comp.c_object_table.keys()) |key| { |
| 2273 | 2280 | _ = try man.addFile(key.src.src_path, null); |
src/link.zig+7-5| ... | ... | @@ -155,8 +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, | |
| 159 | must_link_objects: []const []const u8, | |
| 158 | objects: []Compilation.LinkObject, | |
| 160 | 159 | framework_dirs: []const []const u8, |
| 161 | 160 | frameworks: []const []const u8, |
| 162 | 161 | system_libs: std.StringArrayHashMapUnmanaged(SystemLib), |
| ... | ... | @@ -756,7 +755,10 @@ pub const File = struct { |
| 756 | 755 | // We are about to obtain this lock, so here we give other processes a chance first. |
| 757 | 756 | base.releaseLock(); |
| 758 | 757 | |
| 759 | 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 | } | |
| 760 | 762 | for (comp.c_object_table.keys()) |key| { |
| 761 | 763 | _ = try man.addFile(key.status.success.object_path, null); |
| 762 | 764 | } |
| ... | ... | @@ -793,8 +795,8 @@ pub const File = struct { |
| 793 | 795 | var object_files = try std.ArrayList([*:0]const u8).initCapacity(base.allocator, num_object_files); |
| 794 | 796 | defer object_files.deinit(); |
| 795 | 797 | |
| 796 | for (base.options.objects) |obj_path| { | |
| 797 | 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)); | |
| 798 | 800 | } |
| 799 | 801 | for (comp.c_object_table.keys()) |key| { |
| 800 | 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+18-13| ... | ... | @@ -499,7 +499,10 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { |
| 499 | 499 | |
| 500 | 500 | comptime assert(Compilation.link_hash_implementation_version == 1); |
| 501 | 501 | |
| 502 | 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 | } | |
| 503 | 506 | for (comp.c_object_table.keys()) |key| { |
| 504 | 507 | _ = try man.addFile(key.status.success.object_path, null); |
| 505 | 508 | } |
| ... | ... | @@ -571,8 +574,9 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { |
| 571 | 574 | // here. TODO: think carefully about how we can avoid this redundant operation when doing |
| 572 | 575 | // build-obj. See also the corresponding TODO in linkAsArchive. |
| 573 | 576 | const the_object_path = blk: { |
| 574 | if (self.base.options.objects.len != 0) | |
| 575 | 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 | } | |
| 576 | 580 | |
| 577 | 581 | if (comp.c_object_table.count() != 0) |
| 578 | 582 | break :blk comp.c_object_table.keys()[0].status.success.object_path; |
| ... | ... | @@ -679,19 +683,20 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { |
| 679 | 683 | // the relocatable object files. |
| 680 | 684 | self.invalidate_relocs = true; |
| 681 | 685 | |
| 682 | // Unpack must-link archives | |
| 683 | var must_link_archives = std.StringArrayHashMap(void).init(arena); | |
| 684 | try must_link_archives.ensureTotalCapacity(@intCast(u32, self.base.options.must_link_objects.len)); | |
| 685 | for (self.base.options.must_link_objects) |lib| { | |
| 686 | _ = must_link_archives.getOrPutAssumeCapacity(lib); | |
| 687 | } | |
| 688 | ||
| 689 | 686 | // Positional arguments to the linker such as object files and static archives. |
| 690 | 687 | var positionals = std.ArrayList([]const u8).init(arena); |
| 691 | 688 | try positionals.ensureUnusedCapacity(self.base.options.objects.len); |
| 689 | ||
| 690 | var must_link_archives = std.StringArrayHashMap(void).init(arena); | |
| 691 | try must_link_archives.ensureUnusedCapacity(self.base.options.objects.len); | |
| 692 | ||
| 692 | 693 | for (self.base.options.objects) |obj| { |
| 693 | if (must_link_archives.contains(obj)) continue; | |
| 694 | _ = positionals.appendAssumeCapacity(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 | } | |
| 695 | 700 | } |
| 696 | 701 | |
| 697 | 702 | for (comp.c_object_table.keys()) |key| { |
| ... | ... | @@ -899,7 +904,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { |
| 899 | 904 | try argv.append("dynamic_lookup"); |
| 900 | 905 | } |
| 901 | 906 | |
| 902 | for (self.base.options.must_link_objects) |lib| { | |
| 907 | for (must_link_archives.keys()) |lib| { | |
| 903 | 908 | try argv.append(try std.fmt.allocPrint(arena, "-force_load {s}", .{lib})); |
| 904 | 909 | } |
| 905 | 910 |
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+9-10| ... | ... | @@ -705,12 +705,9 @@ 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 | var must_link_objects = std.ArrayList([]const u8).init(gpa); | |
| 712 | defer must_link_objects.deinit(); | |
| 713 | ||
| 714 | 711 | var framework_dirs = std.ArrayList([]const u8).init(gpa); |
| 715 | 712 | defer framework_dirs.deinit(); |
| 716 | 713 | |
| ... | ... | @@ -1241,7 +1238,7 @@ fn buildOutputType( |
| 1241 | 1238 | } |
| 1242 | 1239 | } else switch (Compilation.classifyFileExt(arg)) { |
| 1243 | 1240 | .object, .static_library, .shared_library => { |
| 1244 | try link_objects.append(arg); | |
| 1241 | try link_objects.append(.{ .path = arg }); | |
| 1245 | 1242 | }, |
| 1246 | 1243 | .assembly, .c, .cpp, .h, .ll, .bc, .m, .mm => { |
| 1247 | 1244 | try c_source_files.append(.{ |
| ... | ... | @@ -1312,7 +1309,7 @@ fn buildOutputType( |
| 1312 | 1309 | switch (file_ext) { |
| 1313 | 1310 | .assembly, .c, .cpp, .ll, .bc, .h, .m, .mm => try c_source_files.append(.{ .src_path = it.only_arg }), |
| 1314 | 1311 | .unknown, .shared_library, .object, .static_library => { |
| 1315 | try link_objects.append(it.only_arg); | |
| 1312 | try link_objects.append(.{ .path = it.only_arg }); | |
| 1316 | 1313 | }, |
| 1317 | 1314 | .zig => { |
| 1318 | 1315 | if (root_src_file) |other| { |
| ... | ... | @@ -1756,7 +1753,10 @@ fn buildOutputType( |
| 1756 | 1753 | if (i >= linker_args.items.len) { |
| 1757 | 1754 | fatal("expected linker arg after '{s}'", .{arg}); |
| 1758 | 1755 | } |
| 1759 | try must_link_objects.append(linker_args.items[i]); | |
| 1756 | try link_objects.append(.{ | |
| 1757 | .path = linker_args.items[i], | |
| 1758 | .must_link = true, | |
| 1759 | }); | |
| 1760 | 1760 | } else { |
| 1761 | 1761 | warn("unsupported linker arg: {s}", .{arg}); |
| 1762 | 1762 | } |
| ... | ... | @@ -1851,7 +1851,7 @@ fn buildOutputType( |
| 1851 | 1851 | const basename = fs.path.basename(c_source_files.items[0].src_path); |
| 1852 | 1852 | break :blk basename[0 .. basename.len - fs.path.extension(basename).len]; |
| 1853 | 1853 | } else if (link_objects.items.len >= 1) { |
| 1854 | const basename = fs.path.basename(link_objects.items[0]); | |
| 1854 | const basename = fs.path.basename(link_objects.items[0].path); | |
| 1855 | 1855 | break :blk basename[0 .. basename.len - fs.path.extension(basename).len]; |
| 1856 | 1856 | } else if (emit_bin == .yes) { |
| 1857 | 1857 | const basename = fs.path.basename(emit_bin.yes); |
| ... | ... | @@ -2054,7 +2054,7 @@ fn buildOutputType( |
| 2054 | 2054 | test_path.items, @errorName(e), |
| 2055 | 2055 | }), |
| 2056 | 2056 | }; |
| 2057 | try link_objects.append(try arena.dupe(u8, test_path.items)); | |
| 2057 | try link_objects.append(.{ .path = try arena.dupe(u8, test_path.items) }); | |
| 2058 | 2058 | break; |
| 2059 | 2059 | } else { |
| 2060 | 2060 | var search_paths = std.ArrayList(u8).init(arena); |
| ... | ... | @@ -2447,7 +2447,6 @@ fn buildOutputType( |
| 2447 | 2447 | .rpath_list = rpath_list.items, |
| 2448 | 2448 | .c_source_files = c_source_files.items, |
| 2449 | 2449 | .link_objects = link_objects.items, |
| 2450 | .must_link_objects = must_link_objects.items, | |
| 2451 | 2450 | .framework_dirs = framework_dirs.items, |
| 2452 | 2451 | .frameworks = frameworks.items, |
| 2453 | 2452 | .system_lib_names = system_libs.keys(), |