CMakeRC Documentation

repository·master·Indexed 21 days ago

https://github.com/vector-of-bool/cmrc

A standalone CMake-based C++ resource compiler that embeds arbitrary data such as files, images, and scripts directly into a C++ executable. It provides the cmrc::embedded_filesystem API for accessing embedded resources, including methods for opening files, checking existence, and iterating through directories via cmrc::directory_iterator and cmrc::directory_entry.

Tokens
1.4K
Snippets
4
Records
7
Agent score
23%

What's inside CMakeRC

  1. Install CMakeRC

    master

    CMakeRC is distributed as a single CMake module, CMakeRC.cmake. You can install it using one of the following methods:

    1. Manual Copy (Recommended): Copy the CMakeRC.cmake script directly into your project directory.
    2. vcpkg: If you use vcpkg, you can install the cmakerc port via:
      vcpkg install cmakerc
       Or by adding `cmakerc` to the `dependencies` section of your `vcpkg.json` file.
    3. **Package Manager:** If installed as a system package, use `find_package(CMakeRC)` in your CMake configuration.
    
    vcpkg install cmakerc
  2. Access embedded resources in C++

    master

    To access the compiled resources within your C++ source code:

    1. Include the header: #include <cmrc/cmrc.hpp> (this is automatically provided to targets linking against a CMakeRC library).
    2. Declare the library: Use the CMRC_DECLARE(<namespace>) macro at global scope. The <namespace> must match the NAMESPACE argument used in cmrc_add_resource_library (or the library name if no namespace was specified).
    3. Get the filesystem handle: Call get_filesystem() within the declared namespace to obtain a cmrc::embedded_filesystem object.

    Example:

    #include <cmrc/cmrc.hpp>
    
    // Declare the namespace used in CMake
    CMRC_DECLARE(foo);
    
    int main() {
        // Obtain the handle
        auto fs = cmrc::foo::get_filesystem();
        
        // Use the filesystem to open a file
        auto file = fs.open("images/logo.png");
    }
    #include <cmrc/cmrc.hpp>
    
    CMRC_DECLARE(foo);
    
    int main() {
        auto fs = cmrc::foo::get_filesystem();
    }
  3. Use CMakeRC in a CMake project

    master

    To integrate CMakeRC into your build system, follow these steps:

    1. Import the module:

      • If copied to your project: include(CMakeRC)
      • If installed via package manager: find_package(CMakeRC)
    2. Create a resource library: Use cmrc_add_resource_library to define a target containing your files. It is recommended to use the ALIAS argument to create a namespaced target (e.g., foo::rc).

      • Note on Namespaces: If your library name is not a valid C++ identifier, you must provide the NAMESPACE argument.
    3. Link the library: Link the generated target to your executable using target_link_libraries.

    Example Workflow:

    # 1. Import
    include(CMakeRC)
    
    # 2. Create library with an alias and a specific C++ namespace
    cmrc_add_resource_library(foo-resources ALIAS foo::rc NAMESPACE foo images/logo.png)
    
    # 3. Link to executable
    add_executable(my-program main.cpp)
    target_link_libraries(my-program PRIVATE foo::rc)
    cmrc_add_resource_library(foo-resources ALIAS foo::rc NAMESPACE foo images/logo.png)
    
    add_executable(my-program main.cpp)
    target_link_libraries(my-program PRIVATE foo::rc)
  4. Configure resource paths with `WHENCE` and `PREFIX`

    master

    When using cmrc_add_resource_library or cmrc_add_resources, you can control how file paths are mapped inside the binary using two keyword parameters:

    • WHENCE <path>: Tells CMakeRC how to rewrite filepaths. It defines the root directory from which resource paths are calculated. This is required for files located outside the current source directory. The default is CMAKE_CURRENT_SOURCE_DIR.
    • PREFIX <string>: Prepends a directory-style path to all resources in the library. This is useful for avoiding filename collisions between different libraries.

    Example: If you have a directory images/ containing rose.jpg and you use:

    cmrc_add_resource_library(flower-images
        NAMESPACE flower
        WHENCE images
        PREFIX flowers
        images/rose.jpg
    )

    The file will be accessible in C++ via fs.open("flowers/rose.jpg").

    Combined Usage Example:

    cmrc_add_resource_library(
        flower-images
        NAMESPACE flower
        WHENCE images
        PREFIX flowers
        images/rose.jpg
        images/tulip.jpg
        images/daisy.jpg
        images/sunflower.jpg
        )
    cmrc_add_resource_library(
        flower-images
        NAMESPACE flower
        WHENCE images
        PREFIX flowers
        images/rose.jpg
        images/tulip.jpg
        images/daisy.jpg
        images/sunflower.jpg
        )
  5. The `cmrc::directory_iterator` and `cmrc::directory_entry` APIs

    master

    Use these to traverse directory structures within the embedded filesystem.

    cmrc::directory_iterator Members:

    • operator*() -> cmrc::directory_entry: Returns the entry for the current position.
    • operator++, operator==, operator!=: Standard iterator semantics.
    • begin(), end(): Standard iterator methods.

    cmrc::directory_entry Members:

    • filename() -> std::string: Returns the name of the entry.
    • is_file() -> bool: Returns true if the entry is a file.
    • is_directory() -> bool: Returns true if the entry is a directory.
  6. The `cmrc::file` API

    master

    The cmrc::file object represents a single resource file.

    Members:

    • begin() / cbegin() -> iterator: Returns an iterator to the start of the file data.
    • end() / cend() -> iterator: Returns an iterator to the end of the file data.
    • file(): Default constructor (refers to no resource).
    • Iterators: The iterator and const_iterator types are simply const char*.
  7. The `cmrc::embedded_filesystem` API

    master

    The cmrc::embedded_filesystem class acts as a handle to the statically allocated resource data. It is trivially copyable and destructible.

    Available Methods:

    • open(const std::string& path) -> cmrc::file: Opens a non-directory file at path. Throws std::system_error() if the file does not exist or is a directory.
    • is_file(const std::string& path) -> bool: Returns true if the path is a regular file.
    • is_directory(const std::string& path) -> bool: Returns true if the path is a directory.
    • exists(const std::string& path) -> bool: Returns true if the path exists.
    • iterate_directory(const std::string& path) -> cmrc::directory_iterator: Returns an iterator for the directory contents. Throws if path is not a directory.