From eee5400b7dc37845ea5f42e0841320953e7852b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20=C3=85stholm?= Date: Fri, 15 Mar 2024 19:59:02 +0100 Subject: [PATCH] Account for dependency boundaries when duping headers This is a temporary workaround that can be revered if/when 'path' lazy paths are updated to encode which build root they are relative to. --- lib/std/Build/Step/Compile.zig | 31 ++++++++++++++++++++--- test/standalone/install_headers/build.zig | 4 +-- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/lib/std/Build/Step/Compile.zig b/lib/std/Build/Step/Compile.zig index 2883992c73..4a5364176a 100644 --- a/lib/std/Build/Step/Compile.zig +++ b/lib/std/Build/Step/Compile.zig @@ -264,8 +264,20 @@ pub const HeaderInstallation = union(enum) { dest_rel_path: []const u8, pub fn dupe(self: File, b: *std.Build) File { + // 'path' lazy paths are relative to the build root of some step, inferred from the step + // in which they are used. This means that we can't dupe such paths, because they may + // come from dependencies with their own build roots and duping the paths as is might + // cause the build script to search for the file relative to the wrong root. + // As a temporary workaround, we convert build root-relative paths to absolute paths. + // If/when the build-root relative paths are updated to encode which build root they are + // relative to, this workaround should be removed. + const duped_source: LazyPath = switch (self.source) { + .path => |root_rel| .{ .cwd_relative = b.pathFromRoot(root_rel) }, + else => self.source.dupe(b), + }; + return .{ - .source = self.source.dupe(b), + .source = duped_source, .dest_rel_path = b.dupePath(self.dest_rel_path), }; } @@ -293,8 +305,20 @@ pub const HeaderInstallation = union(enum) { }; pub fn dupe(self: Directory, b: *std.Build) Directory { + // 'path' lazy paths are relative to the build root of some step, inferred from the step + // in which they are used. This means that we can't dupe such paths, because they may + // come from dependencies with their own build roots and duping the paths as is might + // cause the build script to search for the file relative to the wrong root. + // As a temporary workaround, we convert build root-relative paths to absolute paths. + // If/when the build-root relative paths are updated to encode which build root they are + // relative to, this workaround should be removed. + const duped_source: LazyPath = switch (self.source) { + .path => |root_rel| .{ .cwd_relative = b.pathFromRoot(root_rel) }, + else => self.source.dupe(b), + }; + return .{ - .source = self.source.dupe(b), + .source = duped_source, .dest_rel_path = b.dupePath(self.dest_rel_path), .options = self.options.dupe(b), }; @@ -492,9 +516,8 @@ pub fn installConfigHeader(cs: *Compile, config_header: *Step.ConfigHeader) void /// module's include search path. pub fn installLibraryHeaders(cs: *Compile, lib: *Compile) void { assert(lib.kind == .lib); - const b = cs.step.owner; for (lib.installed_headers.items) |installation| { - const installation_copy = installation.dupe(b); + const installation_copy = installation.dupe(lib.step.owner); cs.installed_headers.append(installation_copy) catch @panic("OOM"); cs.addHeaderInstallationToIncludeTree(installation_copy); installation_copy.getSource().addStepDependencies(&cs.step); diff --git a/test/standalone/install_headers/build.zig b/test/standalone/install_headers/build.zig index 965239aac5..4c9bbb501a 100644 --- a/test/standalone/install_headers/build.zig +++ b/test/standalone/install_headers/build.zig @@ -70,7 +70,7 @@ pub fn build(b: *std.Build) void { run_exe.expectStdOutEqual("ABD12X"); test_step.dependOn(&run_exe.step); - const install_exe = b.addInstallArtifact(libfoo, .{ + const install_libfoo = b.addInstallArtifact(libfoo, .{ .dest_dir = .{ .override = .{ .custom = "custom" } }, .h_dir = .{ .override = .{ .custom = "custom/include" } }, .implib_dir = .disabled, @@ -94,6 +94,6 @@ pub fn build(b: *std.Build) void { }); run_check_exists.setCwd(.{ .cwd_relative = b.getInstallPath(.prefix, "") }); run_check_exists.expectExitCode(0); - run_check_exists.step.dependOn(&install_exe.step); + run_check_exists.step.dependOn(&install_libfoo.step); test_step.dependOn(&run_check_exists.step); }