diff options
| author | Loris Cro <kappaloris@gmail.com> | 2023-06-18 09:06:40 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-06-18 09:06:40 +0200 |
| commit | 216ef10dc471e4db60a30208be178d6c59efeaaf (patch) | |
| tree | 8c239dab283ae9cb3b7fe099bae240bcc53f894e /lib/std/Build/Step/TranslateC.zig | |
| parent | 0fc1d396495c1ab482197021dedac8bea3f9401c (diff) | |
| parent | 729a051e9e38674233190aea23c0ac8c134f2d67 (diff) | |
| download | zig-216ef10dc471e4db60a30208be178d6c59efeaaf.tar.gz zig-216ef10dc471e4db60a30208be178d6c59efeaaf.zip | |
Merge branch 'master' into autodoc-searchkey
Diffstat (limited to 'lib/std/Build/Step/TranslateC.zig')
| -rw-r--r-- | lib/std/Build/Step/TranslateC.zig | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/lib/std/Build/Step/TranslateC.zig b/lib/std/Build/Step/TranslateC.zig new file mode 100644 index 0000000000..ced249b3f2 --- /dev/null +++ b/lib/std/Build/Step/TranslateC.zig @@ -0,0 +1,134 @@ +const std = @import("std"); +const Step = std.Build.Step; +const fs = std.fs; +const mem = std.mem; +const CrossTarget = std.zig.CrossTarget; + +const TranslateC = @This(); + +pub const base_id = .translate_c; + +step: Step, +source: std.Build.FileSource, +include_dirs: std.ArrayList([]const u8), +c_macros: std.ArrayList([]const u8), +out_basename: []const u8, +target: CrossTarget, +optimize: std.builtin.OptimizeMode, +output_file: std.Build.GeneratedFile, + +pub const Options = struct { + source_file: std.Build.FileSource, + target: CrossTarget, + optimize: std.builtin.OptimizeMode, +}; + +pub fn create(owner: *std.Build, options: Options) *TranslateC { + const self = owner.allocator.create(TranslateC) catch @panic("OOM"); + const source = options.source_file.dupe(owner); + self.* = TranslateC{ + .step = Step.init(.{ + .id = .translate_c, + .name = "translate-c", + .owner = owner, + .makeFn = make, + }), + .source = source, + .include_dirs = std.ArrayList([]const u8).init(owner.allocator), + .c_macros = std.ArrayList([]const u8).init(owner.allocator), + .out_basename = undefined, + .target = options.target, + .optimize = options.optimize, + .output_file = std.Build.GeneratedFile{ .step = &self.step }, + }; + source.addStepDependencies(&self.step); + return self; +} + +pub const AddExecutableOptions = struct { + name: ?[]const u8 = null, + version: ?std.SemanticVersion = null, + target: ?CrossTarget = null, + optimize: ?std.builtin.Mode = null, + linkage: ?Step.Compile.Linkage = null, +}; + +/// Creates a step to build an executable from the translated source. +pub fn addExecutable(self: *TranslateC, options: AddExecutableOptions) *Step.Compile { + return self.step.owner.addExecutable(.{ + .root_source_file = .{ .generated = &self.output_file }, + .name = options.name orelse "translated_c", + .version = options.version, + .target = options.target orelse self.target, + .optimize = options.optimize orelse self.optimize, + .linkage = options.linkage, + }); +} + +pub fn addIncludeDir(self: *TranslateC, include_dir: []const u8) void { + self.include_dirs.append(self.step.owner.dupePath(include_dir)) catch @panic("OOM"); +} + +pub fn addCheckFile(self: *TranslateC, expected_matches: []const []const u8) *Step.CheckFile { + return Step.CheckFile.create( + self.step.owner, + .{ .generated = &self.output_file }, + .{ .expected_matches = expected_matches }, + ); +} + +/// If the value is omitted, it is set to 1. +/// `name` and `value` need not live longer than the function call. +pub fn defineCMacro(self: *TranslateC, name: []const u8, value: ?[]const u8) void { + const macro = std.Build.constructCMacro(self.step.owner.allocator, name, value); + self.c_macros.append(macro) catch @panic("OOM"); +} + +/// name_and_value looks like [name]=[value]. If the value is omitted, it is set to 1. +pub fn defineCMacroRaw(self: *TranslateC, name_and_value: []const u8) void { + self.c_macros.append(self.step.owner.dupe(name_and_value)) catch @panic("OOM"); +} + +fn make(step: *Step, prog_node: *std.Progress.Node) !void { + const b = step.owner; + const self = @fieldParentPtr(TranslateC, "step", step); + + var argv_list = std.ArrayList([]const u8).init(b.allocator); + try argv_list.append(b.zig_exe); + try argv_list.append("translate-c"); + try argv_list.append("-lc"); + + try argv_list.append("--listen=-"); + + if (!self.target.isNative()) { + try argv_list.append("-target"); + try argv_list.append(try self.target.zigTriple(b.allocator)); + } + + switch (self.optimize) { + .Debug => {}, // Skip since it's the default. + else => try argv_list.append(b.fmt("-O{s}", .{@tagName(self.optimize)})), + } + + for (self.include_dirs.items) |include_dir| { + try argv_list.append("-I"); + try argv_list.append(include_dir); + } + + for (self.c_macros.items) |c_macro| { + try argv_list.append("-D"); + try argv_list.append(c_macro); + } + + try argv_list.append(self.source.getPath(b)); + + const output_path = try step.evalZigProcess(argv_list.items, prog_node); + + self.out_basename = fs.path.basename(output_path); + const output_dir = fs.path.dirname(output_path).?; + + self.output_file.path = try fs.path.join( + b.allocator, + &[_][]const u8{ output_dir, self.out_basename }, + ); +} |
