Embedding files in C programs with koio May 29, 2018 on Drew DeVault's blog

Quick blog post today to introduce a new tool I wrote: koio. This is a small tool which takes a list of files and embeds them in a C file. A library provides an fopen shim which checks the list of embedded files before resorting to the real filesystem.

I made this tool for chopsui, where I eventually want to be able to bundle up sui markup, stylesheets, images, and so on in a statically linked chopsui program. Many projects have small tools which serve a similar purpose, but it was simple enough and useful enough that I chose to make something generic so it could be used on several projects.

The usage is pretty simple. I can embed ko_fopen.c in a C file with this command:

$ koio -o bundle.c ko_fopen.c://ko_fopen.c

I can compile and link with bundle.c and do something like this:

#include <koio.h>

void koio_load_assets(void);
void koio_unload_assets(void);

int main(int argc, char **argv) {
    FILE *src = ko_fopen("//ko_fopen.c", "r");
    int c;
    while ((c = fgetc(src)) != EOF) {
    return 0;

The generated bundle.c looks like this:

#include <koio.h>

static struct {
	const char *path;
	size_t len;
	char *data;
} files[] = {
		.path = "//ko_fopen.c",
		.len = 408,
		.data =
"#define _POSIX_C_SOURCE 200809L\n#include <errno.h>\n#include <stdlib.h>\n#inc"
"lude <stdio.h>\n#include \"koio_private.h\"\n\nFILE *ko_fopen(const char *path"
", const char *mode) {\n\tstruct file_entry *entry = hashtable_get(&koio_vfs, p"
"ath);\n\tif (entry) {\n\t\tif (mode[0] != 'r' || mode[1] != '\\0') {\n\t\t\ter"
"rno = ENOTSUP;\n\t\t\treturn NULL;\n\t\t}\n\t\treturn fmemopen(entry->data, en"
"try->len, \"r\");\n\t}\n\treturn fopen(path, mode);\n}\n",

void koio_load_assets(void) {
	ko_add_file(files[0].path, files[0].data, files[0].len);

void koio_unload_assets(void) {

A very simple tool, but one that I hope people will find useful. It’s very lightweight:


Have a comment on one of my posts? Start a discussion in my public inbox by sending an email to ~sircmpwn/public-inbox@lists.sr.ht [mailing list etiquette]

Articles from blogs I read Generated by openring

Go runtime: 4 years later

A check-in on the status of Go runtime development

via The Go Blog September 26, 2022

What's cooking on Sourcehut? September 2022

Guten Morgen, SourceHut! Today, I count 681 new users, for a grand total of 32281 registered users. As always, a warm welcome to them and the reminder to everyone else to help them feel welcome while they get settled. Today, I am filling in for Drew on short…

via Blogs on Sourcehut September 15, 2022

Status update, September 2022

Hi all! This month I’ve been working on stuff I’d usually not work on willingly. And by that I mean Rust and screen tearing of course. I’ve been randomly typing keys on my keyboard and before I knew it, a wlroots-rs repository was created. Everybody is saying…

via emersion September 15, 2022