Embedded data in C header

Hello! I’m working on a C project that uses the Zig build system. I have several shader source files in this project that I’d like to embed. If I were writing Zig, I would use @embedFile(), but I’d like these in a C header. I tried cmake-style templates with addConfigHeader(), which worked, but the resulting substitution doesn’t escape newline characters, and won’t compile. My next approach is to make a small Zig lib with these files embedded and link against that in my C program, but was wondering if there is a simpler way. Thanks!

C recently (in C23) the #embed macro which allows you to directly embed files in C code. This is what you’re looking for IIUC.

AFAIK #embed is not yet fully supported by zig build-exe or the build system, but there is an open PR that adds the ability to specify the search path for files to embed.

In addition to the option of linking against a small static Zig lib that uses @embedFile, another option could be creating a small-ish Zig program that takes an input file and writes a simple C source file that defines a string constant (escaping characters as needed) to an output file. The “Generating Files” section of the official build system docs has some useful examples if you want an idea of how to set up Compile and Run steps that consume and produce files that can be depended on by other steps.

1 Like

Your last approach is the one I would take (and currently take in other projects).

Shaders.h

const char *my_cool_shader_source;
size_t my_cool_shader_source_len;

Shaders.zig

const my_cool_shader = @embedFile("mycoolshader.sl");
export const my_cool_shader_source: []const u8 = my_cool_shader.ptr;
export const my_cool_shader_len: usize = my_cool_shader.len;

P.S. castholm’s suggestion of a codegen step also sounds reasonable

2 Likes