CMake对包含项/依赖项的GLSLC调用

CMake对包含项/依赖项的GLSLC调用,cmake,glsl,ninja,Cmake,Glsl,Ninja,我正在使用glslc将带有#includes(不是核心规范IIRC的一部分,但在shaderc中受支持,它是glslc背后的引擎,与LunarG Vulkan SDK一起分发)的GLSL着色器编译为Vulkan和GL 4.5的SPIR-Vglslc发出包含依赖项信息的gcc样式的DepsFile([my_shader].[ext].d)文件 我的项目是用cmake/ninja/MSVC 2017构建的 今天,当磁盘上的着色器发生更改时,我使用cmakecustom_命令调用glslc,作为主要目

我正在使用
glslc
将带有
#include
s(不是核心规范IIRC的一部分,但在shaderc中受支持,它是
glslc
背后的引擎,与LunarG Vulkan SDK一起分发)的GLSL着色器编译为Vulkan和GL 4.5的SPIR-V
glslc
发出包含依赖项信息的gcc样式的DepsFile(
[my_shader].[ext].d
)文件

我的项目是用cmake/ninja/MSVC 2017构建的

今天,当磁盘上的着色器发生更改时,我使用cmake
custom_命令
调用
glslc
,作为主要目标的构建后步骤。但是,这不会捕获包含文件中的更改(根本不知道.d文件或其内容),因此在包含的glsl文件更改时重建着色器可能会让我自己和团队中的其他人感到意外

看起来ninja可以调用任意编译器,既然ninja知道如何处理DepsFile,我应该能够强迫ninja运行glslc——因为现在我们在ninja上实现了标准化,所以不确定其他构建系统


那么,我怎样才能告诉cmake配置忍者为特定目标使用glslc呢?或者有没有一种范例的方法来实现这一点?看起来好像在2016年左右,cmake没有加入,所以无论我做什么,都将是一个解决办法。

cmake在与忍者一起使用时理解DEP文件

DEPFILE

为Ninja生成器指定.d文件。.d文件包含通常由自定义命令本身发出的依赖项。将DEPFILE与Ninja以外的其他生成器一起使用是一个错误

-M生成生成依赖项。意味着-E和-w。
-MM是-M的别名。
-MD生成依赖项并编译。
-MF将依赖项输出写入给定文件。
-MT指定依赖项发出的规则的目标
一代
编辑:越来越花哨

find_package(Vulkan COMPONENTS glslc)
find_program(glslc_executable NAMES glslc HINTS Vulkan::glslc)

function(compile_shader target)
    cmake_parse_arguments(PARSE_ARGV 1 arg "" "ENV;FORMAT" "SOURCES")
    foreach(source ${arg_SOURCES})
        add_custom_command(
            OUTPUT ${source}.${arg_FORMAT}
            DEPENDS ${source}
            DEPFILE ${source}.d
            COMMAND
                ${glslc_executable}
                $<$<BOOL:${arg_ENV}>:--target-env=${arg_ENV}>
                $<$<BOOL:${arg_FORMAT}>:-mfmt=${arg_FORMAT}>
                -MD -MF ${source}.d
                -o ${source}.${arg_FORMAT}
                ${CMAKE_CURRENT_SOURCE_DIR}/${source}
        )
        target_sources(${target} PRIVATE ${source}.${arg_FORMAT})
    endforeach()
endfunction()

当与忍者一起使用时,CMake理解DEP文件

DEPFILE

为Ninja生成器指定.d文件。.d文件包含通常由自定义命令本身发出的依赖项。将DEPFILE与Ninja以外的其他生成器一起使用是一个错误

-M生成生成依赖项。意味着-E和-w。
-MM是-M的别名。
-MD生成依赖项并编译。
-MF将依赖项输出写入给定文件。
-MT指定依赖项发出的规则的目标
一代
编辑:越来越花哨

find_package(Vulkan COMPONENTS glslc)
find_program(glslc_executable NAMES glslc HINTS Vulkan::glslc)

function(compile_shader target)
    cmake_parse_arguments(PARSE_ARGV 1 arg "" "ENV;FORMAT" "SOURCES")
    foreach(source ${arg_SOURCES})
        add_custom_command(
            OUTPUT ${source}.${arg_FORMAT}
            DEPENDS ${source}
            DEPFILE ${source}.d
            COMMAND
                ${glslc_executable}
                $<$<BOOL:${arg_ENV}>:--target-env=${arg_ENV}>
                $<$<BOOL:${arg_FORMAT}>:-mfmt=${arg_FORMAT}>
                -MD -MF ${source}.d
                -o ${source}.${arg_FORMAT}
                ${CMAKE_CURRENT_SOURCE_DIR}/${source}
        )
        target_sources(${target} PRIVATE ${source}.${arg_FORMAT})
    endforeach()
endfunction()
compile_shader(dummy ENV opengl FORMAT num SOURCES dummy.vert dummy.frag)