2020-01-04 23:01:28 -08:00
|
|
|
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;
|
2020-02-25 22:18:23 -08:00
|
|
|
const CrossTarget = std.zig.CrossTarget;
|
2020-01-04 23:01:28 -08:00
|
|
|
|
|
|
|
pub const TranslateCStep = struct {
|
|
|
|
step: Step,
|
|
|
|
builder: *Builder,
|
|
|
|
source: build.FileSource,
|
2020-05-17 02:58:39 -07:00
|
|
|
include_dirs: std.ArrayList([]const u8),
|
2020-01-04 23:01:28 -08:00
|
|
|
output_dir: ?[]const u8,
|
|
|
|
out_basename: []const u8,
|
2020-02-25 22:18:23 -08:00
|
|
|
target: CrossTarget = CrossTarget{},
|
2020-01-04 23:01:28 -08:00
|
|
|
|
|
|
|
pub fn create(builder: *Builder, source: build.FileSource) *TranslateCStep {
|
|
|
|
const self = builder.allocator.create(TranslateCStep) catch unreachable;
|
|
|
|
self.* = TranslateCStep{
|
2020-05-25 01:20:31 -07:00
|
|
|
.step = Step.init(.TranslateC, "translate-c", builder.allocator, make),
|
2020-01-04 23:01:28 -08:00
|
|
|
.builder = builder,
|
|
|
|
.source = source,
|
2020-05-17 02:58:39 -07:00
|
|
|
.include_dirs = std.ArrayList([]const u8).init(builder.allocator),
|
2020-01-04 23:01:28 -08:00
|
|
|
.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;
|
|
|
|
}
|
|
|
|
|
2020-02-25 22:18:23 -08:00
|
|
|
pub fn setTarget(self: *TranslateCStep, target: CrossTarget) void {
|
2020-01-06 11:07:56 -08:00
|
|
|
self.target = target;
|
|
|
|
}
|
|
|
|
|
2020-01-04 23:01:28 -08:00
|
|
|
/// 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 }));
|
|
|
|
}
|
|
|
|
|
2020-05-17 02:58:39 -07:00
|
|
|
pub fn addIncludeDir(self: *TranslateCStep, include_dir: []const u8) void {
|
|
|
|
self.include_dirs.append(include_dir) catch unreachable;
|
|
|
|
}
|
|
|
|
|
2020-01-04 23:01:28 -08:00
|
|
|
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);
|
|
|
|
|
2020-01-06 11:07:56 -08:00
|
|
|
var argv_list = std.ArrayList([]const u8).init(self.builder.allocator);
|
|
|
|
try argv_list.append(self.builder.zig_exe);
|
|
|
|
try argv_list.append("translate-c");
|
|
|
|
try argv_list.append("-lc");
|
|
|
|
|
|
|
|
try argv_list.append("--cache");
|
|
|
|
try argv_list.append("on");
|
|
|
|
|
2020-02-25 22:18:23 -08:00
|
|
|
if (!self.target.isNative()) {
|
|
|
|
try argv_list.append("-target");
|
|
|
|
try argv_list.append(try self.target.zigTriple(self.builder.allocator));
|
2020-01-06 11:07:56 -08:00
|
|
|
}
|
|
|
|
|
2020-05-17 02:58:39 -07:00
|
|
|
for (self.include_dirs.items) |include_dir| {
|
|
|
|
try argv_list.append("-I");
|
|
|
|
try argv_list.append(include_dir);
|
|
|
|
}
|
|
|
|
|
2020-01-06 11:07:56 -08:00
|
|
|
try argv_list.append(self.source.getPath(self.builder));
|
2020-01-04 23:01:28 -08:00
|
|
|
|
2020-03-30 11:23:22 -07:00
|
|
|
const output_path_nl = try self.builder.execFromStep(argv_list.span(), &self.step);
|
2020-01-04 23:01:28 -08:00
|
|
|
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).?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|