# Copyright (c) 2026 Dominic Masters # # This software is released under the MIT License. # https://opensource.org/licenses/MIT # Asset building. Include this from the root CMakeLists.txt. # # Assets are registered with add_asset() and built by dusk_assets_finalize(). # Each asset is dispatched on its file extension to a handler function named # dusk_asset_ (e.g. dusk_asset_obj), defined in its own file in this # directory. Extensions without a handler fall back to a plain copy. include(${CMAKE_CURRENT_LIST_DIR}/copy.cmake) include(${CMAKE_CURRENT_LIST_DIR}/obj.cmake) # Registers an asset to be built into the project. The path is relative to the # calling CMakeLists.txt, and is kept relative to the root assets directory in # the output, so assets/models/a.obj ends up at /assets/models/a.obj. # # This only records the asset. The build rules are created by # dusk_assets_finalize() from the root CMakeLists.txt, because a custom command # output can only be used by targets in the directory it was defined in. function(add_asset ASSET_PATH) set(ASSET_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/${ASSET_PATH}") if(NOT EXISTS "${ASSET_SOURCE}") message(FATAL_ERROR "add_asset: ${ASSET_SOURCE} does not exist") endif() set_property(GLOBAL APPEND PROPERTY DUSK_ASSET_SOURCES "${ASSET_SOURCE}") endfunction() # Determines the lowercase extension of an asset, without the leading dot. function(dusk_asset_extension ASSET_SOURCE OUT_VAR) get_filename_component(ASSET_EXT "${ASSET_SOURCE}" LAST_EXT) string(TOLOWER "${ASSET_EXT}" ASSET_EXT) string(REGEX REPLACE "^\\." "" ASSET_EXT "${ASSET_EXT}") set(${OUT_VAR} "${ASSET_EXT}" PARENT_SCOPE) endfunction() # Creates the TARGET_NAME target, which builds every asset registered with # add_asset(). Call once from the root CMakeLists.txt after adding the assets. function(dusk_assets_finalize TARGET_NAME) get_property(ASSET_SOURCES GLOBAL PROPERTY DUSK_ASSET_SOURCES) set(ASSET_OUTPUTS "") foreach(ASSET_SOURCE IN LISTS ASSET_SOURCES) file(RELATIVE_PATH ASSET_RELATIVE "${DUSK_ASSETS_DIR}" "${ASSET_SOURCE}") dusk_asset_extension("${ASSET_SOURCE}" ASSET_EXT) # Dispatch on the extension, falling back to a plain copy. set(ASSET_OUTPUT "") if(COMMAND dusk_asset_${ASSET_EXT}) cmake_language(CALL dusk_asset_${ASSET_EXT} "${ASSET_SOURCE}" "${ASSET_RELATIVE}" ASSET_OUTPUT ) else() message(STATUS "Asset ${ASSET_RELATIVE}: no handler for '.${ASSET_EXT}', copying") dusk_asset_copy("${ASSET_SOURCE}" "${ASSET_RELATIVE}" ASSET_OUTPUT) endif() list(APPEND ASSET_OUTPUTS "${ASSET_OUTPUT}") endforeach() add_custom_target(${TARGET_NAME} ALL DEPENDS ${ASSET_OUTPUTS}) endfunction()