I want to automatically build GLSL shaders to SPIR-V and then copy them to the location of an executable target using CMake. I created the following function for this purpose:
function(target_shaders target_name paths_in)
set(paths_out "")
foreach(path_in_raw ${paths_in})
set(path_in "${CMAKE_CURRENT_SOURCE_DIR}/${path_in_raw}")
set(path_out "$<TARGET_FILE:${target_name}>/../${path_in_raw}.spv")
add_custom_command(OUTPUT ${path_out}
COMMAND glslc ${path_in} -o ${path_out}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${path_in}
COMMENT "Compiling GLSL shader" ${path_in})
list(APPEND paths_out ${path_out})
endforeach()
add_custom_target("${target_name}_shaders" DEPENDS ${paths_out})
add_dependencies(${target_name} "${target_name}_shaders")
endfunction()
It takes a target name and a list of GLSL files as arguments. I invoke it like this:
add_executable(mini-vk main.cpp)
target_shaders(mini-vk "basic.vert;basic.frag")
I expected this to compile basic.vert
and basic.frag
to respective .spv
files in the same directory that mini-vk.exe
is located. Unfortunately, I get the following error instead:
[cmake] CMake Error at CMakeLists.txt:9 (add_custom_command):
[cmake] Error evaluating generator expression:
[cmake]
[cmake] $<TARGET_FILE:mini-vk>
[cmake]
[cmake] No target "mini-vk"
[cmake] Call Stack (most recent call first):
[cmake] CMakeLists.txt:26 (target_shaders)
I am not sure why there is "no target mini-vk
" as it is created on the line just above target_shaders
.
For clarity, the code does work if I type the output path manually by changing the definition of path_out
:
set(path_out "${CMAKE_CURRENT_SOURCE_DIR}/build/Debug/${path_in_raw}.spv")
I don't want to have to use this hack though.