Skip to content

Easy-to-use CMake utility to generate C/C++ code containing binary data from files

License

Notifications You must be signed in to change notification settings

andoalon/embed-binaries

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

embed-binaries

Easy-to-use CMake utility to generate C/C++ code containing binary data from files. Useful when you want to avoid shipping extra files, but you want to still have them separately during development.

Features

  • Generates C/C++ source files with arrays containing binary data
  • Single CMake file with no dependencies except CMake >=3.17.5. Copy the file to your project and start using it!
  • Generated source files are updated at build-time whenever the original assets get modified (CMake's add_custom_command is used)
  • Platform-independent, since all of the implementation is written in CMake
  • Can optionally generate a constexpr array for compile-time manipulation in C++

Reference

embed_binaries(<generated-target-name>
  [ASSET
    NAME <name>
    PATH <path>
    [BYTE_TYPE <c-cpp-type>]
    [CONSTEXPR]
    [NULL_TERMINATE]
  ]...)
  • NAME: name of the asset (the name of the generated file and variable)
  • PATH: path to the asset file (absolute of relative to CMAKE_CURRENT_SOURCE_DIR)
  • BYTE_TYPE: type of the elements of the generated array. Defaults to: "unsigned char". Useful when embedding ascii string data (use BYTE_TYPE "char")
  • CONSTEXPR: by default, an extern const array will be declared in the header, with the contents in a corresponding .c file, which makes the header as short as possible, improving compile time, especially when embedding larger assets. If you specify this option, a constexpr array will be generated instead (which must go in the header)
  • NULL_TERMINATE: append a null-terminator (0 byte) at the end of the embedded data. Useful when embedding string data that will be used with APIs expecting null-terminated strings

Disclaimer

Having the implementation written in CMake makes this utility easy-to-use and portable, but that also makes it rather slow. This is not really noticeable for small assets (<1MB), but you will notice it as you have more and more data. During my tests, generating the code for an ~8MB big file took ~17 seconds in my machine (and generated a ~40MB big .c file!). Therefore, this utility is intended for projects where ease of use is important (e.g. personal projects) or for projects that will only have a few assets to embed. If you have different plans, I would suggest investing some time on a different solution

Example

NOTE: see the example/ directory for a full example project

include("path/to/embed-binaries.cmake")

embed_binaries(my-embedded-binaries
    ASSET
        NAME "application_logo"
        PATH "assets/application_logo.png"
    ASSET
        NAME "vertex_shader"
        PATH "shaders/dummy_shader.vert"
        BYTE_TYPE "char"
    
        CONSTEXPR # The data will be placed in the header
        
        # OpenGL does not require null-terminated strings for shaders, this is not a good example
        NULL_TERMINATE
    # ASSET ...
)

add_executable(my-executable
    # files...
)
target_link_libraries(my-executable PRIVATE my-embedded-binaries)

Sample generated code

With CONSTEXPR and DATA_TYPE "char":
fragment_shader.h

#pragma once

#ifndef __cplusplus
#error "'constexpr' is a C++ feature"
#endif

constexpr char embedded_fragment_shader[226] = {
0x23,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x33,0x33,0x30,0x0d,0x0a,0x0d,0x0a,0x69,0x6e,0x20,0x76,0x65,0x63,0x32,0x20,0x74,0x65,0x78,0x74,0x75,0x72,0x65,0x5f,
0x63,0x6f,0x6f,0x72,0x64,0x69,0x6e,0x61,0x74,0x65,0x73,0x3b,0x0d,0x0a,0x0d,0x0a,0x75,0x6e,0x69,0x66,0x6f,0x72,0x6d,0x20,0x76,0x65,0x63,0x34,0x20,0x6d,0x6f,0x64,
0x75,0x6c,0x61,0x74,0x69,0x6f,0x6e,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x3b,0x0d,0x0a,0x75,0x6e,0x69,0x66,0x6f,0x72,0x6d,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x32,
0x44,0x20,0x74,0x65,0x78,0x74,0x75,0x72,0x65,0x3b,0x0d,0x0a,0x0d,0x0a,0x6f,0x75,0x74,0x20,0x76,0x65,0x63,0x34,0x20,0x66,0x72,0x61,0x67,0x5f,0x63,0x6f,0x6c,0x6f,
0x72,0x3b,0x0d,0x0a,0x0d,0x0a,0x76,0x6f,0x69,0x64,0x20,0x6d,0x61,0x69,0x6e,0x28,0x29,0x0d,0x0a,0x7b,0x0d,0x0a,0x09,0x66,0x72,0x61,0x67,0x5f,0x63,0x6f,0x6c,0x6f,
0x72,0x20,0x3d,0x20,0x74,0x65,0x78,0x74,0x75,0x72,0x65,0x28,0x74,0x65,0x78,0x74,0x75,0x72,0x65,0x2c,0x20,0x74,0x65,0x78,0x74,0x75,0x72,0x65,0x5f,0x63,0x6f,0x6f,
0x72,0x64,0x69,0x6e,0x61,0x74,0x65,0x73,0x29,0x20,0x2a,0x20,0x6d,0x6f,0x64,0x75,0x6c,0x61,0x74,0x69,0x6f,0x6e,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x3b,0x0d,0x0a,0x7d,
0x0d,0x0a,
};

Normal mode:
application_logo.h

#pragma once

#ifdef __cplusplus
extern "C" {
#endif

extern const unsigned char embedded_application_logo[212253];

#ifdef __cplusplus
}
#endif

application_logo.c

#include "application_logo.h"

#ifdef __cplusplus
extern "C" {
#endif

const unsigned char embedded_application_logo[212253] = {
0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,0x00,0x00,0x02,0x64,0x00,0x00,0x01,0x99,0x08,0x02,0x00,0x00,0x00,0xa8,0x97,0xba,
/* 6632 more lines... */
};

#ifdef __cplusplus
}
#endif

About

Easy-to-use CMake utility to generate C/C++ code containing binary data from files

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published