Changes to .path instead of .getPathFn. Changes LibExeObjStep to also provide FileSource.

This commit is contained in:
Felix (xq) Queißner 2021-02-26 11:28:23 +01:00 committed by Veikka Tuominen
parent 07acb1ccc9
commit 27bd0971bb
6 changed files with 82 additions and 94 deletions

View File

@ -1228,11 +1228,12 @@ pub const GeneratedFile = struct {
/// The step that generates the file
step: *Step,
/// A function that returns the absolute path to the generated file.
getPathFn: fn (self: *const GeneratedFile) []const u8,
/// The path to the generated file. Must be either absolute or relative to the build root.
/// This value must be set in the `fn make()` of the `step` and must not be `null` afterwards.
path: ?[]const u8 = null,
pub fn getPath(self: *const GeneratedFile) []const u8 {
return self.getPathFn(self);
return self.path orelse @panic("getPath() was called on a GeneratedFile that wasn't build yet. Is there a missing Step dependency?");
}
};
@ -1414,6 +1415,11 @@ pub const LibExeObjStep = struct {
want_lto: ?bool = null,
output_path_source: GeneratedFile,
output_lib_path_source: GeneratedFile,
output_h_path_source: GeneratedFile,
output_pdb_path_source: GeneratedFile,
const LinkObject = union(enum) {
static_path: FileSource,
other_step: *LibExeObjStep,
@ -1444,36 +1450,26 @@ pub const LibExeObjStep = struct {
pub const Linkage = enum { dynamic, static };
pub fn createSharedLibrary(builder: *Builder, name: []const u8, root_src: ?FileSource, kind: SharedLibKind) *LibExeObjStep {
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
self.* = initExtraArgs(builder, name, root_src, Kind.Lib, .dynamic, switch (kind) {
return initExtraArgs(builder, name, root_src, Kind.Lib, .dynamic, switch (kind) {
.versioned => |ver| ver,
.unversioned => null,
});
return self;
}
pub fn createStaticLibrary(builder: *Builder, name: []const u8, root_src: ?FileSource) *LibExeObjStep {
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
self.* = initExtraArgs(builder, name, root_src, Kind.Lib, .static, null);
return self;
return initExtraArgs(builder, name, root_src, Kind.Lib, .static, null);
}
pub fn createObject(builder: *Builder, name: []const u8, root_src: ?FileSource) *LibExeObjStep {
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
self.* = initExtraArgs(builder, name, root_src, Kind.Obj, .static, null);
return self;
return initExtraArgs(builder, name, root_src, Kind.Obj, .static, null);
}
pub fn createExecutable(builder: *Builder, name: []const u8, root_src: ?FileSource, linkage: Linkage) *LibExeObjStep {
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
self.* = initExtraArgs(builder, name, root_src, Kind.Exe, linkage, null);
return self;
return initExtraArgs(builder, name, root_src, Kind.Exe, linkage, null);
}
pub fn createTest(builder: *Builder, name: []const u8, root_src: FileSource) *LibExeObjStep {
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
self.* = initExtraArgs(builder, name, root_src, Kind.Test, .static, null);
return self;
return initExtraArgs(builder, name, root_src, Kind.Test, .static, null);
}
fn initExtraArgs(
@ -1483,13 +1479,15 @@ pub const LibExeObjStep = struct {
kind: Kind,
linkage: Linkage,
ver: ?Version,
) LibExeObjStep {
) *LibExeObjStep {
const name = builder.dupe(name_raw);
const root_src: ?FileSource = if (root_src_raw) |rsrc| rsrc.dupe(builder) else null;
if (mem.indexOf(u8, name, "/") != null or mem.indexOf(u8, name, "\\") != null) {
panic("invalid name: '{s}'. It looks like a file path, but it is supposed to be the library or application name.", .{name});
}
var self = LibExeObjStep{
const self = builder.allocator.create(LibExeObjStep) catch unreachable;
self.* = LibExeObjStep{
.strip = false,
.builder = builder,
.verbose_link = false,
@ -1534,6 +1532,11 @@ pub const LibExeObjStep = struct {
.override_dest_dir = null,
.installed_path = null,
.install_step = null,
.output_path_source = GeneratedFile{ .step = &self.step },
.output_lib_path_source = GeneratedFile{ .step = &self.step },
.output_h_path_source = GeneratedFile{ .step = &self.step },
.output_pdb_path_source = GeneratedFile{ .step = &self.step },
};
self.computeOutFileNames();
if (root_src) |rs| rs.addStepDependencies(&self.step);
@ -1871,45 +1874,31 @@ pub const LibExeObjStep = struct {
self.libc_file = if (libc_file) |f| f.dupe(self.builder) else null;
}
/// Unless setOutputDir was called, this function must be called only in
/// the make step, from a step that has declared a dependency on this one.
/// Returns the generated executable, library or object file.
/// To run an executable built with zig build, use `run`, or create an install step and invoke it.
pub fn getOutputPath(self: *LibExeObjStep) []const u8 {
return fs.path.join(
self.builder.allocator,
&[_][]const u8{ self.output_dir.?, self.out_filename },
) catch unreachable;
pub fn getOutputSource(self: *LibExeObjStep) FileSource {
return FileSource{ .generated = &self.output_path_source };
}
/// Unless setOutputDir was called, this function must be called only in
/// the make step, from a step that has declared a dependency on this one.
pub fn getOutputLibPath(self: *LibExeObjStep) []const u8 {
/// Returns the generated import library. This function can only be called for libraries.
pub fn getOutputLibSource(self: *LibExeObjStep) FileSource {
assert(self.kind == Kind.Lib);
return fs.path.join(
self.builder.allocator,
&[_][]const u8{ self.output_dir.?, self.out_lib_filename },
) catch unreachable;
return FileSource{ .generated = &self.output_lib_path_source };
}
/// Unless setOutputDir was called, this function must be called only in
/// the make step, from a step that has declared a dependency on this one.
pub fn getOutputHPath(self: *LibExeObjStep) []const u8 {
/// Returns the generated header file.
/// This function can only be called for libraries or object files which have `emit_h` set.
pub fn getOutputHSource(self: *LibExeObjStep) FileSource {
assert(self.kind != Kind.Exe);
assert(self.emit_h);
return fs.path.join(
self.builder.allocator,
&[_][]const u8{ self.output_dir.?, self.out_h_filename },
) catch unreachable;
return FileSource{ .generated = &self.output_h_path_source };
}
/// Unless setOutputDir was called, this function must be called only in
/// the make step, from a step that has declared a dependency on this one.
pub fn getOutputPdbPath(self: *LibExeObjStep) []const u8 {
/// Returns the generated PDB file. This function can only be called for Windows and UEFI.
pub fn getOutputPdbSource(self: *LibExeObjStep) FileSource {
// TODO: Is this right? Isn't PDB for *any* PE/COFF file?
assert(self.target.isWindows() or self.target.isUefi());
return fs.path.join(
self.builder.allocator,
&[_][]const u8{ self.output_dir.?, self.out_pdb_filename },
) catch unreachable;
return FileSource{ .generated = &self.output_pdb_path_source };
}
pub fn addAssemblyFile(self: *LibExeObjStep, path: []const u8) void {
@ -2185,6 +2174,28 @@ pub const LibExeObjStep = struct {
return error.NeedAnObject;
}
// Update generated files
self.output_path_source.path =
fs.path.join(
self.builder.allocator,
&[_][]const u8{ self.output_dir.?, self.out_filename },
) catch unreachable;
self.output_lib_path_source.path =
fs.path.join(
self.builder.allocator,
&[_][]const u8{ self.output_dir.?, self.out_lib_filename },
) catch unreachable;
self.output_h_path_source.path =
fs.path.join(
self.builder.allocator,
&[_][]const u8{ self.output_dir.?, self.out_h_filename },
) catch unreachable;
self.output_pdb_path_source.path =
fs.path.join(
self.builder.allocator,
&[_][]const u8{ self.output_dir.?, self.out_pdb_filename },
) catch unreachable;
var zig_args = ArrayList([]const u8).init(builder.allocator);
defer zig_args.deinit();
@ -2219,10 +2230,10 @@ pub const LibExeObjStep = struct {
.Exe => unreachable,
.Test => unreachable,
.Obj => {
try zig_args.append(other.getOutputPath());
try zig_args.append(other.getOutputSource().getPath(builder));
},
.Lib => {
const full_path_lib = other.getOutputLibPath();
const full_path_lib = other.getOutputLibSource().getPath(builder);
try zig_args.append(full_path_lib);
if (other.linkage == .dynamic and !self.target.isWindows()) {
@ -2296,7 +2307,7 @@ pub const LibExeObjStep = struct {
self.addBuildOption(
[]const u8,
item.name,
self.builder.pathFromRoot(item.artifact.getOutputPath()),
self.builder.pathFromRoot(item.artifact.getOutputSource().getPath(self.builder)),
);
}
for (self.build_options_file_source_args.items) |item| {
@ -2560,7 +2571,7 @@ pub const LibExeObjStep = struct {
try zig_args.append(self.builder.pathFromRoot(include_path));
},
.other_step => |other| if (other.emit_h) {
const h_path = other.getOutputHPath();
const h_path = other.getOutputHSource().getPath(self.builder);
try zig_args.append("-isystem");
try zig_args.append(fs.path.dirname(h_path).?);
},
@ -2701,7 +2712,7 @@ pub const LibExeObjStep = struct {
}
if (self.kind == .Lib and self.linkage == .dynamic and self.version != null and self.target.wantSharedLibSymLinks()) {
try doAtomicSymLinks(builder.allocator, self.getOutputPath(), self.major_only_filename.?, self.name_only_filename.?);
try doAtomicSymLinks(builder.allocator, self.getOutputSource().getPath(builder), self.major_only_filename.?, self.name_only_filename.?);
}
}
};
@ -2768,17 +2779,17 @@ pub const InstallArtifactStep = struct {
const builder = self.builder;
const full_dest_path = builder.getInstallPath(self.dest_dir, self.artifact.out_filename);
try builder.updateFile(self.artifact.getOutputPath(), full_dest_path);
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()) {
try doAtomicSymLinks(builder.allocator, full_dest_path, self.artifact.major_only_filename.?, self.artifact.name_only_filename.?);
}
if (self.pdb_dir) |pdb_dir| {
const full_pdb_path = builder.getInstallPath(pdb_dir, self.artifact.out_pdb_filename);
try builder.updateFile(self.artifact.getOutputPdbPath(), full_pdb_path);
try builder.updateFile(self.artifact.getOutputPdbSource().getPath(builder), full_pdb_path);
}
if (self.h_dir) |h_dir| {
const full_pdb_path = builder.getInstallPath(h_dir, self.artifact.out_h_filename);
try builder.updateFile(self.artifact.getOutputHPath(), full_pdb_path);
try builder.updateFile(self.artifact.getOutputHSource().getPath(builder), full_pdb_path);
}
self.artifact.installed_path = full_dest_path;
}

View File

@ -214,7 +214,7 @@ fn make(step: *Step) !void {
return error.InvalidObjectFormat;
}
const full_src_path = self.artifact.getOutputPath();
const full_src_path = self.artifact.getOutputSource().getPath(builder);
const full_dest_path = builder.getInstallPath(self.dest_dir, self.dest_filename);
fs.cwd().makePath(builder.getInstallPath(self.dest_dir, "")) catch unreachable;

View File

@ -166,7 +166,7 @@ fn make(step: *Step) !void {
// On Windows we don't have rpaths so we have to add .dll search paths to PATH
self.addPathForDynLibs(artifact);
}
const executable_path = artifact.installed_path orelse artifact.getOutputPath();
const executable_path = artifact.installed_path orelse artifact.getOutputSource().getPath(self.builder);
try argv_list.append(executable_path);
},
}
@ -312,7 +312,7 @@ fn addPathForDynLibs(self: *RunStep, artifact: *LibExeObjStep) void {
switch (link_object) {
.other_step => |other| {
if (other.target.isWindows() and other.isDynamicLibrary()) {
self.addPathDir(fs.path.dirname(other.getOutputPath()).?);
self.addPathDir(fs.path.dirname(other.getOutputSource().getPath(self.builder)).?);
self.addPathForDynLibs(other);
}
},

View File

@ -33,30 +33,12 @@ pub fn create(builder: *Builder, source: build.FileSource) *TranslateCStep {
.include_dirs = std.ArrayList([]const u8).init(builder.allocator),
.output_dir = null,
.out_basename = undefined,
.output_file = build.GeneratedFile{
.step = &self.step,
.getPathFn = getGeneratedFilePath,
},
.output_file = build.GeneratedFile{ .step = &self.step },
};
source.addStepDependencies(&self.step);
return self;
}
fn getGeneratedFilePath(file: *const build.GeneratedFile) []const u8 {
const self = @fieldParentPtr(TranslateCStep, "step", file.step);
return self.getOutputPath();
}
/// Unless setOutputDir was called, this function must be called only in
/// the make step, from a step that has declared a dependency on this one.
/// To run an executable built with zig build, use `run`, or create an install step and invoke it.
pub fn getOutputPath(self: *TranslateCStep) []const u8 {
return fs.path.join(
self.builder.allocator,
&[_][]const u8{ self.output_dir.?, self.out_basename },
) catch unreachable;
}
pub fn setTarget(self: *TranslateCStep, target: CrossTarget) void {
self.target = target;
}
@ -106,4 +88,9 @@ fn make(step: *Step) !void {
} else {
self.output_dir = fs.path.dirname(output_path).?;
}
self.source.path = fs.path.join(
self.builder.allocator,
&[_][]const u8{ self.output_dir.?, self.out_basename },
) catch unreachable;
}

View File

@ -37,10 +37,7 @@ pub fn add(self: *WriteFileStep, basename: []const u8, bytes: []const u8) void {
const node = self.builder.allocator.create(std.TailQueue(File).Node) catch unreachable;
node.* = .{
.data = .{
.source = build.GeneratedFile{
.step = &self.step,
.getPathFn = getFilePath,
},
.source = build.GeneratedFile{ .step = &self.step },
.basename = self.builder.dupePath(basename),
.bytes = self.builder.dupe(bytes),
},
@ -59,17 +56,6 @@ pub fn getFileSource(step: *WriteFileStep, basename: []const u8) ?build.FileSour
return null;
}
/// Returns the
fn getFilePath(source: *const build.GeneratedFile) []const u8 {
const file = @fieldParentPtr(File, "source", source);
const step = @fieldParentPtr(WriteFileStep, "step", source.step);
return fs.path.join(
step.builder.allocator,
&[_][]const u8{ step.output_dir, file.basename },
) catch unreachable;
}
fn make(step: *Step) !void {
const self = @fieldParentPtr(WriteFileStep, "step", step);
@ -124,6 +110,10 @@ fn make(step: *Step) !void {
});
return err;
};
node.data.source.path = fs.path.join(
self.builder.allocator,
&[_][]const u8{ self.output_dir, node.data.basename },
) catch unreachable;
}
}
}

View File

@ -707,7 +707,7 @@ pub const StackTracesContext = struct {
const self = @fieldParentPtr(RunAndCompareStep, "step", step);
const b = self.context.b;
const full_exe_path = self.exe.getOutputPath();
const full_exe_path = self.exe.getOutputSource().getPath(b);
var args = ArrayList([]const u8).init(b.allocator);
defer args.deinit();
args.append(full_exe_path) catch unreachable;