aboutsummaryrefslogtreecommitdiff
path: root/lib/std/Build
diff options
context:
space:
mode:
authorJacob Young <jacobly0@users.noreply.github.com>2025-06-13 12:01:59 -0400
committerJacob Young <jacobly0@users.noreply.github.com>2025-06-19 11:45:06 -0400
commit16d78bc0c024da307c7ab5f6b94622e6b4b37397 (patch)
tree9eb0e671a4ac1cfaf3795384d4b4e7d050d017d2 /lib/std/Build
parentdf4068cabd9af96d0aca1f435b985d1c103976da (diff)
downloadzig-16d78bc0c024da307c7ab5f6b94622e6b4b37397.tar.gz
zig-16d78bc0c024da307c7ab5f6b94622e6b4b37397.zip
Build: add install commands to `--verbose` output
Diffstat (limited to 'lib/std/Build')
-rw-r--r--lib/std/Build/Step.zig71
-rw-r--r--lib/std/Build/Step/Compile.zig1
-rw-r--r--lib/std/Build/Step/InstallArtifact.zig55
-rw-r--r--lib/std/Build/Step/InstallDir.zig38
-rw-r--r--lib/std/Build/Step/InstallFile.zig10
-rw-r--r--lib/std/Build/Step/ObjCopy.zig2
-rw-r--r--lib/std/Build/Step/Run.zig23
7 files changed, 115 insertions, 85 deletions
diff --git a/lib/std/Build/Step.zig b/lib/std/Build/Step.zig
index 9cf0ca475e..9d4802fbbc 100644
--- a/lib/std/Build/Step.zig
+++ b/lib/std/Build/Step.zig
@@ -478,6 +478,29 @@ pub fn evalZigProcess(
return result;
}
+/// Wrapper around `std.fs.Dir.updateFile` that handles verbose and error output.
+pub fn installFile(s: *Step, src_lazy_path: Build.LazyPath, dest_path: []const u8) !std.fs.Dir.PrevStatus {
+ const b = s.owner;
+ const src_path = src_lazy_path.getPath3(b, s);
+ try handleVerbose(b, null, &.{ "install", "-C", b.fmt("{}", .{src_path}), dest_path });
+ return src_path.root_dir.handle.updateFile(src_path.sub_path, std.fs.cwd(), dest_path, .{}) catch |err| {
+ return s.fail("unable to update file from '{}' to '{s}': {s}", .{
+ src_path, dest_path, @errorName(err),
+ });
+ };
+}
+
+/// Wrapper around `std.fs.Dir.makePathStatus` that handles verbose and error output.
+pub fn installDir(s: *Step, dest_path: []const u8) !std.fs.Dir.MakePathStatus {
+ const b = s.owner;
+ try handleVerbose(b, null, &.{ "install", "-d", dest_path });
+ return std.fs.cwd().makePathStatus(dest_path) catch |err| {
+ return s.fail("unable to create dir '{s}': {s}", .{
+ dest_path, @errorName(err),
+ });
+ };
+}
+
fn zigProcessUpdate(s: *Step, zp: *ZigProcess, watch: bool) !?Path {
const b = s.owner;
const arena = b.allocator;
@@ -714,8 +737,44 @@ pub fn allocPrintCmd2(
opt_env: ?*const std.process.EnvMap,
argv: []const []const u8,
) Allocator.Error![]u8 {
+ const shell = struct {
+ fn escape(writer: anytype, string: []const u8, is_argv0: bool) !void {
+ for (string) |c| {
+ if (switch (c) {
+ else => true,
+ '%', '+'...':', '@'...'Z', '_', 'a'...'z' => false,
+ '=' => is_argv0,
+ }) break;
+ } else return writer.writeAll(string);
+
+ try writer.writeByte('"');
+ for (string) |c| {
+ if (switch (c) {
+ std.ascii.control_code.nul => break,
+ '!', '"', '$', '\\', '`' => true,
+ else => !std.ascii.isPrint(c),
+ }) try writer.writeByte('\\');
+ switch (c) {
+ std.ascii.control_code.nul => unreachable,
+ std.ascii.control_code.bel => try writer.writeByte('a'),
+ std.ascii.control_code.bs => try writer.writeByte('b'),
+ std.ascii.control_code.ht => try writer.writeByte('t'),
+ std.ascii.control_code.lf => try writer.writeByte('n'),
+ std.ascii.control_code.vt => try writer.writeByte('v'),
+ std.ascii.control_code.ff => try writer.writeByte('f'),
+ std.ascii.control_code.cr => try writer.writeByte('r'),
+ std.ascii.control_code.esc => try writer.writeByte('E'),
+ ' '...'~' => try writer.writeByte(c),
+ else => try writer.print("{o:0>3}", .{c}),
+ }
+ }
+ try writer.writeByte('"');
+ }
+ };
+
var buf: std.ArrayListUnmanaged(u8) = .empty;
- if (opt_cwd) |cwd| try buf.writer(arena).print("cd {s} && ", .{cwd});
+ const writer = buf.writer(arena);
+ if (opt_cwd) |cwd| try writer.print("cd {s} && ", .{cwd});
if (opt_env) |env| {
const process_env_map = std.process.getEnvMap(arena) catch std.process.EnvMap.init(arena);
var it = env.iterator();
@@ -725,11 +784,15 @@ pub fn allocPrintCmd2(
if (process_env_map.get(key)) |process_value| {
if (std.mem.eql(u8, value, process_value)) continue;
}
- try buf.writer(arena).print("{s}={s} ", .{ key, value });
+ try writer.print("{s}=", .{key});
+ try shell.escape(writer, value, false);
+ try writer.writeByte(' ');
}
}
- for (argv) |arg| {
- try buf.writer(arena).print("{s} ", .{arg});
+ try shell.escape(writer, argv[0], true);
+ for (argv[1..]) |arg| {
+ try writer.writeByte(' ');
+ try shell.escape(writer, arg, false);
}
return buf.toOwnedSlice(arena);
}
diff --git a/lib/std/Build/Step/Compile.zig b/lib/std/Build/Step/Compile.zig
index fa84ac5e6e..e10840db75 100644
--- a/lib/std/Build/Step/Compile.zig
+++ b/lib/std/Build/Step/Compile.zig
@@ -668,6 +668,7 @@ pub fn producesPdbFile(compile: *Compile) bool {
else => return false,
}
if (target.ofmt == .c) return false;
+ if (compile.use_llvm == false) return false;
if (compile.root_module.strip == true or
(compile.root_module.strip == null and compile.root_module.optimize == .ReleaseSmall))
{
diff --git a/lib/std/Build/Step/InstallArtifact.zig b/lib/std/Build/Step/InstallArtifact.zig
index 9d8cb92bb7..6a5b834cae 100644
--- a/lib/std/Build/Step/InstallArtifact.zig
+++ b/lib/std/Build/Step/InstallArtifact.zig
@@ -119,18 +119,12 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
_ = options;
const install_artifact: *InstallArtifact = @fieldParentPtr("step", step);
const b = step.owner;
- const cwd = fs.cwd();
var all_cached = true;
if (install_artifact.dest_dir) |dest_dir| {
const full_dest_path = b.getInstallPath(dest_dir, install_artifact.dest_sub_path);
- const src_path = install_artifact.emitted_bin.?.getPath3(b, step);
- const p = fs.Dir.updateFile(src_path.root_dir.handle, src_path.sub_path, cwd, full_dest_path, .{}) catch |err| {
- return step.fail("unable to update file from '{s}' to '{s}': {s}", .{
- src_path.sub_path, full_dest_path, @errorName(err),
- });
- };
+ const p = try step.installFile(install_artifact.emitted_bin.?, full_dest_path);
all_cached = all_cached and p == .fresh;
if (install_artifact.dylib_symlinks) |dls| {
@@ -141,48 +135,28 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
}
if (install_artifact.implib_dir) |implib_dir| {
- const src_path = install_artifact.emitted_implib.?.getPath3(b, step);
- const full_implib_path = b.getInstallPath(implib_dir, fs.path.basename(src_path.sub_path));
- const p = fs.Dir.updateFile(src_path.root_dir.handle, src_path.sub_path, cwd, full_implib_path, .{}) catch |err| {
- return step.fail("unable to update file from '{s}' to '{s}': {s}", .{
- src_path.sub_path, full_implib_path, @errorName(err),
- });
- };
+ const full_implib_path = b.getInstallPath(implib_dir, install_artifact.emitted_implib.?.basename(b, step));
+ const p = try step.installFile(install_artifact.emitted_implib.?, full_implib_path);
all_cached = all_cached and p == .fresh;
}
if (install_artifact.pdb_dir) |pdb_dir| {
- const src_path = install_artifact.emitted_pdb.?.getPath3(b, step);
- const full_pdb_path = b.getInstallPath(pdb_dir, fs.path.basename(src_path.sub_path));
- const p = fs.Dir.updateFile(src_path.root_dir.handle, src_path.sub_path, cwd, full_pdb_path, .{}) catch |err| {
- return step.fail("unable to update file from '{s}' to '{s}': {s}", .{
- src_path.sub_path, full_pdb_path, @errorName(err),
- });
- };
+ const full_pdb_path = b.getInstallPath(pdb_dir, install_artifact.emitted_pdb.?.basename(b, step));
+ const p = try step.installFile(install_artifact.emitted_pdb.?, full_pdb_path);
all_cached = all_cached and p == .fresh;
}
if (install_artifact.h_dir) |h_dir| {
if (install_artifact.emitted_h) |emitted_h| {
- const src_path = emitted_h.getPath3(b, step);
- const full_h_path = b.getInstallPath(h_dir, fs.path.basename(src_path.sub_path));
- const p = fs.Dir.updateFile(src_path.root_dir.handle, src_path.sub_path, cwd, full_h_path, .{}) catch |err| {
- return step.fail("unable to update file from '{s}' to '{s}': {s}", .{
- src_path.sub_path, full_h_path, @errorName(err),
- });
- };
+ const full_h_path = b.getInstallPath(h_dir, emitted_h.basename(b, step));
+ const p = try step.installFile(emitted_h, full_h_path);
all_cached = all_cached and p == .fresh;
}
for (install_artifact.artifact.installed_headers.items) |installation| switch (installation) {
.file => |file| {
- const src_path = file.source.getPath3(b, step);
const full_h_path = b.getInstallPath(h_dir, file.dest_rel_path);
- const p = fs.Dir.updateFile(src_path.root_dir.handle, src_path.sub_path, cwd, full_h_path, .{}) catch |err| {
- return step.fail("unable to update file from '{s}' to '{s}': {s}", .{
- src_path.sub_path, full_h_path, @errorName(err),
- });
- };
+ const p = try step.installFile(file.source, full_h_path);
all_cached = all_cached and p == .fresh;
},
.directory => |dir| {
@@ -209,16 +183,15 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
}
}
- const src_entry_path = src_dir_path.join(b.allocator, entry.path) catch @panic("OOM");
const full_dest_path = b.pathJoin(&.{ full_h_prefix, entry.path });
switch (entry.kind) {
- .directory => try cwd.makePath(full_dest_path),
+ .directory => {
+ try Step.handleVerbose(b, null, &.{ "install", "-d", full_dest_path });
+ const p = try step.installDir(full_dest_path);
+ all_cached = all_cached and p == .existed;
+ },
.file => {
- const p = fs.Dir.updateFile(src_entry_path.root_dir.handle, src_entry_path.sub_path, cwd, full_dest_path, .{}) catch |err| {
- return step.fail("unable to update file from '{s}' to '{s}': {s}", .{
- src_entry_path.sub_path, full_dest_path, @errorName(err),
- });
- };
+ const p = try step.installFile(try dir.source.join(b.allocator, entry.path), full_dest_path);
all_cached = all_cached and p == .fresh;
},
else => continue,
diff --git a/lib/std/Build/Step/InstallDir.zig b/lib/std/Build/Step/InstallDir.zig
index 4d4ff78cfc..ece1184d8f 100644
--- a/lib/std/Build/Step/InstallDir.zig
+++ b/lib/std/Build/Step/InstallDir.zig
@@ -74,31 +74,23 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
var all_cached = true;
next_entry: while (try it.next()) |entry| {
for (install_dir.options.exclude_extensions) |ext| {
- if (mem.endsWith(u8, entry.path, ext)) {
- continue :next_entry;
- }
+ if (mem.endsWith(u8, entry.path, ext)) continue :next_entry;
}
if (install_dir.options.include_extensions) |incs| {
- var found = false;
for (incs) |inc| {
- if (mem.endsWith(u8, entry.path, inc)) {
- found = true;
- break;
- }
+ if (mem.endsWith(u8, entry.path, inc)) break;
+ } else {
+ continue :next_entry;
}
- if (!found) continue :next_entry;
}
- // relative to src build root
- const src_sub_path = try src_dir_path.join(arena, entry.path);
+ const src_path = try install_dir.options.source_dir.join(b.allocator, entry.path);
const dest_path = b.pathJoin(&.{ dest_prefix, entry.path });
- const cwd = fs.cwd();
-
switch (entry.kind) {
.directory => {
- if (need_derived_inputs) try step.addDirectoryWatchInputFromPath(src_sub_path);
- try cwd.makePath(dest_path);
- // TODO: set result_cached=false if the directory did not already exist.
+ if (need_derived_inputs) _ = try step.addDirectoryWatchInput(src_path);
+ const p = try step.installDir(dest_path);
+ all_cached = all_cached and p == .existed;
},
.file => {
for (install_dir.options.blank_extensions) |ext| {
@@ -108,18 +100,8 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
}
}
- const prev_status = fs.Dir.updateFile(
- src_sub_path.root_dir.handle,
- src_sub_path.sub_path,
- cwd,
- dest_path,
- .{},
- ) catch |err| {
- return step.fail("unable to update file from '{}' to '{s}': {s}", .{
- src_sub_path, dest_path, @errorName(err),
- });
- };
- all_cached = all_cached and prev_status == .fresh;
+ const p = try step.installFile(src_path, dest_path);
+ all_cached = all_cached and p == .fresh;
},
else => continue,
}
diff --git a/lib/std/Build/Step/InstallFile.zig b/lib/std/Build/Step/InstallFile.zig
index fb1c0ffc34..10adb4754d 100644
--- a/lib/std/Build/Step/InstallFile.zig
+++ b/lib/std/Build/Step/InstallFile.zig
@@ -41,13 +41,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
const install_file: *InstallFile = @fieldParentPtr("step", step);
try step.singleUnchangingWatchInput(install_file.source);
- const full_src_path = install_file.source.getPath2(b, step);
const full_dest_path = b.getInstallPath(install_file.dir, install_file.dest_rel_path);
- const cwd = std.fs.cwd();
- const prev = std.fs.Dir.updateFile(cwd, full_src_path, cwd, full_dest_path, .{}) catch |err| {
- return step.fail("unable to update file from '{s}' to '{s}': {s}", .{
- full_src_path, full_dest_path, @errorName(err),
- });
- };
- step.result_cached = prev == .fresh;
+ const p = try step.installFile(install_file.source, full_dest_path);
+ step.result_cached = p == .fresh;
}
diff --git a/lib/std/Build/Step/ObjCopy.zig b/lib/std/Build/Step/ObjCopy.zig
index 9b2c2d596f..74f871d2fc 100644
--- a/lib/std/Build/Step/ObjCopy.zig
+++ b/lib/std/Build/Step/ObjCopy.zig
@@ -209,7 +209,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
}
if (objcopy.add_section) |section| {
try argv.append("--add-section");
- try argv.appendSlice(&.{b.fmt("{s}={s}", .{ section.section_name, section.file_path.getPath(b) })});
+ try argv.appendSlice(&.{b.fmt("{s}={s}", .{ section.section_name, section.file_path.getPath2(b, step) })});
}
if (objcopy.set_section_alignment) |set_align| {
try argv.append("--set-section-alignment");
diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig
index eb5ea1c607..af7f0ee1a9 100644
--- a/lib/std/Build/Step/Run.zig
+++ b/lib/std/Build/Step/Run.zig
@@ -456,11 +456,28 @@ pub fn addPathDir(run: *Run, search_path: []const u8) void {
const b = run.step.owner;
const env_map = getEnvMapInternal(run);
- const key = "PATH";
+ const use_wine = b.enable_wine and b.graph.host.result.os.tag != .windows and use_wine: switch (run.argv.items[0]) {
+ .artifact => |p| p.artifact.rootModuleTarget().os.tag == .windows,
+ .lazy_path => |p| {
+ switch (p.lazy_path) {
+ .generated => |g| if (g.file.step.cast(Step.Compile)) |cs| break :use_wine cs.rootModuleTarget().os.tag == .windows,
+ else => {},
+ }
+ break :use_wine std.mem.endsWith(u8, p.lazy_path.basename(b, &run.step), ".exe");
+ },
+ .decorated_directory => false,
+ .bytes => |bytes| std.mem.endsWith(u8, bytes, ".exe"),
+ .output_file, .output_directory => false,
+ };
+ const key = if (use_wine) "WINEPATH" else "PATH";
const prev_path = env_map.get(key);
if (prev_path) |pp| {
- const new_path = b.fmt("{s}" ++ [1]u8{fs.path.delimiter} ++ "{s}", .{ pp, search_path });
+ const new_path = b.fmt("{s}{c}{s}", .{
+ pp,
+ if (use_wine) fs.path.delimiter_windows else fs.path.delimiter,
+ search_path,
+ });
env_map.put(key, new_path) catch @panic("OOM");
} else {
env_map.put(key, b.dupePath(search_path)) catch @panic("OOM");
@@ -866,7 +883,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void {
try runCommand(run, argv_list.items, has_side_effects, tmp_dir_path, prog_node, null);
const dep_file_dir = std.fs.cwd();
- const dep_file_basename = dep_output_file.generated_file.getPath();
+ const dep_file_basename = dep_output_file.generated_file.getPath2(b, step);
if (has_side_effects)
try man.addDepFile(dep_file_dir, dep_file_basename)
else