commit aa0652ff8dc9add09567d69a92ddaff5ad386919 (tree)
parent dd51fc30f884aa1c3305793010a30d826689be89
Author: Andrew Kelley <andrew@ziglang.org>
Date: Tue, 17 Mar 2026 12:18:56 -0700
maker: implement InstallArtifact and InstallFile
Diffstat:
13 files changed, 421 insertions(+), 283 deletions(-)
diff --git a/BRANCH_TODO b/BRANCH_TODO
@@ -1,9 +1,10 @@
-* replace b.dupe() with string internment
+* implement the build options
* don't forget to add -listen arg back
* get zig init template working
* finish migrating the rest of the build steps
* make zig-pkg path root configurable in maker (make sure --system still works)
* eliminate calls to getPath, getPath2, getPath3
+* replace b.dupe() with string internment
* solve the TODOs added in this branch
* get zig tests passing
* test a bunch of third party projects / help people migrate
@@ -13,3 +14,6 @@
## Followup Issues
* link_eh_frame_hdr should be DefaultingBool
* make --foo, --no-foo CLI args uniform (make them -f args instead)
+* install steps should provide generated files for installed things, then delete the run step hack
+
+
diff --git a/lib/compiler/Maker.zig b/lib/compiler/Maker.zig
@@ -7,6 +7,7 @@ const Cache = std.Build.Cache;
const Configuration = std.Build.Configuration;
const File = std.Io.File;
const Io = std.Io;
+const Dir = std.Io.Dir;
const Path = std.Build.Cache.Path;
const Writer = std.Io.Writer;
const assert = std.debug.assert;
@@ -82,7 +83,7 @@ pub fn main(init: process.Init.Minimal) !void {
const global_cache_root = expectArgOrFatal(args, &arg_idx, "--global-cache");
const configure_path = expectArgOrFatal(args, &arg_idx, "--configuration");
- const cwd: Io.Dir = .cwd();
+ const cwd: Dir = .cwd();
const zig_lib_directory: Cache.Directory = .{
.path = zig_lib_dir,
@@ -497,7 +498,7 @@ pub fn main(init: process.Init.Minimal) !void {
const install_prefix_path: Path = if (graph.environ_map.get("DESTDIR")) |dest_dir| .{
.root_dir = .cwd(),
- .sub_path = try Io.Dir.path.join(arena, &.{ dest_dir, override_install_prefix orelse "/usr" }),
+ .sub_path = try Dir.path.join(arena, &.{ dest_dir, override_install_prefix orelse "/usr" }),
} else if (override_install_prefix) |cwd_relative| .{
.root_dir = .cwd(),
.sub_path = cwd_relative,
@@ -1675,7 +1676,7 @@ fn cleanTmpFiles(io: Io, steps: []const Configuration.Step.Index) void {
const wf = step_index.cast(std.Build.Step.WriteFile) orelse continue;
if (wf.mode != .tmp) continue;
const path = wf.generated_directory.path orelse continue;
- Io.Dir.cwd().deleteTree(io, path) catch |err| {
+ Dir.cwd().deleteTree(io, path) catch |err| {
log.warn("failed to delete {s}: {t}", .{ path, err });
};
}
@@ -1699,29 +1700,14 @@ pub fn resolveLazyPath(
) Allocator.Error!Path {
_ = asking_step_index; // TODO use this to enhance debugability when this function fails
const c = &maker.scanned_config.configuration;
- const graph = maker.graph;
return switch (lazy_path) {
.source_path => |sp| try packagePath(maker, arena, sp.owner, sp.sub_path.slice(c)),
- .relative => |relative| switch (relative.flags.base) {
- .cwd => .{
- .root_dir = .cwd(),
- .sub_path = relative.sub_path.slice(c),
- },
- .local_cache => .{
- .root_dir = graph.local_cache_root,
- },
- .global_cache => .{
- .root_dir = graph.global_cache_root,
- },
- .build_root => .{
- .root_dir = graph.build_root_directory,
- },
- },
+ .relative => |relative| relativePath(maker, relative),
.generated => |gen| {
- const base = maker.generated_files[@intFromEnum(gen.index)];
+ const base = generatedPath(maker, gen.index);
var file_path = base;
for (0..gen.flags.up) |_| {
- file_path.sub_path = Io.Dir.path.dirname(file_path.sub_path) orelse
+ file_path.sub_path = Dir.path.dirname(file_path.sub_path) orelse
fatal("invalid LazyPath traversal: up {d} times from {f}", .{ gen.flags.up, base });
}
return file_path.join(arena, gen.sub_path.slice(c));
@@ -1750,7 +1736,7 @@ pub fn resolveLazyPathAbs(
const p = try resolveLazyPath(maker, arena, lazy_path, asking_step_index);
const root_dir_path = p.root_dir.path orelse return p.subPathOrDot();
if (p.sub_path.len == 0) return root_dir_path;
- return Io.Dir.path.join(arena, &.{ root_dir_path, p.sub_path });
+ return Dir.path.join(arena, &.{ root_dir_path, p.sub_path });
}
/// `resolveLazyPath` is preferred, but this can be necessary when passing Path
@@ -1765,11 +1751,11 @@ pub fn resolveLazyPathIndexAbs(
return resolveLazyPathAbs(maker, arena, lazy_path_index.get(c), asking_step_index);
}
-pub fn generatedPath(maker: *Maker, index: Configuration.GeneratedFileIndex) *Path {
+pub fn generatedPath(maker: *const Maker, index: Configuration.GeneratedFileIndex) *Path {
return &maker.generated_files[@intFromEnum(index)];
}
-fn packagePath(
+pub fn packagePath(
maker: *const Maker,
arena: Allocator,
package_index: Configuration.Package.Index,
@@ -1785,43 +1771,183 @@ fn packagePath(
const pkg_root = graph.pkg_root;
return .{
.root_dir = pkg_root.root_dir,
- .sub_path = try Io.Dir.path.join(arena, &.{ pkg_root.sub_path, hash, sub_path }),
+ .sub_path = try Dir.path.join(arena, &.{ pkg_root.sub_path, hash, sub_path }),
+ };
+}
+
+pub fn relativePath(maker: *const Maker, relative: Configuration.LazyPath.Relative) Path {
+ const graph = maker.graph;
+ const c = &maker.scanned_config.configuration;
+ const sub_path = relative.sub_path.slice(c);
+ return switch (relative.flags.base) {
+ .cwd => .{
+ .root_dir = .cwd(),
+ .sub_path = sub_path,
+ },
+ .local_cache => .{
+ .root_dir = graph.local_cache_root,
+ .sub_path = sub_path,
+ },
+ .global_cache => .{
+ .root_dir = graph.global_cache_root,
+ .sub_path = sub_path,
+ },
+ .build_root => .{
+ .root_dir = graph.build_root_directory,
+ .sub_path = sub_path,
+ },
};
}
-/// Wrapper around `Io.Dir.updateFile` that handles verbose and error output.
-pub fn installFile(
+pub fn resolveInstallDir(
maker: *Maker,
arena: Allocator,
- src_lazy_path: Configuration.LazyPath,
- dest_path: []const u8,
+ dest_dir: Configuration.InstallDestDir,
+) Allocator.Error!Path {
+ const c = &maker.scanned_config.configuration;
+ return switch (dest_dir.unpack().?) {
+ .prefix => maker.install_paths.prefix,
+ .lib => maker.install_paths.lib,
+ .bin => maker.install_paths.bin,
+ .header => maker.install_paths.include,
+ .sub_path => |s| try maker.install_paths.prefix.join(arena, s.slice(c)),
+ };
+}
+
+pub fn installLazyPathSub(
+ maker: *Maker,
+ arena: Allocator,
+ source: Configuration.LazyPath.Index,
+ dest_dir: Configuration.InstallDestDir,
+ sub_path: []const u8,
asking_step_index: Configuration.Step.Index,
-) !Io.Dir.PrevStatus {
+) !Dir.PrevStatus {
+ const src_path = try resolveLazyPathIndex(maker, arena, source, asking_step_index);
+ const dest_dir_path = try resolveInstallDir(maker, arena, dest_dir);
+ const dest_path = try dest_dir_path.join(arena, sub_path);
+ return installPath(maker, arena, src_path, dest_path, asking_step_index);
+}
+
+pub fn installLazyPath(
+ maker: *Maker,
+ arena: Allocator,
+ source: Configuration.LazyPath.Index,
+ dest_dir: Configuration.InstallDestDir,
+ asking_step_index: Configuration.Step.Index,
+) !Dir.PrevStatus {
+ const src_path = try resolveLazyPathIndex(maker, arena, source, asking_step_index);
+ const dest_dir_path = try resolveInstallDir(maker, arena, dest_dir);
+ const dest_path = try dest_dir_path.join(arena, src_path.basename());
+ return installPath(maker, arena, src_path, dest_path, asking_step_index);
+}
+
+pub fn installGenerated(
+ maker: *Maker,
+ arena: Allocator,
+ source: Configuration.GeneratedFileIndex,
+ dest_dir: Configuration.InstallDestDir,
+ asking_step_index: Configuration.Step.Index,
+) !Dir.PrevStatus {
+ const src_path = generatedPath(maker, source).*;
+ const dest_dir_path = try resolveInstallDir(maker, arena, dest_dir);
+ const dest_path = try dest_dir_path.join(arena, src_path.basename());
+ return installPath(maker, arena, src_path, dest_path, asking_step_index);
+}
+
+pub fn installPath(
+ maker: *Maker,
+ arena: Allocator,
+ src_path: Path,
+ dest_path: Path,
+ asking_step_index: Configuration.Step.Index,
+) !Dir.PrevStatus {
const graph = maker.graph;
const io = graph.io;
- const src_path = try resolveLazyPath(maker, arena, src_lazy_path, asking_step_index);
- {
- const src_path_rendered = try src_path.toString(arena);
- defer arena.free(src_path_rendered);
- try graph.handleVerbose(.inherit, null, &.{ "install", "-C", src_path_rendered, dest_path });
- }
- return Io.Dir.updateFile(src_path.root_dir.handle, io, src_path.sub_path, .cwd(), dest_path, .{}) catch |err| {
+ if (graph.verbose) try graph.handleVerbose(.inherit, null, &.{
+ "install", "-C", try src_path.toString(arena), try dest_path.toString(arena),
+ });
+ return Dir.updateFile(
+ src_path.root_dir.handle,
+ io,
+ src_path.sub_path,
+ dest_path.root_dir.handle,
+ dest_path.sub_path,
+ .{},
+ ) catch |err| {
const s = stepByIndex(maker, asking_step_index);
- return s.fail(maker, "unable to update file from '{f}' to '{s}': {t}", .{ src_path, dest_path, err });
+ return s.fail(maker, "unable to update file from {f} to {f}: {t}", .{ src_path, dest_path, err });
};
}
-/// Wrapper around `Io.Dir.createDirPathStatus` that handles verbose and error output.
+/// Wrapper around `Dir.createDirPathStatus` that handles verbose and error output.
pub fn installDir(
maker: *Maker,
- dest_path: []const u8,
+ arena: Allocator,
+ dest_path: Path,
asking_step_index: Configuration.Step.Index,
-) !Io.Dir.CreatePathStatus {
+) !Dir.CreatePathStatus {
const graph = maker.graph;
const io = graph.io;
- try graph.handleVerbose(.inherit, null, &.{ "install", "-d", dest_path });
- return Io.Dir.cwd().createDirPathStatus(io, dest_path, .default_dir) catch |err| {
+ if (graph.verbose) try graph.handleVerbose(.inherit, null, &.{
+ "install", "-d", try dest_path.toString(arena),
+ });
+ return dest_path.root_dir.handle.createDirPathStatus(io, dest_path.sub_path, .default_dir) catch |err| {
const s = stepByIndex(maker, asking_step_index);
- return s.fail(maker, "unable to create dir '{s}': {t}", .{ dest_path, err });
+ return s.fail(maker, "unable to create dir {f}: {t}", .{ dest_path, err });
+ };
+}
+
+pub fn installSymLinks(
+ maker: *Maker,
+ arena: Allocator,
+ output_path: Path,
+ compile_step_index: Configuration.Step.Index,
+ asking_step_index: Configuration.Step.Index,
+) !void {
+ const c = &maker.scanned_config.configuration;
+ const conf_step = compile_step_index.ptr(c);
+ const conf_comp = conf_step.extended.get(c.extra).compile;
+ const root_module = conf_comp.root_module.get(c);
+ const target = root_module.resolved_target.get(c).?.result.get(c);
+ const os_tag = target.flags.os_tag.unwrap().?;
+
+ assert(conf_comp.flags3.kind == .lib);
+ assert(conf_comp.flags2.linkage == .dynamic);
+ assert(os_tag != .windows);
+
+ const version = std.SemanticVersion.parse(conf_comp.version.value.?.slice(c)) catch unreachable;
+ const name = conf_comp.root_name.slice(c);
+
+ const filename_major_only, const filename_name_only = if (os_tag.isDarwin()) .{
+ try std.fmt.allocPrint(arena, "lib{s}.{d}.dylib", .{ name, version.major }),
+ try std.fmt.allocPrint(arena, "lib{s}.dylib", .{name}),
+ } else .{
+ try std.fmt.allocPrint(arena, "lib{s}.so.{d}", .{ name, version.major }),
+ try std.fmt.allocPrint(arena, "lib{s}.so", .{name}),
+ };
+
+ return installSymLinksInner(maker, arena, output_path, asking_step_index, filename_major_only, filename_name_only);
+}
+
+fn installSymLinksInner(
+ maker: *Maker,
+ arena: Allocator,
+ output_path: Path,
+ asking_step_index: Configuration.Step.Index,
+ filename_major_only: []const u8,
+ filename_name_only: []const u8,
+) !void {
+ const io = maker.graph.io;
+ const step = stepByIndex(maker, asking_step_index);
+ const out_dir = output_path.dirname().?;
+ // sym link for libfoo.so.1 to libfoo.so.1.2.3
+ const major_only_path = try out_dir.join(arena, filename_major_only);
+ output_path.root_dir.handle.symLinkAtomic(io, output_path.sub_path, major_only_path.sub_path, .{}) catch |err| {
+ return step.fail(maker, "unable to symlink {f} -> {f}: {t}", .{ output_path, major_only_path, err });
+ };
+ // sym link for libfoo.so to libfoo.so.1
+ const name_only_path = try out_dir.join(arena, filename_name_only);
+ major_only_path.root_dir.handle.symLinkAtomic(io, major_only_path.sub_path, name_only_path.sub_path, .{}) catch |err| {
+ return step.fail(maker, "unable to symlink {f} -> {s}: {t}", .{ name_only_path, filename_major_only, err });
};
}
diff --git a/lib/compiler/Maker/Graph.zig b/lib/compiler/Maker/Graph.zig
@@ -5,6 +5,7 @@ const std = @import("std");
const Io = std.Io;
const Allocator = std.mem.Allocator;
const Configuration = std.Build.Configuration;
+const Path = std.Build.Cache.Path;
io: Io,
/// Process lifetime.
@@ -16,7 +17,7 @@ global_cache_root: std.Build.Cache.Directory,
local_cache_root: std.Build.Cache.Directory,
zig_lib_directory: std.Build.Cache.Directory,
build_root_directory: std.Build.Cache.Directory,
-pkg_root: std.Build.Cache.Path,
+pkg_root: Path,
debug_compiler_runtime_libs: ?std.builtin.OptimizeMode = null,
incremental: ?bool = null,
diff --git a/lib/compiler/Maker/Step.zig b/lib/compiler/Maker/Step.zig
@@ -8,6 +8,7 @@ const std = @import("std");
const Allocator = std.mem.Allocator;
const Cache = std.Build.Cache;
const Io = std.Io;
+const Dir = std.Io.Dir;
const LazyPath = std.Build.Configuration.LazyPath;
const Package = std.Build.Configuration.Package;
const Path = std.Build.Cache.Path;
@@ -19,6 +20,8 @@ const Maker = @import("../Maker.zig");
const Compile = @import("Step/Compile.zig");
const Run = @import("Step/Run.zig");
+const InstallArtifact = @import("Step/InstallArtifact.zig");
+const InstallFile = @import("Step/InstallFile.zig");
/// Avoid false sharing.
_: void align(std.atomic.cache_line) = {},
@@ -69,9 +72,9 @@ pub const Extended = union(enum) {
config_header: Todo,
fail: Todo,
fmt: Todo,
- install_artifact: Todo,
+ install_artifact: InstallArtifact,
install_dir: Todo,
- install_file: Todo,
+ install_file: InstallFile,
objcopy: Todo,
options: Todo,
remove_dir: Todo,
@@ -524,7 +527,7 @@ fn zigProcessUpdate(step_index: Configuration.Step.Index, maker: *Maker, zp: *Zi
const digest = body[@sizeOf(EmitDigest)..][0..Cache.bin_digest_len];
result = .{
.root_dir = graph.local_cache_root,
- .sub_path = try arena.dupe(u8, "o" ++ Io.Dir.path.sep_str ++ Cache.binToHex(digest.*)),
+ .sub_path = try arena.dupe(u8, "o" ++ Dir.path.sep_str ++ Cache.binToHex(digest.*)),
};
},
.file_system_inputs => {
@@ -535,14 +538,14 @@ fn zigProcessUpdate(step_index: Configuration.Step.Index, maker: *Maker, zp: *Zi
while (it.next()) |prefixed_path| {
const prefix_index: std.zig.Server.Message.PathPrefix = @enumFromInt(prefixed_path[0] - 1);
const sub_path = try arena.dupe(u8, prefixed_path[1..]);
- const sub_path_dirname = Io.Dir.path.dirname(sub_path) orelse "";
+ const sub_path_dirname = Dir.path.dirname(sub_path) orelse "";
switch (prefix_index) {
.cwd => {
const path: Path = .{
.root_dir = .cwd(),
.sub_path = sub_path_dirname,
};
- try addWatchInputFromPath(s, maker, path, Io.Dir.path.basename(sub_path));
+ try addWatchInputFromPath(s, maker, path, Dir.path.basename(sub_path));
},
.zig_lib => zl: {
switch (conf_step.extended.get(conf.extra)) {
@@ -558,21 +561,21 @@ fn zigProcessUpdate(step_index: Configuration.Step.Index, maker: *Maker, zp: *Zi
.root_dir = graph.zig_lib_directory,
.sub_path = sub_path_dirname,
};
- try addWatchInputFromPath(s, maker, path, Io.Dir.path.basename(sub_path));
+ try addWatchInputFromPath(s, maker, path, Dir.path.basename(sub_path));
},
.local_cache => {
const path: Path = .{
.root_dir = graph.local_cache_root,
.sub_path = sub_path_dirname,
};
- try addWatchInputFromPath(s, maker, path, Io.Dir.path.basename(sub_path));
+ try addWatchInputFromPath(s, maker, path, Dir.path.basename(sub_path));
},
.global_cache => {
const path: Path = .{
.root_dir = graph.global_cache_root,
.sub_path = sub_path_dirname,
};
- try addWatchInputFromPath(s, maker, path, Io.Dir.path.basename(sub_path));
+ try addWatchInputFromPath(s, maker, path, Dir.path.basename(sub_path));
},
}
}
@@ -680,7 +683,7 @@ fn failWithCacheError(
const pp = man.files.keys()[op.file_index].prefixed_path;
const prefix = man.cache.prefixes()[pp.prefix].path orelse "";
return s.fail(maker, "failed to check cache: '{s}{c}{s}' {t} {t}", .{
- prefix, Io.Dir.path.sep, pp.sub_path, man.diagnostic, op.err,
+ prefix, Dir.path.sep, pp.sub_path, man.diagnostic, op.err,
});
},
},
@@ -718,14 +721,14 @@ fn setWatchInputsFromManifest(s: *Step, maker: *Maker, man: *Cache.Manifest) !vo
const sub_path = try arena.dupe(u8, file.prefixed_path.sub_path);
try addWatchInputFromPath(s, maker, .{
.root_dir = prefixes[file.prefixed_path.prefix],
- .sub_path = Io.Dir.path.dirname(sub_path) orelse "",
- }, Io.Dir.path.basename(sub_path));
+ .sub_path = Dir.path.dirname(sub_path) orelse "",
+ }, Dir.path.basename(sub_path));
}
}
/// For steps that have a single input that never changes when re-running `make`.
-pub fn singleUnchangingWatchInput(step: *Step, maker: *Maker, lazy_path: LazyPath) Allocator.Error!void {
- if (!step.inputs.populated()) try step.addWatchInput(maker, lazy_path);
+pub fn singleUnchangingWatchInput(step: *Step, maker: *Maker, arena: Allocator, lazy_path: LazyPath) Allocator.Error!void {
+ if (!step.inputs.populated()) try step.addWatchInput(maker, arena, lazy_path);
}
pub fn clearWatchInputs(step: *Step, maker: *Maker) void {
@@ -733,19 +736,15 @@ pub fn clearWatchInputs(step: *Step, maker: *Maker) void {
}
/// Places a *file* dependency on the path.
-pub fn addWatchInput(step: *Step, maker: *Maker, lazy_file: LazyPath) Allocator.Error!void {
+pub fn addWatchInput(step: *Step, maker: *Maker, arena: Allocator, lazy_file: LazyPath) Allocator.Error!void {
+ const conf = &maker.scanned_config.configuration;
switch (lazy_file) {
- .src_path => |src_path| try addWatchInputFromBuilder(step, src_path.owner, src_path.sub_path),
- .dependency => |d| try addWatchInputFromBuilder(step, d.dependency.builder, d.sub_path),
- .cwd_relative => |path_string| {
- try addWatchInputFromPath(step, maker, .{
- .root_dir = .{
- .path = null,
- .handle = Io.Dir.cwd(),
- },
- .sub_path = Io.Dir.path.dirname(path_string) orelse "",
- }, Io.Dir.path.basename(path_string));
+ .source_path => |source_path| {
+ const sub_path = source_path.sub_path.slice(conf);
+ const pkg_path = try maker.packagePath(arena, source_path.owner, sub_path);
+ try addWatchInputPath(step, maker, pkg_path);
},
+ .relative => |relative| try addWatchInputPath(step, maker, maker.relativePath(relative)),
// Nothing to watch because this dependency edge is modeled instead via `dependants`.
.generated => {},
}
@@ -766,7 +765,7 @@ pub fn addDirectoryWatchInput(step: *Step, lazy_directory: LazyPath) Allocator.E
try addDirectoryWatchInputFromPath(step, .{
.root_dir = .{
.path = null,
- .handle = Io.Dir.cwd(),
+ .handle = .cwd(),
},
.sub_path = path_string,
});
@@ -789,13 +788,6 @@ pub fn addDirectoryWatchInputFromPath(step: *Step, maker: *Maker, path: Path) !v
return addWatchInputFromPath(step, maker, path, ".");
}
-fn addWatchInputFromBuilder(step: *Step, maker: *Maker, package: Package, sub_path: []const u8) !void {
- return addWatchInputFromPath(step, maker, .{
- .root_dir = package.build_root,
- .sub_path = Io.Dir.path.dirname(sub_path) orelse "",
- }, Io.Dir.path.basename(sub_path));
-}
-
fn addDirectoryWatchInputFromBuilder(step: *Step, package: Package, sub_path: []const u8) !void {
return addDirectoryWatchInputFromPath(step, .{
.root_dir = package.build_root,
@@ -806,8 +798,8 @@ fn addDirectoryWatchInputFromBuilder(step: *Step, package: Package, sub_path: []
fn addWatchInputPath(step: *Step, maker: *Maker, path: Path) Allocator.Error!void {
return addWatchInputFromPath(step, maker, .{
.root_dir = path.root_dir,
- .sub_path = Io.Dir.path.dirname(path.sub_path) orelse "",
- }, Io.Dir.path.basename(path.sub_path));
+ .sub_path = Dir.path.dirname(path.sub_path) orelse "",
+ }, Dir.path.basename(path.sub_path));
}
fn addWatchInputFromPath(step: *Step, maker: *Maker, directory: Path, basename: []const u8) Allocator.Error!void {
diff --git a/lib/compiler/Maker/Step/Compile.zig b/lib/compiler/Maker/Step/Compile.zig
@@ -28,7 +28,7 @@ pub fn make(
progress_node: std.Progress.Node,
) Step.ExtendedMakeError!void {
const graph = maker.graph;
- const step = maker.stepByIndex(compile_index);
+ const arena = graph.arena; // TODO don't leak into process arena
const conf = &maker.scanned_config.configuration;
const conf_step = compile_index.ptr(conf);
const conf_comp = conf_step.extended.get(conf.extra).compile;
@@ -69,16 +69,12 @@ pub fn make(
}
if (conf_comp.flags3.kind == .lib and conf_comp.flags2.linkage == .dynamic and
- conf_comp.version.value != null and conf_comp.generated_bin.value != null and
- target.flags.os_tag != .windows)
+ conf_comp.version.value != null and target.flags.os_tag != .windows)
{
- if (true) @panic("TODO");
- try doAtomicSymLinks(
- step,
- conf_comp.getEmittedBin().getPath2(step),
- conf_comp.major_only_filename.?,
- conf_comp.name_only_filename.?,
- );
+ if (conf_comp.generated_bin.value) |generated_bin| {
+ const full_dest_path = maker.generatedPath(generated_bin).*;
+ try maker.installSymLinks(arena, full_dest_path, compile_index, compile_index);
+ }
}
}
@@ -964,35 +960,6 @@ pub fn rebuildInFuzzMode(compile: *Compile, maker: *Maker, progress_node: std.Pr
return maybe_output_bin_path.?;
}
-pub fn doAtomicSymLinks(
- step: *Step,
- maker: *Maker,
- output_path: []const u8,
- filename_major_only: []const u8,
- filename_name_only: []const u8,
-) !void {
- const graph = maker.graph;
- const arena = graph.arena; // TODO don't leak into process arena
- const io = graph.io;
- const out_dir = Dir.path.dirname(output_path) orelse ".";
- const out_basename = Dir.path.basename(output_path);
- // sym link for libfoo.so.1 to libfoo.so.1.2.3
- const major_only_path = try Dir.path.join(arena, &.{ out_dir, filename_major_only });
- const cwd: Io.Dir = .cwd();
- cwd.symLinkAtomic(io, out_basename, major_only_path, .{}) catch |err| {
- return step.fail(maker, "unable to symlink {s} -> {s}: {t}", .{
- major_only_path, out_basename, err,
- });
- };
- // sym link for libfoo.so to libfoo.so.1
- const name_only_path = try Dir.path.join(arena, &.{ out_dir, filename_name_only });
- cwd.symLinkAtomic(io, filename_major_only, name_only_path, .{}) catch |err| {
- return step.fail(maker, "unable to symlink {s} -> {s}: {t}", .{
- name_only_path, filename_major_only, err,
- });
- };
-}
-
pub const PkgConfigError = error{
PkgConfigCrashed,
PkgConfigFailed,
diff --git a/lib/compiler/Maker/Step/InstallArtifact.zig b/lib/compiler/Maker/Step/InstallArtifact.zig
@@ -1,88 +1,127 @@
+const InstallArtifact = @This();
-fn make(step: *Step, options: Step.MakeOptions) !void {
- _ = options;
- const install_artifact: *InstallArtifact = @fieldParentPtr("step", step);
- const b = step.owner;
- const io = b.graph.io;
+const std = @import("std");
+const Io = std.Io;
+const Configuration = std.Build.Configuration;
+const assert = std.debug.assert;
+
+const Step = @import("../Step.zig");
+const Maker = @import("../../Maker.zig");
+
+pub fn make(
+ install_artifact: *InstallArtifact,
+ step_index: Configuration.Step.Index,
+ maker: *Maker,
+ progress_node: std.Progress.Node,
+) Step.ExtendedMakeError!void {
+ _ = install_artifact;
+ _ = progress_node;
+ const step = maker.stepByIndex(step_index);
+ const conf = &maker.scanned_config.configuration;
+ const graph = maker.graph;
+ const arena = graph.arena; // TODO don't leak into process arena
+ const io = graph.io;
+ const conf_step = step_index.ptr(conf);
+ const conf_ia = conf_step.extended.get(conf.extra).install_artifact;
+ const compile_step_index = conf_step.deps.get(conf).steps.slice[0];
+ const conf_comp_step = compile_step_index.ptr(conf);
+ const conf_comp = conf_comp_step.extended.get(conf.extra).compile;
+ const root_module = conf_comp.root_module.get(conf);
+ const target = root_module.resolved_target.get(conf).?.result.get(conf);
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 p = try step.installFile(install_artifact.emitted_bin.?, full_dest_path);
- all_cached = all_cached and p == .fresh;
+ if (conf_ia.bin_dir.value) |bin_dir| {
+ if (conf_comp.generated_bin.value) |generated_bin| {
+ const bin_sub_path = if (conf_ia.bin_sub_path.value) |s| s.slice(conf) else try std.zig.binNameAlloc(arena, .{
+ .root_name = conf_comp.root_name.slice(conf),
+ .cpu_arch = target.flags.cpu_arch.unwrap().?,
+ .os_tag = target.flags.os_tag.unwrap().?,
+ .ofmt = target.flags.object_format.unwrap().?,
+ .abi = target.flags.abi.unwrap().?,
+ .output_mode = conf_comp.flags3.kind.toOutputMode(),
+ .link_mode = conf_comp.flags2.linkage.unwrap(),
+ .version = v: {
+ const string = conf_comp.version.value orelse break :v null;
+ const slice = string.slice(conf);
+ break :v std.SemanticVersion.parse(slice) catch @panic("bad semver string");
+ },
+ });
+ const dest_dir = try maker.resolveInstallDir(arena, bin_dir);
+ const dest_path = try dest_dir.join(arena, bin_sub_path);
+ const src_path = maker.generatedPath(generated_bin).*;
+ const p = try maker.installPath(arena, src_path, dest_path, step_index);
+ all_cached = all_cached and p == .fresh;
- if (install_artifact.dylib_symlinks) |dls| {
- try Step.Compile.doAtomicSymLinks(step, full_dest_path, dls.major_only_filename, dls.name_only_filename);
+ if (conf_ia.flags.dylib_symlinks)
+ try maker.installSymLinks(arena, dest_path, compile_step_index, step_index);
}
-
- install_artifact.artifact.installed_path = full_dest_path;
}
- if (install_artifact.compiler_rt_dyn_lib_dir) |compiler_rt_dir| {
- const full_compiler_rt_path = b.getInstallPath(compiler_rt_dir, install_artifact.emitted_compiler_rt_dyn_lib.?.basename(b, step));
- const p = try step.installFile(install_artifact.emitted_compiler_rt_dyn_lib.?, full_compiler_rt_path);
- all_cached = all_cached and p == .fresh;
+ if (conf_ia.implib_dir.value) |implib_dir| {
+ if (conf_comp.generated_implib.value) |generated_implib| {
+ const p = try maker.installGenerated(arena, generated_implib, implib_dir, step_index);
+ all_cached = all_cached and p == .fresh;
+ }
}
- if (install_artifact.implib_dir) |implib_dir| {
- 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 (conf_ia.pdb_dir.value) |pdb_dir| {
+ if (conf_comp.generated_pdb.value) |generated_pdb| {
+ const p = try maker.installGenerated(arena, generated_pdb, pdb_dir, step_index);
+ all_cached = all_cached and p == .fresh;
+ }
}
- if (install_artifact.pdb_dir) |pdb_dir| {
- 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 (conf_ia.h_dir.value) |h_dir| {
+ const h_prefix = try maker.resolveInstallDir(arena, h_dir);
- if (install_artifact.h_dir) |h_dir| {
- if (install_artifact.emitted_h) |emitted_h| {
- const full_h_path = b.getInstallPath(h_dir, emitted_h.basename(b, step));
- const p = try step.installFile(emitted_h, full_h_path);
+ if (conf_comp.generated_h.value) |generated_h| {
+ const p = try maker.installGenerated(arena, generated_h, h_dir, step_index);
all_cached = all_cached and p == .fresh;
}
- for (install_artifact.artifact.installed_headers.items) |installation| switch (installation) {
+ for (conf_comp.installed_headers.slice) |installation| switch (installation.get(conf.extra)) {
.file => |file| {
- const full_h_path = b.getInstallPath(h_dir, file.dest_rel_path);
- const p = try step.installFile(file.source, full_h_path);
+ const src_path = try maker.resolveLazyPathIndex(arena, file.source, step_index);
+ const dest_path = try h_prefix.join(arena, file.dest_sub_path.slice(conf));
+ const p = try maker.installPath(arena, src_path, dest_path, step_index);
all_cached = all_cached and p == .fresh;
},
.directory => |dir| {
- const src_dir_path = dir.source.getPath3(b, step);
- const full_h_prefix = b.getInstallPath(h_dir, dir.dest_rel_path);
+ const src_dir_path = try maker.resolveLazyPathIndex(arena, dir.source, step_index);
+ const full_h_prefix = try h_prefix.join(arena, dir.dest_sub_path.slice(conf));
var src_dir = src_dir_path.root_dir.handle.openDir(io, src_dir_path.subPathOrDot(), .{ .iterate = true }) catch |err| {
- return step.fail("unable to open source directory '{f}': {s}", .{
- src_dir_path, @errorName(err),
- });
+ return step.fail(maker, "unable to open source directory {f}: {t}", .{ src_dir_path, err });
};
defer src_dir.close(io);
- var it = try src_dir.walk(b.allocator);
- next_entry: while (try it.next(io)) |entry| {
- for (dir.options.exclude_extensions) |ext| {
- if (std.mem.endsWith(u8, entry.path, ext)) continue :next_entry;
+ var it = try src_dir.walk(arena);
+ next_entry: while (it.next(io) catch |err| switch (err) {
+ error.Canceled, error.OutOfMemory => |e| return e,
+ else => |e| return step.fail(maker, "failed to iterate directory {f}: {t}", .{ src_dir_path, e }),
+ }) |entry| {
+ for (dir.exclude_extensions.slice) |ext| {
+ if (std.mem.endsWith(u8, entry.path, ext.slice(conf))) continue :next_entry;
}
- if (dir.options.include_extensions) |incs| {
- for (incs) |inc| {
- if (std.mem.endsWith(u8, entry.path, inc)) break;
+ if (dir.flags.include_extensions) {
+ for (dir.include_extensions.slice) |inc| {
+ if (std.mem.endsWith(u8, entry.path, inc.slice(conf))) break;
} else {
continue :next_entry;
}
}
- const full_dest_path = b.pathJoin(&.{ full_h_prefix, entry.path });
+ const full_dest_path = try full_h_prefix.join(arena, entry.path);
switch (entry.kind) {
.directory => {
- try Step.handleVerbose(b, .inherit, &.{ "install", "-d", full_dest_path });
- const p = try step.installDir(full_dest_path);
+ const p = try maker.installDir(arena, full_dest_path, step_index);
all_cached = all_cached and p == .existed;
},
.file => {
- const p = try step.installFile(try dir.source.join(b.allocator, entry.path), full_dest_path);
+ const entry_dir_path = try maker.resolveLazyPathIndex(arena, dir.source, step_index);
+ const entry_path = try entry_dir_path.join(arena, entry.path);
+ const p = try maker.installPath(arena, entry_path, full_dest_path, step_index);
all_cached = all_cached and p == .fresh;
},
else => continue,
diff --git a/lib/compiler/Maker/Step/InstallFile.zig b/lib/compiler/Maker/Step/InstallFile.zig
@@ -0,0 +1,25 @@
+const InstallFile = @This();
+
+const std = @import("std");
+const Configuration = std.Build.Configuration;
+
+const Step = @import("../Step.zig");
+const Maker = @import("../../Maker.zig");
+
+pub fn make(
+ install_file: *InstallFile,
+ step_index: Configuration.Step.Index,
+ maker: *Maker,
+ progress_node: std.Progress.Node,
+) Step.ExtendedMakeError!void {
+ _ = install_file;
+ _ = progress_node;
+ const arena = maker.graph.arena; // TODO don't leak into process arena
+ const step = maker.stepByIndex(step_index);
+ const conf = &maker.scanned_config.configuration;
+ const conf_step = step_index.ptr(conf);
+ const conf_if = conf_step.extended.get(conf.extra).install_file;
+ try step.singleUnchangingWatchInput(maker, arena, conf_if.source.get(conf));
+ const p = try maker.installLazyPathSub(arena, conf_if.source, conf_if.dest_dir, conf_if.dest_sub_path.slice(conf), step_index);
+ step.result_cached = p == .fresh;
+}
diff --git a/lib/compiler/configurer.zig b/lib/compiler/configurer.zig
@@ -739,21 +739,28 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void {
const ia: *Step.InstallArtifact = @fieldParentPtr("step", step);
break :e @enumFromInt(try wc.addExtra(@as(Configuration.Step.InstallArtifact, .{
.flags = .{
- .dylib_symlinks = ia.dylib_symlinks != null,
+ .dylib_symlinks = ia.dylib_symlinks,
+ .bin_dir = ia.dest_dir != null,
+ .implib_dir = ia.implib_dir != null,
+ .pdb_dir = ia.pdb_dir != null,
+ .h_dir = ia.h_dir != null,
+ .bin_sub_path = ia.dest_sub_path != null,
},
- .dest_dir = try addInstallDir(wc, ia.dest_dir),
- .dest_sub_path = try wc.addString(ia.dest_sub_path),
- .emitted_bin = try s.addOptionalLazyPathEnum(ia.emitted_bin),
- .implib_dir = try addInstallDir(wc, ia.implib_dir),
- .emitted_implib = try s.addOptionalLazyPathEnum(ia.emitted_implib),
- .pdb_dir = try addInstallDir(wc, ia.pdb_dir),
- .emitted_pdb = try s.addOptionalLazyPathEnum(ia.emitted_pdb),
- .h_dir = try addInstallDir(wc, ia.h_dir),
- .emitted_h = try s.addOptionalLazyPathEnum(ia.emitted_h),
- .artifact = s.stepIndex(&ia.artifact.step),
+ .bin_dir = .{ .value = try addInstallDirDefaultNull(wc, ia.dest_dir) },
+ .implib_dir = .{ .value = try addInstallDirDefaultNull(wc, ia.implib_dir) },
+ .pdb_dir = .{ .value = try addInstallDirDefaultNull(wc, ia.pdb_dir) },
+ .h_dir = .{ .value = try addInstallDirDefaultNull(wc, ia.h_dir) },
+ .bin_sub_path = .{ .value = try s.addOptionalString(ia.dest_sub_path) },
+ })));
+ },
+ .install_file => e: {
+ const sif: *Step.InstallFile = @fieldParentPtr("step", step);
+ break :e @enumFromInt(try wc.addExtra(@as(Configuration.Step.InstallFile, .{
+ .source = try s.addLazyPath(sif.source),
+ .dest_dir = try addInstallDir(wc, sif.dir),
+ .dest_sub_path = try wc.addString(sif.dest_rel_path),
})));
},
- .install_file => @panic("TODO"),
.install_dir => @panic("TODO"),
.remove_dir => @panic("TODO"),
.fail => @panic("TODO"),
@@ -851,6 +858,10 @@ fn addInstallDir(wc: *Configuration.Wip, install_dir: ?std.Build.InstallDir) !Co
}
}
+fn addInstallDirDefaultNull(wc: *Configuration.Wip, install_dir: ?std.Build.InstallDir) !?Configuration.InstallDestDir {
+ return try addInstallDir(wc, install_dir orelse return null);
+}
+
/// If the given `Step` is a `Step.Compile`, adds any dependencies for that step which
/// are implied by the module graph rooted at `step.cast(Step.Compile).?.root_module`.
fn createModuleDependenciesForStep(step: *Step) Allocator.Error!void {
diff --git a/lib/std/Build/Cache/Path.zig b/lib/std/Build/Cache/Path.zig
@@ -213,6 +213,13 @@ pub fn stem(p: Path) []const u8 {
return fs.path.stem(p.sub_path);
}
+pub fn dirname(p: Path) ?Path {
+ return .{
+ .root_dir = p.root_dir,
+ .sub_path = fs.path.dirname(p.subPathOpt() orelse return null) orelse "",
+ };
+}
+
pub fn basename(p: Path) []const u8 {
return fs.path.basename(p.sub_path);
}
diff --git a/lib/std/Build/Configuration.zig b/lib/std/Build/Configuration.zig
@@ -478,29 +478,25 @@ pub const Step = extern struct {
};
};
+ /// The first dependency step index will be the compile step whose
+ /// artifacts are being installed with this step.
pub const InstallArtifact = struct {
flags: @This().Flags,
-
- dest_dir: InstallDestDir,
- dest_sub_path: String,
- emitted_bin: LazyPath.OptionalIndex,
-
- implib_dir: InstallDestDir,
- emitted_implib: LazyPath.OptionalIndex,
-
- pdb_dir: InstallDestDir,
- emitted_pdb: LazyPath.OptionalIndex,
-
- h_dir: InstallDestDir,
- emitted_h: LazyPath.OptionalIndex,
-
- /// Always a compile step.
- artifact: Step.Index,
+ bin_dir: Storage.FlagOptional(.flags, .bin_dir, InstallDestDir),
+ implib_dir: Storage.FlagOptional(.flags, .implib_dir, InstallDestDir),
+ pdb_dir: Storage.FlagOptional(.flags, .pdb_dir, InstallDestDir),
+ h_dir: Storage.FlagOptional(.flags, .h_dir, InstallDestDir),
+ bin_sub_path: Storage.FlagOptional(.flags, .bin_sub_path, String),
pub const Flags = packed struct(u32) {
tag: Tag = .install_artifact,
dylib_symlinks: bool,
- _: u26 = 0,
+ bin_dir: bool,
+ implib_dir: bool,
+ pdb_dir: bool,
+ h_dir: bool,
+ bin_sub_path: bool,
+ _: u21 = 0,
};
};
@@ -790,6 +786,14 @@ pub const Step = extern struct {
.@"test", .test_obj => true,
};
}
+
+ pub fn toOutputMode(kind: Kind) std.builtin.OutputMode {
+ return switch (kind) {
+ .exe, .@"test" => .Exe,
+ .lib => .Lib,
+ .obj, .test_obj => .Obj,
+ };
+ }
};
pub const Subsystem = enum(u4) {
console,
@@ -991,7 +995,10 @@ pub const Step = extern struct {
};
pub const InstallFile = struct {
- flags: @This().Flags,
+ flags: @This().Flags = .{},
+ source: LazyPath.Index,
+ dest_dir: InstallDestDir,
+ dest_sub_path: String,
pub const Flags = packed struct(u32) {
tag: Tag = .install_file,
@@ -1434,6 +1441,25 @@ pub const InstallDestDir = enum(u32) {
assert(@intFromEnum(sub_path) < @intFromEnum(InstallDestDir.none));
return @enumFromInt(@intFromEnum(sub_path));
}
+
+ pub const Unpacked = union(enum) {
+ prefix,
+ lib,
+ bin,
+ header,
+ sub_path: String,
+ };
+
+ pub fn unpack(this: @This()) ?Unpacked {
+ return switch (this) {
+ .none => null,
+ .prefix => .prefix,
+ .lib => .lib,
+ .bin => .bin,
+ .header => .header,
+ _ => .{ .sub_path = @enumFromInt(@intFromEnum(this)) },
+ };
+ }
};
/// Points into `string_bytes`, null-terminated.
@@ -2366,7 +2392,8 @@ pub const Storage = enum {
else => comptime unreachable,
},
.auto => switch (Field.storage) {
- .flag_optional, .enum_optional, .extended => 1,
+ .flag_optional, .enum_optional => (@sizeOf(Field.Value) + 3) / 4,
+ .extended => 1,
.length_prefixed_list,
.flag_length_prefixed_list,
.flag_list,
@@ -2520,7 +2547,7 @@ pub const LoadError = Io.Reader.Error || Allocator.Error;
pub fn load(arena: Allocator, reader: *Io.Reader) LoadError!Configuration {
const header = try reader.takeStruct(Header, .little);
- var result: Configuration = .{
+ const result: Configuration = .{
.string_bytes = try arena.alloc(u8, header.string_bytes_len),
.steps = try arena.alloc(Step, header.steps_len),
.path_deps_sub = try arena.alloc(String, header.path_deps_len),
diff --git a/lib/std/Build/Step/Compile.zig b/lib/std/Build/Step/Compile.zig
@@ -26,12 +26,9 @@ name: []const u8,
linker_script: ?LazyPath = null,
version_script: ?LazyPath = null,
out_filename: []const u8,
-out_lib_filename: []const u8,
linkage: ?std.builtin.LinkMode = null,
version: ?std.SemanticVersion,
kind: Kind,
-major_only_filename: ?[]const u8,
-name_only_filename: ?[]const u8,
formatted_panics: ?bool = null,
compress_debug_sections: std.zig.CompressDebugSections = .none,
verbose_link: bool,
@@ -413,9 +410,6 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
}),
.version = options.version,
.out_filename = out_filename,
- .out_lib_filename = undefined,
- .major_only_filename = null,
- .name_only_filename = null,
.installed_headers = .empty,
.zig_lib_dir = null,
.exec_cmd_args = null,
@@ -463,35 +457,6 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
lp.addStepDependencies(&compile.step);
}
- if (compile.kind == .lib) {
- if (compile.linkage != null and compile.linkage.? == .static) {
- compile.out_lib_filename = compile.out_filename;
- } else if (compile.version) |version| {
- if (target.os.tag.isDarwin()) {
- compile.major_only_filename = owner.fmt("lib{s}.{d}.dylib", .{
- compile.name,
- version.major,
- });
- compile.name_only_filename = owner.fmt("lib{s}.dylib", .{compile.name});
- compile.out_lib_filename = compile.out_filename;
- } else if (target.os.tag == .windows) {
- compile.out_lib_filename = owner.fmt("{s}.lib", .{compile.name});
- } else {
- compile.major_only_filename = owner.fmt("lib{s}.so.{d}", .{ compile.name, version.major });
- compile.name_only_filename = owner.fmt("lib{s}.so", .{compile.name});
- compile.out_lib_filename = compile.out_filename;
- }
- } else {
- if (target.os.tag.isDarwin()) {
- compile.out_lib_filename = compile.out_filename;
- } else if (target.os.tag == .windows) {
- compile.out_lib_filename = owner.fmt("{s}.lib", .{compile.name});
- } else {
- compile.out_lib_filename = compile.out_filename;
- }
- }
- }
-
return compile;
}
diff --git a/lib/std/Build/Step/InstallArtifact.zig b/lib/std/Build/Step/InstallArtifact.zig
@@ -8,7 +8,7 @@ const LazyPath = std.Build.LazyPath;
step: Step,
dest_dir: ?InstallDir,
-dest_sub_path: []const u8,
+dest_sub_path: ?[]const u8,
emitted_bin: ?LazyPath,
implib_dir: ?InstallDir,
@@ -24,7 +24,7 @@ emitted_compiler_rt_dyn_lib: ?LazyPath,
h_dir: ?InstallDir,
emitted_h: ?LazyPath,
-dylib_symlinks: ?DylibSymlinkInfo,
+dylib_symlinks: bool,
artifact: *Step.Compile,
@@ -67,6 +67,16 @@ pub fn create(owner: *std.Build, artifact: *Step.Compile, options: Options) *Ins
},
.override => |o| o,
};
+ const pdb_dir: ?InstallDir = switch (options.pdb_dir) {
+ .disabled => null,
+ .default => if (artifact.producesPdbFile()) dest_dir else null,
+ .override => |o| o,
+ };
+ const implib_dir: ?InstallDir = switch (options.implib_dir) {
+ .disabled => null,
+ .default => if (artifact.producesImplib()) .lib else null,
+ .override => |o| o,
+ };
install_artifact.* = .{
.step = Step.init(.{
.tag = base_tag,
@@ -74,54 +84,30 @@ pub fn create(owner: *std.Build, artifact: *Step.Compile, options: Options) *Ins
.owner = owner,
}),
.dest_dir = dest_dir,
- .pdb_dir = switch (options.pdb_dir) {
- .disabled => null,
- .default => if (artifact.producesPdbFile()) dest_dir else null,
- .override => |o| o,
- },
- .compiler_rt_dyn_lib_dir = switch (options.compiler_rt_dyn_lib_dir) {
- .disabled => null,
- .default => if (artifact.producesCompilerRtDynLib()) dest_dir else null,
- .override => |o| o,
- },
+ .pdb_dir = pdb_dir,
.h_dir = switch (options.h_dir) {
.disabled => null,
.default => if (artifact.kind == .lib) .header else null,
.override => |o| o,
},
- .implib_dir = switch (options.implib_dir) {
- .disabled => null,
- .default => if (artifact.producesImplib()) .lib else null,
- .override => |o| o,
- },
+ .implib_dir = implib_dir,
- .dylib_symlinks = if (options.dylib_symlinks orelse (dest_dir != null and
- artifact.isDynamicLibrary() and
- artifact.version != null and
- std.Build.wantSharedLibSymLinks(artifact.rootModuleTarget()))) .{
- .major_only_filename = artifact.major_only_filename.?,
- .name_only_filename = artifact.name_only_filename.?,
- } else null,
+ .dylib_symlinks = options.dylib_symlinks orelse (dest_dir != null and
+ artifact.isDynamicLibrary() and artifact.version != null and
+ std.Build.wantSharedLibSymLinks(artifact.rootModuleTarget())),
- .dest_sub_path = options.dest_sub_path orelse artifact.out_filename,
+ .dest_sub_path = options.dest_sub_path,
- .emitted_bin = null,
- .emitted_pdb = null,
- .emitted_compiler_rt_dyn_lib = null,
+ .emitted_bin = if (dest_dir != null) artifact.getEmittedBin() else null,
+ .emitted_pdb = if (pdb_dir != null) artifact.getEmittedPdb() else null,
+ // https://github.com/ziglang/zig/issues/9698
.emitted_h = null,
- .emitted_implib = null,
+ .emitted_implib = if (implib_dir != null) artifact.getEmittedImplib() else null,
.artifact = artifact,
};
install_artifact.step.dependOn(&artifact.step);
- if (install_artifact.dest_dir != null) install_artifact.emitted_bin = artifact.getEmittedBin();
- if (install_artifact.compiler_rt_dyn_lib_dir != null) install_artifact.emitted_compiler_rt_dyn_lib = artifact.getEmittedCompilerRtDynLib();
- if (install_artifact.pdb_dir != null) install_artifact.emitted_pdb = artifact.getEmittedPdb();
- // https://github.com/ziglang/zig/issues/9698
- //if (install_artifact.h_dir != null) install_artifact.emitted_h = artifact.getEmittedH();
- if (install_artifact.implib_dir != null) install_artifact.emitted_implib = artifact.getEmittedImplib();
-
return install_artifact;
}
diff --git a/lib/std/Build/Step/InstallFile.zig b/lib/std/Build/Step/InstallFile.zig
@@ -25,7 +25,6 @@ pub fn create(
.tag = base_tag,
.name = owner.fmt("install {s} to {s}", .{ source.getDisplayName(), dest_rel_path }),
.owner = owner,
- .makeFn = make,
}),
.source = source.dupe(owner),
.dir = dir.dupe(owner),
@@ -34,14 +33,3 @@ pub fn create(
source.addStepDependencies(&install_file.step);
return install_file;
}
-
-fn make(step: *Step, options: Step.MakeOptions) !void {
- _ = options;
- const b = step.owner;
- const install_file: *InstallFile = @fieldParentPtr("step", step);
- try step.singleUnchangingWatchInput(install_file.source);
-
- const full_dest_path = b.getInstallPath(install_file.dir, install_file.dest_rel_path);
- const p = try step.installFile(install_file.source, full_dest_path);
- step.result_cached = p == .fresh;
-}