authorgravatar for rohlemF@gmail.comrohlem <rohlemF@gmail.com> 2022-02-04 19:44:38+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-05 03:17:07-05:00
logfbc06f9c9151205896fb167b087506d6580946c4
tree606a4577836fa35a6ca12b3838af8cc86d7861cb
parent7d04ab1f14269b25a7ac03c3f787b3f3ee3453c3

std.build.TranslateCStep: add C macro support

The string construction code is moved out of std.build.LibExeObjStep into std.build.constructCMacroArg, to allow reusing it elsewhere.

2 files changed, 36 insertions(+), 9 deletions(-)

lib/std/build.zig+17-9
...@@ -1862,15 +1862,7 @@ pub const LibExeObjStep = struct {...@@ -1862,15 +1862,7 @@ pub const LibExeObjStep = struct {
1862 /// If the value is omitted, it is set to 1.1862 /// If the value is omitted, it is set to 1.
1863 /// `name` and `value` need not live longer than the function call.1863 /// `name` and `value` need not live longer than the function call.
1864 pub fn defineCMacro(self: *LibExeObjStep, name: []const u8, value: ?[]const u8) void {1864 pub fn defineCMacro(self: *LibExeObjStep, name: []const u8, value: ?[]const u8) void {
1865 var macro = self.builder.allocator.alloc(1865 const macro = constructCMacro(self.builder.allocator, name, value);
1866 u8,
1867 name.len + if (value) |value_slice| value_slice.len + 1 else 0,
1868 ) catch |err| if (err == error.OutOfMemory) @panic("Out of memory") else unreachable;
1869 mem.copy(u8, macro, name);
1870 if (value) |value_slice| {
1871 macro[name.len] = '=';
1872 mem.copy(u8, macro[name.len + 1 ..], value_slice);
1873 }
1874 self.c_macros.append(macro) catch unreachable;1866 self.c_macros.append(macro) catch unreachable;
1875 }1867 }
18761868
...@@ -2934,6 +2926,22 @@ pub const LibExeObjStep = struct {...@@ -2934,6 +2926,22 @@ pub const LibExeObjStep = struct {
2934 }2926 }
2935};2927};
29362928
2929/// Allocates a new string for assigning a value to a named macro.
2930/// If the value is omitted, it is set to 1.
2931/// `name` and `value` need not live longer than the function call.
2932pub fn constructCMacro(allocator: Allocator, name: []const u8, value: ?[]const u8) []const u8 {
2933 var macro = allocator.alloc(
2934 u8,
2935 name.len + if (value) |value_slice| value_slice.len + 1 else 0,
2936 ) catch |err| if (err == error.OutOfMemory) @panic("Out of memory") else unreachable;
2937 mem.copy(u8, macro, name);
2938 if (value) |value_slice| {
2939 macro[name.len] = '=';
2940 mem.copy(u8, macro[name.len + 1 ..], value_slice);
2941 }
2942 return macro;
2943}
2944
2937pub const InstallArtifactStep = struct {2945pub const InstallArtifactStep = struct {
2938 pub const base_id = .install_artifact;2946 pub const base_id = .install_artifact;
29392947
lib/std/build/TranslateCStep.zig+19
...@@ -16,6 +16,7 @@ step: Step,...@@ -16,6 +16,7 @@ step: Step,
16builder: *Builder,16builder: *Builder,
17source: build.FileSource,17source: build.FileSource,
18include_dirs: std.ArrayList([]const u8),18include_dirs: std.ArrayList([]const u8),
19c_macros: std.ArrayList([]const u8),
19output_dir: ?[]const u8,20output_dir: ?[]const u8,
20out_basename: []const u8,21out_basename: []const u8,
21target: CrossTarget = CrossTarget{},22target: CrossTarget = CrossTarget{},
...@@ -28,6 +29,7 @@ pub fn create(builder: *Builder, source: build.FileSource) *TranslateCStep {...@@ -28,6 +29,7 @@ pub fn create(builder: *Builder, source: build.FileSource) *TranslateCStep {
28 .builder = builder,29 .builder = builder,
29 .source = source,30 .source = source,
30 .include_dirs = std.ArrayList([]const u8).init(builder.allocator),31 .include_dirs = std.ArrayList([]const u8).init(builder.allocator),
32 .c_macros = std.ArrayList([]const u8).init(builder.allocator),
31 .output_dir = null,33 .output_dir = null,
32 .out_basename = undefined,34 .out_basename = undefined,
33 .output_file = build.GeneratedFile{ .step = &self.step },35 .output_file = build.GeneratedFile{ .step = &self.step },
...@@ -53,6 +55,18 @@ pub fn addCheckFile(self: *TranslateCStep, expected_matches: []const []const u8)...@@ -53,6 +55,18 @@ pub fn addCheckFile(self: *TranslateCStep, expected_matches: []const []const u8)
53 return CheckFileStep.create(self.builder, .{ .generated = &self.output_file }, self.builder.dupeStrings(expected_matches));55 return CheckFileStep.create(self.builder, .{ .generated = &self.output_file }, self.builder.dupeStrings(expected_matches));
54}56}
5557
58/// If the value is omitted, it is set to 1.
59/// `name` and `value` need not live longer than the function call.
60pub fn defineCMacro(self: *TranslateCStep, name: []const u8, value: ?[]const u8) void {
61 const macro = build.constructCMacro(self.builder.allocator, name, value);
62 self.c_macros.append(macro) catch unreachable;
63}
64
65/// name_and_value looks like [name]=[value]. If the value is omitted, it is set to 1.
66pub fn defineCMacroRaw(self: *TranslateCStep, name_and_value: []const u8) void {
67 self.c_macros.append(self.builder.dupe(name_and_value)) catch unreachable;
68}
69
56fn make(step: *Step) !void {70fn make(step: *Step) !void {
57 const self = @fieldParentPtr(TranslateCStep, "step", step);71 const self = @fieldParentPtr(TranslateCStep, "step", step);
5872
...@@ -73,6 +87,11 @@ fn make(step: *Step) !void {...@@ -73,6 +87,11 @@ fn make(step: *Step) !void {
73 try argv_list.append(include_dir);87 try argv_list.append(include_dir);
74 }88 }
7589
90 for (self.c_macros.items) |c_macro| {
91 try argv_list.append("-D");
92 try argv_list.append(c_macro);
93 }
94
76 try argv_list.append(self.source.getPath(self.builder));95 try argv_list.append(self.source.getPath(self.builder));
7796
78 const output_path_nl = try self.builder.execFromStep(argv_list.items, &self.step);97 const output_path_nl = try self.builder.execFromStep(argv_list.items, &self.step);