Skip to content

Add option to set exact install name for LibExeObjStep #9783

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 62 additions & 22 deletions lib/std/build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ pub const Builder = struct {
search_prefixes: ArrayList([]const u8),
libc_file: ?[]const u8 = null,
installed_files: ArrayList(InstalledFile),
configure_installed_files: ArrayList(*InstallArtifactStep),
build_root: []const u8,
cache_root: []const u8,
global_cache_root: []const u8,
Expand Down Expand Up @@ -173,6 +174,7 @@ pub const Builder = struct {
.h_dir = undefined,
.dest_dir = env_map.get("DESTDIR"),
.installed_files = ArrayList(InstalledFile).init(allocator),
.configure_installed_files = ArrayList(*InstallArtifactStep).init(allocator),
.install_tls = TopLevelStep{
.step = Step.initNoOp(.top_level, "install", allocator),
.description = "Copy build artifacts to prefix path",
Expand Down Expand Up @@ -438,6 +440,10 @@ pub const Builder = struct {
const uninstall_tls = @fieldParentPtr(TopLevelStep, "step", uninstall_step);
const self = @fieldParentPtr(Builder, "uninstall_tls", uninstall_tls);

for (self.configure_installed_files.items) |install_step| {
install_step.configure();
}

for (self.installed_files.items) |installed_file| {
const full_path = self.getInstallPath(installed_file.dir, installed_file.path);
if (self.verbose) {
Expand Down Expand Up @@ -1049,6 +1055,10 @@ pub const Builder = struct {
self.installed_files.append(file.dupe(self)) catch unreachable;
}

pub fn pushInstallConfigure(self: *Builder, install_step: *InstallArtifactStep) void {
self.configure_installed_files.append(install_step) catch unreachable;
}

pub fn updateFile(self: *Builder, source_path: []const u8, dest_path: []const u8) !void {
if (self.verbose) {
warn("cp {s} {s} ", .{ source_path, dest_path });
Expand Down Expand Up @@ -1418,6 +1428,7 @@ pub const LibExeObjStep = struct {
kind: Kind,
major_only_filename: ?[]const u8,
name_only_filename: ?[]const u8,
exact_install_filename: ?[]const u8 = null,
strip: bool,
lib_paths: ArrayList([]const u8),
rpaths: ArrayList([]const u8),
Expand Down Expand Up @@ -2728,6 +2739,7 @@ pub const LibExeObjStep = struct {

// This will ensure all output filenames will now have the output_dir available!
self.computeOutFileNames();
if (self.install_step) |install_step| install_step.configure();

// Update generated files
if (self.output_dir != null) {
Expand All @@ -2754,7 +2766,9 @@ pub const LibExeObjStep = struct {
}
}

if (self.kind == .lib and self.linkage != null and self.linkage.? == .dynamic and self.version != null and self.target.wantSharedLibSymLinks()) {
if (self.exact_install_filename == null and self.kind == .lib and self.linkage != null and
self.linkage.? == .dynamic and self.version != null and self.target.wantSharedLibSymLinks())
{
try doAtomicSymLinks(builder.allocator, self.getOutputSource().getPath(builder), self.major_only_filename.?, self.name_only_filename.?);
}
}
Expand All @@ -2766,20 +2780,25 @@ pub const InstallArtifactStep = struct {
step: Step,
builder: *Builder,
artifact: *LibExeObjStep,
dest_dir: InstallDir,
pdb_dir: ?InstallDir,
h_dir: ?InstallDir,
state: ?ConfiguredState = null,

const Self = @This();

pub fn create(builder: *Builder, artifact: *LibExeObjStep) *Self {
if (artifact.install_step) |s| return s;
const ConfiguredState = struct {
basename: []const u8,
dest_dir: InstallDir,
pdb_dir: ?InstallDir,
h_dir: ?InstallDir,
};

const self = builder.allocator.create(Self) catch unreachable;
self.* = Self{
.builder = builder,
.step = Step.init(.install_artifact, builder.fmt("install {s}", .{artifact.step.name}), builder.allocator, make),
.artifact = artifact,
/// must be called after all declarative setup of the artifact (i.e. by artifact.make() or makeUninstall())
fn configure(self: *InstallArtifactStep) void {
if (self.state != null) return;

const artifact = self.artifact;

const state = ConfiguredState{
.basename = artifact.exact_install_filename orelse artifact.out_filename,
.dest_dir = artifact.override_dest_dir orelse switch (artifact.kind) {
.obj => unreachable,
.@"test" => unreachable,
Expand All @@ -2795,44 +2814,65 @@ pub const InstallArtifactStep = struct {
} else null,
.h_dir = if (artifact.kind == .lib and artifact.emit_h) .header else null,
};
self.step.dependOn(&artifact.step);
artifact.install_step = self;

builder.pushInstalledFile(self.dest_dir, artifact.out_filename);
if (self.artifact.isDynamicLibrary()) {
self.state = state;

const builder = artifact.builder;
builder.pushInstalledFile(state.dest_dir, state.basename);
if (artifact.exact_install_filename == null and artifact.isDynamicLibrary()) {
if (artifact.major_only_filename) |name| {
builder.pushInstalledFile(.lib, name);
}
if (artifact.name_only_filename) |name| {
builder.pushInstalledFile(.lib, name);
}
if (self.artifact.target.isWindows()) {
if (artifact.target.isWindows()) {
builder.pushInstalledFile(.lib, artifact.out_lib_filename);
}
}
if (self.pdb_dir) |pdb_dir| {
if (state.pdb_dir) |pdb_dir| {
builder.pushInstalledFile(pdb_dir, artifact.out_pdb_filename);
}
if (self.h_dir) |h_dir| {
if (state.h_dir) |h_dir| {
builder.pushInstalledFile(h_dir, artifact.out_h_filename);
}
}

pub fn create(builder: *Builder, artifact: *LibExeObjStep) *Self {
if (artifact.install_step) |s| return s;

const self = builder.allocator.create(Self) catch unreachable;
self.* = Self{
.builder = builder,
.step = Step.init(.install_artifact, builder.fmt("install {s}", .{artifact.step.name}), builder.allocator, make),
.artifact = artifact,
};

self.step.dependOn(&artifact.step);
artifact.install_step = self;

builder.pushInstallConfigure(self);
return self;
}

fn make(step: *Step) !void {
const self = @fieldParentPtr(Self, "step", step);
const builder = self.builder;

const full_dest_path = builder.getInstallPath(self.dest_dir, self.artifact.out_filename);
const state = self.state orelse panic("Install state for {s} not configured.", .{self.artifact.name});

const full_dest_path = builder.getInstallPath(state.dest_dir, state.basename);
try builder.updateFile(self.artifact.getOutputSource().getPath(builder), full_dest_path);
if (self.artifact.isDynamicLibrary() and self.artifact.version != null and self.artifact.target.wantSharedLibSymLinks()) {
if (self.artifact.exact_install_filename == null and self.artifact.isDynamicLibrary() and
self.artifact.version != null and self.artifact.target.wantSharedLibSymLinks())
{
try doAtomicSymLinks(builder.allocator, full_dest_path, self.artifact.major_only_filename.?, self.artifact.name_only_filename.?);
}
if (self.pdb_dir) |pdb_dir| {
if (state.pdb_dir) |pdb_dir| {
const full_pdb_path = builder.getInstallPath(pdb_dir, self.artifact.out_pdb_filename);
try builder.updateFile(self.artifact.getOutputPdbSource().getPath(builder), full_pdb_path);
}
if (self.h_dir) |h_dir| {
if (state.h_dir) |h_dir| {
const full_pdb_path = builder.getInstallPath(h_dir, self.artifact.out_h_filename);
try builder.updateFile(self.artifact.getOutputHSource().getPath(builder), full_pdb_path);
}
Expand Down