2

I am trying to bundle together some resources (images, music and data files) into my binary application (written in C++).

I want to have everything contained in a single executable file (so that I could just ship the (large) executable file and it would work, no assets could be deleted).

I see Visual Studio and windows have something called resources files that look like they are designed to do just this.

However, I am interested if there is a cross platform way, or, if there is not, what the Linux equivalent to resource files is (if there is one, provided my any IDE or compiler).

I want to be able to have my entire program contained within one file and so I am not interested in a separate assets or resources directory.

I have found several older answers but find it hard to believe there is not a modern way to do this on Linux.

It seems like the solution is to:

A. Use resource files on Windows

B. Use something that converts the resource into a .c char array and load that on Linux.

Is this really what it takes and if so: what would be the most convenient way to include this process in a cross platform build cycle? Is there some function that CMAKE can run before a program is built?

17
  • 1
    Try Qt ? Qt can embed resource directly into the final executable. Commented Jan 18, 2018 at 16:47
  • What do you mean, "modern"? There's not a lot of bells and whistles you can put on packing a binary file into your executable... Commented Jan 18, 2018 at 16:47
  • 3
    @RSahu .rc files are text files which list arbitrary files to be packed into the executable by the Resource Compiler. In fact I'm knees deep in there right now, waiting for it to finish ;) Commented Jan 18, 2018 at 16:58
  • 3
    @Startec I have oversimplified, my bad. The resource compiler reads in .rc files, locates the listed files and packs them into a .res file, which is passed to the linker along with the usual .obj files and then linked into the executable. Retrieving a resource is done via LoadResource, which hands you back a void* to the beginning of the resource. Commented Jan 18, 2018 at 17:18
  • 1
    @Startec indeed, the executable is then stand-alone. Commented Jan 18, 2018 at 17:22

1 Answer 1

3

I've seen people xxd|sed their binary resources into C const uint8_t arrays. It could be c++ifyed:

Resource1.h

#include <cstdint>
#include <array>
extern std::array<uint8_t, 1024> resource1;

Resource1.cc

#include "Resource1.h"
const std::array<uint8_t, 1024> resource1 = {
    0x42, 0x24, 0x18, ...
    ...
}

If you're not fond of regexp, here is a starting point:

hexdump file.bin | sed 's/^[0-9a-f]* \?//;s/ \?\([0-9a-f]\{2\}\) \?/0x\1, /g'

which outputs something like

0x5b, 0x6b, 0x32, 0x50, 0x69, 0x50, 0x53, 0x64, 0x61, 0x65, 0x63, 0x72, 0x52, 0x68, 0x73, 0x65, 
0x6f, 0x70, 0x73, 0x6e, 0x5d, 0x65, 0x3d, 0x20, 0x30, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 
...
Sign up to request clarification or add additional context in comments.

3 Comments

Above conversion code leaves some garbage lines and causes some missed data. I used the following (solution alluded to in OP): cat resource.bin | xxd -p | sed -s 's/\(..\)/0x\1, /g'
I don't know about this if you have large image files to include.
Is it a question?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.