| ... | @@ -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, |
| 16 | | 18 | |
| 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 | } |
| 86 | | 88 | |
| | 89 | pub fn getFileSource(self: *ConfigHeaderStep) std.Build.FileSource { |
| | 90 | return .{ .generated = &self.output_file }; |
| | 91 | } |
| | 92 | |
| 87 | fn addValuesInner(self: *ConfigHeaderStep, values: anytype) !void { | 93 | fn 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(); |
| 166 | | 172 | |
| 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"; |
| 168 | | 176 | |
| 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 | } |
| 184 | | 199 | |
| 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 | } |
| 258 | | 273 | |
| 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 | } |
| 309 | | 324 | |
| 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( |
| 338 | | 353 | |
| 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 | } |
| 343 | | 358 | |
| 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 | } |
| 348 | | 363 | |
| 349 | fn renderValue(output: *std.ArrayList(u8), name: []const u8, value: Value) !void { | 364 | fn 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 | |
| | 371 | fn 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 | |
| | 402 | fn 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 | } |