Some frameworks (Qt, Windows, Gtk...) offer functionality to add resources to your binaries. I wonder if it would be possible to achieve this without the framework, since all that is really needed is
How can this be achieved with the gcc toolchain?
You could do this:
objcopy --input binary \
--output elf32-i386 \
--binary-architecture i386 my_file.xml myfile.o
This produces an object file that you can link into your executable. This file will contain these symbols that you'll have to declare in your C code to be able to use them
00000550 D _binary_my_file_xml_end
00000550 A _binary_my_file_xml_size
00000000 D _binary_my_file_xml_start
At its most basic, the equivalent is a char
array full of bytes.
On Linux you can use xxd -i <file>
to "compile" files into char
arrays, then link the arrays into your binary and use the constituent bytes however you please.
Here's an example from my own code's makefile
, that creates a "resource file" called templates.h
containing a bunch of char
arrays representing HTML templates:
templates.h:
@echo "#ifndef REDACTED_TEMPLATES_H" > templates.h
@echo "#define REDACTED_TEMPLATES_H" >> templates.h
@echo "// Auto-generated file! Do not modify!" >> templates.h
@echo "// NB: arrays are not null-terminated" >> templates.h
@echo "// (anonymous namespace used to force internal linkage)" >> templates.h
@echo "namespace {" >> templates.h
@echo "namespace templates {" >> templates.h
@cd templates;\
for i in * ;\
do \
echo "Compiling $$i...";\
xxd -i $$i | sed -e 's/ =/ __attribute__((unused)) =/' >> ../templates.h;\
done;\
cd ..
@echo "}" >> templates.h
@echo "}" >> templates.h
@echo "#endif" >> templates.h
(see also: How best can I programmatically apply `__attribute__ ((unused))` to these auto-generated objects?)
The result looks a little like:
#ifndef REDACTED_TEMPLATES_H
#define REDACTED_TEMPLATES_H
// Auto-generated file! Do not modify!
// NB: arrays are not null-terminated
// (anonymous namespace used to force internal linkage)
namespace {
namespace templates {
unsigned char alert_email_finished_events_html[] __attribute__((unused)) = {
0x3c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73,
0x3d, 0x22, 0x6e, 0x6f, 0x64, 0x65, 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x2d,
[..]
0x7d, 0x7d, 0x0d, 0x0a, 0x3c, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e,
0x0d, 0x0a
};
unsigned int alert_email_finished_events_html_len __attribute__((unused)) = 290;
unsigned char alert_email_finished_events_list_html[] __attribute__((unused)) = {
0x3c, 0x74, 0x72, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x73,
0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x2d, 0x70, 0x72, 0x65, 0x76,
[..]
0x73, 0x74, 0x7d, 0x7d, 0x0d, 0x0a
};
unsigned int alert_email_finished_events_list_html_len __attribute__((unused)) = 42;
}
}
#endif
Note that this particular example is optimal when using the resource in only one Translation Unit, but the general approach can be adapted to suit your needs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With