diff --git a/src-self-hosted/Compilation.zig b/src-self-hosted/Compilation.zig index abd12bf370..1f42c87849 100644 --- a/src-self-hosted/Compilation.zig +++ b/src-self-hosted/Compilation.zig @@ -305,6 +305,8 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { options.system_libs.len != 0 or options.link_libc or options.link_libcpp or options.link_eh_frame_hdr or + options.output_mode == .Lib or + options.lld_argv.len != 0 or options.linker_script != null or options.version_script != null) { break :blk true; @@ -320,12 +322,17 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { break :blk false; }; + const is_exe_or_dyn_lib = switch (options.output_mode) { + .Obj => false, + .Lib => (options.link_mode orelse .Static) == .Dynamic, + .Exe => true, + }; const must_dynamic_link = dl: { if (target_util.cannotDynamicLink(options.target)) break :dl false; if (target_util.osRequiresLibC(options.target)) break :dl true; - if (options.link_libc and options.target.isGnuLibC()) + if (is_exe_or_dyn_lib and options.link_libc and options.target.isGnuLibC()) break :dl true; if (options.system_libs.len != 0) break :dl true; diff --git a/src-self-hosted/link.zig b/src-self-hosted/link.zig index f75274eb58..832015faae 100644 --- a/src-self-hosted/link.zig +++ b/src-self-hosted/link.zig @@ -279,16 +279,19 @@ pub const File = struct { } pub fn flush(base: *File, comp: *Compilation) !void { - const tracy = trace(@src()); - defer tracy.end(); - - try switch (base.tag) { - .coff => @fieldParentPtr(Coff, "base", base).flush(comp), - .elf => @fieldParentPtr(Elf, "base", base).flush(comp), - .macho => @fieldParentPtr(MachO, "base", base).flush(comp), - .c => @fieldParentPtr(C, "base", base).flush(comp), - .wasm => @fieldParentPtr(Wasm, "base", base).flush(comp), - }; + const use_lld = build_options.have_llvm and base.options.use_lld; + if (base.options.output_mode == .Lib and base.options.link_mode == .Static and + !base.options.target.isWasm()) + { + return base.linkAsArchive(comp); + } + switch (base.tag) { + .coff => return @fieldParentPtr(Coff, "base", base).flush(comp), + .elf => return @fieldParentPtr(Elf, "base", base).flush(comp), + .macho => return @fieldParentPtr(MachO, "base", base).flush(comp), + .c => return @fieldParentPtr(C, "base", base).flush(comp), + .wasm => return @fieldParentPtr(Wasm, "base", base).flush(comp), + } } pub fn freeDecl(base: *File, decl: *Module.Decl) void { @@ -302,13 +305,13 @@ pub const File = struct { } pub fn errorFlags(base: *File) ErrorFlags { - return switch (base.tag) { - .coff => @fieldParentPtr(Coff, "base", base).error_flags, - .elf => @fieldParentPtr(Elf, "base", base).error_flags, - .macho => @fieldParentPtr(MachO, "base", base).error_flags, + switch (base.tag) { + .coff => return @fieldParentPtr(Coff, "base", base).error_flags, + .elf => return @fieldParentPtr(Elf, "base", base).error_flags, + .macho => return @fieldParentPtr(MachO, "base", base).error_flags, .c => return .{ .no_entry_point_found = false }, .wasm => return ErrorFlags{}, - }; + } } /// May be called before or after updateDecl, but must be called after @@ -338,6 +341,12 @@ pub const File = struct { } } + fn linkAsArchive(base: *File, comp: *Compilation) !void { + // TODO follow pattern from ELF linkWithLLD + // ZigLLVMWriteArchive + return error.TODOMakeArchive; + } + pub const Tag = enum { coff, elf, diff --git a/src-self-hosted/link/C.zig b/src-self-hosted/link/C.zig index f2c3d30a61..97990f34fb 100644 --- a/src-self-hosted/link/C.zig +++ b/src-self-hosted/link/C.zig @@ -7,6 +7,7 @@ const Compilation = @import("../Compilation.zig"); const fs = std.fs; const codegen = @import("../codegen/c.zig"); const link = @import("../link.zig"); +const trace = @import("../tracy.zig").trace; const File = link.File; const C = @This(); @@ -73,6 +74,9 @@ pub fn updateDecl(self: *C, module: *Module, decl: *Module.Decl) !void { } pub fn flush(self: *C, comp: *Compilation) !void { + const tracy = trace(@src()); + defer tracy.end(); + const writer = self.base.file.?.writer(); try writer.writeAll(@embedFile("cbe.h")); var includes = false; diff --git a/src-self-hosted/link/Coff.zig b/src-self-hosted/link/Coff.zig index ffec465155..b927ca2586 100644 --- a/src-self-hosted/link/Coff.zig +++ b/src-self-hosted/link/Coff.zig @@ -724,6 +724,9 @@ pub fn updateDeclExports(self: *Coff, module: *Module, decl: *const Module.Decl, } pub fn flush(self: *Coff, comp: *Compilation) !void { + const tracy = trace(@src()); + defer tracy.end(); + if (self.text_section_size_dirty) { // Write the new raw size in the .text header var buf: [4]u8 = undefined; diff --git a/src-self-hosted/link/Elf.zig b/src-self-hosted/link/Elf.zig index 3b016e3c8e..49cf02d7c4 100644 --- a/src-self-hosted/link/Elf.zig +++ b/src-self-hosted/link/Elf.zig @@ -725,6 +725,9 @@ pub fn flush(self: *Elf, comp: *Compilation) !void { /// Commit pending changes and write headers. fn flushInner(self: *Elf, comp: *Compilation) !void { + const tracy = trace(@src()); + defer tracy.end(); + // TODO This linker code currently assumes there is only 1 compilation unit and it corresponds to the // Zig source code. const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented; @@ -1206,6 +1209,9 @@ fn flushInner(self: *Elf, comp: *Compilation) !void { } fn linkWithLLD(self: *Elf, comp: *Compilation) !void { + const tracy = trace(@src()); + defer tracy.end(); + var arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator); defer arena_allocator.deinit(); const arena = &arena_allocator.allocator; @@ -1315,13 +1321,6 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { if (is_obj) { try argv.append("-r"); } - if (self.base.options.output_mode == .Lib and - self.base.options.link_mode == .Static and - !target.isWasm()) - { - // TODO port the code from link.cpp - return error.TODOMakeArchive; - } const link_in_crt = self.base.options.link_libc and self.base.options.output_mode == .Exe; try argv.append("-error-limit=0"); @@ -1581,8 +1580,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { new_argv[i] = try arena.dupeZ(u8, arg); } - const ZigLLDLink = @import("../llvm.zig").ZigLLDLink; - const ok = ZigLLDLink(.ELF, new_argv.ptr, new_argv.len, append_diagnostic, 0, 0); + const llvm = @import("../llvm.zig"); + const ok = llvm.Link(.ELF, new_argv.ptr, new_argv.len, append_diagnostic, 0, 0); if (!ok) return error.LLDReportedFailure; // Update the dangling symlink "id.txt" with the digest. If it fails we can continue; it only diff --git a/src-self-hosted/link/MachO.zig b/src-self-hosted/link/MachO.zig index 08a948ed0e..ff3fa2810d 100644 --- a/src-self-hosted/link/MachO.zig +++ b/src-self-hosted/link/MachO.zig @@ -178,6 +178,9 @@ pub fn createEmpty(gpa: *Allocator, options: link.Options) !*MachO { } pub fn flush(self: *MachO, comp: *Compilation) !void { + const tracy = trace(@src()); + defer tracy.end(); + switch (self.base.options.output_mode) { .Exe => { var last_cmd_offset: usize = @sizeOf(macho.mach_header_64); diff --git a/src-self-hosted/link/Wasm.zig b/src-self-hosted/link/Wasm.zig index 2351c6a3ea..b4bb2c3195 100644 --- a/src-self-hosted/link/Wasm.zig +++ b/src-self-hosted/link/Wasm.zig @@ -10,6 +10,7 @@ const Module = @import("../Module.zig"); const Compilation = @import("../Compilation.zig"); const codegen = @import("../codegen/wasm.zig"); const link = @import("../link.zig"); +const trace = @import("../tracy.zig").trace; /// Various magic numbers defined by the wasm spec const spec = struct { @@ -134,6 +135,9 @@ pub fn freeDecl(self: *Wasm, decl: *Module.Decl) void { } pub fn flush(self: *Wasm, comp: *Compilation) !void { + const tracy = trace(@src()); + defer tracy.end(); + const file = self.base.file.?; const header_size = 5 + 1; diff --git a/src-self-hosted/llvm.zig b/src-self-hosted/llvm.zig index d65e046169..d247e87c28 100644 --- a/src-self-hosted/llvm.zig +++ b/src-self-hosted/llvm.zig @@ -1,8 +1,9 @@ //! We do this instead of @cImport because the self-hosted compiler is easier //! to bootstrap if it does not depend on translate-c. +pub const Link = ZigLLDLink; pub extern fn ZigLLDLink( - oformat: ZigLLVM_ObjectFormatType, + oformat: ObjectFormatType, args: [*:null]const ?[*:0]const u8, arg_count: usize, append_diagnostic: fn (context: usize, ptr: [*]const u8, len: usize) callconv(.C) void, @@ -10,7 +11,7 @@ pub extern fn ZigLLDLink( context_stderr: usize, ) bool; -pub const ZigLLVM_ObjectFormatType = extern enum(c_int) { +pub const ObjectFormatType = extern enum(c_int) { Unknown, COFF, ELF, @@ -18,3 +19,9 @@ pub const ZigLLVM_ObjectFormatType = extern enum(c_int) { Wasm, XCOFF, }; + +pub const GetHostCPUName = LLVMGetHostCPUName; +extern fn LLVMGetHostCPUName() ?[*:0]u8; + +pub const GetNativeFeatures = ZigLLVMGetNativeFeatures; +extern fn ZigLLVMGetNativeFeatures() ?[*:0]u8; diff --git a/src/codegen.cpp b/src/codegen.cpp index b5c1ca3a41..ce6eeb1def 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -9013,7 +9013,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { if (g->zig_target->os_builtin_str != nullptr) { buf_append_str(contents, g->zig_target->os_builtin_str); } else { - buf_appendf(contents, "Target.Os.defaultVersionRange(.%s);\n", cur_os); + buf_appendf(contents, "Target.Os.Tag.defaultVersionRange(.%s);\n", cur_os); } } buf_appendf(contents, "pub const object_format = ObjectFormat.%s;\n", cur_obj_fmt);