mirror of
https://github.com/ziglang/zig.git
synced 2024-11-27 07:32:44 +00:00
zig build system: add LibExeObjStep.installLibraryHeaders
This function is needed when a library exposes one of its own library dependency's headers as part of its own public API. Also, improve error message when a file system error occurs during install file step.
This commit is contained in:
parent
3ff1f346b0
commit
d703270545
@ -220,6 +220,11 @@ pub fn main() !void {
|
||||
return usageAndErr(builder, true, stderr_stream);
|
||||
},
|
||||
error.UncleanExit => process.exit(1),
|
||||
// This error is intended to indicate that the step has already
|
||||
// logged an error message and so printing the error return trace
|
||||
// here would be unwanted extra information, unless the user opts
|
||||
// into it with a debug flag.
|
||||
error.StepFailed => process.exit(1),
|
||||
else => return err,
|
||||
}
|
||||
};
|
||||
|
@ -316,9 +316,20 @@ pub const Builder = struct {
|
||||
// options to its dependencies. It is the programmatic way to give
|
||||
// command line arguments to a build.zig script.
|
||||
_ = args;
|
||||
// TODO create a hash based on the args and the package hash, use this
|
||||
// to compute the install prefix.
|
||||
const install_prefix = b.pathJoin(&.{ b.cache_root, "pkg" });
|
||||
const Hasher = std.crypto.auth.siphash.SipHash128(1, 3);
|
||||
// Random bytes to make unique. Refresh this with new random bytes when
|
||||
// implementation is modified in a non-backwards-compatible way.
|
||||
var hash = Hasher.init("ZaEsvQ5ClaA2IdH9");
|
||||
hash.update(b.dep_prefix);
|
||||
// TODO additionally update the hash with `args`.
|
||||
|
||||
var digest: [16]u8 = undefined;
|
||||
hash.final(&digest);
|
||||
var hash_basename: [digest.len * 2]u8 = undefined;
|
||||
_ = std.fmt.bufPrint(&hash_basename, "{s}", .{std.fmt.fmtSliceHexLower(&digest)}) catch
|
||||
unreachable;
|
||||
|
||||
const install_prefix = b.pathJoin(&.{ b.cache_root, "i", &hash_basename });
|
||||
b.resolveInstallPrefix(install_prefix, .{});
|
||||
}
|
||||
|
||||
@ -1600,6 +1611,29 @@ pub const Step = struct {
|
||||
install_raw,
|
||||
options,
|
||||
custom,
|
||||
|
||||
pub fn Type(comptime id: Id) type {
|
||||
return switch (id) {
|
||||
.top_level => Builder.TopLevelStep,
|
||||
.lib_exe_obj => LibExeObjStep,
|
||||
.install_artifact => InstallArtifactStep,
|
||||
.install_file => InstallFileStep,
|
||||
.install_dir => InstallDirStep,
|
||||
.log => LogStep,
|
||||
.remove_dir => RemoveDirStep,
|
||||
.fmt => FmtStep,
|
||||
.translate_c => TranslateCStep,
|
||||
.write_file => WriteFileStep,
|
||||
.run => RunStep,
|
||||
.emulatable_run => EmulatableRunStep,
|
||||
.check_file => CheckFileStep,
|
||||
.check_object => CheckObjectStep,
|
||||
.config_header => ConfigHeaderStep,
|
||||
.install_raw => InstallRawStep,
|
||||
.options => OptionsStep,
|
||||
.custom => @compileError("no type available for custom step"),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub fn init(id: Id, name: []const u8, allocator: Allocator, makeFn: MakeFn) Step {
|
||||
|
@ -6,10 +6,14 @@ const Step = build.Step;
|
||||
const Builder = build.Builder;
|
||||
const InstallDir = std.build.InstallDir;
|
||||
const InstallDirStep = @This();
|
||||
const log = std.log;
|
||||
|
||||
step: Step,
|
||||
builder: *Builder,
|
||||
options: Options,
|
||||
/// This is used by the build system when a file being installed comes from one
|
||||
/// package but is being installed by another.
|
||||
override_source_builder: ?*Builder = null,
|
||||
|
||||
pub const base_id = .install_dir;
|
||||
|
||||
@ -53,8 +57,14 @@ pub fn init(
|
||||
fn make(step: *Step) !void {
|
||||
const self = @fieldParentPtr(InstallDirStep, "step", step);
|
||||
const dest_prefix = self.builder.getInstallPath(self.options.install_dir, self.options.install_subdir);
|
||||
const full_src_dir = self.builder.pathFromRoot(self.options.source_dir);
|
||||
var src_dir = try std.fs.cwd().openIterableDir(full_src_dir, .{});
|
||||
const src_builder = self.override_source_builder orelse self.builder;
|
||||
const full_src_dir = src_builder.pathFromRoot(self.options.source_dir);
|
||||
var src_dir = std.fs.cwd().openIterableDir(full_src_dir, .{}) catch |err| {
|
||||
log.err("InstallDirStep: unable to open source directory '{s}': {s}", .{
|
||||
full_src_dir, @errorName(err),
|
||||
});
|
||||
return error.StepFailed;
|
||||
};
|
||||
defer src_dir.close();
|
||||
var it = try src_dir.walk(self.builder.allocator);
|
||||
next_entry: while (try it.next()) |entry| {
|
||||
@ -64,13 +74,8 @@ fn make(step: *Step) !void {
|
||||
}
|
||||
}
|
||||
|
||||
const full_path = self.builder.pathJoin(&.{
|
||||
full_src_dir, entry.path,
|
||||
});
|
||||
|
||||
const dest_path = self.builder.pathJoin(&.{
|
||||
dest_prefix, entry.path,
|
||||
});
|
||||
const full_path = self.builder.pathJoin(&.{ full_src_dir, entry.path });
|
||||
const dest_path = self.builder.pathJoin(&.{ dest_prefix, entry.path });
|
||||
|
||||
switch (entry.kind) {
|
||||
.Directory => try fs.cwd().makePath(dest_path),
|
||||
|
@ -13,6 +13,9 @@ builder: *Builder,
|
||||
source: FileSource,
|
||||
dir: InstallDir,
|
||||
dest_rel_path: []const u8,
|
||||
/// This is used by the build system when a file being installed comes from one
|
||||
/// package but is being installed by another.
|
||||
override_source_builder: ?*Builder = null,
|
||||
|
||||
pub fn init(
|
||||
builder: *Builder,
|
||||
@ -32,7 +35,8 @@ pub fn init(
|
||||
|
||||
fn make(step: *Step) !void {
|
||||
const self = @fieldParentPtr(InstallFileStep, "step", step);
|
||||
const src_builder = self.override_source_builder orelse self.builder;
|
||||
const full_src_path = self.source.getPath(src_builder);
|
||||
const full_dest_path = self.builder.getInstallPath(self.dir, self.dest_rel_path);
|
||||
const full_src_path = self.source.getPath(self.builder);
|
||||
try self.builder.updateFile(full_src_path, full_dest_path);
|
||||
}
|
||||
|
@ -501,6 +501,29 @@ pub fn installHeadersDirectoryOptions(
|
||||
a.installed_headers.append(&install_dir.step) catch unreachable;
|
||||
}
|
||||
|
||||
pub fn installLibraryHeaders(a: *LibExeObjStep, l: *LibExeObjStep) void {
|
||||
assert(l.kind == .lib);
|
||||
const install_step = a.builder.getInstallStep();
|
||||
// Copy each element from installed_headers, modifying the builder
|
||||
// to be the new parent's builder.
|
||||
for (l.installed_headers.items) |step| {
|
||||
const step_copy = switch (step.id) {
|
||||
inline .install_file, .install_dir => |id| blk: {
|
||||
const T = id.Type();
|
||||
const ptr = a.builder.allocator.create(T) catch unreachable;
|
||||
ptr.* = step.cast(T).?.*;
|
||||
ptr.override_source_builder = ptr.builder;
|
||||
ptr.builder = a.builder;
|
||||
break :blk &ptr.step;
|
||||
},
|
||||
else => unreachable,
|
||||
};
|
||||
a.installed_headers.append(step_copy) catch unreachable;
|
||||
install_step.dependOn(step_copy);
|
||||
}
|
||||
a.installed_headers.appendSlice(l.installed_headers.items) catch unreachable;
|
||||
}
|
||||
|
||||
/// Creates a `RunStep` with an executable built with `addExecutable`.
|
||||
/// Add command line arguments with `addArg`.
|
||||
pub fn run(exe: *LibExeObjStep) *RunStep {
|
||||
|
Loading…
Reference in New Issue
Block a user