authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-02-05 16:45:26-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-02-13 06:42:25-07:00
logb061cc9e3ff197d4af1408c8e3a8504dda208e10
tree3b38f5ec9e4d6520a8a5acd62085275067d29388
parentdad6039092d02460d5e993855b129da9949e9c5c

std.Build.ConfigHeaderStep: support outputting assembly config files


1 files changed, 58 insertions(+), 6 deletions(-)

lib/std/Build/ConfigHeaderStep.zig+58-6
...@@ -13,11 +13,13 @@ pub const Style = union(enum) {...@@ -13,11 +13,13 @@ pub const Style = union(enum) {
13 cmake: std.Build.FileSource,13 cmake: std.Build.FileSource,
14 /// Instead of starting with an input file, start with nothing.14 /// Instead of starting with an input file, start with nothing.
15 blank,15 blank,
16 /// Start with nothing, like blank, and output a nasm .asm file.
17 nasm,
1618
17 pub fn getFileSource(style: Style) ?std.Build.FileSource {19 pub fn getFileSource(style: Style) ?std.Build.FileSource {
18 switch (style) {20 switch (style) {
19 .autoconf, .cmake => |s| return s,21 .autoconf, .cmake => |s| return s,
20 .blank => return null,22 .blank, .nasm => return null,
21 }23 }
22 }24 }
23};25};
...@@ -84,6 +86,10 @@ pub fn addValues(self: *ConfigHeaderStep, values: anytype) void {...@@ -84,6 +86,10 @@ pub fn addValues(self: *ConfigHeaderStep, values: anytype) void {
84 return addValuesInner(self, values) catch @panic("OOM");86 return addValuesInner(self, values) catch @panic("OOM");
85}87}
8688
89pub fn getFileSource(self: *ConfigHeaderStep) std.Build.FileSource {
90 return .{ .generated = &self.output_file };
91}
92
87fn addValuesInner(self: *ConfigHeaderStep, values: anytype) !void {93fn addValuesInner(self: *ConfigHeaderStep, values: anytype) !void {
88 inline for (@typeInfo(@TypeOf(values)).Struct.fields) |field| {94 inline for (@typeInfo(@TypeOf(values)).Struct.fields) |field| {
89 try putValue(self, field.name, field.type, @field(values, field.name));95 try putValue(self, field.name, field.type, @field(values, field.name));
...@@ -164,22 +170,31 @@ fn make(step: *Step) !void {...@@ -164,22 +170,31 @@ fn make(step: *Step) !void {
164 var output = std.ArrayList(u8).init(gpa);170 var output = std.ArrayList(u8).init(gpa);
165 defer output.deinit();171 defer output.deinit();
166172
167 try output.appendSlice("/* This file was generated by ConfigHeaderStep using the Zig Build System. */\n");173 const header_text = "This file was generated by ConfigHeaderStep using the Zig Build System.";
174 const c_generated_line = "/* " ++ header_text ++ " */\n";
175 const asm_generated_line = "; " ++ header_text ++ "\n";
168176
169 switch (self.style) {177 switch (self.style) {
170 .autoconf => |file_source| {178 .autoconf => |file_source| {
179 try output.appendSlice(c_generated_line);
171 const src_path = file_source.getPath(self.builder);180 const src_path = file_source.getPath(self.builder);
172 const contents = try std.fs.cwd().readFileAlloc(gpa, src_path, self.max_bytes);181 const contents = try std.fs.cwd().readFileAlloc(gpa, src_path, self.max_bytes);
173 try render_autoconf(contents, &output, self.values, src_path);182 try render_autoconf(contents, &output, self.values, src_path);
174 },183 },
175 .cmake => |file_source| {184 .cmake => |file_source| {
185 try output.appendSlice(c_generated_line);
176 const src_path = file_source.getPath(self.builder);186 const src_path = file_source.getPath(self.builder);
177 const contents = try std.fs.cwd().readFileAlloc(gpa, src_path, self.max_bytes);187 const contents = try std.fs.cwd().readFileAlloc(gpa, src_path, self.max_bytes);
178 try render_cmake(contents, &output, self.values, src_path);188 try render_cmake(contents, &output, self.values, src_path);
179 },189 },
180 .blank => {190 .blank => {
191 try output.appendSlice(c_generated_line);
181 try render_blank(&output, self.values, self.include_path);192 try render_blank(&output, self.values, self.include_path);
182 },193 },
194 .nasm => {
195 try output.appendSlice(asm_generated_line);
196 try render_nasm(&output, self.values);
197 },
183 }198 }
184199
185 hash.update(output.items);200 hash.update(output.items);
...@@ -253,7 +268,7 @@ fn render_autoconf(...@@ -253,7 +268,7 @@ fn render_autoconf(
253 any_errors = true;268 any_errors = true;
254 continue;269 continue;
255 };270 };
256 try renderValue(output, name, kv.value);271 try renderValueC(output, name, kv.value);
257 }272 }
258273
259 for (values_copy.keys()) |name| {274 for (values_copy.keys()) |name| {
...@@ -304,7 +319,7 @@ fn render_cmake(...@@ -304,7 +319,7 @@ fn render_cmake(
304 any_errors = true;319 any_errors = true;
305 continue;320 continue;
306 };321 };
307 try renderValue(output, name, kv.value);322 try renderValueC(output, name, kv.value);
308 }323 }
309324
310 for (values_copy.keys()) |name| {325 for (values_copy.keys()) |name| {
...@@ -338,7 +353,7 @@ fn render_blank(...@@ -338,7 +353,7 @@ fn render_blank(
338353
339 const values = defines.values();354 const values = defines.values();
340 for (defines.keys()) |name, i| {355 for (defines.keys()) |name, i| {
341 try renderValue(output, name, values[i]);356 try renderValueC(output, name, values[i]);
342 }357 }
343358
344 try output.appendSlice("#endif /* ");359 try output.appendSlice("#endif /* ");
...@@ -346,7 +361,14 @@ fn render_blank(...@@ -346,7 +361,14 @@ fn render_blank(
346 try output.appendSlice(" */\n");361 try output.appendSlice(" */\n");
347}362}
348363
349fn renderValue(output: *std.ArrayList(u8), name: []const u8, value: Value) !void {364fn render_nasm(output: *std.ArrayList(u8), defines: std.StringArrayHashMap(Value)) !void {
365 const values = defines.values();
366 for (defines.keys()) |name, i| {
367 try renderValueNasm(output, name, values[i]);
368 }
369}
370
371fn renderValueC(output: *std.ArrayList(u8), name: []const u8, value: Value) !void {
350 switch (value) {372 switch (value) {
351 .undef => {373 .undef => {
352 try output.appendSlice("/* #undef ");374 try output.appendSlice("/* #undef ");
...@@ -376,3 +398,33 @@ fn renderValue(output: *std.ArrayList(u8), name: []const u8, value: Value) !void...@@ -376,3 +398,33 @@ fn renderValue(output: *std.ArrayList(u8), name: []const u8, value: Value) !void
376 },398 },
377 }399 }
378}400}
401
402fn renderValueNasm(output: *std.ArrayList(u8), name: []const u8, value: Value) !void {
403 switch (value) {
404 .undef => {
405 try output.appendSlice("; %undef ");
406 try output.appendSlice(name);
407 try output.appendSlice("\n");
408 },
409 .defined => {
410 try output.appendSlice("%define ");
411 try output.appendSlice(name);
412 try output.appendSlice("\n");
413 },
414 .boolean => |b| {
415 try output.appendSlice("%define ");
416 try output.appendSlice(name);
417 try output.appendSlice(if (b) " 1\n" else " 0\n");
418 },
419 .int => |i| {
420 try output.writer().print("%define {s} {d}\n", .{ name, i });
421 },
422 .ident => |ident| {
423 try output.writer().print("%define {s} {s}\n", .{ name, ident });
424 },
425 .string => |string| {
426 // TODO: use nasm-specific escaping instead of zig string literals
427 try output.writer().print("%define {s} \"{}\"\n", .{ name, std.zig.fmtEscapes(string) });
428 },
429 }
430}