| author | |
| committer | |
| log | 04f6a26955bbb947983cbf3e0681d9092aaaa13f |
| tree | 000d28126a84a4e191305f03f9ce2319789fc0c7 |
| parent | c58e9951effddacfd5cef6c05019bc3f312747f8 |
also prepare for supporting linking into archives9 files changed, 64 insertions(+), 28 deletions(-)
src-self-hosted/Compilation.zig+8-1| ... | @@ -305,6 +305,8 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { | ... | @@ -305,6 +305,8 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 305 | options.system_libs.len != 0 or | 305 | options.system_libs.len != 0 or |
| 306 | options.link_libc or options.link_libcpp or | 306 | options.link_libc or options.link_libcpp or |
| 307 | options.link_eh_frame_hdr or | 307 | options.link_eh_frame_hdr or |
| 308 | options.output_mode == .Lib or | ||
| 309 | options.lld_argv.len != 0 or | ||
| 308 | options.linker_script != null or options.version_script != null) | 310 | options.linker_script != null or options.version_script != null) |
| 309 | { | 311 | { |
| 310 | break :blk true; | 312 | break :blk true; |
| ... | @@ -320,12 +322,17 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { | ... | @@ -320,12 +322,17 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 320 | break :blk false; | 322 | break :blk false; |
| 321 | }; | 323 | }; |
| 322 | 324 | ||
| 325 | const is_exe_or_dyn_lib = switch (options.output_mode) { | ||
| 326 | .Obj => false, | ||
| 327 | .Lib => (options.link_mode orelse .Static) == .Dynamic, | ||
| 328 | .Exe => true, | ||
| 329 | }; | ||
| 323 | const must_dynamic_link = dl: { | 330 | const must_dynamic_link = dl: { |
| 324 | if (target_util.cannotDynamicLink(options.target)) | 331 | if (target_util.cannotDynamicLink(options.target)) |
| 325 | break :dl false; | 332 | break :dl false; |
| 326 | if (target_util.osRequiresLibC(options.target)) | 333 | if (target_util.osRequiresLibC(options.target)) |
| 327 | break :dl true; | 334 | break :dl true; |
| 328 | if (options.link_libc and options.target.isGnuLibC()) | 335 | if (is_exe_or_dyn_lib and options.link_libc and options.target.isGnuLibC()) |
| 329 | break :dl true; | 336 | break :dl true; |
| 330 | if (options.system_libs.len != 0) | 337 | if (options.system_libs.len != 0) |
| 331 | break :dl true; | 338 | break :dl true; |
src-self-hosted/link.zig+24-15| ... | @@ -279,16 +279,19 @@ pub const File = struct { | ... | @@ -279,16 +279,19 @@ pub const File = struct { |
| 279 | } | 279 | } |
| 280 | 280 | ||
| 281 | pub fn flush(base: *File, comp: *Compilation) !void { | 281 | pub fn flush(base: *File, comp: *Compilation) !void { |
| 282 | const tracy = trace(@src()); | 282 | const use_lld = build_options.have_llvm and base.options.use_lld; |
| 283 | defer tracy.end(); | 283 | if (base.options.output_mode == .Lib and base.options.link_mode == .Static and |
| 284 | 284 | !base.options.target.isWasm()) | |
| 285 | try switch (base.tag) { | 285 | { |
| 286 | .coff => @fieldParentPtr(Coff, "base", base).flush(comp), | 286 | return base.linkAsArchive(comp); |
| 287 | .elf => @fieldParentPtr(Elf, "base", base).flush(comp), | 287 | } |
| 288 | .macho => @fieldParentPtr(MachO, "base", base).flush(comp), | 288 | switch (base.tag) { |
| 289 | .c => @fieldParentPtr(C, "base", base).flush(comp), | 289 | .coff => return @fieldParentPtr(Coff, "base", base).flush(comp), |
| 290 | .wasm => @fieldParentPtr(Wasm, "base", base).flush(comp), | 290 | .elf => return @fieldParentPtr(Elf, "base", base).flush(comp), |
| 291 | }; | 291 | .macho => return @fieldParentPtr(MachO, "base", base).flush(comp), |
| 292 | .c => return @fieldParentPtr(C, "base", base).flush(comp), | ||
| 293 | .wasm => return @fieldParentPtr(Wasm, "base", base).flush(comp), | ||
| 294 | } | ||
| 292 | } | 295 | } |
| 293 | 296 | ||
| 294 | pub fn freeDecl(base: *File, decl: *Module.Decl) void { | 297 | pub fn freeDecl(base: *File, decl: *Module.Decl) void { |
| ... | @@ -302,13 +305,13 @@ pub const File = struct { | ... | @@ -302,13 +305,13 @@ pub const File = struct { |
| 302 | } | 305 | } |
| 303 | 306 | ||
| 304 | pub fn errorFlags(base: *File) ErrorFlags { | 307 | pub fn errorFlags(base: *File) ErrorFlags { |
| 305 | return switch (base.tag) { | 308 | switch (base.tag) { |
| 306 | .coff => @fieldParentPtr(Coff, "base", base).error_flags, | 309 | .coff => return @fieldParentPtr(Coff, "base", base).error_flags, |
| 307 | .elf => @fieldParentPtr(Elf, "base", base).error_flags, | 310 | .elf => return @fieldParentPtr(Elf, "base", base).error_flags, |
| 308 | .macho => @fieldParentPtr(MachO, "base", base).error_flags, | 311 | .macho => return @fieldParentPtr(MachO, "base", base).error_flags, |
| 309 | .c => return .{ .no_entry_point_found = false }, | 312 | .c => return .{ .no_entry_point_found = false }, |
| 310 | .wasm => return ErrorFlags{}, | 313 | .wasm => return ErrorFlags{}, |
| 311 | }; | 314 | } |
| 312 | } | 315 | } |
| 313 | 316 | ||
| 314 | /// May be called before or after updateDecl, but must be called after | 317 | /// May be called before or after updateDecl, but must be called after |
| ... | @@ -338,6 +341,12 @@ pub const File = struct { | ... | @@ -338,6 +341,12 @@ pub const File = struct { |
| 338 | } | 341 | } |
| 339 | } | 342 | } |
| 340 | 343 | ||
| 344 | fn linkAsArchive(base: *File, comp: *Compilation) !void { | ||
| 345 | // TODO follow pattern from ELF linkWithLLD | ||
| 346 | // ZigLLVMWriteArchive | ||
| 347 | return error.TODOMakeArchive; | ||
| 348 | } | ||
| 349 | |||
| 341 | pub const Tag = enum { | 350 | pub const Tag = enum { |
| 342 | coff, | 351 | coff, |
| 343 | elf, | 352 | elf, |
src-self-hosted/link/C.zig+4| ... | @@ -7,6 +7,7 @@ const Compilation = @import("../Compilation.zig"); | ... | @@ -7,6 +7,7 @@ const Compilation = @import("../Compilation.zig"); |
| 7 | const fs = std.fs; | 7 | const fs = std.fs; |
| 8 | const codegen = @import("../codegen/c.zig"); | 8 | const codegen = @import("../codegen/c.zig"); |
| 9 | const link = @import("../link.zig"); | 9 | const link = @import("../link.zig"); |
| 10 | const trace = @import("../tracy.zig").trace; | ||
| 10 | const File = link.File; | 11 | const File = link.File; |
| 11 | const C = @This(); | 12 | const C = @This(); |
| 12 | 13 | ||
| ... | @@ -73,6 +74,9 @@ pub fn updateDecl(self: *C, module: *Module, decl: *Module.Decl) !void { | ... | @@ -73,6 +74,9 @@ pub fn updateDecl(self: *C, module: *Module, decl: *Module.Decl) !void { |
| 73 | } | 74 | } |
| 74 | 75 | ||
| 75 | pub fn flush(self: *C, comp: *Compilation) !void { | 76 | pub fn flush(self: *C, comp: *Compilation) !void { |
| 77 | const tracy = trace(@src()); | ||
| 78 | defer tracy.end(); | ||
| 79 | |||
| 76 | const writer = self.base.file.?.writer(); | 80 | const writer = self.base.file.?.writer(); |
| 77 | try writer.writeAll(@embedFile("cbe.h")); | 81 | try writer.writeAll(@embedFile("cbe.h")); |
| 78 | var includes = false; | 82 | var includes = false; |
src-self-hosted/link/Coff.zig+3| ... | @@ -724,6 +724,9 @@ pub fn updateDeclExports(self: *Coff, module: *Module, decl: *const Module.Decl, | ... | @@ -724,6 +724,9 @@ pub fn updateDeclExports(self: *Coff, module: *Module, decl: *const Module.Decl, |
| 724 | } | 724 | } |
| 725 | 725 | ||
| 726 | pub fn flush(self: *Coff, comp: *Compilation) !void { | 726 | pub fn flush(self: *Coff, comp: *Compilation) !void { |
| 727 | const tracy = trace(@src()); | ||
| 728 | defer tracy.end(); | ||
| 729 | |||
| 727 | if (self.text_section_size_dirty) { | 730 | if (self.text_section_size_dirty) { |
| 728 | // Write the new raw size in the .text header | 731 | // Write the new raw size in the .text header |
| 729 | var buf: [4]u8 = undefined; | 732 | var buf: [4]u8 = undefined; |
src-self-hosted/link/Elf.zig+8-9| ... | @@ -725,6 +725,9 @@ pub fn flush(self: *Elf, comp: *Compilation) !void { | ... | @@ -725,6 +725,9 @@ pub fn flush(self: *Elf, comp: *Compilation) !void { |
| 725 | 725 | ||
| 726 | /// Commit pending changes and write headers. | 726 | /// Commit pending changes and write headers. |
| 727 | fn flushInner(self: *Elf, comp: *Compilation) !void { | 727 | fn flushInner(self: *Elf, comp: *Compilation) !void { |
| 728 | const tracy = trace(@src()); | ||
| 729 | defer tracy.end(); | ||
| 730 | |||
| 728 | // TODO This linker code currently assumes there is only 1 compilation unit and it corresponds to the | 731 | // TODO This linker code currently assumes there is only 1 compilation unit and it corresponds to the |
| 729 | // Zig source code. | 732 | // Zig source code. |
| 730 | const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented; | 733 | const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented; |
| ... | @@ -1206,6 +1209,9 @@ fn flushInner(self: *Elf, comp: *Compilation) !void { | ... | @@ -1206,6 +1209,9 @@ fn flushInner(self: *Elf, comp: *Compilation) !void { |
| 1206 | } | 1209 | } |
| 1207 | 1210 | ||
| 1208 | fn linkWithLLD(self: *Elf, comp: *Compilation) !void { | 1211 | fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1212 | const tracy = trace(@src()); | ||
| 1213 | defer tracy.end(); | ||
| 1214 | |||
| 1209 | var arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator); | 1215 | var arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator); |
| 1210 | defer arena_allocator.deinit(); | 1216 | defer arena_allocator.deinit(); |
| 1211 | const arena = &arena_allocator.allocator; | 1217 | const arena = &arena_allocator.allocator; |
| ... | @@ -1315,13 +1321,6 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { | ... | @@ -1315,13 +1321,6 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1315 | if (is_obj) { | 1321 | if (is_obj) { |
| 1316 | try argv.append("-r"); | 1322 | try argv.append("-r"); |
| 1317 | } | 1323 | } |
| 1318 | if (self.base.options.output_mode == .Lib and | ||
| 1319 | self.base.options.link_mode == .Static and | ||
| 1320 | !target.isWasm()) | ||
| 1321 | { | ||
| 1322 | // TODO port the code from link.cpp | ||
| 1323 | return error.TODOMakeArchive; | ||
| 1324 | } | ||
| 1325 | const link_in_crt = self.base.options.link_libc and self.base.options.output_mode == .Exe; | 1324 | const link_in_crt = self.base.options.link_libc and self.base.options.output_mode == .Exe; |
| 1326 | 1325 | ||
| 1327 | try argv.append("-error-limit=0"); | 1326 | try argv.append("-error-limit=0"); |
| ... | @@ -1581,8 +1580,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { | ... | @@ -1581,8 +1580,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1581 | new_argv[i] = try arena.dupeZ(u8, arg); | 1580 | new_argv[i] = try arena.dupeZ(u8, arg); |
| 1582 | } | 1581 | } |
| 1583 | 1582 | ||
| 1584 | const ZigLLDLink = @import("../llvm.zig").ZigLLDLink; | 1583 | const llvm = @import("../llvm.zig"); |
| 1585 | const ok = ZigLLDLink(.ELF, new_argv.ptr, new_argv.len, append_diagnostic, 0, 0); | 1584 | const ok = llvm.Link(.ELF, new_argv.ptr, new_argv.len, append_diagnostic, 0, 0); |
| 1586 | if (!ok) return error.LLDReportedFailure; | 1585 | if (!ok) return error.LLDReportedFailure; |
| 1587 | 1586 | ||
| 1588 | // Update the dangling symlink "id.txt" with the digest. If it fails we can continue; it only | 1587 | // Update the dangling symlink "id.txt" with the digest. If it fails we can continue; it only |
src-self-hosted/link/MachO.zig+3| ... | @@ -178,6 +178,9 @@ pub fn createEmpty(gpa: *Allocator, options: link.Options) !*MachO { | ... | @@ -178,6 +178,9 @@ pub fn createEmpty(gpa: *Allocator, options: link.Options) !*MachO { |
| 178 | } | 178 | } |
| 179 | 179 | ||
| 180 | pub fn flush(self: *MachO, comp: *Compilation) !void { | 180 | pub fn flush(self: *MachO, comp: *Compilation) !void { |
| 181 | const tracy = trace(@src()); | ||
| 182 | defer tracy.end(); | ||
| 183 | |||
| 181 | switch (self.base.options.output_mode) { | 184 | switch (self.base.options.output_mode) { |
| 182 | .Exe => { | 185 | .Exe => { |
| 183 | var last_cmd_offset: usize = @sizeOf(macho.mach_header_64); | 186 | var last_cmd_offset: usize = @sizeOf(macho.mach_header_64); |
src-self-hosted/link/Wasm.zig+4| ... | @@ -10,6 +10,7 @@ const Module = @import("../Module.zig"); | ... | @@ -10,6 +10,7 @@ const Module = @import("../Module.zig"); |
| 10 | const Compilation = @import("../Compilation.zig"); | 10 | const Compilation = @import("../Compilation.zig"); |
| 11 | const codegen = @import("../codegen/wasm.zig"); | 11 | const codegen = @import("../codegen/wasm.zig"); |
| 12 | const link = @import("../link.zig"); | 12 | const link = @import("../link.zig"); |
| 13 | const trace = @import("../tracy.zig").trace; | ||
| 13 | 14 | ||
| 14 | /// Various magic numbers defined by the wasm spec | 15 | /// Various magic numbers defined by the wasm spec |
| 15 | const spec = struct { | 16 | const spec = struct { |
| ... | @@ -134,6 +135,9 @@ pub fn freeDecl(self: *Wasm, decl: *Module.Decl) void { | ... | @@ -134,6 +135,9 @@ pub fn freeDecl(self: *Wasm, decl: *Module.Decl) void { |
| 134 | } | 135 | } |
| 135 | 136 | ||
| 136 | pub fn flush(self: *Wasm, comp: *Compilation) !void { | 137 | pub fn flush(self: *Wasm, comp: *Compilation) !void { |
| 138 | const tracy = trace(@src()); | ||
| 139 | defer tracy.end(); | ||
| 140 | |||
| 137 | const file = self.base.file.?; | 141 | const file = self.base.file.?; |
| 138 | const header_size = 5 + 1; | 142 | const header_size = 5 + 1; |
| 139 | 143 |
src-self-hosted/llvm.zig+9-2| ... | @@ -1,8 +1,9 @@ | ... | @@ -1,8 +1,9 @@ |
| 1 | //! We do this instead of @cImport because the self-hosted compiler is easier | 1 | //! We do this instead of @cImport because the self-hosted compiler is easier |
| 2 | //! to bootstrap if it does not depend on translate-c. | 2 | //! to bootstrap if it does not depend on translate-c. |
| 3 | 3 | ||
| 4 | pub const Link = ZigLLDLink; | ||
| 4 | pub extern fn ZigLLDLink( | 5 | pub extern fn ZigLLDLink( |
| 5 | oformat: ZigLLVM_ObjectFormatType, | 6 | oformat: ObjectFormatType, |
| 6 | args: [*:null]const ?[*:0]const u8, | 7 | args: [*:null]const ?[*:0]const u8, |
| 7 | arg_count: usize, | 8 | arg_count: usize, |
| 8 | append_diagnostic: fn (context: usize, ptr: [*]const u8, len: usize) callconv(.C) void, | 9 | append_diagnostic: fn (context: usize, ptr: [*]const u8, len: usize) callconv(.C) void, |
| ... | @@ -10,7 +11,7 @@ pub extern fn ZigLLDLink( | ... | @@ -10,7 +11,7 @@ pub extern fn ZigLLDLink( |
| 10 | context_stderr: usize, | 11 | context_stderr: usize, |
| 11 | ) bool; | 12 | ) bool; |
| 12 | 13 | ||
| 13 | pub const ZigLLVM_ObjectFormatType = extern enum(c_int) { | 14 | pub const ObjectFormatType = extern enum(c_int) { |
| 14 | Unknown, | 15 | Unknown, |
| 15 | COFF, | 16 | COFF, |
| 16 | ELF, | 17 | ELF, |
| ... | @@ -18,3 +19,9 @@ pub const ZigLLVM_ObjectFormatType = extern enum(c_int) { | ... | @@ -18,3 +19,9 @@ pub const ZigLLVM_ObjectFormatType = extern enum(c_int) { |
| 18 | Wasm, | 19 | Wasm, |
| 19 | XCOFF, | 20 | XCOFF, |
| 20 | }; | 21 | }; |
| 22 | |||
| 23 | pub const GetHostCPUName = LLVMGetHostCPUName; | ||
| 24 | extern fn LLVMGetHostCPUName() ?[*:0]u8; | ||
| 25 | |||
| 26 | pub const GetNativeFeatures = ZigLLVMGetNativeFeatures; | ||
| 27 | extern fn ZigLLVMGetNativeFeatures() ?[*:0]u8; |
src/codegen.cpp+1-1| ... | @@ -9013,7 +9013,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { | ... | @@ -9013,7 +9013,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { |
| 9013 | if (g->zig_target->os_builtin_str != nullptr) { | 9013 | if (g->zig_target->os_builtin_str != nullptr) { |
| 9014 | buf_append_str(contents, g->zig_target->os_builtin_str); | 9014 | buf_append_str(contents, g->zig_target->os_builtin_str); |
| 9015 | } else { | 9015 | } else { |
| 9016 | buf_appendf(contents, "Target.Os.defaultVersionRange(.%s);\n", cur_os); | 9016 | buf_appendf(contents, "Target.Os.Tag.defaultVersionRange(.%s);\n", cur_os); |
| 9017 | } | 9017 | } |
| 9018 | } | 9018 | } |
| 9019 | buf_appendf(contents, "pub const object_format = ObjectFormat.%s;\n", cur_obj_fmt); | 9019 | buf_appendf(contents, "pub const object_format = ObjectFormat.%s;\n", cur_obj_fmt); |