| author | |
| committer | |
| log | 26798018b780846eb0613b2061835985bf0c58ea |
| tree | 1c7620cb2aecda0537ee6adbce4c3110d9394cc2 |
| parent | 40cb712d13aff4bfe83256858ad6b18d82e70211 |
9 files changed, 246 insertions(+), 11 deletions(-)
src-self-hosted/Compilation.zig+2| ... | @@ -535,6 +535,8 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { | ... | @@ -535,6 +535,8 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 535 | var hash = cache.hash; | 535 | var hash = cache.hash; |
| 536 | if (options.c_source_files.len >= 1) { | 536 | if (options.c_source_files.len >= 1) { |
| 537 | hash.addBytes(options.c_source_files[0].src_path); | 537 | hash.addBytes(options.c_source_files[0].src_path); |
| 538 | } else if (options.link_objects.len >= 1) { | ||
| 539 | hash.addBytes(options.link_objects[0]); | ||
| 538 | } | 540 | } |
| 539 | 541 | ||
| 540 | const digest = hash.final(); | 542 | const digest = hash.final(); |
src-self-hosted/link.zig+119-4| ... | @@ -1,4 +1,5 @@ | ... | @@ -1,4 +1,5 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const mem = std.mem; | ||
| 2 | const Allocator = std.mem.Allocator; | 3 | const Allocator = std.mem.Allocator; |
| 3 | const Compilation = @import("Compilation.zig"); | 4 | const Compilation = @import("Compilation.zig"); |
| 4 | const Module = @import("Module.zig"); | 5 | const Module = @import("Module.zig"); |
| ... | @@ -9,6 +10,7 @@ const Type = @import("type.zig").Type; | ... | @@ -9,6 +10,7 @@ const Type = @import("type.zig").Type; |
| 9 | const Cache = @import("Cache.zig"); | 10 | const Cache = @import("Cache.zig"); |
| 10 | const build_options = @import("build_options"); | 11 | const build_options = @import("build_options"); |
| 11 | const LibCInstallation = @import("libc_installation.zig").LibCInstallation; | 12 | const LibCInstallation = @import("libc_installation.zig").LibCInstallation; |
| 13 | const log = std.log.scoped(.link); | ||
| 12 | 14 | ||
| 13 | pub const producer_string = if (std.builtin.is_test) "zig test" else "zig " ++ build_options.version; | 15 | pub const producer_string = if (std.builtin.is_test) "zig test" else "zig " ++ build_options.version; |
| 14 | 16 | ||
| ... | @@ -279,9 +281,11 @@ pub const File = struct { | ... | @@ -279,9 +281,11 @@ pub const File = struct { |
| 279 | } | 281 | } |
| 280 | } | 282 | } |
| 281 | 283 | ||
| 284 | /// Commit pending changes and write headers. Takes into account final output mode | ||
| 285 | /// and `use_lld`, not only `effectiveOutputMode`. | ||
| 282 | pub fn flush(base: *File, comp: *Compilation) !void { | 286 | pub fn flush(base: *File, comp: *Compilation) !void { |
| 283 | const use_lld = build_options.have_llvm and base.options.use_lld; | 287 | const use_lld = build_options.have_llvm and base.options.use_lld; |
| 284 | if (base.options.output_mode == .Lib and base.options.link_mode == .Static and | 288 | if (use_lld and base.options.output_mode == .Lib and base.options.link_mode == .Static and |
| 285 | !base.options.target.isWasm()) | 289 | !base.options.target.isWasm()) |
| 286 | { | 290 | { |
| 287 | return base.linkAsArchive(comp); | 291 | return base.linkAsArchive(comp); |
| ... | @@ -295,6 +299,18 @@ pub const File = struct { | ... | @@ -295,6 +299,18 @@ pub const File = struct { |
| 295 | } | 299 | } |
| 296 | } | 300 | } |
| 297 | 301 | ||
| 302 | /// Commit pending changes and write headers. Works based on `effectiveOutputMode` | ||
| 303 | /// rather than final output mode. | ||
| 304 | pub fn flushModule(base: *File, comp: *Compilation) !void { | ||
| 305 | switch (base.tag) { | ||
| 306 | .coff => return @fieldParentPtr(Coff, "base", base).flushModule(comp), | ||
| 307 | .elf => return @fieldParentPtr(Elf, "base", base).flushModule(comp), | ||
| 308 | .macho => return @fieldParentPtr(MachO, "base", base).flushModule(comp), | ||
| 309 | .c => return @fieldParentPtr(C, "base", base).flushModule(comp), | ||
| 310 | .wasm => return @fieldParentPtr(Wasm, "base", base).flushModule(comp), | ||
| 311 | } | ||
| 312 | } | ||
| 313 | |||
| 298 | pub fn freeDecl(base: *File, decl: *Module.Decl) void { | 314 | pub fn freeDecl(base: *File, decl: *Module.Decl) void { |
| 299 | switch (base.tag) { | 315 | switch (base.tag) { |
| 300 | .coff => @fieldParentPtr(Coff, "base", base).freeDecl(decl), | 316 | .coff => @fieldParentPtr(Coff, "base", base).freeDecl(decl), |
| ... | @@ -343,9 +359,108 @@ pub const File = struct { | ... | @@ -343,9 +359,108 @@ pub const File = struct { |
| 343 | } | 359 | } |
| 344 | 360 | ||
| 345 | fn linkAsArchive(base: *File, comp: *Compilation) !void { | 361 | fn linkAsArchive(base: *File, comp: *Compilation) !void { |
| 346 | // TODO follow pattern from ELF linkWithLLD | 362 | const tracy = trace(@src()); |
| 347 | // ZigLLVMWriteArchive | 363 | defer tracy.end(); |
| 348 | return error.TODOMakeArchive; | 364 | |
| 365 | var arena_allocator = std.heap.ArenaAllocator.init(base.allocator); | ||
| 366 | defer arena_allocator.deinit(); | ||
| 367 | const arena = &arena_allocator.allocator; | ||
| 368 | |||
| 369 | const directory = base.options.directory; // Just an alias to make it shorter to type. | ||
| 370 | |||
| 371 | // If there is no Zig code to compile, then we should skip flushing the output file because it | ||
| 372 | // will not be part of the linker line anyway. | ||
| 373 | const module_obj_path: ?[]const u8 = if (base.options.module) |module| blk: { | ||
| 374 | try base.flushModule(comp); | ||
| 375 | |||
| 376 | const obj_basename = base.intermediary_basename.?; | ||
| 377 | const full_obj_path = if (directory.path) |dir_path| | ||
| 378 | try std.fs.path.join(arena, &[_][]const u8{ dir_path, obj_basename }) | ||
| 379 | else | ||
| 380 | obj_basename; | ||
| 381 | break :blk full_obj_path; | ||
| 382 | } else null; | ||
| 383 | |||
| 384 | // This function follows the same pattern as link.Elf.linkWithLLD so if you want some | ||
| 385 | // insight as to what's going on here you can read that function body which is more | ||
| 386 | // well-commented. | ||
| 387 | |||
| 388 | const id_symlink_basename = "llvm-ar.id"; | ||
| 389 | |||
| 390 | base.releaseLock(); | ||
| 391 | |||
| 392 | var ch = comp.cache_parent.obtain(); | ||
| 393 | defer ch.deinit(); | ||
| 394 | |||
| 395 | try ch.addListOfFiles(base.options.objects); | ||
| 396 | for (comp.c_object_table.items()) |entry| { | ||
| 397 | _ = try ch.addFile(entry.key.status.success.object_path, null); | ||
| 398 | } | ||
| 399 | try ch.addOptionalFile(module_obj_path); | ||
| 400 | |||
| 401 | // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock. | ||
| 402 | _ = try ch.hit(); | ||
| 403 | const digest = ch.final(); | ||
| 404 | |||
| 405 | var prev_digest_buf: [digest.len]u8 = undefined; | ||
| 406 | const prev_digest: []u8 = directory.handle.readLink(id_symlink_basename, &prev_digest_buf) catch |err| b: { | ||
| 407 | log.debug("archive new_digest={} readlink error: {}", .{ digest, @errorName(err) }); | ||
| 408 | break :b prev_digest_buf[0..0]; | ||
| 409 | }; | ||
| 410 | if (mem.eql(u8, prev_digest, &digest)) { | ||
| 411 | log.debug("archive digest={} match - skipping invocation", .{digest}); | ||
| 412 | base.lock = ch.toOwnedLock(); | ||
| 413 | return; | ||
| 414 | } | ||
| 415 | |||
| 416 | // We are about to change the output file to be different, so we invalidate the build hash now. | ||
| 417 | directory.handle.deleteFile(id_symlink_basename) catch |err| switch (err) { | ||
| 418 | error.FileNotFound => {}, | ||
| 419 | else => |e| return e, | ||
| 420 | }; | ||
| 421 | |||
| 422 | var object_files = std.ArrayList([*:0]const u8).init(base.allocator); | ||
| 423 | defer object_files.deinit(); | ||
| 424 | |||
| 425 | try object_files.ensureCapacity(base.options.objects.len + comp.c_object_table.items().len + 1); | ||
| 426 | for (base.options.objects) |obj_path| { | ||
| 427 | object_files.appendAssumeCapacity(try arena.dupeZ(u8, obj_path)); | ||
| 428 | } | ||
| 429 | for (comp.c_object_table.items()) |entry| { | ||
| 430 | object_files.appendAssumeCapacity(try arena.dupeZ(u8, entry.key.status.success.object_path)); | ||
| 431 | } | ||
| 432 | if (module_obj_path) |p| { | ||
| 433 | object_files.appendAssumeCapacity(try arena.dupeZ(u8, p)); | ||
| 434 | } | ||
| 435 | |||
| 436 | const full_out_path = if (directory.path) |dir_path| | ||
| 437 | try std.fs.path.join(arena, &[_][]const u8{ dir_path, base.options.sub_path }) | ||
| 438 | else | ||
| 439 | base.options.sub_path; | ||
| 440 | const full_out_path_z = try arena.dupeZ(u8, full_out_path); | ||
| 441 | |||
| 442 | if (base.options.debug_link) { | ||
| 443 | std.debug.print("ar rcs {}", .{full_out_path_z}); | ||
| 444 | for (object_files.items) |arg| { | ||
| 445 | std.debug.print(" {}", .{arg}); | ||
| 446 | } | ||
| 447 | std.debug.print("\n", .{}); | ||
| 448 | } | ||
| 449 | |||
| 450 | const llvm = @import("llvm.zig"); | ||
| 451 | const os_type = @import("target.zig").osToLLVM(base.options.target.os.tag); | ||
| 452 | const bad = llvm.WriteArchive(full_out_path_z, object_files.items.ptr, object_files.items.len, os_type); | ||
| 453 | if (bad) return error.UnableToWriteArchive; | ||
| 454 | |||
| 455 | directory.handle.symLink(&digest, id_symlink_basename, .{}) catch |err| { | ||
| 456 | std.log.warn("failed to save archive hash digest symlink: {}", .{@errorName(err)}); | ||
| 457 | }; | ||
| 458 | |||
| 459 | ch.writeManifest() catch |err| { | ||
| 460 | std.log.warn("failed to write cache manifest when archiving: {}", .{@errorName(err)}); | ||
| 461 | }; | ||
| 462 | |||
| 463 | base.lock = ch.toOwnedLock(); | ||
| 349 | } | 464 | } |
| 350 | 465 | ||
| 351 | pub const Tag = enum { | 466 | pub const Tag = enum { |
src-self-hosted/link/C.zig+4| ... | @@ -74,6 +74,10 @@ pub fn updateDecl(self: *C, module: *Module, decl: *Module.Decl) !void { | ... | @@ -74,6 +74,10 @@ pub fn updateDecl(self: *C, module: *Module, decl: *Module.Decl) !void { |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | pub fn flush(self: *C, comp: *Compilation) !void { | 76 | pub fn flush(self: *C, comp: *Compilation) !void { |
| 77 | return self.flushModule(comp); | ||
| 78 | } | ||
| 79 | |||
| 80 | pub fn flushModule(self: *C, comp: *Compilation) !void { | ||
| 77 | const tracy = trace(@src()); | 81 | const tracy = trace(@src()); |
| 78 | defer tracy.end(); | 82 | defer tracy.end(); |
| 79 | 83 |
src-self-hosted/link/Coff.zig+9| ... | @@ -11,6 +11,7 @@ const Module = @import("../Module.zig"); | ... | @@ -11,6 +11,7 @@ const Module = @import("../Module.zig"); |
| 11 | const Compilation = @import("../Compilation.zig"); | 11 | const Compilation = @import("../Compilation.zig"); |
| 12 | const codegen = @import("../codegen.zig"); | 12 | const codegen = @import("../codegen.zig"); |
| 13 | const link = @import("../link.zig"); | 13 | const link = @import("../link.zig"); |
| 14 | const build_options = @import("build_options"); | ||
| 14 | 15 | ||
| 15 | const allocation_padding = 4 / 3; | 16 | const allocation_padding = 4 / 3; |
| 16 | const minimum_text_block_size = 64 * allocation_padding; | 17 | const minimum_text_block_size = 64 * allocation_padding; |
| ... | @@ -724,6 +725,14 @@ pub fn updateDeclExports(self: *Coff, module: *Module, decl: *const Module.Decl, | ... | @@ -724,6 +725,14 @@ pub fn updateDeclExports(self: *Coff, module: *Module, decl: *const Module.Decl, |
| 724 | } | 725 | } |
| 725 | 726 | ||
| 726 | pub fn flush(self: *Coff, comp: *Compilation) !void { | 727 | pub fn flush(self: *Coff, comp: *Compilation) !void { |
| 728 | if (build_options.have_llvm and self.base.options.use_lld) { | ||
| 729 | return error.CoffLinkingWithLLDUnimplemented; | ||
| 730 | } else { | ||
| 731 | return self.flushModule(comp); | ||
| 732 | } | ||
| 733 | } | ||
| 734 | |||
| 735 | pub fn flushModule(self: *Coff, comp: *Compilation) !void { | ||
| 727 | const tracy = trace(@src()); | 736 | const tracy = trace(@src()); |
| 728 | defer tracy.end(); | 737 | defer tracy.end(); |
| 729 | 738 |
src-self-hosted/link/Elf.zig+4-5| ... | @@ -719,12 +719,11 @@ pub fn flush(self: *Elf, comp: *Compilation) !void { | ... | @@ -719,12 +719,11 @@ pub fn flush(self: *Elf, comp: *Compilation) !void { |
| 719 | .Exe, .Obj => {}, | 719 | .Exe, .Obj => {}, |
| 720 | .Lib => return error.TODOImplementWritingLibFiles, | 720 | .Lib => return error.TODOImplementWritingLibFiles, |
| 721 | } | 721 | } |
| 722 | return self.flushInner(comp); | 722 | return self.flushModule(comp); |
| 723 | } | 723 | } |
| 724 | } | 724 | } |
| 725 | 725 | ||
| 726 | /// Commit pending changes and write headers. | 726 | pub fn flushModule(self: *Elf, comp: *Compilation) !void { |
| 727 | fn flushInner(self: *Elf, comp: *Compilation) !void { | ||
| 728 | const tracy = trace(@src()); | 727 | const tracy = trace(@src()); |
| 729 | defer tracy.end(); | 728 | defer tracy.end(); |
| 730 | 729 | ||
| ... | @@ -1221,7 +1220,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { | ... | @@ -1221,7 +1220,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1221 | // If there is no Zig code to compile, then we should skip flushing the output file because it | 1220 | // If there is no Zig code to compile, then we should skip flushing the output file because it |
| 1222 | // will not be part of the linker line anyway. | 1221 | // will not be part of the linker line anyway. |
| 1223 | const module_obj_path: ?[]const u8 = if (self.base.options.module) |module| blk: { | 1222 | const module_obj_path: ?[]const u8 = if (self.base.options.module) |module| blk: { |
| 1224 | try self.flushInner(comp); | 1223 | try self.flushModule(comp); |
| 1225 | 1224 | ||
| 1226 | const obj_basename = self.base.intermediary_basename.?; | 1225 | const obj_basename = self.base.intermediary_basename.?; |
| 1227 | const full_obj_path = if (directory.path) |dir_path| | 1226 | const full_obj_path = if (directory.path) |dir_path| |
| ... | @@ -1239,7 +1238,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { | ... | @@ -1239,7 +1238,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1239 | // After a successful link, we store the id in the metadata of a symlink named "id.txt" in | 1238 | // After a successful link, we store the id in the metadata of a symlink named "id.txt" in |
| 1240 | // the artifact directory. So, now, we check if this symlink exists, and if it matches | 1239 | // the artifact directory. So, now, we check if this symlink exists, and if it matches |
| 1241 | // our digest. If so, we can skip linking. Otherwise, we proceed with invoking LLD. | 1240 | // our digest. If so, we can skip linking. Otherwise, we proceed with invoking LLD. |
| 1242 | const id_symlink_basename = "id.txt"; | 1241 | const id_symlink_basename = "lld.id"; |
| 1243 | 1242 | ||
| 1244 | // We are about to obtain this lock, so here we give other processes a chance first. | 1243 | // We are about to obtain this lock, so here we give other processes a chance first. |
| 1245 | self.base.releaseLock(); | 1244 | self.base.releaseLock(); |
src-self-hosted/link/MachO.zig+10-1| ... | @@ -9,9 +9,10 @@ const macho = std.macho; | ... | @@ -9,9 +9,10 @@ const macho = std.macho; |
| 9 | const codegen = @import("../codegen.zig"); | 9 | const codegen = @import("../codegen.zig"); |
| 10 | const math = std.math; | 10 | const math = std.math; |
| 11 | const mem = std.mem; | 11 | const mem = std.mem; |
| 12 | |||
| 12 | const trace = @import("../tracy.zig").trace; | 13 | const trace = @import("../tracy.zig").trace; |
| 13 | const Type = @import("../type.zig").Type; | 14 | const Type = @import("../type.zig").Type; |
| 14 | 15 | const build_options = @import("build_options"); | |
| 15 | const Module = @import("../Module.zig"); | 16 | const Module = @import("../Module.zig"); |
| 16 | const Compilation = @import("../Compilation.zig"); | 17 | const Compilation = @import("../Compilation.zig"); |
| 17 | const link = @import("../link.zig"); | 18 | const link = @import("../link.zig"); |
| ... | @@ -178,6 +179,14 @@ pub fn createEmpty(gpa: *Allocator, options: link.Options) !*MachO { | ... | @@ -178,6 +179,14 @@ pub fn createEmpty(gpa: *Allocator, options: link.Options) !*MachO { |
| 178 | } | 179 | } |
| 179 | 180 | ||
| 180 | pub fn flush(self: *MachO, comp: *Compilation) !void { | 181 | pub fn flush(self: *MachO, comp: *Compilation) !void { |
| 182 | if (build_options.have_llvm and self.base.options.use_lld) { | ||
| 183 | return error.MachOLLDLinkingUnimplemented; | ||
| 184 | } else { | ||
| 185 | return self.flushModule(comp); | ||
| 186 | } | ||
| 187 | } | ||
| 188 | |||
| 189 | pub fn flushModule(self: *MachO, comp: *Compilation) !void { | ||
| 181 | const tracy = trace(@src()); | 190 | const tracy = trace(@src()); |
| 182 | defer tracy.end(); | 191 | defer tracy.end(); |
| 183 | 192 |
src-self-hosted/link/Wasm.zig+9| ... | @@ -11,6 +11,7 @@ const Compilation = @import("../Compilation.zig"); | ... | @@ -11,6 +11,7 @@ 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 | const trace = @import("../tracy.zig").trace; |
| 14 | const build_options = @import("build_options"); | ||
| 14 | 15 | ||
| 15 | /// Various magic numbers defined by the wasm spec | 16 | /// Various magic numbers defined by the wasm spec |
| 16 | const spec = struct { | 17 | const spec = struct { |
| ... | @@ -135,6 +136,14 @@ pub fn freeDecl(self: *Wasm, decl: *Module.Decl) void { | ... | @@ -135,6 +136,14 @@ pub fn freeDecl(self: *Wasm, decl: *Module.Decl) void { |
| 135 | } | 136 | } |
| 136 | 137 | ||
| 137 | pub fn flush(self: *Wasm, comp: *Compilation) !void { | 138 | pub fn flush(self: *Wasm, comp: *Compilation) !void { |
| 139 | if (build_options.have_llvm and self.base.options.use_lld) { | ||
| 140 | return error.WasmLinkingWithLLDUnimplemented; | ||
| 141 | } else { | ||
| 142 | return self.flushModule(comp); | ||
| 143 | } | ||
| 144 | } | ||
| 145 | |||
| 146 | pub fn flushModule(self: *Wasm, comp: *Compilation) !void { | ||
| 138 | const tracy = trace(@src()); | 147 | const tracy = trace(@src()); |
| 139 | defer tracy.end(); | 148 | defer tracy.end(); |
| 140 | 149 |
src-self-hosted/llvm.zig+48-1| ... | @@ -2,7 +2,7 @@ | ... | @@ -2,7 +2,7 @@ |
| 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 const Link = ZigLLDLink; |
| 5 | pub extern fn ZigLLDLink( | 5 | extern fn ZigLLDLink( |
| 6 | oformat: ObjectFormatType, | 6 | oformat: ObjectFormatType, |
| 7 | args: [*:null]const ?[*:0]const u8, | 7 | args: [*:null]const ?[*:0]const u8, |
| 8 | arg_count: usize, | 8 | arg_count: usize, |
| ... | @@ -25,3 +25,50 @@ extern fn LLVMGetHostCPUName() ?[*:0]u8; | ... | @@ -25,3 +25,50 @@ extern fn LLVMGetHostCPUName() ?[*:0]u8; |
| 25 | 25 | ||
| 26 | pub const GetNativeFeatures = ZigLLVMGetNativeFeatures; | 26 | pub const GetNativeFeatures = ZigLLVMGetNativeFeatures; |
| 27 | extern fn ZigLLVMGetNativeFeatures() ?[*:0]u8; | 27 | extern fn ZigLLVMGetNativeFeatures() ?[*:0]u8; |
| 28 | |||
| 29 | pub const WriteArchive = ZigLLVMWriteArchive; | ||
| 30 | extern fn ZigLLVMWriteArchive( | ||
| 31 | archive_name: [*:0]const u8, | ||
| 32 | file_names_ptr: [*]const [*:0]const u8, | ||
| 33 | file_names_len: usize, | ||
| 34 | os_type: OSType, | ||
| 35 | ) bool; | ||
| 36 | |||
| 37 | pub const OSType = extern enum(c_int) { | ||
| 38 | UnknownOS = 0, | ||
| 39 | Ananas = 1, | ||
| 40 | CloudABI = 2, | ||
| 41 | Darwin = 3, | ||
| 42 | DragonFly = 4, | ||
| 43 | FreeBSD = 5, | ||
| 44 | Fuchsia = 6, | ||
| 45 | IOS = 7, | ||
| 46 | KFreeBSD = 8, | ||
| 47 | Linux = 9, | ||
| 48 | Lv2 = 10, | ||
| 49 | MacOSX = 11, | ||
| 50 | NetBSD = 12, | ||
| 51 | OpenBSD = 13, | ||
| 52 | Solaris = 14, | ||
| 53 | Win32 = 15, | ||
| 54 | Haiku = 16, | ||
| 55 | Minix = 17, | ||
| 56 | RTEMS = 18, | ||
| 57 | NaCl = 19, | ||
| 58 | CNK = 20, | ||
| 59 | AIX = 21, | ||
| 60 | CUDA = 22, | ||
| 61 | NVCL = 23, | ||
| 62 | AMDHSA = 24, | ||
| 63 | PS4 = 25, | ||
| 64 | ELFIAMCU = 26, | ||
| 65 | TvOS = 27, | ||
| 66 | WatchOS = 28, | ||
| 67 | Mesa3D = 29, | ||
| 68 | Contiki = 30, | ||
| 69 | AMDPAL = 31, | ||
| 70 | HermitCore = 32, | ||
| 71 | Hurd = 33, | ||
| 72 | WASI = 34, | ||
| 73 | Emscripten = 35, | ||
| 74 | }; |
src-self-hosted/target.zig+41| ... | @@ -1,4 +1,5 @@ | ... | @@ -1,4 +1,5 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const llvm = @import("llvm.zig"); | ||
| 2 | 3 | ||
| 3 | pub const ArchOsAbi = struct { | 4 | pub const ArchOsAbi = struct { |
| 4 | arch: std.Target.Cpu.Arch, | 5 | arch: std.Target.Cpu.Arch, |
| ... | @@ -168,3 +169,43 @@ pub fn supportsStackProbing(target: std.Target) bool { | ... | @@ -168,3 +169,43 @@ pub fn supportsStackProbing(target: std.Target) bool { |
| 168 | return target.os.tag != .windows and target.os.tag != .uefi and | 169 | return target.os.tag != .windows and target.os.tag != .uefi and |
| 169 | (target.cpu.arch == .i386 or target.cpu.arch == .x86_64); | 170 | (target.cpu.arch == .i386 or target.cpu.arch == .x86_64); |
| 170 | } | 171 | } |
| 172 | |||
| 173 | pub fn osToLLVM(os_tag: std.Target.Os.Tag) llvm.OSType { | ||
| 174 | return switch (os_tag) { | ||
| 175 | .freestanding, .other => .UnknownOS, | ||
| 176 | .windows, .uefi => .Win32, | ||
| 177 | .ananas => .Ananas, | ||
| 178 | .cloudabi => .CloudABI, | ||
| 179 | .dragonfly => .DragonFly, | ||
| 180 | .freebsd => .FreeBSD, | ||
| 181 | .fuchsia => .Fuchsia, | ||
| 182 | .ios => .IOS, | ||
| 183 | .kfreebsd => .KFreeBSD, | ||
| 184 | .linux => .Linux, | ||
| 185 | .lv2 => .Lv2, | ||
| 186 | .macosx => .MacOSX, | ||
| 187 | .netbsd => .NetBSD, | ||
| 188 | .openbsd => .OpenBSD, | ||
| 189 | .solaris => .Solaris, | ||
| 190 | .haiku => .Haiku, | ||
| 191 | .minix => .Minix, | ||
| 192 | .rtems => .RTEMS, | ||
| 193 | .nacl => .NaCl, | ||
| 194 | .cnk => .CNK, | ||
| 195 | .aix => .AIX, | ||
| 196 | .cuda => .CUDA, | ||
| 197 | .nvcl => .NVCL, | ||
| 198 | .amdhsa => .AMDHSA, | ||
| 199 | .ps4 => .PS4, | ||
| 200 | .elfiamcu => .ELFIAMCU, | ||
| 201 | .tvos => .TvOS, | ||
| 202 | .watchos => .WatchOS, | ||
| 203 | .mesa3d => .Mesa3D, | ||
| 204 | .contiki => .Contiki, | ||
| 205 | .amdpal => .AMDPAL, | ||
| 206 | .hermit => .HermitCore, | ||
| 207 | .hurd => .Hurd, | ||
| 208 | .wasi => .WASI, | ||
| 209 | .emscripten => .Emscripten, | ||
| 210 | }; | ||
| 211 | } |