This CMake module provides the function add_resource_library
, which can be used to embed binary or text resource files into a static or shared library.
add_resource_library(name <STATIC | SHARED> [file1] [file2 ...])
- Copy ResourceLibrary.cmake to a directory in your module path, e.g. cmake
- Include it in your CMakeLists.txt using
include(ResourceLibrary)
- (Optional) When using GCC, Clang or Apple Clang, set
RESOURCE_LIBRARY_USE_ASM
toOn
(see How it works below) - Define a resource library, either STATIC or SHARED, containing a list of files:
add_resource_library(ExampleResourceLibrary STATIC example.txt directory/example.png)
- Add it to another target's link libraries:
target_link_libraries(ExampleTarget ExampleResourceLibrary)
- Include the resource library's header file, with the same name as its target:
The resource library will then be available in a namespace containing functions for accessing the embedded resources:
#include<ExampleResourceLibrary.h>
Use the file names passed tonamespace ExampleResourceLibrary { const std::map<std::string, std::vector<std::uint8_t>>& resources(); const std::vector<std::uint8_t>& resourceData(const std::string& resource_name); std::string resourceDataAsString(const std::string& resource_name); bool hasResource(const std::string& resource_name); }
add_resource_library
to identify a resource:std::string contents = ExampleResourceLibrary::resourceDataAsString("example.txt");
See the example directory for a minimal project using a resource library.
Calling add_resource_library
will create a library target and a series of custom commands, one to create the header file, one for each resource, and one for a loader file which contains the implementations of the functions above. These commands call ResourceLibrary.cmake in script mode to generate the files.
By default, the contents of the resource files are converted to byte-wise hex representation and then used as initializers for unsigned char
arrays. When the CMake option RESOURCE_LIBRARY_USE_ASM
is set to On
, the resources are directly included in x86 assembly files using .incbin
. In both cases, the arrays are used to create a std::vector<std::uint8_t>
for each resource in a per-library std::map
once the resource library is first used.