| author | |
| committer | |
| log | 76176104001420ea04840f9b31e706289e4ebf11 |
| tree | 4ba46044adc883630a3452b33f9d70541581d7ae |
| parent | 1b41f2d77ea14de27b0655a35a727d664cfc4ca4 |
| parent | 3cba603eae1a1c8b0338f5584041c73d55682c0a |
| signature |
introduce operating system version ranges as part of the target; self-host native dynamic linker detection and native glibc version detection104 files changed, 3338 insertions(+), 2123 deletions(-)
build.zig+1-1| ... | @@ -298,7 +298,7 @@ fn configureStage2(b: *Builder, exe: var, ctx: Context) !void { | ... | @@ -298,7 +298,7 @@ fn configureStage2(b: *Builder, exe: var, ctx: Context) !void { |
| 298 | } | 298 | } |
| 299 | dependOnLib(b, exe, ctx.llvm); | 299 | dependOnLib(b, exe, ctx.llvm); |
| 300 | 300 | ||
| 301 | if (exe.target.getOs() == .linux) { | 301 | if (exe.target.getOsTag() == .linux) { |
| 302 | try addCxxKnownPath(b, ctx, exe, "libstdc++.a", | 302 | try addCxxKnownPath(b, ctx, exe, "libstdc++.a", |
| 303 | \\Unable to determine path to libstdc++.a | 303 | \\Unable to determine path to libstdc++.a |
| 304 | \\On Fedora, install libstdc++-static and try again. | 304 | \\On Fedora, install libstdc++-static and try again. |
doc/docgen.zig+42-41| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 2 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const builtin = std.builtin; | ||
| 3 | const io = std.io; | 3 | const io = std.io; |
| 4 | const fs = std.fs; | 4 | const fs = std.fs; |
| 5 | const process = std.process; | 5 | const process = std.process; |
| ... | @@ -10,8 +10,8 @@ const testing = std.testing; | ... | @@ -10,8 +10,8 @@ const testing = std.testing; |
| 10 | 10 | ||
| 11 | const max_doc_file_size = 10 * 1024 * 1024; | 11 | const max_doc_file_size = 10 * 1024 * 1024; |
| 12 | 12 | ||
| 13 | const exe_ext = @as(std.build.Target, std.build.Target.Native).exeFileExt(); | 13 | const exe_ext = @as(std.zig.CrossTarget, .{}).exeFileExt(); |
| 14 | const obj_ext = @as(std.build.Target, std.build.Target.Native).oFileExt(); | 14 | const obj_ext = @as(std.zig.CrossTarget, .{}).oFileExt(); |
| 15 | const tmp_dir_name = "docgen_tmp"; | 15 | const tmp_dir_name = "docgen_tmp"; |
| 16 | const test_out_path = tmp_dir_name ++ fs.path.sep_str ++ "test" ++ exe_ext; | 16 | const test_out_path = tmp_dir_name ++ fs.path.sep_str ++ "test" ++ exe_ext; |
| 17 | 17 | ||
| ... | @@ -521,7 +521,7 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc { | ... | @@ -521,7 +521,7 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc { |
| 521 | return parseError(tokenizer, code_kind_tok, "unrecognized code kind: {}", .{code_kind_str}); | 521 | return parseError(tokenizer, code_kind_tok, "unrecognized code kind: {}", .{code_kind_str}); |
| 522 | } | 522 | } |
| 523 | 523 | ||
| 524 | var mode = builtin.Mode.Debug; | 524 | var mode: builtin.Mode = .Debug; |
| 525 | var link_objects = std.ArrayList([]const u8).init(allocator); | 525 | var link_objects = std.ArrayList([]const u8).init(allocator); |
| 526 | defer link_objects.deinit(); | 526 | defer link_objects.deinit(); |
| 527 | var target_str: ?[]const u8 = null; | 527 | var target_str: ?[]const u8 = null; |
| ... | @@ -533,9 +533,9 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc { | ... | @@ -533,9 +533,9 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc { |
| 533 | const end_code_tag = try eatToken(tokenizer, Token.Id.TagContent); | 533 | const end_code_tag = try eatToken(tokenizer, Token.Id.TagContent); |
| 534 | const end_tag_name = tokenizer.buffer[end_code_tag.start..end_code_tag.end]; | 534 | const end_tag_name = tokenizer.buffer[end_code_tag.start..end_code_tag.end]; |
| 535 | if (mem.eql(u8, end_tag_name, "code_release_fast")) { | 535 | if (mem.eql(u8, end_tag_name, "code_release_fast")) { |
| 536 | mode = builtin.Mode.ReleaseFast; | 536 | mode = .ReleaseFast; |
| 537 | } else if (mem.eql(u8, end_tag_name, "code_release_safe")) { | 537 | } else if (mem.eql(u8, end_tag_name, "code_release_safe")) { |
| 538 | mode = builtin.Mode.ReleaseSafe; | 538 | mode = .ReleaseSafe; |
| 539 | } else if (mem.eql(u8, end_tag_name, "code_link_object")) { | 539 | } else if (mem.eql(u8, end_tag_name, "code_link_object")) { |
| 540 | _ = try eatToken(tokenizer, Token.Id.Separator); | 540 | _ = try eatToken(tokenizer, Token.Id.Separator); |
| 541 | const obj_tok = try eatToken(tokenizer, Token.Id.TagContent); | 541 | const obj_tok = try eatToken(tokenizer, Token.Id.TagContent); |
| ... | @@ -1001,30 +1001,30 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var | ... | @@ -1001,30 +1001,30 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var |
| 1001 | 1001 | ||
| 1002 | for (toc.nodes) |node| { | 1002 | for (toc.nodes) |node| { |
| 1003 | switch (node) { | 1003 | switch (node) { |
| 1004 | Node.Content => |data| { | 1004 | .Content => |data| { |
| 1005 | try out.write(data); | 1005 | try out.write(data); |
| 1006 | }, | 1006 | }, |
| 1007 | Node.Link => |info| { | 1007 | .Link => |info| { |
| 1008 | if (!toc.urls.contains(info.url)) { | 1008 | if (!toc.urls.contains(info.url)) { |
| 1009 | return parseError(tokenizer, info.token, "url not found: {}", .{info.url}); | 1009 | return parseError(tokenizer, info.token, "url not found: {}", .{info.url}); |
| 1010 | } | 1010 | } |
| 1011 | try out.print("<a href=\"#{}\">{}</a>", .{ info.url, info.name }); | 1011 | try out.print("<a href=\"#{}\">{}</a>", .{ info.url, info.name }); |
| 1012 | }, | 1012 | }, |
| 1013 | Node.Nav => { | 1013 | .Nav => { |
| 1014 | try out.write(toc.toc); | 1014 | try out.write(toc.toc); |
| 1015 | }, | 1015 | }, |
| 1016 | Node.Builtin => |tok| { | 1016 | .Builtin => |tok| { |
| 1017 | try out.write("<pre>"); | 1017 | try out.write("<pre>"); |
| 1018 | try tokenizeAndPrintRaw(tokenizer, out, tok, builtin_code); | 1018 | try tokenizeAndPrintRaw(tokenizer, out, tok, builtin_code); |
| 1019 | try out.write("</pre>"); | 1019 | try out.write("</pre>"); |
| 1020 | }, | 1020 | }, |
| 1021 | Node.HeaderOpen => |info| { | 1021 | .HeaderOpen => |info| { |
| 1022 | try out.print( | 1022 | try out.print( |
| 1023 | "<h{} id=\"{}\"><a href=\"#toc-{}\">{}</a> <a class=\"hdr\" href=\"#{}\">§</a></h{}>\n", | 1023 | "<h{} id=\"{}\"><a href=\"#toc-{}\">{}</a> <a class=\"hdr\" href=\"#{}\">§</a></h{}>\n", |
| 1024 | .{ info.n, info.url, info.url, info.name, info.url, info.n }, | 1024 | .{ info.n, info.url, info.url, info.name, info.url, info.n }, |
| 1025 | ); | 1025 | ); |
| 1026 | }, | 1026 | }, |
| 1027 | Node.SeeAlso => |items| { | 1027 | .SeeAlso => |items| { |
| 1028 | try out.write("<p>See also:</p><ul>\n"); | 1028 | try out.write("<p>See also:</p><ul>\n"); |
| 1029 | for (items) |item| { | 1029 | for (items) |item| { |
| 1030 | const url = try urlize(allocator, item.name); | 1030 | const url = try urlize(allocator, item.name); |
| ... | @@ -1035,10 +1035,10 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var | ... | @@ -1035,10 +1035,10 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var |
| 1035 | } | 1035 | } |
| 1036 | try out.write("</ul>\n"); | 1036 | try out.write("</ul>\n"); |
| 1037 | }, | 1037 | }, |
| 1038 | Node.Syntax => |content_tok| { | 1038 | .Syntax => |content_tok| { |
| 1039 | try tokenizeAndPrint(tokenizer, out, content_tok); | 1039 | try tokenizeAndPrint(tokenizer, out, content_tok); |
| 1040 | }, | 1040 | }, |
| 1041 | Node.Code => |code| { | 1041 | .Code => |code| { |
| 1042 | code_progress_index += 1; | 1042 | code_progress_index += 1; |
| 1043 | warn("docgen example code {}/{}...", .{ code_progress_index, tokenizer.code_node_count }); | 1043 | warn("docgen example code {}/{}...", .{ code_progress_index, tokenizer.code_node_count }); |
| 1044 | 1044 | ||
| ... | @@ -1075,16 +1075,16 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var | ... | @@ -1075,16 +1075,16 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var |
| 1075 | }); | 1075 | }); |
| 1076 | try out.print("<pre><code class=\"shell\">$ zig build-exe {}.zig", .{code.name}); | 1076 | try out.print("<pre><code class=\"shell\">$ zig build-exe {}.zig", .{code.name}); |
| 1077 | switch (code.mode) { | 1077 | switch (code.mode) { |
| 1078 | builtin.Mode.Debug => {}, | 1078 | .Debug => {}, |
| 1079 | builtin.Mode.ReleaseSafe => { | 1079 | .ReleaseSafe => { |
| 1080 | try build_args.append("--release-safe"); | 1080 | try build_args.append("--release-safe"); |
| 1081 | try out.print(" --release-safe", .{}); | 1081 | try out.print(" --release-safe", .{}); |
| 1082 | }, | 1082 | }, |
| 1083 | builtin.Mode.ReleaseFast => { | 1083 | .ReleaseFast => { |
| 1084 | try build_args.append("--release-fast"); | 1084 | try build_args.append("--release-fast"); |
| 1085 | try out.print(" --release-fast", .{}); | 1085 | try out.print(" --release-fast", .{}); |
| 1086 | }, | 1086 | }, |
| 1087 | builtin.Mode.ReleaseSmall => { | 1087 | .ReleaseSmall => { |
| 1088 | try build_args.append("--release-small"); | 1088 | try build_args.append("--release-small"); |
| 1089 | try out.print(" --release-small", .{}); | 1089 | try out.print(" --release-small", .{}); |
| 1090 | }, | 1090 | }, |
| ... | @@ -1142,13 +1142,14 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var | ... | @@ -1142,13 +1142,14 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var |
| 1142 | try out.print("\n{}</code></pre>\n", .{colored_stderr}); | 1142 | try out.print("\n{}</code></pre>\n", .{colored_stderr}); |
| 1143 | break :code_block; | 1143 | break :code_block; |
| 1144 | } | 1144 | } |
| 1145 | const exec_result = exec(allocator, &env_map, build_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "example failed to compile", .{}); | 1145 | const exec_result = exec(allocator, &env_map, build_args.toSliceConst()) catch |
| 1146 | return parseError(tokenizer, code.source_token, "example failed to compile", .{}); | ||
| 1146 | 1147 | ||
| 1147 | if (code.target_str) |triple| { | 1148 | if (code.target_str) |triple| { |
| 1148 | if (mem.startsWith(u8, triple, "wasm32") or | 1149 | if (mem.startsWith(u8, triple, "wasm32") or |
| 1149 | mem.startsWith(u8, triple, "riscv64-linux") or | 1150 | mem.startsWith(u8, triple, "riscv64-linux") or |
| 1150 | mem.startsWith(u8, triple, "x86_64-linux") and | 1151 | (mem.startsWith(u8, triple, "x86_64-linux") and |
| 1151 | (builtin.os != .linux or builtin.arch != .x86_64)) | 1152 | std.Target.current.os.tag != .linux or std.Target.current.cpu.arch != .x86_64)) |
| 1152 | { | 1153 | { |
| 1153 | // skip execution | 1154 | // skip execution |
| 1154 | try out.print("</code></pre>\n", .{}); | 1155 | try out.print("</code></pre>\n", .{}); |
| ... | @@ -1207,16 +1208,16 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var | ... | @@ -1207,16 +1208,16 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var |
| 1207 | }); | 1208 | }); |
| 1208 | try out.print("<pre><code class=\"shell\">$ zig test {}.zig", .{code.name}); | 1209 | try out.print("<pre><code class=\"shell\">$ zig test {}.zig", .{code.name}); |
| 1209 | switch (code.mode) { | 1210 | switch (code.mode) { |
| 1210 | builtin.Mode.Debug => {}, | 1211 | .Debug => {}, |
| 1211 | builtin.Mode.ReleaseSafe => { | 1212 | .ReleaseSafe => { |
| 1212 | try test_args.append("--release-safe"); | 1213 | try test_args.append("--release-safe"); |
| 1213 | try out.print(" --release-safe", .{}); | 1214 | try out.print(" --release-safe", .{}); |
| 1214 | }, | 1215 | }, |
| 1215 | builtin.Mode.ReleaseFast => { | 1216 | .ReleaseFast => { |
| 1216 | try test_args.append("--release-fast"); | 1217 | try test_args.append("--release-fast"); |
| 1217 | try out.print(" --release-fast", .{}); | 1218 | try out.print(" --release-fast", .{}); |
| 1218 | }, | 1219 | }, |
| 1219 | builtin.Mode.ReleaseSmall => { | 1220 | .ReleaseSmall => { |
| 1220 | try test_args.append("--release-small"); | 1221 | try test_args.append("--release-small"); |
| 1221 | try out.print(" --release-small", .{}); | 1222 | try out.print(" --release-small", .{}); |
| 1222 | }, | 1223 | }, |
| ... | @@ -1249,16 +1250,16 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var | ... | @@ -1249,16 +1250,16 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var |
| 1249 | }); | 1250 | }); |
| 1250 | try out.print("<pre><code class=\"shell\">$ zig test {}.zig", .{code.name}); | 1251 | try out.print("<pre><code class=\"shell\">$ zig test {}.zig", .{code.name}); |
| 1251 | switch (code.mode) { | 1252 | switch (code.mode) { |
| 1252 | builtin.Mode.Debug => {}, | 1253 | .Debug => {}, |
| 1253 | builtin.Mode.ReleaseSafe => { | 1254 | .ReleaseSafe => { |
| 1254 | try test_args.append("--release-safe"); | 1255 | try test_args.append("--release-safe"); |
| 1255 | try out.print(" --release-safe", .{}); | 1256 | try out.print(" --release-safe", .{}); |
| 1256 | }, | 1257 | }, |
| 1257 | builtin.Mode.ReleaseFast => { | 1258 | .ReleaseFast => { |
| 1258 | try test_args.append("--release-fast"); | 1259 | try test_args.append("--release-fast"); |
| 1259 | try out.print(" --release-fast", .{}); | 1260 | try out.print(" --release-fast", .{}); |
| 1260 | }, | 1261 | }, |
| 1261 | builtin.Mode.ReleaseSmall => { | 1262 | .ReleaseSmall => { |
| 1262 | try test_args.append("--release-small"); | 1263 | try test_args.append("--release-small"); |
| 1263 | try out.print(" --release-small", .{}); | 1264 | try out.print(" --release-small", .{}); |
| 1264 | }, | 1265 | }, |
| ... | @@ -1306,16 +1307,16 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var | ... | @@ -1306,16 +1307,16 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var |
| 1306 | }); | 1307 | }); |
| 1307 | var mode_arg: []const u8 = ""; | 1308 | var mode_arg: []const u8 = ""; |
| 1308 | switch (code.mode) { | 1309 | switch (code.mode) { |
| 1309 | builtin.Mode.Debug => {}, | 1310 | .Debug => {}, |
| 1310 | builtin.Mode.ReleaseSafe => { | 1311 | .ReleaseSafe => { |
| 1311 | try test_args.append("--release-safe"); | 1312 | try test_args.append("--release-safe"); |
| 1312 | mode_arg = " --release-safe"; | 1313 | mode_arg = " --release-safe"; |
| 1313 | }, | 1314 | }, |
| 1314 | builtin.Mode.ReleaseFast => { | 1315 | .ReleaseFast => { |
| 1315 | try test_args.append("--release-fast"); | 1316 | try test_args.append("--release-fast"); |
| 1316 | mode_arg = " --release-fast"; | 1317 | mode_arg = " --release-fast"; |
| 1317 | }, | 1318 | }, |
| 1318 | builtin.Mode.ReleaseSmall => { | 1319 | .ReleaseSmall => { |
| 1319 | try test_args.append("--release-small"); | 1320 | try test_args.append("--release-small"); |
| 1320 | mode_arg = " --release-small"; | 1321 | mode_arg = " --release-small"; |
| 1321 | }, | 1322 | }, |
| ... | @@ -1386,20 +1387,20 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var | ... | @@ -1386,20 +1387,20 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var |
| 1386 | } | 1387 | } |
| 1387 | 1388 | ||
| 1388 | switch (code.mode) { | 1389 | switch (code.mode) { |
| 1389 | builtin.Mode.Debug => {}, | 1390 | .Debug => {}, |
| 1390 | builtin.Mode.ReleaseSafe => { | 1391 | .ReleaseSafe => { |
| 1391 | try build_args.append("--release-safe"); | 1392 | try build_args.append("--release-safe"); |
| 1392 | if (!code.is_inline) { | 1393 | if (!code.is_inline) { |
| 1393 | try out.print(" --release-safe", .{}); | 1394 | try out.print(" --release-safe", .{}); |
| 1394 | } | 1395 | } |
| 1395 | }, | 1396 | }, |
| 1396 | builtin.Mode.ReleaseFast => { | 1397 | .ReleaseFast => { |
| 1397 | try build_args.append("--release-fast"); | 1398 | try build_args.append("--release-fast"); |
| 1398 | if (!code.is_inline) { | 1399 | if (!code.is_inline) { |
| 1399 | try out.print(" --release-fast", .{}); | 1400 | try out.print(" --release-fast", .{}); |
| 1400 | } | 1401 | } |
| 1401 | }, | 1402 | }, |
| 1402 | builtin.Mode.ReleaseSmall => { | 1403 | .ReleaseSmall => { |
| 1403 | try build_args.append("--release-small"); | 1404 | try build_args.append("--release-small"); |
| 1404 | if (!code.is_inline) { | 1405 | if (!code.is_inline) { |
| 1405 | try out.print(" --release-small", .{}); | 1406 | try out.print(" --release-small", .{}); |
| ... | @@ -1461,16 +1462,16 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var | ... | @@ -1461,16 +1462,16 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var |
| 1461 | }); | 1462 | }); |
| 1462 | try out.print("<pre><code class=\"shell\">$ zig build-lib {}.zig", .{code.name}); | 1463 | try out.print("<pre><code class=\"shell\">$ zig build-lib {}.zig", .{code.name}); |
| 1463 | switch (code.mode) { | 1464 | switch (code.mode) { |
| 1464 | builtin.Mode.Debug => {}, | 1465 | .Debug => {}, |
| 1465 | builtin.Mode.ReleaseSafe => { | 1466 | .ReleaseSafe => { |
| 1466 | try test_args.append("--release-safe"); | 1467 | try test_args.append("--release-safe"); |
| 1467 | try out.print(" --release-safe", .{}); | 1468 | try out.print(" --release-safe", .{}); |
| 1468 | }, | 1469 | }, |
| 1469 | builtin.Mode.ReleaseFast => { | 1470 | .ReleaseFast => { |
| 1470 | try test_args.append("--release-fast"); | 1471 | try test_args.append("--release-fast"); |
| 1471 | try out.print(" --release-fast", .{}); | 1472 | try out.print(" --release-fast", .{}); |
| 1472 | }, | 1473 | }, |
| 1473 | builtin.Mode.ReleaseSmall => { | 1474 | .ReleaseSmall => { |
| 1474 | try test_args.append("--release-small"); | 1475 | try test_args.append("--release-small"); |
| 1475 | try out.print(" --release-small", .{}); | 1476 | try out.print(" --release-small", .{}); |
| 1476 | }, | 1477 | }, |
doc/langref.html.in+15-15| ... | @@ -965,7 +965,8 @@ const nan = std.math.nan(f128); | ... | @@ -965,7 +965,8 @@ const nan = std.math.nan(f128); |
| 965 | but you can switch to {#syntax#}Optimized{#endsyntax#} mode on a per-block basis:</p> | 965 | but you can switch to {#syntax#}Optimized{#endsyntax#} mode on a per-block basis:</p> |
| 966 | {#code_begin|obj|foo#} | 966 | {#code_begin|obj|foo#} |
| 967 | {#code_release_fast#} | 967 | {#code_release_fast#} |
| 968 | const builtin = @import("builtin"); | 968 | const std = @import("std"); |
| 969 | const builtin = std.builtin; | ||
| 969 | const big = @as(f64, 1 << 40); | 970 | const big = @as(f64, 1 << 40); |
| 970 | 971 | ||
| 971 | export fn foo_strict(x: f64) f64 { | 972 | export fn foo_strict(x: f64) f64 { |
| ... | @@ -2063,15 +2064,15 @@ test "pointer child type" { | ... | @@ -2063,15 +2064,15 @@ test "pointer child type" { |
| 2063 | alignment of the underlying type, it can be omitted from the type: | 2064 | alignment of the underlying type, it can be omitted from the type: |
| 2064 | </p> | 2065 | </p> |
| 2065 | {#code_begin|test#} | 2066 | {#code_begin|test#} |
| 2066 | const assert = @import("std").debug.assert; | 2067 | const std = @import("std"); |
| 2067 | const builtin = @import("builtin"); | 2068 | const assert = std.debug.assert; |
| 2068 | 2069 | ||
| 2069 | test "variable alignment" { | 2070 | test "variable alignment" { |
| 2070 | var x: i32 = 1234; | 2071 | var x: i32 = 1234; |
| 2071 | const align_of_i32 = @alignOf(@TypeOf(x)); | 2072 | const align_of_i32 = @alignOf(@TypeOf(x)); |
| 2072 | assert(@TypeOf(&x) == *i32); | 2073 | assert(@TypeOf(&x) == *i32); |
| 2073 | assert(*i32 == *align(align_of_i32) i32); | 2074 | assert(*i32 == *align(align_of_i32) i32); |
| 2074 | if (builtin.arch == builtin.Arch.x86_64) { | 2075 | if (std.Target.current.cpu.arch == .x86_64) { |
| 2075 | assert((*i32).alignment == 4); | 2076 | assert((*i32).alignment == 4); |
| 2076 | } | 2077 | } |
| 2077 | } | 2078 | } |
| ... | @@ -2474,7 +2475,7 @@ test "default struct initialization fields" { | ... | @@ -2474,7 +2475,7 @@ test "default struct initialization fields" { |
| 2474 | </p> | 2475 | </p> |
| 2475 | {#code_begin|test#} | 2476 | {#code_begin|test#} |
| 2476 | const std = @import("std"); | 2477 | const std = @import("std"); |
| 2477 | const builtin = @import("builtin"); | 2478 | const builtin = std.builtin; |
| 2478 | const assert = std.debug.assert; | 2479 | const assert = std.debug.assert; |
| 2479 | 2480 | ||
| 2480 | const Full = packed struct { | 2481 | const Full = packed struct { |
| ... | @@ -3204,8 +3205,8 @@ test "separate scopes" { | ... | @@ -3204,8 +3205,8 @@ test "separate scopes" { |
| 3204 | 3205 | ||
| 3205 | {#header_open|switch#} | 3206 | {#header_open|switch#} |
| 3206 | {#code_begin|test|switch#} | 3207 | {#code_begin|test|switch#} |
| 3207 | const assert = @import("std").debug.assert; | 3208 | const std = @import("std"); |
| 3208 | const builtin = @import("builtin"); | 3209 | const assert = std.debug.assert; |
| 3209 | 3210 | ||
| 3210 | test "switch simple" { | 3211 | test "switch simple" { |
| 3211 | const a: u64 = 10; | 3212 | const a: u64 = 10; |
| ... | @@ -3249,16 +3250,16 @@ test "switch simple" { | ... | @@ -3249,16 +3250,16 @@ test "switch simple" { |
| 3249 | } | 3250 | } |
| 3250 | 3251 | ||
| 3251 | // Switch expressions can be used outside a function: | 3252 | // Switch expressions can be used outside a function: |
| 3252 | const os_msg = switch (builtin.os) { | 3253 | const os_msg = switch (std.Target.current.os.tag) { |
| 3253 | builtin.Os.linux => "we found a linux user", | 3254 | .linux => "we found a linux user", |
| 3254 | else => "not a linux user", | 3255 | else => "not a linux user", |
| 3255 | }; | 3256 | }; |
| 3256 | 3257 | ||
| 3257 | // Inside a function, switch statements implicitly are compile-time | 3258 | // Inside a function, switch statements implicitly are compile-time |
| 3258 | // evaluated if the target expression is compile-time known. | 3259 | // evaluated if the target expression is compile-time known. |
| 3259 | test "switch inside function" { | 3260 | test "switch inside function" { |
| 3260 | switch (builtin.os) { | 3261 | switch (std.Target.current.os.tag) { |
| 3261 | builtin.Os.fuchsia => { | 3262 | .fuchsia => { |
| 3262 | // On an OS other than fuchsia, block is not even analyzed, | 3263 | // On an OS other than fuchsia, block is not even analyzed, |
| 3263 | // so this compile error is not triggered. | 3264 | // so this compile error is not triggered. |
| 3264 | // On fuchsia this compile error would be triggered. | 3265 | // On fuchsia this compile error would be triggered. |
| ... | @@ -7364,8 +7365,6 @@ test "main" { | ... | @@ -7364,8 +7365,6 @@ test "main" { |
| 7364 | the {#syntax#}export{#endsyntax#} keyword used on a function: | 7365 | the {#syntax#}export{#endsyntax#} keyword used on a function: |
| 7365 | </p> | 7366 | </p> |
| 7366 | {#code_begin|obj#} | 7367 | {#code_begin|obj#} |
| 7367 | const builtin = @import("builtin"); | ||
| 7368 | |||
| 7369 | comptime { | 7368 | comptime { |
| 7370 | @export(internalName, .{ .name = "foo", .linkage = .Strong }); | 7369 | @export(internalName, .{ .name = "foo", .linkage = .Strong }); |
| 7371 | } | 7370 | } |
| ... | @@ -9397,7 +9396,7 @@ const separator = if (builtin.os == builtin.Os.windows) '\\' else '/'; | ... | @@ -9397,7 +9396,7 @@ const separator = if (builtin.os == builtin.Os.windows) '\\' else '/'; |
| 9397 | </p> | 9396 | </p> |
| 9398 | {#code_begin|test|detect_test#} | 9397 | {#code_begin|test|detect_test#} |
| 9399 | const std = @import("std"); | 9398 | const std = @import("std"); |
| 9400 | const builtin = @import("builtin"); | 9399 | const builtin = std.builtin; |
| 9401 | const assert = std.debug.assert; | 9400 | const assert = std.debug.assert; |
| 9402 | 9401 | ||
| 9403 | test "builtin.is_test" { | 9402 | test "builtin.is_test" { |
| ... | @@ -9715,7 +9714,8 @@ WebAssembly.instantiate(typedArray, { | ... | @@ -9715,7 +9714,8 @@ WebAssembly.instantiate(typedArray, { |
| 9715 | <pre><code>$ node test.js | 9714 | <pre><code>$ node test.js |
| 9716 | The result is 3</code></pre> | 9715 | The result is 3</code></pre> |
| 9717 | {#header_open|WASI#} | 9716 | {#header_open|WASI#} |
| 9718 | <p>Zig's support for WebAssembly System Interface (WASI) is under active development. Example of using the standard library and reading command line arguments:</p> | 9717 | <p>Zig's support for WebAssembly System Interface (WASI) is under active development. |
| 9718 | Example of using the standard library and reading command line arguments:</p> | ||
| 9719 | {#code_begin|exe|wasi#} | 9719 | {#code_begin|exe|wasi#} |
| 9720 | {#target_wasi#} | 9720 | {#target_wasi#} |
| 9721 | const std = @import("std"); | 9721 | const std = @import("std"); |
lib/std/build.zig+133-106| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | const std = @import("std.zig"); | 1 | const std = @import("std.zig"); |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = std.builtin; |
| 3 | const io = std.io; | 3 | const io = std.io; |
| 4 | const fs = std.fs; | 4 | const fs = std.fs; |
| 5 | const mem = std.mem; | 5 | const mem = std.mem; |
| ... | @@ -15,6 +15,7 @@ const BufSet = std.BufSet; | ... | @@ -15,6 +15,7 @@ const BufSet = std.BufSet; |
| 15 | const BufMap = std.BufMap; | 15 | const BufMap = std.BufMap; |
| 16 | const fmt_lib = std.fmt; | 16 | const fmt_lib = std.fmt; |
| 17 | const File = std.fs.File; | 17 | const File = std.fs.File; |
| 18 | const CrossTarget = std.zig.CrossTarget; | ||
| 18 | 19 | ||
| 19 | pub const FmtStep = @import("build/fmt.zig").FmtStep; | 20 | pub const FmtStep = @import("build/fmt.zig").FmtStep; |
| 20 | pub const TranslateCStep = @import("build/translate_c.zig").TranslateCStep; | 21 | pub const TranslateCStep = @import("build/translate_c.zig").TranslateCStep; |
| ... | @@ -521,24 +522,91 @@ pub const Builder = struct { | ... | @@ -521,24 +522,91 @@ pub const Builder = struct { |
| 521 | return mode; | 522 | return mode; |
| 522 | } | 523 | } |
| 523 | 524 | ||
| 524 | /// Exposes standard `zig build` options for choosing a target. Pass `null` to support all targets. | 525 | pub const StandardTargetOptionsArgs = struct { |
| 525 | pub fn standardTargetOptions(self: *Builder, supported_targets: ?[]const Target) Target { | 526 | whitelist: ?[]const CrossTarget = null, |
| 526 | if (supported_targets) |target_list| { | 527 | |
| 527 | // TODO detect multiple args and emit an error message | 528 | default_target: CrossTarget = CrossTarget{}, |
| 528 | // there's probably a better way to collect the target | 529 | }; |
| 529 | for (target_list) |targ| { | 530 | |
| 530 | const targ_str = targ.zigTriple(self.allocator) catch unreachable; | 531 | /// Exposes standard `zig build` options for choosing a target. |
| 531 | const targ_desc = targ.allocDescription(self.allocator) catch unreachable; | 532 | pub fn standardTargetOptions(self: *Builder, args: StandardTargetOptionsArgs) CrossTarget { |
| 532 | const this_targ_opt = self.option(bool, targ_str, targ_desc) orelse false; | 533 | const triple = self.option( |
| 533 | if (this_targ_opt) { | 534 | []const u8, |
| 534 | return targ; | 535 | "target", |
| 536 | "The CPU architecture, OS, and ABI to build for.", | ||
| 537 | ) orelse return args.default_target; | ||
| 538 | |||
| 539 | // TODO add cpu and features as part of the target triple | ||
| 540 | |||
| 541 | var diags: CrossTarget.ParseOptions.Diagnostics = .{}; | ||
| 542 | const selected_target = CrossTarget.parse(.{ | ||
| 543 | .arch_os_abi = triple, | ||
| 544 | .diagnostics = &diags, | ||
| 545 | }) catch |err| switch (err) { | ||
| 546 | error.UnknownCpuModel => { | ||
| 547 | std.debug.warn("Unknown CPU: '{}'\nAvailable CPUs for architecture '{}':\n", .{ | ||
| 548 | diags.cpu_name.?, | ||
| 549 | @tagName(diags.arch.?), | ||
| 550 | }); | ||
| 551 | for (diags.arch.?.allCpuModels()) |cpu| { | ||
| 552 | std.debug.warn(" {}\n", .{cpu.name}); | ||
| 553 | } | ||
| 554 | process.exit(1); | ||
| 555 | }, | ||
| 556 | error.UnknownCpuFeature => { | ||
| 557 | std.debug.warn( | ||
| 558 | \\Unknown CPU feature: '{}' | ||
| 559 | \\Available CPU features for architecture '{}': | ||
| 560 | \\ | ||
| 561 | , .{ | ||
| 562 | diags.unknown_feature_name, | ||
| 563 | @tagName(diags.arch.?), | ||
| 564 | }); | ||
| 565 | for (diags.arch.?.allFeaturesList()) |feature| { | ||
| 566 | std.debug.warn(" {}: {}\n", .{ feature.name, feature.description }); | ||
| 567 | } | ||
| 568 | process.exit(1); | ||
| 569 | }, | ||
| 570 | error.UnknownOperatingSystem => { | ||
| 571 | std.debug.warn( | ||
| 572 | \\Unknown OS: '{}' | ||
| 573 | \\Available operating systems: | ||
| 574 | \\ | ||
| 575 | , .{diags.os_name}); | ||
| 576 | inline for (std.meta.fields(std.Target.Os.Tag)) |field| { | ||
| 577 | std.debug.warn(" {}\n", .{field.name}); | ||
| 578 | } | ||
| 579 | process.exit(1); | ||
| 580 | }, | ||
| 581 | else => |e| { | ||
| 582 | std.debug.warn("Unable to parse target '{}': {}\n", .{ triple, @errorName(e) }); | ||
| 583 | process.exit(1); | ||
| 584 | }, | ||
| 585 | }; | ||
| 586 | |||
| 587 | const selected_canonicalized_triple = selected_target.zigTriple(self.allocator) catch unreachable; | ||
| 588 | |||
| 589 | if (args.whitelist) |list| whitelist_check: { | ||
| 590 | // Make sure it's a match of one of the list. | ||
| 591 | for (list) |t| { | ||
| 592 | const t_triple = t.zigTriple(self.allocator) catch unreachable; | ||
| 593 | if (mem.eql(u8, t_triple, selected_canonicalized_triple)) { | ||
| 594 | break :whitelist_check; | ||
| 535 | } | 595 | } |
| 536 | } | 596 | } |
| 537 | return Target.Native; | 597 | std.debug.warn("Chosen target '{}' does not match one of the supported targets:\n", .{ |
| 538 | } else { | 598 | selected_canonicalized_triple, |
| 539 | const target_str = self.option([]const u8, "target", "the target to build for") orelse return Target.Native; | 599 | }); |
| 540 | return Target.parse(.{ .arch_os_abi = target_str }) catch unreachable; // TODO better error message for bad target | 600 | for (list) |t| { |
| 601 | const t_triple = t.zigTriple(self.allocator) catch unreachable; | ||
| 602 | std.debug.warn(" {}\n", .{t_triple}); | ||
| 603 | } | ||
| 604 | // TODO instead of process exit, return error and have a zig build flag implemented by | ||
| 605 | // the build runner that turns process exits into error return traces | ||
| 606 | process.exit(1); | ||
| 541 | } | 607 | } |
| 608 | |||
| 609 | return selected_target; | ||
| 542 | } | 610 | } |
| 543 | 611 | ||
| 544 | pub fn addUserInputOption(self: *Builder, name: []const u8, value: []const u8) !bool { | 612 | pub fn addUserInputOption(self: *Builder, name: []const u8, value: []const u8) !bool { |
| ... | @@ -796,7 +864,7 @@ pub const Builder = struct { | ... | @@ -796,7 +864,7 @@ pub const Builder = struct { |
| 796 | 864 | ||
| 797 | pub fn findProgram(self: *Builder, names: []const []const u8, paths: []const []const u8) ![]const u8 { | 865 | pub fn findProgram(self: *Builder, names: []const []const u8, paths: []const []const u8) ![]const u8 { |
| 798 | // TODO report error for ambiguous situations | 866 | // TODO report error for ambiguous situations |
| 799 | const exe_extension = (Target{ .Native = {} }).exeFileExt(); | 867 | const exe_extension = @as(CrossTarget, .{}).exeFileExt(); |
| 800 | for (self.search_prefixes.toSliceConst()) |search_prefix| { | 868 | for (self.search_prefixes.toSliceConst()) |search_prefix| { |
| 801 | for (names) |name| { | 869 | for (names) |name| { |
| 802 | if (fs.path.isAbsolute(name)) { | 870 | if (fs.path.isAbsolute(name)) { |
| ... | @@ -971,21 +1039,19 @@ pub const Builder = struct { | ... | @@ -971,21 +1039,19 @@ pub const Builder = struct { |
| 971 | }; | 1039 | }; |
| 972 | 1040 | ||
| 973 | test "builder.findProgram compiles" { | 1041 | test "builder.findProgram compiles" { |
| 974 | // TODO: uncomment and fix the leak | 1042 | var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); |
| 975 | // const builder = try Builder.create(std.testing.allocator, "zig", "zig-cache", "zig-cache"); | 1043 | defer arena.deinit(); |
| 976 | const builder = try Builder.create(std.heap.page_allocator, "zig", "zig-cache", "zig-cache"); | 1044 | |
| 1045 | const builder = try Builder.create(&arena.allocator, "zig", "zig-cache", "zig-cache"); | ||
| 977 | defer builder.destroy(); | 1046 | defer builder.destroy(); |
| 978 | _ = builder.findProgram(&[_][]const u8{}, &[_][]const u8{}) catch null; | 1047 | _ = builder.findProgram(&[_][]const u8{}, &[_][]const u8{}) catch null; |
| 979 | } | 1048 | } |
| 980 | 1049 | ||
| 981 | /// Deprecated. Use `builtin.Version`. | 1050 | /// Deprecated. Use `std.builtin.Version`. |
| 982 | pub const Version = builtin.Version; | 1051 | pub const Version = builtin.Version; |
| 983 | 1052 | ||
| 984 | /// Deprecated. Use `std.Target.Cross`. | 1053 | /// Deprecated. Use `std.zig.CrossTarget`. |
| 985 | pub const CrossTarget = std.Target.Cross; | 1054 | pub const Target = std.zig.CrossTarget; |
| 986 | |||
| 987 | /// Deprecated. Use `std.Target`. | ||
| 988 | pub const Target = std.Target; | ||
| 989 | 1055 | ||
| 990 | pub const Pkg = struct { | 1056 | pub const Pkg = struct { |
| 991 | name: []const u8, | 1057 | name: []const u8, |
| ... | @@ -1038,7 +1104,7 @@ pub const LibExeObjStep = struct { | ... | @@ -1038,7 +1104,7 @@ pub const LibExeObjStep = struct { |
| 1038 | step: Step, | 1104 | step: Step, |
| 1039 | builder: *Builder, | 1105 | builder: *Builder, |
| 1040 | name: []const u8, | 1106 | name: []const u8, |
| 1041 | target: Target, | 1107 | target: CrossTarget = CrossTarget{}, |
| 1042 | linker_script: ?[]const u8 = null, | 1108 | linker_script: ?[]const u8 = null, |
| 1043 | version_script: ?[]const u8 = null, | 1109 | version_script: ?[]const u8 = null, |
| 1044 | out_filename: []const u8, | 1110 | out_filename: []const u8, |
| ... | @@ -1076,7 +1142,7 @@ pub const LibExeObjStep = struct { | ... | @@ -1076,7 +1142,7 @@ pub const LibExeObjStep = struct { |
| 1076 | out_pdb_filename: []const u8, | 1142 | out_pdb_filename: []const u8, |
| 1077 | packages: ArrayList(Pkg), | 1143 | packages: ArrayList(Pkg), |
| 1078 | build_options_contents: std.Buffer, | 1144 | build_options_contents: std.Buffer, |
| 1079 | system_linker_hack: bool, | 1145 | system_linker_hack: bool = false, |
| 1080 | 1146 | ||
| 1081 | object_src: []const u8, | 1147 | object_src: []const u8, |
| 1082 | 1148 | ||
| ... | @@ -1091,7 +1157,6 @@ pub const LibExeObjStep = struct { | ... | @@ -1091,7 +1157,6 @@ pub const LibExeObjStep = struct { |
| 1091 | install_step: ?*InstallArtifactStep, | 1157 | install_step: ?*InstallArtifactStep, |
| 1092 | 1158 | ||
| 1093 | libc_file: ?[]const u8 = null, | 1159 | libc_file: ?[]const u8 = null, |
| 1094 | target_glibc: ?Version = null, | ||
| 1095 | 1160 | ||
| 1096 | valgrind_support: ?bool = null, | 1161 | valgrind_support: ?bool = null, |
| 1097 | 1162 | ||
| ... | @@ -1112,8 +1177,6 @@ pub const LibExeObjStep = struct { | ... | @@ -1112,8 +1177,6 @@ pub const LibExeObjStep = struct { |
| 1112 | /// that contains the path `aarch64-linux-gnu/lib/ld-linux-aarch64.so.1`. | 1177 | /// that contains the path `aarch64-linux-gnu/lib/ld-linux-aarch64.so.1`. |
| 1113 | glibc_multi_install_dir: ?[]const u8 = null, | 1178 | glibc_multi_install_dir: ?[]const u8 = null, |
| 1114 | 1179 | ||
| 1115 | dynamic_linker: ?[]const u8 = null, | ||
| 1116 | |||
| 1117 | /// Position Independent Code | 1180 | /// Position Independent Code |
| 1118 | force_pic: ?bool = null, | 1181 | force_pic: ?bool = null, |
| 1119 | 1182 | ||
| ... | @@ -1191,7 +1254,6 @@ pub const LibExeObjStep = struct { | ... | @@ -1191,7 +1254,6 @@ pub const LibExeObjStep = struct { |
| 1191 | .kind = kind, | 1254 | .kind = kind, |
| 1192 | .root_src = root_src, | 1255 | .root_src = root_src, |
| 1193 | .name = name, | 1256 | .name = name, |
| 1194 | .target = Target.Native, | ||
| 1195 | .frameworks = BufSet.init(builder.allocator), | 1257 | .frameworks = BufSet.init(builder.allocator), |
| 1196 | .step = Step.init(name, builder.allocator, make), | 1258 | .step = Step.init(name, builder.allocator, make), |
| 1197 | .version = ver, | 1259 | .version = ver, |
| ... | @@ -1210,7 +1272,6 @@ pub const LibExeObjStep = struct { | ... | @@ -1210,7 +1272,6 @@ pub const LibExeObjStep = struct { |
| 1210 | .object_src = undefined, | 1272 | .object_src = undefined, |
| 1211 | .build_options_contents = std.Buffer.initSize(builder.allocator, 0) catch unreachable, | 1273 | .build_options_contents = std.Buffer.initSize(builder.allocator, 0) catch unreachable, |
| 1212 | .c_std = Builder.CStd.C99, | 1274 | .c_std = Builder.CStd.C99, |
| 1213 | .system_linker_hack = false, | ||
| 1214 | .override_lib_dir = null, | 1275 | .override_lib_dir = null, |
| 1215 | .main_pkg_path = null, | 1276 | .main_pkg_path = null, |
| 1216 | .exec_cmd_args = null, | 1277 | .exec_cmd_args = null, |
| ... | @@ -1282,36 +1343,11 @@ pub const LibExeObjStep = struct { | ... | @@ -1282,36 +1343,11 @@ pub const LibExeObjStep = struct { |
| 1282 | } | 1343 | } |
| 1283 | } | 1344 | } |
| 1284 | 1345 | ||
| 1285 | /// Deprecated. Use `setTheTarget`. | 1346 | pub fn setTarget(self: *LibExeObjStep, target: CrossTarget) void { |
| 1286 | pub fn setTarget( | ||
| 1287 | self: *LibExeObjStep, | ||
| 1288 | target_arch: builtin.Arch, | ||
| 1289 | target_os: builtin.Os, | ||
| 1290 | target_abi: builtin.Abi, | ||
| 1291 | ) void { | ||
| 1292 | return self.setTheTarget(Target{ | ||
| 1293 | .Cross = CrossTarget{ | ||
| 1294 | .arch = target_arch, | ||
| 1295 | .os = target_os, | ||
| 1296 | .abi = target_abi, | ||
| 1297 | .cpu_features = target_arch.getBaselineCpuFeatures(), | ||
| 1298 | }, | ||
| 1299 | }); | ||
| 1300 | } | ||
| 1301 | |||
| 1302 | pub fn setTheTarget(self: *LibExeObjStep, target: Target) void { | ||
| 1303 | self.target = target; | 1347 | self.target = target; |
| 1304 | self.computeOutFileNames(); | 1348 | self.computeOutFileNames(); |
| 1305 | } | 1349 | } |
| 1306 | 1350 | ||
| 1307 | pub fn setTargetGLibC(self: *LibExeObjStep, major: u32, minor: u32, patch: u32) void { | ||
| 1308 | self.target_glibc = Version{ | ||
| 1309 | .major = major, | ||
| 1310 | .minor = minor, | ||
| 1311 | .patch = patch, | ||
| 1312 | }; | ||
| 1313 | } | ||
| 1314 | |||
| 1315 | pub fn setOutputDir(self: *LibExeObjStep, dir: []const u8) void { | 1351 | pub fn setOutputDir(self: *LibExeObjStep, dir: []const u8) void { |
| 1316 | self.output_dir = self.builder.dupePath(dir); | 1352 | self.output_dir = self.builder.dupePath(dir); |
| 1317 | } | 1353 | } |
| ... | @@ -1692,7 +1728,7 @@ pub const LibExeObjStep = struct { | ... | @@ -1692,7 +1728,7 @@ pub const LibExeObjStep = struct { |
| 1692 | .NotFound => return error.VcpkgNotFound, | 1728 | .NotFound => return error.VcpkgNotFound, |
| 1693 | .Found => |root| { | 1729 | .Found => |root| { |
| 1694 | const allocator = self.builder.allocator; | 1730 | const allocator = self.builder.allocator; |
| 1695 | const triplet = try Target.vcpkgTriplet(allocator, self.target, linkage); | 1731 | const triplet = try self.target.vcpkgTriplet(allocator, linkage); |
| 1696 | defer self.builder.allocator.free(triplet); | 1732 | defer self.builder.allocator.free(triplet); |
| 1697 | 1733 | ||
| 1698 | const include_path = try fs.path.join(allocator, &[_][]const u8{ root, "installed", triplet, "include" }); | 1734 | const include_path = try fs.path.join(allocator, &[_][]const u8{ root, "installed", triplet, "include" }); |
| ... | @@ -1905,47 +1941,46 @@ pub const LibExeObjStep = struct { | ... | @@ -1905,47 +1941,46 @@ pub const LibExeObjStep = struct { |
| 1905 | try zig_args.append(@tagName(self.code_model)); | 1941 | try zig_args.append(@tagName(self.code_model)); |
| 1906 | } | 1942 | } |
| 1907 | 1943 | ||
| 1908 | switch (self.target) { | 1944 | if (!self.target.isNative()) { |
| 1909 | .Native => {}, | 1945 | try zig_args.append("-target"); |
| 1910 | .Cross => |cross| { | 1946 | try zig_args.append(try self.target.zigTriple(builder.allocator)); |
| 1911 | try zig_args.append("-target"); | ||
| 1912 | try zig_args.append(self.target.zigTriple(builder.allocator) catch unreachable); | ||
| 1913 | 1947 | ||
| 1914 | const all_features = self.target.getArch().allFeaturesList(); | 1948 | // TODO this logic can disappear if cpu model + features becomes part of the target triple |
| 1915 | var populated_cpu_features = cross.cpu.model.features; | 1949 | const cross = self.target.toTarget(); |
| 1916 | populated_cpu_features.populateDependencies(all_features); | 1950 | const all_features = cross.cpu.arch.allFeaturesList(); |
| 1951 | var populated_cpu_features = cross.cpu.model.features; | ||
| 1952 | populated_cpu_features.populateDependencies(all_features); | ||
| 1917 | 1953 | ||
| 1918 | if (populated_cpu_features.eql(cross.cpu.features)) { | 1954 | if (populated_cpu_features.eql(cross.cpu.features)) { |
| 1919 | // The CPU name alone is sufficient. | 1955 | // The CPU name alone is sufficient. |
| 1920 | // If it is the baseline CPU, no command line args are required. | 1956 | // If it is the baseline CPU, no command line args are required. |
| 1921 | if (cross.cpu.model != Target.Cpu.baseline(self.target.getArch()).model) { | 1957 | if (cross.cpu.model != std.Target.Cpu.baseline(cross.cpu.arch).model) { |
| 1922 | try zig_args.append("-mcpu"); | 1958 | try zig_args.append("-mcpu"); |
| 1923 | try zig_args.append(cross.cpu.model.name); | 1959 | try zig_args.append(cross.cpu.model.name); |
| 1924 | } | 1960 | } |
| 1925 | } else { | 1961 | } else { |
| 1926 | var mcpu_buffer = try std.Buffer.init(builder.allocator, "-mcpu="); | 1962 | var mcpu_buffer = try std.Buffer.init(builder.allocator, "-mcpu="); |
| 1927 | try mcpu_buffer.append(cross.cpu.model.name); | 1963 | try mcpu_buffer.append(cross.cpu.model.name); |
| 1928 | 1964 | ||
| 1929 | for (all_features) |feature, i_usize| { | 1965 | for (all_features) |feature, i_usize| { |
| 1930 | const i = @intCast(Target.Cpu.Feature.Set.Index, i_usize); | 1966 | const i = @intCast(std.Target.Cpu.Feature.Set.Index, i_usize); |
| 1931 | const in_cpu_set = populated_cpu_features.isEnabled(i); | 1967 | const in_cpu_set = populated_cpu_features.isEnabled(i); |
| 1932 | const in_actual_set = cross.cpu.features.isEnabled(i); | 1968 | const in_actual_set = cross.cpu.features.isEnabled(i); |
| 1933 | if (in_cpu_set and !in_actual_set) { | 1969 | if (in_cpu_set and !in_actual_set) { |
| 1934 | try mcpu_buffer.appendByte('-'); | 1970 | try mcpu_buffer.appendByte('-'); |
| 1935 | try mcpu_buffer.append(feature.name); | 1971 | try mcpu_buffer.append(feature.name); |
| 1936 | } else if (!in_cpu_set and in_actual_set) { | 1972 | } else if (!in_cpu_set and in_actual_set) { |
| 1937 | try mcpu_buffer.appendByte('+'); | 1973 | try mcpu_buffer.appendByte('+'); |
| 1938 | try mcpu_buffer.append(feature.name); | 1974 | try mcpu_buffer.append(feature.name); |
| 1939 | } | ||
| 1940 | } | 1975 | } |
| 1941 | try zig_args.append(mcpu_buffer.toSliceConst()); | ||
| 1942 | } | 1976 | } |
| 1943 | }, | 1977 | try zig_args.append(mcpu_buffer.toSliceConst()); |
| 1944 | } | 1978 | } |
| 1945 | 1979 | ||
| 1946 | if (self.target_glibc) |ver| { | 1980 | if (self.target.dynamic_linker.get()) |dynamic_linker| { |
| 1947 | try zig_args.append("-target-glibc"); | 1981 | try zig_args.append("--dynamic-linker"); |
| 1948 | try zig_args.append(builder.fmt("{}.{}.{}", .{ ver.major, ver.minor, ver.patch })); | 1982 | try zig_args.append(dynamic_linker); |
| 1983 | } | ||
| 1949 | } | 1984 | } |
| 1950 | 1985 | ||
| 1951 | if (self.linker_script) |linker_script| { | 1986 | if (self.linker_script) |linker_script| { |
| ... | @@ -1953,11 +1988,6 @@ pub const LibExeObjStep = struct { | ... | @@ -1953,11 +1988,6 @@ pub const LibExeObjStep = struct { |
| 1953 | zig_args.append(builder.pathFromRoot(linker_script)) catch unreachable; | 1988 | zig_args.append(builder.pathFromRoot(linker_script)) catch unreachable; |
| 1954 | } | 1989 | } |
| 1955 | 1990 | ||
| 1956 | if (self.dynamic_linker) |dynamic_linker| { | ||
| 1957 | try zig_args.append("--dynamic-linker"); | ||
| 1958 | try zig_args.append(dynamic_linker); | ||
| 1959 | } | ||
| 1960 | |||
| 1961 | if (self.version_script) |version_script| { | 1991 | if (self.version_script) |version_script| { |
| 1962 | try zig_args.append("--version-script"); | 1992 | try zig_args.append("--version-script"); |
| 1963 | try zig_args.append(builder.pathFromRoot(version_script)); | 1993 | try zig_args.append(builder.pathFromRoot(version_script)); |
| ... | @@ -1975,7 +2005,7 @@ pub const LibExeObjStep = struct { | ... | @@ -1975,7 +2005,7 @@ pub const LibExeObjStep = struct { |
| 1975 | } else switch (self.target.getExternalExecutor()) { | 2005 | } else switch (self.target.getExternalExecutor()) { |
| 1976 | .native, .unavailable => {}, | 2006 | .native, .unavailable => {}, |
| 1977 | .qemu => |bin_name| if (self.enable_qemu) qemu: { | 2007 | .qemu => |bin_name| if (self.enable_qemu) qemu: { |
| 1978 | const need_cross_glibc = self.target.isGnu() and self.target.isLinux() and self.is_linking_libc; | 2008 | const need_cross_glibc = self.target.isGnuLibC() and self.is_linking_libc; |
| 1979 | const glibc_dir_arg = if (need_cross_glibc) | 2009 | const glibc_dir_arg = if (need_cross_glibc) |
| 1980 | self.glibc_multi_install_dir orelse break :qemu | 2010 | self.glibc_multi_install_dir orelse break :qemu |
| 1981 | else | 2011 | else |
| ... | @@ -2420,10 +2450,7 @@ const VcpkgRootStatus = enum { | ... | @@ -2420,10 +2450,7 @@ const VcpkgRootStatus = enum { |
| 2420 | Found, | 2450 | Found, |
| 2421 | }; | 2451 | }; |
| 2422 | 2452 | ||
| 2423 | pub const VcpkgLinkage = enum { | 2453 | pub const VcpkgLinkage = std.builtin.LinkMode; |
| 2424 | Static, | ||
| 2425 | Dynamic, | ||
| 2426 | }; | ||
| 2427 | 2454 | ||
| 2428 | pub const InstallDir = enum { | 2455 | pub const InstallDir = enum { |
| 2429 | Prefix, | 2456 | Prefix, |
lib/std/build/run.zig+1-1| ... | @@ -82,7 +82,7 @@ pub const RunStep = struct { | ... | @@ -82,7 +82,7 @@ pub const RunStep = struct { |
| 82 | 82 | ||
| 83 | var key: []const u8 = undefined; | 83 | var key: []const u8 = undefined; |
| 84 | var prev_path: ?[]const u8 = undefined; | 84 | var prev_path: ?[]const u8 = undefined; |
| 85 | if (builtin.os == .windows) { | 85 | if (builtin.os.tag == .windows) { |
| 86 | key = "Path"; | 86 | key = "Path"; |
| 87 | prev_path = env_map.get(key); | 87 | prev_path = env_map.get(key); |
| 88 | if (prev_path == null) { | 88 | if (prev_path == null) { |
lib/std/build/translate_c.zig+6-8| ... | @@ -7,6 +7,7 @@ const LibExeObjStep = build.LibExeObjStep; | ... | @@ -7,6 +7,7 @@ const LibExeObjStep = build.LibExeObjStep; |
| 7 | const CheckFileStep = build.CheckFileStep; | 7 | const CheckFileStep = build.CheckFileStep; |
| 8 | const fs = std.fs; | 8 | const fs = std.fs; |
| 9 | const mem = std.mem; | 9 | const mem = std.mem; |
| 10 | const CrossTarget = std.zig.CrossTarget; | ||
| 10 | 11 | ||
| 11 | pub const TranslateCStep = struct { | 12 | pub const TranslateCStep = struct { |
| 12 | step: Step, | 13 | step: Step, |
| ... | @@ -14,7 +15,7 @@ pub const TranslateCStep = struct { | ... | @@ -14,7 +15,7 @@ pub const TranslateCStep = struct { |
| 14 | source: build.FileSource, | 15 | source: build.FileSource, |
| 15 | output_dir: ?[]const u8, | 16 | output_dir: ?[]const u8, |
| 16 | out_basename: []const u8, | 17 | out_basename: []const u8, |
| 17 | target: std.Target = .Native, | 18 | target: CrossTarget = CrossTarget{}, |
| 18 | 19 | ||
| 19 | pub fn create(builder: *Builder, source: build.FileSource) *TranslateCStep { | 20 | pub fn create(builder: *Builder, source: build.FileSource) *TranslateCStep { |
| 20 | const self = builder.allocator.create(TranslateCStep) catch unreachable; | 21 | const self = builder.allocator.create(TranslateCStep) catch unreachable; |
| ... | @@ -39,7 +40,7 @@ pub const TranslateCStep = struct { | ... | @@ -39,7 +40,7 @@ pub const TranslateCStep = struct { |
| 39 | ) catch unreachable; | 40 | ) catch unreachable; |
| 40 | } | 41 | } |
| 41 | 42 | ||
| 42 | pub fn setTarget(self: *TranslateCStep, target: std.Target) void { | 43 | pub fn setTarget(self: *TranslateCStep, target: CrossTarget) void { |
| 43 | self.target = target; | 44 | self.target = target; |
| 44 | } | 45 | } |
| 45 | 46 | ||
| ... | @@ -63,12 +64,9 @@ pub const TranslateCStep = struct { | ... | @@ -63,12 +64,9 @@ pub const TranslateCStep = struct { |
| 63 | try argv_list.append("--cache"); | 64 | try argv_list.append("--cache"); |
| 64 | try argv_list.append("on"); | 65 | try argv_list.append("on"); |
| 65 | 66 | ||
| 66 | switch (self.target) { | 67 | if (!self.target.isNative()) { |
| 67 | .Native => {}, | 68 | try argv_list.append("-target"); |
| 68 | .Cross => { | 69 | try argv_list.append(try self.target.zigTriple(self.builder.allocator)); |
| 69 | try argv_list.append("-target"); | ||
| 70 | try argv_list.append(try self.target.zigTriple(self.builder.allocator)); | ||
| 71 | }, | ||
| 72 | } | 70 | } |
| 73 | 71 | ||
| 74 | try argv_list.append(self.source.getPath(self.builder)); | 72 | try argv_list.append(self.source.getPath(self.builder)); |
lib/std/builtin.zig+55-2| ... | @@ -398,7 +398,60 @@ pub const LinkMode = enum { | ... | @@ -398,7 +398,60 @@ pub const LinkMode = enum { |
| 398 | pub const Version = struct { | 398 | pub const Version = struct { |
| 399 | major: u32, | 399 | major: u32, |
| 400 | minor: u32, | 400 | minor: u32, |
| 401 | patch: u32, | 401 | patch: u32 = 0, |
| 402 | |||
| 403 | pub const Range = struct { | ||
| 404 | min: Version, | ||
| 405 | max: Version, | ||
| 406 | |||
| 407 | pub fn includesVersion(self: LinuxVersionRange, ver: Version) bool { | ||
| 408 | if (self.min.compare(ver) == .gt) return false; | ||
| 409 | if (self.max.compare(ver) == .lt) return false; | ||
| 410 | return true; | ||
| 411 | } | ||
| 412 | }; | ||
| 413 | |||
| 414 | pub fn order(lhs: Version, rhs: Version) std.math.Order { | ||
| 415 | if (lhs.major < rhs.major) return .lt; | ||
| 416 | if (lhs.major > rhs.major) return .gt; | ||
| 417 | if (lhs.minor < rhs.minor) return .lt; | ||
| 418 | if (lhs.minor > rhs.minor) return .gt; | ||
| 419 | if (lhs.patch < rhs.patch) return .lt; | ||
| 420 | if (lhs.patch > rhs.patch) return .gt; | ||
| 421 | return .eq; | ||
| 422 | } | ||
| 423 | |||
| 424 | pub fn parse(text: []const u8) !Version { | ||
| 425 | var it = std.mem.separate(text, "."); | ||
| 426 | return Version{ | ||
| 427 | .major = try std.fmt.parseInt(u32, it.next() orelse return error.InvalidVersion, 10), | ||
| 428 | .minor = try std.fmt.parseInt(u32, it.next() orelse "0", 10), | ||
| 429 | .patch = try std.fmt.parseInt(u32, it.next() orelse "0", 10), | ||
| 430 | }; | ||
| 431 | } | ||
| 432 | |||
| 433 | pub fn format( | ||
| 434 | self: Version, | ||
| 435 | comptime fmt: []const u8, | ||
| 436 | options: std.fmt.FormatOptions, | ||
| 437 | context: var, | ||
| 438 | comptime Error: type, | ||
| 439 | comptime output: fn (@TypeOf(context), []const u8) Error!void, | ||
| 440 | ) Error!void { | ||
| 441 | if (fmt.len == 0) { | ||
| 442 | if (self.patch == 0) { | ||
| 443 | if (self.minor == 0) { | ||
| 444 | return std.fmt.format(context, Error, output, "{}", .{self.major}); | ||
| 445 | } else { | ||
| 446 | return std.fmt.format(context, Error, output, "{}.{}", .{ self.major, self.minor }); | ||
| 447 | } | ||
| 448 | } else { | ||
| 449 | return std.fmt.format(context, Error, output, "{}.{}.{}", .{ self.major, self.minor, self.patch }); | ||
| 450 | } | ||
| 451 | } else { | ||
| 452 | @compileError("Unknown format string: '" ++ fmt ++ "'"); | ||
| 453 | } | ||
| 454 | } | ||
| 402 | }; | 455 | }; |
| 403 | 456 | ||
| 404 | /// This data structure is used by the Zig language code generation and | 457 | /// This data structure is used by the Zig language code generation and |
| ... | @@ -474,7 +527,7 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace) noreturn | ... | @@ -474,7 +527,7 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace) noreturn |
| 474 | root.os.panic(msg, error_return_trace); | 527 | root.os.panic(msg, error_return_trace); |
| 475 | unreachable; | 528 | unreachable; |
| 476 | } | 529 | } |
| 477 | switch (os) { | 530 | switch (os.tag) { |
| 478 | .freestanding => { | 531 | .freestanding => { |
| 479 | while (true) { | 532 | while (true) { |
| 480 | @breakpoint(); | 533 | @breakpoint(); |
lib/std/c.zig+14-13| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 2 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const builtin = std.builtin; | ||
| 3 | const page_size = std.mem.page_size; | 3 | const page_size = std.mem.page_size; |
| 4 | 4 | ||
| 5 | pub const tokenizer = @import("c/tokenizer.zig"); | 5 | pub const tokenizer = @import("c/tokenizer.zig"); |
| ... | @@ -10,7 +10,7 @@ pub const ast = @import("c/ast.zig"); | ... | @@ -10,7 +10,7 @@ pub const ast = @import("c/ast.zig"); |
| 10 | 10 | ||
| 11 | pub usingnamespace @import("os/bits.zig"); | 11 | pub usingnamespace @import("os/bits.zig"); |
| 12 | 12 | ||
| 13 | pub usingnamespace switch (builtin.os) { | 13 | pub usingnamespace switch (std.Target.current.os.tag) { |
| 14 | .linux => @import("c/linux.zig"), | 14 | .linux => @import("c/linux.zig"), |
| 15 | .windows => @import("c/windows.zig"), | 15 | .windows => @import("c/windows.zig"), |
| 16 | .macosx, .ios, .tvos, .watchos => @import("c/darwin.zig"), | 16 | .macosx, .ios, .tvos, .watchos => @import("c/darwin.zig"), |
| ... | @@ -46,17 +46,16 @@ pub fn versionCheck(glibc_version: builtin.Version) type { | ... | @@ -46,17 +46,16 @@ pub fn versionCheck(glibc_version: builtin.Version) type { |
| 46 | return struct { | 46 | return struct { |
| 47 | pub const ok = blk: { | 47 | pub const ok = blk: { |
| 48 | if (!builtin.link_libc) break :blk false; | 48 | if (!builtin.link_libc) break :blk false; |
| 49 | switch (builtin.abi) { | 49 | if (std.Target.current.abi.isMusl()) break :blk true; |
| 50 | .musl, .musleabi, .musleabihf => break :blk true, | 50 | if (std.Target.current.isGnuLibC()) { |
| 51 | .gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => { | 51 | const ver = std.Target.current.os.version_range.linux.glibc; |
| 52 | const ver = builtin.glibc_version orelse break :blk false; | 52 | const order = ver.order(glibc_version); |
| 53 | if (ver.major < glibc_version.major) break :blk false; | 53 | break :blk switch (order) { |
| 54 | if (ver.major > glibc_version.major) break :blk true; | 54 | .gt, .eq => true, |
| 55 | if (ver.minor < glibc_version.minor) break :blk false; | 55 | .lt => false, |
| 56 | if (ver.minor > glibc_version.minor) break :blk true; | 56 | }; |
| 57 | break :blk ver.patch >= glibc_version.patch; | 57 | } else { |
| 58 | }, | 58 | break :blk false; |
| 59 | else => break :blk false, | ||
| 60 | } | 59 | } |
| 61 | }; | 60 | }; |
| 62 | }; | 61 | }; |
| ... | @@ -109,6 +108,7 @@ pub extern "c" fn execve(path: [*:0]const u8, argv: [*:null]const ?[*:0]const u8 | ... | @@ -109,6 +108,7 @@ pub extern "c" fn execve(path: [*:0]const u8, argv: [*:null]const ?[*:0]const u8 |
| 109 | pub extern "c" fn dup(fd: fd_t) c_int; | 108 | pub extern "c" fn dup(fd: fd_t) c_int; |
| 110 | pub extern "c" fn dup2(old_fd: fd_t, new_fd: fd_t) c_int; | 109 | pub extern "c" fn dup2(old_fd: fd_t, new_fd: fd_t) c_int; |
| 111 | pub extern "c" fn readlink(noalias path: [*:0]const u8, noalias buf: [*]u8, bufsize: usize) isize; | 110 | pub extern "c" fn readlink(noalias path: [*:0]const u8, noalias buf: [*]u8, bufsize: usize) isize; |
| 111 | pub extern "c" fn readlinkat(dirfd: fd_t, noalias path: [*:0]const u8, noalias buf: [*]u8, bufsize: usize) isize; | ||
| 112 | pub extern "c" fn realpath(noalias file_name: [*:0]const u8, noalias resolved_name: [*]u8) ?[*:0]u8; | 112 | pub extern "c" fn realpath(noalias file_name: [*:0]const u8, noalias resolved_name: [*]u8) ?[*:0]u8; |
| 113 | pub extern "c" fn sigprocmask(how: c_int, noalias set: ?*const sigset_t, noalias oset: ?*sigset_t) c_int; | 113 | pub extern "c" fn sigprocmask(how: c_int, noalias set: ?*const sigset_t, noalias oset: ?*sigset_t) c_int; |
| 114 | pub extern "c" fn gettimeofday(noalias tv: ?*timeval, noalias tz: ?*timezone) c_int; | 114 | pub extern "c" fn gettimeofday(noalias tv: ?*timeval, noalias tz: ?*timezone) c_int; |
| ... | @@ -125,6 +125,7 @@ pub extern "c" fn sysctlnametomib(name: [*:0]const u8, mibp: ?*c_int, sizep: ?*u | ... | @@ -125,6 +125,7 @@ pub extern "c" fn sysctlnametomib(name: [*:0]const u8, mibp: ?*c_int, sizep: ?*u |
| 125 | pub extern "c" fn tcgetattr(fd: fd_t, termios_p: *termios) c_int; | 125 | pub extern "c" fn tcgetattr(fd: fd_t, termios_p: *termios) c_int; |
| 126 | pub extern "c" fn tcsetattr(fd: fd_t, optional_action: TCSA, termios_p: *const termios) c_int; | 126 | pub extern "c" fn tcsetattr(fd: fd_t, optional_action: TCSA, termios_p: *const termios) c_int; |
| 127 | pub extern "c" fn fcntl(fd: fd_t, cmd: c_int, ...) c_int; | 127 | pub extern "c" fn fcntl(fd: fd_t, cmd: c_int, ...) c_int; |
| 128 | pub extern "c" fn uname(buf: *utsname) c_int; | ||
| 128 | 129 | ||
| 129 | pub extern "c" fn gethostname(name: [*]u8, len: usize) c_int; | 130 | pub extern "c" fn gethostname(name: [*]u8, len: usize) c_int; |
| 130 | pub extern "c" fn bind(socket: fd_t, address: ?*const sockaddr, address_len: socklen_t) c_int; | 131 | pub extern "c" fn bind(socket: fd_t, address: ?*const sockaddr, address_len: socklen_t) c_int; |
lib/std/c/linux.zig+1-1| ... | @@ -94,7 +94,7 @@ pub const pthread_cond_t = extern struct { | ... | @@ -94,7 +94,7 @@ pub const pthread_cond_t = extern struct { |
| 94 | size: [__SIZEOF_PTHREAD_COND_T]u8 align(@alignOf(usize)) = [_]u8{0} ** __SIZEOF_PTHREAD_COND_T, | 94 | size: [__SIZEOF_PTHREAD_COND_T]u8 align(@alignOf(usize)) = [_]u8{0} ** __SIZEOF_PTHREAD_COND_T, |
| 95 | }; | 95 | }; |
| 96 | const __SIZEOF_PTHREAD_COND_T = 48; | 96 | const __SIZEOF_PTHREAD_COND_T = 48; |
| 97 | const __SIZEOF_PTHREAD_MUTEX_T = if (builtin.os == .fuchsia) 40 else switch (builtin.abi) { | 97 | const __SIZEOF_PTHREAD_MUTEX_T = if (builtin.os.tag == .fuchsia) 40 else switch (builtin.abi) { |
| 98 | .musl, .musleabi, .musleabihf => if (@sizeOf(usize) == 8) 40 else 24, | 98 | .musl, .musleabi, .musleabihf => if (@sizeOf(usize) == 8) 40 else 24, |
| 99 | .gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => switch (builtin.arch) { | 99 | .gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => switch (builtin.arch) { |
| 100 | .aarch64 => 48, | 100 | .aarch64 => 48, |
lib/std/child_process.zig+13-13| ... | @@ -17,9 +17,9 @@ const TailQueue = std.TailQueue; | ... | @@ -17,9 +17,9 @@ const TailQueue = std.TailQueue; |
| 17 | const maxInt = std.math.maxInt; | 17 | const maxInt = std.math.maxInt; |
| 18 | 18 | ||
| 19 | pub const ChildProcess = struct { | 19 | pub const ChildProcess = struct { |
| 20 | pid: if (builtin.os == .windows) void else i32, | 20 | pid: if (builtin.os.tag == .windows) void else i32, |
| 21 | handle: if (builtin.os == .windows) windows.HANDLE else void, | 21 | handle: if (builtin.os.tag == .windows) windows.HANDLE else void, |
| 22 | thread_handle: if (builtin.os == .windows) windows.HANDLE else void, | 22 | thread_handle: if (builtin.os.tag == .windows) windows.HANDLE else void, |
| 23 | 23 | ||
| 24 | allocator: *mem.Allocator, | 24 | allocator: *mem.Allocator, |
| 25 | 25 | ||
| ... | @@ -39,15 +39,15 @@ pub const ChildProcess = struct { | ... | @@ -39,15 +39,15 @@ pub const ChildProcess = struct { |
| 39 | stderr_behavior: StdIo, | 39 | stderr_behavior: StdIo, |
| 40 | 40 | ||
| 41 | /// Set to change the user id when spawning the child process. | 41 | /// Set to change the user id when spawning the child process. |
| 42 | uid: if (builtin.os == .windows) void else ?u32, | 42 | uid: if (builtin.os.tag == .windows) void else ?u32, |
| 43 | 43 | ||
| 44 | /// Set to change the group id when spawning the child process. | 44 | /// Set to change the group id when spawning the child process. |
| 45 | gid: if (builtin.os == .windows) void else ?u32, | 45 | gid: if (builtin.os.tag == .windows) void else ?u32, |
| 46 | 46 | ||
| 47 | /// Set to change the current working directory when spawning the child process. | 47 | /// Set to change the current working directory when spawning the child process. |
| 48 | cwd: ?[]const u8, | 48 | cwd: ?[]const u8, |
| 49 | 49 | ||
| 50 | err_pipe: if (builtin.os == .windows) void else [2]os.fd_t, | 50 | err_pipe: if (builtin.os.tag == .windows) void else [2]os.fd_t, |
| 51 | 51 | ||
| 52 | expand_arg0: Arg0Expand, | 52 | expand_arg0: Arg0Expand, |
| 53 | 53 | ||
| ... | @@ -96,8 +96,8 @@ pub const ChildProcess = struct { | ... | @@ -96,8 +96,8 @@ pub const ChildProcess = struct { |
| 96 | .term = null, | 96 | .term = null, |
| 97 | .env_map = null, | 97 | .env_map = null, |
| 98 | .cwd = null, | 98 | .cwd = null, |
| 99 | .uid = if (builtin.os == .windows) {} else null, | 99 | .uid = if (builtin.os.tag == .windows) {} else null, |
| 100 | .gid = if (builtin.os == .windows) {} else null, | 100 | .gid = if (builtin.os.tag == .windows) {} else null, |
| 101 | .stdin = null, | 101 | .stdin = null, |
| 102 | .stdout = null, | 102 | .stdout = null, |
| 103 | .stderr = null, | 103 | .stderr = null, |
| ... | @@ -118,7 +118,7 @@ pub const ChildProcess = struct { | ... | @@ -118,7 +118,7 @@ pub const ChildProcess = struct { |
| 118 | 118 | ||
| 119 | /// On success must call `kill` or `wait`. | 119 | /// On success must call `kill` or `wait`. |
| 120 | pub fn spawn(self: *ChildProcess) SpawnError!void { | 120 | pub fn spawn(self: *ChildProcess) SpawnError!void { |
| 121 | if (builtin.os == .windows) { | 121 | if (builtin.os.tag == .windows) { |
| 122 | return self.spawnWindows(); | 122 | return self.spawnWindows(); |
| 123 | } else { | 123 | } else { |
| 124 | return self.spawnPosix(); | 124 | return self.spawnPosix(); |
| ... | @@ -132,7 +132,7 @@ pub const ChildProcess = struct { | ... | @@ -132,7 +132,7 @@ pub const ChildProcess = struct { |
| 132 | 132 | ||
| 133 | /// Forcibly terminates child process and then cleans up all resources. | 133 | /// Forcibly terminates child process and then cleans up all resources. |
| 134 | pub fn kill(self: *ChildProcess) !Term { | 134 | pub fn kill(self: *ChildProcess) !Term { |
| 135 | if (builtin.os == .windows) { | 135 | if (builtin.os.tag == .windows) { |
| 136 | return self.killWindows(1); | 136 | return self.killWindows(1); |
| 137 | } else { | 137 | } else { |
| 138 | return self.killPosix(); | 138 | return self.killPosix(); |
| ... | @@ -162,7 +162,7 @@ pub const ChildProcess = struct { | ... | @@ -162,7 +162,7 @@ pub const ChildProcess = struct { |
| 162 | 162 | ||
| 163 | /// Blocks until child process terminates and then cleans up all resources. | 163 | /// Blocks until child process terminates and then cleans up all resources. |
| 164 | pub fn wait(self: *ChildProcess) !Term { | 164 | pub fn wait(self: *ChildProcess) !Term { |
| 165 | if (builtin.os == .windows) { | 165 | if (builtin.os.tag == .windows) { |
| 166 | return self.waitWindows(); | 166 | return self.waitWindows(); |
| 167 | } else { | 167 | } else { |
| 168 | return self.waitPosix(); | 168 | return self.waitPosix(); |
| ... | @@ -307,7 +307,7 @@ pub const ChildProcess = struct { | ... | @@ -307,7 +307,7 @@ pub const ChildProcess = struct { |
| 307 | fn cleanupAfterWait(self: *ChildProcess, status: u32) !Term { | 307 | fn cleanupAfterWait(self: *ChildProcess, status: u32) !Term { |
| 308 | defer destroyPipe(self.err_pipe); | 308 | defer destroyPipe(self.err_pipe); |
| 309 | 309 | ||
| 310 | if (builtin.os == .linux) { | 310 | if (builtin.os.tag == .linux) { |
| 311 | var fd = [1]std.os.pollfd{std.os.pollfd{ | 311 | var fd = [1]std.os.pollfd{std.os.pollfd{ |
| 312 | .fd = self.err_pipe[0], | 312 | .fd = self.err_pipe[0], |
| 313 | .events = std.os.POLLIN, | 313 | .events = std.os.POLLIN, |
| ... | @@ -402,7 +402,7 @@ pub const ChildProcess = struct { | ... | @@ -402,7 +402,7 @@ pub const ChildProcess = struct { |
| 402 | // This pipe is used to communicate errors between the time of fork | 402 | // This pipe is used to communicate errors between the time of fork |
| 403 | // and execve from the child process to the parent process. | 403 | // and execve from the child process to the parent process. |
| 404 | const err_pipe = blk: { | 404 | const err_pipe = blk: { |
| 405 | if (builtin.os == .linux) { | 405 | if (builtin.os.tag == .linux) { |
| 406 | const fd = try os.eventfd(0, 0); | 406 | const fd = try os.eventfd(0, 0); |
| 407 | // There's no distinction between the readable and the writeable | 407 | // There's no distinction between the readable and the writeable |
| 408 | // end with eventfd | 408 | // end with eventfd |
lib/std/cstr.zig+2-2| ... | @@ -4,8 +4,8 @@ const debug = std.debug; | ... | @@ -4,8 +4,8 @@ const debug = std.debug; |
| 4 | const mem = std.mem; | 4 | const mem = std.mem; |
| 5 | const testing = std.testing; | 5 | const testing = std.testing; |
| 6 | 6 | ||
| 7 | pub const line_sep = switch (builtin.os) { | 7 | pub const line_sep = switch (builtin.os.tag) { |
| 8 | builtin.Os.windows => "\r\n", | 8 | .windows => "\r\n", |
| 9 | else => "\n", | 9 | else => "\n", |
| 10 | }; | 10 | }; |
| 11 | 11 |
lib/std/debug.zig+12-12| ... | @@ -1,4 +1,5 @@ | ... | @@ -1,4 +1,5 @@ |
| 1 | const std = @import("std.zig"); | 1 | const std = @import("std.zig"); |
| 2 | const builtin = std.builtin; | ||
| 2 | const math = std.math; | 3 | const math = std.math; |
| 3 | const mem = std.mem; | 4 | const mem = std.mem; |
| 4 | const io = std.io; | 5 | const io = std.io; |
| ... | @@ -11,7 +12,6 @@ const macho = std.macho; | ... | @@ -11,7 +12,6 @@ const macho = std.macho; |
| 11 | const coff = std.coff; | 12 | const coff = std.coff; |
| 12 | const pdb = std.pdb; | 13 | const pdb = std.pdb; |
| 13 | const ArrayList = std.ArrayList; | 14 | const ArrayList = std.ArrayList; |
| 14 | const builtin = @import("builtin"); | ||
| 15 | const root = @import("root"); | 15 | const root = @import("root"); |
| 16 | const maxInt = std.math.maxInt; | 16 | const maxInt = std.math.maxInt; |
| 17 | const File = std.fs.File; | 17 | const File = std.fs.File; |
| ... | @@ -101,7 +101,7 @@ pub fn detectTTYConfig() TTY.Config { | ... | @@ -101,7 +101,7 @@ pub fn detectTTYConfig() TTY.Config { |
| 101 | } else |_| { | 101 | } else |_| { |
| 102 | if (stderr_file.supportsAnsiEscapeCodes()) { | 102 | if (stderr_file.supportsAnsiEscapeCodes()) { |
| 103 | return .escape_codes; | 103 | return .escape_codes; |
| 104 | } else if (builtin.os == .windows and stderr_file.isTty()) { | 104 | } else if (builtin.os.tag == .windows and stderr_file.isTty()) { |
| 105 | return .windows_api; | 105 | return .windows_api; |
| 106 | } else { | 106 | } else { |
| 107 | return .no_color; | 107 | return .no_color; |
| ... | @@ -155,7 +155,7 @@ pub fn dumpStackTraceFromBase(bp: usize, ip: usize) void { | ... | @@ -155,7 +155,7 @@ pub fn dumpStackTraceFromBase(bp: usize, ip: usize) void { |
| 155 | /// chopping off the irrelevant frames and shifting so that the returned addresses pointer | 155 | /// chopping off the irrelevant frames and shifting so that the returned addresses pointer |
| 156 | /// equals the passed in addresses pointer. | 156 | /// equals the passed in addresses pointer. |
| 157 | pub fn captureStackTrace(first_address: ?usize, stack_trace: *builtin.StackTrace) void { | 157 | pub fn captureStackTrace(first_address: ?usize, stack_trace: *builtin.StackTrace) void { |
| 158 | if (builtin.os == .windows) { | 158 | if (builtin.os.tag == .windows) { |
| 159 | const addrs = stack_trace.instruction_addresses; | 159 | const addrs = stack_trace.instruction_addresses; |
| 160 | const u32_addrs_len = @intCast(u32, addrs.len); | 160 | const u32_addrs_len = @intCast(u32, addrs.len); |
| 161 | const first_addr = first_address orelse { | 161 | const first_addr = first_address orelse { |
| ... | @@ -231,7 +231,7 @@ pub fn assert(ok: bool) void { | ... | @@ -231,7 +231,7 @@ pub fn assert(ok: bool) void { |
| 231 | pub fn panic(comptime format: []const u8, args: var) noreturn { | 231 | pub fn panic(comptime format: []const u8, args: var) noreturn { |
| 232 | @setCold(true); | 232 | @setCold(true); |
| 233 | // TODO: remove conditional once wasi / LLVM defines __builtin_return_address | 233 | // TODO: remove conditional once wasi / LLVM defines __builtin_return_address |
| 234 | const first_trace_addr = if (builtin.os == .wasi) null else @returnAddress(); | 234 | const first_trace_addr = if (builtin.os.tag == .wasi) null else @returnAddress(); |
| 235 | panicExtra(null, first_trace_addr, format, args); | 235 | panicExtra(null, first_trace_addr, format, args); |
| 236 | } | 236 | } |
| 237 | 237 | ||
| ... | @@ -361,7 +361,7 @@ pub fn writeCurrentStackTrace( | ... | @@ -361,7 +361,7 @@ pub fn writeCurrentStackTrace( |
| 361 | tty_config: TTY.Config, | 361 | tty_config: TTY.Config, |
| 362 | start_addr: ?usize, | 362 | start_addr: ?usize, |
| 363 | ) !void { | 363 | ) !void { |
| 364 | if (builtin.os == .windows) { | 364 | if (builtin.os.tag == .windows) { |
| 365 | return writeCurrentStackTraceWindows(out_stream, debug_info, tty_config, start_addr); | 365 | return writeCurrentStackTraceWindows(out_stream, debug_info, tty_config, start_addr); |
| 366 | } | 366 | } |
| 367 | var it = StackIterator.init(start_addr, null); | 367 | var it = StackIterator.init(start_addr, null); |
| ... | @@ -418,7 +418,7 @@ pub const TTY = struct { | ... | @@ -418,7 +418,7 @@ pub const TTY = struct { |
| 418 | .Dim => noasync out_stream.write(DIM) catch return, | 418 | .Dim => noasync out_stream.write(DIM) catch return, |
| 419 | .Reset => noasync out_stream.write(RESET) catch return, | 419 | .Reset => noasync out_stream.write(RESET) catch return, |
| 420 | }, | 420 | }, |
| 421 | .windows_api => if (builtin.os == .windows) { | 421 | .windows_api => if (builtin.os.tag == .windows) { |
| 422 | const S = struct { | 422 | const S = struct { |
| 423 | var attrs: windows.WORD = undefined; | 423 | var attrs: windows.WORD = undefined; |
| 424 | var init_attrs = false; | 424 | var init_attrs = false; |
| ... | @@ -617,7 +617,7 @@ pub fn openSelfDebugInfo(allocator: *mem.Allocator) anyerror!DebugInfo { | ... | @@ -617,7 +617,7 @@ pub fn openSelfDebugInfo(allocator: *mem.Allocator) anyerror!DebugInfo { |
| 617 | if (@hasDecl(root, "os") and @hasDecl(root.os, "debug") and @hasDecl(root.os.debug, "openSelfDebugInfo")) { | 617 | if (@hasDecl(root, "os") and @hasDecl(root.os, "debug") and @hasDecl(root.os.debug, "openSelfDebugInfo")) { |
| 618 | return noasync root.os.debug.openSelfDebugInfo(allocator); | 618 | return noasync root.os.debug.openSelfDebugInfo(allocator); |
| 619 | } | 619 | } |
| 620 | switch (builtin.os) { | 620 | switch (builtin.os.tag) { |
| 621 | .linux, | 621 | .linux, |
| 622 | .freebsd, | 622 | .freebsd, |
| 623 | .macosx, | 623 | .macosx, |
| ... | @@ -1019,7 +1019,7 @@ pub const DebugInfo = struct { | ... | @@ -1019,7 +1019,7 @@ pub const DebugInfo = struct { |
| 1019 | pub fn getModuleForAddress(self: *DebugInfo, address: usize) !*ModuleDebugInfo { | 1019 | pub fn getModuleForAddress(self: *DebugInfo, address: usize) !*ModuleDebugInfo { |
| 1020 | if (comptime std.Target.current.isDarwin()) | 1020 | if (comptime std.Target.current.isDarwin()) |
| 1021 | return self.lookupModuleDyld(address) | 1021 | return self.lookupModuleDyld(address) |
| 1022 | else if (builtin.os == .windows) | 1022 | else if (builtin.os.tag == .windows) |
| 1023 | return self.lookupModuleWin32(address) | 1023 | return self.lookupModuleWin32(address) |
| 1024 | else | 1024 | else |
| 1025 | return self.lookupModuleDl(address); | 1025 | return self.lookupModuleDl(address); |
| ... | @@ -1242,7 +1242,7 @@ const SymbolInfo = struct { | ... | @@ -1242,7 +1242,7 @@ const SymbolInfo = struct { |
| 1242 | } | 1242 | } |
| 1243 | }; | 1243 | }; |
| 1244 | 1244 | ||
| 1245 | pub const ModuleDebugInfo = switch (builtin.os) { | 1245 | pub const ModuleDebugInfo = switch (builtin.os.tag) { |
| 1246 | .macosx, .ios, .watchos, .tvos => struct { | 1246 | .macosx, .ios, .watchos, .tvos => struct { |
| 1247 | base_address: usize, | 1247 | base_address: usize, |
| 1248 | mapped_memory: []const u8, | 1248 | mapped_memory: []const u8, |
| ... | @@ -1602,7 +1602,7 @@ fn getDebugInfoAllocator() *mem.Allocator { | ... | @@ -1602,7 +1602,7 @@ fn getDebugInfoAllocator() *mem.Allocator { |
| 1602 | } | 1602 | } |
| 1603 | 1603 | ||
| 1604 | /// Whether or not the current target can print useful debug information when a segfault occurs. | 1604 | /// Whether or not the current target can print useful debug information when a segfault occurs. |
| 1605 | pub const have_segfault_handling_support = builtin.os == .linux or builtin.os == .windows; | 1605 | pub const have_segfault_handling_support = builtin.os.tag == .linux or builtin.os.tag == .windows; |
| 1606 | pub const enable_segfault_handler: bool = if (@hasDecl(root, "enable_segfault_handler")) | 1606 | pub const enable_segfault_handler: bool = if (@hasDecl(root, "enable_segfault_handler")) |
| 1607 | root.enable_segfault_handler | 1607 | root.enable_segfault_handler |
| 1608 | else | 1608 | else |
| ... | @@ -1621,7 +1621,7 @@ pub fn attachSegfaultHandler() void { | ... | @@ -1621,7 +1621,7 @@ pub fn attachSegfaultHandler() void { |
| 1621 | if (!have_segfault_handling_support) { | 1621 | if (!have_segfault_handling_support) { |
| 1622 | @compileError("segfault handler not supported for this target"); | 1622 | @compileError("segfault handler not supported for this target"); |
| 1623 | } | 1623 | } |
| 1624 | if (builtin.os == .windows) { | 1624 | if (builtin.os.tag == .windows) { |
| 1625 | windows_segfault_handle = windows.kernel32.AddVectoredExceptionHandler(0, handleSegfaultWindows); | 1625 | windows_segfault_handle = windows.kernel32.AddVectoredExceptionHandler(0, handleSegfaultWindows); |
| 1626 | return; | 1626 | return; |
| 1627 | } | 1627 | } |
| ... | @@ -1637,7 +1637,7 @@ pub fn attachSegfaultHandler() void { | ... | @@ -1637,7 +1637,7 @@ pub fn attachSegfaultHandler() void { |
| 1637 | } | 1637 | } |
| 1638 | 1638 | ||
| 1639 | fn resetSegfaultHandler() void { | 1639 | fn resetSegfaultHandler() void { |
| 1640 | if (builtin.os == .windows) { | 1640 | if (builtin.os.tag == .windows) { |
| 1641 | if (windows_segfault_handle) |handle| { | 1641 | if (windows_segfault_handle) |handle| { |
| 1642 | assert(windows.kernel32.RemoveVectoredExceptionHandler(handle) != 0); | 1642 | assert(windows.kernel32.RemoveVectoredExceptionHandler(handle) != 0); |
| 1643 | windows_segfault_handle = null; | 1643 | windows_segfault_handle = null; |
lib/std/dynamic_library.zig+4-4| ... | @@ -11,7 +11,7 @@ const system = std.os.system; | ... | @@ -11,7 +11,7 @@ const system = std.os.system; |
| 11 | const maxInt = std.math.maxInt; | 11 | const maxInt = std.math.maxInt; |
| 12 | const max = std.math.max; | 12 | const max = std.math.max; |
| 13 | 13 | ||
| 14 | pub const DynLib = switch (builtin.os) { | 14 | pub const DynLib = switch (builtin.os.tag) { |
| 15 | .linux => if (builtin.link_libc) DlDynlib else ElfDynLib, | 15 | .linux => if (builtin.link_libc) DlDynlib else ElfDynLib, |
| 16 | .windows => WindowsDynLib, | 16 | .windows => WindowsDynLib, |
| 17 | .macosx, .tvos, .watchos, .ios, .freebsd => DlDynlib, | 17 | .macosx, .tvos, .watchos, .ios, .freebsd => DlDynlib, |
| ... | @@ -82,12 +82,12 @@ pub fn linkmap_iterator(phdrs: []elf.Phdr) !LinkMap.Iterator { | ... | @@ -82,12 +82,12 @@ pub fn linkmap_iterator(phdrs: []elf.Phdr) !LinkMap.Iterator { |
| 82 | for (dyn_table) |*dyn| { | 82 | for (dyn_table) |*dyn| { |
| 83 | switch (dyn.d_tag) { | 83 | switch (dyn.d_tag) { |
| 84 | elf.DT_DEBUG => { | 84 | elf.DT_DEBUG => { |
| 85 | const r_debug = @intToPtr(*RDebug, dyn.d_un.d_ptr); | 85 | const r_debug = @intToPtr(*RDebug, dyn.d_val); |
| 86 | if (r_debug.r_version != 1) return error.InvalidExe; | 86 | if (r_debug.r_version != 1) return error.InvalidExe; |
| 87 | break :init r_debug.r_map; | 87 | break :init r_debug.r_map; |
| 88 | }, | 88 | }, |
| 89 | elf.DT_PLTGOT => { | 89 | elf.DT_PLTGOT => { |
| 90 | const got_table = @intToPtr([*]usize, dyn.d_un.d_ptr); | 90 | const got_table = @intToPtr([*]usize, dyn.d_val); |
| 91 | // The address to the link_map structure is stored in the | 91 | // The address to the link_map structure is stored in the |
| 92 | // second slot | 92 | // second slot |
| 93 | break :init @intToPtr(?*LinkMap, got_table[1]); | 93 | break :init @intToPtr(?*LinkMap, got_table[1]); |
| ... | @@ -390,7 +390,7 @@ pub const DlDynlib = struct { | ... | @@ -390,7 +390,7 @@ pub const DlDynlib = struct { |
| 390 | }; | 390 | }; |
| 391 | 391 | ||
| 392 | test "dynamic_library" { | 392 | test "dynamic_library" { |
| 393 | const libname = switch (builtin.os) { | 393 | const libname = switch (builtin.os.tag) { |
| 394 | .linux, .freebsd => "invalid_so.so", | 394 | .linux, .freebsd => "invalid_so.so", |
| 395 | .windows => "invalid_dll.dll", | 395 | .windows => "invalid_dll.dll", |
| 396 | .macosx, .tvos, .watchos, .ios => "invalid_dylib.dylib", | 396 | .macosx, .tvos, .watchos, .ios => "invalid_dylib.dylib", |
lib/std/elf.zig+17-18| ... | @@ -349,16 +349,6 @@ pub const Elf = struct { | ... | @@ -349,16 +349,6 @@ pub const Elf = struct { |
| 349 | program_headers: []ProgramHeader, | 349 | program_headers: []ProgramHeader, |
| 350 | allocator: *mem.Allocator, | 350 | allocator: *mem.Allocator, |
| 351 | 351 | ||
| 352 | /// Call close when done. | ||
| 353 | pub fn openPath(allocator: *mem.Allocator, path: []const u8) !Elf { | ||
| 354 | @compileError("TODO implement"); | ||
| 355 | } | ||
| 356 | |||
| 357 | /// Call close when done. | ||
| 358 | pub fn openFile(allocator: *mem.Allocator, file: File) !Elf { | ||
| 359 | @compileError("TODO implement"); | ||
| 360 | } | ||
| 361 | |||
| 362 | pub fn openStream( | 352 | pub fn openStream( |
| 363 | allocator: *mem.Allocator, | 353 | allocator: *mem.Allocator, |
| 364 | seekable_stream: *io.SeekableStream(anyerror, anyerror), | 354 | seekable_stream: *io.SeekableStream(anyerror, anyerror), |
| ... | @@ -554,6 +544,21 @@ pub const Elf = struct { | ... | @@ -554,6 +544,21 @@ pub const Elf = struct { |
| 554 | }; | 544 | }; |
| 555 | 545 | ||
| 556 | pub const EI_NIDENT = 16; | 546 | pub const EI_NIDENT = 16; |
| 547 | |||
| 548 | pub const EI_CLASS = 4; | ||
| 549 | pub const ELFCLASSNONE = 0; | ||
| 550 | pub const ELFCLASS32 = 1; | ||
| 551 | pub const ELFCLASS64 = 2; | ||
| 552 | pub const ELFCLASSNUM = 3; | ||
| 553 | |||
| 554 | pub const EI_DATA = 5; | ||
| 555 | pub const ELFDATANONE = 0; | ||
| 556 | pub const ELFDATA2LSB = 1; | ||
| 557 | pub const ELFDATA2MSB = 2; | ||
| 558 | pub const ELFDATANUM = 3; | ||
| 559 | |||
| 560 | pub const EI_VERSION = 6; | ||
| 561 | |||
| 557 | pub const Elf32_Half = u16; | 562 | pub const Elf32_Half = u16; |
| 558 | pub const Elf64_Half = u16; | 563 | pub const Elf64_Half = u16; |
| 559 | pub const Elf32_Word = u32; | 564 | pub const Elf32_Word = u32; |
| ... | @@ -703,17 +708,11 @@ pub const Elf64_Rela = extern struct { | ... | @@ -703,17 +708,11 @@ pub const Elf64_Rela = extern struct { |
| 703 | }; | 708 | }; |
| 704 | pub const Elf32_Dyn = extern struct { | 709 | pub const Elf32_Dyn = extern struct { |
| 705 | d_tag: Elf32_Sword, | 710 | d_tag: Elf32_Sword, |
| 706 | d_un: extern union { | 711 | d_val: Elf32_Addr, |
| 707 | d_val: Elf32_Word, | ||
| 708 | d_ptr: Elf32_Addr, | ||
| 709 | }, | ||
| 710 | }; | 712 | }; |
| 711 | pub const Elf64_Dyn = extern struct { | 713 | pub const Elf64_Dyn = extern struct { |
| 712 | d_tag: Elf64_Sxword, | 714 | d_tag: Elf64_Sxword, |
| 713 | d_un: extern union { | 715 | d_val: Elf64_Addr, |
| 714 | d_val: Elf64_Xword, | ||
| 715 | d_ptr: Elf64_Addr, | ||
| 716 | }, | ||
| 717 | }; | 716 | }; |
| 718 | pub const Elf32_Verdef = extern struct { | 717 | pub const Elf32_Verdef = extern struct { |
| 719 | vd_version: Elf32_Half, | 718 | vd_version: Elf32_Half, |
lib/std/event/channel.zig+1-1| ... | @@ -273,7 +273,7 @@ test "std.event.Channel" { | ... | @@ -273,7 +273,7 @@ test "std.event.Channel" { |
| 273 | if (builtin.single_threaded) return error.SkipZigTest; | 273 | if (builtin.single_threaded) return error.SkipZigTest; |
| 274 | 274 | ||
| 275 | // https://github.com/ziglang/zig/issues/3251 | 275 | // https://github.com/ziglang/zig/issues/3251 |
| 276 | if (builtin.os == .freebsd) return error.SkipZigTest; | 276 | if (builtin.os.tag == .freebsd) return error.SkipZigTest; |
| 277 | 277 | ||
| 278 | var channel: Channel(i32) = undefined; | 278 | var channel: Channel(i32) = undefined; |
| 279 | channel.init(&[0]i32{}); | 279 | channel.init(&[0]i32{}); |
lib/std/event/future.zig+1-1| ... | @@ -86,7 +86,7 @@ test "std.event.Future" { | ... | @@ -86,7 +86,7 @@ test "std.event.Future" { |
| 86 | // https://github.com/ziglang/zig/issues/1908 | 86 | // https://github.com/ziglang/zig/issues/1908 |
| 87 | if (builtin.single_threaded) return error.SkipZigTest; | 87 | if (builtin.single_threaded) return error.SkipZigTest; |
| 88 | // https://github.com/ziglang/zig/issues/3251 | 88 | // https://github.com/ziglang/zig/issues/3251 |
| 89 | if (builtin.os == .freebsd) return error.SkipZigTest; | 89 | if (builtin.os.tag == .freebsd) return error.SkipZigTest; |
| 90 | // TODO provide a way to run tests in evented I/O mode | 90 | // TODO provide a way to run tests in evented I/O mode |
| 91 | if (!std.io.is_async) return error.SkipZigTest; | 91 | if (!std.io.is_async) return error.SkipZigTest; |
| 92 | 92 |
lib/std/event/lock.zig+1-1| ... | @@ -123,7 +123,7 @@ test "std.event.Lock" { | ... | @@ -123,7 +123,7 @@ test "std.event.Lock" { |
| 123 | if (builtin.single_threaded) return error.SkipZigTest; | 123 | if (builtin.single_threaded) return error.SkipZigTest; |
| 124 | 124 | ||
| 125 | // TODO https://github.com/ziglang/zig/issues/3251 | 125 | // TODO https://github.com/ziglang/zig/issues/3251 |
| 126 | if (builtin.os == .freebsd) return error.SkipZigTest; | 126 | if (builtin.os.tag == .freebsd) return error.SkipZigTest; |
| 127 | 127 | ||
| 128 | var lock = Lock.init(); | 128 | var lock = Lock.init(); |
| 129 | defer lock.deinit(); | 129 | defer lock.deinit(); |
lib/std/event/loop.zig+13-13| ... | @@ -34,7 +34,7 @@ pub const Loop = struct { | ... | @@ -34,7 +34,7 @@ pub const Loop = struct { |
| 34 | handle: anyframe, | 34 | handle: anyframe, |
| 35 | overlapped: Overlapped, | 35 | overlapped: Overlapped, |
| 36 | 36 | ||
| 37 | pub const overlapped_init = switch (builtin.os) { | 37 | pub const overlapped_init = switch (builtin.os.tag) { |
| 38 | .windows => windows.OVERLAPPED{ | 38 | .windows => windows.OVERLAPPED{ |
| 39 | .Internal = 0, | 39 | .Internal = 0, |
| 40 | .InternalHigh = 0, | 40 | .InternalHigh = 0, |
| ... | @@ -52,7 +52,7 @@ pub const Loop = struct { | ... | @@ -52,7 +52,7 @@ pub const Loop = struct { |
| 52 | EventFd, | 52 | EventFd, |
| 53 | }; | 53 | }; |
| 54 | 54 | ||
| 55 | pub const EventFd = switch (builtin.os) { | 55 | pub const EventFd = switch (builtin.os.tag) { |
| 56 | .macosx, .freebsd, .netbsd, .dragonfly => KEventFd, | 56 | .macosx, .freebsd, .netbsd, .dragonfly => KEventFd, |
| 57 | .linux => struct { | 57 | .linux => struct { |
| 58 | base: ResumeNode, | 58 | base: ResumeNode, |
| ... | @@ -71,7 +71,7 @@ pub const Loop = struct { | ... | @@ -71,7 +71,7 @@ pub const Loop = struct { |
| 71 | kevent: os.Kevent, | 71 | kevent: os.Kevent, |
| 72 | }; | 72 | }; |
| 73 | 73 | ||
| 74 | pub const Basic = switch (builtin.os) { | 74 | pub const Basic = switch (builtin.os.tag) { |
| 75 | .macosx, .freebsd, .netbsd, .dragonfly => KEventBasic, | 75 | .macosx, .freebsd, .netbsd, .dragonfly => KEventBasic, |
| 76 | .linux => struct { | 76 | .linux => struct { |
| 77 | base: ResumeNode, | 77 | base: ResumeNode, |
| ... | @@ -173,7 +173,7 @@ pub const Loop = struct { | ... | @@ -173,7 +173,7 @@ pub const Loop = struct { |
| 173 | const wakeup_bytes = [_]u8{0x1} ** 8; | 173 | const wakeup_bytes = [_]u8{0x1} ** 8; |
| 174 | 174 | ||
| 175 | fn initOsData(self: *Loop, extra_thread_count: usize) InitOsDataError!void { | 175 | fn initOsData(self: *Loop, extra_thread_count: usize) InitOsDataError!void { |
| 176 | switch (builtin.os) { | 176 | switch (builtin.os.tag) { |
| 177 | .linux => { | 177 | .linux => { |
| 178 | self.os_data.fs_queue = std.atomic.Queue(Request).init(); | 178 | self.os_data.fs_queue = std.atomic.Queue(Request).init(); |
| 179 | self.os_data.fs_queue_item = 0; | 179 | self.os_data.fs_queue_item = 0; |
| ... | @@ -404,7 +404,7 @@ pub const Loop = struct { | ... | @@ -404,7 +404,7 @@ pub const Loop = struct { |
| 404 | } | 404 | } |
| 405 | 405 | ||
| 406 | fn deinitOsData(self: *Loop) void { | 406 | fn deinitOsData(self: *Loop) void { |
| 407 | switch (builtin.os) { | 407 | switch (builtin.os.tag) { |
| 408 | .linux => { | 408 | .linux => { |
| 409 | noasync os.close(self.os_data.final_eventfd); | 409 | noasync os.close(self.os_data.final_eventfd); |
| 410 | while (self.available_eventfd_resume_nodes.pop()) |node| noasync os.close(node.data.eventfd); | 410 | while (self.available_eventfd_resume_nodes.pop()) |node| noasync os.close(node.data.eventfd); |
| ... | @@ -568,7 +568,7 @@ pub const Loop = struct { | ... | @@ -568,7 +568,7 @@ pub const Loop = struct { |
| 568 | }; | 568 | }; |
| 569 | const eventfd_node = &resume_stack_node.data; | 569 | const eventfd_node = &resume_stack_node.data; |
| 570 | eventfd_node.base.handle = next_tick_node.data; | 570 | eventfd_node.base.handle = next_tick_node.data; |
| 571 | switch (builtin.os) { | 571 | switch (builtin.os.tag) { |
| 572 | .macosx, .freebsd, .netbsd, .dragonfly => { | 572 | .macosx, .freebsd, .netbsd, .dragonfly => { |
| 573 | const kevent_array = @as(*const [1]os.Kevent, &eventfd_node.kevent); | 573 | const kevent_array = @as(*const [1]os.Kevent, &eventfd_node.kevent); |
| 574 | const empty_kevs = &[0]os.Kevent{}; | 574 | const empty_kevs = &[0]os.Kevent{}; |
| ... | @@ -628,7 +628,7 @@ pub const Loop = struct { | ... | @@ -628,7 +628,7 @@ pub const Loop = struct { |
| 628 | 628 | ||
| 629 | self.workerRun(); | 629 | self.workerRun(); |
| 630 | 630 | ||
| 631 | switch (builtin.os) { | 631 | switch (builtin.os.tag) { |
| 632 | .linux, | 632 | .linux, |
| 633 | .macosx, | 633 | .macosx, |
| 634 | .freebsd, | 634 | .freebsd, |
| ... | @@ -678,7 +678,7 @@ pub const Loop = struct { | ... | @@ -678,7 +678,7 @@ pub const Loop = struct { |
| 678 | const prev = @atomicRmw(usize, &self.pending_event_count, AtomicRmwOp.Sub, 1, AtomicOrder.SeqCst); | 678 | const prev = @atomicRmw(usize, &self.pending_event_count, AtomicRmwOp.Sub, 1, AtomicOrder.SeqCst); |
| 679 | if (prev == 1) { | 679 | if (prev == 1) { |
| 680 | // cause all the threads to stop | 680 | // cause all the threads to stop |
| 681 | switch (builtin.os) { | 681 | switch (builtin.os.tag) { |
| 682 | .linux => { | 682 | .linux => { |
| 683 | self.posixFsRequest(&self.os_data.fs_end_request); | 683 | self.posixFsRequest(&self.os_data.fs_end_request); |
| 684 | // writing 8 bytes to an eventfd cannot fail | 684 | // writing 8 bytes to an eventfd cannot fail |
| ... | @@ -902,7 +902,7 @@ pub const Loop = struct { | ... | @@ -902,7 +902,7 @@ pub const Loop = struct { |
| 902 | self.finishOneEvent(); | 902 | self.finishOneEvent(); |
| 903 | } | 903 | } |
| 904 | 904 | ||
| 905 | switch (builtin.os) { | 905 | switch (builtin.os.tag) { |
| 906 | .linux => { | 906 | .linux => { |
| 907 | // only process 1 event so we don't steal from other threads | 907 | // only process 1 event so we don't steal from other threads |
| 908 | var events: [1]os.linux.epoll_event = undefined; | 908 | var events: [1]os.linux.epoll_event = undefined; |
| ... | @@ -989,7 +989,7 @@ pub const Loop = struct { | ... | @@ -989,7 +989,7 @@ pub const Loop = struct { |
| 989 | fn posixFsRequest(self: *Loop, request_node: *Request.Node) void { | 989 | fn posixFsRequest(self: *Loop, request_node: *Request.Node) void { |
| 990 | self.beginOneEvent(); // finished in posixFsRun after processing the msg | 990 | self.beginOneEvent(); // finished in posixFsRun after processing the msg |
| 991 | self.os_data.fs_queue.put(request_node); | 991 | self.os_data.fs_queue.put(request_node); |
| 992 | switch (builtin.os) { | 992 | switch (builtin.os.tag) { |
| 993 | .macosx, .freebsd, .netbsd, .dragonfly => { | 993 | .macosx, .freebsd, .netbsd, .dragonfly => { |
| 994 | const fs_kevs = @as(*const [1]os.Kevent, &self.os_data.fs_kevent_wake); | 994 | const fs_kevs = @as(*const [1]os.Kevent, &self.os_data.fs_kevent_wake); |
| 995 | const empty_kevs = &[0]os.Kevent{}; | 995 | const empty_kevs = &[0]os.Kevent{}; |
| ... | @@ -1018,7 +1018,7 @@ pub const Loop = struct { | ... | @@ -1018,7 +1018,7 @@ pub const Loop = struct { |
| 1018 | // https://github.com/ziglang/zig/issues/3157 | 1018 | // https://github.com/ziglang/zig/issues/3157 |
| 1019 | fn posixFsRun(self: *Loop) void { | 1019 | fn posixFsRun(self: *Loop) void { |
| 1020 | while (true) { | 1020 | while (true) { |
| 1021 | if (builtin.os == .linux) { | 1021 | if (builtin.os.tag == .linux) { |
| 1022 | @atomicStore(i32, &self.os_data.fs_queue_item, 0, .SeqCst); | 1022 | @atomicStore(i32, &self.os_data.fs_queue_item, 0, .SeqCst); |
| 1023 | } | 1023 | } |
| 1024 | while (self.os_data.fs_queue.get()) |node| { | 1024 | while (self.os_data.fs_queue.get()) |node| { |
| ... | @@ -1053,7 +1053,7 @@ pub const Loop = struct { | ... | @@ -1053,7 +1053,7 @@ pub const Loop = struct { |
| 1053 | } | 1053 | } |
| 1054 | self.finishOneEvent(); | 1054 | self.finishOneEvent(); |
| 1055 | } | 1055 | } |
| 1056 | switch (builtin.os) { | 1056 | switch (builtin.os.tag) { |
| 1057 | .linux => { | 1057 | .linux => { |
| 1058 | const rc = os.linux.futex_wait(&self.os_data.fs_queue_item, os.linux.FUTEX_WAIT, 0, null); | 1058 | const rc = os.linux.futex_wait(&self.os_data.fs_queue_item, os.linux.FUTEX_WAIT, 0, null); |
| 1059 | switch (os.linux.getErrno(rc)) { | 1059 | switch (os.linux.getErrno(rc)) { |
| ... | @@ -1071,7 +1071,7 @@ pub const Loop = struct { | ... | @@ -1071,7 +1071,7 @@ pub const Loop = struct { |
| 1071 | } | 1071 | } |
| 1072 | } | 1072 | } |
| 1073 | 1073 | ||
| 1074 | const OsData = switch (builtin.os) { | 1074 | const OsData = switch (builtin.os.tag) { |
| 1075 | .linux => LinuxOsData, | 1075 | .linux => LinuxOsData, |
| 1076 | .macosx, .freebsd, .netbsd, .dragonfly => KEventData, | 1076 | .macosx, .freebsd, .netbsd, .dragonfly => KEventData, |
| 1077 | .windows => struct { | 1077 | .windows => struct { |
lib/std/fmt/parse_float.zig+1-1| ... | @@ -382,7 +382,7 @@ pub fn parseFloat(comptime T: type, s: []const u8) !T { | ... | @@ -382,7 +382,7 @@ pub fn parseFloat(comptime T: type, s: []const u8) !T { |
| 382 | } | 382 | } |
| 383 | 383 | ||
| 384 | test "fmt.parseFloat" { | 384 | test "fmt.parseFloat" { |
| 385 | if (std.Target.current.isWindows()) { | 385 | if (std.Target.current.os.tag == .windows) { |
| 386 | // TODO https://github.com/ziglang/zig/issues/508 | 386 | // TODO https://github.com/ziglang/zig/issues/508 |
| 387 | return error.SkipZigTest; | 387 | return error.SkipZigTest; |
| 388 | } | 388 | } |
lib/std/fs.zig+23-23| ... | @@ -29,7 +29,7 @@ pub const Watch = @import("fs/watch.zig").Watch; | ... | @@ -29,7 +29,7 @@ pub const Watch = @import("fs/watch.zig").Watch; |
| 29 | /// All file system operations which return a path are guaranteed to | 29 | /// All file system operations which return a path are guaranteed to |
| 30 | /// fit into a UTF-8 encoded array of this length. | 30 | /// fit into a UTF-8 encoded array of this length. |
| 31 | /// The byte count includes room for a null sentinel byte. | 31 | /// The byte count includes room for a null sentinel byte. |
| 32 | pub const MAX_PATH_BYTES = switch (builtin.os) { | 32 | pub const MAX_PATH_BYTES = switch (builtin.os.tag) { |
| 33 | .linux, .macosx, .ios, .freebsd, .netbsd, .dragonfly => os.PATH_MAX, | 33 | .linux, .macosx, .ios, .freebsd, .netbsd, .dragonfly => os.PATH_MAX, |
| 34 | // Each UTF-16LE character may be expanded to 3 UTF-8 bytes. | 34 | // Each UTF-16LE character may be expanded to 3 UTF-8 bytes. |
| 35 | // If it would require 4 UTF-8 bytes, then there would be a surrogate | 35 | // If it would require 4 UTF-8 bytes, then there would be a surrogate |
| ... | @@ -47,7 +47,7 @@ pub const base64_encoder = base64.Base64Encoder.init( | ... | @@ -47,7 +47,7 @@ pub const base64_encoder = base64.Base64Encoder.init( |
| 47 | 47 | ||
| 48 | /// Whether or not async file system syscalls need a dedicated thread because the operating | 48 | /// Whether or not async file system syscalls need a dedicated thread because the operating |
| 49 | /// system does not support non-blocking I/O on the file system. | 49 | /// system does not support non-blocking I/O on the file system. |
| 50 | pub const need_async_thread = std.io.is_async and switch (builtin.os) { | 50 | pub const need_async_thread = std.io.is_async and switch (builtin.os.tag) { |
| 51 | .windows, .other => false, | 51 | .windows, .other => false, |
| 52 | else => true, | 52 | else => true, |
| 53 | }; | 53 | }; |
| ... | @@ -270,7 +270,7 @@ pub const AtomicFile = struct { | ... | @@ -270,7 +270,7 @@ pub const AtomicFile = struct { |
| 270 | assert(!self.finished); | 270 | assert(!self.finished); |
| 271 | self.file.close(); | 271 | self.file.close(); |
| 272 | self.finished = true; | 272 | self.finished = true; |
| 273 | if (builtin.os == .windows) { | 273 | if (builtin.os.tag == .windows) { |
| 274 | const dest_path_w = try os.windows.sliceToPrefixedFileW(self.dest_path); | 274 | const dest_path_w = try os.windows.sliceToPrefixedFileW(self.dest_path); |
| 275 | const tmp_path_w = try os.windows.cStrToPrefixedFileW(@ptrCast([*:0]u8, &self.tmp_path_buf)); | 275 | const tmp_path_w = try os.windows.cStrToPrefixedFileW(@ptrCast([*:0]u8, &self.tmp_path_buf)); |
| 276 | return os.renameW(&tmp_path_w, &dest_path_w); | 276 | return os.renameW(&tmp_path_w, &dest_path_w); |
| ... | @@ -394,7 +394,7 @@ pub const Dir = struct { | ... | @@ -394,7 +394,7 @@ pub const Dir = struct { |
| 394 | 394 | ||
| 395 | const IteratorError = error{AccessDenied} || os.UnexpectedError; | 395 | const IteratorError = error{AccessDenied} || os.UnexpectedError; |
| 396 | 396 | ||
| 397 | pub const Iterator = switch (builtin.os) { | 397 | pub const Iterator = switch (builtin.os.tag) { |
| 398 | .macosx, .ios, .freebsd, .netbsd, .dragonfly => struct { | 398 | .macosx, .ios, .freebsd, .netbsd, .dragonfly => struct { |
| 399 | dir: Dir, | 399 | dir: Dir, |
| 400 | seek: i64, | 400 | seek: i64, |
| ... | @@ -409,7 +409,7 @@ pub const Dir = struct { | ... | @@ -409,7 +409,7 @@ pub const Dir = struct { |
| 409 | /// Memory such as file names referenced in this returned entry becomes invalid | 409 | /// Memory such as file names referenced in this returned entry becomes invalid |
| 410 | /// with subsequent calls to `next`, as well as when this `Dir` is deinitialized. | 410 | /// with subsequent calls to `next`, as well as when this `Dir` is deinitialized. |
| 411 | pub fn next(self: *Self) Error!?Entry { | 411 | pub fn next(self: *Self) Error!?Entry { |
| 412 | switch (builtin.os) { | 412 | switch (builtin.os.tag) { |
| 413 | .macosx, .ios => return self.nextDarwin(), | 413 | .macosx, .ios => return self.nextDarwin(), |
| 414 | .freebsd, .netbsd, .dragonfly => return self.nextBsd(), | 414 | .freebsd, .netbsd, .dragonfly => return self.nextBsd(), |
| 415 | else => @compileError("unimplemented"), | 415 | else => @compileError("unimplemented"), |
| ... | @@ -644,7 +644,7 @@ pub const Dir = struct { | ... | @@ -644,7 +644,7 @@ pub const Dir = struct { |
| 644 | }; | 644 | }; |
| 645 | 645 | ||
| 646 | pub fn iterate(self: Dir) Iterator { | 646 | pub fn iterate(self: Dir) Iterator { |
| 647 | switch (builtin.os) { | 647 | switch (builtin.os.tag) { |
| 648 | .macosx, .ios, .freebsd, .netbsd, .dragonfly => return Iterator{ | 648 | .macosx, .ios, .freebsd, .netbsd, .dragonfly => return Iterator{ |
| 649 | .dir = self, | 649 | .dir = self, |
| 650 | .seek = 0, | 650 | .seek = 0, |
| ... | @@ -710,7 +710,7 @@ pub const Dir = struct { | ... | @@ -710,7 +710,7 @@ pub const Dir = struct { |
| 710 | /// Asserts that the path parameter has no null bytes. | 710 | /// Asserts that the path parameter has no null bytes. |
| 711 | pub fn openFile(self: Dir, sub_path: []const u8, flags: File.OpenFlags) File.OpenError!File { | 711 | pub fn openFile(self: Dir, sub_path: []const u8, flags: File.OpenFlags) File.OpenError!File { |
| 712 | if (std.debug.runtime_safety) for (sub_path) |byte| assert(byte != 0); | 712 | if (std.debug.runtime_safety) for (sub_path) |byte| assert(byte != 0); |
| 713 | if (builtin.os == .windows) { | 713 | if (builtin.os.tag == .windows) { |
| 714 | const path_w = try os.windows.sliceToPrefixedFileW(sub_path); | 714 | const path_w = try os.windows.sliceToPrefixedFileW(sub_path); |
| 715 | return self.openFileW(&path_w, flags); | 715 | return self.openFileW(&path_w, flags); |
| 716 | } | 716 | } |
| ... | @@ -720,7 +720,7 @@ pub const Dir = struct { | ... | @@ -720,7 +720,7 @@ pub const Dir = struct { |
| 720 | 720 | ||
| 721 | /// Same as `openFile` but the path parameter is null-terminated. | 721 | /// Same as `openFile` but the path parameter is null-terminated. |
| 722 | pub fn openFileC(self: Dir, sub_path: [*:0]const u8, flags: File.OpenFlags) File.OpenError!File { | 722 | pub fn openFileC(self: Dir, sub_path: [*:0]const u8, flags: File.OpenFlags) File.OpenError!File { |
| 723 | if (builtin.os == .windows) { | 723 | if (builtin.os.tag == .windows) { |
| 724 | const path_w = try os.windows.cStrToPrefixedFileW(sub_path); | 724 | const path_w = try os.windows.cStrToPrefixedFileW(sub_path); |
| 725 | return self.openFileW(&path_w, flags); | 725 | return self.openFileW(&path_w, flags); |
| 726 | } | 726 | } |
| ... | @@ -760,7 +760,7 @@ pub const Dir = struct { | ... | @@ -760,7 +760,7 @@ pub const Dir = struct { |
| 760 | /// Asserts that the path parameter has no null bytes. | 760 | /// Asserts that the path parameter has no null bytes. |
| 761 | pub fn createFile(self: Dir, sub_path: []const u8, flags: File.CreateFlags) File.OpenError!File { | 761 | pub fn createFile(self: Dir, sub_path: []const u8, flags: File.CreateFlags) File.OpenError!File { |
| 762 | if (std.debug.runtime_safety) for (sub_path) |byte| assert(byte != 0); | 762 | if (std.debug.runtime_safety) for (sub_path) |byte| assert(byte != 0); |
| 763 | if (builtin.os == .windows) { | 763 | if (builtin.os.tag == .windows) { |
| 764 | const path_w = try os.windows.sliceToPrefixedFileW(sub_path); | 764 | const path_w = try os.windows.sliceToPrefixedFileW(sub_path); |
| 765 | return self.createFileW(&path_w, flags); | 765 | return self.createFileW(&path_w, flags); |
| 766 | } | 766 | } |
| ... | @@ -770,7 +770,7 @@ pub const Dir = struct { | ... | @@ -770,7 +770,7 @@ pub const Dir = struct { |
| 770 | 770 | ||
| 771 | /// Same as `createFile` but the path parameter is null-terminated. | 771 | /// Same as `createFile` but the path parameter is null-terminated. |
| 772 | pub fn createFileC(self: Dir, sub_path_c: [*:0]const u8, flags: File.CreateFlags) File.OpenError!File { | 772 | pub fn createFileC(self: Dir, sub_path_c: [*:0]const u8, flags: File.CreateFlags) File.OpenError!File { |
| 773 | if (builtin.os == .windows) { | 773 | if (builtin.os.tag == .windows) { |
| 774 | const path_w = try os.windows.cStrToPrefixedFileW(sub_path_c); | 774 | const path_w = try os.windows.cStrToPrefixedFileW(sub_path_c); |
| 775 | return self.createFileW(&path_w, flags); | 775 | return self.createFileW(&path_w, flags); |
| 776 | } | 776 | } |
| ... | @@ -901,7 +901,7 @@ pub const Dir = struct { | ... | @@ -901,7 +901,7 @@ pub const Dir = struct { |
| 901 | /// Asserts that the path parameter has no null bytes. | 901 | /// Asserts that the path parameter has no null bytes. |
| 902 | pub fn openDirTraverse(self: Dir, sub_path: []const u8) OpenError!Dir { | 902 | pub fn openDirTraverse(self: Dir, sub_path: []const u8) OpenError!Dir { |
| 903 | if (std.debug.runtime_safety) for (sub_path) |byte| assert(byte != 0); | 903 | if (std.debug.runtime_safety) for (sub_path) |byte| assert(byte != 0); |
| 904 | if (builtin.os == .windows) { | 904 | if (builtin.os.tag == .windows) { |
| 905 | const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path); | 905 | const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path); |
| 906 | return self.openDirTraverseW(&sub_path_w); | 906 | return self.openDirTraverseW(&sub_path_w); |
| 907 | } | 907 | } |
| ... | @@ -919,7 +919,7 @@ pub const Dir = struct { | ... | @@ -919,7 +919,7 @@ pub const Dir = struct { |
| 919 | /// Asserts that the path parameter has no null bytes. | 919 | /// Asserts that the path parameter has no null bytes. |
| 920 | pub fn openDirList(self: Dir, sub_path: []const u8) OpenError!Dir { | 920 | pub fn openDirList(self: Dir, sub_path: []const u8) OpenError!Dir { |
| 921 | if (std.debug.runtime_safety) for (sub_path) |byte| assert(byte != 0); | 921 | if (std.debug.runtime_safety) for (sub_path) |byte| assert(byte != 0); |
| 922 | if (builtin.os == .windows) { | 922 | if (builtin.os.tag == .windows) { |
| 923 | const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path); | 923 | const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path); |
| 924 | return self.openDirListW(&sub_path_w); | 924 | return self.openDirListW(&sub_path_w); |
| 925 | } | 925 | } |
| ... | @@ -930,7 +930,7 @@ pub const Dir = struct { | ... | @@ -930,7 +930,7 @@ pub const Dir = struct { |
| 930 | 930 | ||
| 931 | /// Same as `openDirTraverse` except the parameter is null-terminated. | 931 | /// Same as `openDirTraverse` except the parameter is null-terminated. |
| 932 | pub fn openDirTraverseC(self: Dir, sub_path_c: [*:0]const u8) OpenError!Dir { | 932 | pub fn openDirTraverseC(self: Dir, sub_path_c: [*:0]const u8) OpenError!Dir { |
| 933 | if (builtin.os == .windows) { | 933 | if (builtin.os.tag == .windows) { |
| 934 | const sub_path_w = try os.windows.cStrToPrefixedFileW(sub_path_c); | 934 | const sub_path_w = try os.windows.cStrToPrefixedFileW(sub_path_c); |
| 935 | return self.openDirTraverseW(&sub_path_w); | 935 | return self.openDirTraverseW(&sub_path_w); |
| 936 | } else { | 936 | } else { |
| ... | @@ -941,7 +941,7 @@ pub const Dir = struct { | ... | @@ -941,7 +941,7 @@ pub const Dir = struct { |
| 941 | 941 | ||
| 942 | /// Same as `openDirList` except the parameter is null-terminated. | 942 | /// Same as `openDirList` except the parameter is null-terminated. |
| 943 | pub fn openDirListC(self: Dir, sub_path_c: [*:0]const u8) OpenError!Dir { | 943 | pub fn openDirListC(self: Dir, sub_path_c: [*:0]const u8) OpenError!Dir { |
| 944 | if (builtin.os == .windows) { | 944 | if (builtin.os.tag == .windows) { |
| 945 | const sub_path_w = try os.windows.cStrToPrefixedFileW(sub_path_c); | 945 | const sub_path_w = try os.windows.cStrToPrefixedFileW(sub_path_c); |
| 946 | return self.openDirListW(&sub_path_w); | 946 | return self.openDirListW(&sub_path_w); |
| 947 | } else { | 947 | } else { |
| ... | @@ -1083,7 +1083,7 @@ pub const Dir = struct { | ... | @@ -1083,7 +1083,7 @@ pub const Dir = struct { |
| 1083 | /// Asserts that the path parameter has no null bytes. | 1083 | /// Asserts that the path parameter has no null bytes. |
| 1084 | pub fn deleteDir(self: Dir, sub_path: []const u8) DeleteDirError!void { | 1084 | pub fn deleteDir(self: Dir, sub_path: []const u8) DeleteDirError!void { |
| 1085 | if (std.debug.runtime_safety) for (sub_path) |byte| assert(byte != 0); | 1085 | if (std.debug.runtime_safety) for (sub_path) |byte| assert(byte != 0); |
| 1086 | if (builtin.os == .windows) { | 1086 | if (builtin.os.tag == .windows) { |
| 1087 | const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path); | 1087 | const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path); |
| 1088 | return self.deleteDirW(&sub_path_w); | 1088 | return self.deleteDirW(&sub_path_w); |
| 1089 | } | 1089 | } |
| ... | @@ -1340,7 +1340,7 @@ pub const Dir = struct { | ... | @@ -1340,7 +1340,7 @@ pub const Dir = struct { |
| 1340 | /// For example, instead of testing if a file exists and then opening it, just | 1340 | /// For example, instead of testing if a file exists and then opening it, just |
| 1341 | /// open it and handle the error for file not found. | 1341 | /// open it and handle the error for file not found. |
| 1342 | pub fn access(self: Dir, sub_path: []const u8, flags: File.OpenFlags) AccessError!void { | 1342 | pub fn access(self: Dir, sub_path: []const u8, flags: File.OpenFlags) AccessError!void { |
| 1343 | if (builtin.os == .windows) { | 1343 | if (builtin.os.tag == .windows) { |
| 1344 | const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path); | 1344 | const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path); |
| 1345 | return self.accessW(&sub_path_w, flags); | 1345 | return self.accessW(&sub_path_w, flags); |
| 1346 | } | 1346 | } |
| ... | @@ -1350,7 +1350,7 @@ pub const Dir = struct { | ... | @@ -1350,7 +1350,7 @@ pub const Dir = struct { |
| 1350 | 1350 | ||
| 1351 | /// Same as `access` except the path parameter is null-terminated. | 1351 | /// Same as `access` except the path parameter is null-terminated. |
| 1352 | pub fn accessZ(self: Dir, sub_path: [*:0]const u8, flags: File.OpenFlags) AccessError!void { | 1352 | pub fn accessZ(self: Dir, sub_path: [*:0]const u8, flags: File.OpenFlags) AccessError!void { |
| 1353 | if (builtin.os == .windows) { | 1353 | if (builtin.os.tag == .windows) { |
| 1354 | const sub_path_w = try os.windows.cStrToPrefixedFileW(sub_path); | 1354 | const sub_path_w = try os.windows.cStrToPrefixedFileW(sub_path); |
| 1355 | return self.accessW(&sub_path_w, flags); | 1355 | return self.accessW(&sub_path_w, flags); |
| 1356 | } | 1356 | } |
| ... | @@ -1381,7 +1381,7 @@ pub const Dir = struct { | ... | @@ -1381,7 +1381,7 @@ pub const Dir = struct { |
| 1381 | /// Closing the returned `Dir` is checked illegal behavior. Iterating over the result is illegal behavior. | 1381 | /// Closing the returned `Dir` is checked illegal behavior. Iterating over the result is illegal behavior. |
| 1382 | /// On POSIX targets, this function is comptime-callable. | 1382 | /// On POSIX targets, this function is comptime-callable. |
| 1383 | pub fn cwd() Dir { | 1383 | pub fn cwd() Dir { |
| 1384 | if (builtin.os == .windows) { | 1384 | if (builtin.os.tag == .windows) { |
| 1385 | return Dir{ .fd = os.windows.peb().ProcessParameters.CurrentDirectory.Handle }; | 1385 | return Dir{ .fd = os.windows.peb().ProcessParameters.CurrentDirectory.Handle }; |
| 1386 | } else { | 1386 | } else { |
| 1387 | return Dir{ .fd = os.AT_FDCWD }; | 1387 | return Dir{ .fd = os.AT_FDCWD }; |
| ... | @@ -1560,10 +1560,10 @@ pub fn readLinkC(pathname_c: [*]const u8, buffer: *[MAX_PATH_BYTES]u8) ![]u8 { | ... | @@ -1560,10 +1560,10 @@ pub fn readLinkC(pathname_c: [*]const u8, buffer: *[MAX_PATH_BYTES]u8) ![]u8 { |
| 1560 | pub const OpenSelfExeError = os.OpenError || os.windows.CreateFileError || SelfExePathError; | 1560 | pub const OpenSelfExeError = os.OpenError || os.windows.CreateFileError || SelfExePathError; |
| 1561 | 1561 | ||
| 1562 | pub fn openSelfExe() OpenSelfExeError!File { | 1562 | pub fn openSelfExe() OpenSelfExeError!File { |
| 1563 | if (builtin.os == .linux) { | 1563 | if (builtin.os.tag == .linux) { |
| 1564 | return openFileAbsoluteC("/proc/self/exe", .{}); | 1564 | return openFileAbsoluteC("/proc/self/exe", .{}); |
| 1565 | } | 1565 | } |
| 1566 | if (builtin.os == .windows) { | 1566 | if (builtin.os.tag == .windows) { |
| 1567 | const wide_slice = selfExePathW(); | 1567 | const wide_slice = selfExePathW(); |
| 1568 | const prefixed_path_w = try os.windows.wToPrefixedFileW(wide_slice); | 1568 | const prefixed_path_w = try os.windows.wToPrefixedFileW(wide_slice); |
| 1569 | return cwd().openReadW(&prefixed_path_w); | 1569 | return cwd().openReadW(&prefixed_path_w); |
| ... | @@ -1575,7 +1575,7 @@ pub fn openSelfExe() OpenSelfExeError!File { | ... | @@ -1575,7 +1575,7 @@ pub fn openSelfExe() OpenSelfExeError!File { |
| 1575 | } | 1575 | } |
| 1576 | 1576 | ||
| 1577 | test "openSelfExe" { | 1577 | test "openSelfExe" { |
| 1578 | switch (builtin.os) { | 1578 | switch (builtin.os.tag) { |
| 1579 | .linux, .macosx, .ios, .windows, .freebsd, .dragonfly => (try openSelfExe()).close(), | 1579 | .linux, .macosx, .ios, .windows, .freebsd, .dragonfly => (try openSelfExe()).close(), |
| 1580 | else => return error.SkipZigTest, // Unsupported OS. | 1580 | else => return error.SkipZigTest, // Unsupported OS. |
| 1581 | } | 1581 | } |
| ... | @@ -1600,7 +1600,7 @@ pub fn selfExePath(out_buffer: *[MAX_PATH_BYTES]u8) SelfExePathError![]u8 { | ... | @@ -1600,7 +1600,7 @@ pub fn selfExePath(out_buffer: *[MAX_PATH_BYTES]u8) SelfExePathError![]u8 { |
| 1600 | if (rc != 0) return error.NameTooLong; | 1600 | if (rc != 0) return error.NameTooLong; |
| 1601 | return mem.toSlice(u8, @ptrCast([*:0]u8, out_buffer)); | 1601 | return mem.toSlice(u8, @ptrCast([*:0]u8, out_buffer)); |
| 1602 | } | 1602 | } |
| 1603 | switch (builtin.os) { | 1603 | switch (builtin.os.tag) { |
| 1604 | .linux => return os.readlinkC("/proc/self/exe", out_buffer), | 1604 | .linux => return os.readlinkC("/proc/self/exe", out_buffer), |
| 1605 | .freebsd, .dragonfly => { | 1605 | .freebsd, .dragonfly => { |
| 1606 | var mib = [4]c_int{ os.CTL_KERN, os.KERN_PROC, os.KERN_PROC_PATHNAME, -1 }; | 1606 | var mib = [4]c_int{ os.CTL_KERN, os.KERN_PROC, os.KERN_PROC_PATHNAME, -1 }; |
| ... | @@ -1642,7 +1642,7 @@ pub fn selfExeDirPathAlloc(allocator: *Allocator) ![]u8 { | ... | @@ -1642,7 +1642,7 @@ pub fn selfExeDirPathAlloc(allocator: *Allocator) ![]u8 { |
| 1642 | /// Get the directory path that contains the current executable. | 1642 | /// Get the directory path that contains the current executable. |
| 1643 | /// Returned value is a slice of out_buffer. | 1643 | /// Returned value is a slice of out_buffer. |
| 1644 | pub fn selfExeDirPath(out_buffer: *[MAX_PATH_BYTES]u8) SelfExePathError![]const u8 { | 1644 | pub fn selfExeDirPath(out_buffer: *[MAX_PATH_BYTES]u8) SelfExePathError![]const u8 { |
| 1645 | if (builtin.os == .linux) { | 1645 | if (builtin.os.tag == .linux) { |
| 1646 | // If the currently executing binary has been deleted, | 1646 | // If the currently executing binary has been deleted, |
| 1647 | // the file path looks something like `/a/b/c/exe (deleted)` | 1647 | // the file path looks something like `/a/b/c/exe (deleted)` |
| 1648 | // This path cannot be opened, but it's valid for determining the directory | 1648 | // This path cannot be opened, but it's valid for determining the directory |
lib/std/fs/file.zig+6-6| ... | @@ -29,7 +29,7 @@ pub const File = struct { | ... | @@ -29,7 +29,7 @@ pub const File = struct { |
| 29 | 29 | ||
| 30 | pub const Mode = os.mode_t; | 30 | pub const Mode = os.mode_t; |
| 31 | 31 | ||
| 32 | pub const default_mode = switch (builtin.os) { | 32 | pub const default_mode = switch (builtin.os.tag) { |
| 33 | .windows => 0, | 33 | .windows => 0, |
| 34 | else => 0o666, | 34 | else => 0o666, |
| 35 | }; | 35 | }; |
| ... | @@ -83,7 +83,7 @@ pub const File = struct { | ... | @@ -83,7 +83,7 @@ pub const File = struct { |
| 83 | 83 | ||
| 84 | /// Test whether ANSI escape codes will be treated as such. | 84 | /// Test whether ANSI escape codes will be treated as such. |
| 85 | pub fn supportsAnsiEscapeCodes(self: File) bool { | 85 | pub fn supportsAnsiEscapeCodes(self: File) bool { |
| 86 | if (builtin.os == .windows) { | 86 | if (builtin.os.tag == .windows) { |
| 87 | return os.isCygwinPty(self.handle); | 87 | return os.isCygwinPty(self.handle); |
| 88 | } | 88 | } |
| 89 | if (self.isTty()) { | 89 | if (self.isTty()) { |
| ... | @@ -128,7 +128,7 @@ pub const File = struct { | ... | @@ -128,7 +128,7 @@ pub const File = struct { |
| 128 | 128 | ||
| 129 | /// TODO: integrate with async I/O | 129 | /// TODO: integrate with async I/O |
| 130 | pub fn getEndPos(self: File) GetPosError!u64 { | 130 | pub fn getEndPos(self: File) GetPosError!u64 { |
| 131 | if (builtin.os == .windows) { | 131 | if (builtin.os.tag == .windows) { |
| 132 | return windows.GetFileSizeEx(self.handle); | 132 | return windows.GetFileSizeEx(self.handle); |
| 133 | } | 133 | } |
| 134 | return (try self.stat()).size; | 134 | return (try self.stat()).size; |
| ... | @@ -138,7 +138,7 @@ pub const File = struct { | ... | @@ -138,7 +138,7 @@ pub const File = struct { |
| 138 | 138 | ||
| 139 | /// TODO: integrate with async I/O | 139 | /// TODO: integrate with async I/O |
| 140 | pub fn mode(self: File) ModeError!Mode { | 140 | pub fn mode(self: File) ModeError!Mode { |
| 141 | if (builtin.os == .windows) { | 141 | if (builtin.os.tag == .windows) { |
| 142 | return {}; | 142 | return {}; |
| 143 | } | 143 | } |
| 144 | return (try self.stat()).mode; | 144 | return (try self.stat()).mode; |
| ... | @@ -162,7 +162,7 @@ pub const File = struct { | ... | @@ -162,7 +162,7 @@ pub const File = struct { |
| 162 | 162 | ||
| 163 | /// TODO: integrate with async I/O | 163 | /// TODO: integrate with async I/O |
| 164 | pub fn stat(self: File) StatError!Stat { | 164 | pub fn stat(self: File) StatError!Stat { |
| 165 | if (builtin.os == .windows) { | 165 | if (builtin.os.tag == .windows) { |
| 166 | var io_status_block: windows.IO_STATUS_BLOCK = undefined; | 166 | var io_status_block: windows.IO_STATUS_BLOCK = undefined; |
| 167 | var info: windows.FILE_ALL_INFORMATION = undefined; | 167 | var info: windows.FILE_ALL_INFORMATION = undefined; |
| 168 | const rc = windows.ntdll.NtQueryInformationFile(self.handle, &io_status_block, &info, @sizeOf(windows.FILE_ALL_INFORMATION), .FileAllInformation); | 168 | const rc = windows.ntdll.NtQueryInformationFile(self.handle, &io_status_block, &info, @sizeOf(windows.FILE_ALL_INFORMATION), .FileAllInformation); |
| ... | @@ -209,7 +209,7 @@ pub const File = struct { | ... | @@ -209,7 +209,7 @@ pub const File = struct { |
| 209 | /// last modification timestamp in nanoseconds | 209 | /// last modification timestamp in nanoseconds |
| 210 | mtime: i64, | 210 | mtime: i64, |
| 211 | ) UpdateTimesError!void { | 211 | ) UpdateTimesError!void { |
| 212 | if (builtin.os == .windows) { | 212 | if (builtin.os.tag == .windows) { |
| 213 | const atime_ft = windows.nanoSecondsToFileTime(atime); | 213 | const atime_ft = windows.nanoSecondsToFileTime(atime); |
| 214 | const mtime_ft = windows.nanoSecondsToFileTime(mtime); | 214 | const mtime_ft = windows.nanoSecondsToFileTime(mtime); |
| 215 | return windows.SetFileTime(self.handle, null, &atime_ft, &mtime_ft); | 215 | return windows.SetFileTime(self.handle, null, &atime_ft, &mtime_ft); |
lib/std/fs/get_app_data_dir.zig+1-1| ... | @@ -13,7 +13,7 @@ pub const GetAppDataDirError = error{ | ... | @@ -13,7 +13,7 @@ pub const GetAppDataDirError = error{ |
| 13 | /// Caller owns returned memory. | 13 | /// Caller owns returned memory. |
| 14 | /// TODO determine if we can remove the allocator requirement | 14 | /// TODO determine if we can remove the allocator requirement |
| 15 | pub fn getAppDataDir(allocator: *mem.Allocator, appname: []const u8) GetAppDataDirError![]u8 { | 15 | pub fn getAppDataDir(allocator: *mem.Allocator, appname: []const u8) GetAppDataDirError![]u8 { |
| 16 | switch (builtin.os) { | 16 | switch (builtin.os.tag) { |
| 17 | .windows => { | 17 | .windows => { |
| 18 | var dir_path_ptr: [*:0]u16 = undefined; | 18 | var dir_path_ptr: [*:0]u16 = undefined; |
| 19 | switch (os.windows.shell32.SHGetKnownFolderPath( | 19 | switch (os.windows.shell32.SHGetKnownFolderPath( |
lib/std/fs/path.zig+19-19| ... | @@ -13,18 +13,18 @@ const process = std.process; | ... | @@ -13,18 +13,18 @@ const process = std.process; |
| 13 | 13 | ||
| 14 | pub const sep_windows = '\\'; | 14 | pub const sep_windows = '\\'; |
| 15 | pub const sep_posix = '/'; | 15 | pub const sep_posix = '/'; |
| 16 | pub const sep = if (builtin.os == .windows) sep_windows else sep_posix; | 16 | pub const sep = if (builtin.os.tag == .windows) sep_windows else sep_posix; |
| 17 | 17 | ||
| 18 | pub const sep_str_windows = "\\"; | 18 | pub const sep_str_windows = "\\"; |
| 19 | pub const sep_str_posix = "/"; | 19 | pub const sep_str_posix = "/"; |
| 20 | pub const sep_str = if (builtin.os == .windows) sep_str_windows else sep_str_posix; | 20 | pub const sep_str = if (builtin.os.tag == .windows) sep_str_windows else sep_str_posix; |
| 21 | 21 | ||
| 22 | pub const delimiter_windows = ';'; | 22 | pub const delimiter_windows = ';'; |
| 23 | pub const delimiter_posix = ':'; | 23 | pub const delimiter_posix = ':'; |
| 24 | pub const delimiter = if (builtin.os == .windows) delimiter_windows else delimiter_posix; | 24 | pub const delimiter = if (builtin.os.tag == .windows) delimiter_windows else delimiter_posix; |
| 25 | 25 | ||
| 26 | pub fn isSep(byte: u8) bool { | 26 | pub fn isSep(byte: u8) bool { |
| 27 | if (builtin.os == .windows) { | 27 | if (builtin.os.tag == .windows) { |
| 28 | return byte == '/' or byte == '\\'; | 28 | return byte == '/' or byte == '\\'; |
| 29 | } else { | 29 | } else { |
| 30 | return byte == '/'; | 30 | return byte == '/'; |
| ... | @@ -74,7 +74,7 @@ fn joinSep(allocator: *Allocator, separator: u8, paths: []const []const u8) ![]u | ... | @@ -74,7 +74,7 @@ fn joinSep(allocator: *Allocator, separator: u8, paths: []const []const u8) ![]u |
| 74 | return buf; | 74 | return buf; |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | pub const join = if (builtin.os == .windows) joinWindows else joinPosix; | 77 | pub const join = if (builtin.os.tag == .windows) joinWindows else joinPosix; |
| 78 | 78 | ||
| 79 | /// Naively combines a series of paths with the native path seperator. | 79 | /// Naively combines a series of paths with the native path seperator. |
| 80 | /// Allocates memory for the result, which must be freed by the caller. | 80 | /// Allocates memory for the result, which must be freed by the caller. |
| ... | @@ -129,7 +129,7 @@ test "join" { | ... | @@ -129,7 +129,7 @@ test "join" { |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | pub fn isAbsoluteC(path_c: [*:0]const u8) bool { | 131 | pub fn isAbsoluteC(path_c: [*:0]const u8) bool { |
| 132 | if (builtin.os == .windows) { | 132 | if (builtin.os.tag == .windows) { |
| 133 | return isAbsoluteWindowsC(path_c); | 133 | return isAbsoluteWindowsC(path_c); |
| 134 | } else { | 134 | } else { |
| 135 | return isAbsolutePosixC(path_c); | 135 | return isAbsolutePosixC(path_c); |
| ... | @@ -137,7 +137,7 @@ pub fn isAbsoluteC(path_c: [*:0]const u8) bool { | ... | @@ -137,7 +137,7 @@ pub fn isAbsoluteC(path_c: [*:0]const u8) bool { |
| 137 | } | 137 | } |
| 138 | 138 | ||
| 139 | pub fn isAbsolute(path: []const u8) bool { | 139 | pub fn isAbsolute(path: []const u8) bool { |
| 140 | if (builtin.os == .windows) { | 140 | if (builtin.os.tag == .windows) { |
| 141 | return isAbsoluteWindows(path); | 141 | return isAbsoluteWindows(path); |
| 142 | } else { | 142 | } else { |
| 143 | return isAbsolutePosix(path); | 143 | return isAbsolutePosix(path); |
| ... | @@ -318,7 +318,7 @@ test "windowsParsePath" { | ... | @@ -318,7 +318,7 @@ test "windowsParsePath" { |
| 318 | } | 318 | } |
| 319 | 319 | ||
| 320 | pub fn diskDesignator(path: []const u8) []const u8 { | 320 | pub fn diskDesignator(path: []const u8) []const u8 { |
| 321 | if (builtin.os == .windows) { | 321 | if (builtin.os.tag == .windows) { |
| 322 | return diskDesignatorWindows(path); | 322 | return diskDesignatorWindows(path); |
| 323 | } else { | 323 | } else { |
| 324 | return ""; | 324 | return ""; |
| ... | @@ -383,7 +383,7 @@ fn asciiEqlIgnoreCase(s1: []const u8, s2: []const u8) bool { | ... | @@ -383,7 +383,7 @@ fn asciiEqlIgnoreCase(s1: []const u8, s2: []const u8) bool { |
| 383 | 383 | ||
| 384 | /// On Windows, this calls `resolveWindows` and on POSIX it calls `resolvePosix`. | 384 | /// On Windows, this calls `resolveWindows` and on POSIX it calls `resolvePosix`. |
| 385 | pub fn resolve(allocator: *Allocator, paths: []const []const u8) ![]u8 { | 385 | pub fn resolve(allocator: *Allocator, paths: []const []const u8) ![]u8 { |
| 386 | if (builtin.os == .windows) { | 386 | if (builtin.os.tag == .windows) { |
| 387 | return resolveWindows(allocator, paths); | 387 | return resolveWindows(allocator, paths); |
| 388 | } else { | 388 | } else { |
| 389 | return resolvePosix(allocator, paths); | 389 | return resolvePosix(allocator, paths); |
| ... | @@ -400,7 +400,7 @@ pub fn resolve(allocator: *Allocator, paths: []const []const u8) ![]u8 { | ... | @@ -400,7 +400,7 @@ pub fn resolve(allocator: *Allocator, paths: []const []const u8) ![]u8 { |
| 400 | /// Without performing actual syscalls, resolving `..` could be incorrect. | 400 | /// Without performing actual syscalls, resolving `..` could be incorrect. |
| 401 | pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 { | 401 | pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 { |
| 402 | if (paths.len == 0) { | 402 | if (paths.len == 0) { |
| 403 | assert(builtin.os == .windows); // resolveWindows called on non windows can't use getCwd | 403 | assert(builtin.os.tag == .windows); // resolveWindows called on non windows can't use getCwd |
| 404 | return process.getCwdAlloc(allocator); | 404 | return process.getCwdAlloc(allocator); |
| 405 | } | 405 | } |
| 406 | 406 | ||
| ... | @@ -495,7 +495,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 { | ... | @@ -495,7 +495,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 { |
| 495 | result_disk_designator = result[0..result_index]; | 495 | result_disk_designator = result[0..result_index]; |
| 496 | }, | 496 | }, |
| 497 | WindowsPath.Kind.None => { | 497 | WindowsPath.Kind.None => { |
| 498 | assert(builtin.os == .windows); // resolveWindows called on non windows can't use getCwd | 498 | assert(builtin.os.tag == .windows); // resolveWindows called on non windows can't use getCwd |
| 499 | const cwd = try process.getCwdAlloc(allocator); | 499 | const cwd = try process.getCwdAlloc(allocator); |
| 500 | defer allocator.free(cwd); | 500 | defer allocator.free(cwd); |
| 501 | const parsed_cwd = windowsParsePath(cwd); | 501 | const parsed_cwd = windowsParsePath(cwd); |
| ... | @@ -510,7 +510,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 { | ... | @@ -510,7 +510,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 { |
| 510 | }, | 510 | }, |
| 511 | } | 511 | } |
| 512 | } else { | 512 | } else { |
| 513 | assert(builtin.os == .windows); // resolveWindows called on non windows can't use getCwd | 513 | assert(builtin.os.tag == .windows); // resolveWindows called on non windows can't use getCwd |
| 514 | // TODO call get cwd for the result_disk_designator instead of the global one | 514 | // TODO call get cwd for the result_disk_designator instead of the global one |
| 515 | const cwd = try process.getCwdAlloc(allocator); | 515 | const cwd = try process.getCwdAlloc(allocator); |
| 516 | defer allocator.free(cwd); | 516 | defer allocator.free(cwd); |
| ... | @@ -581,7 +581,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 { | ... | @@ -581,7 +581,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 { |
| 581 | /// Without performing actual syscalls, resolving `..` could be incorrect. | 581 | /// Without performing actual syscalls, resolving `..` could be incorrect. |
| 582 | pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 { | 582 | pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 { |
| 583 | if (paths.len == 0) { | 583 | if (paths.len == 0) { |
| 584 | assert(builtin.os != .windows); // resolvePosix called on windows can't use getCwd | 584 | assert(builtin.os.tag != .windows); // resolvePosix called on windows can't use getCwd |
| 585 | return process.getCwdAlloc(allocator); | 585 | return process.getCwdAlloc(allocator); |
| 586 | } | 586 | } |
| 587 | 587 | ||
| ... | @@ -603,7 +603,7 @@ pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 { | ... | @@ -603,7 +603,7 @@ pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 { |
| 603 | if (have_abs) { | 603 | if (have_abs) { |
| 604 | result = try allocator.alloc(u8, max_size); | 604 | result = try allocator.alloc(u8, max_size); |
| 605 | } else { | 605 | } else { |
| 606 | assert(builtin.os != .windows); // resolvePosix called on windows can't use getCwd | 606 | assert(builtin.os.tag != .windows); // resolvePosix called on windows can't use getCwd |
| 607 | const cwd = try process.getCwdAlloc(allocator); | 607 | const cwd = try process.getCwdAlloc(allocator); |
| 608 | defer allocator.free(cwd); | 608 | defer allocator.free(cwd); |
| 609 | result = try allocator.alloc(u8, max_size + cwd.len + 1); | 609 | result = try allocator.alloc(u8, max_size + cwd.len + 1); |
| ... | @@ -645,7 +645,7 @@ pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 { | ... | @@ -645,7 +645,7 @@ pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 { |
| 645 | test "resolve" { | 645 | test "resolve" { |
| 646 | const cwd = try process.getCwdAlloc(testing.allocator); | 646 | const cwd = try process.getCwdAlloc(testing.allocator); |
| 647 | defer testing.allocator.free(cwd); | 647 | defer testing.allocator.free(cwd); |
| 648 | if (builtin.os == .windows) { | 648 | if (builtin.os.tag == .windows) { |
| 649 | if (windowsParsePath(cwd).kind == WindowsPath.Kind.Drive) { | 649 | if (windowsParsePath(cwd).kind == WindowsPath.Kind.Drive) { |
| 650 | cwd[0] = asciiUpper(cwd[0]); | 650 | cwd[0] = asciiUpper(cwd[0]); |
| 651 | } | 651 | } |
| ... | @@ -661,7 +661,7 @@ test "resolveWindows" { | ... | @@ -661,7 +661,7 @@ test "resolveWindows" { |
| 661 | // TODO https://github.com/ziglang/zig/issues/3288 | 661 | // TODO https://github.com/ziglang/zig/issues/3288 |
| 662 | return error.SkipZigTest; | 662 | return error.SkipZigTest; |
| 663 | } | 663 | } |
| 664 | if (builtin.os == .windows) { | 664 | if (builtin.os.tag == .windows) { |
| 665 | const cwd = try process.getCwdAlloc(testing.allocator); | 665 | const cwd = try process.getCwdAlloc(testing.allocator); |
| 666 | defer testing.allocator.free(cwd); | 666 | defer testing.allocator.free(cwd); |
| 667 | const parsed_cwd = windowsParsePath(cwd); | 667 | const parsed_cwd = windowsParsePath(cwd); |
| ... | @@ -732,7 +732,7 @@ fn testResolvePosix(paths: []const []const u8, expected: []const u8) !void { | ... | @@ -732,7 +732,7 @@ fn testResolvePosix(paths: []const []const u8, expected: []const u8) !void { |
| 732 | /// If the path is a file in the current directory (no directory component) | 732 | /// If the path is a file in the current directory (no directory component) |
| 733 | /// then returns null | 733 | /// then returns null |
| 734 | pub fn dirname(path: []const u8) ?[]const u8 { | 734 | pub fn dirname(path: []const u8) ?[]const u8 { |
| 735 | if (builtin.os == .windows) { | 735 | if (builtin.os.tag == .windows) { |
| 736 | return dirnameWindows(path); | 736 | return dirnameWindows(path); |
| 737 | } else { | 737 | } else { |
| 738 | return dirnamePosix(path); | 738 | return dirnamePosix(path); |
| ... | @@ -864,7 +864,7 @@ fn testDirnameWindows(input: []const u8, expected_output: ?[]const u8) void { | ... | @@ -864,7 +864,7 @@ fn testDirnameWindows(input: []const u8, expected_output: ?[]const u8) void { |
| 864 | } | 864 | } |
| 865 | 865 | ||
| 866 | pub fn basename(path: []const u8) []const u8 { | 866 | pub fn basename(path: []const u8) []const u8 { |
| 867 | if (builtin.os == .windows) { | 867 | if (builtin.os.tag == .windows) { |
| 868 | return basenameWindows(path); | 868 | return basenameWindows(path); |
| 869 | } else { | 869 | } else { |
| 870 | return basenamePosix(path); | 870 | return basenamePosix(path); |
| ... | @@ -980,7 +980,7 @@ fn testBasenameWindows(input: []const u8, expected_output: []const u8) void { | ... | @@ -980,7 +980,7 @@ fn testBasenameWindows(input: []const u8, expected_output: []const u8) void { |
| 980 | /// string is returned. | 980 | /// string is returned. |
| 981 | /// On Windows this canonicalizes the drive to a capital letter and paths to `\\`. | 981 | /// On Windows this canonicalizes the drive to a capital letter and paths to `\\`. |
| 982 | pub fn relative(allocator: *Allocator, from: []const u8, to: []const u8) ![]u8 { | 982 | pub fn relative(allocator: *Allocator, from: []const u8, to: []const u8) ![]u8 { |
| 983 | if (builtin.os == .windows) { | 983 | if (builtin.os.tag == .windows) { |
| 984 | return relativeWindows(allocator, from, to); | 984 | return relativeWindows(allocator, from, to); |
| 985 | } else { | 985 | } else { |
| 986 | return relativePosix(allocator, from, to); | 986 | return relativePosix(allocator, from, to); |
lib/std/fs/watch.zig+4-4| ... | @@ -42,7 +42,7 @@ pub fn Watch(comptime V: type) type { | ... | @@ -42,7 +42,7 @@ pub fn Watch(comptime V: type) type { |
| 42 | os_data: OsData, | 42 | os_data: OsData, |
| 43 | allocator: *Allocator, | 43 | allocator: *Allocator, |
| 44 | 44 | ||
| 45 | const OsData = switch (builtin.os) { | 45 | const OsData = switch (builtin.os.tag) { |
| 46 | // TODO https://github.com/ziglang/zig/issues/3778 | 46 | // TODO https://github.com/ziglang/zig/issues/3778 |
| 47 | .macosx, .freebsd, .netbsd, .dragonfly => KqOsData, | 47 | .macosx, .freebsd, .netbsd, .dragonfly => KqOsData, |
| 48 | .linux => LinuxOsData, | 48 | .linux => LinuxOsData, |
| ... | @@ -121,7 +121,7 @@ pub fn Watch(comptime V: type) type { | ... | @@ -121,7 +121,7 @@ pub fn Watch(comptime V: type) type { |
| 121 | const self = try allocator.create(Self); | 121 | const self = try allocator.create(Self); |
| 122 | errdefer allocator.destroy(self); | 122 | errdefer allocator.destroy(self); |
| 123 | 123 | ||
| 124 | switch (builtin.os) { | 124 | switch (builtin.os.tag) { |
| 125 | .linux => { | 125 | .linux => { |
| 126 | const inotify_fd = try os.inotify_init1(os.linux.IN_NONBLOCK | os.linux.IN_CLOEXEC); | 126 | const inotify_fd = try os.inotify_init1(os.linux.IN_NONBLOCK | os.linux.IN_CLOEXEC); |
| 127 | errdefer os.close(inotify_fd); | 127 | errdefer os.close(inotify_fd); |
| ... | @@ -172,7 +172,7 @@ pub fn Watch(comptime V: type) type { | ... | @@ -172,7 +172,7 @@ pub fn Watch(comptime V: type) type { |
| 172 | 172 | ||
| 173 | /// All addFile calls and removeFile calls must have completed. | 173 | /// All addFile calls and removeFile calls must have completed. |
| 174 | pub fn deinit(self: *Self) void { | 174 | pub fn deinit(self: *Self) void { |
| 175 | switch (builtin.os) { | 175 | switch (builtin.os.tag) { |
| 176 | .macosx, .freebsd, .netbsd, .dragonfly => { | 176 | .macosx, .freebsd, .netbsd, .dragonfly => { |
| 177 | // TODO we need to cancel the frames before destroying the lock | 177 | // TODO we need to cancel the frames before destroying the lock |
| 178 | self.os_data.table_lock.deinit(); | 178 | self.os_data.table_lock.deinit(); |
| ... | @@ -223,7 +223,7 @@ pub fn Watch(comptime V: type) type { | ... | @@ -223,7 +223,7 @@ pub fn Watch(comptime V: type) type { |
| 223 | } | 223 | } |
| 224 | 224 | ||
| 225 | pub fn addFile(self: *Self, file_path: []const u8, value: V) !?V { | 225 | pub fn addFile(self: *Self, file_path: []const u8, value: V) !?V { |
| 226 | switch (builtin.os) { | 226 | switch (builtin.os.tag) { |
| 227 | .macosx, .freebsd, .netbsd, .dragonfly => return addFileKEvent(self, file_path, value), | 227 | .macosx, .freebsd, .netbsd, .dragonfly => return addFileKEvent(self, file_path, value), |
| 228 | .linux => return addFileLinux(self, file_path, value), | 228 | .linux => return addFileLinux(self, file_path, value), |
| 229 | .windows => return addFileWindows(self, file_path, value), | 229 | .windows => return addFileWindows(self, file_path, value), |
lib/std/heap.zig+7-7| ... | @@ -36,7 +36,7 @@ fn cShrink(self: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new | ... | @@ -36,7 +36,7 @@ fn cShrink(self: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new |
| 36 | /// Thread-safe and lock-free. | 36 | /// Thread-safe and lock-free. |
| 37 | pub const page_allocator = if (std.Target.current.isWasm()) | 37 | pub const page_allocator = if (std.Target.current.isWasm()) |
| 38 | &wasm_page_allocator_state | 38 | &wasm_page_allocator_state |
| 39 | else if (std.Target.current.getOs() == .freestanding) | 39 | else if (std.Target.current.os.tag == .freestanding) |
| 40 | root.os.heap.page_allocator | 40 | root.os.heap.page_allocator |
| 41 | else | 41 | else |
| 42 | &page_allocator_state; | 42 | &page_allocator_state; |
| ... | @@ -57,7 +57,7 @@ const PageAllocator = struct { | ... | @@ -57,7 +57,7 @@ const PageAllocator = struct { |
| 57 | fn alloc(allocator: *Allocator, n: usize, alignment: u29) error{OutOfMemory}![]u8 { | 57 | fn alloc(allocator: *Allocator, n: usize, alignment: u29) error{OutOfMemory}![]u8 { |
| 58 | if (n == 0) return &[0]u8{}; | 58 | if (n == 0) return &[0]u8{}; |
| 59 | 59 | ||
| 60 | if (builtin.os == .windows) { | 60 | if (builtin.os.tag == .windows) { |
| 61 | const w = os.windows; | 61 | const w = os.windows; |
| 62 | 62 | ||
| 63 | // Although officially it's at least aligned to page boundary, | 63 | // Although officially it's at least aligned to page boundary, |
| ... | @@ -143,7 +143,7 @@ const PageAllocator = struct { | ... | @@ -143,7 +143,7 @@ const PageAllocator = struct { |
| 143 | 143 | ||
| 144 | fn shrink(allocator: *Allocator, old_mem_unaligned: []u8, old_align: u29, new_size: usize, new_align: u29) []u8 { | 144 | fn shrink(allocator: *Allocator, old_mem_unaligned: []u8, old_align: u29, new_size: usize, new_align: u29) []u8 { |
| 145 | const old_mem = @alignCast(mem.page_size, old_mem_unaligned); | 145 | const old_mem = @alignCast(mem.page_size, old_mem_unaligned); |
| 146 | if (builtin.os == .windows) { | 146 | if (builtin.os.tag == .windows) { |
| 147 | const w = os.windows; | 147 | const w = os.windows; |
| 148 | if (new_size == 0) { | 148 | if (new_size == 0) { |
| 149 | // From the docs: | 149 | // From the docs: |
| ... | @@ -183,7 +183,7 @@ const PageAllocator = struct { | ... | @@ -183,7 +183,7 @@ const PageAllocator = struct { |
| 183 | 183 | ||
| 184 | fn realloc(allocator: *Allocator, old_mem_unaligned: []u8, old_align: u29, new_size: usize, new_align: u29) ![]u8 { | 184 | fn realloc(allocator: *Allocator, old_mem_unaligned: []u8, old_align: u29, new_size: usize, new_align: u29) ![]u8 { |
| 185 | const old_mem = @alignCast(mem.page_size, old_mem_unaligned); | 185 | const old_mem = @alignCast(mem.page_size, old_mem_unaligned); |
| 186 | if (builtin.os == .windows) { | 186 | if (builtin.os.tag == .windows) { |
| 187 | if (old_mem.len == 0) { | 187 | if (old_mem.len == 0) { |
| 188 | return alloc(allocator, new_size, new_align); | 188 | return alloc(allocator, new_size, new_align); |
| 189 | } | 189 | } |
| ... | @@ -412,7 +412,7 @@ const WasmPageAllocator = struct { | ... | @@ -412,7 +412,7 @@ const WasmPageAllocator = struct { |
| 412 | } | 412 | } |
| 413 | }; | 413 | }; |
| 414 | 414 | ||
| 415 | pub const HeapAllocator = switch (builtin.os) { | 415 | pub const HeapAllocator = switch (builtin.os.tag) { |
| 416 | .windows => struct { | 416 | .windows => struct { |
| 417 | allocator: Allocator, | 417 | allocator: Allocator, |
| 418 | heap_handle: ?HeapHandle, | 418 | heap_handle: ?HeapHandle, |
| ... | @@ -855,7 +855,7 @@ test "PageAllocator" { | ... | @@ -855,7 +855,7 @@ test "PageAllocator" { |
| 855 | try testAllocatorAlignedShrink(allocator); | 855 | try testAllocatorAlignedShrink(allocator); |
| 856 | } | 856 | } |
| 857 | 857 | ||
| 858 | if (builtin.os == .windows) { | 858 | if (builtin.os.tag == .windows) { |
| 859 | // Trying really large alignment. As mentionned in the implementation, | 859 | // Trying really large alignment. As mentionned in the implementation, |
| 860 | // VirtualAlloc returns 64K aligned addresses. We want to make sure | 860 | // VirtualAlloc returns 64K aligned addresses. We want to make sure |
| 861 | // PageAllocator works beyond that, as it's not tested by | 861 | // PageAllocator works beyond that, as it's not tested by |
| ... | @@ -868,7 +868,7 @@ test "PageAllocator" { | ... | @@ -868,7 +868,7 @@ test "PageAllocator" { |
| 868 | } | 868 | } |
| 869 | 869 | ||
| 870 | test "HeapAllocator" { | 870 | test "HeapAllocator" { |
| 871 | if (builtin.os == .windows) { | 871 | if (builtin.os.tag == .windows) { |
| 872 | var heap_allocator = HeapAllocator.init(); | 872 | var heap_allocator = HeapAllocator.init(); |
| 873 | defer heap_allocator.deinit(); | 873 | defer heap_allocator.deinit(); |
| 874 | 874 |
lib/std/io.zig+3-3| ... | @@ -35,7 +35,7 @@ else | ... | @@ -35,7 +35,7 @@ else |
| 35 | pub const is_async = mode != .blocking; | 35 | pub const is_async = mode != .blocking; |
| 36 | 36 | ||
| 37 | fn getStdOutHandle() os.fd_t { | 37 | fn getStdOutHandle() os.fd_t { |
| 38 | if (builtin.os == .windows) { | 38 | if (builtin.os.tag == .windows) { |
| 39 | return os.windows.peb().ProcessParameters.hStdOutput; | 39 | return os.windows.peb().ProcessParameters.hStdOutput; |
| 40 | } | 40 | } |
| 41 | 41 | ||
| ... | @@ -54,7 +54,7 @@ pub fn getStdOut() File { | ... | @@ -54,7 +54,7 @@ pub fn getStdOut() File { |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | fn getStdErrHandle() os.fd_t { | 56 | fn getStdErrHandle() os.fd_t { |
| 57 | if (builtin.os == .windows) { | 57 | if (builtin.os.tag == .windows) { |
| 58 | return os.windows.peb().ProcessParameters.hStdError; | 58 | return os.windows.peb().ProcessParameters.hStdError; |
| 59 | } | 59 | } |
| 60 | 60 | ||
| ... | @@ -74,7 +74,7 @@ pub fn getStdErr() File { | ... | @@ -74,7 +74,7 @@ pub fn getStdErr() File { |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | fn getStdInHandle() os.fd_t { | 76 | fn getStdInHandle() os.fd_t { |
| 77 | if (builtin.os == .windows) { | 77 | if (builtin.os.tag == .windows) { |
| 78 | return os.windows.peb().ProcessParameters.hStdInput; | 78 | return os.windows.peb().ProcessParameters.hStdInput; |
| 79 | } | 79 | } |
| 80 | 80 |
lib/std/io/test.zig+1-1| ... | @@ -544,7 +544,7 @@ fn testSerializerDeserializer(comptime endian: builtin.Endian, comptime packing: | ... | @@ -544,7 +544,7 @@ fn testSerializerDeserializer(comptime endian: builtin.Endian, comptime packing: |
| 544 | } | 544 | } |
| 545 | 545 | ||
| 546 | test "Serializer/Deserializer generic" { | 546 | test "Serializer/Deserializer generic" { |
| 547 | if (std.Target.current.isWindows()) { | 547 | if (std.Target.current.os.tag == .windows) { |
| 548 | // TODO https://github.com/ziglang/zig/issues/508 | 548 | // TODO https://github.com/ziglang/zig/issues/508 |
| 549 | return error.SkipZigTest; | 549 | return error.SkipZigTest; |
| 550 | } | 550 | } |
lib/std/math/fabs.zig+1-1| ... | @@ -95,7 +95,7 @@ test "math.fabs64.special" { | ... | @@ -95,7 +95,7 @@ test "math.fabs64.special" { |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | test "math.fabs128.special" { | 97 | test "math.fabs128.special" { |
| 98 | if (std.Target.current.isWindows()) { | 98 | if (std.Target.current.os.tag == .windows) { |
| 99 | // TODO https://github.com/ziglang/zig/issues/508 | 99 | // TODO https://github.com/ziglang/zig/issues/508 |
| 100 | return error.SkipZigTest; | 100 | return error.SkipZigTest; |
| 101 | } | 101 | } |
lib/std/math/isinf.zig+3-3| ... | @@ -74,7 +74,7 @@ pub fn isNegativeInf(x: var) bool { | ... | @@ -74,7 +74,7 @@ pub fn isNegativeInf(x: var) bool { |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | test "math.isInf" { | 76 | test "math.isInf" { |
| 77 | if (std.Target.current.isWindows()) { | 77 | if (std.Target.current.os.tag == .windows) { |
| 78 | // TODO https://github.com/ziglang/zig/issues/508 | 78 | // TODO https://github.com/ziglang/zig/issues/508 |
| 79 | return error.SkipZigTest; | 79 | return error.SkipZigTest; |
| 80 | } | 80 | } |
| ... | @@ -97,7 +97,7 @@ test "math.isInf" { | ... | @@ -97,7 +97,7 @@ test "math.isInf" { |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | test "math.isPositiveInf" { | 99 | test "math.isPositiveInf" { |
| 100 | if (std.Target.current.isWindows()) { | 100 | if (std.Target.current.os.tag == .windows) { |
| 101 | // TODO https://github.com/ziglang/zig/issues/508 | 101 | // TODO https://github.com/ziglang/zig/issues/508 |
| 102 | return error.SkipZigTest; | 102 | return error.SkipZigTest; |
| 103 | } | 103 | } |
| ... | @@ -120,7 +120,7 @@ test "math.isPositiveInf" { | ... | @@ -120,7 +120,7 @@ test "math.isPositiveInf" { |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | test "math.isNegativeInf" { | 122 | test "math.isNegativeInf" { |
| 123 | if (std.Target.current.isWindows()) { | 123 | if (std.Target.current.os.tag == .windows) { |
| 124 | // TODO https://github.com/ziglang/zig/issues/508 | 124 | // TODO https://github.com/ziglang/zig/issues/508 |
| 125 | return error.SkipZigTest; | 125 | return error.SkipZigTest; |
| 126 | } | 126 | } |
lib/std/math/isnan.zig+1-1| ... | @@ -16,7 +16,7 @@ pub fn isSignalNan(x: var) bool { | ... | @@ -16,7 +16,7 @@ pub fn isSignalNan(x: var) bool { |
| 16 | } | 16 | } |
| 17 | 17 | ||
| 18 | test "math.isNan" { | 18 | test "math.isNan" { |
| 19 | if (std.Target.current.isWindows()) { | 19 | if (std.Target.current.os.tag == .windows) { |
| 20 | // TODO https://github.com/ziglang/zig/issues/508 | 20 | // TODO https://github.com/ziglang/zig/issues/508 |
| 21 | return error.SkipZigTest; | 21 | return error.SkipZigTest; |
| 22 | } | 22 | } |
lib/std/mutex.zig+2-2| ... | @@ -73,7 +73,7 @@ pub const Mutex = if (builtin.single_threaded) | ... | @@ -73,7 +73,7 @@ pub const Mutex = if (builtin.single_threaded) |
| 73 | return self.tryAcquire() orelse @panic("deadlock detected"); | 73 | return self.tryAcquire() orelse @panic("deadlock detected"); |
| 74 | } | 74 | } |
| 75 | } | 75 | } |
| 76 | else if (builtin.os == .windows) | 76 | else if (builtin.os.tag == .windows) |
| 77 | // https://locklessinc.com/articles/keyed_events/ | 77 | // https://locklessinc.com/articles/keyed_events/ |
| 78 | extern union { | 78 | extern union { |
| 79 | locked: u8, | 79 | locked: u8, |
| ... | @@ -161,7 +161,7 @@ else if (builtin.os == .windows) | ... | @@ -161,7 +161,7 @@ else if (builtin.os == .windows) |
| 161 | } | 161 | } |
| 162 | }; | 162 | }; |
| 163 | } | 163 | } |
| 164 | else if (builtin.link_libc or builtin.os == .linux) | 164 | else if (builtin.link_libc or builtin.os.tag == .linux) |
| 165 | // stack-based version of https://github.com/Amanieu/parking_lot/blob/master/core/src/word_lock.rs | 165 | // stack-based version of https://github.com/Amanieu/parking_lot/blob/master/core/src/word_lock.rs |
| 166 | struct { | 166 | struct { |
| 167 | state: usize, | 167 | state: usize, |
lib/std/net.zig+1-1| ... | @@ -501,7 +501,7 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !* | ... | @@ -501,7 +501,7 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !* |
| 501 | 501 | ||
| 502 | return result; | 502 | return result; |
| 503 | } | 503 | } |
| 504 | if (builtin.os == .linux) { | 504 | if (builtin.os.tag == .linux) { |
| 505 | const flags = std.c.AI_NUMERICSERV; | 505 | const flags = std.c.AI_NUMERICSERV; |
| 506 | const family = os.AF_UNSPEC; | 506 | const family = os.AF_UNSPEC; |
| 507 | var lookup_addrs = std.ArrayList(LookupAddr).init(allocator); | 507 | var lookup_addrs = std.ArrayList(LookupAddr).init(allocator); |
lib/std/net/test.zig+2-2| ... | @@ -63,7 +63,7 @@ test "parse and render IPv4 addresses" { | ... | @@ -63,7 +63,7 @@ test "parse and render IPv4 addresses" { |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | test "resolve DNS" { | 65 | test "resolve DNS" { |
| 66 | if (std.builtin.os == .windows) { | 66 | if (std.builtin.os.tag == .windows) { |
| 67 | // DNS resolution not implemented on Windows yet. | 67 | // DNS resolution not implemented on Windows yet. |
| 68 | return error.SkipZigTest; | 68 | return error.SkipZigTest; |
| 69 | } | 69 | } |
| ... | @@ -81,7 +81,7 @@ test "resolve DNS" { | ... | @@ -81,7 +81,7 @@ test "resolve DNS" { |
| 81 | test "listen on a port, send bytes, receive bytes" { | 81 | test "listen on a port, send bytes, receive bytes" { |
| 82 | if (!std.io.is_async) return error.SkipZigTest; | 82 | if (!std.io.is_async) return error.SkipZigTest; |
| 83 | 83 | ||
| 84 | if (std.builtin.os != .linux) { | 84 | if (std.builtin.os.tag != .linux) { |
| 85 | // TODO build abstractions for other operating systems | 85 | // TODO build abstractions for other operating systems |
| 86 | return error.SkipZigTest; | 86 | return error.SkipZigTest; |
| 87 | } | 87 | } |
lib/std/os.zig+83-81| ... | @@ -56,7 +56,7 @@ pub const system = if (@hasDecl(root, "os") and root.os != @This()) | ... | @@ -56,7 +56,7 @@ pub const system = if (@hasDecl(root, "os") and root.os != @This()) |
| 56 | root.os.system | 56 | root.os.system |
| 57 | else if (builtin.link_libc) | 57 | else if (builtin.link_libc) |
| 58 | std.c | 58 | std.c |
| 59 | else switch (builtin.os) { | 59 | else switch (builtin.os.tag) { |
| 60 | .macosx, .ios, .watchos, .tvos => darwin, | 60 | .macosx, .ios, .watchos, .tvos => darwin, |
| 61 | .freebsd => freebsd, | 61 | .freebsd => freebsd, |
| 62 | .linux => linux, | 62 | .linux => linux, |
| ... | @@ -93,10 +93,10 @@ pub const errno = system.getErrno; | ... | @@ -93,10 +93,10 @@ pub const errno = system.getErrno; |
| 93 | /// must call `fsync` before `close`. | 93 | /// must call `fsync` before `close`. |
| 94 | /// Note: The Zig standard library does not support POSIX thread cancellation. | 94 | /// Note: The Zig standard library does not support POSIX thread cancellation. |
| 95 | pub fn close(fd: fd_t) void { | 95 | pub fn close(fd: fd_t) void { |
| 96 | if (builtin.os == .windows) { | 96 | if (builtin.os.tag == .windows) { |
| 97 | return windows.CloseHandle(fd); | 97 | return windows.CloseHandle(fd); |
| 98 | } | 98 | } |
| 99 | if (builtin.os == .wasi) { | 99 | if (builtin.os.tag == .wasi) { |
| 100 | _ = wasi.fd_close(fd); | 100 | _ = wasi.fd_close(fd); |
| 101 | } | 101 | } |
| 102 | if (comptime std.Target.current.isDarwin()) { | 102 | if (comptime std.Target.current.isDarwin()) { |
| ... | @@ -121,12 +121,12 @@ pub const GetRandomError = OpenError; | ... | @@ -121,12 +121,12 @@ pub const GetRandomError = OpenError; |
| 121 | /// appropriate OS-specific library call. Otherwise it uses the zig standard | 121 | /// appropriate OS-specific library call. Otherwise it uses the zig standard |
| 122 | /// library implementation. | 122 | /// library implementation. |
| 123 | pub fn getrandom(buffer: []u8) GetRandomError!void { | 123 | pub fn getrandom(buffer: []u8) GetRandomError!void { |
| 124 | if (builtin.os == .windows) { | 124 | if (builtin.os.tag == .windows) { |
| 125 | return windows.RtlGenRandom(buffer); | 125 | return windows.RtlGenRandom(buffer); |
| 126 | } | 126 | } |
| 127 | if (builtin.os == .linux or builtin.os == .freebsd) { | 127 | if (builtin.os.tag == .linux or builtin.os.tag == .freebsd) { |
| 128 | var buf = buffer; | 128 | var buf = buffer; |
| 129 | const use_c = builtin.os != .linux or | 129 | const use_c = builtin.os.tag != .linux or |
| 130 | std.c.versionCheck(builtin.Version{ .major = 2, .minor = 25, .patch = 0 }).ok; | 130 | std.c.versionCheck(builtin.Version{ .major = 2, .minor = 25, .patch = 0 }).ok; |
| 131 | 131 | ||
| 132 | while (buf.len != 0) { | 132 | while (buf.len != 0) { |
| ... | @@ -153,7 +153,7 @@ pub fn getrandom(buffer: []u8) GetRandomError!void { | ... | @@ -153,7 +153,7 @@ pub fn getrandom(buffer: []u8) GetRandomError!void { |
| 153 | } | 153 | } |
| 154 | return; | 154 | return; |
| 155 | } | 155 | } |
| 156 | if (builtin.os == .wasi) { | 156 | if (builtin.os.tag == .wasi) { |
| 157 | switch (wasi.random_get(buffer.ptr, buffer.len)) { | 157 | switch (wasi.random_get(buffer.ptr, buffer.len)) { |
| 158 | 0 => return, | 158 | 0 => return, |
| 159 | else => |err| return unexpectedErrno(err), | 159 | else => |err| return unexpectedErrno(err), |
| ... | @@ -188,13 +188,13 @@ pub fn abort() noreturn { | ... | @@ -188,13 +188,13 @@ pub fn abort() noreturn { |
| 188 | // MSVCRT abort() sometimes opens a popup window which is undesirable, so | 188 | // MSVCRT abort() sometimes opens a popup window which is undesirable, so |
| 189 | // even when linking libc on Windows we use our own abort implementation. | 189 | // even when linking libc on Windows we use our own abort implementation. |
| 190 | // See https://github.com/ziglang/zig/issues/2071 for more details. | 190 | // See https://github.com/ziglang/zig/issues/2071 for more details. |
| 191 | if (builtin.os == .windows) { | 191 | if (builtin.os.tag == .windows) { |
| 192 | if (builtin.mode == .Debug) { | 192 | if (builtin.mode == .Debug) { |
| 193 | @breakpoint(); | 193 | @breakpoint(); |
| 194 | } | 194 | } |
| 195 | windows.kernel32.ExitProcess(3); | 195 | windows.kernel32.ExitProcess(3); |
| 196 | } | 196 | } |
| 197 | if (!builtin.link_libc and builtin.os == .linux) { | 197 | if (!builtin.link_libc and builtin.os.tag == .linux) { |
| 198 | raise(SIGABRT) catch {}; | 198 | raise(SIGABRT) catch {}; |
| 199 | 199 | ||
| 200 | // TODO the rest of the implementation of abort() from musl libc here | 200 | // TODO the rest of the implementation of abort() from musl libc here |
| ... | @@ -202,10 +202,10 @@ pub fn abort() noreturn { | ... | @@ -202,10 +202,10 @@ pub fn abort() noreturn { |
| 202 | raise(SIGKILL) catch {}; | 202 | raise(SIGKILL) catch {}; |
| 203 | exit(127); | 203 | exit(127); |
| 204 | } | 204 | } |
| 205 | if (builtin.os == .uefi) { | 205 | if (builtin.os.tag == .uefi) { |
| 206 | exit(0); // TODO choose appropriate exit code | 206 | exit(0); // TODO choose appropriate exit code |
| 207 | } | 207 | } |
| 208 | if (builtin.os == .wasi) { | 208 | if (builtin.os.tag == .wasi) { |
| 209 | @breakpoint(); | 209 | @breakpoint(); |
| 210 | exit(1); | 210 | exit(1); |
| 211 | } | 211 | } |
| ... | @@ -223,7 +223,7 @@ pub fn raise(sig: u8) RaiseError!void { | ... | @@ -223,7 +223,7 @@ pub fn raise(sig: u8) RaiseError!void { |
| 223 | } | 223 | } |
| 224 | } | 224 | } |
| 225 | 225 | ||
| 226 | if (builtin.os == .linux) { | 226 | if (builtin.os.tag == .linux) { |
| 227 | var set: linux.sigset_t = undefined; | 227 | var set: linux.sigset_t = undefined; |
| 228 | // block application signals | 228 | // block application signals |
| 229 | _ = linux.sigprocmask(SIG_BLOCK, &linux.app_mask, &set); | 229 | _ = linux.sigprocmask(SIG_BLOCK, &linux.app_mask, &set); |
| ... | @@ -260,16 +260,16 @@ pub fn exit(status: u8) noreturn { | ... | @@ -260,16 +260,16 @@ pub fn exit(status: u8) noreturn { |
| 260 | if (builtin.link_libc) { | 260 | if (builtin.link_libc) { |
| 261 | system.exit(status); | 261 | system.exit(status); |
| 262 | } | 262 | } |
| 263 | if (builtin.os == .windows) { | 263 | if (builtin.os.tag == .windows) { |
| 264 | windows.kernel32.ExitProcess(status); | 264 | windows.kernel32.ExitProcess(status); |
| 265 | } | 265 | } |
| 266 | if (builtin.os == .wasi) { | 266 | if (builtin.os.tag == .wasi) { |
| 267 | wasi.proc_exit(status); | 267 | wasi.proc_exit(status); |
| 268 | } | 268 | } |
| 269 | if (builtin.os == .linux and !builtin.single_threaded) { | 269 | if (builtin.os.tag == .linux and !builtin.single_threaded) { |
| 270 | linux.exit_group(status); | 270 | linux.exit_group(status); |
| 271 | } | 271 | } |
| 272 | if (builtin.os == .uefi) { | 272 | if (builtin.os.tag == .uefi) { |
| 273 | // exit() is only avaliable if exitBootServices() has not been called yet. | 273 | // exit() is only avaliable if exitBootServices() has not been called yet. |
| 274 | // This call to exit should not fail, so we don't care about its return value. | 274 | // This call to exit should not fail, so we don't care about its return value. |
| 275 | if (uefi.system_table.boot_services) |bs| { | 275 | if (uefi.system_table.boot_services) |bs| { |
| ... | @@ -299,11 +299,11 @@ pub const ReadError = error{ | ... | @@ -299,11 +299,11 @@ pub const ReadError = error{ |
| 299 | /// If the application has a global event loop enabled, EAGAIN is handled | 299 | /// If the application has a global event loop enabled, EAGAIN is handled |
| 300 | /// via the event loop. Otherwise EAGAIN results in error.WouldBlock. | 300 | /// via the event loop. Otherwise EAGAIN results in error.WouldBlock. |
| 301 | pub fn read(fd: fd_t, buf: []u8) ReadError!usize { | 301 | pub fn read(fd: fd_t, buf: []u8) ReadError!usize { |
| 302 | if (builtin.os == .windows) { | 302 | if (builtin.os.tag == .windows) { |
| 303 | return windows.ReadFile(fd, buf, null); | 303 | return windows.ReadFile(fd, buf, null); |
| 304 | } | 304 | } |
| 305 | 305 | ||
| 306 | if (builtin.os == .wasi and !builtin.link_libc) { | 306 | if (builtin.os.tag == .wasi and !builtin.link_libc) { |
| 307 | const iovs = [1]iovec{iovec{ | 307 | const iovs = [1]iovec{iovec{ |
| 308 | .iov_base = buf.ptr, | 308 | .iov_base = buf.ptr, |
| 309 | .iov_len = buf.len, | 309 | .iov_len = buf.len, |
| ... | @@ -352,7 +352,7 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize { | ... | @@ -352,7 +352,7 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize { |
| 352 | /// * Windows | 352 | /// * Windows |
| 353 | /// On these systems, the read races with concurrent writes to the same file descriptor. | 353 | /// On these systems, the read races with concurrent writes to the same file descriptor. |
| 354 | pub fn readv(fd: fd_t, iov: []const iovec) ReadError!usize { | 354 | pub fn readv(fd: fd_t, iov: []const iovec) ReadError!usize { |
| 355 | if (builtin.os == .windows) { | 355 | if (builtin.os.tag == .windows) { |
| 356 | // TODO batch these into parallel requests | 356 | // TODO batch these into parallel requests |
| 357 | var off: usize = 0; | 357 | var off: usize = 0; |
| 358 | var iov_i: usize = 0; | 358 | var iov_i: usize = 0; |
| ... | @@ -406,7 +406,7 @@ pub fn readv(fd: fd_t, iov: []const iovec) ReadError!usize { | ... | @@ -406,7 +406,7 @@ pub fn readv(fd: fd_t, iov: []const iovec) ReadError!usize { |
| 406 | /// On Windows, if the application has a global event loop enabled, I/O Completion Ports are | 406 | /// On Windows, if the application has a global event loop enabled, I/O Completion Ports are |
| 407 | /// used to perform the I/O. `error.WouldBlock` is not possible on Windows. | 407 | /// used to perform the I/O. `error.WouldBlock` is not possible on Windows. |
| 408 | pub fn pread(fd: fd_t, buf: []u8, offset: u64) ReadError!usize { | 408 | pub fn pread(fd: fd_t, buf: []u8, offset: u64) ReadError!usize { |
| 409 | if (builtin.os == .windows) { | 409 | if (builtin.os.tag == .windows) { |
| 410 | return windows.ReadFile(fd, buf, offset); | 410 | return windows.ReadFile(fd, buf, offset); |
| 411 | } | 411 | } |
| 412 | 412 | ||
| ... | @@ -493,7 +493,7 @@ pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) ReadError!usize { | ... | @@ -493,7 +493,7 @@ pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) ReadError!usize { |
| 493 | } | 493 | } |
| 494 | } | 494 | } |
| 495 | 495 | ||
| 496 | if (builtin.os == .windows) { | 496 | if (builtin.os.tag == .windows) { |
| 497 | // TODO batch these into parallel requests | 497 | // TODO batch these into parallel requests |
| 498 | var off: usize = 0; | 498 | var off: usize = 0; |
| 499 | var iov_i: usize = 0; | 499 | var iov_i: usize = 0; |
| ... | @@ -557,11 +557,11 @@ pub const WriteError = error{ | ... | @@ -557,11 +557,11 @@ pub const WriteError = error{ |
| 557 | /// If the application has a global event loop enabled, EAGAIN is handled | 557 | /// If the application has a global event loop enabled, EAGAIN is handled |
| 558 | /// via the event loop. Otherwise EAGAIN results in error.WouldBlock. | 558 | /// via the event loop. Otherwise EAGAIN results in error.WouldBlock. |
| 559 | pub fn write(fd: fd_t, bytes: []const u8) WriteError!void { | 559 | pub fn write(fd: fd_t, bytes: []const u8) WriteError!void { |
| 560 | if (builtin.os == .windows) { | 560 | if (builtin.os.tag == .windows) { |
| 561 | return windows.WriteFile(fd, bytes, null); | 561 | return windows.WriteFile(fd, bytes, null); |
| 562 | } | 562 | } |
| 563 | 563 | ||
| 564 | if (builtin.os == .wasi and !builtin.link_libc) { | 564 | if (builtin.os.tag == .wasi and !builtin.link_libc) { |
| 565 | const ciovs = [1]iovec_const{iovec_const{ | 565 | const ciovs = [1]iovec_const{iovec_const{ |
| 566 | .iov_base = bytes.ptr, | 566 | .iov_base = bytes.ptr, |
| 567 | .iov_len = bytes.len, | 567 | .iov_len = bytes.len, |
| ... | @@ -650,7 +650,7 @@ pub fn writev(fd: fd_t, iov: []const iovec_const) WriteError!void { | ... | @@ -650,7 +650,7 @@ pub fn writev(fd: fd_t, iov: []const iovec_const) WriteError!void { |
| 650 | /// On Windows, if the application has a global event loop enabled, I/O Completion Ports are | 650 | /// On Windows, if the application has a global event loop enabled, I/O Completion Ports are |
| 651 | /// used to perform the I/O. `error.WouldBlock` is not possible on Windows. | 651 | /// used to perform the I/O. `error.WouldBlock` is not possible on Windows. |
| 652 | pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) WriteError!void { | 652 | pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) WriteError!void { |
| 653 | if (comptime std.Target.current.isWindows()) { | 653 | if (std.Target.current.os.tag == .windows) { |
| 654 | return windows.WriteFile(fd, bytes, offset); | 654 | return windows.WriteFile(fd, bytes, offset); |
| 655 | } | 655 | } |
| 656 | 656 | ||
| ... | @@ -739,7 +739,7 @@ pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) WriteError!void | ... | @@ -739,7 +739,7 @@ pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) WriteError!void |
| 739 | } | 739 | } |
| 740 | } | 740 | } |
| 741 | 741 | ||
| 742 | if (comptime std.Target.current.isWindows()) { | 742 | if (std.Target.current.os.tag == .windows) { |
| 743 | var off = offset; | 743 | var off = offset; |
| 744 | for (iov) |item| { | 744 | for (iov) |item| { |
| 745 | try pwrite(fd, item.iov_base[0..item.iov_len], off); | 745 | try pwrite(fd, item.iov_base[0..item.iov_len], off); |
| ... | @@ -1129,7 +1129,7 @@ pub fn getenv(key: []const u8) ?[]const u8 { | ... | @@ -1129,7 +1129,7 @@ pub fn getenv(key: []const u8) ?[]const u8 { |
| 1129 | } | 1129 | } |
| 1130 | return null; | 1130 | return null; |
| 1131 | } | 1131 | } |
| 1132 | if (builtin.os == .windows) { | 1132 | if (builtin.os.tag == .windows) { |
| 1133 | @compileError("std.os.getenv is unavailable for Windows because environment string is in WTF-16 format. See std.process.getEnvVarOwned for cross-platform API or std.os.getenvW for Windows-specific API."); | 1133 | @compileError("std.os.getenv is unavailable for Windows because environment string is in WTF-16 format. See std.process.getEnvVarOwned for cross-platform API or std.os.getenvW for Windows-specific API."); |
| 1134 | } | 1134 | } |
| 1135 | // TODO see https://github.com/ziglang/zig/issues/4524 | 1135 | // TODO see https://github.com/ziglang/zig/issues/4524 |
| ... | @@ -1158,7 +1158,7 @@ pub fn getenvZ(key: [*:0]const u8) ?[]const u8 { | ... | @@ -1158,7 +1158,7 @@ pub fn getenvZ(key: [*:0]const u8) ?[]const u8 { |
| 1158 | const value = system.getenv(key) orelse return null; | 1158 | const value = system.getenv(key) orelse return null; |
| 1159 | return mem.toSliceConst(u8, value); | 1159 | return mem.toSliceConst(u8, value); |
| 1160 | } | 1160 | } |
| 1161 | if (builtin.os == .windows) { | 1161 | if (builtin.os.tag == .windows) { |
| 1162 | @compileError("std.os.getenvZ is unavailable for Windows because environment string is in WTF-16 format. See std.process.getEnvVarOwned for cross-platform API or std.os.getenvW for Windows-specific API."); | 1162 | @compileError("std.os.getenvZ is unavailable for Windows because environment string is in WTF-16 format. See std.process.getEnvVarOwned for cross-platform API or std.os.getenvW for Windows-specific API."); |
| 1163 | } | 1163 | } |
| 1164 | return getenv(mem.toSliceConst(u8, key)); | 1164 | return getenv(mem.toSliceConst(u8, key)); |
| ... | @@ -1167,7 +1167,7 @@ pub fn getenvZ(key: [*:0]const u8) ?[]const u8 { | ... | @@ -1167,7 +1167,7 @@ pub fn getenvZ(key: [*:0]const u8) ?[]const u8 { |
| 1167 | /// Windows-only. Get an environment variable with a null-terminated, WTF-16 encoded name. | 1167 | /// Windows-only. Get an environment variable with a null-terminated, WTF-16 encoded name. |
| 1168 | /// See also `getenv`. | 1168 | /// See also `getenv`. |
| 1169 | pub fn getenvW(key: [*:0]const u16) ?[:0]const u16 { | 1169 | pub fn getenvW(key: [*:0]const u16) ?[:0]const u16 { |
| 1170 | if (builtin.os != .windows) { | 1170 | if (builtin.os.tag != .windows) { |
| 1171 | @compileError("std.os.getenvW is a Windows-only API"); | 1171 | @compileError("std.os.getenvW is a Windows-only API"); |
| 1172 | } | 1172 | } |
| 1173 | const key_slice = mem.toSliceConst(u16, key); | 1173 | const key_slice = mem.toSliceConst(u16, key); |
| ... | @@ -1199,7 +1199,7 @@ pub const GetCwdError = error{ | ... | @@ -1199,7 +1199,7 @@ pub const GetCwdError = error{ |
| 1199 | 1199 | ||
| 1200 | /// The result is a slice of out_buffer, indexed from 0. | 1200 | /// The result is a slice of out_buffer, indexed from 0. |
| 1201 | pub fn getcwd(out_buffer: []u8) GetCwdError![]u8 { | 1201 | pub fn getcwd(out_buffer: []u8) GetCwdError![]u8 { |
| 1202 | if (builtin.os == .windows) { | 1202 | if (builtin.os.tag == .windows) { |
| 1203 | return windows.GetCurrentDirectory(out_buffer); | 1203 | return windows.GetCurrentDirectory(out_buffer); |
| 1204 | } | 1204 | } |
| 1205 | 1205 | ||
| ... | @@ -1240,7 +1240,7 @@ pub const SymLinkError = error{ | ... | @@ -1240,7 +1240,7 @@ pub const SymLinkError = error{ |
| 1240 | /// If `sym_link_path` exists, it will not be overwritten. | 1240 | /// If `sym_link_path` exists, it will not be overwritten. |
| 1241 | /// See also `symlinkC` and `symlinkW`. | 1241 | /// See also `symlinkC` and `symlinkW`. |
| 1242 | pub fn symlink(target_path: []const u8, sym_link_path: []const u8) SymLinkError!void { | 1242 | pub fn symlink(target_path: []const u8, sym_link_path: []const u8) SymLinkError!void { |
| 1243 | if (builtin.os == .windows) { | 1243 | if (builtin.os.tag == .windows) { |
| 1244 | const target_path_w = try windows.sliceToPrefixedFileW(target_path); | 1244 | const target_path_w = try windows.sliceToPrefixedFileW(target_path); |
| 1245 | const sym_link_path_w = try windows.sliceToPrefixedFileW(sym_link_path); | 1245 | const sym_link_path_w = try windows.sliceToPrefixedFileW(sym_link_path); |
| 1246 | return windows.CreateSymbolicLinkW(&sym_link_path_w, &target_path_w, 0); | 1246 | return windows.CreateSymbolicLinkW(&sym_link_path_w, &target_path_w, 0); |
| ... | @@ -1254,7 +1254,7 @@ pub fn symlink(target_path: []const u8, sym_link_path: []const u8) SymLinkError! | ... | @@ -1254,7 +1254,7 @@ pub fn symlink(target_path: []const u8, sym_link_path: []const u8) SymLinkError! |
| 1254 | /// This is the same as `symlink` except the parameters are null-terminated pointers. | 1254 | /// This is the same as `symlink` except the parameters are null-terminated pointers. |
| 1255 | /// See also `symlink`. | 1255 | /// See also `symlink`. |
| 1256 | pub fn symlinkC(target_path: [*:0]const u8, sym_link_path: [*:0]const u8) SymLinkError!void { | 1256 | pub fn symlinkC(target_path: [*:0]const u8, sym_link_path: [*:0]const u8) SymLinkError!void { |
| 1257 | if (builtin.os == .windows) { | 1257 | if (builtin.os.tag == .windows) { |
| 1258 | const target_path_w = try windows.cStrToPrefixedFileW(target_path); | 1258 | const target_path_w = try windows.cStrToPrefixedFileW(target_path); |
| 1259 | const sym_link_path_w = try windows.cStrToPrefixedFileW(sym_link_path); | 1259 | const sym_link_path_w = try windows.cStrToPrefixedFileW(sym_link_path); |
| 1260 | return windows.CreateSymbolicLinkW(&sym_link_path_w, &target_path_w, 0); | 1260 | return windows.CreateSymbolicLinkW(&sym_link_path_w, &target_path_w, 0); |
| ... | @@ -1329,7 +1329,7 @@ pub const UnlinkError = error{ | ... | @@ -1329,7 +1329,7 @@ pub const UnlinkError = error{ |
| 1329 | /// Delete a name and possibly the file it refers to. | 1329 | /// Delete a name and possibly the file it refers to. |
| 1330 | /// See also `unlinkC`. | 1330 | /// See also `unlinkC`. |
| 1331 | pub fn unlink(file_path: []const u8) UnlinkError!void { | 1331 | pub fn unlink(file_path: []const u8) UnlinkError!void { |
| 1332 | if (builtin.os == .windows) { | 1332 | if (builtin.os.tag == .windows) { |
| 1333 | const file_path_w = try windows.sliceToPrefixedFileW(file_path); | 1333 | const file_path_w = try windows.sliceToPrefixedFileW(file_path); |
| 1334 | return windows.DeleteFileW(&file_path_w); | 1334 | return windows.DeleteFileW(&file_path_w); |
| 1335 | } else { | 1335 | } else { |
| ... | @@ -1340,7 +1340,7 @@ pub fn unlink(file_path: []const u8) UnlinkError!void { | ... | @@ -1340,7 +1340,7 @@ pub fn unlink(file_path: []const u8) UnlinkError!void { |
| 1340 | 1340 | ||
| 1341 | /// Same as `unlink` except the parameter is a null terminated UTF8-encoded string. | 1341 | /// Same as `unlink` except the parameter is a null terminated UTF8-encoded string. |
| 1342 | pub fn unlinkC(file_path: [*:0]const u8) UnlinkError!void { | 1342 | pub fn unlinkC(file_path: [*:0]const u8) UnlinkError!void { |
| 1343 | if (builtin.os == .windows) { | 1343 | if (builtin.os.tag == .windows) { |
| 1344 | const file_path_w = try windows.cStrToPrefixedFileW(file_path); | 1344 | const file_path_w = try windows.cStrToPrefixedFileW(file_path); |
| 1345 | return windows.DeleteFileW(&file_path_w); | 1345 | return windows.DeleteFileW(&file_path_w); |
| 1346 | } | 1346 | } |
| ... | @@ -1372,7 +1372,7 @@ pub const UnlinkatError = UnlinkError || error{ | ... | @@ -1372,7 +1372,7 @@ pub const UnlinkatError = UnlinkError || error{ |
| 1372 | /// Asserts that the path parameter has no null bytes. | 1372 | /// Asserts that the path parameter has no null bytes. |
| 1373 | pub fn unlinkat(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatError!void { | 1373 | pub fn unlinkat(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatError!void { |
| 1374 | if (std.debug.runtime_safety) for (file_path) |byte| assert(byte != 0); | 1374 | if (std.debug.runtime_safety) for (file_path) |byte| assert(byte != 0); |
| 1375 | if (builtin.os == .windows) { | 1375 | if (builtin.os.tag == .windows) { |
| 1376 | const file_path_w = try windows.sliceToPrefixedFileW(file_path); | 1376 | const file_path_w = try windows.sliceToPrefixedFileW(file_path); |
| 1377 | return unlinkatW(dirfd, &file_path_w, flags); | 1377 | return unlinkatW(dirfd, &file_path_w, flags); |
| 1378 | } | 1378 | } |
| ... | @@ -1382,7 +1382,7 @@ pub fn unlinkat(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatError!vo | ... | @@ -1382,7 +1382,7 @@ pub fn unlinkat(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatError!vo |
| 1382 | 1382 | ||
| 1383 | /// Same as `unlinkat` but `file_path` is a null-terminated string. | 1383 | /// Same as `unlinkat` but `file_path` is a null-terminated string. |
| 1384 | pub fn unlinkatC(dirfd: fd_t, file_path_c: [*:0]const u8, flags: u32) UnlinkatError!void { | 1384 | pub fn unlinkatC(dirfd: fd_t, file_path_c: [*:0]const u8, flags: u32) UnlinkatError!void { |
| 1385 | if (builtin.os == .windows) { | 1385 | if (builtin.os.tag == .windows) { |
| 1386 | const file_path_w = try windows.cStrToPrefixedFileW(file_path_c); | 1386 | const file_path_w = try windows.cStrToPrefixedFileW(file_path_c); |
| 1387 | return unlinkatW(dirfd, &file_path_w, flags); | 1387 | return unlinkatW(dirfd, &file_path_w, flags); |
| 1388 | } | 1388 | } |
| ... | @@ -1493,7 +1493,7 @@ const RenameError = error{ | ... | @@ -1493,7 +1493,7 @@ const RenameError = error{ |
| 1493 | 1493 | ||
| 1494 | /// Change the name or location of a file. | 1494 | /// Change the name or location of a file. |
| 1495 | pub fn rename(old_path: []const u8, new_path: []const u8) RenameError!void { | 1495 | pub fn rename(old_path: []const u8, new_path: []const u8) RenameError!void { |
| 1496 | if (builtin.os == .windows) { | 1496 | if (builtin.os.tag == .windows) { |
| 1497 | const old_path_w = try windows.sliceToPrefixedFileW(old_path); | 1497 | const old_path_w = try windows.sliceToPrefixedFileW(old_path); |
| 1498 | const new_path_w = try windows.sliceToPrefixedFileW(new_path); | 1498 | const new_path_w = try windows.sliceToPrefixedFileW(new_path); |
| 1499 | return renameW(&old_path_w, &new_path_w); | 1499 | return renameW(&old_path_w, &new_path_w); |
| ... | @@ -1506,7 +1506,7 @@ pub fn rename(old_path: []const u8, new_path: []const u8) RenameError!void { | ... | @@ -1506,7 +1506,7 @@ pub fn rename(old_path: []const u8, new_path: []const u8) RenameError!void { |
| 1506 | 1506 | ||
| 1507 | /// Same as `rename` except the parameters are null-terminated byte arrays. | 1507 | /// Same as `rename` except the parameters are null-terminated byte arrays. |
| 1508 | pub fn renameC(old_path: [*:0]const u8, new_path: [*:0]const u8) RenameError!void { | 1508 | pub fn renameC(old_path: [*:0]const u8, new_path: [*:0]const u8) RenameError!void { |
| 1509 | if (builtin.os == .windows) { | 1509 | if (builtin.os.tag == .windows) { |
| 1510 | const old_path_w = try windows.cStrToPrefixedFileW(old_path); | 1510 | const old_path_w = try windows.cStrToPrefixedFileW(old_path); |
| 1511 | const new_path_w = try windows.cStrToPrefixedFileW(new_path); | 1511 | const new_path_w = try windows.cStrToPrefixedFileW(new_path); |
| 1512 | return renameW(&old_path_w, &new_path_w); | 1512 | return renameW(&old_path_w, &new_path_w); |
| ... | @@ -1561,7 +1561,7 @@ pub const MakeDirError = error{ | ... | @@ -1561,7 +1561,7 @@ pub const MakeDirError = error{ |
| 1561 | /// Create a directory. | 1561 | /// Create a directory. |
| 1562 | /// `mode` is ignored on Windows. | 1562 | /// `mode` is ignored on Windows. |
| 1563 | pub fn mkdir(dir_path: []const u8, mode: u32) MakeDirError!void { | 1563 | pub fn mkdir(dir_path: []const u8, mode: u32) MakeDirError!void { |
| 1564 | if (builtin.os == .windows) { | 1564 | if (builtin.os.tag == .windows) { |
| 1565 | const dir_path_w = try windows.sliceToPrefixedFileW(dir_path); | 1565 | const dir_path_w = try windows.sliceToPrefixedFileW(dir_path); |
| 1566 | return windows.CreateDirectoryW(&dir_path_w, null); | 1566 | return windows.CreateDirectoryW(&dir_path_w, null); |
| 1567 | } else { | 1567 | } else { |
| ... | @@ -1572,7 +1572,7 @@ pub fn mkdir(dir_path: []const u8, mode: u32) MakeDirError!void { | ... | @@ -1572,7 +1572,7 @@ pub fn mkdir(dir_path: []const u8, mode: u32) MakeDirError!void { |
| 1572 | 1572 | ||
| 1573 | /// Same as `mkdir` but the parameter is a null-terminated UTF8-encoded string. | 1573 | /// Same as `mkdir` but the parameter is a null-terminated UTF8-encoded string. |
| 1574 | pub fn mkdirC(dir_path: [*:0]const u8, mode: u32) MakeDirError!void { | 1574 | pub fn mkdirC(dir_path: [*:0]const u8, mode: u32) MakeDirError!void { |
| 1575 | if (builtin.os == .windows) { | 1575 | if (builtin.os.tag == .windows) { |
| 1576 | const dir_path_w = try windows.cStrToPrefixedFileW(dir_path); | 1576 | const dir_path_w = try windows.cStrToPrefixedFileW(dir_path); |
| 1577 | return windows.CreateDirectoryW(&dir_path_w, null); | 1577 | return windows.CreateDirectoryW(&dir_path_w, null); |
| 1578 | } | 1578 | } |
| ... | @@ -1611,7 +1611,7 @@ pub const DeleteDirError = error{ | ... | @@ -1611,7 +1611,7 @@ pub const DeleteDirError = error{ |
| 1611 | 1611 | ||
| 1612 | /// Deletes an empty directory. | 1612 | /// Deletes an empty directory. |
| 1613 | pub fn rmdir(dir_path: []const u8) DeleteDirError!void { | 1613 | pub fn rmdir(dir_path: []const u8) DeleteDirError!void { |
| 1614 | if (builtin.os == .windows) { | 1614 | if (builtin.os.tag == .windows) { |
| 1615 | const dir_path_w = try windows.sliceToPrefixedFileW(dir_path); | 1615 | const dir_path_w = try windows.sliceToPrefixedFileW(dir_path); |
| 1616 | return windows.RemoveDirectoryW(&dir_path_w); | 1616 | return windows.RemoveDirectoryW(&dir_path_w); |
| 1617 | } else { | 1617 | } else { |
| ... | @@ -1622,7 +1622,7 @@ pub fn rmdir(dir_path: []const u8) DeleteDirError!void { | ... | @@ -1622,7 +1622,7 @@ pub fn rmdir(dir_path: []const u8) DeleteDirError!void { |
| 1622 | 1622 | ||
| 1623 | /// Same as `rmdir` except the parameter is null-terminated. | 1623 | /// Same as `rmdir` except the parameter is null-terminated. |
| 1624 | pub fn rmdirC(dir_path: [*:0]const u8) DeleteDirError!void { | 1624 | pub fn rmdirC(dir_path: [*:0]const u8) DeleteDirError!void { |
| 1625 | if (builtin.os == .windows) { | 1625 | if (builtin.os.tag == .windows) { |
| 1626 | const dir_path_w = try windows.cStrToPrefixedFileW(dir_path); | 1626 | const dir_path_w = try windows.cStrToPrefixedFileW(dir_path); |
| 1627 | return windows.RemoveDirectoryW(&dir_path_w); | 1627 | return windows.RemoveDirectoryW(&dir_path_w); |
| 1628 | } | 1628 | } |
| ... | @@ -1658,7 +1658,7 @@ pub const ChangeCurDirError = error{ | ... | @@ -1658,7 +1658,7 @@ pub const ChangeCurDirError = error{ |
| 1658 | /// Changes the current working directory of the calling process. | 1658 | /// Changes the current working directory of the calling process. |
| 1659 | /// `dir_path` is recommended to be a UTF-8 encoded string. | 1659 | /// `dir_path` is recommended to be a UTF-8 encoded string. |
| 1660 | pub fn chdir(dir_path: []const u8) ChangeCurDirError!void { | 1660 | pub fn chdir(dir_path: []const u8) ChangeCurDirError!void { |
| 1661 | if (builtin.os == .windows) { | 1661 | if (builtin.os.tag == .windows) { |
| 1662 | const dir_path_w = try windows.sliceToPrefixedFileW(dir_path); | 1662 | const dir_path_w = try windows.sliceToPrefixedFileW(dir_path); |
| 1663 | @compileError("TODO implement chdir for Windows"); | 1663 | @compileError("TODO implement chdir for Windows"); |
| 1664 | } else { | 1664 | } else { |
| ... | @@ -1669,7 +1669,7 @@ pub fn chdir(dir_path: []const u8) ChangeCurDirError!void { | ... | @@ -1669,7 +1669,7 @@ pub fn chdir(dir_path: []const u8) ChangeCurDirError!void { |
| 1669 | 1669 | ||
| 1670 | /// Same as `chdir` except the parameter is null-terminated. | 1670 | /// Same as `chdir` except the parameter is null-terminated. |
| 1671 | pub fn chdirC(dir_path: [*:0]const u8) ChangeCurDirError!void { | 1671 | pub fn chdirC(dir_path: [*:0]const u8) ChangeCurDirError!void { |
| 1672 | if (builtin.os == .windows) { | 1672 | if (builtin.os.tag == .windows) { |
| 1673 | const dir_path_w = try windows.cStrToPrefixedFileW(dir_path); | 1673 | const dir_path_w = try windows.cStrToPrefixedFileW(dir_path); |
| 1674 | @compileError("TODO implement chdir for Windows"); | 1674 | @compileError("TODO implement chdir for Windows"); |
| 1675 | } | 1675 | } |
| ... | @@ -1700,7 +1700,7 @@ pub const ReadLinkError = error{ | ... | @@ -1700,7 +1700,7 @@ pub const ReadLinkError = error{ |
| 1700 | /// Read value of a symbolic link. | 1700 | /// Read value of a symbolic link. |
| 1701 | /// The return value is a slice of `out_buffer` from index 0. | 1701 | /// The return value is a slice of `out_buffer` from index 0. |
| 1702 | pub fn readlink(file_path: []const u8, out_buffer: []u8) ReadLinkError![]u8 { | 1702 | pub fn readlink(file_path: []const u8, out_buffer: []u8) ReadLinkError![]u8 { |
| 1703 | if (builtin.os == .windows) { | 1703 | if (builtin.os.tag == .windows) { |
| 1704 | const file_path_w = try windows.sliceToPrefixedFileW(file_path); | 1704 | const file_path_w = try windows.sliceToPrefixedFileW(file_path); |
| 1705 | @compileError("TODO implement readlink for Windows"); | 1705 | @compileError("TODO implement readlink for Windows"); |
| 1706 | } else { | 1706 | } else { |
| ... | @@ -1711,7 +1711,7 @@ pub fn readlink(file_path: []const u8, out_buffer: []u8) ReadLinkError![]u8 { | ... | @@ -1711,7 +1711,7 @@ pub fn readlink(file_path: []const u8, out_buffer: []u8) ReadLinkError![]u8 { |
| 1711 | 1711 | ||
| 1712 | /// Same as `readlink` except `file_path` is null-terminated. | 1712 | /// Same as `readlink` except `file_path` is null-terminated. |
| 1713 | pub fn readlinkC(file_path: [*:0]const u8, out_buffer: []u8) ReadLinkError![]u8 { | 1713 | pub fn readlinkC(file_path: [*:0]const u8, out_buffer: []u8) ReadLinkError![]u8 { |
| 1714 | if (builtin.os == .windows) { | 1714 | if (builtin.os.tag == .windows) { |
| 1715 | const file_path_w = try windows.cStrToPrefixedFileW(file_path); | 1715 | const file_path_w = try windows.cStrToPrefixedFileW(file_path); |
| 1716 | @compileError("TODO implement readlink for Windows"); | 1716 | @compileError("TODO implement readlink for Windows"); |
| 1717 | } | 1717 | } |
| ... | @@ -1732,7 +1732,7 @@ pub fn readlinkC(file_path: [*:0]const u8, out_buffer: []u8) ReadLinkError![]u8 | ... | @@ -1732,7 +1732,7 @@ pub fn readlinkC(file_path: [*:0]const u8, out_buffer: []u8) ReadLinkError![]u8 |
| 1732 | } | 1732 | } |
| 1733 | 1733 | ||
| 1734 | pub fn readlinkatC(dirfd: fd_t, file_path: [*:0]const u8, out_buffer: []u8) ReadLinkError![]u8 { | 1734 | pub fn readlinkatC(dirfd: fd_t, file_path: [*:0]const u8, out_buffer: []u8) ReadLinkError![]u8 { |
| 1735 | if (builtin.os == .windows) { | 1735 | if (builtin.os.tag == .windows) { |
| 1736 | const file_path_w = try windows.cStrToPrefixedFileW(file_path); | 1736 | const file_path_w = try windows.cStrToPrefixedFileW(file_path); |
| 1737 | @compileError("TODO implement readlink for Windows"); | 1737 | @compileError("TODO implement readlink for Windows"); |
| 1738 | } | 1738 | } |
| ... | @@ -1800,7 +1800,7 @@ pub fn setregid(rgid: u32, egid: u32) SetIdError!void { | ... | @@ -1800,7 +1800,7 @@ pub fn setregid(rgid: u32, egid: u32) SetIdError!void { |
| 1800 | 1800 | ||
| 1801 | /// Test whether a file descriptor refers to a terminal. | 1801 | /// Test whether a file descriptor refers to a terminal. |
| 1802 | pub fn isatty(handle: fd_t) bool { | 1802 | pub fn isatty(handle: fd_t) bool { |
| 1803 | if (builtin.os == .windows) { | 1803 | if (builtin.os.tag == .windows) { |
| 1804 | if (isCygwinPty(handle)) | 1804 | if (isCygwinPty(handle)) |
| 1805 | return true; | 1805 | return true; |
| 1806 | 1806 | ||
| ... | @@ -1810,7 +1810,7 @@ pub fn isatty(handle: fd_t) bool { | ... | @@ -1810,7 +1810,7 @@ pub fn isatty(handle: fd_t) bool { |
| 1810 | if (builtin.link_libc) { | 1810 | if (builtin.link_libc) { |
| 1811 | return system.isatty(handle) != 0; | 1811 | return system.isatty(handle) != 0; |
| 1812 | } | 1812 | } |
| 1813 | if (builtin.os == .wasi) { | 1813 | if (builtin.os.tag == .wasi) { |
| 1814 | var statbuf: fdstat_t = undefined; | 1814 | var statbuf: fdstat_t = undefined; |
| 1815 | const err = system.fd_fdstat_get(handle, &statbuf); | 1815 | const err = system.fd_fdstat_get(handle, &statbuf); |
| 1816 | if (err != 0) { | 1816 | if (err != 0) { |
| ... | @@ -1828,7 +1828,7 @@ pub fn isatty(handle: fd_t) bool { | ... | @@ -1828,7 +1828,7 @@ pub fn isatty(handle: fd_t) bool { |
| 1828 | 1828 | ||
| 1829 | return true; | 1829 | return true; |
| 1830 | } | 1830 | } |
| 1831 | if (builtin.os == .linux) { | 1831 | if (builtin.os.tag == .linux) { |
| 1832 | var wsz: linux.winsize = undefined; | 1832 | var wsz: linux.winsize = undefined; |
| 1833 | return linux.syscall3(linux.SYS_ioctl, @bitCast(usize, @as(isize, handle)), linux.TIOCGWINSZ, @ptrToInt(&wsz)) == 0; | 1833 | return linux.syscall3(linux.SYS_ioctl, @bitCast(usize, @as(isize, handle)), linux.TIOCGWINSZ, @ptrToInt(&wsz)) == 0; |
| 1834 | } | 1834 | } |
| ... | @@ -1836,7 +1836,7 @@ pub fn isatty(handle: fd_t) bool { | ... | @@ -1836,7 +1836,7 @@ pub fn isatty(handle: fd_t) bool { |
| 1836 | } | 1836 | } |
| 1837 | 1837 | ||
| 1838 | pub fn isCygwinPty(handle: fd_t) bool { | 1838 | pub fn isCygwinPty(handle: fd_t) bool { |
| 1839 | if (builtin.os != .windows) return false; | 1839 | if (builtin.os.tag != .windows) return false; |
| 1840 | 1840 | ||
| 1841 | const size = @sizeOf(windows.FILE_NAME_INFO); | 1841 | const size = @sizeOf(windows.FILE_NAME_INFO); |
| 1842 | var name_info_bytes align(@alignOf(windows.FILE_NAME_INFO)) = [_]u8{0} ** (size + windows.MAX_PATH); | 1842 | var name_info_bytes align(@alignOf(windows.FILE_NAME_INFO)) = [_]u8{0} ** (size + windows.MAX_PATH); |
| ... | @@ -2589,7 +2589,7 @@ pub const AccessError = error{ | ... | @@ -2589,7 +2589,7 @@ pub const AccessError = error{ |
| 2589 | /// check user's permissions for a file | 2589 | /// check user's permissions for a file |
| 2590 | /// TODO currently this assumes `mode` is `F_OK` on Windows. | 2590 | /// TODO currently this assumes `mode` is `F_OK` on Windows. |
| 2591 | pub fn access(path: []const u8, mode: u32) AccessError!void { | 2591 | pub fn access(path: []const u8, mode: u32) AccessError!void { |
| 2592 | if (builtin.os == .windows) { | 2592 | if (builtin.os.tag == .windows) { |
| 2593 | const path_w = try windows.sliceToPrefixedFileW(path); | 2593 | const path_w = try windows.sliceToPrefixedFileW(path); |
| 2594 | _ = try windows.GetFileAttributesW(&path_w); | 2594 | _ = try windows.GetFileAttributesW(&path_w); |
| 2595 | return; | 2595 | return; |
| ... | @@ -2603,7 +2603,7 @@ pub const accessC = accessZ; | ... | @@ -2603,7 +2603,7 @@ pub const accessC = accessZ; |
| 2603 | 2603 | ||
| 2604 | /// Same as `access` except `path` is null-terminated. | 2604 | /// Same as `access` except `path` is null-terminated. |
| 2605 | pub fn accessZ(path: [*:0]const u8, mode: u32) AccessError!void { | 2605 | pub fn accessZ(path: [*:0]const u8, mode: u32) AccessError!void { |
| 2606 | if (builtin.os == .windows) { | 2606 | if (builtin.os.tag == .windows) { |
| 2607 | const path_w = try windows.cStrToPrefixedFileW(path); | 2607 | const path_w = try windows.cStrToPrefixedFileW(path); |
| 2608 | _ = try windows.GetFileAttributesW(&path_w); | 2608 | _ = try windows.GetFileAttributesW(&path_w); |
| 2609 | return; | 2609 | return; |
| ... | @@ -2644,7 +2644,7 @@ pub fn accessW(path: [*:0]const u16, mode: u32) windows.GetFileAttributesError!v | ... | @@ -2644,7 +2644,7 @@ pub fn accessW(path: [*:0]const u16, mode: u32) windows.GetFileAttributesError!v |
| 2644 | /// Check user's permissions for a file, based on an open directory handle. | 2644 | /// Check user's permissions for a file, based on an open directory handle. |
| 2645 | /// TODO currently this ignores `mode` and `flags` on Windows. | 2645 | /// TODO currently this ignores `mode` and `flags` on Windows. |
| 2646 | pub fn faccessat(dirfd: fd_t, path: []const u8, mode: u32, flags: u32) AccessError!void { | 2646 | pub fn faccessat(dirfd: fd_t, path: []const u8, mode: u32, flags: u32) AccessError!void { |
| 2647 | if (builtin.os == .windows) { | 2647 | if (builtin.os.tag == .windows) { |
| 2648 | const path_w = try windows.sliceToPrefixedFileW(path); | 2648 | const path_w = try windows.sliceToPrefixedFileW(path); |
| 2649 | return faccessatW(dirfd, &path_w, mode, flags); | 2649 | return faccessatW(dirfd, &path_w, mode, flags); |
| 2650 | } | 2650 | } |
| ... | @@ -2654,7 +2654,7 @@ pub fn faccessat(dirfd: fd_t, path: []const u8, mode: u32, flags: u32) AccessErr | ... | @@ -2654,7 +2654,7 @@ pub fn faccessat(dirfd: fd_t, path: []const u8, mode: u32, flags: u32) AccessErr |
| 2654 | 2654 | ||
| 2655 | /// Same as `faccessat` except the path parameter is null-terminated. | 2655 | /// Same as `faccessat` except the path parameter is null-terminated. |
| 2656 | pub fn faccessatZ(dirfd: fd_t, path: [*:0]const u8, mode: u32, flags: u32) AccessError!void { | 2656 | pub fn faccessatZ(dirfd: fd_t, path: [*:0]const u8, mode: u32, flags: u32) AccessError!void { |
| 2657 | if (builtin.os == .windows) { | 2657 | if (builtin.os.tag == .windows) { |
| 2658 | const path_w = try windows.cStrToPrefixedFileW(path); | 2658 | const path_w = try windows.cStrToPrefixedFileW(path); |
| 2659 | return faccessatW(dirfd, &path_w, mode, flags); | 2659 | return faccessatW(dirfd, &path_w, mode, flags); |
| 2660 | } | 2660 | } |
| ... | @@ -2811,7 +2811,7 @@ pub const SeekError = error{Unseekable} || UnexpectedError; | ... | @@ -2811,7 +2811,7 @@ pub const SeekError = error{Unseekable} || UnexpectedError; |
| 2811 | 2811 | ||
| 2812 | /// Repositions read/write file offset relative to the beginning. | 2812 | /// Repositions read/write file offset relative to the beginning. |
| 2813 | pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void { | 2813 | pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void { |
| 2814 | if (builtin.os == .linux and !builtin.link_libc and @sizeOf(usize) == 4) { | 2814 | if (builtin.os.tag == .linux and !builtin.link_libc and @sizeOf(usize) == 4) { |
| 2815 | var result: u64 = undefined; | 2815 | var result: u64 = undefined; |
| 2816 | switch (errno(system.llseek(fd, offset, &result, SEEK_SET))) { | 2816 | switch (errno(system.llseek(fd, offset, &result, SEEK_SET))) { |
| 2817 | 0 => return, | 2817 | 0 => return, |
| ... | @@ -2823,7 +2823,7 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void { | ... | @@ -2823,7 +2823,7 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void { |
| 2823 | else => |err| return unexpectedErrno(err), | 2823 | else => |err| return unexpectedErrno(err), |
| 2824 | } | 2824 | } |
| 2825 | } | 2825 | } |
| 2826 | if (builtin.os == .windows) { | 2826 | if (builtin.os.tag == .windows) { |
| 2827 | return windows.SetFilePointerEx_BEGIN(fd, offset); | 2827 | return windows.SetFilePointerEx_BEGIN(fd, offset); |
| 2828 | } | 2828 | } |
| 2829 | const ipos = @bitCast(i64, offset); // the OS treats this as unsigned | 2829 | const ipos = @bitCast(i64, offset); // the OS treats this as unsigned |
| ... | @@ -2840,7 +2840,7 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void { | ... | @@ -2840,7 +2840,7 @@ pub fn lseek_SET(fd: fd_t, offset: u64) SeekError!void { |
| 2840 | 2840 | ||
| 2841 | /// Repositions read/write file offset relative to the current offset. | 2841 | /// Repositions read/write file offset relative to the current offset. |
| 2842 | pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void { | 2842 | pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void { |
| 2843 | if (builtin.os == .linux and !builtin.link_libc and @sizeOf(usize) == 4) { | 2843 | if (builtin.os.tag == .linux and !builtin.link_libc and @sizeOf(usize) == 4) { |
| 2844 | var result: u64 = undefined; | 2844 | var result: u64 = undefined; |
| 2845 | switch (errno(system.llseek(fd, @bitCast(u64, offset), &result, SEEK_CUR))) { | 2845 | switch (errno(system.llseek(fd, @bitCast(u64, offset), &result, SEEK_CUR))) { |
| 2846 | 0 => return, | 2846 | 0 => return, |
| ... | @@ -2852,7 +2852,7 @@ pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void { | ... | @@ -2852,7 +2852,7 @@ pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void { |
| 2852 | else => |err| return unexpectedErrno(err), | 2852 | else => |err| return unexpectedErrno(err), |
| 2853 | } | 2853 | } |
| 2854 | } | 2854 | } |
| 2855 | if (builtin.os == .windows) { | 2855 | if (builtin.os.tag == .windows) { |
| 2856 | return windows.SetFilePointerEx_CURRENT(fd, offset); | 2856 | return windows.SetFilePointerEx_CURRENT(fd, offset); |
| 2857 | } | 2857 | } |
| 2858 | switch (errno(system.lseek(fd, offset, SEEK_CUR))) { | 2858 | switch (errno(system.lseek(fd, offset, SEEK_CUR))) { |
| ... | @@ -2868,7 +2868,7 @@ pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void { | ... | @@ -2868,7 +2868,7 @@ pub fn lseek_CUR(fd: fd_t, offset: i64) SeekError!void { |
| 2868 | 2868 | ||
| 2869 | /// Repositions read/write file offset relative to the end. | 2869 | /// Repositions read/write file offset relative to the end. |
| 2870 | pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void { | 2870 | pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void { |
| 2871 | if (builtin.os == .linux and !builtin.link_libc and @sizeOf(usize) == 4) { | 2871 | if (builtin.os.tag == .linux and !builtin.link_libc and @sizeOf(usize) == 4) { |
| 2872 | var result: u64 = undefined; | 2872 | var result: u64 = undefined; |
| 2873 | switch (errno(system.llseek(fd, @bitCast(u64, offset), &result, SEEK_END))) { | 2873 | switch (errno(system.llseek(fd, @bitCast(u64, offset), &result, SEEK_END))) { |
| 2874 | 0 => return, | 2874 | 0 => return, |
| ... | @@ -2880,7 +2880,7 @@ pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void { | ... | @@ -2880,7 +2880,7 @@ pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void { |
| 2880 | else => |err| return unexpectedErrno(err), | 2880 | else => |err| return unexpectedErrno(err), |
| 2881 | } | 2881 | } |
| 2882 | } | 2882 | } |
| 2883 | if (builtin.os == .windows) { | 2883 | if (builtin.os.tag == .windows) { |
| 2884 | return windows.SetFilePointerEx_END(fd, offset); | 2884 | return windows.SetFilePointerEx_END(fd, offset); |
| 2885 | } | 2885 | } |
| 2886 | switch (errno(system.lseek(fd, offset, SEEK_END))) { | 2886 | switch (errno(system.lseek(fd, offset, SEEK_END))) { |
| ... | @@ -2896,7 +2896,7 @@ pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void { | ... | @@ -2896,7 +2896,7 @@ pub fn lseek_END(fd: fd_t, offset: i64) SeekError!void { |
| 2896 | 2896 | ||
| 2897 | /// Returns the read/write file offset relative to the beginning. | 2897 | /// Returns the read/write file offset relative to the beginning. |
| 2898 | pub fn lseek_CUR_get(fd: fd_t) SeekError!u64 { | 2898 | pub fn lseek_CUR_get(fd: fd_t) SeekError!u64 { |
| 2899 | if (builtin.os == .linux and !builtin.link_libc and @sizeOf(usize) == 4) { | 2899 | if (builtin.os.tag == .linux and !builtin.link_libc and @sizeOf(usize) == 4) { |
| 2900 | var result: u64 = undefined; | 2900 | var result: u64 = undefined; |
| 2901 | switch (errno(system.llseek(fd, 0, &result, SEEK_CUR))) { | 2901 | switch (errno(system.llseek(fd, 0, &result, SEEK_CUR))) { |
| 2902 | 0 => return result, | 2902 | 0 => return result, |
| ... | @@ -2908,7 +2908,7 @@ pub fn lseek_CUR_get(fd: fd_t) SeekError!u64 { | ... | @@ -2908,7 +2908,7 @@ pub fn lseek_CUR_get(fd: fd_t) SeekError!u64 { |
| 2908 | else => |err| return unexpectedErrno(err), | 2908 | else => |err| return unexpectedErrno(err), |
| 2909 | } | 2909 | } |
| 2910 | } | 2910 | } |
| 2911 | if (builtin.os == .windows) { | 2911 | if (builtin.os.tag == .windows) { |
| 2912 | return windows.SetFilePointerEx_CURRENT_get(fd); | 2912 | return windows.SetFilePointerEx_CURRENT_get(fd); |
| 2913 | } | 2913 | } |
| 2914 | const rc = system.lseek(fd, 0, SEEK_CUR); | 2914 | const rc = system.lseek(fd, 0, SEEK_CUR); |
| ... | @@ -2957,7 +2957,7 @@ pub const RealPathError = error{ | ... | @@ -2957,7 +2957,7 @@ pub const RealPathError = error{ |
| 2957 | /// The return value is a slice of `out_buffer`, but not necessarily from the beginning. | 2957 | /// The return value is a slice of `out_buffer`, but not necessarily from the beginning. |
| 2958 | /// See also `realpathC` and `realpathW`. | 2958 | /// See also `realpathC` and `realpathW`. |
| 2959 | pub fn realpath(pathname: []const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 { | 2959 | pub fn realpath(pathname: []const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 { |
| 2960 | if (builtin.os == .windows) { | 2960 | if (builtin.os.tag == .windows) { |
| 2961 | const pathname_w = try windows.sliceToPrefixedFileW(pathname); | 2961 | const pathname_w = try windows.sliceToPrefixedFileW(pathname); |
| 2962 | return realpathW(&pathname_w, out_buffer); | 2962 | return realpathW(&pathname_w, out_buffer); |
| 2963 | } | 2963 | } |
| ... | @@ -2967,11 +2967,11 @@ pub fn realpath(pathname: []const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathE | ... | @@ -2967,11 +2967,11 @@ pub fn realpath(pathname: []const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathE |
| 2967 | 2967 | ||
| 2968 | /// Same as `realpath` except `pathname` is null-terminated. | 2968 | /// Same as `realpath` except `pathname` is null-terminated. |
| 2969 | pub fn realpathC(pathname: [*:0]const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 { | 2969 | pub fn realpathC(pathname: [*:0]const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 { |
| 2970 | if (builtin.os == .windows) { | 2970 | if (builtin.os.tag == .windows) { |
| 2971 | const pathname_w = try windows.cStrToPrefixedFileW(pathname); | 2971 | const pathname_w = try windows.cStrToPrefixedFileW(pathname); |
| 2972 | return realpathW(&pathname_w, out_buffer); | 2972 | return realpathW(&pathname_w, out_buffer); |
| 2973 | } | 2973 | } |
| 2974 | if (builtin.os == .linux and !builtin.link_libc) { | 2974 | if (builtin.os.tag == .linux and !builtin.link_libc) { |
| 2975 | const fd = try openC(pathname, linux.O_PATH | linux.O_NONBLOCK | linux.O_CLOEXEC, 0); | 2975 | const fd = try openC(pathname, linux.O_PATH | linux.O_NONBLOCK | linux.O_CLOEXEC, 0); |
| 2976 | defer close(fd); | 2976 | defer close(fd); |
| 2977 | 2977 | ||
| ... | @@ -3121,7 +3121,7 @@ pub fn dl_iterate_phdr( | ... | @@ -3121,7 +3121,7 @@ pub fn dl_iterate_phdr( |
| 3121 | pub const ClockGetTimeError = error{UnsupportedClock} || UnexpectedError; | 3121 | pub const ClockGetTimeError = error{UnsupportedClock} || UnexpectedError; |
| 3122 | 3122 | ||
| 3123 | pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void { | 3123 | pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void { |
| 3124 | if (comptime std.Target.current.getOs() == .wasi) { | 3124 | if (std.Target.current.os.tag == .wasi) { |
| 3125 | var ts: timestamp_t = undefined; | 3125 | var ts: timestamp_t = undefined; |
| 3126 | switch (system.clock_time_get(@bitCast(u32, clk_id), 1, &ts)) { | 3126 | switch (system.clock_time_get(@bitCast(u32, clk_id), 1, &ts)) { |
| 3127 | 0 => { | 3127 | 0 => { |
| ... | @@ -3144,7 +3144,7 @@ pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void { | ... | @@ -3144,7 +3144,7 @@ pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void { |
| 3144 | } | 3144 | } |
| 3145 | 3145 | ||
| 3146 | pub fn clock_getres(clk_id: i32, res: *timespec) ClockGetTimeError!void { | 3146 | pub fn clock_getres(clk_id: i32, res: *timespec) ClockGetTimeError!void { |
| 3147 | if (comptime std.Target.current.getOs() == .wasi) { | 3147 | if (std.Target.current.os.tag == .wasi) { |
| 3148 | var ts: timestamp_t = undefined; | 3148 | var ts: timestamp_t = undefined; |
| 3149 | switch (system.clock_res_get(@bitCast(u32, clk_id), &ts)) { | 3149 | switch (system.clock_res_get(@bitCast(u32, clk_id), &ts)) { |
| 3150 | 0 => res.* = .{ | 3150 | 0 => res.* = .{ |
| ... | @@ -3222,7 +3222,7 @@ pub const SigaltstackError = error{ | ... | @@ -3222,7 +3222,7 @@ pub const SigaltstackError = error{ |
| 3222 | } || UnexpectedError; | 3222 | } || UnexpectedError; |
| 3223 | 3223 | ||
| 3224 | pub fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) SigaltstackError!void { | 3224 | pub fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) SigaltstackError!void { |
| 3225 | if (builtin.os == .windows or builtin.os == .uefi or builtin.os == .wasi) | 3225 | if (builtin.os.tag == .windows or builtin.os.tag == .uefi or builtin.os.tag == .wasi) |
| 3226 | @compileError("std.os.sigaltstack not available for this target"); | 3226 | @compileError("std.os.sigaltstack not available for this target"); |
| 3227 | 3227 | ||
| 3228 | switch (errno(system.sigaltstack(ss, old_ss))) { | 3228 | switch (errno(system.sigaltstack(ss, old_ss))) { |
| ... | @@ -3294,23 +3294,25 @@ pub fn gethostname(name_buffer: *[HOST_NAME_MAX]u8) GetHostNameError![]u8 { | ... | @@ -3294,23 +3294,25 @@ pub fn gethostname(name_buffer: *[HOST_NAME_MAX]u8) GetHostNameError![]u8 { |
| 3294 | else => |err| return unexpectedErrno(err), | 3294 | else => |err| return unexpectedErrno(err), |
| 3295 | } | 3295 | } |
| 3296 | } | 3296 | } |
| 3297 | if (builtin.os == .linux) { | 3297 | if (builtin.os.tag == .linux) { |
| 3298 | var uts: utsname = undefined; | 3298 | const uts = uname(); |
| 3299 | switch (errno(system.uname(&uts))) { | 3299 | const hostname = mem.toSliceConst(u8, @ptrCast([*:0]const u8, &uts.nodename)); |
| 3300 | 0 => { | 3300 | mem.copy(u8, name_buffer, hostname); |
| 3301 | const hostname = mem.toSlice(u8, @ptrCast([*:0]u8, &uts.nodename)); | 3301 | return name_buffer[0..hostname.len]; |
| 3302 | mem.copy(u8, name_buffer, hostname); | ||
| 3303 | return name_buffer[0..hostname.len]; | ||
| 3304 | }, | ||
| 3305 | EFAULT => unreachable, | ||
| 3306 | EPERM => return error.PermissionDenied, | ||
| 3307 | else => |err| return unexpectedErrno(err), | ||
| 3308 | } | ||
| 3309 | } | 3302 | } |
| 3310 | 3303 | ||
| 3311 | @compileError("TODO implement gethostname for this OS"); | 3304 | @compileError("TODO implement gethostname for this OS"); |
| 3312 | } | 3305 | } |
| 3313 | 3306 | ||
| 3307 | pub fn uname() utsname { | ||
| 3308 | var uts: utsname = undefined; | ||
| 3309 | switch (errno(system.uname(&uts))) { | ||
| 3310 | 0 => return uts, | ||
| 3311 | EFAULT => unreachable, | ||
| 3312 | else => unreachable, | ||
| 3313 | } | ||
| 3314 | } | ||
| 3315 | |||
| 3314 | pub fn res_mkquery( | 3316 | pub fn res_mkquery( |
| 3315 | op: u4, | 3317 | op: u4, |
| 3316 | dname: []const u8, | 3318 | dname: []const u8, |
| ... | @@ -3611,7 +3613,7 @@ pub const SchedYieldError = error{ | ... | @@ -3611,7 +3613,7 @@ pub const SchedYieldError = error{ |
| 3611 | }; | 3613 | }; |
| 3612 | 3614 | ||
| 3613 | pub fn sched_yield() SchedYieldError!void { | 3615 | pub fn sched_yield() SchedYieldError!void { |
| 3614 | if (builtin.os == .windows) { | 3616 | if (builtin.os.tag == .windows) { |
| 3615 | // The return value has to do with how many other threads there are; it is not | 3617 | // The return value has to do with how many other threads there are; it is not |
| 3616 | // an error condition on Windows. | 3618 | // an error condition on Windows. |
| 3617 | _ = windows.kernel32.SwitchToThread(); | 3619 | _ = windows.kernel32.SwitchToThread(); |
lib/std/os/bits.zig+2-2| ... | @@ -3,10 +3,10 @@ | ... | @@ -3,10 +3,10 @@ |
| 3 | //! Root source files can define `os.bits` and these will additionally be added | 3 | //! Root source files can define `os.bits` and these will additionally be added |
| 4 | //! to the namespace. | 4 | //! to the namespace. |
| 5 | 5 | ||
| 6 | const builtin = @import("builtin"); | 6 | const std = @import("std"); |
| 7 | const root = @import("root"); | 7 | const root = @import("root"); |
| 8 | 8 | ||
| 9 | pub usingnamespace switch (builtin.os) { | 9 | pub usingnamespace switch (std.Target.current.os.tag) { |
| 10 | .macosx, .ios, .tvos, .watchos => @import("bits/darwin.zig"), | 10 | .macosx, .ios, .tvos, .watchos => @import("bits/darwin.zig"), |
| 11 | .dragonfly => @import("bits/dragonfly.zig"), | 11 | .dragonfly => @import("bits/dragonfly.zig"), |
| 12 | .freebsd => @import("bits/freebsd.zig"), | 12 | .freebsd => @import("bits/freebsd.zig"), |
lib/std/os/linux.zig+1-1| ... | @@ -1070,7 +1070,7 @@ pub fn tcsetattr(fd: fd_t, optional_action: TCSA, termios_p: *const termios) usi | ... | @@ -1070,7 +1070,7 @@ pub fn tcsetattr(fd: fd_t, optional_action: TCSA, termios_p: *const termios) usi |
| 1070 | } | 1070 | } |
| 1071 | 1071 | ||
| 1072 | test "" { | 1072 | test "" { |
| 1073 | if (builtin.os == .linux) { | 1073 | if (builtin.os.tag == .linux) { |
| 1074 | _ = @import("linux/test.zig"); | 1074 | _ = @import("linux/test.zig"); |
| 1075 | } | 1075 | } |
| 1076 | } | 1076 | } |
lib/std/os/test.zig+8-8| ... | @@ -53,7 +53,7 @@ test "std.Thread.getCurrentId" { | ... | @@ -53,7 +53,7 @@ test "std.Thread.getCurrentId" { |
| 53 | thread.wait(); | 53 | thread.wait(); |
| 54 | if (Thread.use_pthreads) { | 54 | if (Thread.use_pthreads) { |
| 55 | expect(thread_current_id == thread_id); | 55 | expect(thread_current_id == thread_id); |
| 56 | } else if (builtin.os == .windows) { | 56 | } else if (builtin.os.tag == .windows) { |
| 57 | expect(Thread.getCurrentId() != thread_current_id); | 57 | expect(Thread.getCurrentId() != thread_current_id); |
| 58 | } else { | 58 | } else { |
| 59 | // If the thread completes very quickly, then thread_id can be 0. See the | 59 | // If the thread completes very quickly, then thread_id can be 0. See the |
| ... | @@ -151,7 +151,7 @@ test "realpath" { | ... | @@ -151,7 +151,7 @@ test "realpath" { |
| 151 | } | 151 | } |
| 152 | 152 | ||
| 153 | test "sigaltstack" { | 153 | test "sigaltstack" { |
| 154 | if (builtin.os == .windows or builtin.os == .wasi) return error.SkipZigTest; | 154 | if (builtin.os.tag == .windows or builtin.os.tag == .wasi) return error.SkipZigTest; |
| 155 | 155 | ||
| 156 | var st: os.stack_t = undefined; | 156 | var st: os.stack_t = undefined; |
| 157 | try os.sigaltstack(null, &st); | 157 | try os.sigaltstack(null, &st); |
| ... | @@ -204,7 +204,7 @@ fn iter_fn(info: *dl_phdr_info, size: usize, counter: *usize) IterFnError!void { | ... | @@ -204,7 +204,7 @@ fn iter_fn(info: *dl_phdr_info, size: usize, counter: *usize) IterFnError!void { |
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | test "dl_iterate_phdr" { | 206 | test "dl_iterate_phdr" { |
| 207 | if (builtin.os == .windows or builtin.os == .wasi or builtin.os == .macosx) | 207 | if (builtin.os.tag == .windows or builtin.os.tag == .wasi or builtin.os.tag == .macosx) |
| 208 | return error.SkipZigTest; | 208 | return error.SkipZigTest; |
| 209 | 209 | ||
| 210 | var counter: usize = 0; | 210 | var counter: usize = 0; |
| ... | @@ -213,7 +213,7 @@ test "dl_iterate_phdr" { | ... | @@ -213,7 +213,7 @@ test "dl_iterate_phdr" { |
| 213 | } | 213 | } |
| 214 | 214 | ||
| 215 | test "gethostname" { | 215 | test "gethostname" { |
| 216 | if (builtin.os == .windows) | 216 | if (builtin.os.tag == .windows) |
| 217 | return error.SkipZigTest; | 217 | return error.SkipZigTest; |
| 218 | 218 | ||
| 219 | var buf: [os.HOST_NAME_MAX]u8 = undefined; | 219 | var buf: [os.HOST_NAME_MAX]u8 = undefined; |
| ... | @@ -222,7 +222,7 @@ test "gethostname" { | ... | @@ -222,7 +222,7 @@ test "gethostname" { |
| 222 | } | 222 | } |
| 223 | 223 | ||
| 224 | test "pipe" { | 224 | test "pipe" { |
| 225 | if (builtin.os == .windows) | 225 | if (builtin.os.tag == .windows) |
| 226 | return error.SkipZigTest; | 226 | return error.SkipZigTest; |
| 227 | 227 | ||
| 228 | var fds = try os.pipe(); | 228 | var fds = try os.pipe(); |
| ... | @@ -241,7 +241,7 @@ test "argsAlloc" { | ... | @@ -241,7 +241,7 @@ test "argsAlloc" { |
| 241 | 241 | ||
| 242 | test "memfd_create" { | 242 | test "memfd_create" { |
| 243 | // memfd_create is linux specific. | 243 | // memfd_create is linux specific. |
| 244 | if (builtin.os != .linux) return error.SkipZigTest; | 244 | if (builtin.os.tag != .linux) return error.SkipZigTest; |
| 245 | const fd = std.os.memfd_create("test", 0) catch |err| switch (err) { | 245 | const fd = std.os.memfd_create("test", 0) catch |err| switch (err) { |
| 246 | // Related: https://github.com/ziglang/zig/issues/4019 | 246 | // Related: https://github.com/ziglang/zig/issues/4019 |
| 247 | error.SystemOutdated => return error.SkipZigTest, | 247 | error.SystemOutdated => return error.SkipZigTest, |
| ... | @@ -258,7 +258,7 @@ test "memfd_create" { | ... | @@ -258,7 +258,7 @@ test "memfd_create" { |
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | test "mmap" { | 260 | test "mmap" { |
| 261 | if (builtin.os == .windows) | 261 | if (builtin.os.tag == .windows) |
| 262 | return error.SkipZigTest; | 262 | return error.SkipZigTest; |
| 263 | 263 | ||
| 264 | // Simple mmap() call with non page-aligned size | 264 | // Simple mmap() call with non page-aligned size |
| ... | @@ -353,7 +353,7 @@ test "mmap" { | ... | @@ -353,7 +353,7 @@ test "mmap" { |
| 353 | } | 353 | } |
| 354 | 354 | ||
| 355 | test "getenv" { | 355 | test "getenv" { |
| 356 | if (builtin.os == .windows) { | 356 | if (builtin.os.tag == .windows) { |
| 357 | expect(os.getenvW(&[_:0]u16{ 'B', 'O', 'G', 'U', 'S', 0x11, 0x22, 0x33, 0x44, 0x55 }) == null); | 357 | expect(os.getenvW(&[_:0]u16{ 'B', 'O', 'G', 'U', 'S', 0x11, 0x22, 0x33, 0x44, 0x55 }) == null); |
| 358 | } else { | 358 | } else { |
| 359 | expect(os.getenvZ("BOGUSDOESNOTEXISTENVVAR") == null); | 359 | expect(os.getenvZ("BOGUSDOESNOTEXISTENVVAR") == null); |
lib/std/packed_int_array.zig+2-2| ... | @@ -593,7 +593,7 @@ test "PackedInt(Array/Slice)Endian" { | ... | @@ -593,7 +593,7 @@ test "PackedInt(Array/Slice)Endian" { |
| 593 | // after this one is not mapped and will cause a segfault if we | 593 | // after this one is not mapped and will cause a segfault if we |
| 594 | // don't account for the bounds. | 594 | // don't account for the bounds. |
| 595 | test "PackedIntArray at end of available memory" { | 595 | test "PackedIntArray at end of available memory" { |
| 596 | switch (builtin.os) { | 596 | switch (builtin.os.tag) { |
| 597 | .linux, .macosx, .ios, .freebsd, .netbsd, .windows => {}, | 597 | .linux, .macosx, .ios, .freebsd, .netbsd, .windows => {}, |
| 598 | else => return, | 598 | else => return, |
| 599 | } | 599 | } |
| ... | @@ -612,7 +612,7 @@ test "PackedIntArray at end of available memory" { | ... | @@ -612,7 +612,7 @@ test "PackedIntArray at end of available memory" { |
| 612 | } | 612 | } |
| 613 | 613 | ||
| 614 | test "PackedIntSlice at end of available memory" { | 614 | test "PackedIntSlice at end of available memory" { |
| 615 | switch (builtin.os) { | 615 | switch (builtin.os.tag) { |
| 616 | .linux, .macosx, .ios, .freebsd, .netbsd, .windows => {}, | 616 | .linux, .macosx, .ios, .freebsd, .netbsd, .windows => {}, |
| 617 | else => return, | 617 | else => return, |
| 618 | } | 618 | } |
lib/std/process.zig+15-11| ... | @@ -36,7 +36,7 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap { | ... | @@ -36,7 +36,7 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap { |
| 36 | var result = BufMap.init(allocator); | 36 | var result = BufMap.init(allocator); |
| 37 | errdefer result.deinit(); | 37 | errdefer result.deinit(); |
| 38 | 38 | ||
| 39 | if (builtin.os == .windows) { | 39 | if (builtin.os.tag == .windows) { |
| 40 | const ptr = os.windows.peb().ProcessParameters.Environment; | 40 | const ptr = os.windows.peb().ProcessParameters.Environment; |
| 41 | 41 | ||
| 42 | var i: usize = 0; | 42 | var i: usize = 0; |
| ... | @@ -61,7 +61,7 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap { | ... | @@ -61,7 +61,7 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap { |
| 61 | try result.setMove(key, value); | 61 | try result.setMove(key, value); |
| 62 | } | 62 | } |
| 63 | return result; | 63 | return result; |
| 64 | } else if (builtin.os == .wasi) { | 64 | } else if (builtin.os.tag == .wasi) { |
| 65 | var environ_count: usize = undefined; | 65 | var environ_count: usize = undefined; |
| 66 | var environ_buf_size: usize = undefined; | 66 | var environ_buf_size: usize = undefined; |
| 67 | 67 | ||
| ... | @@ -137,7 +137,7 @@ pub const GetEnvVarOwnedError = error{ | ... | @@ -137,7 +137,7 @@ pub const GetEnvVarOwnedError = error{ |
| 137 | 137 | ||
| 138 | /// Caller must free returned memory. | 138 | /// Caller must free returned memory. |
| 139 | pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwnedError![]u8 { | 139 | pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwnedError![]u8 { |
| 140 | if (builtin.os == .windows) { | 140 | if (builtin.os.tag == .windows) { |
| 141 | const result_w = blk: { | 141 | const result_w = blk: { |
| 142 | const key_w = try std.unicode.utf8ToUtf16LeWithNull(allocator, key); | 142 | const key_w = try std.unicode.utf8ToUtf16LeWithNull(allocator, key); |
| 143 | defer allocator.free(key_w); | 143 | defer allocator.free(key_w); |
| ... | @@ -338,12 +338,12 @@ pub const ArgIteratorWindows = struct { | ... | @@ -338,12 +338,12 @@ pub const ArgIteratorWindows = struct { |
| 338 | }; | 338 | }; |
| 339 | 339 | ||
| 340 | pub const ArgIterator = struct { | 340 | pub const ArgIterator = struct { |
| 341 | const InnerType = if (builtin.os == .windows) ArgIteratorWindows else ArgIteratorPosix; | 341 | const InnerType = if (builtin.os.tag == .windows) ArgIteratorWindows else ArgIteratorPosix; |
| 342 | 342 | ||
| 343 | inner: InnerType, | 343 | inner: InnerType, |
| 344 | 344 | ||
| 345 | pub fn init() ArgIterator { | 345 | pub fn init() ArgIterator { |
| 346 | if (builtin.os == .wasi) { | 346 | if (builtin.os.tag == .wasi) { |
| 347 | // TODO: Figure out a compatible interface accomodating WASI | 347 | // TODO: Figure out a compatible interface accomodating WASI |
| 348 | @compileError("ArgIterator is not yet supported in WASI. Use argsAlloc and argsFree instead."); | 348 | @compileError("ArgIterator is not yet supported in WASI. Use argsAlloc and argsFree instead."); |
| 349 | } | 349 | } |
| ... | @@ -355,7 +355,7 @@ pub const ArgIterator = struct { | ... | @@ -355,7 +355,7 @@ pub const ArgIterator = struct { |
| 355 | 355 | ||
| 356 | /// You must free the returned memory when done. | 356 | /// You must free the returned memory when done. |
| 357 | pub fn next(self: *ArgIterator, allocator: *Allocator) ?(NextError![]u8) { | 357 | pub fn next(self: *ArgIterator, allocator: *Allocator) ?(NextError![]u8) { |
| 358 | if (builtin.os == .windows) { | 358 | if (builtin.os.tag == .windows) { |
| 359 | return self.inner.next(allocator); | 359 | return self.inner.next(allocator); |
| 360 | } else { | 360 | } else { |
| 361 | return mem.dupe(allocator, u8, self.inner.next() orelse return null); | 361 | return mem.dupe(allocator, u8, self.inner.next() orelse return null); |
| ... | @@ -380,7 +380,7 @@ pub fn args() ArgIterator { | ... | @@ -380,7 +380,7 @@ pub fn args() ArgIterator { |
| 380 | 380 | ||
| 381 | /// Caller must call argsFree on result. | 381 | /// Caller must call argsFree on result. |
| 382 | pub fn argsAlloc(allocator: *mem.Allocator) ![][]u8 { | 382 | pub fn argsAlloc(allocator: *mem.Allocator) ![][]u8 { |
| 383 | if (builtin.os == .wasi) { | 383 | if (builtin.os.tag == .wasi) { |
| 384 | var count: usize = undefined; | 384 | var count: usize = undefined; |
| 385 | var buf_size: usize = undefined; | 385 | var buf_size: usize = undefined; |
| 386 | 386 | ||
| ... | @@ -445,7 +445,7 @@ pub fn argsAlloc(allocator: *mem.Allocator) ![][]u8 { | ... | @@ -445,7 +445,7 @@ pub fn argsAlloc(allocator: *mem.Allocator) ![][]u8 { |
| 445 | } | 445 | } |
| 446 | 446 | ||
| 447 | pub fn argsFree(allocator: *mem.Allocator, args_alloc: []const []u8) void { | 447 | pub fn argsFree(allocator: *mem.Allocator, args_alloc: []const []u8) void { |
| 448 | if (builtin.os == .wasi) { | 448 | if (builtin.os.tag == .wasi) { |
| 449 | const last_item = args_alloc[args_alloc.len - 1]; | 449 | const last_item = args_alloc[args_alloc.len - 1]; |
| 450 | const last_byte_addr = @ptrToInt(last_item.ptr) + last_item.len + 1; // null terminated | 450 | const last_byte_addr = @ptrToInt(last_item.ptr) + last_item.len + 1; // null terminated |
| 451 | const first_item_ptr = args_alloc[0].ptr; | 451 | const first_item_ptr = args_alloc[0].ptr; |
| ... | @@ -498,7 +498,7 @@ pub const UserInfo = struct { | ... | @@ -498,7 +498,7 @@ pub const UserInfo = struct { |
| 498 | 498 | ||
| 499 | /// POSIX function which gets a uid from username. | 499 | /// POSIX function which gets a uid from username. |
| 500 | pub fn getUserInfo(name: []const u8) !UserInfo { | 500 | pub fn getUserInfo(name: []const u8) !UserInfo { |
| 501 | return switch (builtin.os) { | 501 | return switch (builtin.os.tag) { |
| 502 | .linux, .macosx, .watchos, .tvos, .ios, .freebsd, .netbsd => posixGetUserInfo(name), | 502 | .linux, .macosx, .watchos, .tvos, .ios, .freebsd, .netbsd => posixGetUserInfo(name), |
| 503 | else => @compileError("Unsupported OS"), | 503 | else => @compileError("Unsupported OS"), |
| 504 | }; | 504 | }; |
| ... | @@ -591,7 +591,7 @@ pub fn posixGetUserInfo(name: []const u8) !UserInfo { | ... | @@ -591,7 +591,7 @@ pub fn posixGetUserInfo(name: []const u8) !UserInfo { |
| 591 | } | 591 | } |
| 592 | 592 | ||
| 593 | pub fn getBaseAddress() usize { | 593 | pub fn getBaseAddress() usize { |
| 594 | switch (builtin.os) { | 594 | switch (builtin.os.tag) { |
| 595 | .linux => { | 595 | .linux => { |
| 596 | const base = os.system.getauxval(std.elf.AT_BASE); | 596 | const base = os.system.getauxval(std.elf.AT_BASE); |
| 597 | if (base != 0) { | 597 | if (base != 0) { |
| ... | @@ -609,13 +609,17 @@ pub fn getBaseAddress() usize { | ... | @@ -609,13 +609,17 @@ pub fn getBaseAddress() usize { |
| 609 | } | 609 | } |
| 610 | 610 | ||
| 611 | /// Caller owns the result value and each inner slice. | 611 | /// Caller owns the result value and each inner slice. |
| 612 | /// TODO Remove the `Allocator` requirement from this API, which will remove the `Allocator` | ||
| 613 | /// requirement from `std.zig.system.NativeTargetInfo.detect`. Most likely this will require | ||
| 614 | /// introducing a new, lower-level function which takes a callback function, and then this | ||
| 615 | /// function which takes an allocator can exist on top of it. | ||
| 612 | pub fn getSelfExeSharedLibPaths(allocator: *Allocator) error{OutOfMemory}![][:0]u8 { | 616 | pub fn getSelfExeSharedLibPaths(allocator: *Allocator) error{OutOfMemory}![][:0]u8 { |
| 613 | switch (builtin.link_mode) { | 617 | switch (builtin.link_mode) { |
| 614 | .Static => return &[_][:0]u8{}, | 618 | .Static => return &[_][:0]u8{}, |
| 615 | .Dynamic => {}, | 619 | .Dynamic => {}, |
| 616 | } | 620 | } |
| 617 | const List = std.ArrayList([:0]u8); | 621 | const List = std.ArrayList([:0]u8); |
| 618 | switch (builtin.os) { | 622 | switch (builtin.os.tag) { |
| 619 | .linux, | 623 | .linux, |
| 620 | .freebsd, | 624 | .freebsd, |
| 621 | .netbsd, | 625 | .netbsd, |
lib/std/reset_event.zig+3-3| ... | @@ -16,7 +16,7 @@ pub const ResetEvent = struct { | ... | @@ -16,7 +16,7 @@ pub const ResetEvent = struct { |
| 16 | 16 | ||
| 17 | pub const OsEvent = if (builtin.single_threaded) | 17 | pub const OsEvent = if (builtin.single_threaded) |
| 18 | DebugEvent | 18 | DebugEvent |
| 19 | else if (builtin.link_libc and builtin.os != .windows and builtin.os != .linux) | 19 | else if (builtin.link_libc and builtin.os.tag != .windows and builtin.os.tag != .linux) |
| 20 | PosixEvent | 20 | PosixEvent |
| 21 | else | 21 | else |
| 22 | AtomicEvent; | 22 | AtomicEvent; |
| ... | @@ -106,7 +106,7 @@ const PosixEvent = struct { | ... | @@ -106,7 +106,7 @@ const PosixEvent = struct { |
| 106 | fn deinit(self: *PosixEvent) void { | 106 | fn deinit(self: *PosixEvent) void { |
| 107 | // on dragonfly, *destroy() functions can return EINVAL | 107 | // on dragonfly, *destroy() functions can return EINVAL |
| 108 | // for statically initialized pthread structures | 108 | // for statically initialized pthread structures |
| 109 | const err = if (builtin.os == .dragonfly) os.EINVAL else 0; | 109 | const err = if (builtin.os.tag == .dragonfly) os.EINVAL else 0; |
| 110 | 110 | ||
| 111 | const retm = c.pthread_mutex_destroy(&self.mutex); | 111 | const retm = c.pthread_mutex_destroy(&self.mutex); |
| 112 | assert(retm == 0 or retm == err); | 112 | assert(retm == 0 or retm == err); |
| ... | @@ -215,7 +215,7 @@ const AtomicEvent = struct { | ... | @@ -215,7 +215,7 @@ const AtomicEvent = struct { |
| 215 | } | 215 | } |
| 216 | } | 216 | } |
| 217 | 217 | ||
| 218 | pub const Futex = switch (builtin.os) { | 218 | pub const Futex = switch (builtin.os.tag) { |
| 219 | .windows => WindowsFutex, | 219 | .windows => WindowsFutex, |
| 220 | .linux => LinuxFutex, | 220 | .linux => LinuxFutex, |
| 221 | else => SpinFutex, | 221 | else => SpinFutex, |
lib/std/special/c.zig+4-4| ... | @@ -17,7 +17,7 @@ const is_msvc = switch (builtin.abi) { | ... | @@ -17,7 +17,7 @@ const is_msvc = switch (builtin.abi) { |
| 17 | .msvc => true, | 17 | .msvc => true, |
| 18 | else => false, | 18 | else => false, |
| 19 | }; | 19 | }; |
| 20 | const is_freestanding = switch (builtin.os) { | 20 | const is_freestanding = switch (builtin.os.tag) { |
| 21 | .freestanding => true, | 21 | .freestanding => true, |
| 22 | else => false, | 22 | else => false, |
| 23 | }; | 23 | }; |
| ... | @@ -81,7 +81,7 @@ pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn | ... | @@ -81,7 +81,7 @@ pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn |
| 81 | @setCold(true); | 81 | @setCold(true); |
| 82 | std.debug.panic("{}", .{msg}); | 82 | std.debug.panic("{}", .{msg}); |
| 83 | } | 83 | } |
| 84 | if (builtin.os != .freestanding and builtin.os != .other) { | 84 | if (builtin.os.tag != .freestanding and builtin.os.tag != .other) { |
| 85 | std.os.abort(); | 85 | std.os.abort(); |
| 86 | } | 86 | } |
| 87 | while (true) {} | 87 | while (true) {} |
| ... | @@ -178,11 +178,11 @@ test "test_bcmp" { | ... | @@ -178,11 +178,11 @@ test "test_bcmp" { |
| 178 | comptime { | 178 | comptime { |
| 179 | if (builtin.mode != builtin.Mode.ReleaseFast and | 179 | if (builtin.mode != builtin.Mode.ReleaseFast and |
| 180 | builtin.mode != builtin.Mode.ReleaseSmall and | 180 | builtin.mode != builtin.Mode.ReleaseSmall and |
| 181 | builtin.os != builtin.Os.windows) | 181 | builtin.os.tag != .windows) |
| 182 | { | 182 | { |
| 183 | @export(__stack_chk_fail, .{ .name = "__stack_chk_fail" }); | 183 | @export(__stack_chk_fail, .{ .name = "__stack_chk_fail" }); |
| 184 | } | 184 | } |
| 185 | if (builtin.os == builtin.Os.linux) { | 185 | if (builtin.os.tag == .linux) { |
| 186 | @export(clone, .{ .name = "clone" }); | 186 | @export(clone, .{ .name = "clone" }); |
| 187 | } | 187 | } |
| 188 | } | 188 | } |
lib/std/special/compiler_rt.zig+8-10| ... | @@ -1,11 +1,9 @@ | ... | @@ -1,11 +1,9 @@ |
| 1 | const builtin = @import("builtin"); | 1 | const std = @import("std"); |
| 2 | const builtin = std.builtin; | ||
| 2 | const is_test = builtin.is_test; | 3 | const is_test = builtin.is_test; |
| 3 | 4 | ||
| 4 | const is_gnu = switch (builtin.abi) { | 5 | const is_gnu = std.Target.current.abi.isGnu(); |
| 5 | .gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => true, | 6 | const is_mingw = builtin.os.tag == .windows and is_gnu; |
| 6 | else => false, | ||
| 7 | }; | ||
| 8 | const is_mingw = builtin.os == .windows and is_gnu; | ||
| 9 | 7 | ||
| 10 | comptime { | 8 | comptime { |
| 11 | const linkage = if (is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Weak; | 9 | const linkage = if (is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Weak; |
| ... | @@ -180,7 +178,7 @@ comptime { | ... | @@ -180,7 +178,7 @@ comptime { |
| 180 | @export(@import("compiler_rt/arm.zig").__aeabi_memclr, .{ .name = "__aeabi_memclr4", .linkage = linkage }); | 178 | @export(@import("compiler_rt/arm.zig").__aeabi_memclr, .{ .name = "__aeabi_memclr4", .linkage = linkage }); |
| 181 | @export(@import("compiler_rt/arm.zig").__aeabi_memclr, .{ .name = "__aeabi_memclr8", .linkage = linkage }); | 179 | @export(@import("compiler_rt/arm.zig").__aeabi_memclr, .{ .name = "__aeabi_memclr8", .linkage = linkage }); |
| 182 | 180 | ||
| 183 | if (builtin.os == .linux) { | 181 | if (builtin.os.tag == .linux) { |
| 184 | @export(@import("compiler_rt/arm.zig").__aeabi_read_tp, .{ .name = "__aeabi_read_tp", .linkage = linkage }); | 182 | @export(@import("compiler_rt/arm.zig").__aeabi_read_tp, .{ .name = "__aeabi_read_tp", .linkage = linkage }); |
| 185 | } | 183 | } |
| 186 | 184 | ||
| ... | @@ -250,7 +248,7 @@ comptime { | ... | @@ -250,7 +248,7 @@ comptime { |
| 250 | @export(@import("compiler_rt/aullrem.zig")._aullrem, .{ .name = "\x01__aullrem", .linkage = strong_linkage }); | 248 | @export(@import("compiler_rt/aullrem.zig")._aullrem, .{ .name = "\x01__aullrem", .linkage = strong_linkage }); |
| 251 | } | 249 | } |
| 252 | 250 | ||
| 253 | if (builtin.os == .windows) { | 251 | if (builtin.os.tag == .windows) { |
| 254 | // Default stack-probe functions emitted by LLVM | 252 | // Default stack-probe functions emitted by LLVM |
| 255 | if (is_mingw) { | 253 | if (is_mingw) { |
| 256 | @export(@import("compiler_rt/stack_probe.zig")._chkstk, .{ .name = "_alloca", .linkage = strong_linkage }); | 254 | @export(@import("compiler_rt/stack_probe.zig")._chkstk, .{ .name = "_alloca", .linkage = strong_linkage }); |
| ... | @@ -288,7 +286,7 @@ comptime { | ... | @@ -288,7 +286,7 @@ comptime { |
| 288 | else => {}, | 286 | else => {}, |
| 289 | } | 287 | } |
| 290 | } else { | 288 | } else { |
| 291 | if (builtin.glibc_version != null) { | 289 | if (std.Target.current.isGnuLibC() and builtin.link_libc) { |
| 292 | @export(__stack_chk_guard, .{ .name = "__stack_chk_guard", .linkage = linkage }); | 290 | @export(__stack_chk_guard, .{ .name = "__stack_chk_guard", .linkage = linkage }); |
| 293 | } | 291 | } |
| 294 | @export(@import("compiler_rt/divti3.zig").__divti3, .{ .name = "__divti3", .linkage = linkage }); | 292 | @export(@import("compiler_rt/divti3.zig").__divti3, .{ .name = "__divti3", .linkage = linkage }); |
| ... | @@ -307,7 +305,7 @@ comptime { | ... | @@ -307,7 +305,7 @@ comptime { |
| 307 | pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn { | 305 | pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn { |
| 308 | @setCold(true); | 306 | @setCold(true); |
| 309 | if (is_test) { | 307 | if (is_test) { |
| 310 | @import("std").debug.panic("{}", .{msg}); | 308 | std.debug.panic("{}", .{msg}); |
| 311 | } else { | 309 | } else { |
| 312 | unreachable; | 310 | unreachable; |
| 313 | } | 311 | } |
lib/std/special/compiler_rt/addXf3_test.zig+2-2| ... | @@ -31,7 +31,7 @@ fn test__addtf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) void { | ... | @@ -31,7 +31,7 @@ fn test__addtf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) void { |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | test "addtf3" { | 33 | test "addtf3" { |
| 34 | if (@import("std").Target.current.isWindows()) { | 34 | if (@import("std").Target.current.os.tag == .windows) { |
| 35 | // TODO https://github.com/ziglang/zig/issues/508 | 35 | // TODO https://github.com/ziglang/zig/issues/508 |
| 36 | return error.SkipZigTest; | 36 | return error.SkipZigTest; |
| 37 | } | 37 | } |
| ... | @@ -75,7 +75,7 @@ fn test__subtf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) void { | ... | @@ -75,7 +75,7 @@ fn test__subtf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) void { |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | test "subtf3" { | 77 | test "subtf3" { |
| 78 | if (@import("std").Target.current.isWindows()) { | 78 | if (@import("std").Target.current.os.tag == .windows) { |
| 79 | // TODO https://github.com/ziglang/zig/issues/508 | 79 | // TODO https://github.com/ziglang/zig/issues/508 |
| 80 | return error.SkipZigTest; | 80 | return error.SkipZigTest; |
| 81 | } | 81 | } |
lib/std/special/compiler_rt/extendXfYf2_test.zig+1-1| ... | @@ -90,7 +90,7 @@ test "extendhfsf2" { | ... | @@ -90,7 +90,7 @@ test "extendhfsf2" { |
| 90 | test__extendhfsf2(0x7f00, 0x7fe00000); // sNaN | 90 | test__extendhfsf2(0x7f00, 0x7fe00000); // sNaN |
| 91 | // On x86 the NaN becomes quiet because the return is pushed on the x87 | 91 | // On x86 the NaN becomes quiet because the return is pushed on the x87 |
| 92 | // stack due to ABI requirements | 92 | // stack due to ABI requirements |
| 93 | if (builtin.arch != .i386 and builtin.os == .windows) | 93 | if (builtin.arch != .i386 and builtin.os.tag == .windows) |
| 94 | test__extendhfsf2(0x7c01, 0x7f802000); // sNaN | 94 | test__extendhfsf2(0x7c01, 0x7f802000); // sNaN |
| 95 | 95 | ||
| 96 | test__extendhfsf2(0, 0); // 0 | 96 | test__extendhfsf2(0, 0); // 0 |
lib/std/special/compiler_rt/fixtfdi_test.zig+1-1| ... | @@ -11,7 +11,7 @@ fn test__fixtfdi(a: f128, expected: i64) void { | ... | @@ -11,7 +11,7 @@ fn test__fixtfdi(a: f128, expected: i64) void { |
| 11 | } | 11 | } |
| 12 | 12 | ||
| 13 | test "fixtfdi" { | 13 | test "fixtfdi" { |
| 14 | if (@import("std").Target.current.isWindows()) { | 14 | if (@import("std").Target.current.os.tag == .windows) { |
| 15 | // TODO https://github.com/ziglang/zig/issues/508 | 15 | // TODO https://github.com/ziglang/zig/issues/508 |
| 16 | return error.SkipZigTest; | 16 | return error.SkipZigTest; |
| 17 | } | 17 | } |
lib/std/special/compiler_rt/fixtfsi_test.zig+1-1| ... | @@ -11,7 +11,7 @@ fn test__fixtfsi(a: f128, expected: i32) void { | ... | @@ -11,7 +11,7 @@ fn test__fixtfsi(a: f128, expected: i32) void { |
| 11 | } | 11 | } |
| 12 | 12 | ||
| 13 | test "fixtfsi" { | 13 | test "fixtfsi" { |
| 14 | if (@import("std").Target.current.isWindows()) { | 14 | if (@import("std").Target.current.os.tag == .windows) { |
| 15 | // TODO https://github.com/ziglang/zig/issues/508 | 15 | // TODO https://github.com/ziglang/zig/issues/508 |
| 16 | return error.SkipZigTest; | 16 | return error.SkipZigTest; |
| 17 | } | 17 | } |
lib/std/special/compiler_rt/fixtfti_test.zig+1-1| ... | @@ -11,7 +11,7 @@ fn test__fixtfti(a: f128, expected: i128) void { | ... | @@ -11,7 +11,7 @@ fn test__fixtfti(a: f128, expected: i128) void { |
| 11 | } | 11 | } |
| 12 | 12 | ||
| 13 | test "fixtfti" { | 13 | test "fixtfti" { |
| 14 | if (@import("std").Target.current.isWindows()) { | 14 | if (@import("std").Target.current.os.tag == .windows) { |
| 15 | // TODO https://github.com/ziglang/zig/issues/508 | 15 | // TODO https://github.com/ziglang/zig/issues/508 |
| 16 | return error.SkipZigTest; | 16 | return error.SkipZigTest; |
| 17 | } | 17 | } |
lib/std/special/compiler_rt/fixunstfdi_test.zig+1-1| ... | @@ -7,7 +7,7 @@ fn test__fixunstfdi(a: f128, expected: u64) void { | ... | @@ -7,7 +7,7 @@ fn test__fixunstfdi(a: f128, expected: u64) void { |
| 7 | } | 7 | } |
| 8 | 8 | ||
| 9 | test "fixunstfdi" { | 9 | test "fixunstfdi" { |
| 10 | if (@import("std").Target.current.isWindows()) { | 10 | if (@import("std").Target.current.os.tag == .windows) { |
| 11 | // TODO https://github.com/ziglang/zig/issues/508 | 11 | // TODO https://github.com/ziglang/zig/issues/508 |
| 12 | return error.SkipZigTest; | 12 | return error.SkipZigTest; |
| 13 | } | 13 | } |
lib/std/special/compiler_rt/fixunstfsi_test.zig+1-1| ... | @@ -9,7 +9,7 @@ fn test__fixunstfsi(a: f128, expected: u32) void { | ... | @@ -9,7 +9,7 @@ fn test__fixunstfsi(a: f128, expected: u32) void { |
| 9 | const inf128 = @bitCast(f128, @as(u128, 0x7fff0000000000000000000000000000)); | 9 | const inf128 = @bitCast(f128, @as(u128, 0x7fff0000000000000000000000000000)); |
| 10 | 10 | ||
| 11 | test "fixunstfsi" { | 11 | test "fixunstfsi" { |
| 12 | if (@import("std").Target.current.isWindows()) { | 12 | if (@import("std").Target.current.os.tag == .windows) { |
| 13 | // TODO https://github.com/ziglang/zig/issues/508 | 13 | // TODO https://github.com/ziglang/zig/issues/508 |
| 14 | return error.SkipZigTest; | 14 | return error.SkipZigTest; |
| 15 | } | 15 | } |
lib/std/special/compiler_rt/fixunstfti_test.zig+1-1| ... | @@ -9,7 +9,7 @@ fn test__fixunstfti(a: f128, expected: u128) void { | ... | @@ -9,7 +9,7 @@ fn test__fixunstfti(a: f128, expected: u128) void { |
| 9 | const inf128 = @bitCast(f128, @as(u128, 0x7fff0000000000000000000000000000)); | 9 | const inf128 = @bitCast(f128, @as(u128, 0x7fff0000000000000000000000000000)); |
| 10 | 10 | ||
| 11 | test "fixunstfti" { | 11 | test "fixunstfti" { |
| 12 | if (@import("std").Target.current.isWindows()) { | 12 | if (@import("std").Target.current.os.tag == .windows) { |
| 13 | // TODO https://github.com/ziglang/zig/issues/508 | 13 | // TODO https://github.com/ziglang/zig/issues/508 |
| 14 | return error.SkipZigTest; | 14 | return error.SkipZigTest; |
| 15 | } | 15 | } |
lib/std/special/compiler_rt/floattitf_test.zig+1-1| ... | @@ -7,7 +7,7 @@ fn test__floattitf(a: i128, expected: f128) void { | ... | @@ -7,7 +7,7 @@ fn test__floattitf(a: i128, expected: f128) void { |
| 7 | } | 7 | } |
| 8 | 8 | ||
| 9 | test "floattitf" { | 9 | test "floattitf" { |
| 10 | if (@import("std").Target.current.isWindows()) { | 10 | if (@import("std").Target.current.os.tag == .windows) { |
| 11 | // TODO https://github.com/ziglang/zig/issues/508 | 11 | // TODO https://github.com/ziglang/zig/issues/508 |
| 12 | return error.SkipZigTest; | 12 | return error.SkipZigTest; |
| 13 | } | 13 | } |
lib/std/special/compiler_rt/floatuntitf_test.zig+1-1| ... | @@ -7,7 +7,7 @@ fn test__floatuntitf(a: u128, expected: f128) void { | ... | @@ -7,7 +7,7 @@ fn test__floatuntitf(a: u128, expected: f128) void { |
| 7 | } | 7 | } |
| 8 | 8 | ||
| 9 | test "floatuntitf" { | 9 | test "floatuntitf" { |
| 10 | if (@import("std").Target.current.isWindows()) { | 10 | if (@import("std").Target.current.os.tag == .windows) { |
| 11 | // TODO https://github.com/ziglang/zig/issues/508 | 11 | // TODO https://github.com/ziglang/zig/issues/508 |
| 12 | return error.SkipZigTest; | 12 | return error.SkipZigTest; |
| 13 | } | 13 | } |
lib/std/special/compiler_rt/mulXf3_test.zig+1-1| ... | @@ -44,7 +44,7 @@ fn makeNaN128(rand: u64) f128 { | ... | @@ -44,7 +44,7 @@ fn makeNaN128(rand: u64) f128 { |
| 44 | return float_result; | 44 | return float_result; |
| 45 | } | 45 | } |
| 46 | test "multf3" { | 46 | test "multf3" { |
| 47 | if (@import("std").Target.current.isWindows()) { | 47 | if (@import("std").Target.current.os.tag == .windows) { |
| 48 | // TODO https://github.com/ziglang/zig/issues/508 | 48 | // TODO https://github.com/ziglang/zig/issues/508 |
| 49 | return error.SkipZigTest; | 49 | return error.SkipZigTest; |
| 50 | } | 50 | } |
lib/std/special/compiler_rt/truncXfYf2.zig+6-6| ... | @@ -1,23 +1,23 @@ | ... | @@ -1,23 +1,23 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | 2 | ||
| 3 | pub fn __truncsfhf2(a: f32) callconv(.C) u16 { | 3 | pub fn __truncsfhf2(a: f32) callconv(.C) u16 { |
| 4 | return @bitCast(u16, truncXfYf2(f16, f32, a)); | 4 | return @bitCast(u16, @call(.{ .modifier = .always_inline }, truncXfYf2, .{ f16, f32, a })); |
| 5 | } | 5 | } |
| 6 | 6 | ||
| 7 | pub fn __truncdfhf2(a: f64) callconv(.C) u16 { | 7 | pub fn __truncdfhf2(a: f64) callconv(.C) u16 { |
| 8 | return @bitCast(u16, truncXfYf2(f16, f64, a)); | 8 | return @bitCast(u16, @call(.{ .modifier = .always_inline }, truncXfYf2, .{ f16, f64, a })); |
| 9 | } | 9 | } |
| 10 | 10 | ||
| 11 | pub fn __trunctfsf2(a: f128) callconv(.C) f32 { | 11 | pub fn __trunctfsf2(a: f128) callconv(.C) f32 { |
| 12 | return truncXfYf2(f32, f128, a); | 12 | return @call(.{ .modifier = .always_inline }, truncXfYf2, .{ f32, f128, a }); |
| 13 | } | 13 | } |
| 14 | 14 | ||
| 15 | pub fn __trunctfdf2(a: f128) callconv(.C) f64 { | 15 | pub fn __trunctfdf2(a: f128) callconv(.C) f64 { |
| 16 | return truncXfYf2(f64, f128, a); | 16 | return @call(.{ .modifier = .always_inline }, truncXfYf2, .{ f64, f128, a }); |
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | pub fn __truncdfsf2(a: f64) callconv(.C) f32 { | 19 | pub fn __truncdfsf2(a: f64) callconv(.C) f32 { |
| 20 | return truncXfYf2(f32, f64, a); | 20 | return @call(.{ .modifier = .always_inline }, truncXfYf2, .{ f32, f64, a }); |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | pub fn __aeabi_d2f(a: f64) callconv(.AAPCS) f32 { | 23 | pub fn __aeabi_d2f(a: f64) callconv(.AAPCS) f32 { |
| ... | @@ -35,7 +35,7 @@ pub fn __aeabi_f2h(a: f32) callconv(.AAPCS) u16 { | ... | @@ -35,7 +35,7 @@ pub fn __aeabi_f2h(a: f32) callconv(.AAPCS) u16 { |
| 35 | return @call(.{ .modifier = .always_inline }, __truncsfhf2, .{a}); | 35 | return @call(.{ .modifier = .always_inline }, __truncsfhf2, .{a}); |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | inline fn truncXfYf2(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t { | 38 | fn truncXfYf2(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t { |
| 39 | const src_rep_t = std.meta.IntType(false, @typeInfo(src_t).Float.bits); | 39 | const src_rep_t = std.meta.IntType(false, @typeInfo(src_t).Float.bits); |
| 40 | const dst_rep_t = std.meta.IntType(false, @typeInfo(dst_t).Float.bits); | 40 | const dst_rep_t = std.meta.IntType(false, @typeInfo(dst_t).Float.bits); |
| 41 | const srcSigBits = std.math.floatMantissaBits(src_t); | 41 | const srcSigBits = std.math.floatMantissaBits(src_t); |
lib/std/special/compiler_rt/truncXfYf2_test.zig+2-2| ... | @@ -151,7 +151,7 @@ fn test__trunctfsf2(a: f128, expected: u32) void { | ... | @@ -151,7 +151,7 @@ fn test__trunctfsf2(a: f128, expected: u32) void { |
| 151 | } | 151 | } |
| 152 | 152 | ||
| 153 | test "trunctfsf2" { | 153 | test "trunctfsf2" { |
| 154 | if (@import("std").Target.current.isWindows()) { | 154 | if (@import("std").Target.current.os.tag == .windows) { |
| 155 | // TODO https://github.com/ziglang/zig/issues/508 | 155 | // TODO https://github.com/ziglang/zig/issues/508 |
| 156 | return error.SkipZigTest; | 156 | return error.SkipZigTest; |
| 157 | } | 157 | } |
| ... | @@ -190,7 +190,7 @@ fn test__trunctfdf2(a: f128, expected: u64) void { | ... | @@ -190,7 +190,7 @@ fn test__trunctfdf2(a: f128, expected: u64) void { |
| 190 | } | 190 | } |
| 191 | 191 | ||
| 192 | test "trunctfdf2" { | 192 | test "trunctfdf2" { |
| 193 | if (@import("std").Target.current.isWindows()) { | 193 | if (@import("std").Target.current.os.tag == .windows) { |
| 194 | // TODO https://github.com/ziglang/zig/issues/508 | 194 | // TODO https://github.com/ziglang/zig/issues/508 |
| 195 | return error.SkipZigTest; | 195 | return error.SkipZigTest; |
| 196 | } | 196 | } |
lib/std/special/init-exe/build.zig+10| ... | @@ -1,8 +1,18 @@ | ... | @@ -1,8 +1,18 @@ |
| 1 | const Builder = @import("std").build.Builder; | 1 | const Builder = @import("std").build.Builder; |
| 2 | 2 | ||
| 3 | pub fn build(b: *Builder) void { | 3 | pub fn build(b: *Builder) void { |
| 4 | // Standard target options allows the person running `zig build` to choose | ||
| 5 | // what target to build for. Here we do not override the defaults, which | ||
| 6 | // means any target is allowed, and the default is native. Other options | ||
| 7 | // for restricting supported target set are available. | ||
| 8 | const target = b.standardTargetOptions(.{}); | ||
| 9 | |||
| 10 | // Standard release options allow the person running `zig build` to select | ||
| 11 | // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. | ||
| 4 | const mode = b.standardReleaseOptions(); | 12 | const mode = b.standardReleaseOptions(); |
| 13 | |||
| 5 | const exe = b.addExecutable("$", "src/main.zig"); | 14 | const exe = b.addExecutable("$", "src/main.zig"); |
| 15 | exe.setTarget(target); | ||
| 6 | exe.setBuildMode(mode); | 16 | exe.setBuildMode(mode); |
| 7 | exe.install(); | 17 | exe.install(); |
| 8 | 18 |
lib/std/special/init-exe/src/main.zig+1-1| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | 2 | ||
| 3 | pub fn main() anyerror!void { | 3 | pub fn main() anyerror!void { |
| 4 | std.debug.warn("All your base are belong to us.\n", .{}); | 4 | std.debug.warn("All your codebase are belong to us.\n", .{}); |
| 5 | } | 5 | } |
lib/std/spinlock.zig+1-1| ... | @@ -46,7 +46,7 @@ pub const SpinLock = struct { | ... | @@ -46,7 +46,7 @@ pub const SpinLock = struct { |
| 46 | // and yielding for 380-410 iterations was found to be | 46 | // and yielding for 380-410 iterations was found to be |
| 47 | // a nice sweet spot. Posix systems on the other hand, | 47 | // a nice sweet spot. Posix systems on the other hand, |
| 48 | // especially linux, perform better by yielding the thread. | 48 | // especially linux, perform better by yielding the thread. |
| 49 | switch (builtin.os) { | 49 | switch (builtin.os.tag) { |
| 50 | .windows => loopHint(400), | 50 | .windows => loopHint(400), |
| 51 | else => std.os.sched_yield() catch loopHint(1), | 51 | else => std.os.sched_yield() catch loopHint(1), |
| 52 | } | 52 | } |
lib/std/start.zig+8-8| ... | @@ -12,7 +12,7 @@ const start_sym_name = if (builtin.arch.isMIPS()) "__start" else "_start"; | ... | @@ -12,7 +12,7 @@ const start_sym_name = if (builtin.arch.isMIPS()) "__start" else "_start"; |
| 12 | 12 | ||
| 13 | comptime { | 13 | comptime { |
| 14 | if (builtin.output_mode == .Lib and builtin.link_mode == .Dynamic) { | 14 | if (builtin.output_mode == .Lib and builtin.link_mode == .Dynamic) { |
| 15 | if (builtin.os == .windows and !@hasDecl(root, "_DllMainCRTStartup")) { | 15 | if (builtin.os.tag == .windows and !@hasDecl(root, "_DllMainCRTStartup")) { |
| 16 | @export(_DllMainCRTStartup, .{ .name = "_DllMainCRTStartup" }); | 16 | @export(_DllMainCRTStartup, .{ .name = "_DllMainCRTStartup" }); |
| 17 | } | 17 | } |
| 18 | } else if (builtin.output_mode == .Exe or @hasDecl(root, "main")) { | 18 | } else if (builtin.output_mode == .Exe or @hasDecl(root, "main")) { |
| ... | @@ -20,17 +20,17 @@ comptime { | ... | @@ -20,17 +20,17 @@ comptime { |
| 20 | if (@typeInfo(@TypeOf(root.main)).Fn.calling_convention != .C) { | 20 | if (@typeInfo(@TypeOf(root.main)).Fn.calling_convention != .C) { |
| 21 | @export(main, .{ .name = "main", .linkage = .Weak }); | 21 | @export(main, .{ .name = "main", .linkage = .Weak }); |
| 22 | } | 22 | } |
| 23 | } else if (builtin.os == .windows) { | 23 | } else if (builtin.os.tag == .windows) { |
| 24 | if (!@hasDecl(root, "WinMain") and !@hasDecl(root, "WinMainCRTStartup") and | 24 | if (!@hasDecl(root, "WinMain") and !@hasDecl(root, "WinMainCRTStartup") and |
| 25 | !@hasDecl(root, "wWinMain") and !@hasDecl(root, "wWinMainCRTStartup")) | 25 | !@hasDecl(root, "wWinMain") and !@hasDecl(root, "wWinMainCRTStartup")) |
| 26 | { | 26 | { |
| 27 | @export(WinMainCRTStartup, .{ .name = "WinMainCRTStartup" }); | 27 | @export(WinMainCRTStartup, .{ .name = "WinMainCRTStartup" }); |
| 28 | } | 28 | } |
| 29 | } else if (builtin.os == .uefi) { | 29 | } else if (builtin.os.tag == .uefi) { |
| 30 | if (!@hasDecl(root, "EfiMain")) @export(EfiMain, .{ .name = "EfiMain" }); | 30 | if (!@hasDecl(root, "EfiMain")) @export(EfiMain, .{ .name = "EfiMain" }); |
| 31 | } else if (builtin.arch.isWasm() and builtin.os == .freestanding) { | 31 | } else if (builtin.arch.isWasm() and builtin.os.tag == .freestanding) { |
| 32 | if (!@hasDecl(root, start_sym_name)) @export(wasm_freestanding_start, .{ .name = start_sym_name }); | 32 | if (!@hasDecl(root, start_sym_name)) @export(wasm_freestanding_start, .{ .name = start_sym_name }); |
| 33 | } else if (builtin.os != .other and builtin.os != .freestanding) { | 33 | } else if (builtin.os.tag != .other and builtin.os.tag != .freestanding) { |
| 34 | if (!@hasDecl(root, start_sym_name)) @export(_start, .{ .name = start_sym_name }); | 34 | if (!@hasDecl(root, start_sym_name)) @export(_start, .{ .name = start_sym_name }); |
| 35 | } | 35 | } |
| 36 | } | 36 | } |
| ... | @@ -78,7 +78,7 @@ fn EfiMain(handle: uefi.Handle, system_table: *uefi.tables.SystemTable) callconv | ... | @@ -78,7 +78,7 @@ fn EfiMain(handle: uefi.Handle, system_table: *uefi.tables.SystemTable) callconv |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | fn _start() callconv(.Naked) noreturn { | 80 | fn _start() callconv(.Naked) noreturn { |
| 81 | if (builtin.os == builtin.Os.wasi) { | 81 | if (builtin.os.tag == .wasi) { |
| 82 | // This is marked inline because for some reason LLVM in release mode fails to inline it, | 82 | // This is marked inline because for some reason LLVM in release mode fails to inline it, |
| 83 | // and we want fewer call frames in stack traces. | 83 | // and we want fewer call frames in stack traces. |
| 84 | std.os.wasi.proc_exit(@call(.{ .modifier = .always_inline }, callMain, .{})); | 84 | std.os.wasi.proc_exit(@call(.{ .modifier = .always_inline }, callMain, .{})); |
| ... | @@ -133,7 +133,7 @@ fn WinMainCRTStartup() callconv(.Stdcall) noreturn { | ... | @@ -133,7 +133,7 @@ fn WinMainCRTStartup() callconv(.Stdcall) noreturn { |
| 133 | 133 | ||
| 134 | // TODO https://github.com/ziglang/zig/issues/265 | 134 | // TODO https://github.com/ziglang/zig/issues/265 |
| 135 | fn posixCallMainAndExit() noreturn { | 135 | fn posixCallMainAndExit() noreturn { |
| 136 | if (builtin.os == builtin.Os.freebsd) { | 136 | if (builtin.os.tag == .freebsd) { |
| 137 | @setAlignStack(16); | 137 | @setAlignStack(16); |
| 138 | } | 138 | } |
| 139 | const argc = starting_stack_ptr[0]; | 139 | const argc = starting_stack_ptr[0]; |
| ... | @@ -144,7 +144,7 @@ fn posixCallMainAndExit() noreturn { | ... | @@ -144,7 +144,7 @@ fn posixCallMainAndExit() noreturn { |
| 144 | while (envp_optional[envp_count]) |_| : (envp_count += 1) {} | 144 | while (envp_optional[envp_count]) |_| : (envp_count += 1) {} |
| 145 | const envp = @ptrCast([*][*:0]u8, envp_optional)[0..envp_count]; | 145 | const envp = @ptrCast([*][*:0]u8, envp_optional)[0..envp_count]; |
| 146 | 146 | ||
| 147 | if (builtin.os == .linux) { | 147 | if (builtin.os.tag == .linux) { |
| 148 | // Find the beginning of the auxiliary vector | 148 | // Find the beginning of the auxiliary vector |
| 149 | const auxv = @ptrCast([*]std.elf.Auxv, @alignCast(@alignOf(usize), envp.ptr + envp_count + 1)); | 149 | const auxv = @ptrCast([*]std.elf.Auxv, @alignCast(@alignOf(usize), envp.ptr + envp_count + 1)); |
| 150 | std.os.linux.elf_aux_maybe = auxv; | 150 | std.os.linux.elf_aux_maybe = auxv; |
lib/std/target.zig+602-621| ... | @@ -1,61 +1,291 @@ | ... | @@ -1,61 +1,291 @@ |
| 1 | const std = @import("std.zig"); | 1 | const std = @import("std.zig"); |
| 2 | const mem = std.mem; | 2 | const mem = std.mem; |
| 3 | const builtin = std.builtin; | 3 | const builtin = std.builtin; |
| 4 | const Version = std.builtin.Version; | ||
| 4 | 5 | ||
| 5 | /// TODO Nearly all the functions in this namespace would be | 6 | /// TODO Nearly all the functions in this namespace would be |
| 6 | /// better off if https://github.com/ziglang/zig/issues/425 | 7 | /// better off if https://github.com/ziglang/zig/issues/425 |
| 7 | /// was solved. | 8 | /// was solved. |
| 8 | pub const Target = union(enum) { | 9 | pub const Target = struct { |
| 9 | Native: void, | 10 | cpu: Cpu, |
| 10 | Cross: Cross, | 11 | os: Os, |
| 11 | 12 | abi: Abi, | |
| 12 | pub const Os = enum { | 13 | |
| 13 | freestanding, | 14 | pub const Os = struct { |
| 14 | ananas, | 15 | tag: Tag, |
| 15 | cloudabi, | 16 | version_range: VersionRange, |
| 16 | dragonfly, | 17 | |
| 17 | freebsd, | 18 | pub const Tag = enum { |
| 18 | fuchsia, | 19 | freestanding, |
| 19 | ios, | 20 | ananas, |
| 20 | kfreebsd, | 21 | cloudabi, |
| 21 | linux, | 22 | dragonfly, |
| 22 | lv2, | 23 | freebsd, |
| 23 | macosx, | 24 | fuchsia, |
| 24 | netbsd, | 25 | ios, |
| 25 | openbsd, | 26 | kfreebsd, |
| 26 | solaris, | 27 | linux, |
| 27 | windows, | 28 | lv2, |
| 28 | haiku, | 29 | macosx, |
| 29 | minix, | 30 | netbsd, |
| 30 | rtems, | 31 | openbsd, |
| 31 | nacl, | 32 | solaris, |
| 32 | cnk, | 33 | windows, |
| 33 | aix, | 34 | haiku, |
| 34 | cuda, | 35 | minix, |
| 35 | nvcl, | 36 | rtems, |
| 36 | amdhsa, | 37 | nacl, |
| 37 | ps4, | 38 | cnk, |
| 38 | elfiamcu, | 39 | aix, |
| 39 | tvos, | 40 | cuda, |
| 40 | watchos, | 41 | nvcl, |
| 41 | mesa3d, | 42 | amdhsa, |
| 42 | contiki, | 43 | ps4, |
| 43 | amdpal, | 44 | elfiamcu, |
| 44 | hermit, | 45 | tvos, |
| 45 | hurd, | 46 | watchos, |
| 46 | wasi, | 47 | mesa3d, |
| 47 | emscripten, | 48 | contiki, |
| 48 | uefi, | 49 | amdpal, |
| 49 | other, | 50 | hermit, |
| 50 | 51 | hurd, | |
| 51 | pub fn parse(text: []const u8) !Os { | 52 | wasi, |
| 52 | const info = @typeInfo(Os); | 53 | emscripten, |
| 53 | inline for (info.Enum.fields) |field| { | 54 | uefi, |
| 54 | if (mem.eql(u8, text, field.name)) { | 55 | other, |
| 55 | return @field(Os, field.name); | 56 | |
| 57 | pub fn isDarwin(tag: Tag) bool { | ||
| 58 | return switch (tag) { | ||
| 59 | .ios, .macosx, .watchos, .tvos => true, | ||
| 60 | else => false, | ||
| 61 | }; | ||
| 62 | } | ||
| 63 | |||
| 64 | pub fn dynamicLibSuffix(tag: Tag) [:0]const u8 { | ||
| 65 | if (tag.isDarwin()) { | ||
| 66 | return ".dylib"; | ||
| 67 | } | ||
| 68 | switch (tag) { | ||
| 69 | .windows => return ".dll", | ||
| 70 | else => return ".so", | ||
| 71 | } | ||
| 72 | } | ||
| 73 | }; | ||
| 74 | |||
| 75 | /// Based on NTDDI version constants from | ||
| 76 | /// https://docs.microsoft.com/en-us/cpp/porting/modifying-winver-and-win32-winnt | ||
| 77 | pub const WindowsVersion = enum(u32) { | ||
| 78 | nt4 = 0x04000000, | ||
| 79 | win2k = 0x05000000, | ||
| 80 | xp = 0x05010000, | ||
| 81 | ws2003 = 0x05020000, | ||
| 82 | vista = 0x06000000, | ||
| 83 | win7 = 0x06010000, | ||
| 84 | win8 = 0x06020000, | ||
| 85 | win8_1 = 0x06030000, | ||
| 86 | win10 = 0x0A000000, | ||
| 87 | win10_th2 = 0x0A000001, | ||
| 88 | win10_rs1 = 0x0A000002, | ||
| 89 | win10_rs2 = 0x0A000003, | ||
| 90 | win10_rs3 = 0x0A000004, | ||
| 91 | win10_rs4 = 0x0A000005, | ||
| 92 | win10_rs5 = 0x0A000006, | ||
| 93 | win10_19h1 = 0x0A000007, | ||
| 94 | _, | ||
| 95 | |||
| 96 | pub const Range = struct { | ||
| 97 | min: WindowsVersion, | ||
| 98 | max: WindowsVersion, | ||
| 99 | |||
| 100 | pub fn includesVersion(self: Range, ver: WindowsVersion) bool { | ||
| 101 | return @enumToInt(ver) >= @enumToInt(self.min) and @enumToInt(ver) <= @enumToInt(self.max); | ||
| 56 | } | 102 | } |
| 103 | }; | ||
| 104 | }; | ||
| 105 | |||
| 106 | pub const LinuxVersionRange = struct { | ||
| 107 | range: Version.Range, | ||
| 108 | glibc: Version, | ||
| 109 | |||
| 110 | pub fn includesVersion(self: LinuxVersionRange, ver: Version) bool { | ||
| 111 | return self.range.includesVersion(ver); | ||
| 57 | } | 112 | } |
| 58 | return error.UnknownOperatingSystem; | 113 | }; |
| 114 | |||
| 115 | /// The version ranges here represent the minimum OS version to be supported | ||
| 116 | /// and the maximum OS version to be supported. The default values represent | ||
| 117 | /// the range that the Zig Standard Library bases its abstractions on. | ||
| 118 | /// | ||
| 119 | /// The minimum version of the range is the main setting to tweak for a target. | ||
| 120 | /// Usually, the maximum target OS version will remain the default, which is | ||
| 121 | /// the latest released version of the OS. | ||
| 122 | /// | ||
| 123 | /// To test at compile time if the target is guaranteed to support a given OS feature, | ||
| 124 | /// one should check that the minimum version of the range is greater than or equal to | ||
| 125 | /// the version the feature was introduced in. | ||
| 126 | /// | ||
| 127 | /// To test at compile time if the target certainly will not support a given OS feature, | ||
| 128 | /// one should check that the maximum version of the range is less than the version the | ||
| 129 | /// feature was introduced in. | ||
| 130 | /// | ||
| 131 | /// If neither of these cases apply, a runtime check should be used to determine if the | ||
| 132 | /// target supports a given OS feature. | ||
| 133 | /// | ||
| 134 | /// Binaries built with a given maximum version will continue to function on newer operating system | ||
| 135 | /// versions. However, such a binary may not take full advantage of the newer operating system APIs. | ||
| 136 | pub const VersionRange = union { | ||
| 137 | none: void, | ||
| 138 | semver: Version.Range, | ||
| 139 | linux: LinuxVersionRange, | ||
| 140 | windows: WindowsVersion.Range, | ||
| 141 | |||
| 142 | /// The default `VersionRange` represents the range that the Zig Standard Library | ||
| 143 | /// bases its abstractions on. | ||
| 144 | pub fn default(tag: Tag) VersionRange { | ||
| 145 | switch (tag) { | ||
| 146 | .freestanding, | ||
| 147 | .ananas, | ||
| 148 | .cloudabi, | ||
| 149 | .dragonfly, | ||
| 150 | .fuchsia, | ||
| 151 | .kfreebsd, | ||
| 152 | .lv2, | ||
| 153 | .solaris, | ||
| 154 | .haiku, | ||
| 155 | .minix, | ||
| 156 | .rtems, | ||
| 157 | .nacl, | ||
| 158 | .cnk, | ||
| 159 | .aix, | ||
| 160 | .cuda, | ||
| 161 | .nvcl, | ||
| 162 | .amdhsa, | ||
| 163 | .ps4, | ||
| 164 | .elfiamcu, | ||
| 165 | .mesa3d, | ||
| 166 | .contiki, | ||
| 167 | .amdpal, | ||
| 168 | .hermit, | ||
| 169 | .hurd, | ||
| 170 | .wasi, | ||
| 171 | .emscripten, | ||
| 172 | .uefi, | ||
| 173 | .other, | ||
| 174 | => return .{ .none = {} }, | ||
| 175 | |||
| 176 | .freebsd => return .{ | ||
| 177 | .semver = Version.Range{ | ||
| 178 | .min = .{ .major = 12, .minor = 0 }, | ||
| 179 | .max = .{ .major = 12, .minor = 1 }, | ||
| 180 | }, | ||
| 181 | }, | ||
| 182 | .macosx => return .{ | ||
| 183 | .semver = .{ | ||
| 184 | .min = .{ .major = 10, .minor = 13 }, | ||
| 185 | .max = .{ .major = 10, .minor = 15, .patch = 3 }, | ||
| 186 | }, | ||
| 187 | }, | ||
| 188 | .ios => return .{ | ||
| 189 | .semver = .{ | ||
| 190 | .min = .{ .major = 12, .minor = 0 }, | ||
| 191 | .max = .{ .major = 13, .minor = 4, .patch = 0 }, | ||
| 192 | }, | ||
| 193 | }, | ||
| 194 | .watchos => return .{ | ||
| 195 | .semver = .{ | ||
| 196 | .min = .{ .major = 6, .minor = 0 }, | ||
| 197 | .max = .{ .major = 6, .minor = 2, .patch = 0 }, | ||
| 198 | }, | ||
| 199 | }, | ||
| 200 | .tvos => return .{ | ||
| 201 | .semver = .{ | ||
| 202 | .min = .{ .major = 13, .minor = 0 }, | ||
| 203 | .max = .{ .major = 13, .minor = 4, .patch = 0 }, | ||
| 204 | }, | ||
| 205 | }, | ||
| 206 | .netbsd => return .{ | ||
| 207 | .semver = .{ | ||
| 208 | .min = .{ .major = 8, .minor = 0 }, | ||
| 209 | .max = .{ .major = 9, .minor = 0 }, | ||
| 210 | }, | ||
| 211 | }, | ||
| 212 | .openbsd => return .{ | ||
| 213 | .semver = .{ | ||
| 214 | .min = .{ .major = 6, .minor = 6 }, | ||
| 215 | .max = .{ .major = 6, .minor = 6 }, | ||
| 216 | }, | ||
| 217 | }, | ||
| 218 | |||
| 219 | .linux => return .{ | ||
| 220 | .linux = .{ | ||
| 221 | .range = .{ | ||
| 222 | .min = .{ .major = 3, .minor = 16 }, | ||
| 223 | .max = .{ .major = 5, .minor = 5, .patch = 5 }, | ||
| 224 | }, | ||
| 225 | .glibc = .{ .major = 2, .minor = 17 }, | ||
| 226 | }, | ||
| 227 | }, | ||
| 228 | |||
| 229 | .windows => return .{ | ||
| 230 | .windows = .{ | ||
| 231 | .min = .win8_1, | ||
| 232 | .max = .win10_19h1, | ||
| 233 | }, | ||
| 234 | }, | ||
| 235 | } | ||
| 236 | } | ||
| 237 | }; | ||
| 238 | |||
| 239 | pub fn defaultVersionRange(tag: Tag) Os { | ||
| 240 | return .{ | ||
| 241 | .tag = tag, | ||
| 242 | .version_range = VersionRange.default(tag), | ||
| 243 | }; | ||
| 244 | } | ||
| 245 | |||
| 246 | pub fn requiresLibC(os: Os) bool { | ||
| 247 | return switch (os.tag) { | ||
| 248 | .freebsd, | ||
| 249 | .netbsd, | ||
| 250 | .macosx, | ||
| 251 | .ios, | ||
| 252 | .tvos, | ||
| 253 | .watchos, | ||
| 254 | .dragonfly, | ||
| 255 | .openbsd, | ||
| 256 | => true, | ||
| 257 | |||
| 258 | .linux, | ||
| 259 | .windows, | ||
| 260 | .freestanding, | ||
| 261 | .ananas, | ||
| 262 | .cloudabi, | ||
| 263 | .fuchsia, | ||
| 264 | .kfreebsd, | ||
| 265 | .lv2, | ||
| 266 | .solaris, | ||
| 267 | .haiku, | ||
| 268 | .minix, | ||
| 269 | .rtems, | ||
| 270 | .nacl, | ||
| 271 | .cnk, | ||
| 272 | .aix, | ||
| 273 | .cuda, | ||
| 274 | .nvcl, | ||
| 275 | .amdhsa, | ||
| 276 | .ps4, | ||
| 277 | .elfiamcu, | ||
| 278 | .mesa3d, | ||
| 279 | .contiki, | ||
| 280 | .amdpal, | ||
| 281 | .hermit, | ||
| 282 | .hurd, | ||
| 283 | .wasi, | ||
| 284 | .emscripten, | ||
| 285 | .uefi, | ||
| 286 | .other, | ||
| 287 | => false, | ||
| 288 | }; | ||
| 59 | } | 289 | } |
| 60 | }; | 290 | }; |
| 61 | 291 | ||
| ... | @@ -100,11 +330,10 @@ pub const Target = union(enum) { | ... | @@ -100,11 +330,10 @@ pub const Target = union(enum) { |
| 100 | macabi, | 330 | macabi, |
| 101 | 331 | ||
| 102 | pub fn default(arch: Cpu.Arch, target_os: Os) Abi { | 332 | pub fn default(arch: Cpu.Arch, target_os: Os) Abi { |
| 103 | switch (arch) { | 333 | if (arch.isWasm()) { |
| 104 | .wasm32, .wasm64 => return .musl, | 334 | return .musl; |
| 105 | else => {}, | ||
| 106 | } | 335 | } |
| 107 | switch (target_os) { | 336 | switch (target_os.tag) { |
| 108 | .freestanding, | 337 | .freestanding, |
| 109 | .ananas, | 338 | .ananas, |
| 110 | .cloudabi, | 339 | .cloudabi, |
| ... | @@ -149,14 +378,25 @@ pub const Target = union(enum) { | ... | @@ -149,14 +378,25 @@ pub const Target = union(enum) { |
| 149 | } | 378 | } |
| 150 | } | 379 | } |
| 151 | 380 | ||
| 152 | pub fn parse(text: []const u8) !Abi { | 381 | pub fn isGnu(abi: Abi) bool { |
| 153 | const info = @typeInfo(Abi); | 382 | return switch (abi) { |
| 154 | inline for (info.Enum.fields) |field| { | 383 | .gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => true, |
| 155 | if (mem.eql(u8, text, field.name)) { | 384 | else => false, |
| 156 | return @field(Abi, field.name); | 385 | }; |
| 157 | } | 386 | } |
| 158 | } | 387 | |
| 159 | return error.UnknownApplicationBinaryInterface; | 388 | pub fn isMusl(abi: Abi) bool { |
| 389 | return switch (abi) { | ||
| 390 | .musl, .musleabi, .musleabihf => true, | ||
| 391 | else => false, | ||
| 392 | }; | ||
| 393 | } | ||
| 394 | |||
| 395 | pub fn oFileExt(abi: Abi) [:0]const u8 { | ||
| 396 | return switch (abi) { | ||
| 397 | .msvc => ".obj", | ||
| 398 | else => ".o", | ||
| 399 | }; | ||
| 160 | } | 400 | } |
| 161 | }; | 401 | }; |
| 162 | 402 | ||
| ... | @@ -179,12 +419,6 @@ pub const Target = union(enum) { | ... | @@ -179,12 +419,6 @@ pub const Target = union(enum) { |
| 179 | EfiRuntimeDriver, | 419 | EfiRuntimeDriver, |
| 180 | }; | 420 | }; |
| 181 | 421 | ||
| 182 | pub const Cross = struct { | ||
| 183 | cpu: Cpu, | ||
| 184 | os: Os, | ||
| 185 | abi: Abi, | ||
| 186 | }; | ||
| 187 | |||
| 188 | pub const Cpu = struct { | 422 | pub const Cpu = struct { |
| 189 | /// Architecture | 423 | /// Architecture |
| 190 | arch: Arch, | 424 | arch: Arch, |
| ... | @@ -230,6 +464,12 @@ pub const Target = union(enum) { | ... | @@ -230,6 +464,12 @@ pub const Target = union(enum) { |
| 230 | return Set{ .ints = [1]usize{0} ** usize_count }; | 464 | return Set{ .ints = [1]usize{0} ** usize_count }; |
| 231 | } | 465 | } |
| 232 | 466 | ||
| 467 | pub fn isEmpty(set: Set) bool { | ||
| 468 | return for (set.ints) |x| { | ||
| 469 | if (x != 0) break false; | ||
| 470 | } else true; | ||
| 471 | } | ||
| 472 | |||
| 233 | pub fn isEnabled(set: Set, arch_feature_index: Index) bool { | 473 | pub fn isEnabled(set: Set, arch_feature_index: Index) bool { |
| 234 | const usize_index = arch_feature_index / @bitSizeOf(usize); | 474 | const usize_index = arch_feature_index / @bitSizeOf(usize); |
| 235 | const bit_index = @intCast(ShiftInt, arch_feature_index % @bitSizeOf(usize)); | 475 | const bit_index = @intCast(ShiftInt, arch_feature_index % @bitSizeOf(usize)); |
| ... | @@ -256,6 +496,15 @@ pub const Target = union(enum) { | ... | @@ -256,6 +496,15 @@ pub const Target = union(enum) { |
| 256 | set.ints[usize_index] &= ~(@as(usize, 1) << bit_index); | 496 | set.ints[usize_index] &= ~(@as(usize, 1) << bit_index); |
| 257 | } | 497 | } |
| 258 | 498 | ||
| 499 | /// Removes the specified feature but not its dependents. | ||
| 500 | pub fn removeFeatureSet(set: *Set, other_set: Set) void { | ||
| 501 | // TODO should be able to use binary not on @Vector type. | ||
| 502 | // https://github.com/ziglang/zig/issues/903 | ||
| 503 | for (set.ints) |*int, i| { | ||
| 504 | int.* &= ~other_set.ints[i]; | ||
| 505 | } | ||
| 506 | } | ||
| 507 | |||
| 259 | pub fn populateDependencies(set: *Set, all_features_list: []const Cpu.Feature) void { | 508 | pub fn populateDependencies(set: *Set, all_features_list: []const Cpu.Feature) void { |
| 260 | @setEvalBranchQuota(1000000); | 509 | @setEvalBranchQuota(1000000); |
| 261 | 510 | ||
| ... | @@ -393,7 +642,7 @@ pub const Target = union(enum) { | ... | @@ -393,7 +642,7 @@ pub const Target = union(enum) { |
| 393 | return cpu; | 642 | return cpu; |
| 394 | } | 643 | } |
| 395 | } | 644 | } |
| 396 | return error.UnknownCpu; | 645 | return error.UnknownCpuModel; |
| 397 | } | 646 | } |
| 398 | 647 | ||
| 399 | pub fn toElfMachine(arch: Arch) std.elf.EM { | 648 | pub fn toElfMachine(arch: Arch) std.elf.EM { |
| ... | @@ -509,6 +758,66 @@ pub const Target = union(enum) { | ... | @@ -509,6 +758,66 @@ pub const Target = union(enum) { |
| 509 | }; | 758 | }; |
| 510 | } | 759 | } |
| 511 | 760 | ||
| 761 | pub fn ptrBitWidth(arch: Arch) u32 { | ||
| 762 | switch (arch) { | ||
| 763 | .avr, | ||
| 764 | .msp430, | ||
| 765 | => return 16, | ||
| 766 | |||
| 767 | .arc, | ||
| 768 | .arm, | ||
| 769 | .armeb, | ||
| 770 | .hexagon, | ||
| 771 | .le32, | ||
| 772 | .mips, | ||
| 773 | .mipsel, | ||
| 774 | .powerpc, | ||
| 775 | .r600, | ||
| 776 | .riscv32, | ||
| 777 | .sparc, | ||
| 778 | .sparcel, | ||
| 779 | .tce, | ||
| 780 | .tcele, | ||
| 781 | .thumb, | ||
| 782 | .thumbeb, | ||
| 783 | .i386, | ||
| 784 | .xcore, | ||
| 785 | .nvptx, | ||
| 786 | .amdil, | ||
| 787 | .hsail, | ||
| 788 | .spir, | ||
| 789 | .kalimba, | ||
| 790 | .shave, | ||
| 791 | .lanai, | ||
| 792 | .wasm32, | ||
| 793 | .renderscript32, | ||
| 794 | .aarch64_32, | ||
| 795 | => return 32, | ||
| 796 | |||
| 797 | .aarch64, | ||
| 798 | .aarch64_be, | ||
| 799 | .mips64, | ||
| 800 | .mips64el, | ||
| 801 | .powerpc64, | ||
| 802 | .powerpc64le, | ||
| 803 | .riscv64, | ||
| 804 | .x86_64, | ||
| 805 | .nvptx64, | ||
| 806 | .le64, | ||
| 807 | .amdil64, | ||
| 808 | .hsail64, | ||
| 809 | .spir64, | ||
| 810 | .wasm64, | ||
| 811 | .renderscript64, | ||
| 812 | .amdgcn, | ||
| 813 | .bpfel, | ||
| 814 | .bpfeb, | ||
| 815 | .sparcv9, | ||
| 816 | .s390x, | ||
| 817 | => return 64, | ||
| 818 | } | ||
| 819 | } | ||
| 820 | |||
| 512 | /// Returns a name that matches the lib/std/target/* directory name. | 821 | /// Returns a name that matches the lib/std/target/* directory name. |
| 513 | pub fn genericName(arch: Arch) []const u8 { | 822 | pub fn genericName(arch: Arch) []const u8 { |
| 514 | return switch (arch) { | 823 | return switch (arch) { |
| ... | @@ -576,16 +885,6 @@ pub const Target = union(enum) { | ... | @@ -576,16 +885,6 @@ pub const Target = union(enum) { |
| 576 | else => &[0]*const Model{}, | 885 | else => &[0]*const Model{}, |
| 577 | }; | 886 | }; |
| 578 | } | 887 | } |
| 579 | |||
| 580 | pub fn parse(text: []const u8) !Arch { | ||
| 581 | const info = @typeInfo(Arch); | ||
| 582 | inline for (info.Enum.fields) |field| { | ||
| 583 | if (mem.eql(u8, text, field.name)) { | ||
| 584 | return @as(Arch, @field(Arch, field.name)); | ||
| 585 | } | ||
| 586 | } | ||
| 587 | return error.UnknownArchitecture; | ||
| 588 | } | ||
| 589 | }; | 888 | }; |
| 590 | 889 | ||
| 591 | pub const Model = struct { | 890 | pub const Model = struct { |
| ... | @@ -602,524 +901,168 @@ pub const Target = union(enum) { | ... | @@ -602,524 +901,168 @@ pub const Target = union(enum) { |
| 602 | .features = features, | 901 | .features = features, |
| 603 | }; | 902 | }; |
| 604 | } | 903 | } |
| 904 | |||
| 905 | pub fn baseline(arch: Arch) *const Model { | ||
| 906 | const S = struct { | ||
| 907 | const generic_model = Model{ | ||
| 908 | .name = "generic", | ||
| 909 | .llvm_name = null, | ||
| 910 | .features = Cpu.Feature.Set.empty, | ||
| 911 | }; | ||
| 912 | }; | ||
| 913 | return switch (arch) { | ||
| 914 | .arm, .armeb, .thumb, .thumbeb => &arm.cpu.baseline, | ||
| 915 | .aarch64, .aarch64_be, .aarch64_32 => &aarch64.cpu.generic, | ||
| 916 | .avr => &avr.cpu.avr1, | ||
| 917 | .bpfel, .bpfeb => &bpf.cpu.generic, | ||
| 918 | .hexagon => &hexagon.cpu.generic, | ||
| 919 | .mips, .mipsel => &mips.cpu.mips32, | ||
| 920 | .mips64, .mips64el => &mips.cpu.mips64, | ||
| 921 | .msp430 => &msp430.cpu.generic, | ||
| 922 | .powerpc, .powerpc64, .powerpc64le => &powerpc.cpu.generic, | ||
| 923 | .amdgcn => &amdgpu.cpu.generic, | ||
| 924 | .riscv32 => &riscv.cpu.baseline_rv32, | ||
| 925 | .riscv64 => &riscv.cpu.baseline_rv64, | ||
| 926 | .sparc, .sparcv9, .sparcel => &sparc.cpu.generic, | ||
| 927 | .s390x => &systemz.cpu.generic, | ||
| 928 | .i386 => &x86.cpu.pentium4, | ||
| 929 | .x86_64 => &x86.cpu.x86_64, | ||
| 930 | .nvptx, .nvptx64 => &nvptx.cpu.sm_20, | ||
| 931 | .wasm32, .wasm64 => &wasm.cpu.generic, | ||
| 932 | |||
| 933 | else => &S.generic_model, | ||
| 934 | }; | ||
| 935 | } | ||
| 605 | }; | 936 | }; |
| 606 | 937 | ||
| 607 | /// The "default" set of CPU features for cross-compiling. A conservative set | 938 | /// The "default" set of CPU features for cross-compiling. A conservative set |
| 608 | /// of features that is expected to be supported on most available hardware. | 939 | /// of features that is expected to be supported on most available hardware. |
| 609 | pub fn baseline(arch: Arch) Cpu { | 940 | pub fn baseline(arch: Arch) Cpu { |
| 610 | const S = struct { | 941 | return Model.baseline(arch).toCpu(arch); |
| 611 | const generic_model = Model{ | ||
| 612 | .name = "generic", | ||
| 613 | .llvm_name = null, | ||
| 614 | .features = Cpu.Feature.Set.empty, | ||
| 615 | }; | ||
| 616 | }; | ||
| 617 | const model = switch (arch) { | ||
| 618 | .arm, .armeb, .thumb, .thumbeb => &arm.cpu.baseline, | ||
| 619 | .aarch64, .aarch64_be, .aarch64_32 => &aarch64.cpu.generic, | ||
| 620 | .avr => &avr.cpu.avr1, | ||
| 621 | .bpfel, .bpfeb => &bpf.cpu.generic, | ||
| 622 | .hexagon => &hexagon.cpu.generic, | ||
| 623 | .mips, .mipsel => &mips.cpu.mips32, | ||
| 624 | .mips64, .mips64el => &mips.cpu.mips64, | ||
| 625 | .msp430 => &msp430.cpu.generic, | ||
| 626 | .powerpc, .powerpc64, .powerpc64le => &powerpc.cpu.generic, | ||
| 627 | .amdgcn => &amdgpu.cpu.generic, | ||
| 628 | .riscv32 => &riscv.cpu.baseline_rv32, | ||
| 629 | .riscv64 => &riscv.cpu.baseline_rv64, | ||
| 630 | .sparc, .sparcv9, .sparcel => &sparc.cpu.generic, | ||
| 631 | .s390x => &systemz.cpu.generic, | ||
| 632 | .i386 => &x86.cpu.pentium4, | ||
| 633 | .x86_64 => &x86.cpu.x86_64, | ||
| 634 | .nvptx, .nvptx64 => &nvptx.cpu.sm_20, | ||
| 635 | .wasm32, .wasm64 => &wasm.cpu.generic, | ||
| 636 | |||
| 637 | else => &S.generic_model, | ||
| 638 | }; | ||
| 639 | return model.toCpu(arch); | ||
| 640 | } | 942 | } |
| 641 | }; | 943 | }; |
| 642 | 944 | ||
| 643 | pub const current = Target{ | 945 | pub const current = Target{ |
| 644 | .Cross = Cross{ | 946 | .cpu = builtin.cpu, |
| 645 | .cpu = builtin.cpu, | 947 | .os = builtin.os, |
| 646 | .os = builtin.os, | 948 | .abi = builtin.abi, |
| 647 | .abi = builtin.abi, | ||
| 648 | }, | ||
| 649 | }; | 949 | }; |
| 650 | 950 | ||
| 651 | pub const stack_align = 16; | 951 | pub const stack_align = 16; |
| 652 | 952 | ||
| 653 | pub fn zigTriple(self: Target, allocator: *mem.Allocator) ![]u8 { | 953 | pub fn zigTriple(self: Target, allocator: *mem.Allocator) ![:0]u8 { |
| 654 | return std.fmt.allocPrint(allocator, "{}-{}-{}", .{ | 954 | return std.zig.CrossTarget.fromTarget(self).zigTriple(allocator); |
| 655 | @tagName(self.getArch()), | ||
| 656 | @tagName(self.getOs()), | ||
| 657 | @tagName(self.getAbi()), | ||
| 658 | }); | ||
| 659 | } | ||
| 660 | |||
| 661 | /// Returned slice must be freed by the caller. | ||
| 662 | pub fn vcpkgTriplet(allocator: *mem.Allocator, target: Target, linkage: std.build.VcpkgLinkage) ![]const u8 { | ||
| 663 | const arch = switch (target.getArch()) { | ||
| 664 | .i386 => "x86", | ||
| 665 | .x86_64 => "x64", | ||
| 666 | |||
| 667 | .arm, | ||
| 668 | .armeb, | ||
| 669 | .thumb, | ||
| 670 | .thumbeb, | ||
| 671 | .aarch64_32, | ||
| 672 | => "arm", | ||
| 673 | |||
| 674 | .aarch64, | ||
| 675 | .aarch64_be, | ||
| 676 | => "arm64", | ||
| 677 | |||
| 678 | else => return error.VcpkgNoSuchArchitecture, | ||
| 679 | }; | ||
| 680 | |||
| 681 | const os = switch (target.getOs()) { | ||
| 682 | .windows => "windows", | ||
| 683 | .linux => "linux", | ||
| 684 | .macosx => "macos", | ||
| 685 | else => return error.VcpkgNoSuchOs, | ||
| 686 | }; | ||
| 687 | |||
| 688 | if (linkage == .Static) { | ||
| 689 | return try mem.join(allocator, "-", &[_][]const u8{ arch, os, "static" }); | ||
| 690 | } else { | ||
| 691 | return try mem.join(allocator, "-", &[_][]const u8{ arch, os }); | ||
| 692 | } | ||
| 693 | } | 955 | } |
| 694 | 956 | ||
| 695 | pub fn allocDescription(self: Target, allocator: *mem.Allocator) ![]u8 { | 957 | pub fn linuxTripleSimple(allocator: *mem.Allocator, cpu_arch: Cpu.Arch, os_tag: Os.Tag, abi: Abi) ![:0]u8 { |
| 696 | // TODO is there anything else worthy of the description that is not | 958 | return std.fmt.allocPrint0(allocator, "{}-{}-{}", .{ @tagName(cpu_arch), @tagName(os_tag), @tagName(abi) }); |
| 697 | // already captured in the triple? | ||
| 698 | return self.zigTriple(allocator); | ||
| 699 | } | 959 | } |
| 700 | 960 | ||
| 701 | pub fn zigTripleNoSubArch(self: Target, allocator: *mem.Allocator) ![]u8 { | 961 | pub fn linuxTriple(self: Target, allocator: *mem.Allocator) ![:0]u8 { |
| 702 | return std.fmt.allocPrint(allocator, "{}-{}-{}", .{ | 962 | return linuxTripleSimple(allocator, self.cpu.arch, self.os.tag, self.abi); |
| 703 | @tagName(self.getArch()), | ||
| 704 | @tagName(self.getOs()), | ||
| 705 | @tagName(self.getAbi()), | ||
| 706 | }); | ||
| 707 | } | 963 | } |
| 708 | 964 | ||
| 709 | pub fn linuxTriple(self: Target, allocator: *mem.Allocator) ![]u8 { | 965 | pub fn oFileExt(self: Target) [:0]const u8 { |
| 710 | return std.fmt.allocPrint(allocator, "{}-{}-{}", .{ | 966 | return self.abi.oFileExt(); |
| 711 | @tagName(self.getArch()), | ||
| 712 | @tagName(self.getOs()), | ||
| 713 | @tagName(self.getAbi()), | ||
| 714 | }); | ||
| 715 | } | 967 | } |
| 716 | 968 | ||
| 717 | pub const ParseOptions = struct { | 969 | pub fn exeFileExtSimple(cpu_arch: Cpu.Arch, os_tag: Os.Tag) [:0]const u8 { |
| 718 | /// This is sometimes called a "triple". It looks roughly like this: | 970 | switch (os_tag) { |
| 719 | /// riscv64-linux-gnu | 971 | .windows => return ".exe", |
| 720 | /// The fields are, respectively: | 972 | .uefi => return ".efi", |
| 721 | /// * CPU Architecture | 973 | else => if (cpu_arch.isWasm()) { |
| 722 | /// * Operating System | 974 | return ".wasm"; |
| 723 | /// * C ABI (optional) | 975 | } else { |
| 724 | arch_os_abi: []const u8, | 976 | return ""; |
| 725 | 977 | }, | |
| 726 | /// Looks like "name+a+b-c-d+e", where "name" is a CPU Model name, "a", "b", and "e" | ||
| 727 | /// are examples of CPU features to add to the set, and "c" and "d" are examples of CPU features | ||
| 728 | /// to remove from the set. | ||
| 729 | cpu_features: []const u8 = "baseline", | ||
| 730 | |||
| 731 | /// If this is provided, the function will populate some information about parsing failures, | ||
| 732 | /// so that user-friendly error messages can be delivered. | ||
| 733 | diagnostics: ?*Diagnostics = null, | ||
| 734 | |||
| 735 | pub const Diagnostics = struct { | ||
| 736 | /// If the architecture was determined, this will be populated. | ||
| 737 | arch: ?Cpu.Arch = null, | ||
| 738 | |||
| 739 | /// If the OS was determined, this will be populated. | ||
| 740 | os: ?Os = null, | ||
| 741 | |||
| 742 | /// If the ABI was determined, this will be populated. | ||
| 743 | abi: ?Abi = null, | ||
| 744 | |||
| 745 | /// If the CPU name was determined, this will be populated. | ||
| 746 | cpu_name: ?[]const u8 = null, | ||
| 747 | |||
| 748 | /// If error.UnknownCpuFeature is returned, this will be populated. | ||
| 749 | unknown_feature_name: ?[]const u8 = null, | ||
| 750 | }; | ||
| 751 | }; | ||
| 752 | |||
| 753 | pub fn parse(args: ParseOptions) !Target { | ||
| 754 | var dummy_diags: ParseOptions.Diagnostics = undefined; | ||
| 755 | var diags = args.diagnostics orelse &dummy_diags; | ||
| 756 | |||
| 757 | var it = mem.separate(args.arch_os_abi, "-"); | ||
| 758 | const arch_name = it.next() orelse return error.MissingArchitecture; | ||
| 759 | const arch = try Cpu.Arch.parse(arch_name); | ||
| 760 | diags.arch = arch; | ||
| 761 | |||
| 762 | const os_name = it.next() orelse return error.MissingOperatingSystem; | ||
| 763 | const os = try Os.parse(os_name); | ||
| 764 | diags.os = os; | ||
| 765 | |||
| 766 | const abi_name = it.next(); | ||
| 767 | const abi = if (abi_name) |n| try Abi.parse(n) else Abi.default(arch, os); | ||
| 768 | diags.abi = abi; | ||
| 769 | |||
| 770 | if (it.next() != null) return error.UnexpectedExtraField; | ||
| 771 | |||
| 772 | const all_features = arch.allFeaturesList(); | ||
| 773 | var index: usize = 0; | ||
| 774 | while (index < args.cpu_features.len and | ||
| 775 | args.cpu_features[index] != '+' and | ||
| 776 | args.cpu_features[index] != '-') | ||
| 777 | { | ||
| 778 | index += 1; | ||
| 779 | } | 978 | } |
| 780 | const cpu_name = args.cpu_features[0..index]; | ||
| 781 | diags.cpu_name = cpu_name; | ||
| 782 | |||
| 783 | const cpu: Cpu = if (mem.eql(u8, cpu_name, "baseline")) Cpu.baseline(arch) else blk: { | ||
| 784 | const cpu_model = try arch.parseCpuModel(cpu_name); | ||
| 785 | |||
| 786 | var set = cpu_model.features; | ||
| 787 | while (index < args.cpu_features.len) { | ||
| 788 | const op = args.cpu_features[index]; | ||
| 789 | index += 1; | ||
| 790 | const start = index; | ||
| 791 | while (index < args.cpu_features.len and | ||
| 792 | args.cpu_features[index] != '+' and | ||
| 793 | args.cpu_features[index] != '-') | ||
| 794 | { | ||
| 795 | index += 1; | ||
| 796 | } | ||
| 797 | const feature_name = args.cpu_features[start..index]; | ||
| 798 | for (all_features) |feature, feat_index_usize| { | ||
| 799 | const feat_index = @intCast(Cpu.Feature.Set.Index, feat_index_usize); | ||
| 800 | if (mem.eql(u8, feature_name, feature.name)) { | ||
| 801 | switch (op) { | ||
| 802 | '+' => set.addFeature(feat_index), | ||
| 803 | '-' => set.removeFeature(feat_index), | ||
| 804 | else => unreachable, | ||
| 805 | } | ||
| 806 | break; | ||
| 807 | } | ||
| 808 | } else { | ||
| 809 | diags.unknown_feature_name = feature_name; | ||
| 810 | return error.UnknownCpuFeature; | ||
| 811 | } | ||
| 812 | } | ||
| 813 | set.populateDependencies(all_features); | ||
| 814 | break :blk .{ | ||
| 815 | .arch = arch, | ||
| 816 | .model = cpu_model, | ||
| 817 | .features = set, | ||
| 818 | }; | ||
| 819 | }; | ||
| 820 | var cross = Cross{ | ||
| 821 | .cpu = cpu, | ||
| 822 | .os = os, | ||
| 823 | .abi = abi, | ||
| 824 | }; | ||
| 825 | return Target{ .Cross = cross }; | ||
| 826 | } | 979 | } |
| 827 | 980 | ||
| 828 | pub fn oFileExt(self: Target) []const u8 { | 981 | pub fn exeFileExt(self: Target) [:0]const u8 { |
| 829 | return switch (self.getAbi()) { | 982 | return exeFileExtSimple(self.cpu.arch, self.os.tag); |
| 830 | .msvc => ".obj", | ||
| 831 | else => ".o", | ||
| 832 | }; | ||
| 833 | } | 983 | } |
| 834 | 984 | ||
| 835 | pub fn exeFileExt(self: Target) []const u8 { | 985 | pub fn staticLibSuffix_cpu_arch_abi(cpu_arch: Cpu.Arch, abi: Abi) [:0]const u8 { |
| 836 | if (self.isWindows()) { | 986 | if (cpu_arch.isWasm()) { |
| 837 | return ".exe"; | ||
| 838 | } else if (self.isUefi()) { | ||
| 839 | return ".efi"; | ||
| 840 | } else if (self.isWasm()) { | ||
| 841 | return ".wasm"; | 987 | return ".wasm"; |
| 842 | } else { | ||
| 843 | return ""; | ||
| 844 | } | 988 | } |
| 845 | } | 989 | switch (abi) { |
| 846 | |||
| 847 | pub fn staticLibSuffix(self: Target) []const u8 { | ||
| 848 | if (self.isWasm()) { | ||
| 849 | return ".wasm"; | ||
| 850 | } | ||
| 851 | switch (self.getAbi()) { | ||
| 852 | .msvc => return ".lib", | 990 | .msvc => return ".lib", |
| 853 | else => return ".a", | 991 | else => return ".a", |
| 854 | } | 992 | } |
| 855 | } | 993 | } |
| 856 | 994 | ||
| 857 | pub fn dynamicLibSuffix(self: Target) []const u8 { | 995 | pub fn staticLibSuffix(self: Target) [:0]const u8 { |
| 858 | if (self.isDarwin()) { | 996 | return staticLibSuffix_cpu_arch_abi(self.cpu.arch, self.abi); |
| 859 | return ".dylib"; | 997 | } |
| 860 | } | 998 | |
| 861 | switch (self.getOs()) { | 999 | pub fn dynamicLibSuffix(self: Target) [:0]const u8 { |
| 862 | .windows => return ".dll", | 1000 | return self.os.tag.dynamicLibSuffix(); |
| 863 | else => return ".so", | ||
| 864 | } | ||
| 865 | } | 1001 | } |
| 866 | 1002 | ||
| 867 | pub fn libPrefix(self: Target) []const u8 { | 1003 | pub fn libPrefix_cpu_arch_abi(cpu_arch: Cpu.Arch, abi: Abi) [:0]const u8 { |
| 868 | if (self.isWasm()) { | 1004 | if (cpu_arch.isWasm()) { |
| 869 | return ""; | 1005 | return ""; |
| 870 | } | 1006 | } |
| 871 | switch (self.getAbi()) { | 1007 | switch (abi) { |
| 872 | .msvc => return "", | 1008 | .msvc => return "", |
| 873 | else => return "lib", | 1009 | else => return "lib", |
| 874 | } | 1010 | } |
| 875 | } | 1011 | } |
| 876 | 1012 | ||
| 877 | pub fn getOs(self: Target) Os { | 1013 | pub fn libPrefix(self: Target) [:0]const u8 { |
| 878 | return switch (self) { | 1014 | return libPrefix_cpu_arch_abi(self.cpu.arch, self.abi); |
| 879 | .Native => builtin.os, | ||
| 880 | .Cross => |t| t.os, | ||
| 881 | }; | ||
| 882 | } | ||
| 883 | |||
| 884 | pub fn getCpu(self: Target) Cpu { | ||
| 885 | return switch (self) { | ||
| 886 | .Native => builtin.cpu, | ||
| 887 | .Cross => |cross| cross.cpu, | ||
| 888 | }; | ||
| 889 | } | ||
| 890 | |||
| 891 | pub fn getArch(self: Target) Cpu.Arch { | ||
| 892 | return self.getCpu().arch; | ||
| 893 | } | ||
| 894 | |||
| 895 | pub fn getAbi(self: Target) Abi { | ||
| 896 | switch (self) { | ||
| 897 | .Native => return builtin.abi, | ||
| 898 | .Cross => |t| return t.abi, | ||
| 899 | } | ||
| 900 | } | 1015 | } |
| 901 | 1016 | ||
| 902 | pub fn getObjectFormat(self: Target) ObjectFormat { | 1017 | pub fn getObjectFormat(self: Target) ObjectFormat { |
| 903 | switch (self) { | 1018 | if (self.os.tag == .windows or self.os.tag == .uefi) { |
| 904 | .Native => return @import("builtin").object_format, | 1019 | return .coff; |
| 905 | .Cross => blk: { | 1020 | } else if (self.isDarwin()) { |
| 906 | if (self.isWindows() or self.isUefi()) { | 1021 | return .macho; |
| 907 | return .coff; | 1022 | } |
| 908 | } else if (self.isDarwin()) { | 1023 | if (self.cpu.arch.isWasm()) { |
| 909 | return .macho; | 1024 | return .wasm; |
| 910 | } | ||
| 911 | if (self.isWasm()) { | ||
| 912 | return .wasm; | ||
| 913 | } | ||
| 914 | return .elf; | ||
| 915 | }, | ||
| 916 | } | 1025 | } |
| 1026 | return .elf; | ||
| 917 | } | 1027 | } |
| 918 | 1028 | ||
| 919 | pub fn isMinGW(self: Target) bool { | 1029 | pub fn isMinGW(self: Target) bool { |
| 920 | return self.isWindows() and self.isGnu(); | 1030 | return self.os.tag == .windows and self.isGnu(); |
| 921 | } | 1031 | } |
| 922 | 1032 | ||
| 923 | pub fn isGnu(self: Target) bool { | 1033 | pub fn isGnu(self: Target) bool { |
| 924 | return switch (self.getAbi()) { | 1034 | return self.abi.isGnu(); |
| 925 | .gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => true, | ||
| 926 | else => false, | ||
| 927 | }; | ||
| 928 | } | 1035 | } |
| 929 | 1036 | ||
| 930 | pub fn isMusl(self: Target) bool { | 1037 | pub fn isMusl(self: Target) bool { |
| 931 | return switch (self.getAbi()) { | 1038 | return self.abi.isMusl(); |
| 932 | .musl, .musleabi, .musleabihf => true, | ||
| 933 | else => false, | ||
| 934 | }; | ||
| 935 | } | ||
| 936 | |||
| 937 | pub fn isDarwin(self: Target) bool { | ||
| 938 | return switch (self.getOs()) { | ||
| 939 | .ios, .macosx, .watchos, .tvos => true, | ||
| 940 | else => false, | ||
| 941 | }; | ||
| 942 | } | ||
| 943 | |||
| 944 | pub fn isWindows(self: Target) bool { | ||
| 945 | return switch (self.getOs()) { | ||
| 946 | .windows => true, | ||
| 947 | else => false, | ||
| 948 | }; | ||
| 949 | } | ||
| 950 | |||
| 951 | pub fn isLinux(self: Target) bool { | ||
| 952 | return switch (self.getOs()) { | ||
| 953 | .linux => true, | ||
| 954 | else => false, | ||
| 955 | }; | ||
| 956 | } | 1039 | } |
| 957 | 1040 | ||
| 958 | pub fn isAndroid(self: Target) bool { | 1041 | pub fn isAndroid(self: Target) bool { |
| 959 | return switch (self.getAbi()) { | 1042 | return switch (self.abi) { |
| 960 | .android => true, | 1043 | .android => true, |
| 961 | else => false, | 1044 | else => false, |
| 962 | }; | 1045 | }; |
| 963 | } | 1046 | } |
| 964 | 1047 | ||
| 965 | pub fn isDragonFlyBSD(self: Target) bool { | ||
| 966 | return switch (self.getOs()) { | ||
| 967 | .dragonfly => true, | ||
| 968 | else => false, | ||
| 969 | }; | ||
| 970 | } | ||
| 971 | |||
| 972 | pub fn isUefi(self: Target) bool { | ||
| 973 | return switch (self.getOs()) { | ||
| 974 | .uefi => true, | ||
| 975 | else => false, | ||
| 976 | }; | ||
| 977 | } | ||
| 978 | |||
| 979 | pub fn isWasm(self: Target) bool { | 1048 | pub fn isWasm(self: Target) bool { |
| 980 | return switch (self.getArch()) { | 1049 | return self.cpu.arch.isWasm(); |
| 981 | .wasm32, .wasm64 => true, | ||
| 982 | else => false, | ||
| 983 | }; | ||
| 984 | } | ||
| 985 | |||
| 986 | pub fn isFreeBSD(self: Target) bool { | ||
| 987 | return switch (self.getOs()) { | ||
| 988 | .freebsd => true, | ||
| 989 | else => false, | ||
| 990 | }; | ||
| 991 | } | 1050 | } |
| 992 | 1051 | ||
| 993 | pub fn isNetBSD(self: Target) bool { | 1052 | pub fn isDarwin(self: Target) bool { |
| 994 | return switch (self.getOs()) { | 1053 | return self.os.tag.isDarwin(); |
| 995 | .netbsd => true, | ||
| 996 | else => false, | ||
| 997 | }; | ||
| 998 | } | 1054 | } |
| 999 | 1055 | ||
| 1000 | pub fn wantSharedLibSymLinks(self: Target) bool { | 1056 | pub fn isGnuLibC_os_tag_abi(os_tag: Os.Tag, abi: Abi) bool { |
| 1001 | return !self.isWindows(); | 1057 | return os_tag == .linux and abi.isGnu(); |
| 1002 | } | 1058 | } |
| 1003 | 1059 | ||
| 1004 | pub fn osRequiresLibC(self: Target) bool { | 1060 | pub fn isGnuLibC(self: Target) bool { |
| 1005 | return self.isDarwin() or self.isFreeBSD() or self.isNetBSD(); | 1061 | return isGnuLibC_os_tag_abi(self.os.tag, self.abi); |
| 1006 | } | ||
| 1007 | |||
| 1008 | pub fn getArchPtrBitWidth(self: Target) u32 { | ||
| 1009 | switch (self.getArch()) { | ||
| 1010 | .avr, | ||
| 1011 | .msp430, | ||
| 1012 | => return 16, | ||
| 1013 | |||
| 1014 | .arc, | ||
| 1015 | .arm, | ||
| 1016 | .armeb, | ||
| 1017 | .hexagon, | ||
| 1018 | .le32, | ||
| 1019 | .mips, | ||
| 1020 | .mipsel, | ||
| 1021 | .powerpc, | ||
| 1022 | .r600, | ||
| 1023 | .riscv32, | ||
| 1024 | .sparc, | ||
| 1025 | .sparcel, | ||
| 1026 | .tce, | ||
| 1027 | .tcele, | ||
| 1028 | .thumb, | ||
| 1029 | .thumbeb, | ||
| 1030 | .i386, | ||
| 1031 | .xcore, | ||
| 1032 | .nvptx, | ||
| 1033 | .amdil, | ||
| 1034 | .hsail, | ||
| 1035 | .spir, | ||
| 1036 | .kalimba, | ||
| 1037 | .shave, | ||
| 1038 | .lanai, | ||
| 1039 | .wasm32, | ||
| 1040 | .renderscript32, | ||
| 1041 | .aarch64_32, | ||
| 1042 | => return 32, | ||
| 1043 | |||
| 1044 | .aarch64, | ||
| 1045 | .aarch64_be, | ||
| 1046 | .mips64, | ||
| 1047 | .mips64el, | ||
| 1048 | .powerpc64, | ||
| 1049 | .powerpc64le, | ||
| 1050 | .riscv64, | ||
| 1051 | .x86_64, | ||
| 1052 | .nvptx64, | ||
| 1053 | .le64, | ||
| 1054 | .amdil64, | ||
| 1055 | .hsail64, | ||
| 1056 | .spir64, | ||
| 1057 | .wasm64, | ||
| 1058 | .renderscript64, | ||
| 1059 | .amdgcn, | ||
| 1060 | .bpfel, | ||
| 1061 | .bpfeb, | ||
| 1062 | .sparcv9, | ||
| 1063 | .s390x, | ||
| 1064 | => return 64, | ||
| 1065 | } | ||
| 1066 | } | 1062 | } |
| 1067 | 1063 | ||
| 1068 | pub fn supportsNewStackCall(self: Target) bool { | 1064 | pub fn supportsNewStackCall(self: Target) bool { |
| 1069 | return !self.isWasm(); | 1065 | return !self.cpu.arch.isWasm(); |
| 1070 | } | ||
| 1071 | |||
| 1072 | pub const Executor = union(enum) { | ||
| 1073 | native, | ||
| 1074 | qemu: []const u8, | ||
| 1075 | wine: []const u8, | ||
| 1076 | wasmtime: []const u8, | ||
| 1077 | unavailable, | ||
| 1078 | }; | ||
| 1079 | |||
| 1080 | pub fn getExternalExecutor(self: Target) Executor { | ||
| 1081 | if (@as(@TagType(Target), self) == .Native) return .native; | ||
| 1082 | |||
| 1083 | // If the target OS matches the host OS, we can use QEMU to emulate a foreign architecture. | ||
| 1084 | if (self.getOs() == builtin.os) { | ||
| 1085 | return switch (self.getArch()) { | ||
| 1086 | .aarch64 => Executor{ .qemu = "qemu-aarch64" }, | ||
| 1087 | .aarch64_be => Executor{ .qemu = "qemu-aarch64_be" }, | ||
| 1088 | .arm => Executor{ .qemu = "qemu-arm" }, | ||
| 1089 | .armeb => Executor{ .qemu = "qemu-armeb" }, | ||
| 1090 | .i386 => Executor{ .qemu = "qemu-i386" }, | ||
| 1091 | .mips => Executor{ .qemu = "qemu-mips" }, | ||
| 1092 | .mipsel => Executor{ .qemu = "qemu-mipsel" }, | ||
| 1093 | .mips64 => Executor{ .qemu = "qemu-mips64" }, | ||
| 1094 | .mips64el => Executor{ .qemu = "qemu-mips64el" }, | ||
| 1095 | .powerpc => Executor{ .qemu = "qemu-ppc" }, | ||
| 1096 | .powerpc64 => Executor{ .qemu = "qemu-ppc64" }, | ||
| 1097 | .powerpc64le => Executor{ .qemu = "qemu-ppc64le" }, | ||
| 1098 | .riscv32 => Executor{ .qemu = "qemu-riscv32" }, | ||
| 1099 | .riscv64 => Executor{ .qemu = "qemu-riscv64" }, | ||
| 1100 | .s390x => Executor{ .qemu = "qemu-s390x" }, | ||
| 1101 | .sparc => Executor{ .qemu = "qemu-sparc" }, | ||
| 1102 | .x86_64 => Executor{ .qemu = "qemu-x86_64" }, | ||
| 1103 | else => return .unavailable, | ||
| 1104 | }; | ||
| 1105 | } | ||
| 1106 | |||
| 1107 | if (self.isWindows()) { | ||
| 1108 | switch (self.getArchPtrBitWidth()) { | ||
| 1109 | 32 => return Executor{ .wine = "wine" }, | ||
| 1110 | 64 => return Executor{ .wine = "wine64" }, | ||
| 1111 | else => return .unavailable, | ||
| 1112 | } | ||
| 1113 | } | ||
| 1114 | |||
| 1115 | if (self.getOs() == .wasi) { | ||
| 1116 | switch (self.getArchPtrBitWidth()) { | ||
| 1117 | 32 => return Executor{ .wasmtime = "wasmtime" }, | ||
| 1118 | else => return .unavailable, | ||
| 1119 | } | ||
| 1120 | } | ||
| 1121 | |||
| 1122 | return .unavailable; | ||
| 1123 | } | 1066 | } |
| 1124 | 1067 | ||
| 1125 | pub const FloatAbi = enum { | 1068 | pub const FloatAbi = enum { |
| ... | @@ -1129,7 +1072,7 @@ pub const Target = union(enum) { | ... | @@ -1129,7 +1072,7 @@ pub const Target = union(enum) { |
| 1129 | }; | 1072 | }; |
| 1130 | 1073 | ||
| 1131 | pub fn getFloatAbi(self: Target) FloatAbi { | 1074 | pub fn getFloatAbi(self: Target) FloatAbi { |
| 1132 | return switch (self.getAbi()) { | 1075 | return switch (self.abi) { |
| 1133 | .gnueabihf, | 1076 | .gnueabihf, |
| 1134 | .eabihf, | 1077 | .eabihf, |
| 1135 | .musleabihf, | 1078 | .musleabihf, |
| ... | @@ -1139,13 +1082,10 @@ pub const Target = union(enum) { | ... | @@ -1139,13 +1082,10 @@ pub const Target = union(enum) { |
| 1139 | } | 1082 | } |
| 1140 | 1083 | ||
| 1141 | pub fn hasDynamicLinker(self: Target) bool { | 1084 | pub fn hasDynamicLinker(self: Target) bool { |
| 1142 | switch (self.getArch()) { | 1085 | if (self.cpu.arch.isWasm()) { |
| 1143 | .wasm32, | 1086 | return false; |
| 1144 | .wasm64, | ||
| 1145 | => return false, | ||
| 1146 | else => {}, | ||
| 1147 | } | 1087 | } |
| 1148 | switch (self.getOs()) { | 1088 | switch (self.os.tag) { |
| 1149 | .freestanding, | 1089 | .freestanding, |
| 1150 | .ios, | 1090 | .ios, |
| 1151 | .tvos, | 1091 | .tvos, |
| ... | @@ -1160,65 +1100,95 @@ pub const Target = union(enum) { | ... | @@ -1160,65 +1100,95 @@ pub const Target = union(enum) { |
| 1160 | } | 1100 | } |
| 1161 | } | 1101 | } |
| 1162 | 1102 | ||
| 1163 | /// Caller owns returned memory. | 1103 | pub const DynamicLinker = struct { |
| 1164 | pub fn getStandardDynamicLinkerPath( | 1104 | /// Contains the memory used to store the dynamic linker path. This field should |
| 1165 | self: Target, | 1105 | /// not be used directly. See `get` and `set`. This field exists so that this API requires no allocator. |
| 1166 | allocator: *mem.Allocator, | 1106 | buffer: [255]u8 = undefined, |
| 1167 | ) error{ | 1107 | |
| 1168 | OutOfMemory, | 1108 | /// Used to construct the dynamic linker path. This field should not be used |
| 1169 | UnknownDynamicLinkerPath, | 1109 | /// directly. See `get` and `set`. |
| 1170 | TargetHasNoDynamicLinker, | 1110 | max_byte: ?u8 = null, |
| 1171 | }![:0]u8 { | 1111 | |
| 1172 | const a = allocator; | 1112 | /// Asserts that the length is less than or equal to 255 bytes. |
| 1173 | if (self.isAndroid()) { | 1113 | pub fn init(dl_or_null: ?[]const u8) DynamicLinker { |
| 1174 | return mem.dupeZ(a, u8, if (self.getArchPtrBitWidth() == 64) | 1114 | var result: DynamicLinker = undefined; |
| 1175 | "/system/bin/linker64" | 1115 | result.set(dl_or_null); |
| 1176 | else | 1116 | return result; |
| 1177 | "/system/bin/linker"); | ||
| 1178 | } | 1117 | } |
| 1179 | 1118 | ||
| 1180 | if (self.isMusl()) { | 1119 | /// The returned memory has the same lifetime as the `DynamicLinker`. |
| 1181 | var result = try std.Buffer.init(allocator, "/lib/ld-musl-"); | 1120 | pub fn get(self: *const DynamicLinker) ?[]const u8 { |
| 1182 | defer result.deinit(); | 1121 | const m: usize = self.max_byte orelse return null; |
| 1183 | 1122 | return self.buffer[0 .. m + 1]; | |
| 1184 | var is_arm = false; | 1123 | } |
| 1185 | switch (self.getArch()) { | 1124 | |
| 1186 | .arm, .thumb => { | 1125 | /// Asserts that the length is less than or equal to 255 bytes. |
| 1187 | try result.append("arm"); | 1126 | pub fn set(self: *DynamicLinker, dl_or_null: ?[]const u8) void { |
| 1188 | is_arm = true; | 1127 | if (dl_or_null) |dl| { |
| 1189 | }, | 1128 | mem.copy(u8, &self.buffer, dl); |
| 1190 | .armeb, .thumbeb => { | 1129 | self.max_byte = @intCast(u8, dl.len - 1); |
| 1191 | try result.append("armeb"); | 1130 | } else { |
| 1192 | is_arm = true; | 1131 | self.max_byte = null; |
| 1193 | }, | 1132 | } |
| 1194 | else => |arch| try result.append(@tagName(arch)), | 1133 | } |
| 1134 | }; | ||
| 1135 | |||
| 1136 | /// The result will be a byte index *pointing at the final byte*. In other words, length minus one. | ||
| 1137 | /// A return value of `null` means the concept of a dynamic linker is not meaningful for that target. | ||
| 1138 | pub fn standardDynamicLinkerPath(self: Target) DynamicLinker { | ||
| 1139 | var result: DynamicLinker = .{}; | ||
| 1140 | const S = struct { | ||
| 1141 | fn print(r: *DynamicLinker, comptime fmt: []const u8, args: var) DynamicLinker { | ||
| 1142 | r.max_byte = @intCast(u8, (std.fmt.bufPrint(&r.buffer, fmt, args) catch unreachable).len - 1); | ||
| 1143 | return r.*; | ||
| 1195 | } | 1144 | } |
| 1196 | if (is_arm and self.getFloatAbi() == .hard) { | 1145 | fn copy(r: *DynamicLinker, s: []const u8) DynamicLinker { |
| 1197 | try result.append("hf"); | 1146 | mem.copy(u8, &r.buffer, s); |
| 1147 | r.max_byte = @intCast(u8, s.len - 1); | ||
| 1148 | return r.*; | ||
| 1198 | } | 1149 | } |
| 1199 | try result.append(".so.1"); | 1150 | }; |
| 1200 | return result.toOwnedSlice(); | 1151 | const print = S.print; |
| 1152 | const copy = S.copy; | ||
| 1153 | |||
| 1154 | if (self.isAndroid()) { | ||
| 1155 | const suffix = if (self.cpu.arch.ptrBitWidth() == 64) "64" else ""; | ||
| 1156 | return print(&result, "/system/bin/linker{}", .{suffix}); | ||
| 1201 | } | 1157 | } |
| 1202 | 1158 | ||
| 1203 | switch (self.getOs()) { | 1159 | if (self.isMusl()) { |
| 1204 | .freebsd => return mem.dupeZ(a, u8, "/libexec/ld-elf.so.1"), | 1160 | const is_arm = switch (self.cpu.arch) { |
| 1205 | .netbsd => return mem.dupeZ(a, u8, "/libexec/ld.elf_so"), | 1161 | .arm, .armeb, .thumb, .thumbeb => true, |
| 1206 | .dragonfly => return mem.dupeZ(a, u8, "/libexec/ld-elf.so.2"), | 1162 | else => false, |
| 1207 | .linux => switch (self.getArch()) { | 1163 | }; |
| 1164 | const arch_part = switch (self.cpu.arch) { | ||
| 1165 | .arm, .thumb => "arm", | ||
| 1166 | .armeb, .thumbeb => "armeb", | ||
| 1167 | else => |arch| @tagName(arch), | ||
| 1168 | }; | ||
| 1169 | const arch_suffix = if (is_arm and self.getFloatAbi() == .hard) "hf" else ""; | ||
| 1170 | return print(&result, "/lib/ld-musl-{}{}.so.1", .{ arch_part, arch_suffix }); | ||
| 1171 | } | ||
| 1172 | |||
| 1173 | switch (self.os.tag) { | ||
| 1174 | .freebsd => return copy(&result, "/libexec/ld-elf.so.1"), | ||
| 1175 | .netbsd => return copy(&result, "/libexec/ld.elf_so"), | ||
| 1176 | .dragonfly => return copy(&result, "/libexec/ld-elf.so.2"), | ||
| 1177 | .linux => switch (self.cpu.arch) { | ||
| 1208 | .i386, | 1178 | .i386, |
| 1209 | .sparc, | 1179 | .sparc, |
| 1210 | .sparcel, | 1180 | .sparcel, |
| 1211 | => return mem.dupeZ(a, u8, "/lib/ld-linux.so.2"), | 1181 | => return copy(&result, "/lib/ld-linux.so.2"), |
| 1212 | 1182 | ||
| 1213 | .aarch64 => return mem.dupeZ(a, u8, "/lib/ld-linux-aarch64.so.1"), | 1183 | .aarch64 => return copy(&result, "/lib/ld-linux-aarch64.so.1"), |
| 1214 | .aarch64_be => return mem.dupeZ(a, u8, "/lib/ld-linux-aarch64_be.so.1"), | 1184 | .aarch64_be => return copy(&result, "/lib/ld-linux-aarch64_be.so.1"), |
| 1215 | .aarch64_32 => return mem.dupeZ(a, u8, "/lib/ld-linux-aarch64_32.so.1"), | 1185 | .aarch64_32 => return copy(&result, "/lib/ld-linux-aarch64_32.so.1"), |
| 1216 | 1186 | ||
| 1217 | .arm, | 1187 | .arm, |
| 1218 | .armeb, | 1188 | .armeb, |
| 1219 | .thumb, | 1189 | .thumb, |
| 1220 | .thumbeb, | 1190 | .thumbeb, |
| 1221 | => return mem.dupeZ(a, u8, switch (self.getFloatAbi()) { | 1191 | => return copy(&result, switch (self.getFloatAbi()) { |
| 1222 | .hard => "/lib/ld-linux-armhf.so.3", | 1192 | .hard => "/lib/ld-linux-armhf.so.3", |
| 1223 | else => "/lib/ld-linux.so.3", | 1193 | else => "/lib/ld-linux.so.3", |
| 1224 | }), | 1194 | }), |
| ... | @@ -1227,28 +1197,43 @@ pub const Target = union(enum) { | ... | @@ -1227,28 +1197,43 @@ pub const Target = union(enum) { |
| 1227 | .mipsel, | 1197 | .mipsel, |
| 1228 | .mips64, | 1198 | .mips64, |
| 1229 | .mips64el, | 1199 | .mips64el, |
| 1230 | => return error.UnknownDynamicLinkerPath, | 1200 | => { |
| 1201 | const lib_suffix = switch (self.abi) { | ||
| 1202 | .gnuabin32, .gnux32 => "32", | ||
| 1203 | .gnuabi64 => "64", | ||
| 1204 | else => "", | ||
| 1205 | }; | ||
| 1206 | const is_nan_2008 = mips.featureSetHas(self.cpu.features, .nan2008); | ||
| 1207 | const loader = if (is_nan_2008) "ld-linux-mipsn8.so.1" else "ld.so.1"; | ||
| 1208 | return print(&result, "/lib{}/{}", .{ lib_suffix, loader }); | ||
| 1209 | }, | ||
| 1231 | 1210 | ||
| 1232 | .powerpc => return mem.dupeZ(a, u8, "/lib/ld.so.1"), | 1211 | .powerpc => return copy(&result, "/lib/ld.so.1"), |
| 1233 | .powerpc64, .powerpc64le => return mem.dupeZ(a, u8, "/lib64/ld64.so.2"), | 1212 | .powerpc64, .powerpc64le => return copy(&result, "/lib64/ld64.so.2"), |
| 1234 | .s390x => return mem.dupeZ(a, u8, "/lib64/ld64.so.1"), | 1213 | .s390x => return copy(&result, "/lib64/ld64.so.1"), |
| 1235 | .sparcv9 => return mem.dupeZ(a, u8, "/lib64/ld-linux.so.2"), | 1214 | .sparcv9 => return copy(&result, "/lib64/ld-linux.so.2"), |
| 1236 | .x86_64 => return mem.dupeZ(a, u8, switch (self.getAbi()) { | 1215 | .x86_64 => return copy(&result, switch (self.abi) { |
| 1237 | .gnux32 => "/libx32/ld-linux-x32.so.2", | 1216 | .gnux32 => "/libx32/ld-linux-x32.so.2", |
| 1238 | else => "/lib64/ld-linux-x86-64.so.2", | 1217 | else => "/lib64/ld-linux-x86-64.so.2", |
| 1239 | }), | 1218 | }), |
| 1240 | 1219 | ||
| 1241 | .riscv32 => return mem.dupeZ(a, u8, "/lib/ld-linux-riscv32-ilp32.so.1"), | 1220 | .riscv32 => return copy(&result, "/lib/ld-linux-riscv32-ilp32.so.1"), |
| 1242 | .riscv64 => return mem.dupeZ(a, u8, "/lib/ld-linux-riscv64-lp64.so.1"), | 1221 | .riscv64 => return copy(&result, "/lib/ld-linux-riscv64-lp64.so.1"), |
| 1243 | 1222 | ||
| 1223 | // Architectures in this list have been verified as not having a standard | ||
| 1224 | // dynamic linker path. | ||
| 1244 | .wasm32, | 1225 | .wasm32, |
| 1245 | .wasm64, | 1226 | .wasm64, |
| 1246 | => return error.TargetHasNoDynamicLinker, | 1227 | .bpfel, |
| 1228 | .bpfeb, | ||
| 1229 | .nvptx, | ||
| 1230 | .nvptx64, | ||
| 1231 | => return result, | ||
| 1247 | 1232 | ||
| 1233 | // TODO go over each item in this list and either move it to the above list, or | ||
| 1234 | // implement the standard dynamic linker path code for it. | ||
| 1248 | .arc, | 1235 | .arc, |
| 1249 | .avr, | 1236 | .avr, |
| 1250 | .bpfel, | ||
| 1251 | .bpfeb, | ||
| 1252 | .hexagon, | 1237 | .hexagon, |
| 1253 | .msp430, | 1238 | .msp430, |
| 1254 | .r600, | 1239 | .r600, |
| ... | @@ -1256,8 +1241,6 @@ pub const Target = union(enum) { | ... | @@ -1256,8 +1241,6 @@ pub const Target = union(enum) { |
| 1256 | .tce, | 1241 | .tce, |
| 1257 | .tcele, | 1242 | .tcele, |
| 1258 | .xcore, | 1243 | .xcore, |
| 1259 | .nvptx, | ||
| 1260 | .nvptx64, | ||
| 1261 | .le32, | 1244 | .le32, |
| 1262 | .le64, | 1245 | .le64, |
| 1263 | .amdil, | 1246 | .amdil, |
| ... | @@ -1271,9 +1254,11 @@ pub const Target = union(enum) { | ... | @@ -1271,9 +1254,11 @@ pub const Target = union(enum) { |
| 1271 | .lanai, | 1254 | .lanai, |
| 1272 | .renderscript32, | 1255 | .renderscript32, |
| 1273 | .renderscript64, | 1256 | .renderscript64, |
| 1274 | => return error.UnknownDynamicLinkerPath, | 1257 | => return result, |
| 1275 | }, | 1258 | }, |
| 1276 | 1259 | ||
| 1260 | // Operating systems in this list have been verified as not having a standard | ||
| 1261 | // dynamic linker path. | ||
| 1277 | .freestanding, | 1262 | .freestanding, |
| 1278 | .ios, | 1263 | .ios, |
| 1279 | .tvos, | 1264 | .tvos, |
| ... | @@ -1282,40 +1267,36 @@ pub const Target = union(enum) { | ... | @@ -1282,40 +1267,36 @@ pub const Target = union(enum) { |
| 1282 | .uefi, | 1267 | .uefi, |
| 1283 | .windows, | 1268 | .windows, |
| 1284 | .emscripten, | 1269 | .emscripten, |
| 1270 | .wasi, | ||
| 1285 | .other, | 1271 | .other, |
| 1286 | => return error.TargetHasNoDynamicLinker, | 1272 | => return result, |
| 1287 | 1273 | ||
| 1288 | else => return error.UnknownDynamicLinkerPath, | 1274 | // TODO go over each item in this list and either move it to the above list, or |
| 1275 | // implement the standard dynamic linker path code for it. | ||
| 1276 | .ananas, | ||
| 1277 | .cloudabi, | ||
| 1278 | .fuchsia, | ||
| 1279 | .kfreebsd, | ||
| 1280 | .lv2, | ||
| 1281 | .openbsd, | ||
| 1282 | .solaris, | ||
| 1283 | .haiku, | ||
| 1284 | .minix, | ||
| 1285 | .rtems, | ||
| 1286 | .nacl, | ||
| 1287 | .cnk, | ||
| 1288 | .aix, | ||
| 1289 | .cuda, | ||
| 1290 | .nvcl, | ||
| 1291 | .amdhsa, | ||
| 1292 | .ps4, | ||
| 1293 | .elfiamcu, | ||
| 1294 | .mesa3d, | ||
| 1295 | .contiki, | ||
| 1296 | .amdpal, | ||
| 1297 | .hermit, | ||
| 1298 | .hurd, | ||
| 1299 | => return result, | ||
| 1289 | } | 1300 | } |
| 1290 | } | 1301 | } |
| 1291 | }; | 1302 | }; |
| 1292 | |||
| 1293 | test "Target.parse" { | ||
| 1294 | { | ||
| 1295 | const target = (try Target.parse(.{ | ||
| 1296 | .arch_os_abi = "x86_64-linux-gnu", | ||
| 1297 | .cpu_features = "x86_64-sse-sse2-avx-cx8", | ||
| 1298 | })).Cross; | ||
| 1299 | |||
| 1300 | std.testing.expect(target.os == .linux); | ||
| 1301 | std.testing.expect(target.abi == .gnu); | ||
| 1302 | std.testing.expect(target.cpu.arch == .x86_64); | ||
| 1303 | std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .sse)); | ||
| 1304 | std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .avx)); | ||
| 1305 | std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .cx8)); | ||
| 1306 | std.testing.expect(Target.x86.featureSetHas(target.cpu.features, .cmov)); | ||
| 1307 | std.testing.expect(Target.x86.featureSetHas(target.cpu.features, .fxsr)); | ||
| 1308 | } | ||
| 1309 | { | ||
| 1310 | const target = (try Target.parse(.{ | ||
| 1311 | .arch_os_abi = "arm-linux-musleabihf", | ||
| 1312 | .cpu_features = "generic+v8a", | ||
| 1313 | })).Cross; | ||
| 1314 | |||
| 1315 | std.testing.expect(target.os == .linux); | ||
| 1316 | std.testing.expect(target.abi == .musleabihf); | ||
| 1317 | std.testing.expect(target.cpu.arch == .arm); | ||
| 1318 | std.testing.expect(target.cpu.model == &Target.arm.cpu.generic); | ||
| 1319 | std.testing.expect(Target.arm.featureSetHas(target.cpu.features, .v8a)); | ||
| 1320 | } | ||
| 1321 | } |
lib/std/testing.zig+4-6| ... | @@ -1,5 +1,3 @@ | ... | @@ -1,5 +1,3 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 2 | const TypeId = builtin.TypeId; | ||
| 3 | const std = @import("std.zig"); | 1 | const std = @import("std.zig"); |
| 4 | 2 | ||
| 5 | pub const LeakCountAllocator = @import("testing/leak_count_allocator.zig").LeakCountAllocator; | 3 | pub const LeakCountAllocator = @import("testing/leak_count_allocator.zig").LeakCountAllocator; |
| ... | @@ -65,16 +63,16 @@ pub fn expectEqual(expected: var, actual: @TypeOf(expected)) void { | ... | @@ -65,16 +63,16 @@ pub fn expectEqual(expected: var, actual: @TypeOf(expected)) void { |
| 65 | 63 | ||
| 66 | .Pointer => |pointer| { | 64 | .Pointer => |pointer| { |
| 67 | switch (pointer.size) { | 65 | switch (pointer.size) { |
| 68 | builtin.TypeInfo.Pointer.Size.One, | 66 | .One, |
| 69 | builtin.TypeInfo.Pointer.Size.Many, | 67 | .Many, |
| 70 | builtin.TypeInfo.Pointer.Size.C, | 68 | .C, |
| 71 | => { | 69 | => { |
| 72 | if (actual != expected) { | 70 | if (actual != expected) { |
| 73 | std.debug.panic("expected {*}, found {*}", .{ expected, actual }); | 71 | std.debug.panic("expected {*}, found {*}", .{ expected, actual }); |
| 74 | } | 72 | } |
| 75 | }, | 73 | }, |
| 76 | 74 | ||
| 77 | builtin.TypeInfo.Pointer.Size.Slice => { | 75 | .Slice => { |
| 78 | if (actual.ptr != expected.ptr) { | 76 | if (actual.ptr != expected.ptr) { |
| 79 | std.debug.panic("expected slice ptr {}, found {}", .{ expected.ptr, actual.ptr }); | 77 | std.debug.panic("expected slice ptr {}, found {}", .{ expected.ptr, actual.ptr }); |
| 80 | } | 78 | } |
lib/std/thread.zig+10-10| ... | @@ -9,14 +9,14 @@ const assert = std.debug.assert; | ... | @@ -9,14 +9,14 @@ const assert = std.debug.assert; |
| 9 | pub const Thread = struct { | 9 | pub const Thread = struct { |
| 10 | data: Data, | 10 | data: Data, |
| 11 | 11 | ||
| 12 | pub const use_pthreads = builtin.os != .windows and builtin.link_libc; | 12 | pub const use_pthreads = builtin.os.tag != .windows and builtin.link_libc; |
| 13 | 13 | ||
| 14 | /// Represents a kernel thread handle. | 14 | /// Represents a kernel thread handle. |
| 15 | /// May be an integer or a pointer depending on the platform. | 15 | /// May be an integer or a pointer depending on the platform. |
| 16 | /// On Linux and POSIX, this is the same as Id. | 16 | /// On Linux and POSIX, this is the same as Id. |
| 17 | pub const Handle = if (use_pthreads) | 17 | pub const Handle = if (use_pthreads) |
| 18 | c.pthread_t | 18 | c.pthread_t |
| 19 | else switch (builtin.os) { | 19 | else switch (builtin.os.tag) { |
| 20 | .linux => i32, | 20 | .linux => i32, |
| 21 | .windows => windows.HANDLE, | 21 | .windows => windows.HANDLE, |
| 22 | else => void, | 22 | else => void, |
| ... | @@ -25,7 +25,7 @@ pub const Thread = struct { | ... | @@ -25,7 +25,7 @@ pub const Thread = struct { |
| 25 | /// Represents a unique ID per thread. | 25 | /// Represents a unique ID per thread. |
| 26 | /// May be an integer or pointer depending on the platform. | 26 | /// May be an integer or pointer depending on the platform. |
| 27 | /// On Linux and POSIX, this is the same as Handle. | 27 | /// On Linux and POSIX, this is the same as Handle. |
| 28 | pub const Id = switch (builtin.os) { | 28 | pub const Id = switch (builtin.os.tag) { |
| 29 | .windows => windows.DWORD, | 29 | .windows => windows.DWORD, |
| 30 | else => Handle, | 30 | else => Handle, |
| 31 | }; | 31 | }; |
| ... | @@ -35,7 +35,7 @@ pub const Thread = struct { | ... | @@ -35,7 +35,7 @@ pub const Thread = struct { |
| 35 | handle: Thread.Handle, | 35 | handle: Thread.Handle, |
| 36 | memory: []align(mem.page_size) u8, | 36 | memory: []align(mem.page_size) u8, |
| 37 | } | 37 | } |
| 38 | else switch (builtin.os) { | 38 | else switch (builtin.os.tag) { |
| 39 | .linux => struct { | 39 | .linux => struct { |
| 40 | handle: Thread.Handle, | 40 | handle: Thread.Handle, |
| 41 | memory: []align(mem.page_size) u8, | 41 | memory: []align(mem.page_size) u8, |
| ... | @@ -55,7 +55,7 @@ pub const Thread = struct { | ... | @@ -55,7 +55,7 @@ pub const Thread = struct { |
| 55 | if (use_pthreads) { | 55 | if (use_pthreads) { |
| 56 | return c.pthread_self(); | 56 | return c.pthread_self(); |
| 57 | } else | 57 | } else |
| 58 | return switch (builtin.os) { | 58 | return switch (builtin.os.tag) { |
| 59 | .linux => os.linux.gettid(), | 59 | .linux => os.linux.gettid(), |
| 60 | .windows => windows.kernel32.GetCurrentThreadId(), | 60 | .windows => windows.kernel32.GetCurrentThreadId(), |
| 61 | else => @compileError("Unsupported OS"), | 61 | else => @compileError("Unsupported OS"), |
| ... | @@ -83,7 +83,7 @@ pub const Thread = struct { | ... | @@ -83,7 +83,7 @@ pub const Thread = struct { |
| 83 | else => unreachable, | 83 | else => unreachable, |
| 84 | } | 84 | } |
| 85 | os.munmap(self.data.memory); | 85 | os.munmap(self.data.memory); |
| 86 | } else switch (builtin.os) { | 86 | } else switch (builtin.os.tag) { |
| 87 | .linux => { | 87 | .linux => { |
| 88 | while (true) { | 88 | while (true) { |
| 89 | const pid_value = @atomicLoad(i32, &self.data.handle, .SeqCst); | 89 | const pid_value = @atomicLoad(i32, &self.data.handle, .SeqCst); |
| ... | @@ -150,7 +150,7 @@ pub const Thread = struct { | ... | @@ -150,7 +150,7 @@ pub const Thread = struct { |
| 150 | const Context = @TypeOf(context); | 150 | const Context = @TypeOf(context); |
| 151 | comptime assert(@typeInfo(@TypeOf(startFn)).Fn.args[0].arg_type.? == Context); | 151 | comptime assert(@typeInfo(@TypeOf(startFn)).Fn.args[0].arg_type.? == Context); |
| 152 | 152 | ||
| 153 | if (builtin.os == builtin.Os.windows) { | 153 | if (builtin.os.tag == .windows) { |
| 154 | const WinThread = struct { | 154 | const WinThread = struct { |
| 155 | const OuterContext = struct { | 155 | const OuterContext = struct { |
| 156 | thread: Thread, | 156 | thread: Thread, |
| ... | @@ -309,7 +309,7 @@ pub const Thread = struct { | ... | @@ -309,7 +309,7 @@ pub const Thread = struct { |
| 309 | os.EINVAL => unreachable, | 309 | os.EINVAL => unreachable, |
| 310 | else => return os.unexpectedErrno(@intCast(usize, err)), | 310 | else => return os.unexpectedErrno(@intCast(usize, err)), |
| 311 | } | 311 | } |
| 312 | } else if (builtin.os == .linux) { | 312 | } else if (builtin.os.tag == .linux) { |
| 313 | var flags: u32 = os.CLONE_VM | os.CLONE_FS | os.CLONE_FILES | os.CLONE_SIGHAND | | 313 | var flags: u32 = os.CLONE_VM | os.CLONE_FS | os.CLONE_FILES | os.CLONE_SIGHAND | |
| 314 | os.CLONE_THREAD | os.CLONE_SYSVSEM | os.CLONE_PARENT_SETTID | os.CLONE_CHILD_CLEARTID | | 314 | os.CLONE_THREAD | os.CLONE_SYSVSEM | os.CLONE_PARENT_SETTID | os.CLONE_CHILD_CLEARTID | |
| 315 | os.CLONE_DETACHED; | 315 | os.CLONE_DETACHED; |
| ... | @@ -369,11 +369,11 @@ pub const Thread = struct { | ... | @@ -369,11 +369,11 @@ pub const Thread = struct { |
| 369 | }; | 369 | }; |
| 370 | 370 | ||
| 371 | pub fn cpuCount() CpuCountError!usize { | 371 | pub fn cpuCount() CpuCountError!usize { |
| 372 | if (builtin.os == .linux) { | 372 | if (builtin.os.tag == .linux) { |
| 373 | const cpu_set = try os.sched_getaffinity(0); | 373 | const cpu_set = try os.sched_getaffinity(0); |
| 374 | return @as(usize, os.CPU_COUNT(cpu_set)); // TODO should not need this usize cast | 374 | return @as(usize, os.CPU_COUNT(cpu_set)); // TODO should not need this usize cast |
| 375 | } | 375 | } |
| 376 | if (builtin.os == .windows) { | 376 | if (builtin.os.tag == .windows) { |
| 377 | var system_info: windows.SYSTEM_INFO = undefined; | 377 | var system_info: windows.SYSTEM_INFO = undefined; |
| 378 | windows.kernel32.GetSystemInfo(&system_info); | 378 | windows.kernel32.GetSystemInfo(&system_info); |
| 379 | return @intCast(usize, system_info.dwNumberOfProcessors); | 379 | return @intCast(usize, system_info.dwNumberOfProcessors); |
lib/std/time.zig+10-8| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 2 | const std = @import("std.zig"); | 1 | const std = @import("std.zig"); |
| 2 | const builtin = std.builtin; | ||
| 3 | const assert = std.debug.assert; | 3 | const assert = std.debug.assert; |
| 4 | const testing = std.testing; | 4 | const testing = std.testing; |
| 5 | const os = std.os; | 5 | const os = std.os; |
| ... | @@ -7,10 +7,12 @@ const math = std.math; | ... | @@ -7,10 +7,12 @@ const math = std.math; |
| 7 | 7 | ||
| 8 | pub const epoch = @import("time/epoch.zig"); | 8 | pub const epoch = @import("time/epoch.zig"); |
| 9 | 9 | ||
| 10 | const is_windows = std.Target.current.os.tag == .windows; | ||
| 11 | |||
| 10 | /// Spurious wakeups are possible and no precision of timing is guaranteed. | 12 | /// Spurious wakeups are possible and no precision of timing is guaranteed. |
| 11 | /// TODO integrate with evented I/O | 13 | /// TODO integrate with evented I/O |
| 12 | pub fn sleep(nanoseconds: u64) void { | 14 | pub fn sleep(nanoseconds: u64) void { |
| 13 | if (builtin.os == .windows) { | 15 | if (is_windows) { |
| 14 | const ns_per_ms = ns_per_s / ms_per_s; | 16 | const ns_per_ms = ns_per_s / ms_per_s; |
| 15 | const big_ms_from_ns = nanoseconds / ns_per_ms; | 17 | const big_ms_from_ns = nanoseconds / ns_per_ms; |
| 16 | const ms = math.cast(os.windows.DWORD, big_ms_from_ns) catch math.maxInt(os.windows.DWORD); | 18 | const ms = math.cast(os.windows.DWORD, big_ms_from_ns) catch math.maxInt(os.windows.DWORD); |
| ... | @@ -31,7 +33,7 @@ pub fn timestamp() u64 { | ... | @@ -31,7 +33,7 @@ pub fn timestamp() u64 { |
| 31 | /// Get the posix timestamp, UTC, in milliseconds | 33 | /// Get the posix timestamp, UTC, in milliseconds |
| 32 | /// TODO audit this function. is it possible to return an error? | 34 | /// TODO audit this function. is it possible to return an error? |
| 33 | pub fn milliTimestamp() u64 { | 35 | pub fn milliTimestamp() u64 { |
| 34 | if (builtin.os == .windows) { | 36 | if (is_windows) { |
| 35 | //FileTime has a granularity of 100 nanoseconds | 37 | //FileTime has a granularity of 100 nanoseconds |
| 36 | // and uses the NTFS/Windows epoch | 38 | // and uses the NTFS/Windows epoch |
| 37 | var ft: os.windows.FILETIME = undefined; | 39 | var ft: os.windows.FILETIME = undefined; |
| ... | @@ -42,7 +44,7 @@ pub fn milliTimestamp() u64 { | ... | @@ -42,7 +44,7 @@ pub fn milliTimestamp() u64 { |
| 42 | const ft64 = (@as(u64, ft.dwHighDateTime) << 32) | ft.dwLowDateTime; | 44 | const ft64 = (@as(u64, ft.dwHighDateTime) << 32) | ft.dwLowDateTime; |
| 43 | return @divFloor(ft64, hns_per_ms) - -epoch_adj; | 45 | return @divFloor(ft64, hns_per_ms) - -epoch_adj; |
| 44 | } | 46 | } |
| 45 | if (builtin.os == .wasi and !builtin.link_libc) { | 47 | if (builtin.os.tag == .wasi and !builtin.link_libc) { |
| 46 | var ns: os.wasi.timestamp_t = undefined; | 48 | var ns: os.wasi.timestamp_t = undefined; |
| 47 | 49 | ||
| 48 | // TODO: Verify that precision is ignored | 50 | // TODO: Verify that precision is ignored |
| ... | @@ -102,7 +104,7 @@ pub const Timer = struct { | ... | @@ -102,7 +104,7 @@ pub const Timer = struct { |
| 102 | ///if we used resolution's value when performing the | 104 | ///if we used resolution's value when performing the |
| 103 | /// performance counter calc on windows/darwin, it would | 105 | /// performance counter calc on windows/darwin, it would |
| 104 | /// be less precise | 106 | /// be less precise |
| 105 | frequency: switch (builtin.os) { | 107 | frequency: switch (builtin.os.tag) { |
| 106 | .windows => u64, | 108 | .windows => u64, |
| 107 | .macosx, .ios, .tvos, .watchos => os.darwin.mach_timebase_info_data, | 109 | .macosx, .ios, .tvos, .watchos => os.darwin.mach_timebase_info_data, |
| 108 | else => void, | 110 | else => void, |
| ... | @@ -127,7 +129,7 @@ pub const Timer = struct { | ... | @@ -127,7 +129,7 @@ pub const Timer = struct { |
| 127 | pub fn start() Error!Timer { | 129 | pub fn start() Error!Timer { |
| 128 | var self: Timer = undefined; | 130 | var self: Timer = undefined; |
| 129 | 131 | ||
| 130 | if (builtin.os == .windows) { | 132 | if (is_windows) { |
| 131 | self.frequency = os.windows.QueryPerformanceFrequency(); | 133 | self.frequency = os.windows.QueryPerformanceFrequency(); |
| 132 | self.resolution = @divFloor(ns_per_s, self.frequency); | 134 | self.resolution = @divFloor(ns_per_s, self.frequency); |
| 133 | self.start_time = os.windows.QueryPerformanceCounter(); | 135 | self.start_time = os.windows.QueryPerformanceCounter(); |
| ... | @@ -172,7 +174,7 @@ pub const Timer = struct { | ... | @@ -172,7 +174,7 @@ pub const Timer = struct { |
| 172 | } | 174 | } |
| 173 | 175 | ||
| 174 | fn clockNative() u64 { | 176 | fn clockNative() u64 { |
| 175 | if (builtin.os == .windows) { | 177 | if (is_windows) { |
| 176 | return os.windows.QueryPerformanceCounter(); | 178 | return os.windows.QueryPerformanceCounter(); |
| 177 | } | 179 | } |
| 178 | if (comptime std.Target.current.isDarwin()) { | 180 | if (comptime std.Target.current.isDarwin()) { |
| ... | @@ -184,7 +186,7 @@ pub const Timer = struct { | ... | @@ -184,7 +186,7 @@ pub const Timer = struct { |
| 184 | } | 186 | } |
| 185 | 187 | ||
| 186 | fn nativeDurationToNanos(self: Timer, duration: u64) u64 { | 188 | fn nativeDurationToNanos(self: Timer, duration: u64) u64 { |
| 187 | if (builtin.os == .windows) { | 189 | if (is_windows) { |
| 188 | return @divFloor(duration * ns_per_s, self.frequency); | 190 | return @divFloor(duration * ns_per_s, self.frequency); |
| 189 | } | 191 | } |
| 190 | if (comptime std.Target.current.isDarwin()) { | 192 | if (comptime std.Target.current.isDarwin()) { |
lib/std/zig.zig+3-6| ... | @@ -6,11 +6,8 @@ pub const parseStringLiteral = @import("zig/parse_string_literal.zig").parseStri | ... | @@ -6,11 +6,8 @@ pub const parseStringLiteral = @import("zig/parse_string_literal.zig").parseStri |
| 6 | pub const render = @import("zig/render.zig").render; | 6 | pub const render = @import("zig/render.zig").render; |
| 7 | pub const ast = @import("zig/ast.zig"); | 7 | pub const ast = @import("zig/ast.zig"); |
| 8 | pub const system = @import("zig/system.zig"); | 8 | pub const system = @import("zig/system.zig"); |
| 9 | pub const CrossTarget = @import("zig/cross_target.zig").CrossTarget; | ||
| 9 | 10 | ||
| 10 | test "std.zig tests" { | 11 | test "" { |
| 11 | _ = @import("zig/ast.zig"); | 12 | @import("std").meta.refAllDecls(@This()); |
| 12 | _ = @import("zig/parse.zig"); | ||
| 13 | _ = @import("zig/render.zig"); | ||
| 14 | _ = @import("zig/tokenizer.zig"); | ||
| 15 | _ = @import("zig/parse_string_literal.zig"); | ||
| 16 | } | 13 | } |
lib/std/zig/cross_target.zig created+835| ... | @@ -0,0 +1,835 @@ | ||
| 1 | const std = @import("../std.zig"); | ||
| 2 | const assert = std.debug.assert; | ||
| 3 | const Target = std.Target; | ||
| 4 | const mem = std.mem; | ||
| 5 | |||
| 6 | /// Contains all the same data as `Target`, additionally introducing the concept of "the native target". | ||
| 7 | /// The purpose of this abstraction is to provide meaningful and unsurprising defaults. | ||
| 8 | /// This struct does reference any resources and it is copyable. | ||
| 9 | pub const CrossTarget = struct { | ||
| 10 | /// `null` means native. | ||
| 11 | cpu_arch: ?Target.Cpu.Arch = null, | ||
| 12 | |||
| 13 | cpu_model: CpuModel = CpuModel.determined_by_cpu_arch, | ||
| 14 | |||
| 15 | /// Sparse set of CPU features to add to the set from `cpu_model`. | ||
| 16 | cpu_features_add: Target.Cpu.Feature.Set = Target.Cpu.Feature.Set.empty, | ||
| 17 | |||
| 18 | /// Sparse set of CPU features to remove from the set from `cpu_model`. | ||
| 19 | cpu_features_sub: Target.Cpu.Feature.Set = Target.Cpu.Feature.Set.empty, | ||
| 20 | |||
| 21 | /// `null` means native. | ||
| 22 | os_tag: ?Target.Os.Tag = null, | ||
| 23 | |||
| 24 | /// `null` means the default version range for `os_tag`. If `os_tag` is `null` (native) | ||
| 25 | /// then `null` for this field means native. | ||
| 26 | os_version_min: ?OsVersion = null, | ||
| 27 | |||
| 28 | /// When cross compiling, `null` means default (latest known OS version). | ||
| 29 | /// When `os_tag` is native, `null` means equal to the native OS version. | ||
| 30 | os_version_max: ?OsVersion = null, | ||
| 31 | |||
| 32 | /// `null` means default when cross compiling, or native when os_tag is native. | ||
| 33 | /// If `isGnuLibC()` is `false`, this must be `null` and is ignored. | ||
| 34 | glibc_version: ?SemVer = null, | ||
| 35 | |||
| 36 | /// `null` means the native C ABI, if `os_tag` is native, otherwise it means the default C ABI. | ||
| 37 | abi: ?Target.Abi = null, | ||
| 38 | |||
| 39 | /// When `os_tag` is `null`, then `null` means native. Otherwise it means the standard path | ||
| 40 | /// based on the `os_tag`. | ||
| 41 | dynamic_linker: DynamicLinker = DynamicLinker{}, | ||
| 42 | |||
| 43 | pub const CpuModel = union(enum) { | ||
| 44 | /// Always native | ||
| 45 | native, | ||
| 46 | |||
| 47 | /// Always baseline | ||
| 48 | baseline, | ||
| 49 | |||
| 50 | /// If CPU Architecture is native, then the CPU model will be native. Otherwise, | ||
| 51 | /// it will be baseline. | ||
| 52 | determined_by_cpu_arch, | ||
| 53 | |||
| 54 | explicit: *const Target.Cpu.Model, | ||
| 55 | }; | ||
| 56 | |||
| 57 | pub const OsVersion = union(enum) { | ||
| 58 | none: void, | ||
| 59 | semver: SemVer, | ||
| 60 | windows: Target.Os.WindowsVersion, | ||
| 61 | }; | ||
| 62 | |||
| 63 | pub const SemVer = std.builtin.Version; | ||
| 64 | |||
| 65 | pub const DynamicLinker = Target.DynamicLinker; | ||
| 66 | |||
| 67 | pub fn fromTarget(target: Target) CrossTarget { | ||
| 68 | var result: CrossTarget = .{ | ||
| 69 | .cpu_arch = target.cpu.arch, | ||
| 70 | .cpu_model = .{ .explicit = target.cpu.model }, | ||
| 71 | .os_tag = target.os.tag, | ||
| 72 | .os_version_min = undefined, | ||
| 73 | .os_version_max = undefined, | ||
| 74 | .abi = target.abi, | ||
| 75 | .glibc_version = if (target.isGnuLibC()) | ||
| 76 | target.os.version_range.linux.glibc | ||
| 77 | else | ||
| 78 | null, | ||
| 79 | }; | ||
| 80 | result.updateOsVersionRange(target.os); | ||
| 81 | |||
| 82 | const all_features = target.cpu.arch.allFeaturesList(); | ||
| 83 | var cpu_model_set = target.cpu.model.features; | ||
| 84 | cpu_model_set.populateDependencies(all_features); | ||
| 85 | { | ||
| 86 | // The "add" set is the full set with the CPU Model set removed. | ||
| 87 | const add_set = &result.cpu_features_add; | ||
| 88 | add_set.* = target.cpu.features; | ||
| 89 | add_set.removeFeatureSet(cpu_model_set); | ||
| 90 | } | ||
| 91 | { | ||
| 92 | // The "sub" set is the features that are on in CPU Model set and off in the full set. | ||
| 93 | const sub_set = &result.cpu_features_sub; | ||
| 94 | sub_set.* = cpu_model_set; | ||
| 95 | sub_set.removeFeatureSet(target.cpu.features); | ||
| 96 | } | ||
| 97 | return result; | ||
| 98 | } | ||
| 99 | |||
| 100 | fn updateOsVersionRange(self: *CrossTarget, os: Target.Os) void { | ||
| 101 | switch (os.tag) { | ||
| 102 | .freestanding, | ||
| 103 | .ananas, | ||
| 104 | .cloudabi, | ||
| 105 | .dragonfly, | ||
| 106 | .fuchsia, | ||
| 107 | .kfreebsd, | ||
| 108 | .lv2, | ||
| 109 | .solaris, | ||
| 110 | .haiku, | ||
| 111 | .minix, | ||
| 112 | .rtems, | ||
| 113 | .nacl, | ||
| 114 | .cnk, | ||
| 115 | .aix, | ||
| 116 | .cuda, | ||
| 117 | .nvcl, | ||
| 118 | .amdhsa, | ||
| 119 | .ps4, | ||
| 120 | .elfiamcu, | ||
| 121 | .mesa3d, | ||
| 122 | .contiki, | ||
| 123 | .amdpal, | ||
| 124 | .hermit, | ||
| 125 | .hurd, | ||
| 126 | .wasi, | ||
| 127 | .emscripten, | ||
| 128 | .uefi, | ||
| 129 | .other, | ||
| 130 | => { | ||
| 131 | self.os_version_min = .{ .none = {} }; | ||
| 132 | self.os_version_max = .{ .none = {} }; | ||
| 133 | }, | ||
| 134 | |||
| 135 | .freebsd, | ||
| 136 | .macosx, | ||
| 137 | .ios, | ||
| 138 | .netbsd, | ||
| 139 | .openbsd, | ||
| 140 | .tvos, | ||
| 141 | .watchos, | ||
| 142 | => { | ||
| 143 | self.os_version_min = .{ .semver = os.version_range.semver.min }; | ||
| 144 | self.os_version_max = .{ .semver = os.version_range.semver.max }; | ||
| 145 | }, | ||
| 146 | |||
| 147 | .linux => { | ||
| 148 | self.os_version_min = .{ .semver = os.version_range.linux.range.min }; | ||
| 149 | self.os_version_max = .{ .semver = os.version_range.linux.range.max }; | ||
| 150 | }, | ||
| 151 | |||
| 152 | .windows => { | ||
| 153 | self.os_version_min = .{ .windows = os.version_range.windows.min }; | ||
| 154 | self.os_version_max = .{ .windows = os.version_range.windows.max }; | ||
| 155 | }, | ||
| 156 | } | ||
| 157 | } | ||
| 158 | |||
| 159 | /// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`. | ||
| 160 | pub fn toTarget(self: CrossTarget) Target { | ||
| 161 | return .{ | ||
| 162 | .cpu = self.getCpu(), | ||
| 163 | .os = self.getOs(), | ||
| 164 | .abi = self.getAbi(), | ||
| 165 | }; | ||
| 166 | } | ||
| 167 | |||
| 168 | pub const ParseOptions = struct { | ||
| 169 | /// This is sometimes called a "triple". It looks roughly like this: | ||
| 170 | /// riscv64-linux-musl | ||
| 171 | /// The fields are, respectively: | ||
| 172 | /// * CPU Architecture | ||
| 173 | /// * Operating System (and optional version range) | ||
| 174 | /// * C ABI (optional, with optional glibc version) | ||
| 175 | /// The string "native" can be used for CPU architecture as well as Operating System. | ||
| 176 | /// If the CPU Architecture is specified as "native", then the Operating System and C ABI may be omitted. | ||
| 177 | arch_os_abi: []const u8 = "native", | ||
| 178 | |||
| 179 | /// Looks like "name+a+b-c-d+e", where "name" is a CPU Model name, "a", "b", and "e" | ||
| 180 | /// are examples of CPU features to add to the set, and "c" and "d" are examples of CPU features | ||
| 181 | /// to remove from the set. | ||
| 182 | /// The following special strings are recognized for CPU Model name: | ||
| 183 | /// * "baseline" - The "default" set of CPU features for cross-compiling. A conservative set | ||
| 184 | /// of features that is expected to be supported on most available hardware. | ||
| 185 | /// * "native" - The native CPU model is to be detected when compiling. | ||
| 186 | /// If this field is not provided (`null`), then the value will depend on the | ||
| 187 | /// parsed CPU Architecture. If native, then this will be "native". Otherwise, it will be "baseline". | ||
| 188 | cpu_features: ?[]const u8 = null, | ||
| 189 | |||
| 190 | /// Absolute path to dynamic linker, to override the default, which is either a natively | ||
| 191 | /// detected path, or a standard path. | ||
| 192 | dynamic_linker: ?[]const u8 = null, | ||
| 193 | |||
| 194 | /// If this is provided, the function will populate some information about parsing failures, | ||
| 195 | /// so that user-friendly error messages can be delivered. | ||
| 196 | diagnostics: ?*Diagnostics = null, | ||
| 197 | |||
| 198 | pub const Diagnostics = struct { | ||
| 199 | /// If the architecture was determined, this will be populated. | ||
| 200 | arch: ?Target.Cpu.Arch = null, | ||
| 201 | |||
| 202 | /// If the OS name was determined, this will be populated. | ||
| 203 | os_name: ?[]const u8 = null, | ||
| 204 | |||
| 205 | /// If the OS tag was determined, this will be populated. | ||
| 206 | os_tag: ?Target.Os.Tag = null, | ||
| 207 | |||
| 208 | /// If the ABI was determined, this will be populated. | ||
| 209 | abi: ?Target.Abi = null, | ||
| 210 | |||
| 211 | /// If the CPU name was determined, this will be populated. | ||
| 212 | cpu_name: ?[]const u8 = null, | ||
| 213 | |||
| 214 | /// If error.UnknownCpuFeature is returned, this will be populated. | ||
| 215 | unknown_feature_name: ?[]const u8 = null, | ||
| 216 | }; | ||
| 217 | }; | ||
| 218 | |||
| 219 | pub fn parse(args: ParseOptions) !CrossTarget { | ||
| 220 | var dummy_diags: ParseOptions.Diagnostics = undefined; | ||
| 221 | const diags = args.diagnostics orelse &dummy_diags; | ||
| 222 | |||
| 223 | var result: CrossTarget = .{ | ||
| 224 | .dynamic_linker = DynamicLinker.init(args.dynamic_linker), | ||
| 225 | }; | ||
| 226 | |||
| 227 | var it = mem.separate(args.arch_os_abi, "-"); | ||
| 228 | const arch_name = it.next().?; | ||
| 229 | const arch_is_native = mem.eql(u8, arch_name, "native"); | ||
| 230 | if (!arch_is_native) { | ||
| 231 | result.cpu_arch = std.meta.stringToEnum(Target.Cpu.Arch, arch_name) orelse | ||
| 232 | return error.UnknownArchitecture; | ||
| 233 | } | ||
| 234 | const arch = result.getCpuArch(); | ||
| 235 | diags.arch = arch; | ||
| 236 | |||
| 237 | if (it.next()) |os_text| { | ||
| 238 | try parseOs(&result, diags, os_text); | ||
| 239 | } else if (!arch_is_native) { | ||
| 240 | return error.MissingOperatingSystem; | ||
| 241 | } | ||
| 242 | |||
| 243 | const opt_abi_text = it.next(); | ||
| 244 | if (opt_abi_text) |abi_text| { | ||
| 245 | var abi_it = mem.separate(abi_text, "."); | ||
| 246 | const abi = std.meta.stringToEnum(Target.Abi, abi_it.next().?) orelse | ||
| 247 | return error.UnknownApplicationBinaryInterface; | ||
| 248 | result.abi = abi; | ||
| 249 | diags.abi = abi; | ||
| 250 | |||
| 251 | const abi_ver_text = abi_it.rest(); | ||
| 252 | if (abi_it.next() != null) { | ||
| 253 | if (result.isGnuLibC()) { | ||
| 254 | result.glibc_version = SemVer.parse(abi_ver_text) catch |err| switch (err) { | ||
| 255 | error.Overflow => return error.InvalidAbiVersion, | ||
| 256 | error.InvalidCharacter => return error.InvalidAbiVersion, | ||
| 257 | error.InvalidVersion => return error.InvalidAbiVersion, | ||
| 258 | }; | ||
| 259 | } else { | ||
| 260 | return error.InvalidAbiVersion; | ||
| 261 | } | ||
| 262 | } | ||
| 263 | } | ||
| 264 | |||
| 265 | if (it.next() != null) return error.UnexpectedExtraField; | ||
| 266 | |||
| 267 | if (args.cpu_features) |cpu_features| { | ||
| 268 | const all_features = arch.allFeaturesList(); | ||
| 269 | var index: usize = 0; | ||
| 270 | while (index < cpu_features.len and | ||
| 271 | cpu_features[index] != '+' and | ||
| 272 | cpu_features[index] != '-') | ||
| 273 | { | ||
| 274 | index += 1; | ||
| 275 | } | ||
| 276 | const cpu_name = cpu_features[0..index]; | ||
| 277 | diags.cpu_name = cpu_name; | ||
| 278 | |||
| 279 | const add_set = &result.cpu_features_add; | ||
| 280 | const sub_set = &result.cpu_features_sub; | ||
| 281 | if (mem.eql(u8, cpu_name, "native")) { | ||
| 282 | result.cpu_model = .native; | ||
| 283 | } else if (mem.eql(u8, cpu_name, "baseline")) { | ||
| 284 | result.cpu_model = .baseline; | ||
| 285 | } else { | ||
| 286 | result.cpu_model = .{ .explicit = try arch.parseCpuModel(cpu_name) }; | ||
| 287 | } | ||
| 288 | |||
| 289 | while (index < cpu_features.len) { | ||
| 290 | const op = cpu_features[index]; | ||
| 291 | const set = switch (op) { | ||
| 292 | '+' => add_set, | ||
| 293 | '-' => sub_set, | ||
| 294 | else => unreachable, | ||
| 295 | }; | ||
| 296 | index += 1; | ||
| 297 | const start = index; | ||
| 298 | while (index < cpu_features.len and | ||
| 299 | cpu_features[index] != '+' and | ||
| 300 | cpu_features[index] != '-') | ||
| 301 | { | ||
| 302 | index += 1; | ||
| 303 | } | ||
| 304 | const feature_name = cpu_features[start..index]; | ||
| 305 | for (all_features) |feature, feat_index_usize| { | ||
| 306 | const feat_index = @intCast(Target.Cpu.Feature.Set.Index, feat_index_usize); | ||
| 307 | if (mem.eql(u8, feature_name, feature.name)) { | ||
| 308 | set.addFeature(feat_index); | ||
| 309 | break; | ||
| 310 | } | ||
| 311 | } else { | ||
| 312 | diags.unknown_feature_name = feature_name; | ||
| 313 | return error.UnknownCpuFeature; | ||
| 314 | } | ||
| 315 | } | ||
| 316 | } | ||
| 317 | |||
| 318 | return result; | ||
| 319 | } | ||
| 320 | |||
| 321 | /// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`. | ||
| 322 | pub fn getCpu(self: CrossTarget) Target.Cpu { | ||
| 323 | switch (self.cpu_model) { | ||
| 324 | .native => { | ||
| 325 | // This works when doing `zig build` because Zig generates a build executable using | ||
| 326 | // native CPU model & features. However this will not be accurate otherwise, and | ||
| 327 | // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`. | ||
| 328 | return Target.current.cpu; | ||
| 329 | }, | ||
| 330 | .baseline => { | ||
| 331 | var adjusted_baseline = Target.Cpu.baseline(self.getCpuArch()); | ||
| 332 | self.updateCpuFeatures(&adjusted_baseline.features); | ||
| 333 | return adjusted_baseline; | ||
| 334 | }, | ||
| 335 | .determined_by_cpu_arch => if (self.cpu_arch == null) { | ||
| 336 | // This works when doing `zig build` because Zig generates a build executable using | ||
| 337 | // native CPU model & features. However this will not be accurate otherwise, and | ||
| 338 | // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`. | ||
| 339 | return Target.current.cpu; | ||
| 340 | } else { | ||
| 341 | var adjusted_baseline = Target.Cpu.baseline(self.getCpuArch()); | ||
| 342 | self.updateCpuFeatures(&adjusted_baseline.features); | ||
| 343 | return adjusted_baseline; | ||
| 344 | }, | ||
| 345 | .explicit => |model| { | ||
| 346 | var adjusted_model = model.toCpu(self.getCpuArch()); | ||
| 347 | self.updateCpuFeatures(&adjusted_model.features); | ||
| 348 | return adjusted_model; | ||
| 349 | }, | ||
| 350 | } | ||
| 351 | } | ||
| 352 | |||
| 353 | pub fn getCpuArch(self: CrossTarget) Target.Cpu.Arch { | ||
| 354 | return self.cpu_arch orelse Target.current.cpu.arch; | ||
| 355 | } | ||
| 356 | |||
| 357 | pub fn getCpuModel(self: CrossTarget) *const Target.Cpu.Model { | ||
| 358 | if (self.cpu_model) |cpu_model| return cpu_model; | ||
| 359 | return self.getCpu().model; | ||
| 360 | } | ||
| 361 | |||
| 362 | pub fn getCpuFeatures(self: CrossTarget) Target.Cpu.Feature.Set { | ||
| 363 | return self.getCpu().features; | ||
| 364 | } | ||
| 365 | |||
| 366 | /// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`. | ||
| 367 | pub fn getOs(self: CrossTarget) Target.Os { | ||
| 368 | // `Target.current.os` works when doing `zig build` because Zig generates a build executable using | ||
| 369 | // native OS version range. However this will not be accurate otherwise, and | ||
| 370 | // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`. | ||
| 371 | var adjusted_os = if (self.os_tag) |os_tag| Target.Os.defaultVersionRange(os_tag) else Target.current.os; | ||
| 372 | |||
| 373 | if (self.os_version_min) |min| switch (min) { | ||
| 374 | .none => {}, | ||
| 375 | .semver => |semver| switch (self.getOsTag()) { | ||
| 376 | .linux => adjusted_os.version_range.linux.range.min = semver, | ||
| 377 | else => adjusted_os.version_range.semver.min = semver, | ||
| 378 | }, | ||
| 379 | .windows => |win_ver| adjusted_os.version_range.windows.min = win_ver, | ||
| 380 | }; | ||
| 381 | |||
| 382 | if (self.os_version_max) |max| switch (max) { | ||
| 383 | .none => {}, | ||
| 384 | .semver => |semver| switch (self.getOsTag()) { | ||
| 385 | .linux => adjusted_os.version_range.linux.range.max = semver, | ||
| 386 | else => adjusted_os.version_range.semver.max = semver, | ||
| 387 | }, | ||
| 388 | .windows => |win_ver| adjusted_os.version_range.windows.max = win_ver, | ||
| 389 | }; | ||
| 390 | |||
| 391 | if (self.glibc_version) |glibc| { | ||
| 392 | assert(self.isGnuLibC()); | ||
| 393 | adjusted_os.version_range.linux.glibc = glibc; | ||
| 394 | } | ||
| 395 | |||
| 396 | return adjusted_os; | ||
| 397 | } | ||
| 398 | |||
| 399 | pub fn getOsTag(self: CrossTarget) Target.Os.Tag { | ||
| 400 | return self.os_tag orelse Target.current.os.tag; | ||
| 401 | } | ||
| 402 | |||
| 403 | /// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`. | ||
| 404 | pub fn getOsVersionMin(self: CrossTarget) OsVersion { | ||
| 405 | if (self.os_version_min) |version_min| return version_min; | ||
| 406 | var tmp: CrossTarget = undefined; | ||
| 407 | tmp.updateOsVersionRange(self.getOs()); | ||
| 408 | return tmp.os_version_min.?; | ||
| 409 | } | ||
| 410 | |||
| 411 | /// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`. | ||
| 412 | pub fn getOsVersionMax(self: CrossTarget) OsVersion { | ||
| 413 | if (self.os_version_max) |version_max| return version_max; | ||
| 414 | var tmp: CrossTarget = undefined; | ||
| 415 | tmp.updateOsVersionRange(self.getOs()); | ||
| 416 | return tmp.os_version_max.?; | ||
| 417 | } | ||
| 418 | |||
| 419 | /// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`. | ||
| 420 | pub fn getAbi(self: CrossTarget) Target.Abi { | ||
| 421 | if (self.abi) |abi| return abi; | ||
| 422 | |||
| 423 | if (self.os_tag == null) { | ||
| 424 | // This works when doing `zig build` because Zig generates a build executable using | ||
| 425 | // native CPU model & features. However this will not be accurate otherwise, and | ||
| 426 | // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`. | ||
| 427 | return Target.current.abi; | ||
| 428 | } | ||
| 429 | |||
| 430 | return Target.Abi.default(self.getCpuArch(), self.getOs()); | ||
| 431 | } | ||
| 432 | |||
| 433 | pub fn isFreeBSD(self: CrossTarget) bool { | ||
| 434 | return self.getOsTag() == .freebsd; | ||
| 435 | } | ||
| 436 | |||
| 437 | pub fn isDarwin(self: CrossTarget) bool { | ||
| 438 | return self.getOsTag().isDarwin(); | ||
| 439 | } | ||
| 440 | |||
| 441 | pub fn isNetBSD(self: CrossTarget) bool { | ||
| 442 | return self.getOsTag() == .netbsd; | ||
| 443 | } | ||
| 444 | |||
| 445 | pub fn isUefi(self: CrossTarget) bool { | ||
| 446 | return self.getOsTag() == .uefi; | ||
| 447 | } | ||
| 448 | |||
| 449 | pub fn isDragonFlyBSD(self: CrossTarget) bool { | ||
| 450 | return self.getOsTag() == .dragonfly; | ||
| 451 | } | ||
| 452 | |||
| 453 | pub fn isLinux(self: CrossTarget) bool { | ||
| 454 | return self.getOsTag() == .linux; | ||
| 455 | } | ||
| 456 | |||
| 457 | pub fn isWindows(self: CrossTarget) bool { | ||
| 458 | return self.getOsTag() == .windows; | ||
| 459 | } | ||
| 460 | |||
| 461 | pub fn oFileExt(self: CrossTarget) [:0]const u8 { | ||
| 462 | return self.getAbi().oFileExt(); | ||
| 463 | } | ||
| 464 | |||
| 465 | pub fn exeFileExt(self: CrossTarget) [:0]const u8 { | ||
| 466 | return Target.exeFileExtSimple(self.getCpuArch(), self.getOsTag()); | ||
| 467 | } | ||
| 468 | |||
| 469 | pub fn staticLibSuffix(self: CrossTarget) [:0]const u8 { | ||
| 470 | return Target.staticLibSuffix_cpu_arch_abi(self.getCpuArch(), self.getAbi()); | ||
| 471 | } | ||
| 472 | |||
| 473 | pub fn dynamicLibSuffix(self: CrossTarget) [:0]const u8 { | ||
| 474 | return self.getOsTag().dynamicLibSuffix(); | ||
| 475 | } | ||
| 476 | |||
| 477 | pub fn libPrefix(self: CrossTarget) [:0]const u8 { | ||
| 478 | return Target.libPrefix_cpu_arch_abi(self.getCpuArch(), self.getAbi()); | ||
| 479 | } | ||
| 480 | |||
| 481 | pub fn isNative(self: CrossTarget) bool { | ||
| 482 | return self.cpu_arch == null and | ||
| 483 | (self.cpu_model == .native or self.cpu_model == .determined_by_cpu_arch) and | ||
| 484 | self.cpu_features_sub.isEmpty() and self.cpu_features_add.isEmpty() and | ||
| 485 | self.os_tag == null and self.os_version_min == null and self.os_version_max == null and | ||
| 486 | self.abi == null and self.dynamic_linker.get() == null and self.glibc_version == null; | ||
| 487 | } | ||
| 488 | |||
| 489 | pub fn zigTriple(self: CrossTarget, allocator: *mem.Allocator) error{OutOfMemory}![:0]u8 { | ||
| 490 | if (self.isNative()) { | ||
| 491 | return mem.dupeZ(allocator, u8, "native"); | ||
| 492 | } | ||
| 493 | |||
| 494 | const arch_name = if (self.cpu_arch) |arch| @tagName(arch) else "native"; | ||
| 495 | const os_name = if (self.os_tag) |os_tag| @tagName(os_tag) else "native"; | ||
| 496 | |||
| 497 | var result = try std.Buffer.allocPrint(allocator, "{}-{}", .{ arch_name, os_name }); | ||
| 498 | defer result.deinit(); | ||
| 499 | |||
| 500 | // The zig target syntax does not allow specifying a max os version with no min, so | ||
| 501 | // if either are present, we need the min. | ||
| 502 | if (self.os_version_min != null or self.os_version_max != null) { | ||
| 503 | switch (self.getOsVersionMin()) { | ||
| 504 | .none => {}, | ||
| 505 | .semver => |v| try result.print(".{}", .{v}), | ||
| 506 | .windows => |v| try result.print(".{}", .{@tagName(v)}), | ||
| 507 | } | ||
| 508 | } | ||
| 509 | if (self.os_version_max) |max| { | ||
| 510 | switch (max) { | ||
| 511 | .none => {}, | ||
| 512 | .semver => |v| try result.print("...{}", .{v}), | ||
| 513 | .windows => |v| try result.print("...{}", .{@tagName(v)}), | ||
| 514 | } | ||
| 515 | } | ||
| 516 | |||
| 517 | if (self.glibc_version) |v| { | ||
| 518 | try result.print("-{}.{}", .{ @tagName(self.getAbi()), v }); | ||
| 519 | } else if (self.abi) |abi| { | ||
| 520 | try result.print("-{}", .{@tagName(abi)}); | ||
| 521 | } | ||
| 522 | |||
| 523 | return result.toOwnedSlice(); | ||
| 524 | } | ||
| 525 | |||
| 526 | pub fn allocDescription(self: CrossTarget, allocator: *mem.Allocator) ![:0]u8 { | ||
| 527 | // TODO is there anything else worthy of the description that is not | ||
| 528 | // already captured in the triple? | ||
| 529 | return self.zigTriple(allocator); | ||
| 530 | } | ||
| 531 | |||
| 532 | pub fn linuxTriple(self: CrossTarget, allocator: *mem.Allocator) ![:0]u8 { | ||
| 533 | return Target.linuxTripleSimple(allocator, self.getCpuArch(), self.getOsTag(), self.getAbi()); | ||
| 534 | } | ||
| 535 | |||
| 536 | pub fn wantSharedLibSymLinks(self: CrossTarget) bool { | ||
| 537 | return self.getOsTag() != .windows; | ||
| 538 | } | ||
| 539 | |||
| 540 | pub const VcpkgLinkage = std.builtin.LinkMode; | ||
| 541 | |||
| 542 | /// Returned slice must be freed by the caller. | ||
| 543 | pub fn vcpkgTriplet(self: CrossTarget, allocator: *mem.Allocator, linkage: VcpkgLinkage) ![:0]u8 { | ||
| 544 | const arch = switch (self.getCpuArch()) { | ||
| 545 | .i386 => "x86", | ||
| 546 | .x86_64 => "x64", | ||
| 547 | |||
| 548 | .arm, | ||
| 549 | .armeb, | ||
| 550 | .thumb, | ||
| 551 | .thumbeb, | ||
| 552 | .aarch64_32, | ||
| 553 | => "arm", | ||
| 554 | |||
| 555 | .aarch64, | ||
| 556 | .aarch64_be, | ||
| 557 | => "arm64", | ||
| 558 | |||
| 559 | else => return error.UnsupportedVcpkgArchitecture, | ||
| 560 | }; | ||
| 561 | |||
| 562 | const os = switch (self.getOsTag()) { | ||
| 563 | .windows => "windows", | ||
| 564 | .linux => "linux", | ||
| 565 | .macosx => "macos", | ||
| 566 | else => return error.UnsupportedVcpkgOperatingSystem, | ||
| 567 | }; | ||
| 568 | |||
| 569 | const static_suffix = switch (linkage) { | ||
| 570 | .Static => "-static", | ||
| 571 | .Dynamic => "", | ||
| 572 | }; | ||
| 573 | |||
| 574 | return std.fmt.allocPrint0(allocator, "{}-{}{}", .{ arch, os, static_suffix }); | ||
| 575 | } | ||
| 576 | |||
| 577 | pub const Executor = union(enum) { | ||
| 578 | native, | ||
| 579 | qemu: []const u8, | ||
| 580 | wine: []const u8, | ||
| 581 | wasmtime: []const u8, | ||
| 582 | unavailable, | ||
| 583 | }; | ||
| 584 | |||
| 585 | /// Note that even a `CrossTarget` which returns `false` for `isNative` could still be natively executed. | ||
| 586 | /// For example `-target arm-native` running on an aarch64 host. | ||
| 587 | pub fn getExternalExecutor(self: CrossTarget) Executor { | ||
| 588 | const cpu_arch = self.getCpuArch(); | ||
| 589 | const os_tag = self.getOsTag(); | ||
| 590 | const os_match = os_tag == Target.current.os.tag; | ||
| 591 | |||
| 592 | // If the OS and CPU arch match, the binary can be considered native. | ||
| 593 | if (os_match and cpu_arch == Target.current.cpu.arch) { | ||
| 594 | // However, we also need to verify that the dynamic linker path is valid. | ||
| 595 | // TODO Until that is implemented, we prevent returning `.native` when the OS is non-native. | ||
| 596 | if (self.os_tag == null) { | ||
| 597 | return .native; | ||
| 598 | } | ||
| 599 | } | ||
| 600 | |||
| 601 | // If the OS matches, we can use QEMU to emulate a foreign architecture. | ||
| 602 | if (os_match) { | ||
| 603 | return switch (cpu_arch) { | ||
| 604 | .aarch64 => Executor{ .qemu = "qemu-aarch64" }, | ||
| 605 | .aarch64_be => Executor{ .qemu = "qemu-aarch64_be" }, | ||
| 606 | .arm => Executor{ .qemu = "qemu-arm" }, | ||
| 607 | .armeb => Executor{ .qemu = "qemu-armeb" }, | ||
| 608 | .i386 => Executor{ .qemu = "qemu-i386" }, | ||
| 609 | .mips => Executor{ .qemu = "qemu-mips" }, | ||
| 610 | .mipsel => Executor{ .qemu = "qemu-mipsel" }, | ||
| 611 | .mips64 => Executor{ .qemu = "qemu-mips64" }, | ||
| 612 | .mips64el => Executor{ .qemu = "qemu-mips64el" }, | ||
| 613 | .powerpc => Executor{ .qemu = "qemu-ppc" }, | ||
| 614 | .powerpc64 => Executor{ .qemu = "qemu-ppc64" }, | ||
| 615 | .powerpc64le => Executor{ .qemu = "qemu-ppc64le" }, | ||
| 616 | .riscv32 => Executor{ .qemu = "qemu-riscv32" }, | ||
| 617 | .riscv64 => Executor{ .qemu = "qemu-riscv64" }, | ||
| 618 | .s390x => Executor{ .qemu = "qemu-s390x" }, | ||
| 619 | .sparc => Executor{ .qemu = "qemu-sparc" }, | ||
| 620 | .x86_64 => Executor{ .qemu = "qemu-x86_64" }, | ||
| 621 | else => return .unavailable, | ||
| 622 | }; | ||
| 623 | } | ||
| 624 | |||
| 625 | switch (os_tag) { | ||
| 626 | .windows => switch (cpu_arch.ptrBitWidth()) { | ||
| 627 | 32 => return Executor{ .wine = "wine" }, | ||
| 628 | 64 => return Executor{ .wine = "wine64" }, | ||
| 629 | else => return .unavailable, | ||
| 630 | }, | ||
| 631 | .wasi => switch (cpu_arch.ptrBitWidth()) { | ||
| 632 | 32 => return Executor{ .wasmtime = "wasmtime" }, | ||
| 633 | else => return .unavailable, | ||
| 634 | }, | ||
| 635 | else => return .unavailable, | ||
| 636 | } | ||
| 637 | } | ||
| 638 | |||
| 639 | pub fn isGnuLibC(self: CrossTarget) bool { | ||
| 640 | return Target.isGnuLibC_os_tag_abi(self.getOsTag(), self.getAbi()); | ||
| 641 | } | ||
| 642 | |||
| 643 | pub fn setGnuLibCVersion(self: *CrossTarget, major: u32, minor: u32, patch: u32) void { | ||
| 644 | assert(self.isGnuLibC()); | ||
| 645 | self.glibc_version = SemVer{ .major = major, .minor = minor, .patch = patch }; | ||
| 646 | } | ||
| 647 | |||
| 648 | fn updateCpuFeatures(self: CrossTarget, set: *Target.Cpu.Feature.Set) void { | ||
| 649 | set.removeFeatureSet(self.cpu_features_sub); | ||
| 650 | set.addFeatureSet(self.cpu_features_add); | ||
| 651 | set.populateDependencies(self.getCpuArch().allFeaturesList()); | ||
| 652 | set.removeFeatureSet(self.cpu_features_sub); | ||
| 653 | } | ||
| 654 | |||
| 655 | fn parseOs(result: *CrossTarget, diags: *ParseOptions.Diagnostics, text: []const u8) !void { | ||
| 656 | var it = mem.separate(text, "."); | ||
| 657 | const os_name = it.next().?; | ||
| 658 | diags.os_name = os_name; | ||
| 659 | const os_is_native = mem.eql(u8, os_name, "native"); | ||
| 660 | if (!os_is_native) { | ||
| 661 | result.os_tag = std.meta.stringToEnum(Target.Os.Tag, os_name) orelse | ||
| 662 | return error.UnknownOperatingSystem; | ||
| 663 | } | ||
| 664 | const tag = result.getOsTag(); | ||
| 665 | diags.os_tag = tag; | ||
| 666 | |||
| 667 | const version_text = it.rest(); | ||
| 668 | if (it.next() == null) return; | ||
| 669 | |||
| 670 | switch (tag) { | ||
| 671 | .freestanding, | ||
| 672 | .ananas, | ||
| 673 | .cloudabi, | ||
| 674 | .dragonfly, | ||
| 675 | .fuchsia, | ||
| 676 | .ios, | ||
| 677 | .kfreebsd, | ||
| 678 | .lv2, | ||
| 679 | .solaris, | ||
| 680 | .haiku, | ||
| 681 | .minix, | ||
| 682 | .rtems, | ||
| 683 | .nacl, | ||
| 684 | .cnk, | ||
| 685 | .aix, | ||
| 686 | .cuda, | ||
| 687 | .nvcl, | ||
| 688 | .amdhsa, | ||
| 689 | .ps4, | ||
| 690 | .elfiamcu, | ||
| 691 | .tvos, | ||
| 692 | .watchos, | ||
| 693 | .mesa3d, | ||
| 694 | .contiki, | ||
| 695 | .amdpal, | ||
| 696 | .hermit, | ||
| 697 | .hurd, | ||
| 698 | .wasi, | ||
| 699 | .emscripten, | ||
| 700 | .uefi, | ||
| 701 | .other, | ||
| 702 | => return error.InvalidOperatingSystemVersion, | ||
| 703 | |||
| 704 | .freebsd, | ||
| 705 | .macosx, | ||
| 706 | .netbsd, | ||
| 707 | .openbsd, | ||
| 708 | .linux, | ||
| 709 | => { | ||
| 710 | var range_it = mem.separate(version_text, "..."); | ||
| 711 | |||
| 712 | const min_text = range_it.next().?; | ||
| 713 | const min_ver = SemVer.parse(min_text) catch |err| switch (err) { | ||
| 714 | error.Overflow => return error.InvalidOperatingSystemVersion, | ||
| 715 | error.InvalidCharacter => return error.InvalidOperatingSystemVersion, | ||
| 716 | error.InvalidVersion => return error.InvalidOperatingSystemVersion, | ||
| 717 | }; | ||
| 718 | result.os_version_min = .{ .semver = min_ver }; | ||
| 719 | |||
| 720 | const max_text = range_it.next() orelse return; | ||
| 721 | const max_ver = SemVer.parse(max_text) catch |err| switch (err) { | ||
| 722 | error.Overflow => return error.InvalidOperatingSystemVersion, | ||
| 723 | error.InvalidCharacter => return error.InvalidOperatingSystemVersion, | ||
| 724 | error.InvalidVersion => return error.InvalidOperatingSystemVersion, | ||
| 725 | }; | ||
| 726 | result.os_version_max = .{ .semver = max_ver }; | ||
| 727 | }, | ||
| 728 | |||
| 729 | .windows => { | ||
| 730 | var range_it = mem.separate(version_text, "..."); | ||
| 731 | |||
| 732 | const min_text = range_it.next().?; | ||
| 733 | const min_ver = std.meta.stringToEnum(Target.Os.WindowsVersion, min_text) orelse | ||
| 734 | return error.InvalidOperatingSystemVersion; | ||
| 735 | result.os_version_min = .{ .windows = min_ver }; | ||
| 736 | |||
| 737 | const max_text = range_it.next() orelse return; | ||
| 738 | const max_ver = std.meta.stringToEnum(Target.Os.WindowsVersion, max_text) orelse | ||
| 739 | return error.InvalidOperatingSystemVersion; | ||
| 740 | result.os_version_max = .{ .windows = max_ver }; | ||
| 741 | }, | ||
| 742 | } | ||
| 743 | } | ||
| 744 | }; | ||
| 745 | |||
| 746 | test "CrossTarget.parse" { | ||
| 747 | if (Target.current.isGnuLibC()) { | ||
| 748 | var cross_target = try CrossTarget.parse(.{}); | ||
| 749 | cross_target.setGnuLibCVersion(2, 1, 1); | ||
| 750 | |||
| 751 | const text = try cross_target.zigTriple(std.testing.allocator); | ||
| 752 | defer std.testing.allocator.free(text); | ||
| 753 | std.testing.expectEqualSlices(u8, "native-native-gnu.2.1.1", text); | ||
| 754 | } | ||
| 755 | { | ||
| 756 | const cross_target = try CrossTarget.parse(.{ | ||
| 757 | .arch_os_abi = "aarch64-linux", | ||
| 758 | .cpu_features = "native", | ||
| 759 | }); | ||
| 760 | |||
| 761 | std.testing.expect(cross_target.cpu_arch.? == .aarch64); | ||
| 762 | std.testing.expect(cross_target.cpu_model == .native); | ||
| 763 | } | ||
| 764 | { | ||
| 765 | const cross_target = try CrossTarget.parse(.{ .arch_os_abi = "native" }); | ||
| 766 | |||
| 767 | std.testing.expect(cross_target.cpu_arch == null); | ||
| 768 | std.testing.expect(cross_target.isNative()); | ||
| 769 | |||
| 770 | const text = try cross_target.zigTriple(std.testing.allocator); | ||
| 771 | defer std.testing.allocator.free(text); | ||
| 772 | std.testing.expectEqualSlices(u8, "native", text); | ||
| 773 | } | ||
| 774 | { | ||
| 775 | const cross_target = try CrossTarget.parse(.{ | ||
| 776 | .arch_os_abi = "x86_64-linux-gnu", | ||
| 777 | .cpu_features = "x86_64-sse-sse2-avx-cx8", | ||
| 778 | }); | ||
| 779 | const target = cross_target.toTarget(); | ||
| 780 | |||
| 781 | std.testing.expect(target.os.tag == .linux); | ||
| 782 | std.testing.expect(target.abi == .gnu); | ||
| 783 | std.testing.expect(target.cpu.arch == .x86_64); | ||
| 784 | std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .sse)); | ||
| 785 | std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .avx)); | ||
| 786 | std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .cx8)); | ||
| 787 | std.testing.expect(Target.x86.featureSetHas(target.cpu.features, .cmov)); | ||
| 788 | std.testing.expect(Target.x86.featureSetHas(target.cpu.features, .fxsr)); | ||
| 789 | |||
| 790 | const text = try cross_target.zigTriple(std.testing.allocator); | ||
| 791 | defer std.testing.allocator.free(text); | ||
| 792 | std.testing.expectEqualSlices(u8, "x86_64-linux-gnu", text); | ||
| 793 | } | ||
| 794 | { | ||
| 795 | const cross_target = try CrossTarget.parse(.{ | ||
| 796 | .arch_os_abi = "arm-linux-musleabihf", | ||
| 797 | .cpu_features = "generic+v8a", | ||
| 798 | }); | ||
| 799 | const target = cross_target.toTarget(); | ||
| 800 | |||
| 801 | std.testing.expect(target.os.tag == .linux); | ||
| 802 | std.testing.expect(target.abi == .musleabihf); | ||
| 803 | std.testing.expect(target.cpu.arch == .arm); | ||
| 804 | std.testing.expect(target.cpu.model == &Target.arm.cpu.generic); | ||
| 805 | std.testing.expect(Target.arm.featureSetHas(target.cpu.features, .v8a)); | ||
| 806 | |||
| 807 | const text = try cross_target.zigTriple(std.testing.allocator); | ||
| 808 | defer std.testing.allocator.free(text); | ||
| 809 | std.testing.expectEqualSlices(u8, "arm-linux-musleabihf", text); | ||
| 810 | } | ||
| 811 | { | ||
| 812 | const cross_target = try CrossTarget.parse(.{ | ||
| 813 | .arch_os_abi = "aarch64-linux.3.10...4.4.1-gnu.2.27", | ||
| 814 | .cpu_features = "generic+v8a", | ||
| 815 | }); | ||
| 816 | const target = cross_target.toTarget(); | ||
| 817 | |||
| 818 | std.testing.expect(target.cpu.arch == .aarch64); | ||
| 819 | std.testing.expect(target.os.tag == .linux); | ||
| 820 | std.testing.expect(target.os.version_range.linux.range.min.major == 3); | ||
| 821 | std.testing.expect(target.os.version_range.linux.range.min.minor == 10); | ||
| 822 | std.testing.expect(target.os.version_range.linux.range.min.patch == 0); | ||
| 823 | std.testing.expect(target.os.version_range.linux.range.max.major == 4); | ||
| 824 | std.testing.expect(target.os.version_range.linux.range.max.minor == 4); | ||
| 825 | std.testing.expect(target.os.version_range.linux.range.max.patch == 1); | ||
| 826 | std.testing.expect(target.os.version_range.linux.glibc.major == 2); | ||
| 827 | std.testing.expect(target.os.version_range.linux.glibc.minor == 27); | ||
| 828 | std.testing.expect(target.os.version_range.linux.glibc.patch == 0); | ||
| 829 | std.testing.expect(target.abi == .gnu); | ||
| 830 | |||
| 831 | const text = try cross_target.zigTriple(std.testing.allocator); | ||
| 832 | defer std.testing.allocator.free(text); | ||
| 833 | std.testing.expectEqualSlices(u8, "aarch64-linux.3.10...4.4.1-gnu.2.27", text); | ||
| 834 | } | ||
| 835 | } | ||
lib/std/zig/system.zig+612-2| ... | @@ -1,11 +1,15 @@ | ... | @@ -1,11 +1,15 @@ |
| 1 | const std = @import("../std.zig"); | 1 | const std = @import("../std.zig"); |
| 2 | const elf = std.elf; | ||
| 2 | const mem = std.mem; | 3 | const mem = std.mem; |
| 4 | const fs = std.fs; | ||
| 3 | const Allocator = std.mem.Allocator; | 5 | const Allocator = std.mem.Allocator; |
| 4 | const ArrayList = std.ArrayList; | 6 | const ArrayList = std.ArrayList; |
| 5 | const assert = std.debug.assert; | 7 | const assert = std.debug.assert; |
| 6 | const process = std.process; | 8 | const process = std.process; |
| 9 | const Target = std.Target; | ||
| 10 | const CrossTarget = std.zig.CrossTarget; | ||
| 7 | 11 | ||
| 8 | const is_windows = std.Target.current.isWindows(); | 12 | const is_windows = Target.current.os.tag == .windows; |
| 9 | 13 | ||
| 10 | pub const NativePaths = struct { | 14 | pub const NativePaths = struct { |
| 11 | include_dirs: ArrayList([:0]u8), | 15 | include_dirs: ArrayList([:0]u8), |
| ... | @@ -77,7 +81,7 @@ pub const NativePaths = struct { | ... | @@ -77,7 +81,7 @@ pub const NativePaths = struct { |
| 77 | } | 81 | } |
| 78 | 82 | ||
| 79 | if (!is_windows) { | 83 | if (!is_windows) { |
| 80 | const triple = try std.Target.current.linuxTriple(allocator); | 84 | const triple = try Target.current.linuxTriple(allocator); |
| 81 | 85 | ||
| 82 | // TODO: $ ld --verbose | grep SEARCH_DIR | 86 | // TODO: $ ld --verbose | grep SEARCH_DIR |
| 83 | // the output contains some paths that end with lib64, maybe include them too? | 87 | // the output contains some paths that end with lib64, maybe include them too? |
| ... | @@ -161,3 +165,609 @@ pub const NativePaths = struct { | ... | @@ -161,3 +165,609 @@ pub const NativePaths = struct { |
| 161 | try array.append(item); | 165 | try array.append(item); |
| 162 | } | 166 | } |
| 163 | }; | 167 | }; |
| 168 | |||
| 169 | pub const NativeTargetInfo = struct { | ||
| 170 | target: Target, | ||
| 171 | |||
| 172 | dynamic_linker: DynamicLinker = DynamicLinker{}, | ||
| 173 | |||
| 174 | pub const DynamicLinker = Target.DynamicLinker; | ||
| 175 | |||
| 176 | pub const DetectError = error{ | ||
| 177 | OutOfMemory, | ||
| 178 | FileSystem, | ||
| 179 | SystemResources, | ||
| 180 | SymLinkLoop, | ||
| 181 | ProcessFdQuotaExceeded, | ||
| 182 | SystemFdQuotaExceeded, | ||
| 183 | DeviceBusy, | ||
| 184 | }; | ||
| 185 | |||
| 186 | /// Given a `CrossTarget`, which specifies in detail which parts of the target should be detected | ||
| 187 | /// natively, which should be standard or default, and which are provided explicitly, this function | ||
| 188 | /// resolves the native components by detecting the native system, and then resolves standard/default parts | ||
| 189 | /// relative to that. | ||
| 190 | /// Any resources this function allocates are released before returning, and so there is no | ||
| 191 | /// deinitialization method. | ||
| 192 | /// TODO Remove the Allocator requirement from this function. | ||
| 193 | pub fn detect(allocator: *Allocator, cross_target: CrossTarget) DetectError!NativeTargetInfo { | ||
| 194 | const cpu = switch (cross_target.cpu_model) { | ||
| 195 | .native => detectNativeCpuAndFeatures(cross_target), | ||
| 196 | .baseline => baselineCpuAndFeatures(cross_target), | ||
| 197 | .determined_by_cpu_arch => if (cross_target.cpu_arch == null) | ||
| 198 | detectNativeCpuAndFeatures(cross_target) | ||
| 199 | else | ||
| 200 | baselineCpuAndFeatures(cross_target), | ||
| 201 | .explicit => |model| blk: { | ||
| 202 | var adjusted_model = model.toCpu(cross_target.getCpuArch()); | ||
| 203 | cross_target.updateCpuFeatures(&adjusted_model.features); | ||
| 204 | break :blk adjusted_model; | ||
| 205 | }, | ||
| 206 | }; | ||
| 207 | |||
| 208 | var os = Target.Os.defaultVersionRange(cross_target.getOsTag()); | ||
| 209 | if (cross_target.os_tag == null) { | ||
| 210 | switch (Target.current.os.tag) { | ||
| 211 | .linux => { | ||
| 212 | const uts = std.os.uname(); | ||
| 213 | const release = mem.toSliceConst(u8, @ptrCast([*:0]const u8, &uts.release)); | ||
| 214 | if (std.builtin.Version.parse(release)) |ver| { | ||
| 215 | os.version_range.linux.range.min = ver; | ||
| 216 | os.version_range.linux.range.max = ver; | ||
| 217 | } else |err| switch (err) { | ||
| 218 | error.Overflow => {}, | ||
| 219 | error.InvalidCharacter => {}, | ||
| 220 | error.InvalidVersion => {}, | ||
| 221 | } | ||
| 222 | }, | ||
| 223 | .windows => { | ||
| 224 | // TODO Detect native operating system version. | ||
| 225 | }, | ||
| 226 | .macosx => { | ||
| 227 | // TODO Detect native operating system version. | ||
| 228 | }, | ||
| 229 | .freebsd => { | ||
| 230 | // TODO Detect native operating system version. | ||
| 231 | }, | ||
| 232 | else => {}, | ||
| 233 | } | ||
| 234 | } | ||
| 235 | |||
| 236 | if (cross_target.os_version_min) |min| switch (min) { | ||
| 237 | .none => {}, | ||
| 238 | .semver => |semver| switch (cross_target.getOsTag()) { | ||
| 239 | .linux => os.version_range.linux.range.min = semver, | ||
| 240 | else => os.version_range.semver.min = semver, | ||
| 241 | }, | ||
| 242 | .windows => |win_ver| os.version_range.windows.min = win_ver, | ||
| 243 | }; | ||
| 244 | |||
| 245 | if (cross_target.os_version_max) |max| switch (max) { | ||
| 246 | .none => {}, | ||
| 247 | .semver => |semver| switch (cross_target.getOsTag()) { | ||
| 248 | .linux => os.version_range.linux.range.max = semver, | ||
| 249 | else => os.version_range.semver.max = semver, | ||
| 250 | }, | ||
| 251 | .windows => |win_ver| os.version_range.windows.max = win_ver, | ||
| 252 | }; | ||
| 253 | |||
| 254 | if (cross_target.glibc_version) |glibc| { | ||
| 255 | assert(cross_target.isGnuLibC()); | ||
| 256 | os.version_range.linux.glibc = glibc; | ||
| 257 | } | ||
| 258 | |||
| 259 | return detectAbiAndDynamicLinker(allocator, cpu, os, cross_target); | ||
| 260 | } | ||
| 261 | |||
| 262 | /// First we attempt to use the executable's own binary. If it is dynamically | ||
| 263 | /// linked, then it should answer both the C ABI question and the dynamic linker question. | ||
| 264 | /// If it is statically linked, then we try /usr/bin/env. If that does not provide the answer, then | ||
| 265 | /// we fall back to the defaults. | ||
| 266 | /// TODO Remove the Allocator requirement from this function. | ||
| 267 | fn detectAbiAndDynamicLinker( | ||
| 268 | allocator: *Allocator, | ||
| 269 | cpu: Target.Cpu, | ||
| 270 | os: Target.Os, | ||
| 271 | cross_target: CrossTarget, | ||
| 272 | ) DetectError!NativeTargetInfo { | ||
| 273 | const native_target_has_ld = comptime Target.current.hasDynamicLinker(); | ||
| 274 | const is_linux = Target.current.os.tag == .linux; | ||
| 275 | const have_all_info = cross_target.dynamic_linker.get() != null and | ||
| 276 | cross_target.abi != null and (!is_linux or cross_target.abi.?.isGnu()); | ||
| 277 | const os_is_non_native = cross_target.os_tag != null; | ||
| 278 | if (!native_target_has_ld or have_all_info or os_is_non_native) { | ||
| 279 | return defaultAbiAndDynamicLinker(cpu, os, cross_target); | ||
| 280 | } | ||
| 281 | // The current target's ABI cannot be relied on for this. For example, we may build the zig | ||
| 282 | // compiler for target riscv64-linux-musl and provide a tarball for users to download. | ||
| 283 | // A user could then run that zig compiler on riscv64-linux-gnu. This use case is well-defined | ||
| 284 | // and supported by Zig. But that means that we must detect the system ABI here rather than | ||
| 285 | // relying on `Target.current`. | ||
| 286 | const all_abis = comptime blk: { | ||
| 287 | assert(@enumToInt(Target.Abi.none) == 0); | ||
| 288 | const fields = std.meta.fields(Target.Abi)[1..]; | ||
| 289 | var array: [fields.len]Target.Abi = undefined; | ||
| 290 | inline for (fields) |field, i| { | ||
| 291 | array[i] = @field(Target.Abi, field.name); | ||
| 292 | } | ||
| 293 | break :blk array; | ||
| 294 | }; | ||
| 295 | var ld_info_list_buffer: [all_abis.len]LdInfo = undefined; | ||
| 296 | var ld_info_list_len: usize = 0; | ||
| 297 | |||
| 298 | for (all_abis) |abi| { | ||
| 299 | // This may be a nonsensical parameter. We detect this with error.UnknownDynamicLinkerPath and | ||
| 300 | // skip adding it to `ld_info_list`. | ||
| 301 | const target: Target = .{ | ||
| 302 | .cpu = cpu, | ||
| 303 | .os = os, | ||
| 304 | .abi = abi, | ||
| 305 | }; | ||
| 306 | const ld = target.standardDynamicLinkerPath(); | ||
| 307 | if (ld.get() == null) continue; | ||
| 308 | |||
| 309 | ld_info_list_buffer[ld_info_list_len] = .{ | ||
| 310 | .ld = ld, | ||
| 311 | .abi = abi, | ||
| 312 | }; | ||
| 313 | ld_info_list_len += 1; | ||
| 314 | } | ||
| 315 | const ld_info_list = ld_info_list_buffer[0..ld_info_list_len]; | ||
| 316 | |||
| 317 | if (cross_target.dynamic_linker.get()) |explicit_ld| { | ||
| 318 | const explicit_ld_basename = fs.path.basename(explicit_ld); | ||
| 319 | for (ld_info_list) |ld_info| { | ||
| 320 | const standard_ld_basename = fs.path.basename(ld_info.ld.get().?); | ||
| 321 | } | ||
| 322 | } | ||
| 323 | |||
| 324 | // Best case scenario: the executable is dynamically linked, and we can iterate | ||
| 325 | // over our own shared objects and find a dynamic linker. | ||
| 326 | self_exe: { | ||
| 327 | const lib_paths = try std.process.getSelfExeSharedLibPaths(allocator); | ||
| 328 | defer allocator.free(lib_paths); | ||
| 329 | |||
| 330 | var found_ld_info: LdInfo = undefined; | ||
| 331 | var found_ld_path: [:0]const u8 = undefined; | ||
| 332 | |||
| 333 | // Look for dynamic linker. | ||
| 334 | // This is O(N^M) but typical case here is N=2 and M=10. | ||
| 335 | find_ld: for (lib_paths) |lib_path| { | ||
| 336 | for (ld_info_list) |ld_info| { | ||
| 337 | const standard_ld_basename = fs.path.basename(ld_info.ld.get().?); | ||
| 338 | if (std.mem.endsWith(u8, lib_path, standard_ld_basename)) { | ||
| 339 | found_ld_info = ld_info; | ||
| 340 | found_ld_path = lib_path; | ||
| 341 | break :find_ld; | ||
| 342 | } | ||
| 343 | } | ||
| 344 | } else break :self_exe; | ||
| 345 | |||
| 346 | // Look for glibc version. | ||
| 347 | var os_adjusted = os; | ||
| 348 | if (Target.current.os.tag == .linux and found_ld_info.abi.isGnu() and | ||
| 349 | cross_target.glibc_version == null) | ||
| 350 | { | ||
| 351 | for (lib_paths) |lib_path| { | ||
| 352 | if (std.mem.endsWith(u8, lib_path, glibc_so_basename)) { | ||
| 353 | os_adjusted.version_range.linux.glibc = glibcVerFromSO(lib_path) catch |err| switch (err) { | ||
| 354 | error.UnrecognizedGnuLibCFileName => continue, | ||
| 355 | error.InvalidGnuLibCVersion => continue, | ||
| 356 | error.GnuLibCVersionUnavailable => continue, | ||
| 357 | else => |e| return e, | ||
| 358 | }; | ||
| 359 | break; | ||
| 360 | } | ||
| 361 | } | ||
| 362 | } | ||
| 363 | |||
| 364 | var result: NativeTargetInfo = .{ | ||
| 365 | .target = .{ | ||
| 366 | .cpu = cpu, | ||
| 367 | .os = os_adjusted, | ||
| 368 | .abi = cross_target.abi orelse found_ld_info.abi, | ||
| 369 | }, | ||
| 370 | .dynamic_linker = if (cross_target.dynamic_linker.get() == null) | ||
| 371 | DynamicLinker.init(found_ld_path) | ||
| 372 | else | ||
| 373 | cross_target.dynamic_linker, | ||
| 374 | }; | ||
| 375 | return result; | ||
| 376 | } | ||
| 377 | |||
| 378 | // If Zig is statically linked, such as via distributed binary static builds, the above | ||
| 379 | // trick won't work. The next thing we fall back to is the same thing, but for /usr/bin/env. | ||
| 380 | // Since that path is hard-coded into the shebang line of many portable scripts, it's a | ||
| 381 | // reasonably reliable path to check for. | ||
| 382 | return abiAndDynamicLinkerFromUsrBinEnv(cpu, os, ld_info_list, cross_target) catch |err| switch (err) { | ||
| 383 | error.FileSystem, | ||
| 384 | error.SystemResources, | ||
| 385 | error.SymLinkLoop, | ||
| 386 | error.ProcessFdQuotaExceeded, | ||
| 387 | error.SystemFdQuotaExceeded, | ||
| 388 | error.DeviceBusy, | ||
| 389 | => |e| return e, | ||
| 390 | |||
| 391 | error.UnableToReadElfFile, | ||
| 392 | error.InvalidElfClass, | ||
| 393 | error.InvalidElfVersion, | ||
| 394 | error.InvalidElfEndian, | ||
| 395 | error.InvalidElfFile, | ||
| 396 | error.InvalidElfMagic, | ||
| 397 | error.UsrBinEnvNotAvailable, | ||
| 398 | error.Unexpected, | ||
| 399 | error.UnexpectedEndOfFile, | ||
| 400 | error.NameTooLong, | ||
| 401 | // Finally, we fall back on the standard path. | ||
| 402 | => defaultAbiAndDynamicLinker(cpu, os, cross_target), | ||
| 403 | }; | ||
| 404 | } | ||
| 405 | |||
| 406 | const glibc_so_basename = "libc.so.6"; | ||
| 407 | |||
| 408 | fn glibcVerFromSO(so_path: [:0]const u8) !std.builtin.Version { | ||
| 409 | var link_buf: [std.os.PATH_MAX]u8 = undefined; | ||
| 410 | const link_name = std.os.readlinkC(so_path.ptr, &link_buf) catch |err| switch (err) { | ||
| 411 | error.AccessDenied => return error.GnuLibCVersionUnavailable, | ||
| 412 | error.FileSystem => return error.FileSystem, | ||
| 413 | error.SymLinkLoop => return error.SymLinkLoop, | ||
| 414 | error.NameTooLong => unreachable, | ||
| 415 | error.FileNotFound => return error.GnuLibCVersionUnavailable, | ||
| 416 | error.SystemResources => return error.SystemResources, | ||
| 417 | error.NotDir => return error.GnuLibCVersionUnavailable, | ||
| 418 | error.Unexpected => return error.GnuLibCVersionUnavailable, | ||
| 419 | }; | ||
| 420 | return glibcVerFromLinkName(link_name); | ||
| 421 | } | ||
| 422 | |||
| 423 | fn glibcVerFromLinkName(link_name: []const u8) !std.builtin.Version { | ||
| 424 | // example: "libc-2.3.4.so" | ||
| 425 | // example: "libc-2.27.so" | ||
| 426 | const prefix = "libc-"; | ||
| 427 | const suffix = ".so"; | ||
| 428 | if (!mem.startsWith(u8, link_name, prefix) or !mem.endsWith(u8, link_name, suffix)) { | ||
| 429 | return error.UnrecognizedGnuLibCFileName; | ||
| 430 | } | ||
| 431 | // chop off "libc-" and ".so" | ||
| 432 | const link_name_chopped = link_name[prefix.len .. link_name.len - suffix.len]; | ||
| 433 | return std.builtin.Version.parse(link_name_chopped) catch |err| switch (err) { | ||
| 434 | error.Overflow => return error.InvalidGnuLibCVersion, | ||
| 435 | error.InvalidCharacter => return error.InvalidGnuLibCVersion, | ||
| 436 | error.InvalidVersion => return error.InvalidGnuLibCVersion, | ||
| 437 | }; | ||
| 438 | } | ||
| 439 | |||
| 440 | fn abiAndDynamicLinkerFromUsrBinEnv( | ||
| 441 | cpu: Target.Cpu, | ||
| 442 | os: Target.Os, | ||
| 443 | ld_info_list: []const LdInfo, | ||
| 444 | cross_target: CrossTarget, | ||
| 445 | ) !NativeTargetInfo { | ||
| 446 | const env_file = std.fs.openFileAbsoluteC("/usr/bin/env", .{}) catch |err| switch (err) { | ||
| 447 | error.NoSpaceLeft => unreachable, | ||
| 448 | error.NameTooLong => unreachable, | ||
| 449 | error.PathAlreadyExists => unreachable, | ||
| 450 | error.SharingViolation => unreachable, | ||
| 451 | error.InvalidUtf8 => unreachable, | ||
| 452 | error.BadPathName => unreachable, | ||
| 453 | error.PipeBusy => unreachable, | ||
| 454 | |||
| 455 | error.IsDir => return error.UsrBinEnvNotAvailable, | ||
| 456 | error.NotDir => return error.UsrBinEnvNotAvailable, | ||
| 457 | error.AccessDenied => return error.UsrBinEnvNotAvailable, | ||
| 458 | error.NoDevice => return error.UsrBinEnvNotAvailable, | ||
| 459 | error.FileNotFound => return error.UsrBinEnvNotAvailable, | ||
| 460 | error.FileTooBig => return error.UsrBinEnvNotAvailable, | ||
| 461 | |||
| 462 | else => |e| return e, | ||
| 463 | }; | ||
| 464 | var hdr_buf: [@sizeOf(elf.Elf64_Ehdr)]u8 align(@alignOf(elf.Elf64_Ehdr)) = undefined; | ||
| 465 | _ = try preadFull(env_file, &hdr_buf, 0, hdr_buf.len); | ||
| 466 | const hdr32 = @ptrCast(*elf.Elf32_Ehdr, &hdr_buf); | ||
| 467 | const hdr64 = @ptrCast(*elf.Elf64_Ehdr, &hdr_buf); | ||
| 468 | if (!mem.eql(u8, hdr32.e_ident[0..4], "\x7fELF")) return error.InvalidElfMagic; | ||
| 469 | const elf_endian: std.builtin.Endian = switch (hdr32.e_ident[elf.EI_DATA]) { | ||
| 470 | elf.ELFDATA2LSB => .Little, | ||
| 471 | elf.ELFDATA2MSB => .Big, | ||
| 472 | else => return error.InvalidElfEndian, | ||
| 473 | }; | ||
| 474 | const need_bswap = elf_endian != std.builtin.endian; | ||
| 475 | if (hdr32.e_ident[elf.EI_VERSION] != 1) return error.InvalidElfVersion; | ||
| 476 | |||
| 477 | const is_64 = switch (hdr32.e_ident[elf.EI_CLASS]) { | ||
| 478 | elf.ELFCLASS32 => false, | ||
| 479 | elf.ELFCLASS64 => true, | ||
| 480 | else => return error.InvalidElfClass, | ||
| 481 | }; | ||
| 482 | var phoff = elfInt(is_64, need_bswap, hdr32.e_phoff, hdr64.e_phoff); | ||
| 483 | const phentsize = elfInt(is_64, need_bswap, hdr32.e_phentsize, hdr64.e_phentsize); | ||
| 484 | const phnum = elfInt(is_64, need_bswap, hdr32.e_phnum, hdr64.e_phnum); | ||
| 485 | |||
| 486 | var result: NativeTargetInfo = .{ | ||
| 487 | .target = .{ | ||
| 488 | .cpu = cpu, | ||
| 489 | .os = os, | ||
| 490 | .abi = cross_target.abi orelse Target.Abi.default(cpu.arch, os), | ||
| 491 | }, | ||
| 492 | .dynamic_linker = cross_target.dynamic_linker, | ||
| 493 | }; | ||
| 494 | var rpath_offset: ?u64 = null; // Found inside PT_DYNAMIC | ||
| 495 | const look_for_ld = cross_target.dynamic_linker.get() == null; | ||
| 496 | |||
| 497 | var ph_buf: [16 * @sizeOf(elf.Elf64_Phdr)]u8 align(@alignOf(elf.Elf64_Phdr)) = undefined; | ||
| 498 | if (phentsize > @sizeOf(elf.Elf64_Phdr)) return error.InvalidElfFile; | ||
| 499 | |||
| 500 | var ph_i: u16 = 0; | ||
| 501 | while (ph_i < phnum) { | ||
| 502 | // Reserve some bytes so that we can deref the 64-bit struct fields | ||
| 503 | // even when the ELF file is 32-bits. | ||
| 504 | const ph_reserve: usize = @sizeOf(elf.Elf64_Phdr) - @sizeOf(elf.Elf32_Phdr); | ||
| 505 | const ph_read_byte_len = try preadFull(env_file, ph_buf[0 .. ph_buf.len - ph_reserve], phoff, phentsize); | ||
| 506 | var ph_buf_i: usize = 0; | ||
| 507 | while (ph_buf_i < ph_read_byte_len and ph_i < phnum) : ({ | ||
| 508 | ph_i += 1; | ||
| 509 | phoff += phentsize; | ||
| 510 | ph_buf_i += phentsize; | ||
| 511 | }) { | ||
| 512 | const ph32 = @ptrCast(*elf.Elf32_Phdr, @alignCast(@alignOf(elf.Elf32_Phdr), &ph_buf[ph_buf_i])); | ||
| 513 | const ph64 = @ptrCast(*elf.Elf64_Phdr, @alignCast(@alignOf(elf.Elf64_Phdr), &ph_buf[ph_buf_i])); | ||
| 514 | const p_type = elfInt(is_64, need_bswap, ph32.p_type, ph64.p_type); | ||
| 515 | switch (p_type) { | ||
| 516 | elf.PT_INTERP => if (look_for_ld) { | ||
| 517 | const p_offset = elfInt(is_64, need_bswap, ph32.p_offset, ph64.p_offset); | ||
| 518 | const p_filesz = elfInt(is_64, need_bswap, ph32.p_filesz, ph64.p_filesz); | ||
| 519 | if (p_filesz > result.dynamic_linker.buffer.len) return error.NameTooLong; | ||
| 520 | _ = try preadFull(env_file, result.dynamic_linker.buffer[0..p_filesz], p_offset, p_filesz); | ||
| 521 | // PT_INTERP includes a null byte in p_filesz. | ||
| 522 | const len = p_filesz - 1; | ||
| 523 | // dynamic_linker.max_byte is "max", not "len". | ||
| 524 | // We know it will fit in u8 because we check against dynamic_linker.buffer.len above. | ||
| 525 | result.dynamic_linker.max_byte = @intCast(u8, len - 1); | ||
| 526 | |||
| 527 | // Use it to determine ABI. | ||
| 528 | const full_ld_path = result.dynamic_linker.buffer[0..len]; | ||
| 529 | for (ld_info_list) |ld_info| { | ||
| 530 | const standard_ld_basename = fs.path.basename(ld_info.ld.get().?); | ||
| 531 | if (std.mem.endsWith(u8, full_ld_path, standard_ld_basename)) { | ||
| 532 | result.target.abi = ld_info.abi; | ||
| 533 | break; | ||
| 534 | } | ||
| 535 | } | ||
| 536 | }, | ||
| 537 | // We only need this for detecting glibc version. | ||
| 538 | elf.PT_DYNAMIC => if (Target.current.os.tag == .linux and result.target.isGnuLibC() and | ||
| 539 | cross_target.glibc_version == null) | ||
| 540 | { | ||
| 541 | var dyn_off = elfInt(is_64, need_bswap, ph32.p_offset, ph64.p_offset); | ||
| 542 | const p_filesz = elfInt(is_64, need_bswap, ph32.p_filesz, ph64.p_filesz); | ||
| 543 | const dyn_size: u64 = if (is_64) @sizeOf(elf.Elf64_Dyn) else @sizeOf(elf.Elf32_Dyn); | ||
| 544 | const dyn_num = p_filesz / dyn_size; | ||
| 545 | var dyn_buf: [16 * @sizeOf(elf.Elf64_Dyn)]u8 align(@alignOf(elf.Elf64_Dyn)) = undefined; | ||
| 546 | var dyn_i: usize = 0; | ||
| 547 | dyn: while (dyn_i < dyn_num) { | ||
| 548 | // Reserve some bytes so that we can deref the 64-bit struct fields | ||
| 549 | // even when the ELF file is 32-bits. | ||
| 550 | const dyn_reserve: usize = @sizeOf(elf.Elf64_Dyn) - @sizeOf(elf.Elf32_Dyn); | ||
| 551 | const dyn_read_byte_len = try preadFull( | ||
| 552 | env_file, | ||
| 553 | dyn_buf[0 .. dyn_buf.len - dyn_reserve], | ||
| 554 | dyn_off, | ||
| 555 | dyn_size, | ||
| 556 | ); | ||
| 557 | var dyn_buf_i: usize = 0; | ||
| 558 | while (dyn_buf_i < dyn_read_byte_len and dyn_i < dyn_num) : ({ | ||
| 559 | dyn_i += 1; | ||
| 560 | dyn_off += dyn_size; | ||
| 561 | dyn_buf_i += dyn_size; | ||
| 562 | }) { | ||
| 563 | const dyn32 = @ptrCast( | ||
| 564 | *elf.Elf32_Dyn, | ||
| 565 | @alignCast(@alignOf(elf.Elf32_Dyn), &dyn_buf[dyn_buf_i]), | ||
| 566 | ); | ||
| 567 | const dyn64 = @ptrCast( | ||
| 568 | *elf.Elf64_Dyn, | ||
| 569 | @alignCast(@alignOf(elf.Elf64_Dyn), &dyn_buf[dyn_buf_i]), | ||
| 570 | ); | ||
| 571 | const tag = elfInt(is_64, need_bswap, dyn32.d_tag, dyn64.d_tag); | ||
| 572 | const val = elfInt(is_64, need_bswap, dyn32.d_val, dyn64.d_val); | ||
| 573 | if (tag == elf.DT_RUNPATH) { | ||
| 574 | rpath_offset = val; | ||
| 575 | break :dyn; | ||
| 576 | } | ||
| 577 | } | ||
| 578 | } | ||
| 579 | }, | ||
| 580 | else => continue, | ||
| 581 | } | ||
| 582 | } | ||
| 583 | } | ||
| 584 | |||
| 585 | if (Target.current.os.tag == .linux and result.target.isGnuLibC() and cross_target.glibc_version == null) { | ||
| 586 | if (rpath_offset) |rpoff| { | ||
| 587 | const shstrndx = elfInt(is_64, need_bswap, hdr32.e_shstrndx, hdr64.e_shstrndx); | ||
| 588 | |||
| 589 | var shoff = elfInt(is_64, need_bswap, hdr32.e_shoff, hdr64.e_shoff); | ||
| 590 | const shentsize = elfInt(is_64, need_bswap, hdr32.e_shentsize, hdr64.e_shentsize); | ||
| 591 | const str_section_off = shoff + @as(u64, shentsize) * @as(u64, shstrndx); | ||
| 592 | |||
| 593 | var sh_buf: [16 * @sizeOf(elf.Elf64_Shdr)]u8 align(@alignOf(elf.Elf64_Shdr)) = undefined; | ||
| 594 | if (sh_buf.len < shentsize) return error.InvalidElfFile; | ||
| 595 | |||
| 596 | _ = try preadFull(env_file, &sh_buf, str_section_off, shentsize); | ||
| 597 | const shstr32 = @ptrCast(*elf.Elf32_Shdr, @alignCast(@alignOf(elf.Elf32_Shdr), &sh_buf)); | ||
| 598 | const shstr64 = @ptrCast(*elf.Elf64_Shdr, @alignCast(@alignOf(elf.Elf64_Shdr), &sh_buf)); | ||
| 599 | const shstrtab_off = elfInt(is_64, need_bswap, shstr32.sh_offset, shstr64.sh_offset); | ||
| 600 | const shstrtab_size = elfInt(is_64, need_bswap, shstr32.sh_size, shstr64.sh_size); | ||
| 601 | var strtab_buf: [4096:0]u8 = undefined; | ||
| 602 | const shstrtab_len = std.math.min(shstrtab_size, strtab_buf.len); | ||
| 603 | const shstrtab_read_len = try preadFull(env_file, &strtab_buf, shstrtab_off, shstrtab_len); | ||
| 604 | const shstrtab = strtab_buf[0..shstrtab_read_len]; | ||
| 605 | |||
| 606 | const shnum = elfInt(is_64, need_bswap, hdr32.e_shnum, hdr64.e_shnum); | ||
| 607 | var sh_i: u16 = 0; | ||
| 608 | const dynstr: ?struct { offset: u64, size: u64 } = find_dyn_str: while (sh_i < shnum) { | ||
| 609 | // Reserve some bytes so that we can deref the 64-bit struct fields | ||
| 610 | // even when the ELF file is 32-bits. | ||
| 611 | const sh_reserve: usize = @sizeOf(elf.Elf64_Shdr) - @sizeOf(elf.Elf32_Shdr); | ||
| 612 | const sh_read_byte_len = try preadFull( | ||
| 613 | env_file, | ||
| 614 | sh_buf[0 .. sh_buf.len - sh_reserve], | ||
| 615 | shoff, | ||
| 616 | shentsize, | ||
| 617 | ); | ||
| 618 | var sh_buf_i: usize = 0; | ||
| 619 | while (sh_buf_i < sh_read_byte_len and sh_i < shnum) : ({ | ||
| 620 | sh_i += 1; | ||
| 621 | shoff += shentsize; | ||
| 622 | sh_buf_i += shentsize; | ||
| 623 | }) { | ||
| 624 | const sh32 = @ptrCast( | ||
| 625 | *elf.Elf32_Shdr, | ||
| 626 | @alignCast(@alignOf(elf.Elf32_Shdr), &sh_buf[sh_buf_i]), | ||
| 627 | ); | ||
| 628 | const sh64 = @ptrCast( | ||
| 629 | *elf.Elf64_Shdr, | ||
| 630 | @alignCast(@alignOf(elf.Elf64_Shdr), &sh_buf[sh_buf_i]), | ||
| 631 | ); | ||
| 632 | const sh_name_off = elfInt(is_64, need_bswap, sh32.sh_name, sh64.sh_name); | ||
| 633 | // TODO this pointer cast should not be necessary | ||
| 634 | const sh_name = mem.toSliceConst(u8, @ptrCast([*:0]u8, shstrtab[sh_name_off..].ptr)); | ||
| 635 | if (mem.eql(u8, sh_name, ".dynstr")) { | ||
| 636 | break :find_dyn_str .{ | ||
| 637 | .offset = elfInt(is_64, need_bswap, sh32.sh_offset, sh64.sh_offset), | ||
| 638 | .size = elfInt(is_64, need_bswap, sh32.sh_size, sh64.sh_size), | ||
| 639 | }; | ||
| 640 | } | ||
| 641 | } | ||
| 642 | } else null; | ||
| 643 | |||
| 644 | if (dynstr) |ds| { | ||
| 645 | const strtab_len = std.math.min(ds.size, strtab_buf.len); | ||
| 646 | const strtab_read_len = try preadFull(env_file, &strtab_buf, ds.offset, shstrtab_len); | ||
| 647 | const strtab = strtab_buf[0..strtab_read_len]; | ||
| 648 | // TODO this pointer cast should not be necessary | ||
| 649 | const rpath_list = mem.toSliceConst(u8, @ptrCast([*:0]u8, strtab[rpoff..].ptr)); | ||
| 650 | var it = mem.tokenize(rpath_list, ":"); | ||
| 651 | while (it.next()) |rpath| { | ||
| 652 | var dir = fs.cwd().openDirList(rpath) catch |err| switch (err) { | ||
| 653 | error.NameTooLong => unreachable, | ||
| 654 | error.InvalidUtf8 => unreachable, | ||
| 655 | error.BadPathName => unreachable, | ||
| 656 | error.DeviceBusy => unreachable, | ||
| 657 | |||
| 658 | error.FileNotFound, | ||
| 659 | error.NotDir, | ||
| 660 | error.AccessDenied, | ||
| 661 | error.NoDevice, | ||
| 662 | => continue, | ||
| 663 | |||
| 664 | error.ProcessFdQuotaExceeded, | ||
| 665 | error.SystemFdQuotaExceeded, | ||
| 666 | error.SystemResources, | ||
| 667 | error.SymLinkLoop, | ||
| 668 | error.Unexpected, | ||
| 669 | => |e| return e, | ||
| 670 | }; | ||
| 671 | defer dir.close(); | ||
| 672 | |||
| 673 | var link_buf: [std.os.PATH_MAX]u8 = undefined; | ||
| 674 | const link_name = std.os.readlinkatC( | ||
| 675 | dir.fd, | ||
| 676 | glibc_so_basename, | ||
| 677 | &link_buf, | ||
| 678 | ) catch |err| switch (err) { | ||
| 679 | error.NameTooLong => unreachable, | ||
| 680 | |||
| 681 | error.AccessDenied, | ||
| 682 | error.FileNotFound, | ||
| 683 | error.NotDir, | ||
| 684 | => continue, | ||
| 685 | |||
| 686 | error.SystemResources, | ||
| 687 | error.FileSystem, | ||
| 688 | error.SymLinkLoop, | ||
| 689 | error.Unexpected, | ||
| 690 | => |e| return e, | ||
| 691 | }; | ||
| 692 | result.target.os.version_range.linux.glibc = glibcVerFromLinkName( | ||
| 693 | link_name, | ||
| 694 | ) catch |err| switch (err) { | ||
| 695 | error.UnrecognizedGnuLibCFileName, | ||
| 696 | error.InvalidGnuLibCVersion, | ||
| 697 | => continue, | ||
| 698 | }; | ||
| 699 | break; | ||
| 700 | } | ||
| 701 | } | ||
| 702 | } | ||
| 703 | } | ||
| 704 | |||
| 705 | return result; | ||
| 706 | } | ||
| 707 | |||
| 708 | fn preadFull(file: fs.File, buf: []u8, offset: u64, min_read_len: usize) !usize { | ||
| 709 | var i: u64 = 0; | ||
| 710 | while (i < min_read_len) { | ||
| 711 | const len = file.pread(buf[i .. buf.len - i], offset + i) catch |err| switch (err) { | ||
| 712 | error.OperationAborted => unreachable, // Windows-only | ||
| 713 | error.WouldBlock => unreachable, // Did not request blocking mode | ||
| 714 | error.SystemResources => return error.SystemResources, | ||
| 715 | error.IsDir => return error.UnableToReadElfFile, | ||
| 716 | error.BrokenPipe => return error.UnableToReadElfFile, | ||
| 717 | error.ConnectionResetByPeer => return error.UnableToReadElfFile, | ||
| 718 | error.Unexpected => return error.Unexpected, | ||
| 719 | error.InputOutput => return error.FileSystem, | ||
| 720 | }; | ||
| 721 | if (len == 0) return error.UnexpectedEndOfFile; | ||
| 722 | i += len; | ||
| 723 | } | ||
| 724 | return i; | ||
| 725 | } | ||
| 726 | |||
| 727 | fn defaultAbiAndDynamicLinker(cpu: Target.Cpu, os: Target.Os, cross_target: CrossTarget) !NativeTargetInfo { | ||
| 728 | const target: Target = .{ | ||
| 729 | .cpu = cpu, | ||
| 730 | .os = os, | ||
| 731 | .abi = cross_target.abi orelse Target.Abi.default(cpu.arch, os), | ||
| 732 | }; | ||
| 733 | return NativeTargetInfo{ | ||
| 734 | .target = target, | ||
| 735 | .dynamic_linker = if (cross_target.dynamic_linker.get() == null) | ||
| 736 | target.standardDynamicLinkerPath() | ||
| 737 | else | ||
| 738 | cross_target.dynamic_linker, | ||
| 739 | }; | ||
| 740 | } | ||
| 741 | |||
| 742 | const LdInfo = struct { | ||
| 743 | ld: DynamicLinker, | ||
| 744 | abi: Target.Abi, | ||
| 745 | }; | ||
| 746 | |||
| 747 | fn elfInt(is_64: bool, need_bswap: bool, int_32: var, int_64: var) @TypeOf(int_64) { | ||
| 748 | if (is_64) { | ||
| 749 | if (need_bswap) { | ||
| 750 | return @byteSwap(@TypeOf(int_64), int_64); | ||
| 751 | } else { | ||
| 752 | return int_64; | ||
| 753 | } | ||
| 754 | } else { | ||
| 755 | if (need_bswap) { | ||
| 756 | return @byteSwap(@TypeOf(int_32), int_32); | ||
| 757 | } else { | ||
| 758 | return int_32; | ||
| 759 | } | ||
| 760 | } | ||
| 761 | } | ||
| 762 | |||
| 763 | fn detectNativeCpuAndFeatures(cross_target: CrossTarget) Target.Cpu { | ||
| 764 | // TODO Detect native CPU model & features. Until that is implemented we use baseline. | ||
| 765 | return baselineCpuAndFeatures(cross_target); | ||
| 766 | } | ||
| 767 | |||
| 768 | fn baselineCpuAndFeatures(cross_target: CrossTarget) Target.Cpu { | ||
| 769 | var adjusted_baseline = Target.Cpu.baseline(cross_target.getCpuArch()); | ||
| 770 | cross_target.updateCpuFeatures(&adjusted_baseline.features); | ||
| 771 | return adjusted_baseline; | ||
| 772 | } | ||
| 773 | }; |
src-self-hosted/c_int.zig+1-1| ... | @@ -70,7 +70,7 @@ pub const CInt = struct { | ... | @@ -70,7 +70,7 @@ pub const CInt = struct { |
| 70 | 70 | ||
| 71 | pub fn sizeInBits(cint: CInt, self: Target) u32 { | 71 | pub fn sizeInBits(cint: CInt, self: Target) u32 { |
| 72 | const arch = self.getArch(); | 72 | const arch = self.getArch(); |
| 73 | switch (self.getOs()) { | 73 | switch (self.os.tag) { |
| 74 | .freestanding, .other => switch (self.getArch()) { | 74 | .freestanding, .other => switch (self.getArch()) { |
| 75 | .msp430 => switch (cint.id) { | 75 | .msp430 => switch (cint.id) { |
| 76 | .Short, | 76 | .Short, |
src-self-hosted/clang.zig+1-1| ... | @@ -1050,7 +1050,7 @@ pub const struct_ZigClangExprEvalResult = extern struct { | ... | @@ -1050,7 +1050,7 @@ pub const struct_ZigClangExprEvalResult = extern struct { |
| 1050 | 1050 | ||
| 1051 | pub const struct_ZigClangAPValue = extern struct { | 1051 | pub const struct_ZigClangAPValue = extern struct { |
| 1052 | Kind: ZigClangAPValueKind, | 1052 | Kind: ZigClangAPValueKind, |
| 1053 | Data: if (builtin.os == .windows and builtin.abi == .msvc) [52]u8 else [68]u8, | 1053 | Data: if (builtin.os.tag == .windows and builtin.abi == .msvc) [52]u8 else [68]u8, |
| 1054 | }; | 1054 | }; |
| 1055 | pub extern fn ZigClangVarDecl_getTypeSourceInfo_getType(self: *const struct_ZigClangVarDecl) struct_ZigClangQualType; | 1055 | pub extern fn ZigClangVarDecl_getTypeSourceInfo_getType(self: *const struct_ZigClangVarDecl) struct_ZigClangQualType; |
| 1056 | 1056 |
src-self-hosted/introspect.zig+1-9| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | // Introspection and determination of system libraries needed by zig. | 1 | //! Introspection and determination of system libraries needed by zig. |
| 2 | 2 | ||
| 3 | const std = @import("std"); | 3 | const std = @import("std"); |
| 4 | const mem = std.mem; | 4 | const mem = std.mem; |
| ... | @@ -6,14 +6,6 @@ const fs = std.fs; | ... | @@ -6,14 +6,6 @@ const fs = std.fs; |
| 6 | 6 | ||
| 7 | const warn = std.debug.warn; | 7 | const warn = std.debug.warn; |
| 8 | 8 | ||
| 9 | pub fn detectDynamicLinker(allocator: *mem.Allocator, target: std.Target) ![:0]u8 { | ||
| 10 | if (target == .Native) { | ||
| 11 | return @import("libc_installation.zig").detectNativeDynamicLinker(allocator); | ||
| 12 | } else { | ||
| 13 | return target.getStandardDynamicLinkerPath(allocator); | ||
| 14 | } | ||
| 15 | } | ||
| 16 | |||
| 17 | /// Caller must free result | 9 | /// Caller must free result |
| 18 | pub fn testZigInstallPrefix(allocator: *mem.Allocator, test_path: []const u8) ![]u8 { | 10 | pub fn testZigInstallPrefix(allocator: *mem.Allocator, test_path: []const u8) ![]u8 { |
| 19 | const test_zig_dir = try fs.path.join(allocator, &[_][]const u8{ test_path, "lib", "zig" }); | 11 | const test_zig_dir = try fs.path.join(allocator, &[_][]const u8{ test_path, "lib", "zig" }); |
src-self-hosted/libc_installation.zig+12-114| ... | @@ -7,11 +7,7 @@ const Allocator = std.mem.Allocator; | ... | @@ -7,11 +7,7 @@ const Allocator = std.mem.Allocator; |
| 7 | const Batch = std.event.Batch; | 7 | const Batch = std.event.Batch; |
| 8 | 8 | ||
| 9 | const is_darwin = Target.current.isDarwin(); | 9 | const is_darwin = Target.current.isDarwin(); |
| 10 | const is_windows = Target.current.isWindows(); | 10 | const is_windows = Target.current.os.tag == .windows; |
| 11 | const is_freebsd = Target.current.isFreeBSD(); | ||
| 12 | const is_netbsd = Target.current.isNetBSD(); | ||
| 13 | const is_linux = Target.current.isLinux(); | ||
| 14 | const is_dragonfly = Target.current.isDragonFlyBSD(); | ||
| 15 | const is_gnu = Target.current.isGnu(); | 11 | const is_gnu = Target.current.isGnu(); |
| 16 | 12 | ||
| 17 | usingnamespace @import("windows_sdk.zig"); | 13 | usingnamespace @import("windows_sdk.zig"); |
| ... | @@ -99,27 +95,27 @@ pub const LibCInstallation = struct { | ... | @@ -99,27 +95,27 @@ pub const LibCInstallation = struct { |
| 99 | return error.ParseError; | 95 | return error.ParseError; |
| 100 | } | 96 | } |
| 101 | if (self.crt_dir == null and !is_darwin) { | 97 | if (self.crt_dir == null and !is_darwin) { |
| 102 | try stderr.print("crt_dir may not be empty for {}\n", .{@tagName(Target.current.getOs())}); | 98 | try stderr.print("crt_dir may not be empty for {}\n", .{@tagName(Target.current.os.tag)}); |
| 103 | return error.ParseError; | 99 | return error.ParseError; |
| 104 | } | 100 | } |
| 105 | if (self.static_crt_dir == null and is_windows and is_gnu) { | 101 | if (self.static_crt_dir == null and is_windows and is_gnu) { |
| 106 | try stderr.print("static_crt_dir may not be empty for {}-{}\n", .{ | 102 | try stderr.print("static_crt_dir may not be empty for {}-{}\n", .{ |
| 107 | @tagName(Target.current.getOs()), | 103 | @tagName(Target.current.os.tag), |
| 108 | @tagName(Target.current.getAbi()), | 104 | @tagName(Target.current.abi), |
| 109 | }); | 105 | }); |
| 110 | return error.ParseError; | 106 | return error.ParseError; |
| 111 | } | 107 | } |
| 112 | if (self.msvc_lib_dir == null and is_windows and !is_gnu) { | 108 | if (self.msvc_lib_dir == null and is_windows and !is_gnu) { |
| 113 | try stderr.print("msvc_lib_dir may not be empty for {}-{}\n", .{ | 109 | try stderr.print("msvc_lib_dir may not be empty for {}-{}\n", .{ |
| 114 | @tagName(Target.current.getOs()), | 110 | @tagName(Target.current.os.tag), |
| 115 | @tagName(Target.current.getAbi()), | 111 | @tagName(Target.current.abi), |
| 116 | }); | 112 | }); |
| 117 | return error.ParseError; | 113 | return error.ParseError; |
| 118 | } | 114 | } |
| 119 | if (self.kernel32_lib_dir == null and is_windows and !is_gnu) { | 115 | if (self.kernel32_lib_dir == null and is_windows and !is_gnu) { |
| 120 | try stderr.print("kernel32_lib_dir may not be empty for {}-{}\n", .{ | 116 | try stderr.print("kernel32_lib_dir may not be empty for {}-{}\n", .{ |
| 121 | @tagName(Target.current.getOs()), | 117 | @tagName(Target.current.os.tag), |
| 122 | @tagName(Target.current.getAbi()), | 118 | @tagName(Target.current.abi), |
| 123 | }); | 119 | }); |
| 124 | return error.ParseError; | 120 | return error.ParseError; |
| 125 | } | 121 | } |
| ... | @@ -216,10 +212,10 @@ pub const LibCInstallation = struct { | ... | @@ -216,10 +212,10 @@ pub const LibCInstallation = struct { |
| 216 | var batch = Batch(FindError!void, 2, .auto_async).init(); | 212 | var batch = Batch(FindError!void, 2, .auto_async).init(); |
| 217 | errdefer batch.wait() catch {}; | 213 | errdefer batch.wait() catch {}; |
| 218 | batch.add(&async self.findNativeIncludeDirPosix(args)); | 214 | batch.add(&async self.findNativeIncludeDirPosix(args)); |
| 219 | if (is_freebsd or is_netbsd) { | 215 | switch (Target.current.os.tag) { |
| 220 | self.crt_dir = try std.mem.dupeZ(args.allocator, u8, "/usr/lib"); | 216 | .freebsd, .netbsd => self.crt_dir = try std.mem.dupeZ(args.allocator, u8, "/usr/lib"), |
| 221 | } else if (is_linux or is_dragonfly) { | 217 | .linux, .dragonfly => batch.add(&async self.findNativeCrtDirPosix(args)), |
| 222 | batch.add(&async self.findNativeCrtDirPosix(args)); | 218 | else => {}, |
| 223 | } | 219 | } |
| 224 | break :blk batch.wait(); | 220 | break :blk batch.wait(); |
| 225 | }; | 221 | }; |
| ... | @@ -616,104 +612,6 @@ fn printVerboseInvocation( | ... | @@ -616,104 +612,6 @@ fn printVerboseInvocation( |
| 616 | } | 612 | } |
| 617 | } | 613 | } |
| 618 | 614 | ||
| 619 | /// Caller owns returned memory. | ||
| 620 | pub fn detectNativeDynamicLinker(allocator: *Allocator) error{ | ||
| 621 | OutOfMemory, | ||
| 622 | TargetHasNoDynamicLinker, | ||
| 623 | UnknownDynamicLinkerPath, | ||
| 624 | }![:0]u8 { | ||
| 625 | if (!comptime Target.current.hasDynamicLinker()) { | ||
| 626 | return error.TargetHasNoDynamicLinker; | ||
| 627 | } | ||
| 628 | |||
| 629 | // The current target's ABI cannot be relied on for this. For example, we may build the zig | ||
| 630 | // compiler for target riscv64-linux-musl and provide a tarball for users to download. | ||
| 631 | // A user could then run that zig compiler on riscv64-linux-gnu. This use case is well-defined | ||
| 632 | // and supported by Zig. But that means that we must detect the system ABI here rather than | ||
| 633 | // relying on `std.Target.current`. | ||
| 634 | |||
| 635 | const LdInfo = struct { | ||
| 636 | ld_path: []u8, | ||
| 637 | abi: Target.Abi, | ||
| 638 | }; | ||
| 639 | var ld_info_list = std.ArrayList(LdInfo).init(allocator); | ||
| 640 | defer { | ||
| 641 | for (ld_info_list.toSlice()) |ld_info| allocator.free(ld_info.ld_path); | ||
| 642 | ld_info_list.deinit(); | ||
| 643 | } | ||
| 644 | |||
| 645 | const all_abis = comptime blk: { | ||
| 646 | const fields = std.meta.fields(Target.Abi); | ||
| 647 | var array: [fields.len]Target.Abi = undefined; | ||
| 648 | inline for (fields) |field, i| { | ||
| 649 | array[i] = @field(Target.Abi, field.name); | ||
| 650 | } | ||
| 651 | break :blk array; | ||
| 652 | }; | ||
| 653 | for (all_abis) |abi| { | ||
| 654 | // This may be a nonsensical parameter. We detect this with error.UnknownDynamicLinkerPath and | ||
| 655 | // skip adding it to `ld_info_list`. | ||
| 656 | const target: Target = .{ | ||
| 657 | .Cross = .{ | ||
| 658 | .cpu = Target.Cpu.baseline(Target.current.getArch()), | ||
| 659 | .os = Target.current.getOs(), | ||
| 660 | .abi = abi, | ||
| 661 | }, | ||
| 662 | }; | ||
| 663 | const standard_ld_path = target.getStandardDynamicLinkerPath(allocator) catch |err| switch (err) { | ||
| 664 | error.OutOfMemory => return error.OutOfMemory, | ||
| 665 | error.UnknownDynamicLinkerPath, error.TargetHasNoDynamicLinker => continue, | ||
| 666 | }; | ||
| 667 | errdefer allocator.free(standard_ld_path); | ||
| 668 | try ld_info_list.append(.{ | ||
| 669 | .ld_path = standard_ld_path, | ||
| 670 | .abi = abi, | ||
| 671 | }); | ||
| 672 | } | ||
| 673 | |||
| 674 | // Best case scenario: the zig compiler is dynamically linked, and we can iterate | ||
| 675 | // over our own shared objects and find a dynamic linker. | ||
| 676 | { | ||
| 677 | const lib_paths = try std.process.getSelfExeSharedLibPaths(allocator); | ||
| 678 | defer allocator.free(lib_paths); | ||
| 679 | |||
| 680 | // This is O(N^M) but typical case here is N=2 and M=10. | ||
| 681 | for (lib_paths) |lib_path| { | ||
| 682 | for (ld_info_list.toSlice()) |ld_info| { | ||
| 683 | const standard_ld_basename = fs.path.basename(ld_info.ld_path); | ||
| 684 | if (std.mem.endsWith(u8, lib_path, standard_ld_basename)) { | ||
| 685 | return std.mem.dupeZ(allocator, u8, lib_path); | ||
| 686 | } | ||
| 687 | } | ||
| 688 | } | ||
| 689 | } | ||
| 690 | |||
| 691 | // If Zig is statically linked, such as via distributed binary static builds, the above | ||
| 692 | // trick won't work. What are we left with? Try to run the system C compiler and get | ||
| 693 | // it to tell us the dynamic linker path. | ||
| 694 | // TODO: instead of this, look at the shared libs of /usr/bin/env. | ||
| 695 | for (ld_info_list.toSlice()) |ld_info| { | ||
| 696 | const standard_ld_basename = fs.path.basename(ld_info.ld_path); | ||
| 697 | |||
| 698 | const full_ld_path = ccPrintFileName(.{ | ||
| 699 | .allocator = allocator, | ||
| 700 | .search_basename = standard_ld_basename, | ||
| 701 | .want_dirname = .full_path, | ||
| 702 | }) catch |err| switch (err) { | ||
| 703 | error.OutOfMemory => return error.OutOfMemory, | ||
| 704 | error.LibCRuntimeNotFound, | ||
| 705 | error.CCompilerExitCode, | ||
| 706 | error.CCompilerCrashed, | ||
| 707 | error.UnableToSpawnCCompiler, | ||
| 708 | => continue, | ||
| 709 | }; | ||
| 710 | return full_ld_path; | ||
| 711 | } | ||
| 712 | |||
| 713 | // Finally, we fall back on the standard path. | ||
| 714 | return Target.current.getStandardDynamicLinkerPath(allocator); | ||
| 715 | } | ||
| 716 | |||
| 717 | const Search = struct { | 615 | const Search = struct { |
| 718 | path: []const u8, | 616 | path: []const u8, |
| 719 | version: []const u8, | 617 | version: []const u8, |
src-self-hosted/link.zig+2-2| ... | @@ -515,7 +515,7 @@ const DarwinPlatform = struct { | ... | @@ -515,7 +515,7 @@ const DarwinPlatform = struct { |
| 515 | break :blk ver; | 515 | break :blk ver; |
| 516 | }, | 516 | }, |
| 517 | .None => blk: { | 517 | .None => blk: { |
| 518 | assert(comp.target.getOs() == .macosx); | 518 | assert(comp.target.os.tag == .macosx); |
| 519 | result.kind = .MacOS; | 519 | result.kind = .MacOS; |
| 520 | break :blk "10.14"; | 520 | break :blk "10.14"; |
| 521 | }, | 521 | }, |
| ... | @@ -534,7 +534,7 @@ const DarwinPlatform = struct { | ... | @@ -534,7 +534,7 @@ const DarwinPlatform = struct { |
| 534 | } | 534 | } |
| 535 | 535 | ||
| 536 | if (result.kind == .IPhoneOS) { | 536 | if (result.kind == .IPhoneOS) { |
| 537 | switch (comp.target.getArch()) { | 537 | switch (comp.target.cpu.arch) { |
| 538 | .i386, | 538 | .i386, |
| 539 | .x86_64, | 539 | .x86_64, |
| 540 | => result.kind = .IPhoneOSSimulator, | 540 | => result.kind = .IPhoneOSSimulator, |
src-self-hosted/main.zig+3-3| ... | @@ -79,9 +79,9 @@ pub fn main() !void { | ... | @@ -79,9 +79,9 @@ pub fn main() !void { |
| 79 | } else if (mem.eql(u8, cmd, "libc")) { | 79 | } else if (mem.eql(u8, cmd, "libc")) { |
| 80 | return cmdLibC(allocator, cmd_args); | 80 | return cmdLibC(allocator, cmd_args); |
| 81 | } else if (mem.eql(u8, cmd, "targets")) { | 81 | } else if (mem.eql(u8, cmd, "targets")) { |
| 82 | // TODO figure out the current target rather than using the target that was specified when | 82 | const info = try std.zig.system.NativeTargetInfo.detect(allocator); |
| 83 | // compiling the compiler | 83 | defer info.deinit(allocator); |
| 84 | return @import("print_targets.zig").cmdTargets(allocator, cmd_args, stdout, Target.current); | 84 | return @import("print_targets.zig").cmdTargets(allocator, cmd_args, stdout, info.target); |
| 85 | } else if (mem.eql(u8, cmd, "version")) { | 85 | } else if (mem.eql(u8, cmd, "version")) { |
| 86 | return cmdVersion(allocator, cmd_args); | 86 | return cmdVersion(allocator, cmd_args); |
| 87 | } else if (mem.eql(u8, cmd, "zen")) { | 87 | } else if (mem.eql(u8, cmd, "zen")) { |
src-self-hosted/print_targets.zig+6-6| ... | @@ -124,7 +124,7 @@ pub fn cmdTargets( | ... | @@ -124,7 +124,7 @@ pub fn cmdTargets( |
| 124 | 124 | ||
| 125 | try jws.objectField("os"); | 125 | try jws.objectField("os"); |
| 126 | try jws.beginArray(); | 126 | try jws.beginArray(); |
| 127 | inline for (@typeInfo(Target.Os).Enum.fields) |field| { | 127 | inline for (@typeInfo(Target.Os.Tag).Enum.fields) |field| { |
| 128 | try jws.arrayElem(); | 128 | try jws.arrayElem(); |
| 129 | try jws.emitString(field.name); | 129 | try jws.emitString(field.name); |
| 130 | } | 130 | } |
| ... | @@ -201,16 +201,16 @@ pub fn cmdTargets( | ... | @@ -201,16 +201,16 @@ pub fn cmdTargets( |
| 201 | try jws.objectField("cpu"); | 201 | try jws.objectField("cpu"); |
| 202 | try jws.beginObject(); | 202 | try jws.beginObject(); |
| 203 | try jws.objectField("arch"); | 203 | try jws.objectField("arch"); |
| 204 | try jws.emitString(@tagName(native_target.getArch())); | 204 | try jws.emitString(@tagName(native_target.cpu.arch)); |
| 205 | 205 | ||
| 206 | try jws.objectField("name"); | 206 | try jws.objectField("name"); |
| 207 | const cpu = native_target.getCpu(); | 207 | const cpu = native_target.cpu; |
| 208 | try jws.emitString(cpu.model.name); | 208 | try jws.emitString(cpu.model.name); |
| 209 | 209 | ||
| 210 | { | 210 | { |
| 211 | try jws.objectField("features"); | 211 | try jws.objectField("features"); |
| 212 | try jws.beginArray(); | 212 | try jws.beginArray(); |
| 213 | for (native_target.getArch().allFeaturesList()) |feature, i_usize| { | 213 | for (native_target.cpu.arch.allFeaturesList()) |feature, i_usize| { |
| 214 | const index = @intCast(Target.Cpu.Feature.Set.Index, i_usize); | 214 | const index = @intCast(Target.Cpu.Feature.Set.Index, i_usize); |
| 215 | if (cpu.features.isEnabled(index)) { | 215 | if (cpu.features.isEnabled(index)) { |
| 216 | try jws.arrayElem(); | 216 | try jws.arrayElem(); |
| ... | @@ -222,9 +222,9 @@ pub fn cmdTargets( | ... | @@ -222,9 +222,9 @@ pub fn cmdTargets( |
| 222 | try jws.endObject(); | 222 | try jws.endObject(); |
| 223 | } | 223 | } |
| 224 | try jws.objectField("os"); | 224 | try jws.objectField("os"); |
| 225 | try jws.emitString(@tagName(native_target.getOs())); | 225 | try jws.emitString(@tagName(native_target.os.tag)); |
| 226 | try jws.objectField("abi"); | 226 | try jws.objectField("abi"); |
| 227 | try jws.emitString(@tagName(native_target.getAbi())); | 227 | try jws.emitString(@tagName(native_target.abi)); |
| 228 | // TODO implement native glibc version detection in self-hosted | 228 | // TODO implement native glibc version detection in self-hosted |
| 229 | try jws.endObject(); | 229 | try jws.endObject(); |
| 230 | 230 |
src-self-hosted/stage2.zig+279-124| ... | @@ -10,6 +10,7 @@ const Allocator = mem.Allocator; | ... | @@ -10,6 +10,7 @@ const Allocator = mem.Allocator; |
| 10 | const ArrayList = std.ArrayList; | 10 | const ArrayList = std.ArrayList; |
| 11 | const Buffer = std.Buffer; | 11 | const Buffer = std.Buffer; |
| 12 | const Target = std.Target; | 12 | const Target = std.Target; |
| 13 | const CrossTarget = std.zig.CrossTarget; | ||
| 13 | const self_hosted_main = @import("main.zig"); | 14 | const self_hosted_main = @import("main.zig"); |
| 14 | const errmsg = @import("errmsg.zig"); | 15 | const errmsg = @import("errmsg.zig"); |
| 15 | const DepTokenizer = @import("dep_tokenizer.zig").Tokenizer; | 16 | const DepTokenizer = @import("dep_tokenizer.zig").Tokenizer; |
| ... | @@ -87,7 +88,7 @@ const Error = extern enum { | ... | @@ -87,7 +88,7 @@ const Error = extern enum { |
| 87 | NotLazy, | 88 | NotLazy, |
| 88 | IsAsync, | 89 | IsAsync, |
| 89 | ImportOutsidePkgPath, | 90 | ImportOutsidePkgPath, |
| 90 | UnknownCpu, | 91 | UnknownCpuModel, |
| 91 | UnknownCpuFeature, | 92 | UnknownCpuFeature, |
| 92 | InvalidCpuFeatures, | 93 | InvalidCpuFeatures, |
| 93 | InvalidLlvmCpuFeaturesFormat, | 94 | InvalidLlvmCpuFeaturesFormat, |
| ... | @@ -110,6 +111,8 @@ const Error = extern enum { | ... | @@ -110,6 +111,8 @@ const Error = extern enum { |
| 110 | WindowsSdkNotFound, | 111 | WindowsSdkNotFound, |
| 111 | UnknownDynamicLinkerPath, | 112 | UnknownDynamicLinkerPath, |
| 112 | TargetHasNoDynamicLinker, | 113 | TargetHasNoDynamicLinker, |
| 114 | InvalidAbiVersion, | ||
| 115 | InvalidOperatingSystemVersion, | ||
| 113 | }; | 116 | }; |
| 114 | 117 | ||
| 115 | const FILE = std.c.FILE; | 118 | const FILE = std.c.FILE; |
| ... | @@ -632,13 +635,9 @@ export fn stage2_cmd_targets(zig_triple: [*:0]const u8) c_int { | ... | @@ -632,13 +635,9 @@ export fn stage2_cmd_targets(zig_triple: [*:0]const u8) c_int { |
| 632 | } | 635 | } |
| 633 | 636 | ||
| 634 | fn cmdTargets(zig_triple: [*:0]const u8) !void { | 637 | fn cmdTargets(zig_triple: [*:0]const u8) !void { |
| 635 | var target = try Target.parse(.{ .arch_os_abi = mem.toSliceConst(u8, zig_triple) }); | 638 | var cross_target = try CrossTarget.parse(.{ .arch_os_abi = mem.toSliceConst(u8, zig_triple) }); |
| 636 | target.Cross.cpu = blk: { | 639 | var dynamic_linker: ?[*:0]u8 = null; |
| 637 | const llvm = @import("llvm.zig"); | 640 | const target = try crossTargetToTarget(cross_target, &dynamic_linker); |
| 638 | const llvm_cpu_name = llvm.GetHostCPUName(); | ||
| 639 | const llvm_cpu_features = llvm.GetNativeFeatures(); | ||
| 640 | break :blk try detectNativeCpuWithLLVM(target.getArch(), llvm_cpu_name, llvm_cpu_features); | ||
| 641 | }; | ||
| 642 | return @import("print_targets.zig").cmdTargets( | 641 | return @import("print_targets.zig").cmdTargets( |
| 643 | std.heap.c_allocator, | 642 | std.heap.c_allocator, |
| 644 | &[0][]u8{}, | 643 | &[0][]u8{}, |
| ... | @@ -652,16 +651,24 @@ export fn stage2_target_parse( | ... | @@ -652,16 +651,24 @@ export fn stage2_target_parse( |
| 652 | target: *Stage2Target, | 651 | target: *Stage2Target, |
| 653 | zig_triple: ?[*:0]const u8, | 652 | zig_triple: ?[*:0]const u8, |
| 654 | mcpu: ?[*:0]const u8, | 653 | mcpu: ?[*:0]const u8, |
| 654 | dynamic_linker: ?[*:0]const u8, | ||
| 655 | ) Error { | 655 | ) Error { |
| 656 | stage2TargetParse(target, zig_triple, mcpu) catch |err| switch (err) { | 656 | stage2TargetParse(target, zig_triple, mcpu, dynamic_linker) catch |err| switch (err) { |
| 657 | error.OutOfMemory => return .OutOfMemory, | 657 | error.OutOfMemory => return .OutOfMemory, |
| 658 | error.UnknownArchitecture => return .UnknownArchitecture, | 658 | error.UnknownArchitecture => return .UnknownArchitecture, |
| 659 | error.UnknownOperatingSystem => return .UnknownOperatingSystem, | 659 | error.UnknownOperatingSystem => return .UnknownOperatingSystem, |
| 660 | error.UnknownApplicationBinaryInterface => return .UnknownApplicationBinaryInterface, | 660 | error.UnknownApplicationBinaryInterface => return .UnknownApplicationBinaryInterface, |
| 661 | error.MissingOperatingSystem => return .MissingOperatingSystem, | 661 | error.MissingOperatingSystem => return .MissingOperatingSystem, |
| 662 | error.MissingArchitecture => return .MissingArchitecture, | ||
| 663 | error.InvalidLlvmCpuFeaturesFormat => return .InvalidLlvmCpuFeaturesFormat, | 662 | error.InvalidLlvmCpuFeaturesFormat => return .InvalidLlvmCpuFeaturesFormat, |
| 664 | error.UnexpectedExtraField => return .SemanticAnalyzeFail, | 663 | error.UnexpectedExtraField => return .SemanticAnalyzeFail, |
| 664 | error.InvalidAbiVersion => return .InvalidAbiVersion, | ||
| 665 | error.InvalidOperatingSystemVersion => return .InvalidOperatingSystemVersion, | ||
| 666 | error.FileSystem => return .FileSystem, | ||
| 667 | error.SymLinkLoop => return .SymLinkLoop, | ||
| 668 | error.SystemResources => return .SystemResources, | ||
| 669 | error.ProcessFdQuotaExceeded => return .ProcessFdQuotaExceeded, | ||
| 670 | error.SystemFdQuotaExceeded => return .SystemFdQuotaExceeded, | ||
| 671 | error.DeviceBusy => return .DeviceBusy, | ||
| 665 | }; | 672 | }; |
| 666 | return .None; | 673 | return .None; |
| 667 | } | 674 | } |
| ... | @@ -670,17 +677,20 @@ fn stage2TargetParse( | ... | @@ -670,17 +677,20 @@ fn stage2TargetParse( |
| 670 | stage1_target: *Stage2Target, | 677 | stage1_target: *Stage2Target, |
| 671 | zig_triple_oz: ?[*:0]const u8, | 678 | zig_triple_oz: ?[*:0]const u8, |
| 672 | mcpu_oz: ?[*:0]const u8, | 679 | mcpu_oz: ?[*:0]const u8, |
| 680 | dynamic_linker_oz: ?[*:0]const u8, | ||
| 673 | ) !void { | 681 | ) !void { |
| 674 | const target: Target = if (zig_triple_oz) |zig_triple_z| blk: { | 682 | const target: CrossTarget = if (zig_triple_oz) |zig_triple_z| blk: { |
| 675 | const zig_triple = mem.toSliceConst(u8, zig_triple_z); | 683 | const zig_triple = mem.toSliceConst(u8, zig_triple_z); |
| 676 | const mcpu = if (mcpu_oz) |mcpu_z| mem.toSliceConst(u8, mcpu_z) else "baseline"; | 684 | const mcpu = if (mcpu_oz) |mcpu_z| mem.toSliceConst(u8, mcpu_z) else null; |
| 677 | var diags: std.Target.ParseOptions.Diagnostics = .{}; | 685 | const dynamic_linker = if (dynamic_linker_oz) |dl_z| mem.toSliceConst(u8, dl_z) else null; |
| 678 | break :blk Target.parse(.{ | 686 | var diags: CrossTarget.ParseOptions.Diagnostics = .{}; |
| 687 | break :blk CrossTarget.parse(.{ | ||
| 679 | .arch_os_abi = zig_triple, | 688 | .arch_os_abi = zig_triple, |
| 680 | .cpu_features = mcpu, | 689 | .cpu_features = mcpu, |
| 690 | .dynamic_linker = dynamic_linker, | ||
| 681 | .diagnostics = &diags, | 691 | .diagnostics = &diags, |
| 682 | }) catch |err| switch (err) { | 692 | }) catch |err| switch (err) { |
| 683 | error.UnknownCpu => { | 693 | error.UnknownCpuModel => { |
| 684 | std.debug.warn("Unknown CPU: '{}'\nAvailable CPUs for architecture '{}':\n", .{ | 694 | std.debug.warn("Unknown CPU: '{}'\nAvailable CPUs for architecture '{}':\n", .{ |
| 685 | diags.cpu_name.?, | 695 | diags.cpu_name.?, |
| 686 | @tagName(diags.arch.?), | 696 | @tagName(diags.arch.?), |
| ... | @@ -706,73 +716,11 @@ fn stage2TargetParse( | ... | @@ -706,73 +716,11 @@ fn stage2TargetParse( |
| 706 | }, | 716 | }, |
| 707 | else => |e| return e, | 717 | else => |e| return e, |
| 708 | }; | 718 | }; |
| 709 | } else Target.Native; | 719 | } else .{}; |
| 710 | 720 | ||
| 711 | try stage1_target.fromTarget(target); | 721 | try stage1_target.fromTarget(target); |
| 712 | } | 722 | } |
| 713 | 723 | ||
| 714 | fn initStage1TargetCpuFeatures(stage1_target: *Stage2Target, cpu: Target.Cpu) !void { | ||
| 715 | const allocator = std.heap.c_allocator; | ||
| 716 | const cache_hash = try std.fmt.allocPrint0(allocator, "{}\n{}", .{ | ||
| 717 | cpu.model.name, | ||
| 718 | cpu.features.asBytes(), | ||
| 719 | }); | ||
| 720 | errdefer allocator.free(cache_hash); | ||
| 721 | |||
| 722 | const generic_arch_name = cpu.arch.genericName(); | ||
| 723 | var builtin_str_buffer = try std.Buffer.allocPrint(allocator, | ||
| 724 | \\Cpu{{ | ||
| 725 | \\ .arch = .{}, | ||
| 726 | \\ .model = &Target.{}.cpu.{}, | ||
| 727 | \\ .features = Target.{}.featureSet(&[_]Target.{}.Feature{{ | ||
| 728 | \\ | ||
| 729 | , .{ | ||
| 730 | @tagName(cpu.arch), | ||
| 731 | generic_arch_name, | ||
| 732 | cpu.model.name, | ||
| 733 | generic_arch_name, | ||
| 734 | generic_arch_name, | ||
| 735 | }); | ||
| 736 | defer builtin_str_buffer.deinit(); | ||
| 737 | |||
| 738 | var llvm_features_buffer = try std.Buffer.initSize(allocator, 0); | ||
| 739 | defer llvm_features_buffer.deinit(); | ||
| 740 | |||
| 741 | for (cpu.arch.allFeaturesList()) |feature, index_usize| { | ||
| 742 | const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize); | ||
| 743 | const is_enabled = cpu.features.isEnabled(index); | ||
| 744 | |||
| 745 | if (feature.llvm_name) |llvm_name| { | ||
| 746 | const plus_or_minus = "-+"[@boolToInt(is_enabled)]; | ||
| 747 | try llvm_features_buffer.appendByte(plus_or_minus); | ||
| 748 | try llvm_features_buffer.append(llvm_name); | ||
| 749 | try llvm_features_buffer.append(","); | ||
| 750 | } | ||
| 751 | |||
| 752 | if (is_enabled) { | ||
| 753 | // TODO some kind of "zig identifier escape" function rather than | ||
| 754 | // unconditionally using @"" syntax | ||
| 755 | try builtin_str_buffer.append(" .@\""); | ||
| 756 | try builtin_str_buffer.append(feature.name); | ||
| 757 | try builtin_str_buffer.append("\",\n"); | ||
| 758 | } | ||
| 759 | } | ||
| 760 | |||
| 761 | try builtin_str_buffer.append( | ||
| 762 | \\ }), | ||
| 763 | \\}; | ||
| 764 | \\ | ||
| 765 | ); | ||
| 766 | |||
| 767 | assert(mem.endsWith(u8, llvm_features_buffer.toSliceConst(), ",")); | ||
| 768 | llvm_features_buffer.shrink(llvm_features_buffer.len() - 1); | ||
| 769 | |||
| 770 | stage1_target.llvm_cpu_name = if (cpu.model.llvm_name) |s| s.ptr else null; | ||
| 771 | stage1_target.llvm_cpu_features = llvm_features_buffer.toOwnedSlice().ptr; | ||
| 772 | stage1_target.builtin_str = builtin_str_buffer.toOwnedSlice().ptr; | ||
| 773 | stage1_target.cache_hash = cache_hash.ptr; | ||
| 774 | } | ||
| 775 | |||
| 776 | // ABI warning | 724 | // ABI warning |
| 777 | const Stage2LibCInstallation = extern struct { | 725 | const Stage2LibCInstallation = extern struct { |
| 778 | include_dir: [*:0]const u8, | 726 | include_dir: [*:0]const u8, |
| ... | @@ -948,15 +896,18 @@ const Stage2Target = extern struct { | ... | @@ -948,15 +896,18 @@ const Stage2Target = extern struct { |
| 948 | 896 | ||
| 949 | is_native: bool, | 897 | is_native: bool, |
| 950 | 898 | ||
| 951 | glibc_version: ?*Stage2GLibCVersion, // null means default | 899 | glibc_or_darwin_version: ?*Stage2SemVer, |
| 952 | 900 | ||
| 953 | llvm_cpu_name: ?[*:0]const u8, | 901 | llvm_cpu_name: ?[*:0]const u8, |
| 954 | llvm_cpu_features: ?[*:0]const u8, | 902 | llvm_cpu_features: ?[*:0]const u8, |
| 955 | builtin_str: ?[*:0]const u8, | 903 | cpu_builtin_str: ?[*:0]const u8, |
| 956 | cache_hash: ?[*:0]const u8, | 904 | cache_hash: ?[*:0]const u8, |
| 905 | os_builtin_str: ?[*:0]const u8, | ||
| 957 | 906 | ||
| 958 | fn toTarget(in_target: Stage2Target) Target { | 907 | dynamic_linker: ?[*:0]const u8, |
| 959 | if (in_target.is_native) return .Native; | 908 | |
| 909 | fn toTarget(in_target: Stage2Target) CrossTarget { | ||
| 910 | if (in_target.is_native) return .{}; | ||
| 960 | 911 | ||
| 961 | const in_arch = in_target.arch - 1; // skip over ZigLLVM_UnknownArch | 912 | const in_arch = in_target.arch - 1; // skip over ZigLLVM_UnknownArch |
| 962 | const in_os = in_target.os; | 913 | const in_os = in_target.os; |
| ... | @@ -965,66 +916,270 @@ const Stage2Target = extern struct { | ... | @@ -965,66 +916,270 @@ const Stage2Target = extern struct { |
| 965 | return .{ | 916 | return .{ |
| 966 | .Cross = .{ | 917 | .Cross = .{ |
| 967 | .cpu = Target.Cpu.baseline(enumInt(Target.Cpu.Arch, in_arch)), | 918 | .cpu = Target.Cpu.baseline(enumInt(Target.Cpu.Arch, in_arch)), |
| 968 | .os = enumInt(Target.Os, in_os), | 919 | .os = Target.Os.defaultVersionRange(enumInt(Target.Os.Tag, in_os)), |
| 969 | .abi = enumInt(Target.Abi, in_abi), | 920 | .abi = enumInt(Target.Abi, in_abi), |
| 970 | }, | 921 | }, |
| 971 | }; | 922 | }; |
| 972 | } | 923 | } |
| 973 | 924 | ||
| 974 | fn fromTarget(self: *Stage2Target, target: Target) !void { | 925 | fn fromTarget(self: *Stage2Target, cross_target: CrossTarget) !void { |
| 975 | const cpu = switch (target) { | 926 | const allocator = std.heap.c_allocator; |
| 976 | .Native => blk: { | 927 | |
| 977 | // TODO self-host CPU model and feature detection instead of relying on LLVM | 928 | var dynamic_linker: ?[*:0]u8 = null; |
| 978 | const llvm = @import("llvm.zig"); | 929 | const target = try crossTargetToTarget(cross_target, &dynamic_linker); |
| 979 | const llvm_cpu_name = llvm.GetHostCPUName(); | 930 | |
| 980 | const llvm_cpu_features = llvm.GetNativeFeatures(); | 931 | var cache_hash = try std.Buffer.allocPrint(allocator, "{}\n{}\n", .{ |
| 981 | break :blk try detectNativeCpuWithLLVM(target.getArch(), llvm_cpu_name, llvm_cpu_features); | 932 | target.cpu.model.name, |
| 982 | }, | 933 | target.cpu.features.asBytes(), |
| 983 | .Cross => target.getCpu(), | 934 | }); |
| 935 | defer cache_hash.deinit(); | ||
| 936 | |||
| 937 | const generic_arch_name = target.cpu.arch.genericName(); | ||
| 938 | var cpu_builtin_str_buffer = try std.Buffer.allocPrint(allocator, | ||
| 939 | \\Cpu{{ | ||
| 940 | \\ .arch = .{}, | ||
| 941 | \\ .model = &Target.{}.cpu.{}, | ||
| 942 | \\ .features = Target.{}.featureSet(&[_]Target.{}.Feature{{ | ||
| 943 | \\ | ||
| 944 | , .{ | ||
| 945 | @tagName(target.cpu.arch), | ||
| 946 | generic_arch_name, | ||
| 947 | target.cpu.model.name, | ||
| 948 | generic_arch_name, | ||
| 949 | generic_arch_name, | ||
| 950 | }); | ||
| 951 | defer cpu_builtin_str_buffer.deinit(); | ||
| 952 | |||
| 953 | var llvm_features_buffer = try std.Buffer.initSize(allocator, 0); | ||
| 954 | defer llvm_features_buffer.deinit(); | ||
| 955 | |||
| 956 | for (target.cpu.arch.allFeaturesList()) |feature, index_usize| { | ||
| 957 | const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize); | ||
| 958 | const is_enabled = target.cpu.features.isEnabled(index); | ||
| 959 | |||
| 960 | if (feature.llvm_name) |llvm_name| { | ||
| 961 | const plus_or_minus = "-+"[@boolToInt(is_enabled)]; | ||
| 962 | try llvm_features_buffer.appendByte(plus_or_minus); | ||
| 963 | try llvm_features_buffer.append(llvm_name); | ||
| 964 | try llvm_features_buffer.append(","); | ||
| 965 | } | ||
| 966 | |||
| 967 | if (is_enabled) { | ||
| 968 | // TODO some kind of "zig identifier escape" function rather than | ||
| 969 | // unconditionally using @"" syntax | ||
| 970 | try cpu_builtin_str_buffer.append(" .@\""); | ||
| 971 | try cpu_builtin_str_buffer.append(feature.name); | ||
| 972 | try cpu_builtin_str_buffer.append("\",\n"); | ||
| 973 | } | ||
| 974 | } | ||
| 975 | |||
| 976 | try cpu_builtin_str_buffer.append( | ||
| 977 | \\ }), | ||
| 978 | \\}; | ||
| 979 | \\ | ||
| 980 | ); | ||
| 981 | |||
| 982 | assert(mem.endsWith(u8, llvm_features_buffer.toSliceConst(), ",")); | ||
| 983 | llvm_features_buffer.shrink(llvm_features_buffer.len() - 1); | ||
| 984 | |||
| 985 | var os_builtin_str_buffer = try std.Buffer.allocPrint(allocator, | ||
| 986 | \\Os{{ | ||
| 987 | \\ .tag = .{}, | ||
| 988 | \\ .version_range = .{{ | ||
| 989 | , .{@tagName(target.os.tag)}); | ||
| 990 | defer os_builtin_str_buffer.deinit(); | ||
| 991 | |||
| 992 | // We'll re-use the OS version range builtin string for the cache hash. | ||
| 993 | const os_builtin_str_ver_start_index = os_builtin_str_buffer.len(); | ||
| 994 | |||
| 995 | @setEvalBranchQuota(2000); | ||
| 996 | switch (target.os.tag) { | ||
| 997 | .freestanding, | ||
| 998 | .ananas, | ||
| 999 | .cloudabi, | ||
| 1000 | .dragonfly, | ||
| 1001 | .fuchsia, | ||
| 1002 | .ios, | ||
| 1003 | .kfreebsd, | ||
| 1004 | .lv2, | ||
| 1005 | .solaris, | ||
| 1006 | .haiku, | ||
| 1007 | .minix, | ||
| 1008 | .rtems, | ||
| 1009 | .nacl, | ||
| 1010 | .cnk, | ||
| 1011 | .aix, | ||
| 1012 | .cuda, | ||
| 1013 | .nvcl, | ||
| 1014 | .amdhsa, | ||
| 1015 | .ps4, | ||
| 1016 | .elfiamcu, | ||
| 1017 | .tvos, | ||
| 1018 | .watchos, | ||
| 1019 | .mesa3d, | ||
| 1020 | .contiki, | ||
| 1021 | .amdpal, | ||
| 1022 | .hermit, | ||
| 1023 | .hurd, | ||
| 1024 | .wasi, | ||
| 1025 | .emscripten, | ||
| 1026 | .uefi, | ||
| 1027 | .other, | ||
| 1028 | => try os_builtin_str_buffer.append(" .none = {} }\n"), | ||
| 1029 | |||
| 1030 | .freebsd, | ||
| 1031 | .macosx, | ||
| 1032 | .netbsd, | ||
| 1033 | .openbsd, | ||
| 1034 | => try os_builtin_str_buffer.print( | ||
| 1035 | \\ .semver = .{{ | ||
| 1036 | \\ .min = .{{ | ||
| 1037 | \\ .major = {}, | ||
| 1038 | \\ .minor = {}, | ||
| 1039 | \\ .patch = {}, | ||
| 1040 | \\ }}, | ||
| 1041 | \\ .max = .{{ | ||
| 1042 | \\ .major = {}, | ||
| 1043 | \\ .minor = {}, | ||
| 1044 | \\ .patch = {}, | ||
| 1045 | \\ }}, | ||
| 1046 | \\ }}}}, | ||
| 1047 | \\ | ||
| 1048 | , .{ | ||
| 1049 | target.os.version_range.semver.min.major, | ||
| 1050 | target.os.version_range.semver.min.minor, | ||
| 1051 | target.os.version_range.semver.min.patch, | ||
| 1052 | |||
| 1053 | target.os.version_range.semver.max.major, | ||
| 1054 | target.os.version_range.semver.max.minor, | ||
| 1055 | target.os.version_range.semver.max.patch, | ||
| 1056 | }), | ||
| 1057 | |||
| 1058 | .linux => try os_builtin_str_buffer.print( | ||
| 1059 | \\ .linux = .{{ | ||
| 1060 | \\ .range = .{{ | ||
| 1061 | \\ .min = .{{ | ||
| 1062 | \\ .major = {}, | ||
| 1063 | \\ .minor = {}, | ||
| 1064 | \\ .patch = {}, | ||
| 1065 | \\ }}, | ||
| 1066 | \\ .max = .{{ | ||
| 1067 | \\ .major = {}, | ||
| 1068 | \\ .minor = {}, | ||
| 1069 | \\ .patch = {}, | ||
| 1070 | \\ }}, | ||
| 1071 | \\ }}, | ||
| 1072 | \\ .glibc = .{{ | ||
| 1073 | \\ .major = {}, | ||
| 1074 | \\ .minor = {}, | ||
| 1075 | \\ .patch = {}, | ||
| 1076 | \\ }}, | ||
| 1077 | \\ }}}}, | ||
| 1078 | \\ | ||
| 1079 | , .{ | ||
| 1080 | target.os.version_range.linux.range.min.major, | ||
| 1081 | target.os.version_range.linux.range.min.minor, | ||
| 1082 | target.os.version_range.linux.range.min.patch, | ||
| 1083 | |||
| 1084 | target.os.version_range.linux.range.max.major, | ||
| 1085 | target.os.version_range.linux.range.max.minor, | ||
| 1086 | target.os.version_range.linux.range.max.patch, | ||
| 1087 | |||
| 1088 | target.os.version_range.linux.glibc.major, | ||
| 1089 | target.os.version_range.linux.glibc.minor, | ||
| 1090 | target.os.version_range.linux.glibc.patch, | ||
| 1091 | }), | ||
| 1092 | |||
| 1093 | .windows => try os_builtin_str_buffer.print( | ||
| 1094 | \\ .windows = .{{ | ||
| 1095 | \\ .min = .{}, | ||
| 1096 | \\ .max = .{}, | ||
| 1097 | \\ }}}}, | ||
| 1098 | \\ | ||
| 1099 | , .{ | ||
| 1100 | @tagName(target.os.version_range.windows.min), | ||
| 1101 | @tagName(target.os.version_range.windows.max), | ||
| 1102 | }), | ||
| 1103 | } | ||
| 1104 | try os_builtin_str_buffer.append("};\n"); | ||
| 1105 | |||
| 1106 | try cache_hash.append( | ||
| 1107 | os_builtin_str_buffer.toSlice()[os_builtin_str_ver_start_index..os_builtin_str_buffer.len()], | ||
| 1108 | ); | ||
| 1109 | |||
| 1110 | const glibc_or_darwin_version = blk: { | ||
| 1111 | if (target.isGnuLibC()) { | ||
| 1112 | const stage1_glibc = try std.heap.c_allocator.create(Stage2SemVer); | ||
| 1113 | const stage2_glibc = target.os.version_range.linux.glibc; | ||
| 1114 | stage1_glibc.* = .{ | ||
| 1115 | .major = stage2_glibc.major, | ||
| 1116 | .minor = stage2_glibc.minor, | ||
| 1117 | .patch = stage2_glibc.patch, | ||
| 1118 | }; | ||
| 1119 | break :blk stage1_glibc; | ||
| 1120 | } else if (target.isDarwin()) { | ||
| 1121 | const stage1_semver = try std.heap.c_allocator.create(Stage2SemVer); | ||
| 1122 | const stage2_semver = target.os.version_range.semver.min; | ||
| 1123 | stage1_semver.* = .{ | ||
| 1124 | .major = stage2_semver.major, | ||
| 1125 | .minor = stage2_semver.minor, | ||
| 1126 | .patch = stage2_semver.patch, | ||
| 1127 | }; | ||
| 1128 | break :blk stage1_semver; | ||
| 1129 | } else { | ||
| 1130 | break :blk null; | ||
| 1131 | } | ||
| 984 | }; | 1132 | }; |
| 1133 | |||
| 985 | self.* = .{ | 1134 | self.* = .{ |
| 986 | .arch = @enumToInt(target.getArch()) + 1, // skip over ZigLLVM_UnknownArch | 1135 | .arch = @enumToInt(target.cpu.arch) + 1, // skip over ZigLLVM_UnknownArch |
| 987 | .vendor = 0, | 1136 | .vendor = 0, |
| 988 | .os = @enumToInt(target.getOs()), | 1137 | .os = @enumToInt(target.os.tag), |
| 989 | .abi = @enumToInt(target.getAbi()), | 1138 | .abi = @enumToInt(target.abi), |
| 990 | .llvm_cpu_name = null, | 1139 | .llvm_cpu_name = if (target.cpu.model.llvm_name) |s| s.ptr else null, |
| 991 | .llvm_cpu_features = null, | 1140 | .llvm_cpu_features = llvm_features_buffer.toOwnedSlice().ptr, |
| 992 | .builtin_str = null, | 1141 | .cpu_builtin_str = cpu_builtin_str_buffer.toOwnedSlice().ptr, |
| 993 | .cache_hash = null, | 1142 | .os_builtin_str = os_builtin_str_buffer.toOwnedSlice().ptr, |
| 994 | .is_native = target == .Native, | 1143 | .cache_hash = cache_hash.toOwnedSlice().ptr, |
| 995 | .glibc_version = null, | 1144 | .is_native = cross_target.isNative(), |
| 1145 | .glibc_or_darwin_version = glibc_or_darwin_version, | ||
| 1146 | .dynamic_linker = dynamic_linker, | ||
| 996 | }; | 1147 | }; |
| 997 | try initStage1TargetCpuFeatures(self, cpu); | ||
| 998 | } | 1148 | } |
| 999 | }; | 1149 | }; |
| 1000 | 1150 | ||
| 1151 | fn enumInt(comptime Enum: type, int: c_int) Enum { | ||
| 1152 | return @intToEnum(Enum, @intCast(@TagType(Enum), int)); | ||
| 1153 | } | ||
| 1154 | |||
| 1155 | fn crossTargetToTarget(cross_target: CrossTarget, dynamic_linker_ptr: *?[*:0]u8) !Target { | ||
| 1156 | var info = try std.zig.system.NativeTargetInfo.detect(std.heap.c_allocator, cross_target); | ||
| 1157 | if (cross_target.cpu_arch == null or cross_target.cpu_model == .native) { | ||
| 1158 | // TODO We want to just use detected_info.target but implementing | ||
| 1159 | // CPU model & feature detection is todo so here we rely on LLVM. | ||
| 1160 | const llvm = @import("llvm.zig"); | ||
| 1161 | const llvm_cpu_name = llvm.GetHostCPUName(); | ||
| 1162 | const llvm_cpu_features = llvm.GetNativeFeatures(); | ||
| 1163 | const arch = std.Target.current.cpu.arch; | ||
| 1164 | info.target.cpu = try detectNativeCpuWithLLVM(arch, llvm_cpu_name, llvm_cpu_features); | ||
| 1165 | cross_target.updateCpuFeatures(&info.target.cpu.features); | ||
| 1166 | info.target.cpu.arch = cross_target.getCpuArch(); | ||
| 1167 | } | ||
| 1168 | if (info.dynamic_linker.get()) |dl| { | ||
| 1169 | dynamic_linker_ptr.* = try mem.dupeZ(std.heap.c_allocator, u8, dl); | ||
| 1170 | } else { | ||
| 1171 | dynamic_linker_ptr.* = null; | ||
| 1172 | } | ||
| 1173 | return info.target; | ||
| 1174 | } | ||
| 1175 | |||
| 1001 | // ABI warning | 1176 | // ABI warning |
| 1002 | const Stage2GLibCVersion = extern struct { | 1177 | const Stage2SemVer = extern struct { |
| 1003 | major: u32, | 1178 | major: u32, |
| 1004 | minor: u32, | 1179 | minor: u32, |
| 1005 | patch: u32, | 1180 | patch: u32, |
| 1006 | }; | 1181 | }; |
| 1007 | 1182 | ||
| 1008 | // ABI warning | ||
| 1009 | export fn stage2_detect_dynamic_linker(in_target: *const Stage2Target, out_ptr: *[*:0]u8, out_len: *usize) Error { | ||
| 1010 | const target = in_target.toTarget(); | ||
| 1011 | const result = @import("introspect.zig").detectDynamicLinker( | ||
| 1012 | std.heap.c_allocator, | ||
| 1013 | target, | ||
| 1014 | ) catch |err| switch (err) { | ||
| 1015 | error.OutOfMemory => return .OutOfMemory, | ||
| 1016 | error.UnknownDynamicLinkerPath => return .UnknownDynamicLinkerPath, | ||
| 1017 | error.TargetHasNoDynamicLinker => return .TargetHasNoDynamicLinker, | ||
| 1018 | }; | ||
| 1019 | out_ptr.* = result.ptr; | ||
| 1020 | out_len.* = result.len; | ||
| 1021 | return .None; | ||
| 1022 | } | ||
| 1023 | |||
| 1024 | fn enumInt(comptime Enum: type, int: c_int) Enum { | ||
| 1025 | return @intToEnum(Enum, @intCast(@TagType(Enum), int)); | ||
| 1026 | } | ||
| 1027 | |||
| 1028 | // ABI warning | 1183 | // ABI warning |
| 1029 | const Stage2NativePaths = extern struct { | 1184 | const Stage2NativePaths = extern struct { |
| 1030 | include_dirs_ptr: [*][*:0]u8, | 1185 | include_dirs_ptr: [*][*:0]u8, |
src-self-hosted/util.zig-22| ... | @@ -34,25 +34,3 @@ pub fn initializeAllTargets() void { | ... | @@ -34,25 +34,3 @@ pub fn initializeAllTargets() void { |
| 34 | llvm.InitializeAllAsmPrinters(); | 34 | llvm.InitializeAllAsmPrinters(); |
| 35 | llvm.InitializeAllAsmParsers(); | 35 | llvm.InitializeAllAsmParsers(); |
| 36 | } | 36 | } |
| 37 | |||
| 38 | pub fn getTriple(allocator: *std.mem.Allocator, self: std.Target) !std.Buffer { | ||
| 39 | var result = try std.Buffer.initSize(allocator, 0); | ||
| 40 | errdefer result.deinit(); | ||
| 41 | |||
| 42 | // LLVM WebAssembly output support requires the target to be activated at | ||
| 43 | // build type with -DCMAKE_LLVM_EXPIERMENTAL_TARGETS_TO_BUILD=WebAssembly. | ||
| 44 | // | ||
| 45 | // LLVM determines the output format based on the abi suffix, | ||
| 46 | // defaulting to an object based on the architecture. The default format in | ||
| 47 | // LLVM 6 sets the wasm arch output incorrectly to ELF. We need to | ||
| 48 | // explicitly set this ourself in order for it to work. | ||
| 49 | // | ||
| 50 | // This is fixed in LLVM 7 and you will be able to get wasm output by | ||
| 51 | // using the target triple `wasm32-unknown-unknown-unknown`. | ||
| 52 | const env_name = if (self.isWasm()) "wasm" else @tagName(self.getAbi()); | ||
| 53 | |||
| 54 | var out = &std.io.BufferOutStream.init(&result).stream; | ||
| 55 | try out.print("{}-unknown-{}-{}", .{ @tagName(self.getArch()), @tagName(self.getOs()), env_name }); | ||
| 56 | |||
| 57 | return result; | ||
| 58 | } |
src/all_types.hpp-3| ... | @@ -2250,14 +2250,11 @@ struct CodeGen { | ... | @@ -2250,14 +2250,11 @@ struct CodeGen { |
| 2250 | bool test_is_evented; | 2250 | bool test_is_evented; |
| 2251 | CodeModel code_model; | 2251 | CodeModel code_model; |
| 2252 | 2252 | ||
| 2253 | Buf *mmacosx_version_min; | ||
| 2254 | Buf *mios_version_min; | ||
| 2255 | Buf *root_out_name; | 2253 | Buf *root_out_name; |
| 2256 | Buf *test_filter; | 2254 | Buf *test_filter; |
| 2257 | Buf *test_name_prefix; | 2255 | Buf *test_name_prefix; |
| 2258 | Buf *zig_lib_dir; | 2256 | Buf *zig_lib_dir; |
| 2259 | Buf *zig_std_dir; | 2257 | Buf *zig_std_dir; |
| 2260 | Buf *dynamic_linker_path; | ||
| 2261 | Buf *version_script_path; | 2258 | Buf *version_script_path; |
| 2262 | 2259 | ||
| 2263 | const char **llvm_argv; | 2260 | const char **llvm_argv; |
src/analyze.cpp+20-23| ... | @@ -3963,7 +3963,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var, bool allow_lazy) { | ... | @@ -3963,7 +3963,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var, bool allow_lazy) { |
| 3963 | 3963 | ||
| 3964 | // TODO more validation for types that can't be used for export/extern variables | 3964 | // TODO more validation for types that can't be used for export/extern variables |
| 3965 | ZigType *implicit_type = nullptr; | 3965 | ZigType *implicit_type = nullptr; |
| 3966 | if (explicit_type != nullptr && explicit_type->id == ZigTypeIdInvalid) { | 3966 | if (explicit_type != nullptr && type_is_invalid(explicit_type)) { |
| 3967 | implicit_type = explicit_type; | 3967 | implicit_type = explicit_type; |
| 3968 | } else if (var_decl->expr) { | 3968 | } else if (var_decl->expr) { |
| 3969 | init_value = analyze_const_value(g, tld_var->base.parent_scope, var_decl->expr, explicit_type, | 3969 | init_value = analyze_const_value(g, tld_var->base.parent_scope, var_decl->expr, explicit_type, |
| ... | @@ -5401,6 +5401,8 @@ bool generic_fn_type_id_eql(GenericFnTypeId *a, GenericFnTypeId *b) { | ... | @@ -5401,6 +5401,8 @@ bool generic_fn_type_id_eql(GenericFnTypeId *a, GenericFnTypeId *b) { |
| 5401 | 5401 | ||
| 5402 | static bool can_mutate_comptime_var_state(ZigValue *value) { | 5402 | static bool can_mutate_comptime_var_state(ZigValue *value) { |
| 5403 | assert(value != nullptr); | 5403 | assert(value != nullptr); |
| 5404 | if (value->special == ConstValSpecialUndef) | ||
| 5405 | return false; | ||
| 5404 | switch (value->type->id) { | 5406 | switch (value->type->id) { |
| 5405 | case ZigTypeIdInvalid: | 5407 | case ZigTypeIdInvalid: |
| 5406 | zig_unreachable(); | 5408 | zig_unreachable(); |
| ... | @@ -6734,8 +6736,6 @@ static bool const_values_equal_array(CodeGen *g, ZigValue *a, ZigValue *b, size_ | ... | @@ -6734,8 +6736,6 @@ static bool const_values_equal_array(CodeGen *g, ZigValue *a, ZigValue *b, size_ |
| 6734 | 6736 | ||
| 6735 | bool const_values_equal(CodeGen *g, ZigValue *a, ZigValue *b) { | 6737 | bool const_values_equal(CodeGen *g, ZigValue *a, ZigValue *b) { |
| 6736 | if (a->type->id != b->type->id) return false; | 6738 | if (a->type->id != b->type->id) return false; |
| 6737 | assert(a->special == ConstValSpecialStatic); | ||
| 6738 | assert(b->special == ConstValSpecialStatic); | ||
| 6739 | if (a->type == b->type) { | 6739 | if (a->type == b->type) { |
| 6740 | switch (type_has_one_possible_value(g, a->type)) { | 6740 | switch (type_has_one_possible_value(g, a->type)) { |
| 6741 | case OnePossibleValueInvalid: | 6741 | case OnePossibleValueInvalid: |
| ... | @@ -6746,6 +6746,11 @@ bool const_values_equal(CodeGen *g, ZigValue *a, ZigValue *b) { | ... | @@ -6746,6 +6746,11 @@ bool const_values_equal(CodeGen *g, ZigValue *a, ZigValue *b) { |
| 6746 | return true; | 6746 | return true; |
| 6747 | } | 6747 | } |
| 6748 | } | 6748 | } |
| 6749 | if (a->special == ConstValSpecialUndef || b->special == ConstValSpecialUndef) { | ||
| 6750 | return a->special == b->special; | ||
| 6751 | } | ||
| 6752 | assert(a->special == ConstValSpecialStatic); | ||
| 6753 | assert(b->special == ConstValSpecialStatic); | ||
| 6749 | switch (a->type->id) { | 6754 | switch (a->type->id) { |
| 6750 | case ZigTypeIdOpaque: | 6755 | case ZigTypeIdOpaque: |
| 6751 | zig_unreachable(); | 6756 | zig_unreachable(); |
| ... | @@ -8729,7 +8734,6 @@ static void resolve_llvm_types_optional(CodeGen *g, ZigType *type, ResolveStatus | ... | @@ -8729,7 +8734,6 @@ static void resolve_llvm_types_optional(CodeGen *g, ZigType *type, ResolveStatus |
| 8729 | if (ResolveStatusLLVMFwdDecl >= wanted_resolve_status) return; | 8734 | if (ResolveStatusLLVMFwdDecl >= wanted_resolve_status) return; |
| 8730 | } | 8735 | } |
| 8731 | 8736 | ||
| 8732 | LLVMTypeRef child_llvm_type = get_llvm_type(g, child_type); | ||
| 8733 | ZigLLVMDIType *child_llvm_di_type = get_llvm_di_type(g, child_type); | 8737 | ZigLLVMDIType *child_llvm_di_type = get_llvm_di_type(g, child_type); |
| 8734 | if (type->data.maybe.resolve_status >= wanted_resolve_status) return; | 8738 | if (type->data.maybe.resolve_status >= wanted_resolve_status) return; |
| 8735 | 8739 | ||
| ... | @@ -8739,35 +8743,28 @@ static void resolve_llvm_types_optional(CodeGen *g, ZigType *type, ResolveStatus | ... | @@ -8739,35 +8743,28 @@ static void resolve_llvm_types_optional(CodeGen *g, ZigType *type, ResolveStatus |
| 8739 | }; | 8743 | }; |
| 8740 | LLVMStructSetBody(type->llvm_type, elem_types, 2, false); | 8744 | LLVMStructSetBody(type->llvm_type, elem_types, 2, false); |
| 8741 | 8745 | ||
| 8742 | uint64_t val_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, child_llvm_type); | 8746 | uint64_t val_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, type->llvm_type, maybe_child_index); |
| 8743 | uint64_t val_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, child_llvm_type); | 8747 | uint64_t maybe_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, type->llvm_type, maybe_null_index); |
| 8744 | uint64_t val_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, type->llvm_type, 0); | ||
| 8745 | 8748 | ||
| 8746 | uint64_t maybe_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, bool_llvm_type); | 8749 | ZigLLVMDIType *di_element_types[2]; |
| 8747 | uint64_t maybe_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, bool_llvm_type); | 8750 | di_element_types[maybe_child_index] = |
| 8748 | uint64_t maybe_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, type->llvm_type, 1); | ||
| 8749 | |||
| 8750 | uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, type->llvm_type); | ||
| 8751 | uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, type->llvm_type); | ||
| 8752 | |||
| 8753 | ZigLLVMDIType *di_element_types[] = { | ||
| 8754 | ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(type->llvm_di_type), | 8751 | ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(type->llvm_di_type), |
| 8755 | "val", di_file, line, | 8752 | "val", di_file, line, |
| 8756 | val_debug_size_in_bits, | 8753 | 8 * child_type->abi_size, |
| 8757 | val_debug_align_in_bits, | 8754 | 8 * child_type->abi_align, |
| 8758 | val_offset_in_bits, | 8755 | val_offset_in_bits, |
| 8759 | ZigLLVM_DIFlags_Zero, child_llvm_di_type), | 8756 | ZigLLVM_DIFlags_Zero, child_llvm_di_type); |
| 8757 | di_element_types[maybe_null_index] = | ||
| 8760 | ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(type->llvm_di_type), | 8758 | ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(type->llvm_di_type), |
| 8761 | "maybe", di_file, line, | 8759 | "maybe", di_file, line, |
| 8762 | maybe_debug_size_in_bits, | 8760 | 8*g->builtin_types.entry_bool->abi_size, |
| 8763 | maybe_debug_align_in_bits, | 8761 | 8*g->builtin_types.entry_bool->abi_align, |
| 8764 | maybe_offset_in_bits, | 8762 | maybe_offset_in_bits, |
| 8765 | ZigLLVM_DIFlags_Zero, bool_llvm_di_type), | 8763 | ZigLLVM_DIFlags_Zero, bool_llvm_di_type); |
| 8766 | }; | ||
| 8767 | ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder, | 8764 | ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder, |
| 8768 | compile_unit_scope, | 8765 | compile_unit_scope, |
| 8769 | buf_ptr(&type->name), | 8766 | buf_ptr(&type->name), |
| 8770 | di_file, line, debug_size_in_bits, debug_align_in_bits, ZigLLVM_DIFlags_Zero, | 8767 | di_file, line, 8 * type->abi_size, 8 * type->abi_align, ZigLLVM_DIFlags_Zero, |
| 8771 | nullptr, di_element_types, 2, 0, nullptr, ""); | 8768 | nullptr, di_element_types, 2, 0, nullptr, ""); |
| 8772 | 8769 | ||
| 8773 | ZigLLVMReplaceTemporary(g->dbuilder, type->llvm_di_type, replacement_di_type); | 8770 | ZigLLVMReplaceTemporary(g->dbuilder, type->llvm_di_type, replacement_di_type); |
src/codegen.cpp+23-89| ... | @@ -32,31 +32,6 @@ enum ResumeId { | ... | @@ -32,31 +32,6 @@ enum ResumeId { |
| 32 | ResumeIdCall, | 32 | ResumeIdCall, |
| 33 | }; | 33 | }; |
| 34 | 34 | ||
| 35 | static void init_darwin_native(CodeGen *g) { | ||
| 36 | char *osx_target = getenv("MACOSX_DEPLOYMENT_TARGET"); | ||
| 37 | char *ios_target = getenv("IPHONEOS_DEPLOYMENT_TARGET"); | ||
| 38 | |||
| 39 | // Allow conflicts among OSX and iOS, but choose the default platform. | ||
| 40 | if (osx_target && ios_target) { | ||
| 41 | if (g->zig_target->arch == ZigLLVM_arm || | ||
| 42 | g->zig_target->arch == ZigLLVM_aarch64 || | ||
| 43 | g->zig_target->arch == ZigLLVM_thumb) | ||
| 44 | { | ||
| 45 | osx_target = nullptr; | ||
| 46 | } else { | ||
| 47 | ios_target = nullptr; | ||
| 48 | } | ||
| 49 | } | ||
| 50 | |||
| 51 | if (osx_target) { | ||
| 52 | g->mmacosx_version_min = buf_create_from_str(osx_target); | ||
| 53 | } else if (ios_target) { | ||
| 54 | g->mios_version_min = buf_create_from_str(ios_target); | ||
| 55 | } else if (g->zig_target->os != OsIOS) { | ||
| 56 | g->mmacosx_version_min = buf_create_from_str("10.14"); | ||
| 57 | } | ||
| 58 | } | ||
| 59 | |||
| 60 | static ZigPackage *new_package(const char *root_src_dir, const char *root_src_path, const char *pkg_path) { | 35 | static ZigPackage *new_package(const char *root_src_dir, const char *root_src_path, const char *pkg_path) { |
| 61 | ZigPackage *entry = heap::c_allocator.create<ZigPackage>(); | 36 | ZigPackage *entry = heap::c_allocator.create<ZigPackage>(); |
| 62 | entry->package_table.init(4); | 37 | entry->package_table.init(4); |
| ... | @@ -160,14 +135,6 @@ void codegen_add_framework(CodeGen *g, const char *framework) { | ... | @@ -160,14 +135,6 @@ void codegen_add_framework(CodeGen *g, const char *framework) { |
| 160 | g->darwin_frameworks.append(buf_create_from_str(framework)); | 135 | g->darwin_frameworks.append(buf_create_from_str(framework)); |
| 161 | } | 136 | } |
| 162 | 137 | ||
| 163 | void codegen_set_mmacosx_version_min(CodeGen *g, Buf *mmacosx_version_min) { | ||
| 164 | g->mmacosx_version_min = mmacosx_version_min; | ||
| 165 | } | ||
| 166 | |||
| 167 | void codegen_set_mios_version_min(CodeGen *g, Buf *mios_version_min) { | ||
| 168 | g->mios_version_min = mios_version_min; | ||
| 169 | } | ||
| 170 | |||
| 171 | void codegen_set_rdynamic(CodeGen *g, bool rdynamic) { | 138 | void codegen_set_rdynamic(CodeGen *g, bool rdynamic) { |
| 172 | g->linker_rdynamic = rdynamic; | 139 | g->linker_rdynamic = rdynamic; |
| 173 | } | 140 | } |
| ... | @@ -4483,7 +4450,7 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutableGen *execu | ... | @@ -4483,7 +4450,7 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutableGen *execu |
| 4483 | 4450 | ||
| 4484 | if (!type_has_bits(field->type_entry)) { | 4451 | if (!type_has_bits(field->type_entry)) { |
| 4485 | ZigType *tag_type = union_type->data.unionation.tag_type; | 4452 | ZigType *tag_type = union_type->data.unionation.tag_type; |
| 4486 | if (!instruction->initializing || !type_has_bits(tag_type)) | 4453 | if (!instruction->initializing || tag_type == nullptr || !type_has_bits(tag_type)) |
| 4487 | return nullptr; | 4454 | return nullptr; |
| 4488 | 4455 | ||
| 4489 | // The field has no bits but we still have to change the discriminant | 4456 | // The field has no bits but we still have to change the discriminant |
| ... | @@ -8543,25 +8510,24 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { | ... | @@ -8543,25 +8510,24 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { |
| 8543 | buf_appendf(contents, "pub const link_mode = LinkMode.%s;\n", link_type); | 8510 | buf_appendf(contents, "pub const link_mode = LinkMode.%s;\n", link_type); |
| 8544 | buf_appendf(contents, "pub const is_test = %s;\n", bool_to_str(g->is_test_build)); | 8511 | buf_appendf(contents, "pub const is_test = %s;\n", bool_to_str(g->is_test_build)); |
| 8545 | buf_appendf(contents, "pub const single_threaded = %s;\n", bool_to_str(g->is_single_threaded)); | 8512 | buf_appendf(contents, "pub const single_threaded = %s;\n", bool_to_str(g->is_single_threaded)); |
| 8546 | buf_appendf(contents, "pub const os = Os.%s;\n", cur_os); | 8513 | buf_append_str(contents, "/// Deprecated: use `std.Target.cpu.arch`\n"); |
| 8547 | buf_appendf(contents, "pub const arch = Arch.%s;\n", cur_arch); | 8514 | buf_appendf(contents, "pub const arch = Arch.%s;\n", cur_arch); |
| 8548 | buf_appendf(contents, "pub const abi = Abi.%s;\n", cur_abi); | 8515 | buf_appendf(contents, "pub const abi = Abi.%s;\n", cur_abi); |
| 8549 | { | 8516 | { |
| 8550 | buf_append_str(contents, "pub const cpu: Cpu = "); | 8517 | buf_append_str(contents, "pub const cpu: Cpu = "); |
| 8551 | if (g->zig_target->builtin_str != nullptr) { | 8518 | if (g->zig_target->cpu_builtin_str != nullptr) { |
| 8552 | buf_append_str(contents, g->zig_target->builtin_str); | 8519 | buf_append_str(contents, g->zig_target->cpu_builtin_str); |
| 8553 | } else { | 8520 | } else { |
| 8554 | buf_append_str(contents, "Target.Cpu.baseline(arch);\n"); | 8521 | buf_appendf(contents, "Target.Cpu.baseline(.%s);\n", cur_arch); |
| 8555 | } | 8522 | } |
| 8556 | } | 8523 | } |
| 8557 | if (g->libc_link_lib != nullptr && g->zig_target->glibc_version != nullptr) { | 8524 | { |
| 8558 | buf_appendf(contents, | 8525 | buf_append_str(contents, "pub const os = "); |
| 8559 | "pub const glibc_version: ?Version = Version{.major = %d, .minor = %d, .patch = %d};\n", | 8526 | if (g->zig_target->os_builtin_str != nullptr) { |
| 8560 | g->zig_target->glibc_version->major, | 8527 | buf_append_str(contents, g->zig_target->os_builtin_str); |
| 8561 | g->zig_target->glibc_version->minor, | 8528 | } else { |
| 8562 | g->zig_target->glibc_version->patch); | 8529 | buf_appendf(contents, "Target.Os.defaultVersionRange(.%s);\n", cur_os); |
| 8563 | } else { | 8530 | } |
| 8564 | buf_appendf(contents, "pub const glibc_version: ?Version = null;\n"); | ||
| 8565 | } | 8531 | } |
| 8566 | buf_appendf(contents, "pub const object_format = ObjectFormat.%s;\n", cur_obj_fmt); | 8532 | buf_appendf(contents, "pub const object_format = ObjectFormat.%s;\n", cur_obj_fmt); |
| 8567 | buf_appendf(contents, "pub const mode = %s;\n", build_mode_to_str(g->build_mode)); | 8533 | buf_appendf(contents, "pub const mode = %s;\n", build_mode_to_str(g->build_mode)); |
| ... | @@ -8656,10 +8622,10 @@ static Error define_builtin_compile_vars(CodeGen *g) { | ... | @@ -8656,10 +8622,10 @@ static Error define_builtin_compile_vars(CodeGen *g) { |
| 8656 | if (g->zig_target->cache_hash != nullptr) { | 8622 | if (g->zig_target->cache_hash != nullptr) { |
| 8657 | cache_str(&cache_hash, g->zig_target->cache_hash); | 8623 | cache_str(&cache_hash, g->zig_target->cache_hash); |
| 8658 | } | 8624 | } |
| 8659 | if (g->zig_target->glibc_version != nullptr) { | 8625 | if (g->zig_target->glibc_or_darwin_version != nullptr) { |
| 8660 | cache_int(&cache_hash, g->zig_target->glibc_version->major); | 8626 | cache_int(&cache_hash, g->zig_target->glibc_or_darwin_version->major); |
| 8661 | cache_int(&cache_hash, g->zig_target->glibc_version->minor); | 8627 | cache_int(&cache_hash, g->zig_target->glibc_or_darwin_version->minor); |
| 8662 | cache_int(&cache_hash, g->zig_target->glibc_version->patch); | 8628 | cache_int(&cache_hash, g->zig_target->glibc_or_darwin_version->patch); |
| 8663 | } | 8629 | } |
| 8664 | cache_bool(&cache_hash, g->have_err_ret_tracing); | 8630 | cache_bool(&cache_hash, g->have_err_ret_tracing); |
| 8665 | cache_bool(&cache_hash, g->libc_link_lib != nullptr); | 8631 | cache_bool(&cache_hash, g->libc_link_lib != nullptr); |
| ... | @@ -8866,28 +8832,6 @@ static void init(CodeGen *g) { | ... | @@ -8866,28 +8832,6 @@ static void init(CodeGen *g) { |
| 8866 | } | 8832 | } |
| 8867 | } | 8833 | } |
| 8868 | 8834 | ||
| 8869 | static void detect_dynamic_linker(CodeGen *g) { | ||
| 8870 | Error err; | ||
| 8871 | |||
| 8872 | if (g->dynamic_linker_path != nullptr) | ||
| 8873 | return; | ||
| 8874 | if (!g->have_dynamic_link) | ||
| 8875 | return; | ||
| 8876 | if (g->out_type == OutTypeObj || (g->out_type == OutTypeLib && !g->is_dynamic)) | ||
| 8877 | return; | ||
| 8878 | |||
| 8879 | char *dynamic_linker_ptr; | ||
| 8880 | size_t dynamic_linker_len; | ||
| 8881 | if ((err = stage2_detect_dynamic_linker(g->zig_target, &dynamic_linker_ptr, &dynamic_linker_len))) { | ||
| 8882 | if (err == ErrorTargetHasNoDynamicLinker) return; | ||
| 8883 | fprintf(stderr, "Unable to detect dynamic linker: %s\n", err_str(err)); | ||
| 8884 | exit(1); | ||
| 8885 | } | ||
| 8886 | g->dynamic_linker_path = buf_create_from_mem(dynamic_linker_ptr, dynamic_linker_len); | ||
| 8887 | // Skips heap::c_allocator because the memory is allocated by stage2 library. | ||
| 8888 | free(dynamic_linker_ptr); | ||
| 8889 | } | ||
| 8890 | |||
| 8891 | static void detect_libc(CodeGen *g) { | 8835 | static void detect_libc(CodeGen *g) { |
| 8892 | Error err; | 8836 | Error err; |
| 8893 | 8837 | ||
| ... | @@ -10323,10 +10267,13 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { | ... | @@ -10323,10 +10267,13 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { |
| 10323 | if (g->zig_target->cache_hash != nullptr) { | 10267 | if (g->zig_target->cache_hash != nullptr) { |
| 10324 | cache_str(ch, g->zig_target->cache_hash); | 10268 | cache_str(ch, g->zig_target->cache_hash); |
| 10325 | } | 10269 | } |
| 10326 | if (g->zig_target->glibc_version != nullptr) { | 10270 | if (g->zig_target->glibc_or_darwin_version != nullptr) { |
| 10327 | cache_int(ch, g->zig_target->glibc_version->major); | 10271 | cache_int(ch, g->zig_target->glibc_or_darwin_version->major); |
| 10328 | cache_int(ch, g->zig_target->glibc_version->minor); | 10272 | cache_int(ch, g->zig_target->glibc_or_darwin_version->minor); |
| 10329 | cache_int(ch, g->zig_target->glibc_version->patch); | 10273 | cache_int(ch, g->zig_target->glibc_or_darwin_version->patch); |
| 10274 | } | ||
| 10275 | if (g->zig_target->dynamic_linker != nullptr) { | ||
| 10276 | cache_str(ch, g->zig_target->dynamic_linker); | ||
| 10330 | } | 10277 | } |
| 10331 | cache_int(ch, detect_subsystem(g)); | 10278 | cache_int(ch, detect_subsystem(g)); |
| 10332 | cache_bool(ch, g->strip_debug_symbols); | 10279 | cache_bool(ch, g->strip_debug_symbols); |
| ... | @@ -10354,8 +10301,6 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { | ... | @@ -10354,8 +10301,6 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { |
| 10354 | cache_bool(ch, g->emit_bin); | 10301 | cache_bool(ch, g->emit_bin); |
| 10355 | cache_bool(ch, g->emit_llvm_ir); | 10302 | cache_bool(ch, g->emit_llvm_ir); |
| 10356 | cache_bool(ch, g->emit_asm); | 10303 | cache_bool(ch, g->emit_asm); |
| 10357 | cache_buf_opt(ch, g->mmacosx_version_min); | ||
| 10358 | cache_buf_opt(ch, g->mios_version_min); | ||
| 10359 | cache_usize(ch, g->version_major); | 10304 | cache_usize(ch, g->version_major); |
| 10360 | cache_usize(ch, g->version_minor); | 10305 | cache_usize(ch, g->version_minor); |
| 10361 | cache_usize(ch, g->version_patch); | 10306 | cache_usize(ch, g->version_patch); |
| ... | @@ -10370,7 +10315,6 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { | ... | @@ -10370,7 +10315,6 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { |
| 10370 | cache_str(ch, g->libc->msvc_lib_dir); | 10315 | cache_str(ch, g->libc->msvc_lib_dir); |
| 10371 | cache_str(ch, g->libc->kernel32_lib_dir); | 10316 | cache_str(ch, g->libc->kernel32_lib_dir); |
| 10372 | } | 10317 | } |
| 10373 | cache_buf_opt(ch, g->dynamic_linker_path); | ||
| 10374 | cache_buf_opt(ch, g->version_script_path); | 10318 | cache_buf_opt(ch, g->version_script_path); |
| 10375 | 10319 | ||
| 10376 | // gen_c_objects appends objects to g->link_objects which we want to include in the hash | 10320 | // gen_c_objects appends objects to g->link_objects which we want to include in the hash |
| ... | @@ -10467,7 +10411,6 @@ void codegen_build_and_link(CodeGen *g) { | ... | @@ -10467,7 +10411,6 @@ void codegen_build_and_link(CodeGen *g) { |
| 10467 | g->have_err_ret_tracing = detect_err_ret_tracing(g); | 10411 | g->have_err_ret_tracing = detect_err_ret_tracing(g); |
| 10468 | g->have_sanitize_c = detect_sanitize_c(g); | 10412 | g->have_sanitize_c = detect_sanitize_c(g); |
| 10469 | detect_libc(g); | 10413 | detect_libc(g); |
| 10470 | detect_dynamic_linker(g); | ||
| 10471 | 10414 | ||
| 10472 | Buf digest = BUF_INIT; | 10415 | Buf digest = BUF_INIT; |
| 10473 | if (g->enable_cache) { | 10416 | if (g->enable_cache) { |
| ... | @@ -10664,7 +10607,6 @@ CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType o | ... | @@ -10664,7 +10607,6 @@ CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType o |
| 10664 | child_gen->verbose_cc = parent_gen->verbose_cc; | 10607 | child_gen->verbose_cc = parent_gen->verbose_cc; |
| 10665 | child_gen->verbose_llvm_cpu_features = parent_gen->verbose_llvm_cpu_features; | 10608 | child_gen->verbose_llvm_cpu_features = parent_gen->verbose_llvm_cpu_features; |
| 10666 | child_gen->llvm_argv = parent_gen->llvm_argv; | 10609 | child_gen->llvm_argv = parent_gen->llvm_argv; |
| 10667 | child_gen->dynamic_linker_path = parent_gen->dynamic_linker_path; | ||
| 10668 | 10610 | ||
| 10669 | codegen_set_strip(child_gen, parent_gen->strip_debug_symbols); | 10611 | codegen_set_strip(child_gen, parent_gen->strip_debug_symbols); |
| 10670 | child_gen->want_pic = parent_gen->have_pic ? WantPICEnabled : WantPICDisabled; | 10612 | child_gen->want_pic = parent_gen->have_pic ? WantPICEnabled : WantPICDisabled; |
| ... | @@ -10672,9 +10614,6 @@ CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType o | ... | @@ -10672,9 +10614,6 @@ CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType o |
| 10672 | 10614 | ||
| 10673 | codegen_set_errmsg_color(child_gen, parent_gen->err_color); | 10615 | codegen_set_errmsg_color(child_gen, parent_gen->err_color); |
| 10674 | 10616 | ||
| 10675 | codegen_set_mmacosx_version_min(child_gen, parent_gen->mmacosx_version_min); | ||
| 10676 | codegen_set_mios_version_min(child_gen, parent_gen->mios_version_min); | ||
| 10677 | |||
| 10678 | child_gen->enable_cache = true; | 10617 | child_gen->enable_cache = true; |
| 10679 | 10618 | ||
| 10680 | return child_gen; | 10619 | return child_gen; |
| ... | @@ -10782,11 +10721,6 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget | ... | @@ -10782,11 +10721,6 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget |
| 10782 | g->each_lib_rpath = false; | 10721 | g->each_lib_rpath = false; |
| 10783 | } else { | 10722 | } else { |
| 10784 | g->each_lib_rpath = true; | 10723 | g->each_lib_rpath = true; |
| 10785 | |||
| 10786 | if (target_os_is_darwin(g->zig_target->os)) { | ||
| 10787 | init_darwin_native(g); | ||
| 10788 | } | ||
| 10789 | |||
| 10790 | } | 10724 | } |
| 10791 | 10725 | ||
| 10792 | if (target_os_requires_libc(g->zig_target->os)) { | 10726 | if (target_os_requires_libc(g->zig_target->os)) { |
src/codegen.hpp-2| ... | @@ -35,8 +35,6 @@ LinkLib *codegen_add_link_lib(CodeGen *codegen, Buf *lib); | ... | @@ -35,8 +35,6 @@ LinkLib *codegen_add_link_lib(CodeGen *codegen, Buf *lib); |
| 35 | void codegen_add_framework(CodeGen *codegen, const char *name); | 35 | void codegen_add_framework(CodeGen *codegen, const char *name); |
| 36 | void codegen_add_rpath(CodeGen *codegen, const char *name); | 36 | void codegen_add_rpath(CodeGen *codegen, const char *name); |
| 37 | void codegen_set_rdynamic(CodeGen *g, bool rdynamic); | 37 | void codegen_set_rdynamic(CodeGen *g, bool rdynamic); |
| 38 | void codegen_set_mmacosx_version_min(CodeGen *g, Buf *mmacosx_version_min); | ||
| 39 | void codegen_set_mios_version_min(CodeGen *g, Buf *mios_version_min); | ||
| 40 | void codegen_set_linker_script(CodeGen *g, const char *linker_script); | 38 | void codegen_set_linker_script(CodeGen *g, const char *linker_script); |
| 41 | void codegen_set_test_filter(CodeGen *g, Buf *filter); | 39 | void codegen_set_test_filter(CodeGen *g, Buf *filter); |
| 42 | void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix); | 40 | void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix); |
src/compiler.cpp-25| ... | @@ -4,31 +4,6 @@ | ... | @@ -4,31 +4,6 @@ |
| 4 | 4 | ||
| 5 | #include <stdio.h> | 5 | #include <stdio.h> |
| 6 | 6 | ||
| 7 | Buf *get_self_libc_path(void) { | ||
| 8 | static Buf saved_libc_path = BUF_INIT; | ||
| 9 | static bool searched_for_libc = false; | ||
| 10 | |||
| 11 | for (;;) { | ||
| 12 | if (saved_libc_path.list.length != 0) { | ||
| 13 | return &saved_libc_path; | ||
| 14 | } | ||
| 15 | if (searched_for_libc) | ||
| 16 | return nullptr; | ||
| 17 | ZigList<Buf *> lib_paths = {}; | ||
| 18 | Error err; | ||
| 19 | if ((err = os_self_exe_shared_libs(lib_paths))) | ||
| 20 | return nullptr; | ||
| 21 | for (size_t i = 0; i < lib_paths.length; i += 1) { | ||
| 22 | Buf *lib_path = lib_paths.at(i); | ||
| 23 | if (buf_ends_with_str(lib_path, "libc.so.6")) { | ||
| 24 | buf_init_from_buf(&saved_libc_path, lib_path); | ||
| 25 | return &saved_libc_path; | ||
| 26 | } | ||
| 27 | } | ||
| 28 | searched_for_libc = true; | ||
| 29 | } | ||
| 30 | } | ||
| 31 | |||
| 32 | Error get_compiler_id(Buf **result) { | 7 | Error get_compiler_id(Buf **result) { |
| 33 | static Buf saved_compiler_id = BUF_INIT; | 8 | static Buf saved_compiler_id = BUF_INIT; |
| 34 | 9 |
src/compiler.hpp-1| ... | @@ -12,7 +12,6 @@ | ... | @@ -12,7 +12,6 @@ |
| 12 | #include "error.hpp" | 12 | #include "error.hpp" |
| 13 | 13 | ||
| 14 | Error get_compiler_id(Buf **result); | 14 | Error get_compiler_id(Buf **result); |
| 15 | Buf *get_self_libc_path(void); | ||
| 16 | 15 | ||
| 17 | Buf *get_zig_lib_dir(void); | 16 | Buf *get_zig_lib_dir(void); |
| 18 | Buf *get_zig_special_dir(Buf *zig_lib_dir); | 17 | Buf *get_zig_special_dir(Buf *zig_lib_dir); |
src/error.cpp+2| ... | @@ -81,6 +81,8 @@ const char *err_str(Error err) { | ... | @@ -81,6 +81,8 @@ const char *err_str(Error err) { |
| 81 | case ErrorWindowsSdkNotFound: return "Windows SDK not found"; | 81 | case ErrorWindowsSdkNotFound: return "Windows SDK not found"; |
| 82 | case ErrorUnknownDynamicLinkerPath: return "unknown dynamic linker path"; | 82 | case ErrorUnknownDynamicLinkerPath: return "unknown dynamic linker path"; |
| 83 | case ErrorTargetHasNoDynamicLinker: return "target has no dynamic linker"; | 83 | case ErrorTargetHasNoDynamicLinker: return "target has no dynamic linker"; |
| 84 | case ErrorInvalidAbiVersion: return "invalid C ABI version"; | ||
| 85 | case ErrorInvalidOperatingSystemVersion: return "invalid operating system version"; | ||
| 84 | } | 86 | } |
| 85 | return "(invalid error)"; | 87 | return "(invalid error)"; |
| 86 | } | 88 | } |
src/glibc.cpp+13-50| ... | @@ -55,7 +55,7 @@ Error glibc_load_metadata(ZigGLibCAbi **out_result, Buf *zig_lib_dir, bool verbo | ... | @@ -55,7 +55,7 @@ Error glibc_load_metadata(ZigGLibCAbi **out_result, Buf *zig_lib_dir, bool verbo |
| 55 | Optional<Slice<uint8_t>> opt_component = SplitIterator_next(&it); | 55 | Optional<Slice<uint8_t>> opt_component = SplitIterator_next(&it); |
| 56 | if (!opt_component.is_some) break; | 56 | if (!opt_component.is_some) break; |
| 57 | Buf *ver_buf = buf_create_from_slice(opt_component.value); | 57 | Buf *ver_buf = buf_create_from_slice(opt_component.value); |
| 58 | ZigGLibCVersion *this_ver = glibc_abi->all_versions.add_one(); | 58 | Stage2SemVer *this_ver = glibc_abi->all_versions.add_one(); |
| 59 | if ((err = target_parse_glibc_version(this_ver, buf_ptr(ver_buf)))) { | 59 | if ((err = target_parse_glibc_version(this_ver, buf_ptr(ver_buf)))) { |
| 60 | if (verbose) { | 60 | if (verbose) { |
| 61 | fprintf(stderr, "Unable to parse glibc version '%s': %s\n", buf_ptr(ver_buf), err_str(err)); | 61 | fprintf(stderr, "Unable to parse glibc version '%s': %s\n", buf_ptr(ver_buf), err_str(err)); |
| ... | @@ -186,9 +186,9 @@ Error glibc_build_dummies_and_maps(CodeGen *g, const ZigGLibCAbi *glibc_abi, con | ... | @@ -186,9 +186,9 @@ Error glibc_build_dummies_and_maps(CodeGen *g, const ZigGLibCAbi *glibc_abi, con |
| 186 | cache_buf(cache_hash, compiler_id); | 186 | cache_buf(cache_hash, compiler_id); |
| 187 | cache_int(cache_hash, target->arch); | 187 | cache_int(cache_hash, target->arch); |
| 188 | cache_int(cache_hash, target->abi); | 188 | cache_int(cache_hash, target->abi); |
| 189 | cache_int(cache_hash, target->glibc_version->major); | 189 | cache_int(cache_hash, target->glibc_or_darwin_version->major); |
| 190 | cache_int(cache_hash, target->glibc_version->minor); | 190 | cache_int(cache_hash, target->glibc_or_darwin_version->minor); |
| 191 | cache_int(cache_hash, target->glibc_version->patch); | 191 | cache_int(cache_hash, target->glibc_or_darwin_version->patch); |
| 192 | 192 | ||
| 193 | Buf digest = BUF_INIT; | 193 | Buf digest = BUF_INIT; |
| 194 | buf_resize(&digest, 0); | 194 | buf_resize(&digest, 0); |
| ... | @@ -224,10 +224,10 @@ Error glibc_build_dummies_and_maps(CodeGen *g, const ZigGLibCAbi *glibc_abi, con | ... | @@ -224,10 +224,10 @@ Error glibc_build_dummies_and_maps(CodeGen *g, const ZigGLibCAbi *glibc_abi, con |
| 224 | 224 | ||
| 225 | uint8_t target_ver_index = 0; | 225 | uint8_t target_ver_index = 0; |
| 226 | for (;target_ver_index < glibc_abi->all_versions.length; target_ver_index += 1) { | 226 | for (;target_ver_index < glibc_abi->all_versions.length; target_ver_index += 1) { |
| 227 | const ZigGLibCVersion *this_ver = &glibc_abi->all_versions.at(target_ver_index); | 227 | const Stage2SemVer *this_ver = &glibc_abi->all_versions.at(target_ver_index); |
| 228 | if (this_ver->major == target->glibc_version->major && | 228 | if (this_ver->major == target->glibc_or_darwin_version->major && |
| 229 | this_ver->minor == target->glibc_version->minor && | 229 | this_ver->minor == target->glibc_or_darwin_version->minor && |
| 230 | this_ver->patch == target->glibc_version->patch) | 230 | this_ver->patch == target->glibc_or_darwin_version->patch) |
| 231 | { | 231 | { |
| 232 | break; | 232 | break; |
| 233 | } | 233 | } |
| ... | @@ -235,9 +235,9 @@ Error glibc_build_dummies_and_maps(CodeGen *g, const ZigGLibCAbi *glibc_abi, con | ... | @@ -235,9 +235,9 @@ Error glibc_build_dummies_and_maps(CodeGen *g, const ZigGLibCAbi *glibc_abi, con |
| 235 | if (target_ver_index == glibc_abi->all_versions.length) { | 235 | if (target_ver_index == glibc_abi->all_versions.length) { |
| 236 | if (verbose) { | 236 | if (verbose) { |
| 237 | fprintf(stderr, "Unrecognized glibc version: %d.%d.%d\n", | 237 | fprintf(stderr, "Unrecognized glibc version: %d.%d.%d\n", |
| 238 | target->glibc_version->major, | 238 | target->glibc_or_darwin_version->major, |
| 239 | target->glibc_version->minor, | 239 | target->glibc_or_darwin_version->minor, |
| 240 | target->glibc_version->patch); | 240 | target->glibc_or_darwin_version->patch); |
| 241 | } | 241 | } |
| 242 | return ErrorUnknownABI; | 242 | return ErrorUnknownABI; |
| 243 | } | 243 | } |
| ... | @@ -246,7 +246,7 @@ Error glibc_build_dummies_and_maps(CodeGen *g, const ZigGLibCAbi *glibc_abi, con | ... | @@ -246,7 +246,7 @@ Error glibc_build_dummies_and_maps(CodeGen *g, const ZigGLibCAbi *glibc_abi, con |
| 246 | Buf *map_contents = buf_alloc(); | 246 | Buf *map_contents = buf_alloc(); |
| 247 | 247 | ||
| 248 | for (uint8_t ver_i = 0; ver_i < glibc_abi->all_versions.length; ver_i += 1) { | 248 | for (uint8_t ver_i = 0; ver_i < glibc_abi->all_versions.length; ver_i += 1) { |
| 249 | const ZigGLibCVersion *ver = &glibc_abi->all_versions.at(ver_i); | 249 | const Stage2SemVer *ver = &glibc_abi->all_versions.at(ver_i); |
| 250 | if (ver->patch == 0) { | 250 | if (ver->patch == 0) { |
| 251 | buf_appendf(map_contents, "GLIBC_%d.%d { };\n", ver->major, ver->minor); | 251 | buf_appendf(map_contents, "GLIBC_%d.%d { };\n", ver->major, ver->minor); |
| 252 | } else { | 252 | } else { |
| ... | @@ -294,7 +294,7 @@ Error glibc_build_dummies_and_maps(CodeGen *g, const ZigGLibCAbi *glibc_abi, con | ... | @@ -294,7 +294,7 @@ Error glibc_build_dummies_and_maps(CodeGen *g, const ZigGLibCAbi *glibc_abi, con |
| 294 | uint8_t ver_index = ver_list->versions[ver_i]; | 294 | uint8_t ver_index = ver_list->versions[ver_i]; |
| 295 | 295 | ||
| 296 | Buf *stub_name; | 296 | Buf *stub_name; |
| 297 | const ZigGLibCVersion *ver = &glibc_abi->all_versions.at(ver_index); | 297 | const Stage2SemVer *ver = &glibc_abi->all_versions.at(ver_index); |
| 298 | const char *sym_name = buf_ptr(libc_fn->name); | 298 | const char *sym_name = buf_ptr(libc_fn->name); |
| 299 | if (ver->patch == 0) { | 299 | if (ver->patch == 0) { |
| 300 | stub_name = buf_sprintf("%s_%d_%d", sym_name, ver->major, ver->minor); | 300 | stub_name = buf_sprintf("%s_%d_%d", sym_name, ver->major, ver->minor); |
| ... | @@ -362,43 +362,6 @@ bool eql_glibc_target(const ZigTarget *a, const ZigTarget *b) { | ... | @@ -362,43 +362,6 @@ bool eql_glibc_target(const ZigTarget *a, const ZigTarget *b) { |
| 362 | a->abi == b->abi; | 362 | a->abi == b->abi; |
| 363 | } | 363 | } |
| 364 | 364 | ||
| 365 | #ifdef ZIG_OS_LINUX | ||
| 366 | #include <unistd.h> | ||
| 367 | Error glibc_detect_native_version(ZigGLibCVersion *glibc_ver) { | ||
| 368 | Buf *self_libc_path = get_self_libc_path(); | ||
| 369 | if (self_libc_path == nullptr) { | ||
| 370 | // TODO There is still more we could do to detect the native glibc version. For example, | ||
| 371 | // we could look at the ELF file of `/usr/bin/env`, find `libc.so.6`, and then `readlink` | ||
| 372 | // to find out the glibc version. This is relevant for the static zig builds distributed | ||
| 373 | // on the download page, since the above detection based on zig's own dynamic linking | ||
| 374 | // will not work. | ||
| 375 | |||
| 376 | return ErrorUnknownABI; | ||
| 377 | } | ||
| 378 | Buf *link_name = buf_alloc(); | ||
| 379 | buf_resize(link_name, 4096); | ||
| 380 | ssize_t amt = readlink(buf_ptr(self_libc_path), buf_ptr(link_name), buf_len(link_name)); | ||
| 381 | if (amt == -1) { | ||
| 382 | return ErrorUnknownABI; | ||
| 383 | } | ||
| 384 | buf_resize(link_name, amt); | ||
| 385 | if (!buf_starts_with_str(link_name, "libc-") || !buf_ends_with_str(link_name, ".so")) { | ||
| 386 | return ErrorUnknownABI; | ||
| 387 | } | ||
| 388 | // example: "libc-2.3.4.so" | ||
| 389 | // example: "libc-2.27.so" | ||
| 390 | buf_resize(link_name, buf_len(link_name) - 3); // chop off ".so" | ||
| 391 | glibc_ver->major = 2; | ||
| 392 | glibc_ver->minor = 0; | ||
| 393 | glibc_ver->patch = 0; | ||
| 394 | return target_parse_glibc_version(glibc_ver, buf_ptr(link_name) + 5); | ||
| 395 | } | ||
| 396 | #else | ||
| 397 | Error glibc_detect_native_version(ZigGLibCVersion *glibc_ver) { | ||
| 398 | return ErrorUnknownABI; | ||
| 399 | } | ||
| 400 | #endif | ||
| 401 | |||
| 402 | size_t glibc_lib_count(void) { | 365 | size_t glibc_lib_count(void) { |
| 403 | return array_length(glibc_libs); | 366 | return array_length(glibc_libs); |
| 404 | } | 367 | } |
src/glibc.hpp+1-4| ... | @@ -32,7 +32,7 @@ struct ZigGLibCAbi { | ... | @@ -32,7 +32,7 @@ struct ZigGLibCAbi { |
| 32 | Buf *abi_txt_path; | 32 | Buf *abi_txt_path; |
| 33 | Buf *vers_txt_path; | 33 | Buf *vers_txt_path; |
| 34 | Buf *fns_txt_path; | 34 | Buf *fns_txt_path; |
| 35 | ZigList<ZigGLibCVersion> all_versions; | 35 | ZigList<Stage2SemVer> all_versions; |
| 36 | ZigList<ZigGLibCFn> all_functions; | 36 | ZigList<ZigGLibCFn> all_functions; |
| 37 | // The value is a pointer to all_functions.length items and each item is an index | 37 | // The value is a pointer to all_functions.length items and each item is an index |
| 38 | // into all_functions. | 38 | // into all_functions. |
| ... | @@ -43,9 +43,6 @@ Error glibc_load_metadata(ZigGLibCAbi **out_result, Buf *zig_lib_dir, bool verbo | ... | @@ -43,9 +43,6 @@ Error glibc_load_metadata(ZigGLibCAbi **out_result, Buf *zig_lib_dir, bool verbo |
| 43 | Error glibc_build_dummies_and_maps(CodeGen *codegen, const ZigGLibCAbi *glibc_abi, const ZigTarget *target, | 43 | Error glibc_build_dummies_and_maps(CodeGen *codegen, const ZigGLibCAbi *glibc_abi, const ZigTarget *target, |
| 44 | Buf **out_dir, bool verbose, Stage2ProgressNode *progress_node); | 44 | Buf **out_dir, bool verbose, Stage2ProgressNode *progress_node); |
| 45 | 45 | ||
| 46 | // returns ErrorUnknownABI when glibc is not the native libc | ||
| 47 | Error glibc_detect_native_version(ZigGLibCVersion *glibc_ver); | ||
| 48 | |||
| 49 | size_t glibc_lib_count(void); | 46 | size_t glibc_lib_count(void); |
| 50 | const ZigGLibCLib *glibc_lib_enum(size_t index); | 47 | const ZigGLibCLib *glibc_lib_enum(size_t index); |
| 51 | const ZigGLibCLib *glibc_lib_find(const char *name); | 48 | const ZigGLibCLib *glibc_lib_find(const char *name); |
src/link.cpp+19-112| ... | @@ -1751,9 +1751,9 @@ static void construct_linker_job_elf(LinkJob *lj) { | ... | @@ -1751,9 +1751,9 @@ static void construct_linker_job_elf(LinkJob *lj) { |
| 1751 | } | 1751 | } |
| 1752 | 1752 | ||
| 1753 | if (g->have_dynamic_link && (is_dyn_lib || g->out_type == OutTypeExe)) { | 1753 | if (g->have_dynamic_link && (is_dyn_lib || g->out_type == OutTypeExe)) { |
| 1754 | assert(g->dynamic_linker_path != nullptr); | 1754 | assert(g->zig_target->dynamic_linker != nullptr); |
| 1755 | lj->args.append("-dynamic-linker"); | 1755 | lj->args.append("-dynamic-linker"); |
| 1756 | lj->args.append(buf_ptr(g->dynamic_linker_path)); | 1756 | lj->args.append(g->zig_target->dynamic_linker); |
| 1757 | } | 1757 | } |
| 1758 | } | 1758 | } |
| 1759 | 1759 | ||
| ... | @@ -2371,99 +2371,6 @@ static void construct_linker_job_coff(LinkJob *lj) { | ... | @@ -2371,99 +2371,6 @@ static void construct_linker_job_coff(LinkJob *lj) { |
| 2371 | } | 2371 | } |
| 2372 | } | 2372 | } |
| 2373 | 2373 | ||
| 2374 | |||
| 2375 | // Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?))?)? and return the | ||
| 2376 | // grouped values as integers. Numbers which are not provided are set to 0. | ||
| 2377 | // return true if the entire string was parsed (9.2), or all groups were | ||
| 2378 | // parsed (10.3.5extrastuff). | ||
| 2379 | static bool darwin_get_release_version(const char *str, int *major, int *minor, int *micro, bool *had_extra) { | ||
| 2380 | *had_extra = false; | ||
| 2381 | |||
| 2382 | *major = 0; | ||
| 2383 | *minor = 0; | ||
| 2384 | *micro = 0; | ||
| 2385 | |||
| 2386 | if (*str == '\0') | ||
| 2387 | return false; | ||
| 2388 | |||
| 2389 | char *end; | ||
| 2390 | *major = (int)strtol(str, &end, 10); | ||
| 2391 | if (*str != '\0' && *end == '\0') | ||
| 2392 | return true; | ||
| 2393 | if (*end != '.') | ||
| 2394 | return false; | ||
| 2395 | |||
| 2396 | str = end + 1; | ||
| 2397 | *minor = (int)strtol(str, &end, 10); | ||
| 2398 | if (*str != '\0' && *end == '\0') | ||
| 2399 | return true; | ||
| 2400 | if (*end != '.') | ||
| 2401 | return false; | ||
| 2402 | |||
| 2403 | str = end + 1; | ||
| 2404 | *micro = (int)strtol(str, &end, 10); | ||
| 2405 | if (*str != '\0' && *end == '\0') | ||
| 2406 | return true; | ||
| 2407 | if (str == end) | ||
| 2408 | return false; | ||
| 2409 | *had_extra = true; | ||
| 2410 | return true; | ||
| 2411 | } | ||
| 2412 | |||
| 2413 | enum DarwinPlatformKind { | ||
| 2414 | MacOS, | ||
| 2415 | IPhoneOS, | ||
| 2416 | IPhoneOSSimulator, | ||
| 2417 | }; | ||
| 2418 | |||
| 2419 | struct DarwinPlatform { | ||
| 2420 | DarwinPlatformKind kind; | ||
| 2421 | int major; | ||
| 2422 | int minor; | ||
| 2423 | int micro; | ||
| 2424 | }; | ||
| 2425 | |||
| 2426 | static void get_darwin_platform(LinkJob *lj, DarwinPlatform *platform) { | ||
| 2427 | CodeGen *g = lj->codegen; | ||
| 2428 | |||
| 2429 | if (g->mmacosx_version_min) { | ||
| 2430 | platform->kind = MacOS; | ||
| 2431 | } else if (g->mios_version_min) { | ||
| 2432 | platform->kind = IPhoneOS; | ||
| 2433 | } else if (g->zig_target->os == OsMacOSX) { | ||
| 2434 | platform->kind = MacOS; | ||
| 2435 | g->mmacosx_version_min = buf_create_from_str("10.14"); | ||
| 2436 | } else { | ||
| 2437 | zig_panic("unable to infer -mmacosx-version-min or -mios-version-min"); | ||
| 2438 | } | ||
| 2439 | |||
| 2440 | bool had_extra; | ||
| 2441 | if (platform->kind == MacOS) { | ||
| 2442 | if (!darwin_get_release_version(buf_ptr(g->mmacosx_version_min), | ||
| 2443 | &platform->major, &platform->minor, &platform->micro, &had_extra) || | ||
| 2444 | had_extra || platform->major != 10 || platform->minor >= 100 || platform->micro >= 100) | ||
| 2445 | { | ||
| 2446 | zig_panic("invalid -mmacosx-version-min"); | ||
| 2447 | } | ||
| 2448 | } else if (platform->kind == IPhoneOS) { | ||
| 2449 | if (!darwin_get_release_version(buf_ptr(g->mios_version_min), | ||
| 2450 | &platform->major, &platform->minor, &platform->micro, &had_extra) || | ||
| 2451 | had_extra || platform->major >= 10 || platform->minor >= 100 || platform->micro >= 100) | ||
| 2452 | { | ||
| 2453 | zig_panic("invalid -mios-version-min"); | ||
| 2454 | } | ||
| 2455 | } else { | ||
| 2456 | zig_unreachable(); | ||
| 2457 | } | ||
| 2458 | |||
| 2459 | if (platform->kind == IPhoneOS && | ||
| 2460 | (g->zig_target->arch == ZigLLVM_x86 || | ||
| 2461 | g->zig_target->arch == ZigLLVM_x86_64)) | ||
| 2462 | { | ||
| 2463 | platform->kind = IPhoneOSSimulator; | ||
| 2464 | } | ||
| 2465 | } | ||
| 2466 | |||
| 2467 | static void construct_linker_job_macho(LinkJob *lj) { | 2374 | static void construct_linker_job_macho(LinkJob *lj) { |
| 2468 | CodeGen *g = lj->codegen; | 2375 | CodeGen *g = lj->codegen; |
| 2469 | 2376 | ||
| ... | @@ -2507,25 +2414,25 @@ static void construct_linker_job_macho(LinkJob *lj) { | ... | @@ -2507,25 +2414,25 @@ static void construct_linker_job_macho(LinkJob *lj) { |
| 2507 | lj->args.append("-arch"); | 2414 | lj->args.append("-arch"); |
| 2508 | lj->args.append(get_darwin_arch_string(g->zig_target)); | 2415 | lj->args.append(get_darwin_arch_string(g->zig_target)); |
| 2509 | 2416 | ||
| 2510 | DarwinPlatform platform; | 2417 | if (g->zig_target->glibc_or_darwin_version != nullptr) { |
| 2511 | get_darwin_platform(lj, &platform); | 2418 | if (g->zig_target->os == OsMacOSX) { |
| 2512 | switch (platform.kind) { | ||
| 2513 | case MacOS: | ||
| 2514 | lj->args.append("-macosx_version_min"); | 2419 | lj->args.append("-macosx_version_min"); |
| 2515 | break; | 2420 | } else if (g->zig_target->os == OsIOS) { |
| 2516 | case IPhoneOS: | 2421 | if (g->zig_target->arch == ZigLLVM_x86 || g->zig_target->arch == ZigLLVM_x86_64) { |
| 2517 | lj->args.append("-iphoneos_version_min"); | 2422 | lj->args.append("-ios_simulator_version_min"); |
| 2518 | break; | 2423 | } else { |
| 2519 | case IPhoneOSSimulator: | 2424 | lj->args.append("-iphoneos_version_min"); |
| 2520 | lj->args.append("-ios_simulator_version_min"); | 2425 | } |
| 2521 | break; | 2426 | } |
| 2522 | } | 2427 | Buf *version_string = buf_sprintf("%d.%d.%d", |
| 2523 | Buf *version_string = buf_sprintf("%d.%d.%d", platform.major, platform.minor, platform.micro); | 2428 | g->zig_target->glibc_or_darwin_version->major, |
| 2524 | lj->args.append(buf_ptr(version_string)); | 2429 | g->zig_target->glibc_or_darwin_version->minor, |
| 2525 | 2430 | g->zig_target->glibc_or_darwin_version->patch); | |
| 2526 | lj->args.append("-sdk_version"); | 2431 | lj->args.append(buf_ptr(version_string)); |
| 2527 | lj->args.append(buf_ptr(version_string)); | ||
| 2528 | 2432 | ||
| 2433 | lj->args.append("-sdk_version"); | ||
| 2434 | lj->args.append(buf_ptr(version_string)); | ||
| 2435 | } | ||
| 2529 | 2436 | ||
| 2530 | if (g->out_type == OutTypeExe) { | 2437 | if (g->out_type == OutTypeExe) { |
| 2531 | lj->args.append("-pie"); | 2438 | lj->args.append("-pie"); |
src/main.cpp+12-54| ... | @@ -89,8 +89,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { | ... | @@ -89,8 +89,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { |
| 89 | " --single-threaded source may assume it is only used single-threaded\n" | 89 | " --single-threaded source may assume it is only used single-threaded\n" |
| 90 | " -dynamic create a shared library (.so; .dll; .dylib)\n" | 90 | " -dynamic create a shared library (.so; .dll; .dylib)\n" |
| 91 | " --strip exclude debug symbols\n" | 91 | " --strip exclude debug symbols\n" |
| 92 | " -target [name] <arch><sub>-<os>-<abi> see the targets command\n" | 92 | " -target [name] <arch>-<os>-<abi> see the targets command\n" |
| 93 | " -target-glibc [version] target a specific glibc version (default: 2.17)\n" | ||
| 94 | " --verbose-tokenize enable compiler debug output for tokenization\n" | 93 | " --verbose-tokenize enable compiler debug output for tokenization\n" |
| 95 | " --verbose-ast enable compiler debug output for AST parsing\n" | 94 | " --verbose-ast enable compiler debug output for AST parsing\n" |
| 96 | " --verbose-link enable compiler debug output for linking\n" | 95 | " --verbose-link enable compiler debug output for linking\n" |
| ... | @@ -128,8 +127,6 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { | ... | @@ -128,8 +127,6 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { |
| 128 | " --subsystem [subsystem] (windows) /SUBSYSTEM:<subsystem> to the linker\n" | 127 | " --subsystem [subsystem] (windows) /SUBSYSTEM:<subsystem> to the linker\n" |
| 129 | " -F[dir] (darwin) add search path for frameworks\n" | 128 | " -F[dir] (darwin) add search path for frameworks\n" |
| 130 | " -framework [name] (darwin) link against framework\n" | 129 | " -framework [name] (darwin) link against framework\n" |
| 131 | " -mios-version-min [ver] (darwin) set iOS deployment target\n" | ||
| 132 | " -mmacosx-version-min [ver] (darwin) set Mac OS X deployment target\n" | ||
| 133 | " --ver-major [ver] dynamic library semver major version\n" | 130 | " --ver-major [ver] dynamic library semver major version\n" |
| 134 | " --ver-minor [ver] dynamic library semver minor version\n" | 131 | " --ver-minor [ver] dynamic library semver minor version\n" |
| 135 | " --ver-patch [ver] dynamic library semver patch version\n" | 132 | " --ver-patch [ver] dynamic library semver patch version\n" |
| ... | @@ -404,7 +401,7 @@ static int main0(int argc, char **argv) { | ... | @@ -404,7 +401,7 @@ static int main0(int argc, char **argv) { |
| 404 | bool link_eh_frame_hdr = false; | 401 | bool link_eh_frame_hdr = false; |
| 405 | ErrColor color = ErrColorAuto; | 402 | ErrColor color = ErrColorAuto; |
| 406 | CacheOpt enable_cache = CacheOptAuto; | 403 | CacheOpt enable_cache = CacheOptAuto; |
| 407 | Buf *dynamic_linker = nullptr; | 404 | const char *dynamic_linker = nullptr; |
| 408 | const char *libc_txt = nullptr; | 405 | const char *libc_txt = nullptr; |
| 409 | ZigList<const char *> clang_argv = {0}; | 406 | ZigList<const char *> clang_argv = {0}; |
| 410 | ZigList<const char *> lib_dirs = {0}; | 407 | ZigList<const char *> lib_dirs = {0}; |
| ... | @@ -415,11 +412,8 @@ static int main0(int argc, char **argv) { | ... | @@ -415,11 +412,8 @@ static int main0(int argc, char **argv) { |
| 415 | bool have_libc = false; | 412 | bool have_libc = false; |
| 416 | const char *target_string = nullptr; | 413 | const char *target_string = nullptr; |
| 417 | bool rdynamic = false; | 414 | bool rdynamic = false; |
| 418 | const char *mmacosx_version_min = nullptr; | ||
| 419 | const char *mios_version_min = nullptr; | ||
| 420 | const char *linker_script = nullptr; | 415 | const char *linker_script = nullptr; |
| 421 | Buf *version_script = nullptr; | 416 | Buf *version_script = nullptr; |
| 422 | const char *target_glibc = nullptr; | ||
| 423 | ZigList<const char *> rpath_list = {0}; | 417 | ZigList<const char *> rpath_list = {0}; |
| 424 | bool each_lib_rpath = false; | 418 | bool each_lib_rpath = false; |
| 425 | ZigList<const char *> objects = {0}; | 419 | ZigList<const char *> objects = {0}; |
| ... | @@ -502,7 +496,10 @@ static int main0(int argc, char **argv) { | ... | @@ -502,7 +496,10 @@ static int main0(int argc, char **argv) { |
| 502 | os_path_join(get_zig_special_dir(zig_lib_dir), buf_create_from_str("build_runner.zig"), build_runner_path); | 496 | os_path_join(get_zig_special_dir(zig_lib_dir), buf_create_from_str("build_runner.zig"), build_runner_path); |
| 503 | 497 | ||
| 504 | ZigTarget target; | 498 | ZigTarget target; |
| 505 | get_native_target(&target); | 499 | if ((err = target_parse_triple(&target, "native", nullptr, nullptr))) { |
| 500 | fprintf(stderr, "Unable to get native target: %s\n", err_str(err)); | ||
| 501 | return EXIT_FAILURE; | ||
| 502 | } | ||
| 506 | 503 | ||
| 507 | Buf *build_file_buf = buf_create_from_str((build_file != nullptr) ? build_file : "build.zig"); | 504 | Buf *build_file_buf = buf_create_from_str((build_file != nullptr) ? build_file : "build.zig"); |
| 508 | Buf build_file_abs = os_path_resolve(&build_file_buf, 1); | 505 | Buf build_file_abs = os_path_resolve(&build_file_buf, 1); |
| ... | @@ -769,7 +766,7 @@ static int main0(int argc, char **argv) { | ... | @@ -769,7 +766,7 @@ static int main0(int argc, char **argv) { |
| 769 | } else if (strcmp(arg, "--name") == 0) { | 766 | } else if (strcmp(arg, "--name") == 0) { |
| 770 | out_name = argv[i]; | 767 | out_name = argv[i]; |
| 771 | } else if (strcmp(arg, "--dynamic-linker") == 0) { | 768 | } else if (strcmp(arg, "--dynamic-linker") == 0) { |
| 772 | dynamic_linker = buf_create_from_str(argv[i]); | 769 | dynamic_linker = argv[i]; |
| 773 | } else if (strcmp(arg, "--libc") == 0) { | 770 | } else if (strcmp(arg, "--libc") == 0) { |
| 774 | libc_txt = argv[i]; | 771 | libc_txt = argv[i]; |
| 775 | } else if (strcmp(arg, "-D") == 0) { | 772 | } else if (strcmp(arg, "-D") == 0) { |
| ... | @@ -843,18 +840,12 @@ static int main0(int argc, char **argv) { | ... | @@ -843,18 +840,12 @@ static int main0(int argc, char **argv) { |
| 843 | cache_dir = argv[i]; | 840 | cache_dir = argv[i]; |
| 844 | } else if (strcmp(arg, "-target") == 0) { | 841 | } else if (strcmp(arg, "-target") == 0) { |
| 845 | target_string = argv[i]; | 842 | target_string = argv[i]; |
| 846 | } else if (strcmp(arg, "-mmacosx-version-min") == 0) { | ||
| 847 | mmacosx_version_min = argv[i]; | ||
| 848 | } else if (strcmp(arg, "-mios-version-min") == 0) { | ||
| 849 | mios_version_min = argv[i]; | ||
| 850 | } else if (strcmp(arg, "-framework") == 0) { | 843 | } else if (strcmp(arg, "-framework") == 0) { |
| 851 | frameworks.append(argv[i]); | 844 | frameworks.append(argv[i]); |
| 852 | } else if (strcmp(arg, "--linker-script") == 0) { | 845 | } else if (strcmp(arg, "--linker-script") == 0) { |
| 853 | linker_script = argv[i]; | 846 | linker_script = argv[i]; |
| 854 | } else if (strcmp(arg, "--version-script") == 0) { | 847 | } else if (strcmp(arg, "--version-script") == 0) { |
| 855 | version_script = buf_create_from_str(argv[i]); | 848 | version_script = buf_create_from_str(argv[i]); |
| 856 | } else if (strcmp(arg, "-target-glibc") == 0) { | ||
| 857 | target_glibc = argv[i]; | ||
| 858 | } else if (strcmp(arg, "-rpath") == 0) { | 849 | } else if (strcmp(arg, "-rpath") == 0) { |
| 859 | rpath_list.append(argv[i]); | 850 | rpath_list.append(argv[i]); |
| 860 | } else if (strcmp(arg, "--test-filter") == 0) { | 851 | } else if (strcmp(arg, "--test-filter") == 0) { |
| ... | @@ -977,34 +968,11 @@ static int main0(int argc, char **argv) { | ... | @@ -977,34 +968,11 @@ static int main0(int argc, char **argv) { |
| 977 | init_all_targets(); | 968 | init_all_targets(); |
| 978 | 969 | ||
| 979 | ZigTarget target; | 970 | ZigTarget target; |
| 980 | if ((err = target_parse_triple(&target, target_string, mcpu))) { | 971 | if ((err = target_parse_triple(&target, target_string, mcpu, dynamic_linker))) { |
| 981 | fprintf(stderr, "invalid target: %s\n" | 972 | fprintf(stderr, "invalid target: %s\n" |
| 982 | "See `%s targets` to display valid targets.\n", err_str(err), arg0); | 973 | "See `%s targets` to display valid targets.\n", err_str(err), arg0); |
| 983 | return print_error_usage(arg0); | 974 | return print_error_usage(arg0); |
| 984 | } | 975 | } |
| 985 | if (target_is_glibc(&target)) { | ||
| 986 | target.glibc_version = heap::c_allocator.create<ZigGLibCVersion>(); | ||
| 987 | |||
| 988 | if (target_glibc != nullptr) { | ||
| 989 | if ((err = target_parse_glibc_version(target.glibc_version, target_glibc))) { | ||
| 990 | fprintf(stderr, "invalid glibc version '%s': %s\n", target_glibc, err_str(err)); | ||
| 991 | return print_error_usage(arg0); | ||
| 992 | } | ||
| 993 | } else { | ||
| 994 | target_init_default_glibc_version(&target); | ||
| 995 | #if defined(ZIG_OS_LINUX) | ||
| 996 | if (target.is_native) { | ||
| 997 | // TODO self-host glibc version detection, and then this logic can go away | ||
| 998 | if ((err = glibc_detect_native_version(target.glibc_version))) { | ||
| 999 | // Fall back to the default version. | ||
| 1000 | } | ||
| 1001 | } | ||
| 1002 | #endif | ||
| 1003 | } | ||
| 1004 | } else if (target_glibc != nullptr) { | ||
| 1005 | fprintf(stderr, "'%s' is not a glibc-compatible target", target_string); | ||
| 1006 | return print_error_usage(arg0); | ||
| 1007 | } | ||
| 1008 | 976 | ||
| 1009 | Buf zig_triple_buf = BUF_INIT; | 977 | Buf zig_triple_buf = BUF_INIT; |
| 1010 | target_triple_zig(&zig_triple_buf, &target); | 978 | target_triple_zig(&zig_triple_buf, &target); |
| ... | @@ -1225,7 +1193,6 @@ static int main0(int argc, char **argv) { | ... | @@ -1225,7 +1193,6 @@ static int main0(int argc, char **argv) { |
| 1225 | 1193 | ||
| 1226 | codegen_set_strip(g, strip); | 1194 | codegen_set_strip(g, strip); |
| 1227 | g->is_dynamic = is_dynamic; | 1195 | g->is_dynamic = is_dynamic; |
| 1228 | g->dynamic_linker_path = dynamic_linker; | ||
| 1229 | g->verbose_tokenize = verbose_tokenize; | 1196 | g->verbose_tokenize = verbose_tokenize; |
| 1230 | g->verbose_ast = verbose_ast; | 1197 | g->verbose_ast = verbose_ast; |
| 1231 | g->verbose_link = verbose_link; | 1198 | g->verbose_link = verbose_link; |
| ... | @@ -1264,18 +1231,6 @@ static int main0(int argc, char **argv) { | ... | @@ -1264,18 +1231,6 @@ static int main0(int argc, char **argv) { |
| 1264 | } | 1231 | } |
| 1265 | 1232 | ||
| 1266 | codegen_set_rdynamic(g, rdynamic); | 1233 | codegen_set_rdynamic(g, rdynamic); |
| 1267 | if (mmacosx_version_min && mios_version_min) { | ||
| 1268 | fprintf(stderr, "-mmacosx-version-min and -mios-version-min options not allowed together\n"); | ||
| 1269 | return main_exit(root_progress_node, EXIT_FAILURE); | ||
| 1270 | } | ||
| 1271 | |||
| 1272 | if (mmacosx_version_min) { | ||
| 1273 | codegen_set_mmacosx_version_min(g, buf_create_from_str(mmacosx_version_min)); | ||
| 1274 | } | ||
| 1275 | |||
| 1276 | if (mios_version_min) { | ||
| 1277 | codegen_set_mios_version_min(g, buf_create_from_str(mios_version_min)); | ||
| 1278 | } | ||
| 1279 | 1234 | ||
| 1280 | if (test_filter) { | 1235 | if (test_filter) { |
| 1281 | codegen_set_test_filter(g, buf_create_from_str(test_filter)); | 1236 | codegen_set_test_filter(g, buf_create_from_str(test_filter)); |
| ... | @@ -1364,7 +1319,10 @@ static int main0(int argc, char **argv) { | ... | @@ -1364,7 +1319,10 @@ static int main0(int argc, char **argv) { |
| 1364 | return main_exit(root_progress_node, EXIT_SUCCESS); | 1319 | return main_exit(root_progress_node, EXIT_SUCCESS); |
| 1365 | } else if (cmd == CmdTest) { | 1320 | } else if (cmd == CmdTest) { |
| 1366 | ZigTarget native; | 1321 | ZigTarget native; |
| 1367 | get_native_target(&native); | 1322 | if ((err = target_parse_triple(&native, "native", nullptr, nullptr))) { |
| 1323 | fprintf(stderr, "Unable to get native target: %s\n", err_str(err)); | ||
| 1324 | return EXIT_FAILURE; | ||
| 1325 | } | ||
| 1368 | 1326 | ||
| 1369 | g->enable_cache = get_cache_opt(enable_cache, output_dir == nullptr); | 1327 | g->enable_cache = get_cache_opt(enable_cache, output_dir == nullptr); |
| 1370 | codegen_build_and_link(g); | 1328 | codegen_build_and_link(g); |
src/stage2.cpp+106-9| ... | @@ -91,7 +91,109 @@ void stage2_progress_complete_one(Stage2ProgressNode *node) {} | ... | @@ -91,7 +91,109 @@ void stage2_progress_complete_one(Stage2ProgressNode *node) {} |
| 91 | void stage2_progress_disable_tty(Stage2Progress *progress) {} | 91 | void stage2_progress_disable_tty(Stage2Progress *progress) {} |
| 92 | void stage2_progress_update_node(Stage2ProgressNode *node, size_t completed_count, size_t estimated_total_items){} | 92 | void stage2_progress_update_node(Stage2ProgressNode *node, size_t completed_count, size_t estimated_total_items){} |
| 93 | 93 | ||
| 94 | Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, const char *mcpu) { | 94 | static Os get_zig_os_type(ZigLLVM_OSType os_type) { |
| 95 | switch (os_type) { | ||
| 96 | case ZigLLVM_UnknownOS: | ||
| 97 | return OsFreestanding; | ||
| 98 | case ZigLLVM_Ananas: | ||
| 99 | return OsAnanas; | ||
| 100 | case ZigLLVM_CloudABI: | ||
| 101 | return OsCloudABI; | ||
| 102 | case ZigLLVM_DragonFly: | ||
| 103 | return OsDragonFly; | ||
| 104 | case ZigLLVM_FreeBSD: | ||
| 105 | return OsFreeBSD; | ||
| 106 | case ZigLLVM_Fuchsia: | ||
| 107 | return OsFuchsia; | ||
| 108 | case ZigLLVM_IOS: | ||
| 109 | return OsIOS; | ||
| 110 | case ZigLLVM_KFreeBSD: | ||
| 111 | return OsKFreeBSD; | ||
| 112 | case ZigLLVM_Linux: | ||
| 113 | return OsLinux; | ||
| 114 | case ZigLLVM_Lv2: | ||
| 115 | return OsLv2; | ||
| 116 | case ZigLLVM_Darwin: | ||
| 117 | case ZigLLVM_MacOSX: | ||
| 118 | return OsMacOSX; | ||
| 119 | case ZigLLVM_NetBSD: | ||
| 120 | return OsNetBSD; | ||
| 121 | case ZigLLVM_OpenBSD: | ||
| 122 | return OsOpenBSD; | ||
| 123 | case ZigLLVM_Solaris: | ||
| 124 | return OsSolaris; | ||
| 125 | case ZigLLVM_Win32: | ||
| 126 | return OsWindows; | ||
| 127 | case ZigLLVM_Haiku: | ||
| 128 | return OsHaiku; | ||
| 129 | case ZigLLVM_Minix: | ||
| 130 | return OsMinix; | ||
| 131 | case ZigLLVM_RTEMS: | ||
| 132 | return OsRTEMS; | ||
| 133 | case ZigLLVM_NaCl: | ||
| 134 | return OsNaCl; | ||
| 135 | case ZigLLVM_CNK: | ||
| 136 | return OsCNK; | ||
| 137 | case ZigLLVM_AIX: | ||
| 138 | return OsAIX; | ||
| 139 | case ZigLLVM_CUDA: | ||
| 140 | return OsCUDA; | ||
| 141 | case ZigLLVM_NVCL: | ||
| 142 | return OsNVCL; | ||
| 143 | case ZigLLVM_AMDHSA: | ||
| 144 | return OsAMDHSA; | ||
| 145 | case ZigLLVM_PS4: | ||
| 146 | return OsPS4; | ||
| 147 | case ZigLLVM_ELFIAMCU: | ||
| 148 | return OsELFIAMCU; | ||
| 149 | case ZigLLVM_TvOS: | ||
| 150 | return OsTvOS; | ||
| 151 | case ZigLLVM_WatchOS: | ||
| 152 | return OsWatchOS; | ||
| 153 | case ZigLLVM_Mesa3D: | ||
| 154 | return OsMesa3D; | ||
| 155 | case ZigLLVM_Contiki: | ||
| 156 | return OsContiki; | ||
| 157 | case ZigLLVM_AMDPAL: | ||
| 158 | return OsAMDPAL; | ||
| 159 | case ZigLLVM_HermitCore: | ||
| 160 | return OsHermitCore; | ||
| 161 | case ZigLLVM_Hurd: | ||
| 162 | return OsHurd; | ||
| 163 | case ZigLLVM_WASI: | ||
| 164 | return OsWASI; | ||
| 165 | case ZigLLVM_Emscripten: | ||
| 166 | return OsEmscripten; | ||
| 167 | } | ||
| 168 | zig_unreachable(); | ||
| 169 | } | ||
| 170 | |||
| 171 | static void get_native_target(ZigTarget *target) { | ||
| 172 | // first zero initialize | ||
| 173 | *target = {}; | ||
| 174 | |||
| 175 | ZigLLVM_OSType os_type; | ||
| 176 | ZigLLVM_ObjectFormatType oformat; // ignored; based on arch/os | ||
| 177 | ZigLLVMGetNativeTarget( | ||
| 178 | &target->arch, | ||
| 179 | &target->vendor, | ||
| 180 | &os_type, | ||
| 181 | &target->abi, | ||
| 182 | &oformat); | ||
| 183 | target->os = get_zig_os_type(os_type); | ||
| 184 | target->is_native = true; | ||
| 185 | if (target->abi == ZigLLVM_UnknownEnvironment) { | ||
| 186 | target->abi = target_default_abi(target->arch, target->os); | ||
| 187 | } | ||
| 188 | if (target_is_glibc(target)) { | ||
| 189 | target->glibc_or_darwin_version = heap::c_allocator.create<Stage2SemVer>(); | ||
| 190 | target_init_default_glibc_version(target); | ||
| 191 | } | ||
| 192 | } | ||
| 193 | |||
| 194 | Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, const char *mcpu, | ||
| 195 | const char *dynamic_linker) | ||
| 196 | { | ||
| 95 | Error err; | 197 | Error err; |
| 96 | 198 | ||
| 97 | if (zig_triple == nullptr) { | 199 | if (zig_triple == nullptr) { |
| ... | @@ -100,13 +202,11 @@ Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, cons | ... | @@ -100,13 +202,11 @@ Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, cons |
| 100 | if (mcpu == nullptr) { | 202 | if (mcpu == nullptr) { |
| 101 | target->llvm_cpu_name = ZigLLVMGetHostCPUName(); | 203 | target->llvm_cpu_name = ZigLLVMGetHostCPUName(); |
| 102 | target->llvm_cpu_features = ZigLLVMGetNativeFeatures(); | 204 | target->llvm_cpu_features = ZigLLVMGetNativeFeatures(); |
| 103 | target->builtin_str = "Target.Cpu.baseline(arch);\n"; | ||
| 104 | target->cache_hash = "native\n\n"; | 205 | target->cache_hash = "native\n\n"; |
| 105 | } else if (strcmp(mcpu, "baseline") == 0) { | 206 | } else if (strcmp(mcpu, "baseline") == 0) { |
| 106 | target->is_native = false; | 207 | target->is_native = false; |
| 107 | target->llvm_cpu_name = ""; | 208 | target->llvm_cpu_name = ""; |
| 108 | target->llvm_cpu_features = ""; | 209 | target->llvm_cpu_features = ""; |
| 109 | target->builtin_str = "Target.Cpu.baseline(arch);\n"; | ||
| 110 | target->cache_hash = "baseline\n\n"; | 210 | target->cache_hash = "baseline\n\n"; |
| 111 | } else { | 211 | } else { |
| 112 | const char *msg = "stage0 can't handle CPU/features in the target"; | 212 | const char *msg = "stage0 can't handle CPU/features in the target"; |
| ... | @@ -148,10 +248,12 @@ Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, cons | ... | @@ -148,10 +248,12 @@ Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, cons |
| 148 | const char *msg = "stage0 can't handle CPU/features in the target"; | 248 | const char *msg = "stage0 can't handle CPU/features in the target"; |
| 149 | stage2_panic(msg, strlen(msg)); | 249 | stage2_panic(msg, strlen(msg)); |
| 150 | } | 250 | } |
| 151 | target->builtin_str = "Target.Cpu.baseline(arch);\n"; | ||
| 152 | target->cache_hash = "\n\n"; | 251 | target->cache_hash = "\n\n"; |
| 153 | } | 252 | } |
| 154 | 253 | ||
| 254 | if (dynamic_linker != nullptr) { | ||
| 255 | target->dynamic_linker = dynamic_linker; | ||
| 256 | } | ||
| 155 | return ErrorNone; | 257 | return ErrorNone; |
| 156 | } | 258 | } |
| 157 | 259 | ||
| ... | @@ -186,11 +288,6 @@ enum Error stage2_libc_find_native(struct Stage2LibCInstallation *libc) { | ... | @@ -186,11 +288,6 @@ enum Error stage2_libc_find_native(struct Stage2LibCInstallation *libc) { |
| 186 | stage2_panic(msg, strlen(msg)); | 288 | stage2_panic(msg, strlen(msg)); |
| 187 | } | 289 | } |
| 188 | 290 | ||
| 189 | enum Error stage2_detect_dynamic_linker(const struct ZigTarget *target, char **out_ptr, size_t *out_len) { | ||
| 190 | const char *msg = "stage0 called stage2_detect_dynamic_linker"; | ||
| 191 | stage2_panic(msg, strlen(msg)); | ||
| 192 | } | ||
| 193 | |||
| 194 | enum Error stage2_detect_native_paths(struct Stage2NativePaths *native_paths) { | 291 | enum Error stage2_detect_native_paths(struct Stage2NativePaths *native_paths) { |
| 195 | native_paths->include_dirs_ptr = nullptr; | 292 | native_paths->include_dirs_ptr = nullptr; |
| 196 | native_paths->include_dirs_len = 0; | 293 | native_paths->include_dirs_len = 0; |
src/stage2.h+11-11| ... | @@ -103,6 +103,8 @@ enum Error { | ... | @@ -103,6 +103,8 @@ enum Error { |
| 103 | ErrorWindowsSdkNotFound, | 103 | ErrorWindowsSdkNotFound, |
| 104 | ErrorUnknownDynamicLinkerPath, | 104 | ErrorUnknownDynamicLinkerPath, |
| 105 | ErrorTargetHasNoDynamicLinker, | 105 | ErrorTargetHasNoDynamicLinker, |
| 106 | ErrorInvalidAbiVersion, | ||
| 107 | ErrorInvalidOperatingSystemVersion, | ||
| 106 | }; | 108 | }; |
| 107 | 109 | ||
| 108 | // ABI warning | 110 | // ABI warning |
| ... | @@ -268,14 +270,12 @@ enum Os { | ... | @@ -268,14 +270,12 @@ enum Os { |
| 268 | }; | 270 | }; |
| 269 | 271 | ||
| 270 | // ABI warning | 272 | // ABI warning |
| 271 | struct ZigGLibCVersion { | 273 | struct Stage2SemVer { |
| 272 | uint32_t major; // always 2 | 274 | uint32_t major; |
| 273 | uint32_t minor; | 275 | uint32_t minor; |
| 274 | uint32_t patch; | 276 | uint32_t patch; |
| 275 | }; | 277 | }; |
| 276 | 278 | ||
| 277 | struct Stage2TargetData; | ||
| 278 | |||
| 279 | // ABI warning | 279 | // ABI warning |
| 280 | struct ZigTarget { | 280 | struct ZigTarget { |
| 281 | enum ZigLLVM_ArchType arch; | 281 | enum ZigLLVM_ArchType arch; |
| ... | @@ -286,20 +286,20 @@ struct ZigTarget { | ... | @@ -286,20 +286,20 @@ struct ZigTarget { |
| 286 | 286 | ||
| 287 | bool is_native; | 287 | bool is_native; |
| 288 | 288 | ||
| 289 | struct ZigGLibCVersion *glibc_version; // null means default | 289 | // null means default. this is double-purposed to be darwin min version |
| 290 | struct Stage2SemVer *glibc_or_darwin_version; | ||
| 290 | 291 | ||
| 291 | const char *llvm_cpu_name; | 292 | const char *llvm_cpu_name; |
| 292 | const char *llvm_cpu_features; | 293 | const char *llvm_cpu_features; |
| 293 | const char *builtin_str; | 294 | const char *cpu_builtin_str; |
| 294 | const char *cache_hash; | 295 | const char *cache_hash; |
| 296 | const char *os_builtin_str; | ||
| 297 | const char *dynamic_linker; | ||
| 295 | }; | 298 | }; |
| 296 | 299 | ||
| 297 | // ABI warning | 300 | // ABI warning |
| 298 | ZIG_EXTERN_C enum Error stage2_detect_dynamic_linker(const struct ZigTarget *target, | 301 | ZIG_EXTERN_C enum Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, const char *mcpu, |
| 299 | char **out_ptr, size_t *out_len); | 302 | const char *dynamic_linker); |
| 300 | |||
| 301 | // ABI warning | ||
| 302 | ZIG_EXTERN_C enum Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, const char *mcpu); | ||
| 303 | 303 | ||
| 304 | 304 | ||
| 305 | // ABI warning | 305 | // ABI warning |
src/target.cpp+4-104| ... | @@ -287,83 +287,6 @@ ZigLLVM_OSType get_llvm_os_type(Os os_type) { | ... | @@ -287,83 +287,6 @@ ZigLLVM_OSType get_llvm_os_type(Os os_type) { |
| 287 | zig_unreachable(); | 287 | zig_unreachable(); |
| 288 | } | 288 | } |
| 289 | 289 | ||
| 290 | static Os get_zig_os_type(ZigLLVM_OSType os_type) { | ||
| 291 | switch (os_type) { | ||
| 292 | case ZigLLVM_UnknownOS: | ||
| 293 | return OsFreestanding; | ||
| 294 | case ZigLLVM_Ananas: | ||
| 295 | return OsAnanas; | ||
| 296 | case ZigLLVM_CloudABI: | ||
| 297 | return OsCloudABI; | ||
| 298 | case ZigLLVM_DragonFly: | ||
| 299 | return OsDragonFly; | ||
| 300 | case ZigLLVM_FreeBSD: | ||
| 301 | return OsFreeBSD; | ||
| 302 | case ZigLLVM_Fuchsia: | ||
| 303 | return OsFuchsia; | ||
| 304 | case ZigLLVM_IOS: | ||
| 305 | return OsIOS; | ||
| 306 | case ZigLLVM_KFreeBSD: | ||
| 307 | return OsKFreeBSD; | ||
| 308 | case ZigLLVM_Linux: | ||
| 309 | return OsLinux; | ||
| 310 | case ZigLLVM_Lv2: | ||
| 311 | return OsLv2; | ||
| 312 | case ZigLLVM_Darwin: | ||
| 313 | case ZigLLVM_MacOSX: | ||
| 314 | return OsMacOSX; | ||
| 315 | case ZigLLVM_NetBSD: | ||
| 316 | return OsNetBSD; | ||
| 317 | case ZigLLVM_OpenBSD: | ||
| 318 | return OsOpenBSD; | ||
| 319 | case ZigLLVM_Solaris: | ||
| 320 | return OsSolaris; | ||
| 321 | case ZigLLVM_Win32: | ||
| 322 | return OsWindows; | ||
| 323 | case ZigLLVM_Haiku: | ||
| 324 | return OsHaiku; | ||
| 325 | case ZigLLVM_Minix: | ||
| 326 | return OsMinix; | ||
| 327 | case ZigLLVM_RTEMS: | ||
| 328 | return OsRTEMS; | ||
| 329 | case ZigLLVM_NaCl: | ||
| 330 | return OsNaCl; | ||
| 331 | case ZigLLVM_CNK: | ||
| 332 | return OsCNK; | ||
| 333 | case ZigLLVM_AIX: | ||
| 334 | return OsAIX; | ||
| 335 | case ZigLLVM_CUDA: | ||
| 336 | return OsCUDA; | ||
| 337 | case ZigLLVM_NVCL: | ||
| 338 | return OsNVCL; | ||
| 339 | case ZigLLVM_AMDHSA: | ||
| 340 | return OsAMDHSA; | ||
| 341 | case ZigLLVM_PS4: | ||
| 342 | return OsPS4; | ||
| 343 | case ZigLLVM_ELFIAMCU: | ||
| 344 | return OsELFIAMCU; | ||
| 345 | case ZigLLVM_TvOS: | ||
| 346 | return OsTvOS; | ||
| 347 | case ZigLLVM_WatchOS: | ||
| 348 | return OsWatchOS; | ||
| 349 | case ZigLLVM_Mesa3D: | ||
| 350 | return OsMesa3D; | ||
| 351 | case ZigLLVM_Contiki: | ||
| 352 | return OsContiki; | ||
| 353 | case ZigLLVM_AMDPAL: | ||
| 354 | return OsAMDPAL; | ||
| 355 | case ZigLLVM_HermitCore: | ||
| 356 | return OsHermitCore; | ||
| 357 | case ZigLLVM_Hurd: | ||
| 358 | return OsHurd; | ||
| 359 | case ZigLLVM_WASI: | ||
| 360 | return OsWASI; | ||
| 361 | case ZigLLVM_Emscripten: | ||
| 362 | return OsEmscripten; | ||
| 363 | } | ||
| 364 | zig_unreachable(); | ||
| 365 | } | ||
| 366 | |||
| 367 | const char *target_os_name(Os os_type) { | 290 | const char *target_os_name(Os os_type) { |
| 368 | switch (os_type) { | 291 | switch (os_type) { |
| 369 | case OsFreestanding: | 292 | case OsFreestanding: |
| ... | @@ -424,7 +347,7 @@ const char *target_abi_name(ZigLLVM_EnvironmentType abi) { | ... | @@ -424,7 +347,7 @@ const char *target_abi_name(ZigLLVM_EnvironmentType abi) { |
| 424 | return ZigLLVMGetEnvironmentTypeName(abi); | 347 | return ZigLLVMGetEnvironmentTypeName(abi); |
| 425 | } | 348 | } |
| 426 | 349 | ||
| 427 | Error target_parse_glibc_version(ZigGLibCVersion *glibc_ver, const char *text) { | 350 | Error target_parse_glibc_version(Stage2SemVer *glibc_ver, const char *text) { |
| 428 | glibc_ver->major = 2; | 351 | glibc_ver->major = 2; |
| 429 | glibc_ver->minor = 0; | 352 | glibc_ver->minor = 0; |
| 430 | glibc_ver->patch = 0; | 353 | glibc_ver->patch = 0; |
| ... | @@ -447,31 +370,8 @@ Error target_parse_glibc_version(ZigGLibCVersion *glibc_ver, const char *text) { | ... | @@ -447,31 +370,8 @@ Error target_parse_glibc_version(ZigGLibCVersion *glibc_ver, const char *text) { |
| 447 | return ErrorNone; | 370 | return ErrorNone; |
| 448 | } | 371 | } |
| 449 | 372 | ||
| 450 | void get_native_target(ZigTarget *target) { | ||
| 451 | // first zero initialize | ||
| 452 | *target = {}; | ||
| 453 | |||
| 454 | ZigLLVM_OSType os_type; | ||
| 455 | ZigLLVM_ObjectFormatType oformat; // ignored; based on arch/os | ||
| 456 | ZigLLVMGetNativeTarget( | ||
| 457 | &target->arch, | ||
| 458 | &target->vendor, | ||
| 459 | &os_type, | ||
| 460 | &target->abi, | ||
| 461 | &oformat); | ||
| 462 | target->os = get_zig_os_type(os_type); | ||
| 463 | target->is_native = true; | ||
| 464 | if (target->abi == ZigLLVM_UnknownEnvironment) { | ||
| 465 | target->abi = target_default_abi(target->arch, target->os); | ||
| 466 | } | ||
| 467 | if (target_is_glibc(target)) { | ||
| 468 | target->glibc_version = heap::c_allocator.create<ZigGLibCVersion>(); | ||
| 469 | target_init_default_glibc_version(target); | ||
| 470 | } | ||
| 471 | } | ||
| 472 | |||
| 473 | void target_init_default_glibc_version(ZigTarget *target) { | 373 | void target_init_default_glibc_version(ZigTarget *target) { |
| 474 | *target->glibc_version = {2, 17, 0}; | 374 | *target->glibc_or_darwin_version = {2, 17, 0}; |
| 475 | } | 375 | } |
| 476 | 376 | ||
| 477 | Error target_parse_arch(ZigLLVM_ArchType *out_arch, const char *arch_ptr, size_t arch_len) { | 377 | Error target_parse_arch(ZigLLVM_ArchType *out_arch, const char *arch_ptr, size_t arch_len) { |
| ... | @@ -510,8 +410,8 @@ Error target_parse_abi(ZigLLVM_EnvironmentType *out_abi, const char *abi_ptr, si | ... | @@ -510,8 +410,8 @@ Error target_parse_abi(ZigLLVM_EnvironmentType *out_abi, const char *abi_ptr, si |
| 510 | return ErrorUnknownABI; | 410 | return ErrorUnknownABI; |
| 511 | } | 411 | } |
| 512 | 412 | ||
| 513 | Error target_parse_triple(ZigTarget *target, const char *triple, const char *mcpu) { | 413 | Error target_parse_triple(ZigTarget *target, const char *triple, const char *mcpu, const char *dynamic_linker) { |
| 514 | return stage2_target_parse(target, triple, mcpu); | 414 | return stage2_target_parse(target, triple, mcpu, dynamic_linker); |
| 515 | } | 415 | } |
| 516 | 416 | ||
| 517 | const char *target_arch_name(ZigLLVM_ArchType arch) { | 417 | const char *target_arch_name(ZigLLVM_ArchType arch) { |
src/target.hpp+2-3| ... | @@ -41,12 +41,12 @@ enum CIntType { | ... | @@ -41,12 +41,12 @@ enum CIntType { |
| 41 | CIntTypeCount, | 41 | CIntTypeCount, |
| 42 | }; | 42 | }; |
| 43 | 43 | ||
| 44 | Error target_parse_triple(ZigTarget *target, const char *triple, const char *mcpu); | 44 | Error target_parse_triple(ZigTarget *target, const char *triple, const char *mcpu, const char *dynamic_linker); |
| 45 | Error target_parse_arch(ZigLLVM_ArchType *arch, const char *arch_ptr, size_t arch_len); | 45 | Error target_parse_arch(ZigLLVM_ArchType *arch, const char *arch_ptr, size_t arch_len); |
| 46 | Error target_parse_os(Os *os, const char *os_ptr, size_t os_len); | 46 | Error target_parse_os(Os *os, const char *os_ptr, size_t os_len); |
| 47 | Error target_parse_abi(ZigLLVM_EnvironmentType *abi, const char *abi_ptr, size_t abi_len); | 47 | Error target_parse_abi(ZigLLVM_EnvironmentType *abi, const char *abi_ptr, size_t abi_len); |
| 48 | 48 | ||
| 49 | Error target_parse_glibc_version(ZigGLibCVersion *out, const char *text); | 49 | Error target_parse_glibc_version(Stage2SemVer *out, const char *text); |
| 50 | void target_init_default_glibc_version(ZigTarget *target); | 50 | void target_init_default_glibc_version(ZigTarget *target); |
| 51 | 51 | ||
| 52 | size_t target_arch_count(void); | 52 | size_t target_arch_count(void); |
| ... | @@ -73,7 +73,6 @@ ZigLLVM_ObjectFormatType target_oformat_enum(size_t index); | ... | @@ -73,7 +73,6 @@ ZigLLVM_ObjectFormatType target_oformat_enum(size_t index); |
| 73 | const char *target_oformat_name(ZigLLVM_ObjectFormatType oformat); | 73 | const char *target_oformat_name(ZigLLVM_ObjectFormatType oformat); |
| 74 | ZigLLVM_ObjectFormatType target_object_format(const ZigTarget *target); | 74 | ZigLLVM_ObjectFormatType target_object_format(const ZigTarget *target); |
| 75 | 75 | ||
| 76 | void get_native_target(ZigTarget *target); | ||
| 77 | void target_triple_llvm(Buf *triple, const ZigTarget *target); | 76 | void target_triple_llvm(Buf *triple, const ZigTarget *target); |
| 78 | void target_triple_zig(Buf *triple, const ZigTarget *target); | 77 | void target_triple_zig(Buf *triple, const ZigTarget *target); |
| 79 | 78 |
test/assemble_and_link.zig+2-2| ... | @@ -1,8 +1,8 @@ | ... | @@ -1,8 +1,8 @@ |
| 1 | const builtin = @import("builtin"); | 1 | const std = @import("std"); |
| 2 | const tests = @import("tests.zig"); | 2 | const tests = @import("tests.zig"); |
| 3 | 3 | ||
| 4 | pub fn addCases(cases: *tests.CompareOutputContext) void { | 4 | pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 5 | if (builtin.os == builtin.Os.linux and builtin.arch == builtin.Arch.x86_64) { | 5 | if (std.Target.current.os.tag == .linux and std.Target.current.cpu.arch == .x86_64) { |
| 6 | cases.addAsm("hello world linux x86_64", | 6 | cases.addAsm("hello world linux x86_64", |
| 7 | \\.text | 7 | \\.text |
| 8 | \\.globl _start | 8 | \\.globl _start |
test/cli.zig+2-3| ... | @@ -1,5 +1,4 @@ | ... | @@ -1,5 +1,4 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const builtin = @import("builtin"); | ||
| 3 | const testing = std.testing; | 2 | const testing = std.testing; |
| 4 | const process = std.process; | 3 | const process = std.process; |
| 5 | const fs = std.fs; | 4 | const fs = std.fs; |
| ... | @@ -93,11 +92,11 @@ fn testZigInitLib(zig_exe: []const u8, dir_path: []const u8) !void { | ... | @@ -93,11 +92,11 @@ fn testZigInitLib(zig_exe: []const u8, dir_path: []const u8) !void { |
| 93 | fn testZigInitExe(zig_exe: []const u8, dir_path: []const u8) !void { | 92 | fn testZigInitExe(zig_exe: []const u8, dir_path: []const u8) !void { |
| 94 | _ = try exec(dir_path, &[_][]const u8{ zig_exe, "init-exe" }); | 93 | _ = try exec(dir_path, &[_][]const u8{ zig_exe, "init-exe" }); |
| 95 | const run_result = try exec(dir_path, &[_][]const u8{ zig_exe, "build", "run" }); | 94 | const run_result = try exec(dir_path, &[_][]const u8{ zig_exe, "build", "run" }); |
| 96 | testing.expect(std.mem.eql(u8, run_result.stderr, "All your base are belong to us.\n")); | 95 | testing.expect(std.mem.eql(u8, run_result.stderr, "All your codebase are belong to us.\n")); |
| 97 | } | 96 | } |
| 98 | 97 | ||
| 99 | fn testGodboltApi(zig_exe: []const u8, dir_path: []const u8) anyerror!void { | 98 | fn testGodboltApi(zig_exe: []const u8, dir_path: []const u8) anyerror!void { |
| 100 | if (builtin.os != .linux or builtin.arch != .x86_64) return; | 99 | if (std.Target.current.os.tag != .linux or std.Target.current.cpu.arch != .x86_64) return; |
| 101 | 100 | ||
| 102 | const example_zig_path = try fs.path.join(a, &[_][]const u8{ dir_path, "example.zig" }); | 101 | const example_zig_path = try fs.path.join(a, &[_][]const u8{ dir_path, "example.zig" }); |
| 103 | const example_s_path = try fs.path.join(a, &[_][]const u8{ dir_path, "example.s" }); | 102 | const example_s_path = try fs.path.join(a, &[_][]const u8{ dir_path, "example.s" }); |
test/compare_output.zig+4-5| ... | @@ -1,4 +1,3 @@ | ... | @@ -1,4 +1,3 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 2 | const std = @import("std"); | 1 | const std = @import("std"); |
| 3 | const os = std.os; | 2 | const os = std.os; |
| 4 | const tests = @import("tests.zig"); | 3 | const tests = @import("tests.zig"); |
| ... | @@ -131,8 +130,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { | ... | @@ -131,8 +130,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 131 | , "Hello, world!\n 12 12 a\n"); | 130 | , "Hello, world!\n 12 12 a\n"); |
| 132 | 131 | ||
| 133 | cases.addC("number literals", | 132 | cases.addC("number literals", |
| 134 | \\const builtin = @import("builtin"); | 133 | \\const std = @import("std"); |
| 135 | \\const is_windows = builtin.os == builtin.Os.windows; | 134 | \\const is_windows = std.Target.current.os.tag == .windows; |
| 136 | \\const c = @cImport({ | 135 | \\const c = @cImport({ |
| 137 | \\ if (is_windows) { | 136 | \\ if (is_windows) { |
| 138 | \\ // See https://github.com/ziglang/zig/issues/515 | 137 | \\ // See https://github.com/ziglang/zig/issues/515 |
| ... | @@ -306,8 +305,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { | ... | @@ -306,8 +305,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 306 | , ""); | 305 | , ""); |
| 307 | 306 | ||
| 308 | cases.addC("casting between float and integer types", | 307 | cases.addC("casting between float and integer types", |
| 309 | \\const builtin = @import("builtin"); | 308 | \\const std = @import("std"); |
| 310 | \\const is_windows = builtin.os == builtin.Os.windows; | 309 | \\const is_windows = std.Target.current.os.tag == .windows; |
| 311 | \\const c = @cImport({ | 310 | \\const c = @cImport({ |
| 312 | \\ if (is_windows) { | 311 | \\ if (is_windows) { |
| 313 | \\ // See https://github.com/ziglang/zig/issues/515 | 312 | \\ // See https://github.com/ziglang/zig/issues/515 |
test/compile_errors.zig+10-15| ... | @@ -1,6 +1,5 @@ | ... | @@ -1,6 +1,5 @@ |
| 1 | const tests = @import("tests.zig"); | 1 | const tests = @import("tests.zig"); |
| 2 | const builtin = @import("builtin"); | 2 | const std = @import("std"); |
| 3 | const Target = @import("std").Target; | ||
| 4 | 3 | ||
| 5 | pub fn addCases(cases: *tests.CompileErrorContext) void { | 4 | pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 6 | cases.addTest("type mismatch with tuple concatenation", | 5 | cases.addTest("type mismatch with tuple concatenation", |
| ... | @@ -387,12 +386,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -387,12 +386,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 387 | , &[_][]const u8{ | 386 | , &[_][]const u8{ |
| 388 | "tmp.zig:3:5: error: target arch 'wasm32' does not support calling with a new stack", | 387 | "tmp.zig:3:5: error: target arch 'wasm32' does not support calling with a new stack", |
| 389 | }); | 388 | }); |
| 390 | tc.target = Target{ | 389 | tc.target = std.zig.CrossTarget{ |
| 391 | .Cross = .{ | 390 | .cpu_arch = .wasm32, |
| 392 | .cpu = Target.Cpu.baseline(.wasm32), | 391 | .os_tag = .wasi, |
| 393 | .os = .wasi, | 392 | .abi = .none, |
| 394 | .abi = .none, | ||
| 395 | }, | ||
| 396 | }; | 393 | }; |
| 397 | break :x tc; | 394 | break :x tc; |
| 398 | }); | 395 | }); |
| ... | @@ -788,12 +785,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -788,12 +785,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 788 | , &[_][]const u8{ | 785 | , &[_][]const u8{ |
| 789 | "tmp.zig:2:14: error: could not find 'foo' in the inputs or outputs", | 786 | "tmp.zig:2:14: error: could not find 'foo' in the inputs or outputs", |
| 790 | }); | 787 | }); |
| 791 | tc.target = Target{ | 788 | tc.target = std.zig.CrossTarget{ |
| 792 | .Cross = .{ | 789 | .cpu_arch = .x86_64, |
| 793 | .cpu = Target.Cpu.baseline(.x86_64), | 790 | .os_tag = .linux, |
| 794 | .os = .linux, | 791 | .abi = .gnu, |
| 795 | .abi = .gnu, | ||
| 796 | }, | ||
| 797 | }; | 792 | }; |
| 798 | break :x tc; | 793 | break :x tc; |
| 799 | }); | 794 | }); |
| ... | @@ -1453,7 +1448,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -1453,7 +1448,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 1453 | "tmp.zig:2:18: error: invalid operands to binary expression: 'error{A}' and 'error{B}'", | 1448 | "tmp.zig:2:18: error: invalid operands to binary expression: 'error{A}' and 'error{B}'", |
| 1454 | }); | 1449 | }); |
| 1455 | 1450 | ||
| 1456 | if (builtin.os == builtin.Os.linux) { | 1451 | if (std.Target.current.os.tag == .linux) { |
| 1457 | cases.addTest("implicit dependency on libc", | 1452 | cases.addTest("implicit dependency on libc", |
| 1458 | \\extern "c" fn exit(u8) void; | 1453 | \\extern "c" fn exit(u8) void; |
| 1459 | \\export fn entry() void { | 1454 | \\export fn entry() void { |
test/src/translate_c.zig+3-2| ... | @@ -7,6 +7,7 @@ const fmt = std.fmt; | ... | @@ -7,6 +7,7 @@ const fmt = std.fmt; |
| 7 | const mem = std.mem; | 7 | const mem = std.mem; |
| 8 | const fs = std.fs; | 8 | const fs = std.fs; |
| 9 | const warn = std.debug.warn; | 9 | const warn = std.debug.warn; |
| 10 | const CrossTarget = std.zig.CrossTarget; | ||
| 10 | 11 | ||
| 11 | pub const TranslateCContext = struct { | 12 | pub const TranslateCContext = struct { |
| 12 | b: *build.Builder, | 13 | b: *build.Builder, |
| ... | @@ -19,7 +20,7 @@ pub const TranslateCContext = struct { | ... | @@ -19,7 +20,7 @@ pub const TranslateCContext = struct { |
| 19 | sources: ArrayList(SourceFile), | 20 | sources: ArrayList(SourceFile), |
| 20 | expected_lines: ArrayList([]const u8), | 21 | expected_lines: ArrayList([]const u8), |
| 21 | allow_warnings: bool, | 22 | allow_warnings: bool, |
| 22 | target: std.Target = .Native, | 23 | target: CrossTarget = CrossTarget{}, |
| 23 | 24 | ||
| 24 | const SourceFile = struct { | 25 | const SourceFile = struct { |
| 25 | filename: []const u8, | 26 | filename: []const u8, |
| ... | @@ -75,7 +76,7 @@ pub const TranslateCContext = struct { | ... | @@ -75,7 +76,7 @@ pub const TranslateCContext = struct { |
| 75 | pub fn addWithTarget( | 76 | pub fn addWithTarget( |
| 76 | self: *TranslateCContext, | 77 | self: *TranslateCContext, |
| 77 | name: []const u8, | 78 | name: []const u8, |
| 78 | target: std.Target, | 79 | target: CrossTarget, |
| 79 | source: []const u8, | 80 | source: []const u8, |
| 80 | expected_lines: []const []const u8, | 81 | expected_lines: []const []const u8, |
| 81 | ) void { | 82 | ) void { |
test/stack_traces.zig+38-39| ... | @@ -1,4 +1,3 @@ | ... | @@ -1,4 +1,3 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 2 | const std = @import("std"); | 1 | const std = @import("std"); |
| 3 | const os = std.os; | 2 | const os = std.os; |
| 4 | const tests = @import("tests.zig"); | 3 | const tests = @import("tests.zig"); |
| ... | @@ -43,32 +42,32 @@ pub fn addCases(cases: *tests.StackTracesContext) void { | ... | @@ -43,32 +42,32 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 43 | \\} | 42 | \\} |
| 44 | ; | 43 | ; |
| 45 | 44 | ||
| 46 | switch (builtin.os) { | 45 | switch (std.Target.current.os.tag) { |
| 47 | .freebsd => { | 46 | .freebsd => { |
| 48 | cases.addCase( | 47 | cases.addCase( |
| 49 | "return", | 48 | "return", |
| 50 | source_return, | 49 | source_return, |
| 51 | [_][]const u8{ | 50 | [_][]const u8{ |
| 52 | // debug | 51 | // debug |
| 53 | \\error: TheSkyIsFalling | 52 | \\error: TheSkyIsFalling |
| 54 | \\source.zig:4:5: [address] in main (test) | 53 | \\source.zig:4:5: [address] in main (test) |
| 55 | \\ return error.TheSkyIsFalling; | 54 | \\ return error.TheSkyIsFalling; |
| 56 | \\ ^ | 55 | \\ ^ |
| 57 | \\ | 56 | \\ |
| 58 | , | 57 | , |
| 59 | // release-safe | 58 | // release-safe |
| 60 | \\error: TheSkyIsFalling | 59 | \\error: TheSkyIsFalling |
| 61 | \\source.zig:4:5: [address] in std.start.main (test) | 60 | \\source.zig:4:5: [address] in std.start.main (test) |
| 62 | \\ return error.TheSkyIsFalling; | 61 | \\ return error.TheSkyIsFalling; |
| 63 | \\ ^ | 62 | \\ ^ |
| 64 | \\ | 63 | \\ |
| 65 | , | 64 | , |
| 66 | // release-fast | 65 | // release-fast |
| 67 | \\error: TheSkyIsFalling | 66 | \\error: TheSkyIsFalling |
| 68 | \\ | 67 | \\ |
| 69 | , | 68 | , |
| 70 | // release-small | 69 | // release-small |
| 71 | \\error: TheSkyIsFalling | 70 | \\error: TheSkyIsFalling |
| 72 | \\ | 71 | \\ |
| 73 | }, | 72 | }, |
| 74 | ); | 73 | ); |
| ... | @@ -77,7 +76,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { | ... | @@ -77,7 +76,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 77 | source_try_return, | 76 | source_try_return, |
| 78 | [_][]const u8{ | 77 | [_][]const u8{ |
| 79 | // debug | 78 | // debug |
| 80 | \\error: TheSkyIsFalling | 79 | \\error: TheSkyIsFalling |
| 81 | \\source.zig:4:5: [address] in foo (test) | 80 | \\source.zig:4:5: [address] in foo (test) |
| 82 | \\ return error.TheSkyIsFalling; | 81 | \\ return error.TheSkyIsFalling; |
| 83 | \\ ^ | 82 | \\ ^ |
| ... | @@ -87,7 +86,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { | ... | @@ -87,7 +86,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 87 | \\ | 86 | \\ |
| 88 | , | 87 | , |
| 89 | // release-safe | 88 | // release-safe |
| 90 | \\error: TheSkyIsFalling | 89 | \\error: TheSkyIsFalling |
| 91 | \\source.zig:4:5: [address] in std.start.main (test) | 90 | \\source.zig:4:5: [address] in std.start.main (test) |
| 92 | \\ return error.TheSkyIsFalling; | 91 | \\ return error.TheSkyIsFalling; |
| 93 | \\ ^ | 92 | \\ ^ |
| ... | @@ -97,11 +96,11 @@ pub fn addCases(cases: *tests.StackTracesContext) void { | ... | @@ -97,11 +96,11 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 97 | \\ | 96 | \\ |
| 98 | , | 97 | , |
| 99 | // release-fast | 98 | // release-fast |
| 100 | \\error: TheSkyIsFalling | 99 | \\error: TheSkyIsFalling |
| 101 | \\ | 100 | \\ |
| 102 | , | 101 | , |
| 103 | // release-small | 102 | // release-small |
| 104 | \\error: TheSkyIsFalling | 103 | \\error: TheSkyIsFalling |
| 105 | \\ | 104 | \\ |
| 106 | }, | 105 | }, |
| 107 | ); | 106 | ); |
| ... | @@ -110,7 +109,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { | ... | @@ -110,7 +109,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 110 | source_try_try_return_return, | 109 | source_try_try_return_return, |
| 111 | [_][]const u8{ | 110 | [_][]const u8{ |
| 112 | // debug | 111 | // debug |
| 113 | \\error: TheSkyIsFalling | 112 | \\error: TheSkyIsFalling |
| 114 | \\source.zig:12:5: [address] in make_error (test) | 113 | \\source.zig:12:5: [address] in make_error (test) |
| 115 | \\ return error.TheSkyIsFalling; | 114 | \\ return error.TheSkyIsFalling; |
| 116 | \\ ^ | 115 | \\ ^ |
| ... | @@ -126,7 +125,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { | ... | @@ -126,7 +125,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 126 | \\ | 125 | \\ |
| 127 | , | 126 | , |
| 128 | // release-safe | 127 | // release-safe |
| 129 | \\error: TheSkyIsFalling | 128 | \\error: TheSkyIsFalling |
| 130 | \\source.zig:12:5: [address] in std.start.main (test) | 129 | \\source.zig:12:5: [address] in std.start.main (test) |
| 131 | \\ return error.TheSkyIsFalling; | 130 | \\ return error.TheSkyIsFalling; |
| 132 | \\ ^ | 131 | \\ ^ |
| ... | @@ -142,11 +141,11 @@ pub fn addCases(cases: *tests.StackTracesContext) void { | ... | @@ -142,11 +141,11 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 142 | \\ | 141 | \\ |
| 143 | , | 142 | , |
| 144 | // release-fast | 143 | // release-fast |
| 145 | \\error: TheSkyIsFalling | 144 | \\error: TheSkyIsFalling |
| 146 | \\ | 145 | \\ |
| 147 | , | 146 | , |
| 148 | // release-small | 147 | // release-small |
| 149 | \\error: TheSkyIsFalling | 148 | \\error: TheSkyIsFalling |
| 150 | \\ | 149 | \\ |
| 151 | }, | 150 | }, |
| 152 | ); | 151 | ); |
| ... | @@ -157,25 +156,25 @@ pub fn addCases(cases: *tests.StackTracesContext) void { | ... | @@ -157,25 +156,25 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 157 | source_return, | 156 | source_return, |
| 158 | [_][]const u8{ | 157 | [_][]const u8{ |
| 159 | // debug | 158 | // debug |
| 160 | \\error: TheSkyIsFalling | 159 | \\error: TheSkyIsFalling |
| 161 | \\source.zig:4:5: [address] in main (test) | 160 | \\source.zig:4:5: [address] in main (test) |
| 162 | \\ return error.TheSkyIsFalling; | 161 | \\ return error.TheSkyIsFalling; |
| 163 | \\ ^ | 162 | \\ ^ |
| 164 | \\ | 163 | \\ |
| 165 | , | 164 | , |
| 166 | // release-safe | 165 | // release-safe |
| 167 | \\error: TheSkyIsFalling | 166 | \\error: TheSkyIsFalling |
| 168 | \\source.zig:4:5: [address] in std.start.posixCallMainAndExit (test) | 167 | \\source.zig:4:5: [address] in std.start.posixCallMainAndExit (test) |
| 169 | \\ return error.TheSkyIsFalling; | 168 | \\ return error.TheSkyIsFalling; |
| 170 | \\ ^ | 169 | \\ ^ |
| 171 | \\ | 170 | \\ |
| 172 | , | 171 | , |
| 173 | // release-fast | 172 | // release-fast |
| 174 | \\error: TheSkyIsFalling | 173 | \\error: TheSkyIsFalling |
| 175 | \\ | 174 | \\ |
| 176 | , | 175 | , |
| 177 | // release-small | 176 | // release-small |
| 178 | \\error: TheSkyIsFalling | 177 | \\error: TheSkyIsFalling |
| 179 | \\ | 178 | \\ |
| 180 | }, | 179 | }, |
| 181 | ); | 180 | ); |
| ... | @@ -184,7 +183,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { | ... | @@ -184,7 +183,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 184 | source_try_return, | 183 | source_try_return, |
| 185 | [_][]const u8{ | 184 | [_][]const u8{ |
| 186 | // debug | 185 | // debug |
| 187 | \\error: TheSkyIsFalling | 186 | \\error: TheSkyIsFalling |
| 188 | \\source.zig:4:5: [address] in foo (test) | 187 | \\source.zig:4:5: [address] in foo (test) |
| 189 | \\ return error.TheSkyIsFalling; | 188 | \\ return error.TheSkyIsFalling; |
| 190 | \\ ^ | 189 | \\ ^ |
| ... | @@ -194,7 +193,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { | ... | @@ -194,7 +193,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 194 | \\ | 193 | \\ |
| 195 | , | 194 | , |
| 196 | // release-safe | 195 | // release-safe |
| 197 | \\error: TheSkyIsFalling | 196 | \\error: TheSkyIsFalling |
| 198 | \\source.zig:4:5: [address] in std.start.posixCallMainAndExit (test) | 197 | \\source.zig:4:5: [address] in std.start.posixCallMainAndExit (test) |
| 199 | \\ return error.TheSkyIsFalling; | 198 | \\ return error.TheSkyIsFalling; |
| 200 | \\ ^ | 199 | \\ ^ |
| ... | @@ -204,11 +203,11 @@ pub fn addCases(cases: *tests.StackTracesContext) void { | ... | @@ -204,11 +203,11 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 204 | \\ | 203 | \\ |
| 205 | , | 204 | , |
| 206 | // release-fast | 205 | // release-fast |
| 207 | \\error: TheSkyIsFalling | 206 | \\error: TheSkyIsFalling |
| 208 | \\ | 207 | \\ |
| 209 | , | 208 | , |
| 210 | // release-small | 209 | // release-small |
| 211 | \\error: TheSkyIsFalling | 210 | \\error: TheSkyIsFalling |
| 212 | \\ | 211 | \\ |
| 213 | }, | 212 | }, |
| 214 | ); | 213 | ); |
| ... | @@ -217,7 +216,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { | ... | @@ -217,7 +216,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 217 | source_try_try_return_return, | 216 | source_try_try_return_return, |
| 218 | [_][]const u8{ | 217 | [_][]const u8{ |
| 219 | // debug | 218 | // debug |
| 220 | \\error: TheSkyIsFalling | 219 | \\error: TheSkyIsFalling |
| 221 | \\source.zig:12:5: [address] in make_error (test) | 220 | \\source.zig:12:5: [address] in make_error (test) |
| 222 | \\ return error.TheSkyIsFalling; | 221 | \\ return error.TheSkyIsFalling; |
| 223 | \\ ^ | 222 | \\ ^ |
| ... | @@ -233,7 +232,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { | ... | @@ -233,7 +232,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 233 | \\ | 232 | \\ |
| 234 | , | 233 | , |
| 235 | // release-safe | 234 | // release-safe |
| 236 | \\error: TheSkyIsFalling | 235 | \\error: TheSkyIsFalling |
| 237 | \\source.zig:12:5: [address] in std.start.posixCallMainAndExit (test) | 236 | \\source.zig:12:5: [address] in std.start.posixCallMainAndExit (test) |
| 238 | \\ return error.TheSkyIsFalling; | 237 | \\ return error.TheSkyIsFalling; |
| 239 | \\ ^ | 238 | \\ ^ |
| ... | @@ -249,11 +248,11 @@ pub fn addCases(cases: *tests.StackTracesContext) void { | ... | @@ -249,11 +248,11 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 249 | \\ | 248 | \\ |
| 250 | , | 249 | , |
| 251 | // release-fast | 250 | // release-fast |
| 252 | \\error: TheSkyIsFalling | 251 | \\error: TheSkyIsFalling |
| 253 | \\ | 252 | \\ |
| 254 | , | 253 | , |
| 255 | // release-small | 254 | // release-small |
| 256 | \\error: TheSkyIsFalling | 255 | \\error: TheSkyIsFalling |
| 257 | \\ | 256 | \\ |
| 258 | }, | 257 | }, |
| 259 | ); | 258 | ); |
| ... | @@ -278,11 +277,11 @@ pub fn addCases(cases: *tests.StackTracesContext) void { | ... | @@ -278,11 +277,11 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 278 | \\ | 277 | \\ |
| 279 | , | 278 | , |
| 280 | // release-fast | 279 | // release-fast |
| 281 | \\error: TheSkyIsFalling | 280 | \\error: TheSkyIsFalling |
| 282 | \\ | 281 | \\ |
| 283 | , | 282 | , |
| 284 | // release-small | 283 | // release-small |
| 285 | \\error: TheSkyIsFalling | 284 | \\error: TheSkyIsFalling |
| 286 | \\ | 285 | \\ |
| 287 | }, | 286 | }, |
| 288 | ); | 287 | ); |
| ... | @@ -311,11 +310,11 @@ pub fn addCases(cases: *tests.StackTracesContext) void { | ... | @@ -311,11 +310,11 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 311 | \\ | 310 | \\ |
| 312 | , | 311 | , |
| 313 | // release-fast | 312 | // release-fast |
| 314 | \\error: TheSkyIsFalling | 313 | \\error: TheSkyIsFalling |
| 315 | \\ | 314 | \\ |
| 316 | , | 315 | , |
| 317 | // release-small | 316 | // release-small |
| 318 | \\error: TheSkyIsFalling | 317 | \\error: TheSkyIsFalling |
| 319 | \\ | 318 | \\ |
| 320 | }, | 319 | }, |
| 321 | ); | 320 | ); |
| ... | @@ -356,11 +355,11 @@ pub fn addCases(cases: *tests.StackTracesContext) void { | ... | @@ -356,11 +355,11 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 356 | \\ | 355 | \\ |
| 357 | , | 356 | , |
| 358 | // release-fast | 357 | // release-fast |
| 359 | \\error: TheSkyIsFalling | 358 | \\error: TheSkyIsFalling |
| 360 | \\ | 359 | \\ |
| 361 | , | 360 | , |
| 362 | // release-small | 361 | // release-small |
| 363 | \\error: TheSkyIsFalling | 362 | \\error: TheSkyIsFalling |
| 364 | \\ | 363 | \\ |
| 365 | }, | 364 | }, |
| 366 | ); | 365 | ); |
| ... | @@ -371,7 +370,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { | ... | @@ -371,7 +370,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 371 | source_return, | 370 | source_return, |
| 372 | [_][]const u8{ | 371 | [_][]const u8{ |
| 373 | // debug | 372 | // debug |
| 374 | \\error: TheSkyIsFalling | 373 | \\error: TheSkyIsFalling |
| 375 | \\source.zig:4:5: [address] in main (test.obj) | 374 | \\source.zig:4:5: [address] in main (test.obj) |
| 376 | \\ return error.TheSkyIsFalling; | 375 | \\ return error.TheSkyIsFalling; |
| 377 | \\ ^ | 376 | \\ ^ |
| ... | @@ -381,11 +380,11 @@ pub fn addCases(cases: *tests.StackTracesContext) void { | ... | @@ -381,11 +380,11 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 381 | // --disabled-- results in segmenetation fault | 380 | // --disabled-- results in segmenetation fault |
| 382 | "", | 381 | "", |
| 383 | // release-fast | 382 | // release-fast |
| 384 | \\error: TheSkyIsFalling | 383 | \\error: TheSkyIsFalling |
| 385 | \\ | 384 | \\ |
| 386 | , | 385 | , |
| 387 | // release-small | 386 | // release-small |
| 388 | \\error: TheSkyIsFalling | 387 | \\error: TheSkyIsFalling |
| 389 | \\ | 388 | \\ |
| 390 | }, | 389 | }, |
| 391 | ); | 390 | ); |
| ... | @@ -407,11 +406,11 @@ pub fn addCases(cases: *tests.StackTracesContext) void { | ... | @@ -407,11 +406,11 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 407 | // --disabled-- results in segmenetation fault | 406 | // --disabled-- results in segmenetation fault |
| 408 | "", | 407 | "", |
| 409 | // release-fast | 408 | // release-fast |
| 410 | \\error: TheSkyIsFalling | 409 | \\error: TheSkyIsFalling |
| 411 | \\ | 410 | \\ |
| 412 | , | 411 | , |
| 413 | // release-small | 412 | // release-small |
| 414 | \\error: TheSkyIsFalling | 413 | \\error: TheSkyIsFalling |
| 415 | \\ | 414 | \\ |
| 416 | }, | 415 | }, |
| 417 | ); | 416 | ); |
| ... | @@ -439,11 +438,11 @@ pub fn addCases(cases: *tests.StackTracesContext) void { | ... | @@ -439,11 +438,11 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 439 | // --disabled-- results in segmenetation fault | 438 | // --disabled-- results in segmenetation fault |
| 440 | "", | 439 | "", |
| 441 | // release-fast | 440 | // release-fast |
| 442 | \\error: TheSkyIsFalling | 441 | \\error: TheSkyIsFalling |
| 443 | \\ | 442 | \\ |
| 444 | , | 443 | , |
| 445 | // release-small | 444 | // release-small |
| 446 | \\error: TheSkyIsFalling | 445 | \\error: TheSkyIsFalling |
| 447 | \\ | 446 | \\ |
| 448 | }, | 447 | }, |
| 449 | ); | 448 | ); |
test/stage1/behavior/asm.zig+4-3| ... | @@ -1,9 +1,10 @@ | ... | @@ -1,9 +1,10 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const config = @import("builtin"); | ||
| 3 | const expect = std.testing.expect; | 2 | const expect = std.testing.expect; |
| 4 | 3 | ||
| 4 | const is_x86_64_linux = std.Target.current.cpu.arch == .x86_64 and std.Target.current.os.tag == .linux; | ||
| 5 | |||
| 5 | comptime { | 6 | comptime { |
| 6 | if (config.arch == config.Arch.x86_64 and config.os == config.Os.linux) { | 7 | if (is_x86_64_linux) { |
| 7 | asm ( | 8 | asm ( |
| 8 | \\.globl this_is_my_alias; | 9 | \\.globl this_is_my_alias; |
| 9 | \\.type this_is_my_alias, @function; | 10 | \\.type this_is_my_alias, @function; |
| ... | @@ -13,7 +14,7 @@ comptime { | ... | @@ -13,7 +14,7 @@ comptime { |
| 13 | } | 14 | } |
| 14 | 15 | ||
| 15 | test "module level assembly" { | 16 | test "module level assembly" { |
| 16 | if (config.arch == config.Arch.x86_64 and config.os == config.Os.linux) { | 17 | if (is_x86_64_linux) { |
| 17 | expect(this_is_my_alias() == 1234); | 18 | expect(this_is_my_alias() == 1234); |
| 18 | } | 19 | } |
| 19 | } | 20 | } |
test/stage1/behavior/byteswap.zig+2-3| ... | @@ -1,6 +1,5 @@ | ... | @@ -1,6 +1,5 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const expect = std.testing.expect; | 2 | const expect = std.testing.expect; |
| 3 | const builtin = @import("builtin"); | ||
| 4 | 3 | ||
| 5 | test "@byteSwap integers" { | 4 | test "@byteSwap integers" { |
| 6 | const ByteSwapIntTest = struct { | 5 | const ByteSwapIntTest = struct { |
| ... | @@ -41,10 +40,10 @@ test "@byteSwap integers" { | ... | @@ -41,10 +40,10 @@ test "@byteSwap integers" { |
| 41 | 40 | ||
| 42 | test "@byteSwap vectors" { | 41 | test "@byteSwap vectors" { |
| 43 | // https://github.com/ziglang/zig/issues/3563 | 42 | // https://github.com/ziglang/zig/issues/3563 |
| 44 | if (builtin.os == .dragonfly) return error.SkipZigTest; | 43 | if (std.Target.current.os.tag == .dragonfly) return error.SkipZigTest; |
| 45 | 44 | ||
| 46 | // https://github.com/ziglang/zig/issues/3317 | 45 | // https://github.com/ziglang/zig/issues/3317 |
| 47 | if (builtin.arch == .mipsel) return error.SkipZigTest; | 46 | if (std.Target.current.cpu.arch == .mipsel) return error.SkipZigTest; |
| 48 | 47 | ||
| 49 | const ByteSwapVectorTest = struct { | 48 | const ByteSwapVectorTest = struct { |
| 50 | fn run() void { | 49 | fn run() void { |
test/stage1/behavior/math.zig+10-10| ... | @@ -529,7 +529,7 @@ test "comptime_int xor" { | ... | @@ -529,7 +529,7 @@ test "comptime_int xor" { |
| 529 | } | 529 | } |
| 530 | 530 | ||
| 531 | test "f128" { | 531 | test "f128" { |
| 532 | if (std.Target.current.isWindows()) { | 532 | if (std.Target.current.os.tag == .windows) { |
| 533 | // TODO https://github.com/ziglang/zig/issues/508 | 533 | // TODO https://github.com/ziglang/zig/issues/508 |
| 534 | return error.SkipZigTest; | 534 | return error.SkipZigTest; |
| 535 | } | 535 | } |
| ... | @@ -631,7 +631,7 @@ test "NaN comparison" { | ... | @@ -631,7 +631,7 @@ test "NaN comparison" { |
| 631 | // TODO: https://github.com/ziglang/zig/issues/3338 | 631 | // TODO: https://github.com/ziglang/zig/issues/3338 |
| 632 | return error.SkipZigTest; | 632 | return error.SkipZigTest; |
| 633 | } | 633 | } |
| 634 | if (std.Target.current.isWindows()) { | 634 | if (std.Target.current.os.tag == .windows) { |
| 635 | // TODO https://github.com/ziglang/zig/issues/508 | 635 | // TODO https://github.com/ziglang/zig/issues/508 |
| 636 | return error.SkipZigTest; | 636 | return error.SkipZigTest; |
| 637 | } | 637 | } |
| ... | @@ -666,14 +666,14 @@ test "128-bit multiplication" { | ... | @@ -666,14 +666,14 @@ test "128-bit multiplication" { |
| 666 | test "vector comparison" { | 666 | test "vector comparison" { |
| 667 | const S = struct { | 667 | const S = struct { |
| 668 | fn doTheTest() void { | 668 | fn doTheTest() void { |
| 669 | var a: @Vector(6, i32) = [_]i32{1, 3, -1, 5, 7, 9}; | 669 | var a: @Vector(6, i32) = [_]i32{ 1, 3, -1, 5, 7, 9 }; |
| 670 | var b: @Vector(6, i32) = [_]i32{-1, 3, 0, 6, 10, -10}; | 670 | var b: @Vector(6, i32) = [_]i32{ -1, 3, 0, 6, 10, -10 }; |
| 671 | expect(mem.eql(bool, &@as([6]bool, a < b), &[_]bool{false, false, true, true, true, false})); | 671 | expect(mem.eql(bool, &@as([6]bool, a < b), &[_]bool{ false, false, true, true, true, false })); |
| 672 | expect(mem.eql(bool, &@as([6]bool, a <= b), &[_]bool{false, true, true, true, true, false})); | 672 | expect(mem.eql(bool, &@as([6]bool, a <= b), &[_]bool{ false, true, true, true, true, false })); |
| 673 | expect(mem.eql(bool, &@as([6]bool, a == b), &[_]bool{false, true, false, false, false, false})); | 673 | expect(mem.eql(bool, &@as([6]bool, a == b), &[_]bool{ false, true, false, false, false, false })); |
| 674 | expect(mem.eql(bool, &@as([6]bool, a != b), &[_]bool{true, false, true, true, true, true})); | 674 | expect(mem.eql(bool, &@as([6]bool, a != b), &[_]bool{ true, false, true, true, true, true })); |
| 675 | expect(mem.eql(bool, &@as([6]bool, a > b), &[_]bool{true, false, false, false, false, true})); | 675 | expect(mem.eql(bool, &@as([6]bool, a > b), &[_]bool{ true, false, false, false, false, true })); |
| 676 | expect(mem.eql(bool, &@as([6]bool, a >= b), &[_]bool{true, true, false, false, false, true})); | 676 | expect(mem.eql(bool, &@as([6]bool, a >= b), &[_]bool{ true, true, false, false, false, true })); |
| 677 | } | 677 | } |
| 678 | }; | 678 | }; |
| 679 | S.doTheTest(); | 679 | S.doTheTest(); |
test/stage1/behavior/namespace_depends_on_compile_var.zig+4-4| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | const builtin = @import("builtin"); | 1 | const std = @import("std"); |
| 2 | const expect = @import("std").testing.expect; | 2 | const expect = std.testing.expect; |
| 3 | 3 | ||
| 4 | test "namespace depends on compile var" { | 4 | test "namespace depends on compile var" { |
| 5 | if (some_namespace.a_bool) { | 5 | if (some_namespace.a_bool) { |
| ... | @@ -8,7 +8,7 @@ test "namespace depends on compile var" { | ... | @@ -8,7 +8,7 @@ test "namespace depends on compile var" { |
| 8 | expect(!some_namespace.a_bool); | 8 | expect(!some_namespace.a_bool); |
| 9 | } | 9 | } |
| 10 | } | 10 | } |
| 11 | const some_namespace = switch (builtin.os) { | 11 | const some_namespace = switch (std.builtin.os.tag) { |
| 12 | builtin.Os.linux => @import("namespace_depends_on_compile_var/a.zig"), | 12 | .linux => @import("namespace_depends_on_compile_var/a.zig"), |
| 13 | else => @import("namespace_depends_on_compile_var/b.zig"), | 13 | else => @import("namespace_depends_on_compile_var/b.zig"), |
| 14 | }; | 14 | }; |
test/stage1/behavior/vector.zig+1-2| ... | @@ -2,7 +2,6 @@ const std = @import("std"); | ... | @@ -2,7 +2,6 @@ const std = @import("std"); |
| 2 | const mem = std.mem; | 2 | const mem = std.mem; |
| 3 | const expect = std.testing.expect; | 3 | const expect = std.testing.expect; |
| 4 | const expectEqual = std.testing.expectEqual; | 4 | const expectEqual = std.testing.expectEqual; |
| 5 | const builtin = @import("builtin"); | ||
| 6 | 5 | ||
| 7 | test "implicit cast vector to array - bool" { | 6 | test "implicit cast vector to array - bool" { |
| 8 | const S = struct { | 7 | const S = struct { |
| ... | @@ -114,7 +113,7 @@ test "array to vector" { | ... | @@ -114,7 +113,7 @@ test "array to vector" { |
| 114 | 113 | ||
| 115 | test "vector casts of sizes not divisable by 8" { | 114 | test "vector casts of sizes not divisable by 8" { |
| 116 | // https://github.com/ziglang/zig/issues/3563 | 115 | // https://github.com/ziglang/zig/issues/3563 |
| 117 | if (builtin.os == .dragonfly) return error.SkipZigTest; | 116 | if (std.Target.current.os.tag == .dragonfly) return error.SkipZigTest; |
| 118 | 117 | ||
| 119 | const S = struct { | 118 | const S = struct { |
| 120 | fn doTheTest() void { | 119 | fn doTheTest() void { |
test/standalone.zig+2-2| ... | @@ -18,10 +18,10 @@ pub fn addCases(cases: *tests.StandaloneContext) void { | ... | @@ -18,10 +18,10 @@ pub fn addCases(cases: *tests.StandaloneContext) void { |
| 18 | cases.addBuildFile("test/standalone/use_alias/build.zig"); | 18 | cases.addBuildFile("test/standalone/use_alias/build.zig"); |
| 19 | cases.addBuildFile("test/standalone/brace_expansion/build.zig"); | 19 | cases.addBuildFile("test/standalone/brace_expansion/build.zig"); |
| 20 | cases.addBuildFile("test/standalone/empty_env/build.zig"); | 20 | cases.addBuildFile("test/standalone/empty_env/build.zig"); |
| 21 | if (std.Target.current.getOs() != .wasi) { | 21 | if (std.Target.current.os.tag != .wasi) { |
| 22 | cases.addBuildFile("test/standalone/load_dynamic_library/build.zig"); | 22 | cases.addBuildFile("test/standalone/load_dynamic_library/build.zig"); |
| 23 | } | 23 | } |
| 24 | if (std.Target.current.getArch() == .x86_64) { // TODO add C ABI support for other architectures | 24 | if (std.Target.current.cpu.arch == .x86_64) { // TODO add C ABI support for other architectures |
| 25 | cases.addBuildFile("test/stage1/c_abi/build.zig"); | 25 | cases.addBuildFile("test/stage1/c_abi/build.zig"); |
| 26 | } | 26 | } |
| 27 | } | 27 | } |
test/tests.zig+78-115| ... | @@ -1,16 +1,15 @@ | ... | @@ -1,16 +1,15 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const builtin = std.builtin; | ||
| 2 | const debug = std.debug; | 3 | const debug = std.debug; |
| 3 | const warn = debug.warn; | 4 | const warn = debug.warn; |
| 4 | const build = std.build; | 5 | const build = std.build; |
| 5 | pub const Target = build.Target; | 6 | const CrossTarget = std.zig.CrossTarget; |
| 6 | pub const CrossTarget = build.CrossTarget; | ||
| 7 | const Buffer = std.Buffer; | 7 | const Buffer = std.Buffer; |
| 8 | const io = std.io; | 8 | const io = std.io; |
| 9 | const fs = std.fs; | 9 | const fs = std.fs; |
| 10 | const mem = std.mem; | 10 | const mem = std.mem; |
| 11 | const fmt = std.fmt; | 11 | const fmt = std.fmt; |
| 12 | const ArrayList = std.ArrayList; | 12 | const ArrayList = std.ArrayList; |
| 13 | const builtin = @import("builtin"); | ||
| 14 | const Mode = builtin.Mode; | 13 | const Mode = builtin.Mode; |
| 15 | const LibExeObjStep = build.LibExeObjStep; | 14 | const LibExeObjStep = build.LibExeObjStep; |
| 16 | 15 | ||
| ... | @@ -31,7 +30,7 @@ pub const RunTranslatedCContext = @import("src/run_translated_c.zig").RunTransla | ... | @@ -31,7 +30,7 @@ pub const RunTranslatedCContext = @import("src/run_translated_c.zig").RunTransla |
| 31 | pub const CompareOutputContext = @import("src/compare_output.zig").CompareOutputContext; | 30 | pub const CompareOutputContext = @import("src/compare_output.zig").CompareOutputContext; |
| 32 | 31 | ||
| 33 | const TestTarget = struct { | 32 | const TestTarget = struct { |
| 34 | target: Target = .Native, | 33 | target: CrossTarget = @as(CrossTarget, .{}), |
| 35 | mode: builtin.Mode = .Debug, | 34 | mode: builtin.Mode = .Debug, |
| 36 | link_libc: bool = false, | 35 | link_libc: bool = false, |
| 37 | single_threaded: bool = false, | 36 | single_threaded: bool = false, |
| ... | @@ -53,93 +52,77 @@ const test_targets = blk: { | ... | @@ -53,93 +52,77 @@ const test_targets = blk: { |
| 53 | }, | 52 | }, |
| 54 | 53 | ||
| 55 | TestTarget{ | 54 | TestTarget{ |
| 56 | .target = Target{ | 55 | .target = .{ |
| 57 | .Cross = CrossTarget{ | 56 | .cpu_arch = .x86_64, |
| 58 | .cpu = Target.Cpu.baseline(.x86_64), | 57 | .os_tag = .linux, |
| 59 | .os = .linux, | 58 | .abi = .none, |
| 60 | .abi = .none, | ||
| 61 | }, | ||
| 62 | }, | 59 | }, |
| 63 | }, | 60 | }, |
| 64 | TestTarget{ | 61 | TestTarget{ |
| 65 | .target = Target{ | 62 | .target = .{ |
| 66 | .Cross = CrossTarget{ | 63 | .cpu_arch = .x86_64, |
| 67 | .cpu = Target.Cpu.baseline(.x86_64), | 64 | .os_tag = .linux, |
| 68 | .os = .linux, | 65 | .abi = .gnu, |
| 69 | .abi = .gnu, | ||
| 70 | }, | ||
| 71 | }, | 66 | }, |
| 72 | .link_libc = true, | 67 | .link_libc = true, |
| 73 | }, | 68 | }, |
| 74 | TestTarget{ | 69 | TestTarget{ |
| 75 | .target = Target{ | 70 | .target = .{ |
| 76 | .Cross = CrossTarget{ | 71 | .cpu_arch = .x86_64, |
| 77 | .cpu = Target.Cpu.baseline(.x86_64), | 72 | .os_tag = .linux, |
| 78 | .os = .linux, | 73 | .abi = .musl, |
| 79 | .abi = .musl, | ||
| 80 | }, | ||
| 81 | }, | 74 | }, |
| 82 | .link_libc = true, | 75 | .link_libc = true, |
| 83 | }, | 76 | }, |
| 84 | 77 | ||
| 85 | TestTarget{ | 78 | TestTarget{ |
| 86 | .target = Target{ | 79 | .target = .{ |
| 87 | .Cross = CrossTarget{ | 80 | .cpu_arch = .i386, |
| 88 | .cpu = Target.Cpu.baseline(.i386), | 81 | .os_tag = .linux, |
| 89 | .os = .linux, | 82 | .abi = .none, |
| 90 | .abi = .none, | ||
| 91 | }, | ||
| 92 | }, | 83 | }, |
| 93 | }, | 84 | }, |
| 94 | TestTarget{ | 85 | TestTarget{ |
| 95 | .target = Target{ | 86 | .target = .{ |
| 96 | .Cross = CrossTarget{ | 87 | .cpu_arch = .i386, |
| 97 | .cpu = Target.Cpu.baseline(.i386), | 88 | .os_tag = .linux, |
| 98 | .os = .linux, | 89 | .abi = .musl, |
| 99 | .abi = .musl, | ||
| 100 | }, | ||
| 101 | }, | 90 | }, |
| 102 | .link_libc = true, | 91 | .link_libc = true, |
| 103 | }, | 92 | }, |
| 104 | 93 | ||
| 105 | TestTarget{ | 94 | TestTarget{ |
| 106 | .target = Target{ | 95 | .target = .{ |
| 107 | .Cross = CrossTarget{ | 96 | .cpu_arch = .aarch64, |
| 108 | .cpu = Target.Cpu.baseline(.aarch64), | 97 | .os_tag = .linux, |
| 109 | .os = .linux, | 98 | .abi = .none, |
| 110 | .abi = .none, | ||
| 111 | }, | ||
| 112 | }, | 99 | }, |
| 113 | }, | 100 | }, |
| 114 | TestTarget{ | 101 | TestTarget{ |
| 115 | .target = Target{ | 102 | .target = .{ |
| 116 | .Cross = CrossTarget{ | 103 | .cpu_arch = .aarch64, |
| 117 | .cpu = Target.Cpu.baseline(.aarch64), | 104 | .os_tag = .linux, |
| 118 | .os = .linux, | 105 | .abi = .musl, |
| 119 | .abi = .musl, | ||
| 120 | }, | ||
| 121 | }, | 106 | }, |
| 122 | .link_libc = true, | 107 | .link_libc = true, |
| 123 | }, | 108 | }, |
| 124 | TestTarget{ | 109 | TestTarget{ |
| 125 | .target = Target{ | 110 | .target = .{ |
| 126 | .Cross = CrossTarget{ | 111 | .cpu_arch = .aarch64, |
| 127 | .cpu = Target.Cpu.baseline(.aarch64), | 112 | .os_tag = .linux, |
| 128 | .os = .linux, | 113 | .abi = .gnu, |
| 129 | .abi = .gnu, | ||
| 130 | }, | ||
| 131 | }, | 114 | }, |
| 132 | .link_libc = true, | 115 | .link_libc = true, |
| 133 | }, | 116 | }, |
| 134 | 117 | ||
| 135 | TestTarget{ | 118 | TestTarget{ |
| 136 | .target = Target.parse(.{ | 119 | .target = CrossTarget.parse(.{ |
| 137 | .arch_os_abi = "arm-linux-none", | 120 | .arch_os_abi = "arm-linux-none", |
| 138 | .cpu_features = "generic+v8a", | 121 | .cpu_features = "generic+v8a", |
| 139 | }) catch unreachable, | 122 | }) catch unreachable, |
| 140 | }, | 123 | }, |
| 141 | TestTarget{ | 124 | TestTarget{ |
| 142 | .target = Target.parse(.{ | 125 | .target = CrossTarget.parse(.{ |
| 143 | .arch_os_abi = "arm-linux-musleabihf", | 126 | .arch_os_abi = "arm-linux-musleabihf", |
| 144 | .cpu_features = "generic+v8a", | 127 | .cpu_features = "generic+v8a", |
| 145 | }) catch unreachable, | 128 | }) catch unreachable, |
| ... | @@ -147,7 +130,7 @@ const test_targets = blk: { | ... | @@ -147,7 +130,7 @@ const test_targets = blk: { |
| 147 | }, | 130 | }, |
| 148 | // TODO https://github.com/ziglang/zig/issues/3287 | 131 | // TODO https://github.com/ziglang/zig/issues/3287 |
| 149 | //TestTarget{ | 132 | //TestTarget{ |
| 150 | // .target = Target.parse(.{ | 133 | // .target = CrossTarget.parse(.{ |
| 151 | // .arch_os_abi = "arm-linux-gnueabihf", | 134 | // .arch_os_abi = "arm-linux-gnueabihf", |
| 152 | // .cpu_features = "generic+v8a", | 135 | // .cpu_features = "generic+v8a", |
| 153 | // }) catch unreachable, | 136 | // }) catch unreachable, |
| ... | @@ -155,75 +138,61 @@ const test_targets = blk: { | ... | @@ -155,75 +138,61 @@ const test_targets = blk: { |
| 155 | //}, | 138 | //}, |
| 156 | 139 | ||
| 157 | TestTarget{ | 140 | TestTarget{ |
| 158 | .target = Target{ | 141 | .target = .{ |
| 159 | .Cross = CrossTarget{ | 142 | .cpu_arch = .mipsel, |
| 160 | .cpu = Target.Cpu.baseline(.mipsel), | 143 | .os_tag = .linux, |
| 161 | .os = .linux, | 144 | .abi = .none, |
| 162 | .abi = .none, | ||
| 163 | }, | ||
| 164 | }, | 145 | }, |
| 165 | }, | 146 | }, |
| 166 | TestTarget{ | 147 | TestTarget{ |
| 167 | .target = Target{ | 148 | .target = .{ |
| 168 | .Cross = CrossTarget{ | 149 | .cpu_arch = .mipsel, |
| 169 | .cpu = Target.Cpu.baseline(.mipsel), | 150 | .os_tag = .linux, |
| 170 | .os = .linux, | 151 | .abi = .musl, |
| 171 | .abi = .musl, | ||
| 172 | }, | ||
| 173 | }, | 152 | }, |
| 174 | .link_libc = true, | 153 | .link_libc = true, |
| 175 | }, | 154 | }, |
| 176 | 155 | ||
| 177 | TestTarget{ | 156 | TestTarget{ |
| 178 | .target = Target{ | 157 | .target = .{ |
| 179 | .Cross = CrossTarget{ | 158 | .cpu_arch = .x86_64, |
| 180 | .cpu = Target.Cpu.baseline(.x86_64), | 159 | .os_tag = .macosx, |
| 181 | .os = .macosx, | 160 | .abi = .gnu, |
| 182 | .abi = .gnu, | ||
| 183 | }, | ||
| 184 | }, | 161 | }, |
| 185 | // TODO https://github.com/ziglang/zig/issues/3295 | 162 | // TODO https://github.com/ziglang/zig/issues/3295 |
| 186 | .disable_native = true, | 163 | .disable_native = true, |
| 187 | }, | 164 | }, |
| 188 | 165 | ||
| 189 | TestTarget{ | 166 | TestTarget{ |
| 190 | .target = Target{ | 167 | .target = .{ |
| 191 | .Cross = CrossTarget{ | 168 | .cpu_arch = .i386, |
| 192 | .cpu = Target.Cpu.baseline(.i386), | 169 | .os_tag = .windows, |
| 193 | .os = .windows, | 170 | .abi = .msvc, |
| 194 | .abi = .msvc, | ||
| 195 | }, | ||
| 196 | }, | 171 | }, |
| 197 | }, | 172 | }, |
| 198 | 173 | ||
| 199 | TestTarget{ | 174 | TestTarget{ |
| 200 | .target = Target{ | 175 | .target = .{ |
| 201 | .Cross = CrossTarget{ | 176 | .cpu_arch = .x86_64, |
| 202 | .cpu = Target.Cpu.baseline(.x86_64), | 177 | .os_tag = .windows, |
| 203 | .os = .windows, | 178 | .abi = .msvc, |
| 204 | .abi = .msvc, | ||
| 205 | }, | ||
| 206 | }, | 179 | }, |
| 207 | }, | 180 | }, |
| 208 | 181 | ||
| 209 | TestTarget{ | 182 | TestTarget{ |
| 210 | .target = Target{ | 183 | .target = .{ |
| 211 | .Cross = CrossTarget{ | 184 | .cpu_arch = .i386, |
| 212 | .cpu = Target.Cpu.baseline(.i386), | 185 | .os_tag = .windows, |
| 213 | .os = .windows, | 186 | .abi = .gnu, |
| 214 | .abi = .gnu, | ||
| 215 | }, | ||
| 216 | }, | 187 | }, |
| 217 | .link_libc = true, | 188 | .link_libc = true, |
| 218 | }, | 189 | }, |
| 219 | 190 | ||
| 220 | TestTarget{ | 191 | TestTarget{ |
| 221 | .target = Target{ | 192 | .target = .{ |
| 222 | .Cross = CrossTarget{ | 193 | .cpu_arch = .x86_64, |
| 223 | .cpu = Target.Cpu.baseline(.x86_64), | 194 | .os_tag = .windows, |
| 224 | .os = .windows, | 195 | .abi = .gnu, |
| 225 | .abi = .gnu, | ||
| 226 | }, | ||
| 227 | }, | 196 | }, |
| 228 | .link_libc = true, | 197 | .link_libc = true, |
| 229 | }, | 198 | }, |
| ... | @@ -432,13 +401,13 @@ pub fn addPkgTests( | ... | @@ -432,13 +401,13 @@ pub fn addPkgTests( |
| 432 | const step = b.step(b.fmt("test-{}", .{name}), desc); | 401 | const step = b.step(b.fmt("test-{}", .{name}), desc); |
| 433 | 402 | ||
| 434 | for (test_targets) |test_target| { | 403 | for (test_targets) |test_target| { |
| 435 | if (skip_non_native and test_target.target != .Native) | 404 | if (skip_non_native and !test_target.target.isNative()) |
| 436 | continue; | 405 | continue; |
| 437 | 406 | ||
| 438 | if (skip_libc and test_target.link_libc) | 407 | if (skip_libc and test_target.link_libc) |
| 439 | continue; | 408 | continue; |
| 440 | 409 | ||
| 441 | if (test_target.link_libc and test_target.target.osRequiresLibC()) { | 410 | if (test_target.link_libc and test_target.target.getOs().requiresLibC()) { |
| 442 | // This would be a redundant test. | 411 | // This would be a redundant test. |
| 443 | continue; | 412 | continue; |
| 444 | } | 413 | } |
| ... | @@ -448,8 +417,8 @@ pub fn addPkgTests( | ... | @@ -448,8 +417,8 @@ pub fn addPkgTests( |
| 448 | 417 | ||
| 449 | const ArchTag = @TagType(builtin.Arch); | 418 | const ArchTag = @TagType(builtin.Arch); |
| 450 | if (test_target.disable_native and | 419 | if (test_target.disable_native and |
| 451 | test_target.target.getOs() == builtin.os and | 420 | test_target.target.getOsTag() == std.Target.current.os.tag and |
| 452 | test_target.target.getArch() == builtin.arch) | 421 | test_target.target.getCpuArch() == std.Target.current.cpu.arch) |
| 453 | { | 422 | { |
| 454 | continue; | 423 | continue; |
| 455 | } | 424 | } |
| ... | @@ -459,17 +428,14 @@ pub fn addPkgTests( | ... | @@ -459,17 +428,14 @@ pub fn addPkgTests( |
| 459 | } else false; | 428 | } else false; |
| 460 | if (!want_this_mode) continue; | 429 | if (!want_this_mode) continue; |
| 461 | 430 | ||
| 462 | const libc_prefix = if (test_target.target.osRequiresLibC()) | 431 | const libc_prefix = if (test_target.target.getOs().requiresLibC()) |
| 463 | "" | 432 | "" |
| 464 | else if (test_target.link_libc) | 433 | else if (test_target.link_libc) |
| 465 | "c" | 434 | "c" |
| 466 | else | 435 | else |
| 467 | "bare"; | 436 | "bare"; |
| 468 | 437 | ||
| 469 | const triple_prefix = if (test_target.target == .Native) | 438 | const triple_prefix = test_target.target.zigTriple(b.allocator) catch unreachable; |
| 470 | @as([]const u8, "native") | ||
| 471 | else | ||
| 472 | test_target.target.zigTripleNoSubArch(b.allocator) catch unreachable; | ||
| 473 | 439 | ||
| 474 | const these_tests = b.addTest(root_src); | 440 | const these_tests = b.addTest(root_src); |
| 475 | const single_threaded_txt = if (test_target.single_threaded) "single" else "multi"; | 441 | const single_threaded_txt = if (test_target.single_threaded) "single" else "multi"; |
| ... | @@ -483,7 +449,7 @@ pub fn addPkgTests( | ... | @@ -483,7 +449,7 @@ pub fn addPkgTests( |
| 483 | these_tests.single_threaded = test_target.single_threaded; | 449 | these_tests.single_threaded = test_target.single_threaded; |
| 484 | these_tests.setFilter(test_filter); | 450 | these_tests.setFilter(test_filter); |
| 485 | these_tests.setBuildMode(test_target.mode); | 451 | these_tests.setBuildMode(test_target.mode); |
| 486 | these_tests.setTheTarget(test_target.target); | 452 | these_tests.setTarget(test_target.target); |
| 487 | if (test_target.link_libc) { | 453 | if (test_target.link_libc) { |
| 488 | these_tests.linkSystemLibrary("c"); | 454 | these_tests.linkSystemLibrary("c"); |
| 489 | } | 455 | } |
| ... | @@ -660,7 +626,7 @@ pub const StackTracesContext = struct { | ... | @@ -660,7 +626,7 @@ pub const StackTracesContext = struct { |
| 660 | const delims = [_][]const u8{ ":", ":", ":", " in " }; | 626 | const delims = [_][]const u8{ ":", ":", ":", " in " }; |
| 661 | var marks = [_]usize{0} ** 4; | 627 | var marks = [_]usize{0} ** 4; |
| 662 | // offset search past `[drive]:` on windows | 628 | // offset search past `[drive]:` on windows |
| 663 | var pos: usize = if (builtin.os == .windows) 2 else 0; | 629 | var pos: usize = if (std.Target.current.os.tag == .windows) 2 else 0; |
| 664 | for (delims) |delim, i| { | 630 | for (delims) |delim, i| { |
| 665 | marks[i] = mem.indexOfPos(u8, line, pos, delim) orelse { | 631 | marks[i] = mem.indexOfPos(u8, line, pos, delim) orelse { |
| 666 | try buf.append(line); | 632 | try buf.append(line); |
| ... | @@ -713,7 +679,7 @@ pub const CompileErrorContext = struct { | ... | @@ -713,7 +679,7 @@ pub const CompileErrorContext = struct { |
| 713 | link_libc: bool, | 679 | link_libc: bool, |
| 714 | is_exe: bool, | 680 | is_exe: bool, |
| 715 | is_test: bool, | 681 | is_test: bool, |
| 716 | target: Target = .Native, | 682 | target: CrossTarget = CrossTarget{}, |
| 717 | 683 | ||
| 718 | const SourceFile = struct { | 684 | const SourceFile = struct { |
| 719 | filename: []const u8, | 685 | filename: []const u8, |
| ... | @@ -805,12 +771,9 @@ pub const CompileErrorContext = struct { | ... | @@ -805,12 +771,9 @@ pub const CompileErrorContext = struct { |
| 805 | zig_args.append("--output-dir") catch unreachable; | 771 | zig_args.append("--output-dir") catch unreachable; |
| 806 | zig_args.append(b.pathFromRoot(b.cache_root)) catch unreachable; | 772 | zig_args.append(b.pathFromRoot(b.cache_root)) catch unreachable; |
| 807 | 773 | ||
| 808 | switch (self.case.target) { | 774 | if (!self.case.target.isNative()) { |
| 809 | .Native => {}, | 775 | try zig_args.append("-target"); |
| 810 | .Cross => { | 776 | try zig_args.append(try self.case.target.zigTriple(b.allocator)); |
| 811 | try zig_args.append("-target"); | ||
| 812 | try zig_args.append(try self.case.target.zigTriple(b.allocator)); | ||
| 813 | }, | ||
| 814 | } | 777 | } |
| 815 | 778 | ||
| 816 | switch (self.build_mode) { | 779 | switch (self.build_mode) { |
test/translate_c.zig+11-13| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | const tests = @import("tests.zig"); | 1 | const tests = @import("tests.zig"); |
| 2 | const builtin = @import("builtin"); | 2 | const std = @import("std"); |
| 3 | const Target = @import("std").Target; | 3 | const CrossTarget = std.zig.CrossTarget; |
| 4 | 4 | ||
| 5 | pub fn addCases(cases: *tests.TranslateCContext) void { | 5 | pub fn addCases(cases: *tests.TranslateCContext) void { |
| 6 | cases.add("macro line continuation", | 6 | cases.add("macro line continuation", |
| ... | @@ -665,7 +665,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -665,7 +665,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 665 | \\} | 665 | \\} |
| 666 | }); | 666 | }); |
| 667 | 667 | ||
| 668 | if (builtin.os != builtin.Os.windows) { | 668 | if (std.Target.current.os.tag != .windows) { |
| 669 | // Windows treats this as an enum with type c_int | 669 | // Windows treats this as an enum with type c_int |
| 670 | cases.add("big negative enum init values when C ABI supports long long enums", | 670 | cases.add("big negative enum init values when C ABI supports long long enums", |
| 671 | \\enum EnumWithInits { | 671 | \\enum EnumWithInits { |
| ... | @@ -1064,7 +1064,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1064,7 +1064,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1064 | \\} | 1064 | \\} |
| 1065 | }); | 1065 | }); |
| 1066 | 1066 | ||
| 1067 | if (builtin.os != builtin.Os.windows) { | 1067 | if (std.Target.current.os.tag != .windows) { |
| 1068 | // sysv_abi not currently supported on windows | 1068 | // sysv_abi not currently supported on windows |
| 1069 | cases.add("Macro qualified functions", | 1069 | cases.add("Macro qualified functions", |
| 1070 | \\void __attribute__((sysv_abi)) foo(void); | 1070 | \\void __attribute__((sysv_abi)) foo(void); |
| ... | @@ -1093,12 +1093,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1093,12 +1093,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1093 | \\pub const fn1 = ?fn (u8) callconv(.C) void; | 1093 | \\pub const fn1 = ?fn (u8) callconv(.C) void; |
| 1094 | }); | 1094 | }); |
| 1095 | 1095 | ||
| 1096 | cases.addWithTarget("Calling convention", tests.Target{ | 1096 | cases.addWithTarget("Calling convention", .{ |
| 1097 | .Cross = .{ | 1097 | .cpu_arch = .i386, |
| 1098 | .cpu = Target.Cpu.baseline(.i386), | 1098 | .os_tag = .linux, |
| 1099 | .os = .linux, | 1099 | .abi = .none, |
| 1100 | .abi = .none, | ||
| 1101 | }, | ||
| 1102 | }, | 1100 | }, |
| 1103 | \\void __attribute__((fastcall)) foo1(float *a); | 1101 | \\void __attribute__((fastcall)) foo1(float *a); |
| 1104 | \\void __attribute__((stdcall)) foo2(float *a); | 1102 | \\void __attribute__((stdcall)) foo2(float *a); |
| ... | @@ -1113,7 +1111,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1113,7 +1111,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1113 | \\pub fn foo5(a: [*c]f32) callconv(.Thiscall) void; | 1111 | \\pub fn foo5(a: [*c]f32) callconv(.Thiscall) void; |
| 1114 | }); | 1112 | }); |
| 1115 | 1113 | ||
| 1116 | cases.addWithTarget("Calling convention", Target.parse(.{ | 1114 | cases.addWithTarget("Calling convention", CrossTarget.parse(.{ |
| 1117 | .arch_os_abi = "arm-linux-none", | 1115 | .arch_os_abi = "arm-linux-none", |
| 1118 | .cpu_features = "generic+v8_5a", | 1116 | .cpu_features = "generic+v8_5a", |
| 1119 | }) catch unreachable, | 1117 | }) catch unreachable, |
| ... | @@ -1124,7 +1122,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1124,7 +1122,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1124 | \\pub fn foo2(a: [*c]f32) callconv(.AAPCSVFP) void; | 1122 | \\pub fn foo2(a: [*c]f32) callconv(.AAPCSVFP) void; |
| 1125 | }); | 1123 | }); |
| 1126 | 1124 | ||
| 1127 | cases.addWithTarget("Calling convention", Target.parse(.{ | 1125 | cases.addWithTarget("Calling convention", CrossTarget.parse(.{ |
| 1128 | .arch_os_abi = "aarch64-linux-none", | 1126 | .arch_os_abi = "aarch64-linux-none", |
| 1129 | .cpu_features = "generic+v8_5a", | 1127 | .cpu_features = "generic+v8_5a", |
| 1130 | }) catch unreachable, | 1128 | }) catch unreachable, |
| ... | @@ -1596,7 +1594,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1596,7 +1594,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1596 | \\} | 1594 | \\} |
| 1597 | }); | 1595 | }); |
| 1598 | 1596 | ||
| 1599 | if (builtin.os != .windows) { | 1597 | if (std.Target.current.os.tag != .windows) { |
| 1600 | // When clang uses the <arch>-windows-none triple it behaves as MSVC and | 1598 | // When clang uses the <arch>-windows-none triple it behaves as MSVC and |
| 1601 | // interprets the inner `struct Bar` as an anonymous structure | 1599 | // interprets the inner `struct Bar` as an anonymous structure |
| 1602 | cases.add("type referenced struct", | 1600 | cases.add("type referenced struct", |