# Usage: # compile_slang_shaders( # TARGET compile_shaders # custom target name to create # SRC_DIR "${CMAKE_SOURCE_DIR}/assets_src/shaders" # OUT_DIR "${CMAKE_SOURCE_DIR}/assets_runtime/shaders" # # Optional: # GLOB_PATTERN "*.slang" # default: "*.slang" # EXTRA_ARGS -O3 # forwarded to slangc # ALL # if present: target is built by default # ) # function(compile_slang_shaders) set(options ALL) set(oneValueArgs TARGET SRC_DIR OUT_DIR GLOB_PATTERN) set(multiValueArgs EXTRA_ARGS) cmake_parse_arguments(CSS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) if(NOT CSS_TARGET) message(FATAL_ERROR "compile_slang_shaders: TARGET is required") endif() if(NOT CSS_SRC_DIR) message(FATAL_ERROR "compile_slang_shaders: SRC_DIR is required") endif() if(NOT CSS_OUT_DIR) message(FATAL_ERROR "compile_slang_shaders: OUT_DIR is required") endif() if(NOT CSS_GLOB_PATTERN) set(CSS_GLOB_PATTERN "*.slang") endif() find_program(SLANGC_EXE NAMES slangc slangc.exe REQUIRED) # Collect shader sources recursively file(GLOB_RECURSE _SLANG_SOURCES CONFIGURE_DEPENDS "${CSS_SRC_DIR}/${CSS_GLOB_PATTERN}" ) if(_SLANG_SOURCES STREQUAL "") message(STATUS "compile_slang_shaders: No sources found in ${CSS_SRC_DIR} (pattern: ${CSS_GLOB_PATTERN})") endif() # Ensure base output directory exists at configure time (nice-to-have) file(MAKE_DIRECTORY "${CSS_OUT_DIR}") set(_SPV_OUTPUTS "") foreach(_SLANG_FILE IN LISTS _SLANG_SOURCES) file(RELATIVE_PATH _REL_PATH "${CSS_SRC_DIR}" "${_SLANG_FILE}") get_filename_component(_REL_DIR "${_REL_PATH}" DIRECTORY) get_filename_component(_FILE_WE "${_SLANG_FILE}" NAME_WE) set(_OUT_SUBDIR "${CSS_OUT_DIR}/${_REL_DIR}") set(_OUT_SPV "${_OUT_SUBDIR}/${_FILE_WE}.spv") add_custom_command( OUTPUT "${_OUT_SPV}" COMMAND "${CMAKE_COMMAND}" -E make_directory "${_OUT_SUBDIR}" COMMAND "${SLANGC_EXE}" "${_SLANG_FILE}" -target spirv -o "${_OUT_SPV}" ${CSS_EXTRA_ARGS} DEPENDS "${_SLANG_FILE}" COMMENT "Compiling Slang: ${_REL_PATH} -> ${_OUT_SPV}" VERBATIM ) list(APPEND _SPV_OUTPUTS "${_OUT_SPV}") endforeach() # Create target if(CSS_ALL) add_custom_target(${CSS_TARGET} ALL DEPENDS ${_SPV_OUTPUTS}) else() add_custom_target(${CSS_TARGET} DEPENDS ${_SPV_OUTPUTS}) endif() # Export outputs to caller if they want them (optional convenience) set(${CSS_TARGET}_OUTPUTS "${_SPV_OUTPUTS}" PARENT_SCOPE) endfunction()