I'm looking for a way to easily embed any external binary data in a C/C++ application compiled by GCC.
A good example of what I'd like to do is handling shader code - I can just keep it in source files like const char* shader = "source here";
but that's extremely impractical.
I'd like the compiler to do it for me: upon compilation (linking stage), read file "foo.bar" and link its content to my program, so that I'd be able to access the contents as binary data from the code.
Could be useful for small applications which I'd like to distribute as a single .exe file.
Does GCC support something like this?
The
.incbin
GAS directive can be used for this task. Here is a totally free licenced library that wraps around it:https://github.com/graphitemaster/incbin
To recap. The incbin method is like this. You have a thing.s assembly file that you compile with gcc -c thing.s
In your c or cpp code you can reference it with:
So then you link the resulting .o with the rest of the compilation units. Credit where due is to @John Ripley with his answer here: C/C++ with GCC: Statically add resource files to executable/library
But the above is not as convenient as what incbin can give you. To accomplish the above with incbin you don't need to write any assembler. Just the following will do:
As well as the suggestions already mentioned, under linux you can use the hex dump tool xxd, which has a feature to generate a C header file:
There are a couple possibilities:
use ld's capability to turn any file into an object (Embedding binary blobs using gcc mingw):
use a
bin2c
/bin2h
utility to turn any file into an array of bytes (Embed image in code, without using resource section or external images)Update: Here's a more complete example of how to use data bound into the executable using
ld -r -b binary
:Update 2 - Getting the resource size: I could not read the _binary_foo_bar_size correctly. At runtime, gdb shows me the right size of the text resource by using
display (unsigned int)&_binary_foo_bar_size
. But assigning this to a variable gave always a wrong value. I could solve this issue the following way:It is a workaround, but it works good and is not too ugly.
You could do this in a header file :
and just include that.
Other way is to read the shader file.