I have certain files (.hlsl) in one of my targets that are compiled using a custom compiler (glslc). After compilation, I use a different tool to embed the compiled binary in a c-file containing c-array like described here.
This workflow is summarized in the following code which invokes 2 custom commands:
function(build_hlsl_shader shader_file)
get_source_file_property(shader_type ${shader_file} ShaderType)
get_filename_component(shader_name ${shader_file} NAME_WE)
# special command: .hlsl file to a .c / .h file
add_custom_command(
TARGET shaders_custom_target # a custom target
#OUTPUT ${shader_name}.cpp # maybe this?
#DEPENDS ${shader_file} # maybe that?
MAIN_DEPENDENCY ${shader_file} # or maybe thee?
COMMAND # special compiler
${glslc_executable}
-fshader-stage=${shader_type}
${CMAKE_CURRENT_SOURCE_DIR}/${shader_file}
-o
${CMAKE_CURRENT_SOURCE_DIR}/${shader_name}.spv
COMMAND # special tool that generates the c header.
bin2h
${CMAKE_CURRENT_SOURCE_DIR}/${shader_name}.spv
)
endfunction()
I then define a custom target that that generates the said files whenever it is built.
add_custom_target(
shaders_custom_target
DEPENDS
"shader.hlsl"
)
build_hlsl_shader("shader.hlsl")
# this library consumes the headers generated by the first target
add_library(library2 STATIC "file1.cpp""file1.hpp")
add_dependencies(library2 shaders_custom_target)
The main issue is that the custom target build process is triggered every time I build my project regardless of the fact the none of the .hlsl files are changed. This is undesirable, I want my custom command to work just like when compiling regular .c or cpp files. They are compiled only when changed.
My requirements are as follows:
- Each time one of the .hlsl files are changed, the custom command should trigger.
- The custom command should not get triggered whenever I build the target / project.
So how can this achieved?
I tried several methods like using DEPENDS
, MAIN_DEPENDENCY
or using OUTPUT
instead of TARGET
. None worked. I also tried the solution offered here and here. They all suffer from the same issue.
As requested in the comments, Here is my attempt to use OUTPUT
instead of TARGET
:
function(build_hlsl_shader shader_file)
get_source_file_property(shader_type ${shader_file} ShaderType)
get_filename_component(shader_name ${shader_file} NAME_WE)
add_custom_command(
#TARGET shaders_custom_target
OUTPUT
#${shader_name}.hpp # the generated header, tried with or without
${shader_file} # tried with and without
DEPENDS ${shader_file} # tried with and without
#MAIN_DEPENDENCY ${shader_file} # tried with and without
COMMAND
${glslc_executable}
-fshader-stage=${shader_type}
${CMAKE_CURRENT_SOURCE_DIR}/${shader_file}
-o
${CMAKE_CURRENT_SOURCE_DIR}/${shader_name}.spv
COMMAND
bin2h
${CMAKE_CURRENT_SOURCE_DIR}/${shader_name}.spv
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
endfunction()