Commit dee9f82f69
Changed files (12)
lib
test
standalone
lib/std/Build/Step/Compile.zig
@@ -806,14 +806,12 @@ pub fn setLibCFile(compile: *Compile, libc_file: ?LazyPath) void {
}
fn getEmittedFileGeneric(compile: *Compile, output_file: *?*GeneratedFile) LazyPath {
- if (output_file.*) |g| {
- return .{ .generated = g };
- }
+ if (output_file.*) |file| return .{ .generated = .{ .file = file } };
const arena = compile.step.owner.allocator;
const generated_file = arena.create(GeneratedFile) catch @panic("OOM");
generated_file.* = .{ .step = &compile.step };
output_file.* = generated_file;
- return .{ .generated = generated_file };
+ return .{ .generated = .{ .file = generated_file } };
}
/// Returns the path to the directory that contains the emitted binary file.
lib/std/Build/Step/ConfigHeader.zig
@@ -59,8 +59,7 @@ pub fn create(owner: *std.Build, options: Options) *ConfigHeader {
if (options.style.getPath()) |s| default_include_path: {
const sub_path = switch (s) {
.src_path => |sp| sp.sub_path,
- .path => |path| path,
- .generated, .generated_dirname => break :default_include_path,
+ .generated => break :default_include_path,
.cwd_relative => |sub_path| sub_path,
.dependency => |dependency| dependency.sub_path,
};
@@ -106,7 +105,7 @@ pub fn addValues(config_header: *ConfigHeader, values: anytype) void {
}
pub fn getOutput(config_header: *ConfigHeader) std.Build.LazyPath {
- return .{ .generated = &config_header.output_file };
+ return .{ .generated = .{ .file = &config_header.output_file } };
}
fn addValuesInner(config_header: *ConfigHeader, values: anytype) !void {
lib/std/Build/Step/ObjCopy.zig
@@ -84,10 +84,10 @@ pub fn create(
pub const getOutputSource = getOutput;
pub fn getOutput(objcopy: *const ObjCopy) std.Build.LazyPath {
- return .{ .generated = &objcopy.output_file };
+ return .{ .generated = .{ .file = &objcopy.output_file } };
}
pub fn getOutputSeparatedDebug(objcopy: *const ObjCopy) ?std.Build.LazyPath {
- return if (objcopy.output_file_debug) |*file| .{ .generated = file } else null;
+ return if (objcopy.output_file_debug) |*file| .{ .generated = .{ .file = file } } else null;
}
fn make(step: *Step, prog_node: *std.Progress.Node) !void {
lib/std/Build/Step/Options.zig
@@ -407,7 +407,7 @@ pub const getSource = getOutput;
/// Returns the main artifact of this Build Step which is a Zig source file
/// generated from the key-value pairs of the Options.
pub fn getOutput(options: *Options) LazyPath {
- return .{ .generated = &options.generated_file };
+ return .{ .generated = .{ .file = &options.generated_file } };
}
fn make(step: *Step, prog_node: *std.Progress.Node) !void {
lib/std/Build/Step/Run.zig
@@ -125,7 +125,8 @@ pub const Arg = union(enum) {
lazy_path: PrefixedLazyPath,
directory_source: PrefixedLazyPath,
bytes: []u8,
- output: *Output,
+ output_file: *Output,
+ output_directory: *Output,
};
pub const PrefixedLazyPath = struct {
@@ -225,13 +226,13 @@ pub fn addPrefixedOutputFileArg(
.basename = b.dupe(basename),
.generated_file = .{ .step = &run.step },
};
- run.argv.append(b.allocator, .{ .output = output }) catch @panic("OOM");
+ run.argv.append(b.allocator, .{ .output_file = output }) catch @panic("OOM");
if (run.rename_step_with_output_arg) {
run.setName(b.fmt("{s} ({s})", .{ run.step.name, basename }));
}
- return .{ .generated = &output.generated_file };
+ return .{ .generated = .{ .file = &output.generated_file } };
}
/// Appends an input file to the command line arguments.
@@ -270,6 +271,56 @@ pub fn addPrefixedFileArg(run: *Run, prefix: []const u8, lp: std.Build.LazyPath)
lp.addStepDependencies(&run.step);
}
+/// Provides a directory path as a command line argument to the command being run.
+///
+/// Returns a `std.Build.LazyPath` which can be used as inputs to other APIs
+/// throughout the build system.
+///
+/// Related:
+/// * `addPrefixedOutputDirectoryArg` - same thing but prepends a string to the argument
+/// * `addDirectoryArg` - for input directories given to the child process
+pub fn addOutputDirectoryArg(run: *Run, basename: []const u8) std.Build.LazyPath {
+ return run.addPrefixedOutputDirectoryArg("", basename);
+}
+
+/// Provides a directory path as a command line argument to the command being run.
+/// Asserts `basename` is not empty.
+///
+/// For example, a prefix of "-o" and basename of "output_dir" will result in
+/// the child process seeing something like this: "-ozig-cache/.../output_dir"
+///
+/// The child process will see a single argument, regardless of whether the
+/// prefix or basename have spaces.
+///
+/// The returned `std.Build.LazyPath` can be used as inputs to other APIs
+/// throughout the build system.
+///
+/// Related:
+/// * `addOutputDirectoryArg` - same thing but without the prefix
+/// * `addDirectoryArg` - for input directories given to the child process
+pub fn addPrefixedOutputDirectoryArg(
+ run: *Run,
+ prefix: []const u8,
+ basename: []const u8,
+) std.Build.LazyPath {
+ if (basename.len == 0) @panic("basename must not be empty");
+ const b = run.step.owner;
+
+ const output = b.allocator.create(Output) catch @panic("OOM");
+ output.* = .{
+ .prefix = b.dupe(prefix),
+ .basename = b.dupe(basename),
+ .generated_file = .{ .step = &run.step },
+ };
+ run.argv.append(b.allocator, .{ .output_directory = output }) catch @panic("OOM");
+
+ if (run.rename_step_with_output_arg) {
+ run.setName(b.fmt("{s} ({s})", .{ run.step.name, basename }));
+ }
+
+ return .{ .generated = .{ .file = &output.generated_file } };
+}
+
/// deprecated: use `addDirectoryArg`
pub const addDirectorySourceArg = addDirectoryArg;
@@ -314,9 +365,9 @@ pub fn addPrefixedDepFileOutputArg(run: *Run, prefix: []const u8, basename: []co
run.dep_output_file = dep_file;
- run.argv.append(b.allocator, .{ .output = dep_file }) catch @panic("OOM");
+ run.argv.append(b.allocator, .{ .output_file = dep_file }) catch @panic("OOM");
- return .{ .generated = &dep_file.generated_file };
+ return .{ .generated = .{ .file = &dep_file.generated_file } };
}
pub fn addArg(run: *Run, arg: []const u8) void {
@@ -432,7 +483,7 @@ pub fn addCheck(run: *Run, new_check: StdIo.Check) void {
pub fn captureStdErr(run: *Run) std.Build.LazyPath {
assert(run.stdio != .inherit);
- if (run.captured_stderr) |output| return .{ .generated = &output.generated_file };
+ if (run.captured_stderr) |output| return .{ .generated = .{ .file = &output.generated_file } };
const output = run.step.owner.allocator.create(Output) catch @panic("OOM");
output.* = .{
@@ -441,13 +492,13 @@ pub fn captureStdErr(run: *Run) std.Build.LazyPath {
.generated_file = .{ .step = &run.step },
};
run.captured_stderr = output;
- return .{ .generated = &output.generated_file };
+ return .{ .generated = .{ .file = &output.generated_file } };
}
pub fn captureStdOut(run: *Run) std.Build.LazyPath {
assert(run.stdio != .inherit);
- if (run.captured_stdout) |output| return .{ .generated = &output.generated_file };
+ if (run.captured_stdout) |output| return .{ .generated = .{ .file = &output.generated_file } };
const output = run.step.owner.allocator.create(Output) catch @panic("OOM");
output.* = .{
@@ -456,7 +507,7 @@ pub fn captureStdOut(run: *Run) std.Build.LazyPath {
.generated_file = .{ .step = &run.step },
};
run.captured_stdout = output;
- return .{ .generated = &output.generated_file };
+ return .{ .generated = .{ .file = &output.generated_file } };
}
/// Adds an additional input files that, when modified, indicates that this Run
@@ -484,7 +535,7 @@ fn hasAnyOutputArgs(run: Run) bool {
if (run.captured_stdout != null) return true;
if (run.captured_stderr != null) return true;
for (run.argv.items) |arg| switch (arg) {
- .output => return true,
+ .output_file, .output_directory => return true,
else => continue,
};
return false;
@@ -520,6 +571,7 @@ fn checksContainStderr(checks: []const StdIo.Check) bool {
const IndexedOutput = struct {
index: usize,
+ tag: @typeInfo(Arg).Union.tag_type.?,
output: *Output,
};
fn make(step: *Step, prog_node: *std.Progress.Node) !void {
@@ -563,17 +615,18 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
_ = try man.addFile(file_path, null);
},
- .output => |output| {
+ .output_file, .output_directory => |output| {
man.hash.addBytes(output.prefix);
man.hash.addBytes(output.basename);
// Add a placeholder into the argument list because we need the
// manifest hash to be updated with all arguments before the
// object directory is computed.
- try argv_list.append("");
try output_placeholders.append(.{
- .index = argv_list.items.len - 1,
+ .index = argv_list.items.len,
+ .tag = arg,
.output = output,
});
+ _ = try argv_list.addOne();
},
}
}
@@ -599,11 +652,6 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
hashStdIo(&man.hash, run.stdio);
- if (has_side_effects) {
- try runCommand(run, argv_list.items, has_side_effects, null, prog_node);
- return;
- }
-
for (run.extra_file_dependencies) |file_path| {
_ = try man.addFile(b.pathFromRoot(file_path), null);
}
@@ -611,7 +659,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
_ = try man.addFile(lazy_path.getPath2(b, step), null);
}
- if (try step.cacheHit(&man)) {
+ if (try step.cacheHit(&man) and !has_side_effects) {
// cache hit, skip running command
const digest = man.final();
@@ -628,13 +676,54 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
return;
}
+ const dep_output_file = run.dep_output_file orelse {
+ // We already know the final output paths, use them directly.
+ const digest = man.final();
+
+ try populateGeneratedPaths(
+ arena,
+ output_placeholders.items,
+ run.captured_stdout,
+ run.captured_stderr,
+ b.cache_root,
+ &digest,
+ );
+
+ const output_dir_path = "o" ++ fs.path.sep_str ++ &digest;
+ for (output_placeholders.items) |placeholder| {
+ const output_sub_path = b.pathJoin(&.{ output_dir_path, placeholder.output.basename });
+ const output_sub_dir_path = switch (placeholder.tag) {
+ .output_file => fs.path.dirname(output_sub_path).?,
+ .output_directory => output_sub_path,
+ else => unreachable,
+ };
+ b.cache_root.handle.makePath(output_sub_dir_path) catch |err| {
+ return step.fail("unable to make path '{}{s}': {s}", .{
+ b.cache_root, output_sub_dir_path, @errorName(err),
+ });
+ };
+ const output_path = placeholder.output.generated_file.path.?;
+ argv_list.items[placeholder.index] = if (placeholder.output.prefix.len == 0)
+ output_path
+ else
+ b.fmt("{s}{s}", .{ placeholder.output.prefix, output_path });
+ }
+
+ return runCommand(run, argv_list.items, has_side_effects, output_dir_path, prog_node);
+ };
+
+ // We do not know the final output paths yet, use temp paths to run the command.
const rand_int = std.crypto.random.int(u64);
const tmp_dir_path = "tmp" ++ fs.path.sep_str ++ std.Build.hex64(rand_int);
for (output_placeholders.items) |placeholder| {
const output_components = .{ tmp_dir_path, placeholder.output.basename };
const output_sub_path = b.pathJoin(&output_components);
- const output_sub_dir_path = fs.path.dirname(output_sub_path).?;
+ const output_sub_dir_path = switch (placeholder.tag) {
+ .output_file => fs.path.dirname(output_sub_path).?,
+ .output_directory => output_sub_path,
+ else => unreachable,
+ };
b.cache_root.handle.makePath(output_sub_dir_path) catch |err| {
return step.fail("unable to make path '{}{s}': {s}", .{
b.cache_root, output_sub_dir_path, @errorName(err),
@@ -642,17 +731,15 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
};
const output_path = try b.cache_root.join(arena, &output_components);
placeholder.output.generated_file.path = output_path;
- const cli_arg = if (placeholder.output.prefix.len == 0)
+ argv_list.items[placeholder.index] = if (placeholder.output.prefix.len == 0)
output_path
else
b.fmt("{s}{s}", .{ placeholder.output.prefix, output_path });
- argv_list.items[placeholder.index] = cli_arg;
}
try runCommand(run, argv_list.items, has_side_effects, tmp_dir_path, prog_node);
- if (run.dep_output_file) |dep_output_file|
- try man.addDepFilePost(std.fs.cwd(), dep_output_file.generated_file.getPath());
+ try man.addDepFilePost(std.fs.cwd(), dep_output_file.generated_file.getPath());
const digest = man.final();
@@ -777,7 +864,7 @@ fn runCommand(
run: *Run,
argv: []const []const u8,
has_side_effects: bool,
- tmp_dir_path: ?[]const u8,
+ output_dir_path: []const u8,
prog_node: *std.Progress.Node,
) !void {
const step = &run.step;
@@ -950,7 +1037,7 @@ fn runCommand(
},
}) |stream| {
if (stream.captured) |output| {
- const output_components = .{ tmp_dir_path.?, output.basename };
+ const output_components = .{ output_dir_path, output.basename };
const output_path = try b.cache_root.join(arena, &output_components);
output.generated_file.path = output_path;
lib/std/Build/Step/TranslateC.zig
@@ -59,7 +59,7 @@ pub const AddExecutableOptions = struct {
};
pub fn getOutput(translate_c: *TranslateC) std.Build.LazyPath {
- return .{ .generated = &translate_c.output_file };
+ return .{ .generated = .{ .file = &translate_c.output_file } };
}
/// Creates a step to build an executable from the translated source.
lib/std/Build/Step/WriteFile.zig
@@ -31,7 +31,7 @@ pub const File = struct {
contents: Contents,
pub fn getPath(file: *File) std.Build.LazyPath {
- return .{ .generated = &file.generated_file };
+ return .{ .generated = .{ .file = &file.generated_file } };
}
};
@@ -58,7 +58,7 @@ pub const Directory = struct {
};
pub fn getPath(dir: *Directory) std.Build.LazyPath {
- return .{ .generated = &dir.generated_dir };
+ return .{ .generated = .{ .file = &dir.generated_dir } };
}
};
@@ -181,7 +181,7 @@ pub fn addBytesToSource(write_file: *WriteFile, bytes: []const u8, sub_path: []c
/// Returns a `LazyPath` representing the base directory that contains all the
/// files from this `WriteFile`.
pub fn getDirectory(write_file: *WriteFile) std.Build.LazyPath {
- return .{ .generated = &write_file.generated_directory };
+ return .{ .generated = .{ .file = &write_file.generated_directory } };
}
fn maybeUpdateName(write_file: *WriteFile) void {
lib/std/Build.zig
@@ -2131,28 +2131,23 @@ test dirnameAllowEmpty {
/// A reference to an existing or future path.
pub const LazyPath = union(enum) {
- /// Deprecated; use the `path` function instead.
- path: []const u8,
-
/// A source file path relative to build root.
src_path: struct {
owner: *std.Build,
sub_path: []const u8,
},
- /// A file that is generated by an interface. Those files usually are
- /// not available until built by a build step.
- generated: *const GeneratedFile,
-
- /// One of the parent directories of a file generated by an interface.
- /// The path is not available until built by a build step.
- generated_dirname: struct {
- generated: *const GeneratedFile,
+ generated: struct {
+ file: *const GeneratedFile,
/// The number of parent directories to go up.
- /// 0 means the directory of the generated file,
- /// 1 means the parent of that directory, and so on.
- up: usize,
+ /// 0 means the generated file itself.
+ /// 1 means the directory of the generated file.
+ /// 2 means the parent of that directory, and so on.
+ up: usize = 0,
+
+ /// Applied after `up`.
+ sub_path: []const u8 = "",
},
/// An absolute path or a path relative to the current working directory of
@@ -2168,12 +2163,6 @@ pub const LazyPath = union(enum) {
sub_path: []const u8,
},
- /// Deprecated. Call `path` instead.
- pub fn relative(sub_path: []const u8) LazyPath {
- std.log.warn("deprecated. call std.Build.path instead", .{});
- return .{ .path = sub_path };
- }
-
/// Returns a lazy path referring to the directory containing this path.
///
/// The dirname is not allowed to escape the logical root for underlying path.
@@ -2183,8 +2172,6 @@ pub const LazyPath = union(enum) {
/// the dirname is not allowed to traverse outside of zig-cache.
pub fn dirname(lazy_path: LazyPath) LazyPath {
return switch (lazy_path) {
- .generated => |gen| .{ .generated_dirname = .{ .generated = gen, .up = 0 } },
- .generated_dirname => |gen| .{ .generated_dirname = .{ .generated = gen.generated, .up = gen.up + 1 } },
.src_path => |sp| .{ .src_path = .{
.owner = sp.owner,
.sub_path = dirnameAllowEmpty(sp.sub_path) orelse {
@@ -2192,12 +2179,15 @@ pub const LazyPath = union(enum) {
@panic("misconfigured build script");
},
} },
- .path => |sub_path| .{
- .path = dirnameAllowEmpty(sub_path) orelse {
- dumpBadDirnameHelp(null, null, "dirname() attempted to traverse outside the build root\n", .{}) catch {};
- @panic("misconfigured build script");
- },
- },
+ .generated => |generated| .{ .generated = if (dirnameAllowEmpty(generated.sub_path)) |sub_dirname| .{
+ .file = generated.file,
+ .up = generated.up,
+ .sub_path = sub_dirname,
+ } else .{
+ .file = generated.file,
+ .up = generated.up + 1,
+ .sub_path = "",
+ } },
.cwd_relative => |rel_path| .{
.cwd_relative = dirnameAllowEmpty(rel_path) orelse {
// If we get null, it means one of two things:
@@ -2234,14 +2224,34 @@ pub const LazyPath = union(enum) {
};
}
+ pub fn path(lazy_path: LazyPath, b: *Build, sub_path: []const u8) LazyPath {
+ return switch (lazy_path) {
+ .src_path => |src| .{ .src_path = .{
+ .owner = src.owner,
+ .sub_path = b.pathResolve(&.{ src.sub_path, sub_path }),
+ } },
+ .generated => |gen| .{ .generated = .{
+ .file = gen.file,
+ .up = gen.up,
+ .sub_path = b.pathResolve(&.{ gen.sub_path, sub_path }),
+ } },
+ .cwd_relative => |cwd_relative| .{
+ .cwd_relative = b.pathResolve(&.{ cwd_relative, sub_path }),
+ },
+ .dependency => |dep| .{ .dependency = .{
+ .dependency = dep.dependency,
+ .sub_path = b.pathResolve(&.{ dep.sub_path, sub_path }),
+ } },
+ };
+ }
+
/// Returns a string that can be shown to represent the file source.
- /// Either returns the path or `"generated"`.
+ /// Either returns the path, `"generated"`, or `"dependency"`.
pub fn getDisplayName(lazy_path: LazyPath) []const u8 {
return switch (lazy_path) {
- .src_path => |src_path| src_path.sub_path,
- .path, .cwd_relative => |sub_path| sub_path,
+ .src_path => |sp| sp.sub_path,
+ .cwd_relative => |p| p,
.generated => "generated",
- .generated_dirname => "generated",
.dependency => "dependency",
};
}
@@ -2249,9 +2259,8 @@ pub const LazyPath = union(enum) {
/// Adds dependencies this file source implies to the given step.
pub fn addStepDependencies(lazy_path: LazyPath, other_step: *Step) void {
switch (lazy_path) {
- .src_path, .path, .cwd_relative, .dependency => {},
- .generated => |gen| other_step.dependOn(gen.step),
- .generated_dirname => |gen| other_step.dependOn(gen.generated.step),
+ .src_path, .cwd_relative, .dependency => {},
+ .generated => |gen| other_step.dependOn(gen.file.step),
}
}
@@ -2268,47 +2277,48 @@ pub const LazyPath = union(enum) {
/// run that is asking for the path.
pub fn getPath2(lazy_path: LazyPath, src_builder: *Build, asking_step: ?*Step) []const u8 {
switch (lazy_path) {
- .path => |p| return src_builder.pathFromRoot(p),
.src_path => |sp| return sp.owner.pathFromRoot(sp.sub_path),
.cwd_relative => |p| return src_builder.pathFromCwd(p),
- .generated => |gen| return gen.step.owner.pathFromRoot(gen.path orelse {
- std.debug.getStderrMutex().lock();
- const stderr = std.io.getStdErr();
- dumpBadGetPathHelp(gen.step, stderr, src_builder, asking_step) catch {};
- @panic("misconfigured build script");
- }),
- .generated_dirname => |gen| {
- const cache_root_path = src_builder.cache_root.path orelse
- (src_builder.cache_root.join(src_builder.allocator, &.{"."}) catch @panic("OOM"));
-
- const gen_step = gen.generated.step;
- var p = getPath2(LazyPath{ .generated = gen.generated }, src_builder, asking_step);
- var i: usize = 0;
- while (i <= gen.up) : (i += 1) {
- // path is absolute.
- // dirname will return null only if we're at root.
- // Typically, we'll stop well before that at the cache root.
- p = fs.path.dirname(p) orelse {
- dumpBadDirnameHelp(gen_step, asking_step,
- \\dirname() reached root.
- \\No more directories left to go up.
- \\
- , .{}) catch {};
- @panic("misconfigured build script");
- };
-
- if (mem.eql(u8, p, cache_root_path) and i < gen.up) {
- // If we hit the cache root and there's still more to go,
- // the script attempted to go too far.
- dumpBadDirnameHelp(gen_step, asking_step,
- \\dirname() attempted to traverse outside the cache root.
- \\This is not allowed.
- \\
- , .{}) catch {};
- @panic("misconfigured build script");
+ .generated => |gen| {
+ var file_path: []const u8 = gen.file.step.owner.pathFromRoot(gen.file.path orelse {
+ std.debug.getStderrMutex().lock();
+ const stderr = std.io.getStdErr();
+ dumpBadGetPathHelp(gen.file.step, stderr, src_builder, asking_step) catch {};
+ std.debug.getStderrMutex().unlock();
+ @panic("misconfigured build script");
+ });
+
+ if (gen.up > 0) {
+ const cache_root_path = src_builder.cache_root.path orelse
+ (src_builder.cache_root.join(src_builder.allocator, &.{"."}) catch @panic("OOM"));
+
+ for (0..gen.up) |_| {
+ if (mem.eql(u8, file_path, cache_root_path)) {
+ // If we hit the cache root and there's still more to go,
+ // the script attempted to go too far.
+ dumpBadDirnameHelp(gen.file.step, asking_step,
+ \\dirname() attempted to traverse outside the cache root.
+ \\This is not allowed.
+ \\
+ , .{}) catch {};
+ @panic("misconfigured build script");
+ }
+
+ // path is absolute.
+ // dirname will return null only if we're at root.
+ // Typically, we'll stop well before that at the cache root.
+ file_path = fs.path.dirname(file_path) orelse {
+ dumpBadDirnameHelp(gen.file.step, asking_step,
+ \\dirname() reached root.
+ \\No more directories left to go up.
+ \\
+ , .{}) catch {};
+ @panic("misconfigured build script");
+ };
}
}
- return p;
+
+ return src_builder.pathResolve(&.{ file_path, gen.sub_path });
},
.dependency => |dep| return dep.dependency.builder.pathFromRoot(dep.sub_path),
}
@@ -2324,15 +2334,12 @@ pub const LazyPath = union(enum) {
.owner = sp.owner,
.sub_path = sp.owner.dupePath(sp.sub_path),
} },
- .path => |p| .{ .path = b.dupePath(p) },
.cwd_relative => |p| .{ .cwd_relative = b.dupePath(p) },
- .generated => |gen| .{ .generated = gen },
- .generated_dirname => |gen| .{
- .generated_dirname = .{
- .generated = gen.generated,
- .up = gen.up,
- },
- },
+ .generated => |gen| .{ .generated = .{
+ .file = gen.file,
+ .up = gen.up,
+ .sub_path = b.dupePath(gen.sub_path),
+ } },
.dependency => |dep| .{ .dependency = dep },
};
}
test/standalone/run_output_paths/build.zig
@@ -0,0 +1,40 @@
+const std = @import("std");
+
+pub fn build(b: *std.Build) void {
+ const test_step = b.step("test", "Test it");
+ b.default_step = test_step;
+
+ const target = b.standardTargetOptions(.{});
+ const optimize = b.standardOptimizeOption(.{});
+
+ const create_file_exe = b.addExecutable(.{
+ .name = "create_file",
+ .root_source_file = b.path("create_file.zig"),
+ .target = target,
+ .optimize = optimize,
+ });
+
+ const create_first = b.addRunArtifact(create_file_exe);
+ const first_dir = create_first.addOutputDirectoryArg("first");
+ create_first.addArg("hello1.txt");
+ test_step.dependOn(&b.addCheckFile(first_dir.path(b, "hello1.txt"), .{ .expected_matches = &.{
+ std.fs.path.sep_str ++
+ \\first
+ \\hello1.txt
+ \\Hello, world!
+ \\
+ ,
+ } }).step);
+
+ const create_second = b.addRunArtifact(create_file_exe);
+ const second_dir = create_second.addPrefixedOutputDirectoryArg("--dir=", "second");
+ create_second.addArg("hello2.txt");
+ test_step.dependOn(&b.addCheckFile(second_dir.path(b, "hello2.txt"), .{ .expected_matches = &.{
+ std.fs.path.sep_str ++
+ \\second
+ \\hello2.txt
+ \\Hello, world!
+ \\
+ ,
+ } }).step);
+}
test/standalone/run_output_paths/create_file.zig
@@ -0,0 +1,19 @@
+const std = @import("std");
+
+pub fn main() !void {
+ var args = try std.process.argsWithAllocator(std.heap.page_allocator);
+ _ = args.skip();
+ const dir_name = args.next().?;
+ const dir = try std.fs.cwd().openDir(if (std.mem.startsWith(u8, dir_name, "--dir="))
+ dir_name["--dir=".len..]
+ else
+ dir_name, .{});
+ const file_name = args.next().?;
+ const file = try dir.createFile(file_name, .{});
+ try file.writer().print(
+ \\{s}
+ \\{s}
+ \\Hello, world!
+ \\
+ , .{ dir_name, file_name });
+}
test/standalone/windows_resources/build.zig
@@ -36,7 +36,7 @@ fn add(
.file = b.path("res/zig.rc"),
.flags = &.{"/c65001"}, // UTF-8 code page
.include_paths = &.{
- .{ .generated = &generated_h_step.generated_directory },
+ .{ .generated = .{ .file = &generated_h_step.generated_directory } },
},
});
exe.rc_includes = switch (rc_includes) {
test/standalone/build.zig.zon
@@ -164,6 +164,9 @@
.dependencyFromBuildZig = .{
.path = "dependencyFromBuildZig",
},
+ .run_output_paths = .{
+ .path = "run_output_paths",
+ },
},
.paths = .{
"build.zig",