我的目标中有一些文件(.hlsl)是使用自定义编译器(glslc)编译的。编译后,我使用不同的工具将编译好的二进制文件嵌入到包含c数组like described here的c文件中。
以下代码对此工作流进行了总结,该代码调用2个自定义命令:
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()然后,我定义了一个自定义目标,它在构建时生成上述文件。
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)主要问题是,每当我构建项目时,都会触发自定义目标构建过程,而不考虑任何.hlsl文件都没有被更改。这是不可取的,我希望我的自定义命令像编译常规.c或cpp文件时一样工作。它们只有在更改时才会编译。
我的要求如下:
每次更改一个
。
那么,如何才能做到这一点呢?
我尝试了几种方法,比如使用DEPENDS、MAIN_DEPENDENCY或使用OUTPUT而不是TARGET。都没起作用。我还尝试了提供给here和here的解决方案。他们都遭受着同样的问题。
按照注释中的要求,下面是我使用OUTPUT而不是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()发布于 2022-05-31 05:40:50
这取决于您认为着色器是“库的一部分”,还是运行时需要的一些数据。
对于生成HLSL着色器的项目,我使用一个与您所做的类似的自定义目标:
add_custom_target(shaders)
set_source_files_properties(VertexShader.hlsl PROPERTIES ShaderType "vs")
set_source_files_properties(PixelShader.hlsl PROPERTIES ShaderType "ps")
foreach(FILE VertexShader.hlsl PixelShader.hlsl)
get_filename_component(FILE_WE ${FILE} NAME_WE)
get_source_file_property(shadertype ${FILE} ShaderType)
add_custom_command(TARGET shaders
COMMAND dxc.exe /nologo /Emain /T${shadertype}_6_0 $<IF:$<CONFIG:DEBUG>,/Od,/O3> /Zi /Fo ${CMAKE_BINARY_DIR}/${FILE_WE}.cso /Fd ${CMAKE_BINARY_DIR}/${FILE_WE}.pdb ${FILE}
MAIN_DEPENDENCY ${FILE}
COMMENT "HLSL ${FILE}"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
VERBATIM)
endforeach(FILE)
add_dependencies(${PROJECT_NAME} shaders)这实际上设置了一个“post build”事件。如果任何一个着色器源文件改变,那么它们都会被重建。
设置输出文件的另一种方法是使用输出文件,但是这里需要一些额外的cmake逻辑,这样就可以将输出文件添加到add_library或add_executable中。
# SOURCES variable is all the C/C++ source files in the library
# Build HLSL shaders
set_source_files_properties(VertexShader.hlsl PROPERTIES ShaderType "vs")
set_source_files_properties(PixelShader.hlsl PROPERTIES ShaderType "ps")
foreach(FILE VertexShader.hlsl PixelShader.hlsl)
get_filename_component(FILE_WE ${FILE} NAME_WE)
get_source_file_property(shadertype ${FILE} ShaderType)
list(APPEND CSO_FILES ${CMAKE_BINARY_DIR}/${FILE_WE}.cso)
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/${FILE_WE}.cso
COMMAND dxc.exe /nologo /Emain /T${shadertype}_6_0 $<IF:$<CONFIG:DEBUG>,/Od,/O3> /Zi /Fo ${CMAKE_BINARY_DIR}/${FILE_WE}.cso /Fd ${CMAKE_BINARY_DIR}/${FILE_WE}.pdb ${FILE}
MAIN_DEPENDENCY ${FILE}
COMMENT "HLSL ${FILE}"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
VERBATIM)
endforeach(FILE)
add_library(library2 ${SOURCES} ${CSO_FILES})第二个版本只在源代码更改时构建特定的输出文件,但一般来说,您不需要使用着色器这种级别的粒度。
https://stackoverflow.com/questions/72418640
复制相似问题