Embed resources (eg, shader code; images) into executable/library with CMake
One of the easiest ways to do this is to include a small, portable C program in your build that reads the resource and generates a C file that contains the length of the resource data and the actual resource data as an array of constant character literals. This will be entirely platform independent, but should only be used for resources that are reasonably small. For larger resources, you probably don't want to embed the files in your program.
For resource "foo", the generated C file "foo.c" would contain:
const char foo[] = { /* bytes of resource foo */ };
const size_t foo_len = sizeof(foo);
To access the resource from C++, you declare the following two symbols in either a header or the cpp file where they're used:
extern "C" const char foo[];
extern "C" const size_t foo_len;
To generate foo.c
in the build, you need a target for the C program (call it embedfile.c), and you need to use the add_custom_command
command to call this program:
add_executable(embedfile embedfile.c)
add_custom_command(
OUTPUT foo.c
COMMAND embedfile foo foo.rsrc
DEPENDS foo.rsrc)
Then, include foo.c
on the source list of a target that requires the "foo" resource. You now have access to the bytes of "foo".
The program embedfile.c is:
#include <stdlib.h>
#include <stdio.h>
FILE* open_or_exit(const char* fname, const char* mode)
{
FILE* f = fopen(fname, mode);
if (f == NULL) {
perror(fname);
exit(EXIT_FAILURE);
}
return f;
}
int main(int argc, char** argv)
{
if (argc < 3) {
fprintf(stderr, "USAGE: %s {sym} {rsrc}\n\n"
" Creates {sym}.c from the contents of {rsrc}\n",
argv[0]);
return EXIT_FAILURE;
}
const char* sym = argv[1];
FILE* in = open_or_exit(argv[2], "r");
char symfile[256];
snprintf(symfile, sizeof(symfile), "%s.c", sym);
FILE* out = open_or_exit(symfile,"w");
fprintf(out, "#include <stdlib.h>\n");
fprintf(out, "const char %s[] = {\n", sym);
unsigned char buf[256];
size_t nread = 0;
size_t linecount = 0;
do {
nread = fread(buf, 1, sizeof(buf), in);
size_t i;
for (i=0; i < nread; i++) {
fprintf(out, "0x%02x, ", buf[i]);
if (++linecount == 10) { fprintf(out, "\n"); linecount = 0; }
}
} while (nread > 0);
if (linecount > 0) fprintf(out, "\n");
fprintf(out, "};\n");
fprintf(out, "const size_t %s_len = sizeof(%s);\n\n",sym,sym);
fclose(in);
fclose(out);
return EXIT_SUCCESS;
}
Is there any standard way of embedding resources into Linux executable image?
Make yourself an assembler file, blob.S:
.global blob
.global blob_size
.section .rodata
blob:
.incbin "blob.bin"
1:
blob_size:
.int 1b - blob
Compile with gcc -c blob.S -o blob.o
The blob can now be accessed from within your C program with:
extern uint8_t blob[];
extern int blob_size;
Using a bin2c converter usually works fine, but if the blob is large, the incbin solution is much faster, and uses much less memory (compile time)
Embeded spv shaders throws error while running program
You are delete[]
ing static variables. That is invalid thing to do.
Passing an arr[]
is something like passing a pointer. If you are confused about C arrays (which is understandable), then try using std::array
s instead.
Related Topics
Get Index of Qpushbutton on 2D Array Qpushbutton
Difference Between Returning Reference VS Returning Value C++
Clock Function in C++ with Threads
Weird Behaviour with Const_Cast
Choosing Embedded Scripting Language for C++
How to Make Objective-C Class Using Std:Vector Made Available to Swift Classes
Advantages of Std::For_Each Over for Loop
Typeid' Versus 'Typeof' in C++
Slot Is Being Called Multiple Times Every Time a Signal Is Emitted
Passing End of Transmission (Ctrl + D) Character in Eclipse Cdt Console
C++ Inheritance and Function Overriding
Why Do We Need a Virtual Table
Setting the Cursor Position in a Win32 Console Application
How to Read and Write a Stl C++ String
How to Reduce the Size of Executable Produced by Mingw G++ Compiler
Are Notes and Examples in the Core Language Specification of the C++ Standard Non-Normative