| ... | ... | @@ -35,6 +35,7 @@ const usage = |
| 35 | 35 | \\ |
| 36 | 36 | \\Commands: |
| 37 | 37 | \\ |
| 38 | \\ build Build project from build.zig |
| 38 | 39 | \\ build-exe Create executable from source or object files |
| 39 | 40 | \\ build-lib Create library from source or object files |
| 40 | 41 | \\ build-obj Create object from source or assembly |
| ... | ... | @@ -42,6 +43,8 @@ const usage = |
| 42 | 43 | \\ c++ Use Zig as a drop-in C++ compiler |
| 43 | 44 | \\ env Print lib path, std path, compiler id and version |
| 44 | 45 | \\ fmt Parse file and render in canonical zig format |
| 46 | \\ init-exe Initialize a `zig build` application in the cwd |
| 47 | \\ init-lib Initialize a `zig build` library in the cwd |
| 45 | 48 | \\ libc Display native libc paths file or validate one |
| 46 | 49 | \\ run Create executable and run immediately |
| 47 | 50 | \\ translate-c Convert C code to Zig code |
| ... | ... | @@ -136,6 +139,8 @@ pub fn mainArgs(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !v |
| 136 | 139 | mem.eql(u8, cmd, "-cc1") or mem.eql(u8, cmd, "-cc1as")) |
| 137 | 140 | { |
| 138 | 141 | return punt_to_clang(arena, args); |
| 142 | } else if (mem.eql(u8, cmd, "build")) { |
| 143 | return cmdBuild(gpa, arena, cmd_args); |
| 139 | 144 | } else if (mem.eql(u8, cmd, "fmt")) { |
| 140 | 145 | return cmdFmt(gpa, cmd_args); |
| 141 | 146 | } else if (mem.eql(u8, cmd, "libc")) { |
| ... | ... | @@ -172,18 +177,18 @@ const usage_build_generic = |
| 172 | 177 | \\Supported file types: |
| 173 | 178 | \\ .zig Zig source code |
| 174 | 179 | \\ .zir Zig Intermediate Representation code |
| 175 | | \\ (planned) .o ELF object file |
| 176 | | \\ (planned) .o MACH-O (macOS) object file |
| 177 | | \\ (planned) .obj COFF (Windows) object file |
| 178 | | \\ (planned) .lib COFF (Windows) static library |
| 179 | | \\ (planned) .a ELF static library |
| 180 | | \\ (planned) .so ELF shared object (dynamic link) |
| 181 | | \\ (planned) .dll Windows Dynamic Link Library |
| 182 | | \\ (planned) .dylib MACH-O (macOS) dynamic library |
| 183 | | \\ (planned) .s Target-specific assembly source code |
| 184 | | \\ (planned) .S Assembly with C preprocessor (requires LLVM extensions) |
| 185 | | \\ (planned) .c C source code (requires LLVM extensions) |
| 186 | | \\ (planned) .cpp C++ source code (requires LLVM extensions) |
| 180 | \\ .o ELF object file |
| 181 | \\ .o MACH-O (macOS) object file |
| 182 | \\ .obj COFF (Windows) object file |
| 183 | \\ .lib COFF (Windows) static library |
| 184 | \\ .a ELF static library |
| 185 | \\ .so ELF shared object (dynamic link) |
| 186 | \\ .dll Windows Dynamic Link Library |
| 187 | \\ .dylib MACH-O (macOS) dynamic library |
| 188 | \\ .s Target-specific assembly source code |
| 189 | \\ .S Assembly with C preprocessor (requires LLVM extensions) |
| 190 | \\ .c C source code (requires LLVM extensions) |
| 191 | \\ .cpp C++ source code (requires LLVM extensions) |
| 187 | 192 | \\ Other C++ extensions: .C .cc .cxx |
| 188 | 193 | \\ |
| 189 | 194 | \\General Options: |
| ... | ... | @@ -195,6 +200,8 @@ const usage_build_generic = |
| 195 | 200 | \\ --show-builtin Output the source of @import("builtin") then exit |
| 196 | 201 | \\ --cache-dir [path] Override the local cache directory |
| 197 | 202 | \\ --global-cache-dir [path] Override the global cache directory |
| 203 | \\ --override-lib-dir [path] Override path to Zig installation lib directory |
| 204 | \\ --enable-cache Output to cache directory; print path to stdout |
| 198 | 205 | \\ |
| 199 | 206 | \\Compile Options: |
| 200 | 207 | \\ -target [name] <arch><sub>-<os>-<abi> see the targets command |
| ... | ... | @@ -357,6 +364,7 @@ pub fn buildOutputType( |
| 357 | 364 | var test_name_prefix: ?[]const u8 = null; |
| 358 | 365 | var override_local_cache_dir: ?[]const u8 = null; |
| 359 | 366 | var override_global_cache_dir: ?[]const u8 = null; |
| 367 | var override_lib_dir: ?[]const u8 = null; |
| 360 | 368 | |
| 361 | 369 | var system_libs = std.ArrayList([]const u8).init(gpa); |
| 362 | 370 | defer system_libs.deinit(); |
| ... | ... | @@ -412,7 +420,7 @@ pub fn buildOutputType( |
| 412 | 420 | if (mem.startsWith(u8, arg, "-")) { |
| 413 | 421 | if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { |
| 414 | 422 | try io.getStdOut().writeAll(usage_build_generic); |
| 415 | | process.exit(0); |
| 423 | return process.cleanExit(); |
| 416 | 424 | } else if (mem.eql(u8, arg, "--")) { |
| 417 | 425 | if (arg_mode == .run) { |
| 418 | 426 | runtime_args_start = i + 1; |
| ... | ... | @@ -547,6 +555,12 @@ pub fn buildOutputType( |
| 547 | 555 | if (i + 1 >= args.len) fatal("expected parameter after {}", .{arg}); |
| 548 | 556 | i += 1; |
| 549 | 557 | override_global_cache_dir = args[i]; |
| 558 | } else if (mem.eql(u8, arg, "--override-lib-dir")) { |
| 559 | if (i + 1 >= args.len) fatal("expected parameter after {}", .{arg}); |
| 560 | i += 1; |
| 561 | override_lib_dir = args[i]; |
| 562 | } else if (mem.eql(u8, arg, "--enable-cache")) { |
| 563 | enable_cache = true; |
| 550 | 564 | } else if (mem.eql(u8, arg, "--test-cmd-bin")) { |
| 551 | 565 | try test_exec_args.append(null); |
| 552 | 566 | } else if (mem.eql(u8, arg, "--test-evented-io")) { |
| ... | ... | @@ -1102,12 +1116,22 @@ pub fn buildOutputType( |
| 1102 | 1116 | var cleanup_emit_bin_dir: ?fs.Dir = null; |
| 1103 | 1117 | defer if (cleanup_emit_bin_dir) |*dir| dir.close(); |
| 1104 | 1118 | |
| 1119 | const have_enable_cache = enable_cache orelse false; |
| 1120 | |
| 1105 | 1121 | const emit_bin_loc: ?Compilation.EmitLoc = switch (emit_bin) { |
| 1106 | 1122 | .no => null, |
| 1107 | 1123 | .yes_default_path => Compilation.EmitLoc{ |
| 1108 | | .directory = switch (arg_mode) { |
| 1109 | | .run, .zig_test => null, |
| 1110 | | else => .{ .path = null, .handle = fs.cwd() }, |
| 1124 | .directory = blk: { |
| 1125 | switch (arg_mode) { |
| 1126 | .run, .zig_test => break :blk null, |
| 1127 | else => { |
| 1128 | if (have_enable_cache) { |
| 1129 | break :blk null; |
| 1130 | } else { |
| 1131 | break :blk .{ .path = null, .handle = fs.cwd() }; |
| 1132 | } |
| 1133 | }, |
| 1134 | } |
| 1111 | 1135 | }, |
| 1112 | 1136 | .basename = try std.zig.binNameAlloc( |
| 1113 | 1137 | arena, |
| ... | ... | @@ -1120,6 +1144,12 @@ pub fn buildOutputType( |
| 1120 | 1144 | }, |
| 1121 | 1145 | .yes => |full_path| b: { |
| 1122 | 1146 | const basename = fs.path.basename(full_path); |
| 1147 | if (have_enable_cache) { |
| 1148 | break :b Compilation.EmitLoc{ |
| 1149 | .basename = basename, |
| 1150 | .directory = null, |
| 1151 | }; |
| 1152 | } |
| 1123 | 1153 | if (fs.path.dirname(full_path)) |dirname| { |
| 1124 | 1154 | const handle = try fs.cwd().openDir(dirname, .{}); |
| 1125 | 1155 | cleanup_emit_bin_dir = handle; |
| ... | ... | @@ -1192,9 +1222,15 @@ pub fn buildOutputType( |
| 1192 | 1222 | } else null; |
| 1193 | 1223 | |
| 1194 | 1224 | const self_exe_path = try fs.selfExePathAlloc(arena); |
| 1195 | | var zig_lib_directory = introspect.findZigLibDirFromSelfExe(arena, self_exe_path) catch |err| { |
| 1196 | | fatal("unable to find zig installation directory: {}\n", .{@errorName(err)}); |
| 1197 | | }; |
| 1225 | var zig_lib_directory: Compilation.Directory = if (override_lib_dir) |lib_dir| |
| 1226 | .{ |
| 1227 | .path = lib_dir, |
| 1228 | .handle = try fs.cwd().openDir(lib_dir, .{}), |
| 1229 | } |
| 1230 | else |
| 1231 | introspect.findZigLibDirFromSelfExe(arena, self_exe_path) catch |err| { |
| 1232 | fatal("unable to find zig installation directory: {}", .{@errorName(err)}); |
| 1233 | }; |
| 1198 | 1234 | defer zig_lib_directory.handle.close(); |
| 1199 | 1235 | |
| 1200 | 1236 | const random_seed = blk: { |
| ... | ... | @@ -1337,7 +1373,20 @@ pub fn buildOutputType( |
| 1337 | 1373 | return cmdTranslateC(comp, arena); |
| 1338 | 1374 | } |
| 1339 | 1375 | |
| 1340 | | try updateModule(gpa, comp, zir_out_path); |
| 1376 | const hook: AfterUpdateHook = blk: { |
| 1377 | if (!have_enable_cache) |
| 1378 | break :blk .none; |
| 1379 | |
| 1380 | switch (emit_bin) { |
| 1381 | .no => break :blk .none, |
| 1382 | .yes_default_path => break :blk .{ |
| 1383 | .print = comp.bin_file.options.directory.path orelse ".", |
| 1384 | }, |
| 1385 | .yes => |full_path| break :blk .{ .update = full_path }, |
| 1386 | } |
| 1387 | }; |
| 1388 | |
| 1389 | try updateModule(gpa, comp, zir_out_path, hook); |
| 1341 | 1390 | |
| 1342 | 1391 | if (build_options.have_llvm and only_pp_or_asm) { |
| 1343 | 1392 | // this may include dumping the output to stdout |
| ... | ... | @@ -1389,7 +1438,7 @@ pub fn buildOutputType( |
| 1389 | 1438 | else => process.exit(1), |
| 1390 | 1439 | } |
| 1391 | 1440 | if (!watch) |
| 1392 | | process.exit(0); |
| 1441 | return process.cleanExit(); |
| 1393 | 1442 | }, |
| 1394 | 1443 | else => {}, |
| 1395 | 1444 | } |
| ... | ... | @@ -1413,7 +1462,7 @@ pub fn buildOutputType( |
| 1413 | 1462 | if (output_mode == .Exe) { |
| 1414 | 1463 | try comp.makeBinFileWritable(); |
| 1415 | 1464 | } |
| 1416 | | try updateModule(gpa, comp, zir_out_path); |
| 1465 | try updateModule(gpa, comp, zir_out_path, hook); |
| 1417 | 1466 | } else if (mem.eql(u8, actual_line, "exit")) { |
| 1418 | 1467 | break; |
| 1419 | 1468 | } else if (mem.eql(u8, actual_line, "help")) { |
| ... | ... | @@ -1427,7 +1476,13 @@ pub fn buildOutputType( |
| 1427 | 1476 | } |
| 1428 | 1477 | } |
| 1429 | 1478 | |
| 1430 | | fn updateModule(gpa: *Allocator, comp: *Compilation, zir_out_path: ?[]const u8) !void { |
| 1479 | const AfterUpdateHook = union(enum) { |
| 1480 | none, |
| 1481 | print: []const u8, |
| 1482 | update: []const u8, |
| 1483 | }; |
| 1484 | |
| 1485 | fn updateModule(gpa: *Allocator, comp: *Compilation, zir_out_path: ?[]const u8, hook: AfterUpdateHook) !void { |
| 1431 | 1486 | try comp.update(); |
| 1432 | 1487 | |
| 1433 | 1488 | var errors = try comp.getAllErrorsAlloc(); |
| ... | ... | @@ -1437,6 +1492,15 @@ fn updateModule(gpa: *Allocator, comp: *Compilation, zir_out_path: ?[]const u8) |
| 1437 | 1492 | for (errors.list) |full_err_msg| { |
| 1438 | 1493 | full_err_msg.renderToStdErr(); |
| 1439 | 1494 | } |
| 1495 | } else switch (hook) { |
| 1496 | .none => {}, |
| 1497 | .print => |bin_path| try io.getStdOut().writer().print("{s}\n", .{bin_path}), |
| 1498 | .update => |full_path| _ = try comp.bin_file.options.directory.handle.updateFile( |
| 1499 | comp.bin_file.options.sub_path, |
| 1500 | fs.cwd(), |
| 1501 | full_path, |
| 1502 | .{}, |
| 1503 | ), |
| 1440 | 1504 | } |
| 1441 | 1505 | |
| 1442 | 1506 | if (zir_out_path) |zop| { |
| ... | ... | @@ -1535,7 +1599,7 @@ pub fn cmdLibC(gpa: *Allocator, args: []const []const u8) !void { |
| 1535 | 1599 | if (mem.eql(u8, arg, "--help")) { |
| 1536 | 1600 | const stdout = io.getStdOut().writer(); |
| 1537 | 1601 | try stdout.writeAll(usage_libc); |
| 1538 | | process.exit(0); |
| 1602 | return process.cleanExit(); |
| 1539 | 1603 | } else { |
| 1540 | 1604 | fatal("unrecognized parameter: '{}'", .{arg}); |
| 1541 | 1605 | } |
| ... | ... | @@ -1592,7 +1656,7 @@ pub fn cmdInit( |
| 1592 | 1656 | if (mem.startsWith(u8, arg, "-")) { |
| 1593 | 1657 | if (mem.eql(u8, arg, "--help")) { |
| 1594 | 1658 | try io.getStdOut().writeAll(usage_init); |
| 1595 | | process.exit(0); |
| 1659 | return process.cleanExit(); |
| 1596 | 1660 | } else { |
| 1597 | 1661 | fatal("unrecognized parameter: '{}'", .{arg}); |
| 1598 | 1662 | } |
| ... | ... | @@ -1657,6 +1721,248 @@ pub fn cmdInit( |
| 1657 | 1721 | } |
| 1658 | 1722 | } |
| 1659 | 1723 | |
| 1724 | pub const usage_build = |
| 1725 | \\Usage: zig build [steps] [options] |
| 1726 | \\ |
| 1727 | \\ Build a project from build.zig. |
| 1728 | \\ |
| 1729 | \\Options: |
| 1730 | \\ --help Print this help and exit |
| 1731 | \\ |
| 1732 | \\ |
| 1733 | ; |
| 1734 | |
| 1735 | pub fn cmdBuild(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !void { |
| 1736 | // We want to release all the locks before executing the child process, so we make a nice |
| 1737 | // big block here to ensure the cleanup gets run when we extract out our argv. |
| 1738 | const lock_and_argv = lock_and_argv: { |
| 1739 | const self_exe_path = try fs.selfExePathAlloc(arena); |
| 1740 | |
| 1741 | var build_file: ?[]const u8 = null; |
| 1742 | var override_lib_dir: ?[]const u8 = null; |
| 1743 | var override_global_cache_dir: ?[]const u8 = null; |
| 1744 | var override_local_cache_dir: ?[]const u8 = null; |
| 1745 | var child_argv = std.ArrayList([]const u8).init(arena); |
| 1746 | |
| 1747 | const argv_index_exe = child_argv.items.len; |
| 1748 | _ = try child_argv.addOne(); |
| 1749 | |
| 1750 | try child_argv.append(self_exe_path); |
| 1751 | |
| 1752 | const argv_index_build_file = child_argv.items.len; |
| 1753 | _ = try child_argv.addOne(); |
| 1754 | |
| 1755 | const argv_index_cache_dir = child_argv.items.len; |
| 1756 | _ = try child_argv.addOne(); |
| 1757 | |
| 1758 | { |
| 1759 | var i: usize = 0; |
| 1760 | while (i < args.len) : (i += 1) { |
| 1761 | const arg = args[i]; |
| 1762 | if (mem.startsWith(u8, arg, "-")) { |
| 1763 | if (mem.eql(u8, arg, "--build-file")) { |
| 1764 | if (i + 1 >= args.len) fatal("expected argument after '{}'", .{arg}); |
| 1765 | i += 1; |
| 1766 | build_file = args[i]; |
| 1767 | continue; |
| 1768 | } else if (mem.eql(u8, arg, "--override-lib-dir")) { |
| 1769 | if (i + 1 >= args.len) fatal("expected argument after '{}'", .{arg}); |
| 1770 | i += 1; |
| 1771 | override_lib_dir = args[i]; |
| 1772 | try child_argv.appendSlice(&[_][]const u8{ arg, args[i] }); |
| 1773 | continue; |
| 1774 | } else if (mem.eql(u8, arg, "--cache-dir")) { |
| 1775 | if (i + 1 >= args.len) fatal("expected argument after '{}'", .{arg}); |
| 1776 | i += 1; |
| 1777 | override_local_cache_dir = args[i]; |
| 1778 | try child_argv.appendSlice(&[_][]const u8{ arg, args[i] }); |
| 1779 | continue; |
| 1780 | } else if (mem.eql(u8, arg, "--global-cache-dir")) { |
| 1781 | if (i + 1 >= args.len) fatal("expected argument after '{}'", .{arg}); |
| 1782 | i += 1; |
| 1783 | override_global_cache_dir = args[i]; |
| 1784 | try child_argv.appendSlice(&[_][]const u8{ arg, args[i] }); |
| 1785 | continue; |
| 1786 | } |
| 1787 | } |
| 1788 | try child_argv.append(arg); |
| 1789 | } |
| 1790 | } |
| 1791 | |
| 1792 | var zig_lib_directory: Compilation.Directory = if (override_lib_dir) |lib_dir| |
| 1793 | .{ |
| 1794 | .path = lib_dir, |
| 1795 | .handle = try fs.cwd().openDir(lib_dir, .{}), |
| 1796 | } |
| 1797 | else |
| 1798 | introspect.findZigLibDirFromSelfExe(arena, self_exe_path) catch |err| { |
| 1799 | fatal("unable to find zig installation directory: {}", .{@errorName(err)}); |
| 1800 | }; |
| 1801 | defer zig_lib_directory.handle.close(); |
| 1802 | |
| 1803 | const std_special = "std" ++ fs.path.sep_str ++ "special"; |
| 1804 | const special_dir_path = try zig_lib_directory.join(arena, &[_][]const u8{std_special}); |
| 1805 | |
| 1806 | var root_pkg: Package = .{ |
| 1807 | .root_src_directory = .{ |
| 1808 | .path = special_dir_path, |
| 1809 | .handle = try zig_lib_directory.handle.openDir(std_special, .{}), |
| 1810 | }, |
| 1811 | .root_src_path = "build_runner.zig", |
| 1812 | }; |
| 1813 | defer root_pkg.root_src_directory.handle.close(); |
| 1814 | |
| 1815 | var cleanup_build_dir: ?fs.Dir = null; |
| 1816 | defer if (cleanup_build_dir) |*dir| dir.close(); |
| 1817 | |
| 1818 | const cwd_path = try process.getCwdAlloc(arena); |
| 1819 | const build_zig_basename = if (build_file) |bf| fs.path.basename(bf) else "build.zig"; |
| 1820 | const build_directory: Compilation.Directory = blk: { |
| 1821 | if (build_file) |bf| { |
| 1822 | if (fs.path.dirname(bf)) |dirname| { |
| 1823 | const dir = try fs.cwd().openDir(dirname, .{}); |
| 1824 | cleanup_build_dir = dir; |
| 1825 | break :blk .{ .path = dirname, .handle = dir }; |
| 1826 | } |
| 1827 | |
| 1828 | break :blk .{ .path = null, .handle = fs.cwd() }; |
| 1829 | } |
| 1830 | // Search up parent directories until we find build.zig. |
| 1831 | var dirname: []const u8 = cwd_path; |
| 1832 | while (true) { |
| 1833 | const joined_path = try fs.path.join(arena, &[_][]const u8{ dirname, build_zig_basename }); |
| 1834 | if (fs.cwd().access(joined_path, .{})) |_| { |
| 1835 | const dir = try fs.cwd().openDir(dirname, .{}); |
| 1836 | break :blk .{ .path = dirname, .handle = dir }; |
| 1837 | } else |err| switch (err) { |
| 1838 | error.FileNotFound => { |
| 1839 | dirname = fs.path.dirname(dirname) orelse { |
| 1840 | std.log.info("{}", .{ |
| 1841 | \\Initialize a 'build.zig' template file with `zig init-lib` or `zig init-exe`, |
| 1842 | \\or see `zig --help` for more options. |
| 1843 | }); |
| 1844 | fatal("No 'build.zig' file found, in the current directory or any parent directories.", .{}); |
| 1845 | }; |
| 1846 | continue; |
| 1847 | }, |
| 1848 | else => |e| return e, |
| 1849 | } |
| 1850 | } |
| 1851 | }; |
| 1852 | child_argv.items[argv_index_build_file] = build_directory.path orelse cwd_path; |
| 1853 | |
| 1854 | var build_pkg: Package = .{ |
| 1855 | .root_src_directory = build_directory, |
| 1856 | .root_src_path = build_zig_basename, |
| 1857 | }; |
| 1858 | try root_pkg.table.put(arena, "@build", &build_pkg); |
| 1859 | |
| 1860 | var global_cache_directory: Compilation.Directory = l: { |
| 1861 | const p = override_global_cache_dir orelse try introspect.resolveGlobalCacheDir(arena); |
| 1862 | break :l .{ |
| 1863 | .handle = try fs.cwd().makeOpenPath(p, .{}), |
| 1864 | .path = p, |
| 1865 | }; |
| 1866 | }; |
| 1867 | defer global_cache_directory.handle.close(); |
| 1868 | |
| 1869 | var local_cache_directory: Compilation.Directory = l: { |
| 1870 | if (override_local_cache_dir) |local_cache_dir_path| { |
| 1871 | break :l .{ |
| 1872 | .handle = try fs.cwd().makeOpenPath(local_cache_dir_path, .{}), |
| 1873 | .path = local_cache_dir_path, |
| 1874 | }; |
| 1875 | } |
| 1876 | const cache_dir_path = try build_directory.join(arena, &[_][]const u8{"zig-cache"}); |
| 1877 | break :l .{ |
| 1878 | .handle = try build_directory.handle.makeOpenPath("zig-cache", .{}), |
| 1879 | .path = cache_dir_path, |
| 1880 | }; |
| 1881 | }; |
| 1882 | defer local_cache_directory.handle.close(); |
| 1883 | |
| 1884 | child_argv.items[argv_index_cache_dir] = local_cache_directory.path orelse cwd_path; |
| 1885 | |
| 1886 | gimmeMoreOfThoseSweetSweetFileDescriptors(); |
| 1887 | |
| 1888 | const cross_target: std.zig.CrossTarget = .{}; |
| 1889 | const target_info = try detectNativeTargetInfo(gpa, cross_target); |
| 1890 | |
| 1891 | const exe_basename = try std.zig.binNameAlloc(arena, "build", target_info.target, .Exe, null, null); |
| 1892 | const emit_bin: Compilation.EmitLoc = .{ |
| 1893 | .directory = null, // Use the local zig-cache. |
| 1894 | .basename = exe_basename, |
| 1895 | }; |
| 1896 | const random_seed = blk: { |
| 1897 | var random_seed: u64 = undefined; |
| 1898 | try std.crypto.randomBytes(mem.asBytes(&random_seed)); |
| 1899 | break :blk random_seed; |
| 1900 | }; |
| 1901 | var default_prng = std.rand.DefaultPrng.init(random_seed); |
| 1902 | const comp = Compilation.create(gpa, .{ |
| 1903 | .zig_lib_directory = zig_lib_directory, |
| 1904 | .local_cache_directory = local_cache_directory, |
| 1905 | .global_cache_directory = global_cache_directory, |
| 1906 | .root_name = "build", |
| 1907 | .target = target_info.target, |
| 1908 | .is_native_os = cross_target.isNativeOs(), |
| 1909 | .dynamic_linker = target_info.dynamic_linker.get(), |
| 1910 | .output_mode = .Exe, |
| 1911 | .root_pkg = &root_pkg, |
| 1912 | .emit_bin = emit_bin, |
| 1913 | .emit_h = null, |
| 1914 | .optimize_mode = .Debug, |
| 1915 | .self_exe_path = self_exe_path, |
| 1916 | .rand = &default_prng.random, |
| 1917 | }) catch |err| { |
| 1918 | fatal("unable to create compilation: {}", .{@errorName(err)}); |
| 1919 | }; |
| 1920 | defer comp.destroy(); |
| 1921 | |
| 1922 | try updateModule(gpa, comp, null, .none); |
| 1923 | |
| 1924 | child_argv.items[argv_index_exe] = try comp.bin_file.options.directory.join(arena, &[_][]const u8{exe_basename}); |
| 1925 | |
| 1926 | break :lock_and_argv .{ |
| 1927 | .child_argv = child_argv.items, |
| 1928 | .lock = comp.bin_file.toOwnedLock(), |
| 1929 | }; |
| 1930 | }; |
| 1931 | const child_argv = lock_and_argv.child_argv; |
| 1932 | var lock = lock_and_argv.lock; |
| 1933 | defer lock.release(); |
| 1934 | |
| 1935 | const child = try std.ChildProcess.init(child_argv, gpa); |
| 1936 | defer child.deinit(); |
| 1937 | |
| 1938 | child.stdin_behavior = .Inherit; |
| 1939 | child.stdout_behavior = .Inherit; |
| 1940 | child.stderr_behavior = .Inherit; |
| 1941 | |
| 1942 | var cmd = std.ArrayList(u8).init(arena); |
| 1943 | |
| 1944 | const term = try child.spawnAndWait(); |
| 1945 | switch (term) { |
| 1946 | .Exited => |code| { |
| 1947 | if (code == 0) return process.cleanExit(); |
| 1948 | try cmd.writer().print("failed with exit code {}:\n", .{code}); |
| 1949 | }, |
| 1950 | else => { |
| 1951 | try cmd.appendSlice("crashed:\n"); |
| 1952 | }, |
| 1953 | } |
| 1954 | |
| 1955 | try cmd.append('\n'); |
| 1956 | for (child_argv[0 .. child_argv.len - 1]) |arg| { |
| 1957 | try cmd.appendSlice(arg); |
| 1958 | try cmd.append(' '); |
| 1959 | } |
| 1960 | try cmd.appendSlice(child_argv[child_argv.len - 1]); |
| 1961 | |
| 1962 | if (true) // Working around erroneous stage1 compile error: unreachable code on child.deinit() |
| 1963 | fatal("The following build command {}", .{cmd.items}); |
| 1964 | } |
| 1965 | |
| 1660 | 1966 | pub const usage_fmt = |
| 1661 | 1967 | \\Usage: zig fmt [file]... |
| 1662 | 1968 | \\ |
| ... | ... | @@ -1699,7 +2005,7 @@ pub fn cmdFmt(gpa: *Allocator, args: []const []const u8) !void { |
| 1699 | 2005 | if (mem.eql(u8, arg, "--help")) { |
| 1700 | 2006 | const stdout = io.getStdOut().outStream(); |
| 1701 | 2007 | try stdout.writeAll(usage_fmt); |
| 1702 | | process.exit(0); |
| 2008 | return process.cleanExit(); |
| 1703 | 2009 | } else if (mem.eql(u8, arg, "--color")) { |
| 1704 | 2010 | if (i + 1 >= args.len) { |
| 1705 | 2011 | fatal("expected [auto|on|off] after --color", .{}); |