| author | |
| committer | |
| log | d7032705456a67cebeb17ad09a11e10d13f5fb21 |
| tree | 562196908a009a9569082d1696d04ef63441db1e |
| parent | 3ff1f346b0c780bce7d70078794312002b3f1639 |
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.5 files changed, 84 insertions(+), 13 deletions(-)
lib/build_runner.zig+5| ... | @@ -220,6 +220,11 @@ pub fn main() !void { | ... | @@ -220,6 +220,11 @@ pub fn main() !void { |
| 220 | return usageAndErr(builder, true, stderr_stream); | 220 | return usageAndErr(builder, true, stderr_stream); |
| 221 | }, | 221 | }, |
| 222 | error.UncleanExit => process.exit(1), | 222 | error.UncleanExit => process.exit(1), |
| 223 | // This error is intended to indicate that the step has already | ||
| 224 | // logged an error message and so printing the error return trace | ||
| 225 | // here would be unwanted extra information, unless the user opts | ||
| 226 | // into it with a debug flag. | ||
| 227 | error.StepFailed => process.exit(1), | ||
| 223 | else => return err, | 228 | else => return err, |
| 224 | } | 229 | } |
| 225 | }; | 230 | }; |
lib/std/build.zig+37-3| ... | @@ -316,9 +316,20 @@ pub const Builder = struct { | ... | @@ -316,9 +316,20 @@ pub const Builder = struct { |
| 316 | // options to its dependencies. It is the programmatic way to give | 316 | // options to its dependencies. It is the programmatic way to give |
| 317 | // command line arguments to a build.zig script. | 317 | // command line arguments to a build.zig script. |
| 318 | _ = args; | 318 | _ = args; |
| 319 | // TODO create a hash based on the args and the package hash, use this | 319 | const Hasher = std.crypto.auth.siphash.SipHash128(1, 3); |
| 320 | // to compute the install prefix. | 320 | // Random bytes to make unique. Refresh this with new random bytes when |
| 321 | const install_prefix = b.pathJoin(&.{ b.cache_root, "pkg" }); | 321 | // implementation is modified in a non-backwards-compatible way. |
| 322 | var hash = Hasher.init("ZaEsvQ5ClaA2IdH9"); | ||
| 323 | hash.update(b.dep_prefix); | ||
| 324 | // TODO additionally update the hash with `args`. | ||
| 325 | |||
| 326 | var digest: [16]u8 = undefined; | ||
| 327 | hash.final(&digest); | ||
| 328 | var hash_basename: [digest.len * 2]u8 = undefined; | ||
| 329 | _ = std.fmt.bufPrint(&hash_basename, "{s}", .{std.fmt.fmtSliceHexLower(&digest)}) catch | ||
| 330 | unreachable; | ||
| 331 | |||
| 332 | const install_prefix = b.pathJoin(&.{ b.cache_root, "i", &hash_basename }); | ||
| 322 | b.resolveInstallPrefix(install_prefix, .{}); | 333 | b.resolveInstallPrefix(install_prefix, .{}); |
| 323 | } | 334 | } |
| 324 | 335 | ||
| ... | @@ -1600,6 +1611,29 @@ pub const Step = struct { | ... | @@ -1600,6 +1611,29 @@ pub const Step = struct { |
| 1600 | install_raw, | 1611 | install_raw, |
| 1601 | options, | 1612 | options, |
| 1602 | custom, | 1613 | custom, |
| 1614 | |||
| 1615 | pub fn Type(comptime id: Id) type { | ||
| 1616 | return switch (id) { | ||
| 1617 | .top_level => Builder.TopLevelStep, | ||
| 1618 | .lib_exe_obj => LibExeObjStep, | ||
| 1619 | .install_artifact => InstallArtifactStep, | ||
| 1620 | .install_file => InstallFileStep, | ||
| 1621 | .install_dir => InstallDirStep, | ||
| 1622 | .log => LogStep, | ||
| 1623 | .remove_dir => RemoveDirStep, | ||
| 1624 | .fmt => FmtStep, | ||
| 1625 | .translate_c => TranslateCStep, | ||
| 1626 | .write_file => WriteFileStep, | ||
| 1627 | .run => RunStep, | ||
| 1628 | .emulatable_run => EmulatableRunStep, | ||
| 1629 | .check_file => CheckFileStep, | ||
| 1630 | .check_object => CheckObjectStep, | ||
| 1631 | .config_header => ConfigHeaderStep, | ||
| 1632 | .install_raw => InstallRawStep, | ||
| 1633 | .options => OptionsStep, | ||
| 1634 | .custom => @compileError("no type available for custom step"), | ||
| 1635 | }; | ||
| 1636 | } | ||
| 1603 | }; | 1637 | }; |
| 1604 | 1638 | ||
| 1605 | pub fn init(id: Id, name: []const u8, allocator: Allocator, makeFn: MakeFn) Step { | 1639 | pub fn init(id: Id, name: []const u8, allocator: Allocator, makeFn: MakeFn) Step { |
lib/std/build/InstallDirStep.zig+14-9| ... | @@ -6,10 +6,14 @@ const Step = build.Step; | ... | @@ -6,10 +6,14 @@ const Step = build.Step; |
| 6 | const Builder = build.Builder; | 6 | const Builder = build.Builder; |
| 7 | const InstallDir = std.build.InstallDir; | 7 | const InstallDir = std.build.InstallDir; |
| 8 | const InstallDirStep = @This(); | 8 | const InstallDirStep = @This(); |
| 9 | const log = std.log; | ||
| 9 | 10 | ||
| 10 | step: Step, | 11 | step: Step, |
| 11 | builder: *Builder, | 12 | builder: *Builder, |
| 12 | options: Options, | 13 | options: Options, |
| 14 | /// This is used by the build system when a file being installed comes from one | ||
| 15 | /// package but is being installed by another. | ||
| 16 | override_source_builder: ?*Builder = null, | ||
| 13 | 17 | ||
| 14 | pub const base_id = .install_dir; | 18 | pub const base_id = .install_dir; |
| 15 | 19 | ||
| ... | @@ -53,8 +57,14 @@ pub fn init( | ... | @@ -53,8 +57,14 @@ pub fn init( |
| 53 | fn make(step: *Step) !void { | 57 | fn make(step: *Step) !void { |
| 54 | const self = @fieldParentPtr(InstallDirStep, "step", step); | 58 | const self = @fieldParentPtr(InstallDirStep, "step", step); |
| 55 | const dest_prefix = self.builder.getInstallPath(self.options.install_dir, self.options.install_subdir); | 59 | const dest_prefix = self.builder.getInstallPath(self.options.install_dir, self.options.install_subdir); |
| 56 | const full_src_dir = self.builder.pathFromRoot(self.options.source_dir); | 60 | const src_builder = self.override_source_builder orelse self.builder; |
| 57 | var src_dir = try std.fs.cwd().openIterableDir(full_src_dir, .{}); | 61 | const full_src_dir = src_builder.pathFromRoot(self.options.source_dir); |
| 62 | var src_dir = std.fs.cwd().openIterableDir(full_src_dir, .{}) catch |err| { | ||
| 63 | log.err("InstallDirStep: unable to open source directory '{s}': {s}", .{ | ||
| 64 | full_src_dir, @errorName(err), | ||
| 65 | }); | ||
| 66 | return error.StepFailed; | ||
| 67 | }; | ||
| 58 | defer src_dir.close(); | 68 | defer src_dir.close(); |
| 59 | var it = try src_dir.walk(self.builder.allocator); | 69 | var it = try src_dir.walk(self.builder.allocator); |
| 60 | next_entry: while (try it.next()) |entry| { | 70 | next_entry: while (try it.next()) |entry| { |
| ... | @@ -64,13 +74,8 @@ fn make(step: *Step) !void { | ... | @@ -64,13 +74,8 @@ fn make(step: *Step) !void { |
| 64 | } | 74 | } |
| 65 | } | 75 | } |
| 66 | 76 | ||
| 67 | const full_path = self.builder.pathJoin(&.{ | 77 | const full_path = self.builder.pathJoin(&.{ full_src_dir, entry.path }); |
| 68 | full_src_dir, entry.path, | 78 | const dest_path = self.builder.pathJoin(&.{ dest_prefix, entry.path }); |
| 69 | }); | ||
| 70 | |||
| 71 | const dest_path = self.builder.pathJoin(&.{ | ||
| 72 | dest_prefix, entry.path, | ||
| 73 | }); | ||
| 74 | 79 | ||
| 75 | switch (entry.kind) { | 80 | switch (entry.kind) { |
| 76 | .Directory => try fs.cwd().makePath(dest_path), | 81 | .Directory => try fs.cwd().makePath(dest_path), |
lib/std/build/InstallFileStep.zig+5-1| ... | @@ -13,6 +13,9 @@ builder: *Builder, | ... | @@ -13,6 +13,9 @@ builder: *Builder, |
| 13 | source: FileSource, | 13 | source: FileSource, |
| 14 | dir: InstallDir, | 14 | dir: InstallDir, |
| 15 | dest_rel_path: []const u8, | 15 | dest_rel_path: []const u8, |
| 16 | /// This is used by the build system when a file being installed comes from one | ||
| 17 | /// package but is being installed by another. | ||
| 18 | override_source_builder: ?*Builder = null, | ||
| 16 | 19 | ||
| 17 | pub fn init( | 20 | pub fn init( |
| 18 | builder: *Builder, | 21 | builder: *Builder, |
| ... | @@ -32,7 +35,8 @@ pub fn init( | ... | @@ -32,7 +35,8 @@ pub fn init( |
| 32 | 35 | ||
| 33 | fn make(step: *Step) !void { | 36 | fn make(step: *Step) !void { |
| 34 | const self = @fieldParentPtr(InstallFileStep, "step", step); | 37 | const self = @fieldParentPtr(InstallFileStep, "step", step); |
| 38 | const src_builder = self.override_source_builder orelse self.builder; | ||
| 39 | const full_src_path = self.source.getPath(src_builder); | ||
| 35 | const full_dest_path = self.builder.getInstallPath(self.dir, self.dest_rel_path); | 40 | const full_dest_path = self.builder.getInstallPath(self.dir, self.dest_rel_path); |
| 36 | const full_src_path = self.source.getPath(self.builder); | ||
| 37 | try self.builder.updateFile(full_src_path, full_dest_path); | 41 | try self.builder.updateFile(full_src_path, full_dest_path); |
| 38 | } | 42 | } |
lib/std/build/LibExeObjStep.zig+23| ... | @@ -501,6 +501,29 @@ pub fn installHeadersDirectoryOptions( | ... | @@ -501,6 +501,29 @@ pub fn installHeadersDirectoryOptions( |
| 501 | a.installed_headers.append(&install_dir.step) catch unreachable; | 501 | a.installed_headers.append(&install_dir.step) catch unreachable; |
| 502 | } | 502 | } |
| 503 | 503 | ||
| 504 | pub fn installLibraryHeaders(a: *LibExeObjStep, l: *LibExeObjStep) void { | ||
| 505 | assert(l.kind == .lib); | ||
| 506 | const install_step = a.builder.getInstallStep(); | ||
| 507 | // Copy each element from installed_headers, modifying the builder | ||
| 508 | // to be the new parent's builder. | ||
| 509 | for (l.installed_headers.items) |step| { | ||
| 510 | const step_copy = switch (step.id) { | ||
| 511 | inline .install_file, .install_dir => |id| blk: { | ||
| 512 | const T = id.Type(); | ||
| 513 | const ptr = a.builder.allocator.create(T) catch unreachable; | ||
| 514 | ptr.* = step.cast(T).?.*; | ||
| 515 | ptr.override_source_builder = ptr.builder; | ||
| 516 | ptr.builder = a.builder; | ||
| 517 | break :blk &ptr.step; | ||
| 518 | }, | ||
| 519 | else => unreachable, | ||
| 520 | }; | ||
| 521 | a.installed_headers.append(step_copy) catch unreachable; | ||
| 522 | install_step.dependOn(step_copy); | ||
| 523 | } | ||
| 524 | a.installed_headers.appendSlice(l.installed_headers.items) catch unreachable; | ||
| 525 | } | ||
| 526 | |||
| 504 | /// Creates a `RunStep` with an executable built with `addExecutable`. | 527 | /// Creates a `RunStep` with an executable built with `addExecutable`. |
| 505 | /// Add command line arguments with `addArg`. | 528 | /// Add command line arguments with `addArg`. |
| 506 | pub fn run(exe: *LibExeObjStep) *RunStep { | 529 | pub fn run(exe: *LibExeObjStep) *RunStep { |