.. index:: single: Resources; Compiling into Applications and Libraries single: CMake; Compiled Resources ************************************************** Compiling Resources into an Application or Library ************************************************** Compiled resources place small application data directly in an executable or static library and expose it through a lazy, read-only lookup interface. This avoids deployment-time file discovery for defaults, templates, schemas, and other data that belongs to a specific application build. Add Resources to a Target ========================= Call ``erbsland_core_add_resources`` after creating an executable or static-library target. The command configures the target for Erbsland Core automatically, scans the directory at configuration time, and generates one data source and one descriptor source for every selected regular file. .. code-block:: cmake add_executable(my_app main.cpp) erbsland_core_add_resources( TARGET my_app DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/data" IDENTIFIER "my_data" RECURSIVE SUFFIXES ".jpeg" ".xml" ".json" ) For a static library, use the same command with the library target. Its generated resource objects are built in an internal companion archive, which is retained automatically when the library is linked into an executable, even when no ordinary library symbol refers to them. Static libraries with compiled resources cannot be exported or installed as CMake package targets; CMake stops with an error if such an export is attempted. .. code-block:: cmake add_library(my_library STATIC library.cpp) erbsland_core_add_resources( TARGET my_library DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/data" IDENTIFIER "my_library_data" ) The identifier is a portable ASCII token chosen by your application. Paths are UTF-8 relative paths with ``/`` separators and remain case-sensitive. You can call the command repeatedly and reuse an identifier as long as every ``(identifier, path)`` pair stays unique. The directory scan tracks additions and removals through CMake's configure dependencies. Suffix matching is case-sensitive. Symbolic links, empty selections, duplicate keys, and files larger than 1 MiB stop configuration with an error. Read Logical Data and Text ========================== Access resources through :cpp:func:`application().resources() `. Optional lookups are useful for fallbacks, while the required variants keep mandatory application assets concise. .. code-block:: cpp const auto &resources = el::application().resources(); if (const auto icon = resources.getData("my_data"_el, "icons/open.jpeg"_el)) { installIcon(*icon); } const auto schema = resources.getTextOrThrow("my_data"_el, "schema/main.json"_el); A present empty file produces an engaged optional containing an empty value. A missing key produces ``std::nullopt``, or :cpp:class:`ResourceError ` from an ``OrThrow`` call. If stored compressed bytes are malformed, optional logical-data and text calls return ``std::nullopt`` and required calls report the ``InvalidData`` category. Inspect Storage and Metadata ============================ The generator tries raw LZ4 compression independently for each file and retains it only when the payload is at most 80 percent of the original size. It hashes the original logical bytes with SHA3-256 by default. ``NO_COMPRESSION`` always embeds the original bytes, and ``NO_HASH`` omits both hash algorithm and digest. .. code-block:: cmake erbsland_core_add_resources( TARGET my_app DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/defaults" IDENTIFIER "defaults" NO_HASH NO_COMPRESSION ) ``getStoredData()`` borrows the exact embedded representation, which can therefore be compressed. ``getData()`` and ``getText()`` always expose original logical content. :cpp:class:`ResourceInfo ` reports the stored and original sizes, algorithms and digest, and compression state. Uncompressed text is backed directly by its generated byte storage, while compressed data and text are decoded and cached on first access. Use the Resource Compiler While Cross-Compiling =============================================== Resource generation runs a native host executable that uses the same compression and hashing implementation as the library. For a cross build, configure ``ERBSLAND_CORE_RESOURCE_COMPILER_EXECUTABLE`` with a compatible native tool built from the same Erbsland Core package. .. code-block:: shell cmake -S . -B build-target \ -DCMAKE_TOOLCHAIN_FILE=target-toolchain.cmake \ -DERBSLAND_CORE_RESOURCE_COMPILER_EXECUTABLE=/host/bin/erbsland-core-resource-compiler Cross configuration fails early when no host tool is supplied. The compiler also validates its generation protocol before writing any source files.