diff options
| author | Jacob Young <jacobly0@users.noreply.github.com> | 2025-06-13 12:01:59 -0400 |
|---|---|---|
| committer | Jacob Young <jacobly0@users.noreply.github.com> | 2025-06-19 11:45:06 -0400 |
| commit | 16d78bc0c024da307c7ab5f6b94622e6b4b37397 (patch) | |
| tree | 9eb0e671a4ac1cfaf3795384d4b4e7d050d017d2 /lib/std/Build | |
| parent | df4068cabd9af96d0aca1f435b985d1c103976da (diff) | |
| download | zig-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.zig | 71 | ||||
| -rw-r--r-- | lib/std/Build/Step/Compile.zig | 1 | ||||
| -rw-r--r-- | lib/std/Build/Step/InstallArtifact.zig | 55 | ||||
| -rw-r--r-- | lib/std/Build/Step/InstallDir.zig | 38 | ||||
| -rw-r--r-- | lib/std/Build/Step/InstallFile.zig | 10 | ||||
| -rw-r--r-- | lib/std/Build/Step/ObjCopy.zig | 2 | ||||
| -rw-r--r-- | lib/std/Build/Step/Run.zig | 23 |
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 |
