authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-09-21 23:28:34-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-09-21 23:28:34-07:00
logbf9a16a037e88d56bec3740698e3fcd34e9ad543
tree94af2ad13293d8bef25e17b3254b067d636f01bf
parent877e4248fc1e8e28b1f43282411aa9868d6d1d9c

stage2: implement `zig init-lib` and `zig init-exe`


2 files changed, 99 insertions(+), 7 deletions(-)

BRANCH_TODO+4-7
......@@ -1,3 +1,5 @@
1 * skip LLD caching when bin directory is not in the cache (so we don't put `id.txt` into the cwd)
2 (maybe make it an explicit option and have main.zig disable it)
13 * `zig build`
24 * repair @cImport
35 * make sure zig cc works
......@@ -12,7 +14,8 @@
1214 * -fno-emit-asm (default) do not output .s (assembly code)\n"
1315 * -femit-llvm-ir produce a .ll file with LLVM IR\n"
1416 * -fno-emit-llvm-ir (default) do not produce a .ll file with LLVM IR\n"
15 * --cache-dir [path] override the local cache directory\n"
17 * --cache-dir [path] override the local cache directory
18 * --global-cache-dir [path] override the global cache directory
1619 * implement proper parsing of LLD stderr/stdout and exposing compile errors
1720 * implement proper parsing of clang stderr/stdout and exposing compile errors
1821 * support rpaths in ELF linker code
......@@ -27,8 +30,6 @@
2730 * support cross compiling stage2 with `zig build`
2831 * --main-pkg-path
2932 * audit the CLI options for stage2
30 * `zig init-lib`
31 * `zig init-exe`
3233 * restore error messages for stage2_add_link_lib
3334 * audit the base cache hash
3435 * On operating systems that support it, do an execve for `zig test` and `zig run` rather than child process.
......@@ -56,10 +57,6 @@
5657 * libc_installation.zig: make it look for msvc only if msvc abi is chosen
5758 * switch the default C ABI for windows to be mingw-w64
5859 * change glibc log errors to normal exposed compile errors
59 * update Package to use Compilation.Directory in create()
60 - skip LLD caching when bin directory is not in the cache (so we don't put `id.txt` into the cwd)
61 (maybe make it an explicit option and have main.zig disable it)
62 - make it possible for Package to not openDir and reference already existing resources.
6360 * improve Directory.join to only use 1 allocation in a clean way.
6461 * tracy builds with lc++
6562 * some kind of "zig identifier escape" function rather than unconditionally using @"" syntax
src/main.zig+95
......@@ -140,6 +140,10 @@ pub fn mainArgs(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !v
140140 return cmdFmt(gpa, cmd_args);
141141 } else if (mem.eql(u8, cmd, "libc")) {
142142 return cmdLibC(gpa, cmd_args);
143 } else if (mem.eql(u8, cmd, "init-exe")) {
144 return cmdInit(gpa, arena, cmd_args, .Exe);
145 } else if (mem.eql(u8, cmd, "init-lib")) {
146 return cmdInit(gpa, arena, cmd_args, .Lib);
143147 } else if (mem.eql(u8, cmd, "targets")) {
144148 const info = try detectNativeTargetInfo(arena, .{});
145149 const stdout = io.getStdOut().outStream();
......@@ -1520,6 +1524,97 @@ pub fn cmdLibC(gpa: *Allocator, args: []const []const u8) !void {
15201524 }
15211525}
15221526
1527pub const usage_init =
1528 \\Usage: zig init-exe
1529 \\ zig init-lib
1530 \\
1531 \\ Initializes a `zig build` project in the current working
1532 \\ directory.
1533 \\
1534 \\Options:
1535 \\ --help Print this help and exit
1536 \\
1537 \\
1538;
1539
1540pub fn cmdInit(
1541 gpa: *Allocator,
1542 arena: *Allocator,
1543 args: []const []const u8,
1544 output_mode: std.builtin.OutputMode,
1545) !void {
1546 {
1547 var i: usize = 0;
1548 while (i < args.len) : (i += 1) {
1549 const arg = args[i];
1550 if (mem.startsWith(u8, arg, "-")) {
1551 if (mem.eql(u8, arg, "--help")) {
1552 try io.getStdOut().writeAll(usage_init);
1553 process.exit(0);
1554 } else {
1555 fatal("unrecognized parameter: '{}'", .{arg});
1556 }
1557 } else {
1558 fatal("unexpected extra parameter: '{}'", .{arg});
1559 }
1560 }
1561 }
1562 const self_exe_path = try fs.selfExePathAlloc(arena);
1563 var zig_lib_directory = introspect.findZigLibDirFromSelfExe(arena, self_exe_path) catch |err| {
1564 fatal("unable to find zig installation directory: {}\n", .{@errorName(err)});
1565 };
1566 defer zig_lib_directory.handle.close();
1567
1568 const s = fs.path.sep_str;
1569 const template_sub_path = switch (output_mode) {
1570 .Obj => unreachable,
1571 .Lib => "std" ++ s ++ "special" ++ s ++ "init-lib",
1572 .Exe => "std" ++ s ++ "special" ++ s ++ "init-exe",
1573 };
1574 var template_dir = try zig_lib_directory.handle.openDir(template_sub_path, .{});
1575 defer template_dir.close();
1576
1577 const cwd_path = try process.getCwdAlloc(arena);
1578 const cwd_basename = fs.path.basename(cwd_path);
1579
1580 const max_bytes = 10 * 1024 * 1024;
1581 const build_zig_contents = template_dir.readFileAlloc(arena, "build.zig", max_bytes) catch |err| {
1582 fatal("unable to read template file 'build.zig': {}", .{@errorName(err)});
1583 };
1584 var modified_build_zig_contents = std.ArrayList(u8).init(arena);
1585 try modified_build_zig_contents.ensureCapacity(build_zig_contents.len);
1586 for (build_zig_contents) |c| {
1587 if (c == '$') {
1588 try modified_build_zig_contents.appendSlice(cwd_basename);
1589 } else {
1590 try modified_build_zig_contents.append(c);
1591 }
1592 }
1593 const main_zig_contents = template_dir.readFileAlloc(arena, "src" ++ s ++ "main.zig", max_bytes) catch |err| {
1594 fatal("unable to read template file 'main.zig': {}", .{@errorName(err)});
1595 };
1596 if (fs.cwd().access("build.zig", .{})) |_| {
1597 fatal("existing build.zig file would be overwritten", .{});
1598 } else |err| switch (err) {
1599 error.FileNotFound => {},
1600 else => fatal("unable to test existence of build.zig: {}\n", .{@errorName(err)}),
1601 }
1602 var src_dir = try fs.cwd().makeOpenPath("src", .{});
1603 defer src_dir.close();
1604
1605 try src_dir.writeFile("main.zig", main_zig_contents);
1606 try fs.cwd().writeFile("build.zig", modified_build_zig_contents.items);
1607
1608 std.log.info("Created build.zig", .{});
1609 std.log.info("Created src" ++ s ++ "main.zig", .{});
1610
1611 switch (output_mode) {
1612 .Lib => std.log.info("Next, try `zig build --help` or `zig build test`", .{}),
1613 .Exe => std.log.info("Next, try `zig build --help` or `zig build run`", .{}),
1614 .Obj => unreachable,
1615 }
1616}
1617
15231618pub const usage_fmt =
15241619 \\Usage: zig fmt [file]...
15251620 \\