#making files in build.zig
1 messages · Page 1 of 1 (latest)
https://github.com/Cloudef/zig-budoux/blob/master/build.zig
See the addAnonymousImport here
After that you can embedFile with the name
thank u I didn't know that imports could be used in embedFile
Yeah its confusing
Similarily addAnonymousImport root_source_file is confusing, but it works
The one thing I'm never quite done with understanding about zig is the build system TT
That said, maybe this little piece of code I use in my build.zig files might help you:
/// Allows you to `@import(name)` any data into a compilation unit:
///
/// embed_str_as_module(b, "pub const SomeConstant: usize = 1337;", "constants.zig", lib);
///
/// Then somewhere in the lib's code:
///
/// const constants = @import("constants.zig");
/// std.log.debug("{}", .{constants.SomeConstant});
///
/// which will print "1337"
fn embed_str_as_module(b: *std.Build, comptime str: []const u8, comptime name: []const u8, compilation: *std.Build.Step.Compile) void {
const step_tool_runner = b.addRunArtifact(b.addExecutable(.{
.name = "Embed data as anonymous module",
.root_source_file = .{ .path = "src/stdin_to_file.zig" },
}));
step_tool_runner.setStdIn(.{ .bytes = str });
// Its a weird default but this basically adds the file name as the first argument...
const output = step_tool_runner.addOutputFileArg(name);
// allow @import to "see" the generated file `memory_info.zon`
compilation.addAnonymousModule(name, .{ .source_file = output });
compilation.step.dependOn(&step_tool_runner.step);
}
I doubt its the best way of doing this, but a few times I have wanted to calcualte X or Y in the build.zig and then provided that via an @import and I've done it like this. The comment of the function explains the usage.
This being the stdin_to_file.zig mentioned in the code:
const std = @import("std");
pub fn main() !void {
var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena_state.deinit();
const arena = arena_state.allocator();
const args = try std.process.argsAlloc(arena);
if (args.len != 2) {
std.debug.print("\n", .{});
for(args, 0..) |arg, i| std.debug.print("{}: {s}\n", .{i, arg});
fatal("wrong number of arguments", .{});
}
const output_file_path = args[1];
var output_file = std.fs.cwd().createFile(output_file_path, .{}) catch |err| {
fatal("unable to open '{s}': {s}", .{ output_file_path, @errorName(err) });
};
defer output_file.close();
var buffer: [1024]u8 = undefined;
var read = std.io.getStdIn().reader().read(&buffer) catch fatal("error reading", .{});
while(read != 0) {
_ = output_file.writer().write(buffer[0..read]) catch fatal("error writing", .{});
read = std.io.getStdIn().reader().read(&buffer) catch fatal("error reading", .{});
}
return std.process.cleanExit();
}
fn fatal(comptime format: []const u8, args: anytype) noreturn {
std.debug.print(format, args);
std.process.exit(1);
}
there is also writeFiles
like ☝️ suggests, you can use a write files step for this. b.addWriteFiles().add(...) is the most concise way of turning a string into a file:
exe.root_module.addAnonymousImport("generated", .{
.root_source_file = b.addWriteFiles().add("generated.txt",
\\HELLO
\\I AM A STRING
\\THAT CAN BE IMPORTED
\\WITH @embedFile("generated")
\\
),
});
const std = @import("std");
const generated = @embedFile("generated");
pub fn main() !void {
std.debug.print("{s}", .{generated});
}
works with both @import and @embedFile