Skip to content

Instantly share code, notes, and snippets.

@louisswarren
Last active March 10, 2023 23:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save louisswarren/ef7160914fc1aeff3c210bf0b0236775 to your computer and use it in GitHub Desktop.
Save louisswarren/ef7160914fc1aeff3c210bf0b0236775 to your computer and use it in GitHub Desktop.
Include files at compile time in C
Hello, world!
This file ends with a null character:
No null termination here - these are just bytes.
static inline
size_t
included_length_raw(const char *s, const char *e)
{
return e - s;
}
static inline
const unsigned char *
included_bytes_raw(const char *s, const char *e)
{
return s;
}
static inline
const char *
included_string_raw(const char *s, const char *e)
{
assert(e[-1] == '\0' || s < e - 1 && e[-2] == '\0');
return s;
}
#define include_file(X) \
extern const char _binary_##X##_start[], _binary_##X##_end[]
#define included_length(X) \
included_length_raw(_binary_##X##_start, _binary_##X##_end)
#define included_bytes(X) \
included_bytes_raw(_binary_##X##_start, _binary_##X##_end)
#define included_string(X) \
included_string_raw(_binary_##X##_start, _binary_##X##_end)
#include <stdio.h>
#include <assert.h>
#include "include_file.h"
include_file(incl_hello_txt);
include_file(incl_message_txt);
int
main(void)
{
printf("Hello: \"%s\"\n", included_string(incl_hello_txt));
printf("Message: \"");
fwrite(included_bytes(incl_message_txt), 1,
included_length(incl_message_txt), stdout);
printf("\"\n");
printf("This will fail due to the assertion failing: %s",
included_string(incl_message_txt));
}
.PHONY: test
test: main
./$<
main: main.o incl_hello.o incl_message.o
main.o: main.c include_file.h
incl_%.o: incl_%.txt
@# If you always want to use includes as strings, you can check that
@# they are null-terminated at compile-time:
@# grep -qPa '\x00' $<
ld -z noexecstack -r -b binary -o $@ $<
.PHONY: clean
clean:
rm -f *.o main
@louisswarren
Copy link
Author

louisswarren commented Mar 10, 2023

Hello: "Hello, world!
This file ends with a null character: "
Message: "No null termination here - these are just bytes.
"
main: include_file.h:19: included_string_raw: Assertion `e[-1] == '\0' || s < e - 1 && e[-2] == '\0'' failed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment