| ... | ... | @@ -965,6 +965,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 965 | 965 | defer arena_allocator.deinit(); |
| 966 | 966 | const arena = arena_allocator.allocator(); |
| 967 | 967 | |
| 968 | const target = self.base.options.target; |
| 968 | 969 | const directory = self.base.options.emit.?.directory; // Just an alias to make it shorter to type. |
| 969 | 970 | const full_out_path = try directory.join(arena, &[_][]const u8{self.base.options.emit.?.sub_path}); |
| 970 | 971 | |
| ... | ... | @@ -993,22 +994,63 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 993 | 994 | try positionals.append(.{ .path = key.status.success.object_path }); |
| 994 | 995 | } |
| 995 | 996 | |
| 997 | for (positionals.items) |obj| { |
| 998 | const in_file = try std.fs.cwd().openFile(obj.path, .{}); |
| 999 | defer in_file.close(); |
| 1000 | var parse_ctx: ParseErrorCtx = .{ .detected_cpu_arch = undefined }; |
| 1001 | self.parsePositional(in_file, obj.path, obj.must_link, &parse_ctx) catch |err| |
| 1002 | try self.handleAndReportParseError(obj.path, err, &parse_ctx); |
| 1003 | } |
| 1004 | |
| 1005 | var system_libs = std.ArrayList(SystemLib).init(arena); |
| 1006 | |
| 1007 | // libc dep |
| 1008 | self.error_flags.missing_libc = false; |
| 1009 | if (self.base.options.link_libc) { |
| 1010 | if (self.base.options.libc_installation != null) { |
| 1011 | @panic("TODO explicit libc_installation"); |
| 1012 | } else if (target.isGnuLibC()) { |
| 1013 | try system_libs.ensureUnusedCapacity(glibc.libs.len + 1); |
| 1014 | for (glibc.libs) |lib| { |
| 1015 | const lib_path = try std.fmt.allocPrint(arena, "{s}{c}lib{s}.so.{d}", .{ |
| 1016 | comp.glibc_so_files.?.dir_path, fs.path.sep, lib.name, lib.sover, |
| 1017 | }); |
| 1018 | system_libs.appendAssumeCapacity(.{ .path = lib_path }); |
| 1019 | } |
| 1020 | system_libs.appendAssumeCapacity(.{ |
| 1021 | .path = try comp.get_libc_crt_file(arena, "libc_nonshared.a"), |
| 1022 | }); |
| 1023 | } else if (target.isMusl()) { |
| 1024 | const path = try comp.get_libc_crt_file(arena, switch (self.base.options.link_mode) { |
| 1025 | .Static => "libc.a", |
| 1026 | .Dynamic => "libc.so", |
| 1027 | }); |
| 1028 | try system_libs.append(.{ .path = path }); |
| 1029 | } else { |
| 1030 | self.error_flags.missing_libc = true; |
| 1031 | } |
| 1032 | } |
| 1033 | |
| 1034 | for (system_libs.items) |lib| { |
| 1035 | const in_file = try std.fs.cwd().openFile(lib.path, .{}); |
| 1036 | defer in_file.close(); |
| 1037 | var parse_ctx: ParseErrorCtx = .{ .detected_cpu_arch = undefined }; |
| 1038 | self.parseLibrary(in_file, lib, false, &parse_ctx) catch |err| |
| 1039 | try self.handleAndReportParseError(lib.path, err, &parse_ctx); |
| 1040 | } |
| 1041 | |
| 1042 | // Finally, as the last input object add compiler_rt if any. |
| 996 | 1043 | const compiler_rt_path: ?[]const u8 = blk: { |
| 997 | 1044 | if (comp.compiler_rt_lib) |x| break :blk x.full_object_path; |
| 998 | 1045 | if (comp.compiler_rt_obj) |x| break :blk x.full_object_path; |
| 999 | 1046 | break :blk null; |
| 1000 | 1047 | }; |
| 1001 | 1048 | if (compiler_rt_path) |path| { |
| 1002 | | try positionals.append(.{ .path = path }); |
| 1003 | | } |
| 1004 | | |
| 1005 | | for (positionals.items) |obj| { |
| 1006 | | const in_file = try std.fs.cwd().openFile(obj.path, .{}); |
| 1049 | const in_file = try std.fs.cwd().openFile(path, .{}); |
| 1007 | 1050 | defer in_file.close(); |
| 1008 | | |
| 1009 | 1051 | var parse_ctx: ParseErrorCtx = .{ .detected_cpu_arch = undefined }; |
| 1010 | | self.parsePositional(in_file, obj.path, obj.must_link, &parse_ctx) catch |err| |
| 1011 | | try self.handleAndReportParseError(obj.path, err, &parse_ctx); |
| 1052 | self.parsePositional(in_file, path, false, &parse_ctx) catch |err| |
| 1053 | try self.handleAndReportParseError(path, err, &parse_ctx); |
| 1012 | 1054 | } |
| 1013 | 1055 | |
| 1014 | 1056 | // Handle any lazy symbols that were emitted by incremental compilation. |
| ... | ... | @@ -1347,28 +1389,22 @@ fn parsePositional( |
| 1347 | 1389 | if (Object.isObject(in_file)) { |
| 1348 | 1390 | try self.parseObject(in_file, path, ctx); |
| 1349 | 1391 | } else { |
| 1350 | | try self.parseLibrary(in_file, path, .{ |
| 1351 | | .path = null, |
| 1352 | | .needed = false, |
| 1353 | | .weak = false, |
| 1354 | | }, must_link, ctx); |
| 1392 | try self.parseLibrary(in_file, .{ .path = path }, must_link, ctx); |
| 1355 | 1393 | } |
| 1356 | 1394 | } |
| 1357 | 1395 | |
| 1358 | 1396 | fn parseLibrary( |
| 1359 | 1397 | self: *Elf, |
| 1360 | 1398 | in_file: std.fs.File, |
| 1361 | | path: []const u8, |
| 1362 | | lib: link.SystemLib, |
| 1399 | lib: SystemLib, |
| 1363 | 1400 | must_link: bool, |
| 1364 | 1401 | ctx: *ParseErrorCtx, |
| 1365 | 1402 | ) ParseError!void { |
| 1366 | 1403 | const tracy = trace(@src()); |
| 1367 | 1404 | defer tracy.end(); |
| 1368 | | _ = lib; |
| 1369 | 1405 | |
| 1370 | 1406 | if (Archive.isArchive(in_file)) { |
| 1371 | | try self.parseArchive(in_file, path, must_link, ctx); |
| 1407 | try self.parseArchive(in_file, lib.path, must_link, ctx); |
| 1372 | 1408 | } else return error.UnknownFileType; |
| 1373 | 1409 | } |
| 1374 | 1410 | |
| ... | ... | @@ -4149,6 +4185,11 @@ pub const null_sym = elf.Elf64_Sym{ |
| 4149 | 4185 | .st_size = 0, |
| 4150 | 4186 | }; |
| 4151 | 4187 | |
| 4188 | const SystemLib = struct { |
| 4189 | needed: bool = false, |
| 4190 | path: []const u8, |
| 4191 | }; |
| 4192 | |
| 4152 | 4193 | const std = @import("std"); |
| 4153 | 4194 | const build_options = @import("build_options"); |
| 4154 | 4195 | const builtin = @import("builtin"); |