zig/lib/std/build/translate_c.zig
Andrew Kelley a690a5085d
rework and improve some of the zig build steps
* `RunStep` moved to lib/std/build/run.zig and gains ability to compare
   output and exit code against expected values. Multiple redundant
   locations in the test harness code are replaced to use `RunStep`.
 * `WriteFileStep` moved to lib/std/build/write_file.zig and gains
   ability to write more than one file into the cache directory, for
   when the files need to be relative to each other. This makes
   usage of `WriteFileStep` no longer problematic when parallelizing
   zig build.
 * Added `CheckFileStep`, which can be used to validate that the output
   of another step produced a valid file. Multiple redundant locations
   in the test harness code are replaced to use `CheckFileStep`.
 * Added `TranslateCStep`. This exposes `zig translate-c` to the build
   system, which is likely to be rarely useful by most Zig users;
   however Zig's own test suite uses it both for translate-c tests and
   for run-translated-c tests.
 * Refactored ad-hoc code to handle source files coming from multiple
   kinds of sources, into `std.build.FileSource`.
 * Added `std.build.Builder.addExecutableFromWriteFileStep`.
 * Added `std.build.Builder.addExecutableSource`.
 * Added `std.build.Builder.addWriteFiles`.
 * Added `std.build.Builder.addTranslateC`.
 * Added `std.build.LibExeObjStep.addCSourceFileSource`.
 * Added `std.build.LibExeObjStep.addAssemblyFileFromWriteFileStep`.
 * Added `std.build.LibExeObjStep.addAssemblyFileSource`.
 * Exposed `std.fs.base64_encoder`.
2020-01-05 02:19:22 -05:00

74 lines
2.7 KiB
Zig

const std = @import("../std.zig");
const build = std.build;
const Step = build.Step;
const Builder = build.Builder;
const WriteFileStep = build.WriteFileStep;
const LibExeObjStep = build.LibExeObjStep;
const CheckFileStep = build.CheckFileStep;
const fs = std.fs;
const mem = std.mem;
pub const TranslateCStep = struct {
step: Step,
builder: *Builder,
source: build.FileSource,
output_dir: ?[]const u8,
out_basename: []const u8,
pub fn create(builder: *Builder, source: build.FileSource) *TranslateCStep {
const self = builder.allocator.create(TranslateCStep) catch unreachable;
self.* = TranslateCStep{
.step = Step.init("zig translate-c", builder.allocator, make),
.builder = builder,
.source = source,
.output_dir = null,
.out_basename = undefined,
};
source.addStepDependencies(&self.step);
return self;
}
/// 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;
}
/// Creates a step to build an executable from the translated source.
pub fn addExecutable(self: *TranslateCStep) *LibExeObjStep {
return self.builder.addExecutableSource("translated_c", @as(build.FileSource, .{ .translate_c = self }));
}
pub fn addCheckFile(self: *TranslateCStep, expected_matches: []const []const u8) *CheckFileStep {
return CheckFileStep.create(self.builder, .{ .translate_c = self }, expected_matches);
}
fn make(step: *Step) !void {
const self = @fieldParentPtr(TranslateCStep, "step", step);
const argv = [_][]const u8{
self.builder.zig_exe,
"translate-c",
"-lc",
"--cache",
"on",
self.source.getPath(self.builder),
};
const output_path_nl = try self.builder.exec(&argv);
const output_path = mem.trimRight(u8, output_path_nl, "\r\n");
self.out_basename = fs.path.basename(output_path);
if (self.output_dir) |output_dir| {
const full_dest = try fs.path.join(self.builder.allocator, &[_][]const u8{ output_dir, self.out_basename });
try self.builder.updateFile(output_path, full_dest);
} else {
self.output_dir = fs.path.dirname(output_path).?;
}
}
};