mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
merge zig init-exe and zig init-lib into zig init
Instead of `zig init-lib` and `zig init-exe`, now there is only `zig init`, which initializes any of the template files that do not already exist, and makes a package that contains both an executable and a static library. The idea is that the user can delete whatever they don't want. In fact, I think even more things should be added to the build.zig template.
This commit is contained in:
parent
8ca4a5240e
commit
f645022d16
7 changed files with 102 additions and 141 deletions
|
|
@ -1,47 +0,0 @@
|
||||||
const std = @import("std");
|
|
||||||
|
|
||||||
// Although this function looks imperative, note that its job is to
|
|
||||||
// declaratively construct a build graph that will be executed by an external
|
|
||||||
// runner.
|
|
||||||
pub fn build(b: *std.Build) void {
|
|
||||||
// Standard target options allows the person running `zig build` to choose
|
|
||||||
// what target to build for. Here we do not override the defaults, which
|
|
||||||
// means any target is allowed, and the default is native. Other options
|
|
||||||
// for restricting supported target set are available.
|
|
||||||
const target = b.standardTargetOptions(.{});
|
|
||||||
|
|
||||||
// Standard optimization options allow the person running `zig build` to select
|
|
||||||
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not
|
|
||||||
// set a preferred release mode, allowing the user to decide how to optimize.
|
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
|
||||||
|
|
||||||
const lib = b.addStaticLibrary(.{
|
|
||||||
.name = "$",
|
|
||||||
// In this case the main source file is merely a path, however, in more
|
|
||||||
// complicated build scripts, this could be a generated file.
|
|
||||||
.root_source_file = .{ .path = "src/main.zig" },
|
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
});
|
|
||||||
|
|
||||||
// This declares intent for the library to be installed into the standard
|
|
||||||
// location when the user invokes the "install" step (the default step when
|
|
||||||
// running `zig build`).
|
|
||||||
b.installArtifact(lib);
|
|
||||||
|
|
||||||
// Creates a step for unit testing. This only builds the test executable
|
|
||||||
// but does not run it.
|
|
||||||
const main_tests = b.addTest(.{
|
|
||||||
.root_source_file = .{ .path = "src/main.zig" },
|
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
});
|
|
||||||
|
|
||||||
const run_main_tests = b.addRunArtifact(main_tests);
|
|
||||||
|
|
||||||
// This creates a build step. It will be visible in the `zig build --help` menu,
|
|
||||||
// and can be selected like this: `zig build test`
|
|
||||||
// This will evaluate the `test` step rather than the default, which is "install".
|
|
||||||
const test_step = b.step("test", "Run library tests");
|
|
||||||
test_step.dependOn(&run_main_tests.step);
|
|
||||||
}
|
|
||||||
|
|
@ -15,10 +15,22 @@ pub fn build(b: *std.Build) void {
|
||||||
// set a preferred release mode, allowing the user to decide how to optimize.
|
// set a preferred release mode, allowing the user to decide how to optimize.
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
const exe = b.addExecutable(.{
|
const lib = b.addStaticLibrary(.{
|
||||||
.name = "$",
|
.name = "$",
|
||||||
// In this case the main source file is merely a path, however, in more
|
// In this case the main source file is merely a path, however, in more
|
||||||
// complicated build scripts, this could be a generated file.
|
// complicated build scripts, this could be a generated file.
|
||||||
|
.root_source_file = .{ .path = "src/root.zig" },
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
|
||||||
|
// This declares intent for the library to be installed into the standard
|
||||||
|
// location when the user invokes the "install" step (the default step when
|
||||||
|
// running `zig build`).
|
||||||
|
b.installArtifact(lib);
|
||||||
|
|
||||||
|
const exe = b.addExecutable(.{
|
||||||
|
.name = "$",
|
||||||
.root_source_file = .{ .path = "src/main.zig" },
|
.root_source_file = .{ .path = "src/main.zig" },
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
|
|
@ -54,17 +66,26 @@ pub fn build(b: *std.Build) void {
|
||||||
|
|
||||||
// Creates a step for unit testing. This only builds the test executable
|
// Creates a step for unit testing. This only builds the test executable
|
||||||
// but does not run it.
|
// but does not run it.
|
||||||
const unit_tests = b.addTest(.{
|
const lib_unit_tests = b.addTest(.{
|
||||||
|
.root_source_file = .{ .path = "src/root.zig" },
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
|
||||||
|
const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests);
|
||||||
|
|
||||||
|
const exe_unit_tests = b.addTest(.{
|
||||||
.root_source_file = .{ .path = "src/main.zig" },
|
.root_source_file = .{ .path = "src/main.zig" },
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
});
|
});
|
||||||
|
|
||||||
const run_unit_tests = b.addRunArtifact(unit_tests);
|
const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);
|
||||||
|
|
||||||
// Similar to creating the run step earlier, this exposes a `test` step to
|
// Similar to creating the run step earlier, this exposes a `test` step to
|
||||||
// the `zig build --help` menu, providing a way for the user to request
|
// the `zig build --help` menu, providing a way for the user to request
|
||||||
// running the unit tests.
|
// running the unit tests.
|
||||||
const test_step = b.step("test", "Run unit tests");
|
const test_step = b.step("test", "Run unit tests");
|
||||||
test_step.dependOn(&run_unit_tests.step);
|
test_step.dependOn(&run_lib_unit_tests.step);
|
||||||
|
test_step.dependOn(&run_exe_unit_tests.step);
|
||||||
}
|
}
|
||||||
|
|
@ -2562,12 +2562,28 @@ pub const Dir = struct {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes content to the file system, creating a new file if it does not exist, truncating
|
pub const WriteFileError = File.WriteError || File.OpenError;
|
||||||
/// if it already exists.
|
|
||||||
pub fn writeFile(self: Dir, sub_path: []const u8, data: []const u8) !void {
|
/// Deprecated: use `writeFile2`.
|
||||||
var file = try self.createFile(sub_path, .{});
|
pub fn writeFile(self: Dir, sub_path: []const u8, data: []const u8) WriteFileError!void {
|
||||||
|
return writeFile2(self, .{
|
||||||
|
.sub_path = sub_path,
|
||||||
|
.data = data,
|
||||||
|
.flags = .{},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const WriteFileOptions = struct {
|
||||||
|
sub_path: []const u8,
|
||||||
|
data: []const u8,
|
||||||
|
flags: File.CreateFlags = .{},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Writes content to the file system, using the file creation flags provided.
|
||||||
|
pub fn writeFile2(self: Dir, options: WriteFileOptions) WriteFileError!void {
|
||||||
|
var file = try self.createFile(options.sub_path, options.flags);
|
||||||
defer file.close();
|
defer file.close();
|
||||||
try file.writeAll(data);
|
try file.writeAll(options.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const AccessError = os.AccessError;
|
pub const AccessError = os.AccessError;
|
||||||
|
|
|
||||||
104
src/main.zig
104
src/main.zig
|
|
@ -86,8 +86,7 @@ const normal_usage =
|
||||||
\\
|
\\
|
||||||
\\ build Build project from build.zig
|
\\ build Build project from build.zig
|
||||||
\\ fetch Copy a package into global cache and print its hash
|
\\ fetch Copy a package into global cache and print its hash
|
||||||
\\ init-exe Initialize a `zig build` application in the cwd
|
\\ init Initialize a Zig package in the current directory
|
||||||
\\ init-lib Initialize a `zig build` library in the cwd
|
|
||||||
\\
|
\\
|
||||||
\\ ast-check Look for simple compile errors in any set of files
|
\\ ast-check Look for simple compile errors in any set of files
|
||||||
\\ build-exe Create executable from source or object files
|
\\ build-exe Create executable from source or object files
|
||||||
|
|
@ -320,10 +319,8 @@ pub fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
|
||||||
return cmdFetch(gpa, arena, cmd_args);
|
return cmdFetch(gpa, arena, cmd_args);
|
||||||
} else if (mem.eql(u8, cmd, "libc")) {
|
} else if (mem.eql(u8, cmd, "libc")) {
|
||||||
return cmdLibC(gpa, cmd_args);
|
return cmdLibC(gpa, cmd_args);
|
||||||
} else if (mem.eql(u8, cmd, "init-exe")) {
|
} else if (mem.eql(u8, cmd, "init")) {
|
||||||
return cmdInit(gpa, arena, cmd_args, .Exe);
|
return cmdInit(gpa, arena, cmd_args);
|
||||||
} else if (mem.eql(u8, cmd, "init-lib")) {
|
|
||||||
return cmdInit(gpa, arena, cmd_args, .Lib);
|
|
||||||
} else if (mem.eql(u8, cmd, "targets")) {
|
} else if (mem.eql(u8, cmd, "targets")) {
|
||||||
const info = try detectNativeTargetInfo(.{});
|
const info = try detectNativeTargetInfo(.{});
|
||||||
const stdout = io.getStdOut().writer();
|
const stdout = io.getStdOut().writer();
|
||||||
|
|
@ -4835,8 +4832,7 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const usage_init =
|
pub const usage_init =
|
||||||
\\Usage: zig init-exe
|
\\Usage: zig init
|
||||||
\\ zig init-lib
|
|
||||||
\\
|
\\
|
||||||
\\ Initializes a `zig build` project in the current working
|
\\ Initializes a `zig build` project in the current working
|
||||||
\\ directory.
|
\\ directory.
|
||||||
|
|
@ -4847,12 +4843,7 @@ pub const usage_init =
|
||||||
\\
|
\\
|
||||||
;
|
;
|
||||||
|
|
||||||
pub fn cmdInit(
|
pub fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
|
||||||
gpa: Allocator,
|
|
||||||
arena: Allocator,
|
|
||||||
args: []const []const u8,
|
|
||||||
output_mode: std.builtin.OutputMode,
|
|
||||||
) !void {
|
|
||||||
_ = gpa;
|
_ = gpa;
|
||||||
{
|
{
|
||||||
var i: usize = 0;
|
var i: usize = 0;
|
||||||
|
|
@ -4877,14 +4868,12 @@ pub fn cmdInit(
|
||||||
defer zig_lib_directory.handle.close();
|
defer zig_lib_directory.handle.close();
|
||||||
|
|
||||||
const s = fs.path.sep_str;
|
const s = fs.path.sep_str;
|
||||||
const template_sub_path = switch (output_mode) {
|
const template_sub_path = "init";
|
||||||
.Obj => unreachable,
|
|
||||||
.Lib => "init-lib",
|
|
||||||
.Exe => "init-exe",
|
|
||||||
};
|
|
||||||
var template_dir = zig_lib_directory.handle.openDir(template_sub_path, .{}) catch |err| {
|
var template_dir = zig_lib_directory.handle.openDir(template_sub_path, .{}) catch |err| {
|
||||||
const path = zig_lib_directory.path orelse ".";
|
const path = zig_lib_directory.path orelse ".";
|
||||||
fatal("unable to open zig project template directory '{s}{s}{s}': {s}", .{ path, s, template_sub_path, @errorName(err) });
|
fatal("unable to open zig project template directory '{s}{s}{s}': {s}", .{
|
||||||
|
path, s, template_sub_path, @errorName(err),
|
||||||
|
});
|
||||||
};
|
};
|
||||||
defer template_dir.close();
|
defer template_dir.close();
|
||||||
|
|
||||||
|
|
@ -4892,46 +4881,51 @@ pub fn cmdInit(
|
||||||
const cwd_basename = fs.path.basename(cwd_path);
|
const cwd_basename = fs.path.basename(cwd_path);
|
||||||
|
|
||||||
const max_bytes = 10 * 1024 * 1024;
|
const max_bytes = 10 * 1024 * 1024;
|
||||||
const build_zig_contents = template_dir.readFileAlloc(arena, "build.zig", max_bytes) catch |err| {
|
const template_paths = [_][]const u8{
|
||||||
fatal("unable to read template file 'build.zig': {s}", .{@errorName(err)});
|
"build.zig",
|
||||||
|
"src" ++ s ++ "main.zig",
|
||||||
|
"src" ++ s ++ "root.zig",
|
||||||
};
|
};
|
||||||
var modified_build_zig_contents = try std.ArrayList(u8).initCapacity(arena, build_zig_contents.len);
|
var ok_count: usize = 0;
|
||||||
for (build_zig_contents) |c| {
|
|
||||||
if (c == '$') {
|
for (template_paths) |template_path| {
|
||||||
try modified_build_zig_contents.appendSlice(cwd_basename);
|
if (fs.path.dirname(template_path)) |dirname| {
|
||||||
} else {
|
fs.cwd().makePath(dirname) catch |err| {
|
||||||
try modified_build_zig_contents.append(c);
|
fatal("unable to make path '{s}': {s}", .{ dirname, @errorName(err) });
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const contents = template_dir.readFileAlloc(arena, template_path, max_bytes) catch |err| {
|
||||||
|
fatal("unable to read template file '{s}': {s}", .{ template_path, @errorName(err) });
|
||||||
|
};
|
||||||
|
var modified_contents = try std.ArrayList(u8).initCapacity(arena, contents.len);
|
||||||
|
for (contents) |c| {
|
||||||
|
if (c == '$') {
|
||||||
|
try modified_contents.appendSlice(cwd_basename);
|
||||||
|
} else {
|
||||||
|
try modified_contents.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fs.cwd().writeFile2(.{
|
||||||
|
.sub_path = template_path,
|
||||||
|
.data = modified_contents.items,
|
||||||
|
.flags = .{ .exclusive = true },
|
||||||
|
})) |_| {
|
||||||
|
std.log.info("created {s}", .{template_path});
|
||||||
|
ok_count += 1;
|
||||||
|
} else |err| switch (err) {
|
||||||
|
error.PathAlreadyExists => std.log.info("preserving already existing file: {s}", .{
|
||||||
|
template_path,
|
||||||
|
}),
|
||||||
|
else => std.log.err("unable to write {s}: {s}\n", .{ template_path, @errorName(err) }),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const main_zig_contents = template_dir.readFileAlloc(arena, "src" ++ s ++ "main.zig", max_bytes) catch |err| {
|
|
||||||
fatal("unable to read template file 'main.zig': {s}", .{@errorName(err)});
|
|
||||||
};
|
|
||||||
if (fs.cwd().access("build.zig", .{})) |_| {
|
|
||||||
fatal("existing build.zig file would be overwritten", .{});
|
|
||||||
} else |err| switch (err) {
|
|
||||||
error.FileNotFound => {},
|
|
||||||
else => fatal("unable to test existence of build.zig: {s}\n", .{@errorName(err)}),
|
|
||||||
}
|
|
||||||
if (fs.cwd().access("src" ++ s ++ "main.zig", .{})) |_| {
|
|
||||||
fatal("existing src" ++ s ++ "main.zig file would be overwritten", .{});
|
|
||||||
} else |err| switch (err) {
|
|
||||||
error.FileNotFound => {},
|
|
||||||
else => fatal("unable to test existence of src" ++ s ++ "main.zig: {s}\n", .{@errorName(err)}),
|
|
||||||
}
|
|
||||||
var src_dir = try fs.cwd().makeOpenPath("src", .{});
|
|
||||||
defer src_dir.close();
|
|
||||||
|
|
||||||
try src_dir.writeFile("main.zig", main_zig_contents);
|
if (ok_count == template_paths.len) {
|
||||||
try fs.cwd().writeFile("build.zig", modified_build_zig_contents.items);
|
std.log.info("see `zig build --help` for a menu of options", .{});
|
||||||
|
|
||||||
std.log.info("Created build.zig", .{});
|
|
||||||
std.log.info("Created src" ++ s ++ "main.zig", .{});
|
|
||||||
|
|
||||||
switch (output_mode) {
|
|
||||||
.Lib => std.log.info("Next, try `zig build --help` or `zig build test`", .{}),
|
|
||||||
.Exe => std.log.info("Next, try `zig build --help` or `zig build run`", .{}),
|
|
||||||
.Obj => unreachable,
|
|
||||||
}
|
}
|
||||||
|
return cleanExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const usage_build =
|
pub const usage_build =
|
||||||
|
|
|
||||||
|
|
@ -776,39 +776,16 @@ pub fn addCliTests(b: *std.Build) *Step {
|
||||||
const s = std.fs.path.sep_str;
|
const s = std.fs.path.sep_str;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
// Test `zig init`.
|
||||||
// Test `zig init-lib`.
|
|
||||||
const tmp_path = b.makeTempPath();
|
const tmp_path = b.makeTempPath();
|
||||||
const init_lib = b.addSystemCommand(&.{ b.zig_exe, "init-lib" });
|
const init_exe = b.addSystemCommand(&.{ b.zig_exe, "init" });
|
||||||
init_lib.setCwd(.{ .cwd_relative = tmp_path });
|
|
||||||
init_lib.setName("zig init-lib");
|
|
||||||
init_lib.expectStdOutEqual("");
|
|
||||||
init_lib.expectStdErrEqual("info: Created build.zig\n" ++
|
|
||||||
"info: Created src" ++ s ++ "main.zig\n" ++
|
|
||||||
"info: Next, try `zig build --help` or `zig build test`\n");
|
|
||||||
|
|
||||||
const run_test = b.addSystemCommand(&.{ b.zig_exe, "build", "test" });
|
|
||||||
run_test.setCwd(.{ .cwd_relative = tmp_path });
|
|
||||||
run_test.setName("zig build test");
|
|
||||||
run_test.expectStdOutEqual("");
|
|
||||||
run_test.step.dependOn(&init_lib.step);
|
|
||||||
|
|
||||||
const cleanup = b.addRemoveDirTree(tmp_path);
|
|
||||||
cleanup.step.dependOn(&run_test.step);
|
|
||||||
|
|
||||||
step.dependOn(&cleanup.step);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
// Test `zig init-exe`.
|
|
||||||
const tmp_path = b.makeTempPath();
|
|
||||||
const init_exe = b.addSystemCommand(&.{ b.zig_exe, "init-exe" });
|
|
||||||
init_exe.setCwd(.{ .cwd_relative = tmp_path });
|
init_exe.setCwd(.{ .cwd_relative = tmp_path });
|
||||||
init_exe.setName("zig init-exe");
|
init_exe.setName("zig init");
|
||||||
init_exe.expectStdOutEqual("");
|
init_exe.expectStdOutEqual("");
|
||||||
init_exe.expectStdErrEqual("info: Created build.zig\n" ++
|
init_exe.expectStdErrEqual("info: created build.zig\n" ++
|
||||||
"info: Created src" ++ s ++ "main.zig\n" ++
|
"info: created src" ++ s ++ "main.zig\n" ++
|
||||||
"info: Next, try `zig build --help` or `zig build run`\n");
|
"info: created src" ++ s ++ "root.zig\n" ++
|
||||||
|
"info: see `zig build --help` for a menu of options\n");
|
||||||
|
|
||||||
// Test missing output path.
|
// Test missing output path.
|
||||||
const bad_out_arg = "-femit-bin=does" ++ s ++ "not" ++ s ++ "exist" ++ s ++ "foo.exe";
|
const bad_out_arg = "-femit-bin=does" ++ s ++ "not" ++ s ++ "exist" ++ s ++ "foo.exe";
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue