【问题标题】:CMake invocation of GLSLC with respect to includes/dependenciesCMake 关于包含/依赖项的 GLSLC 调用
【发布时间】:2020-02-26 18:56:30
【问题描述】:

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

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

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

看起来 ninja 可以调用任意编译器,并且由于 ninja 知道如何处理 depsfiles,我应该能够强制 ninja 运行 glslc —— 不确定其他构建系统,因为现在我们对 ninja 进行了标准化。

那么我怎样才能告诉 cmake 配置 ninja 以将 glslc 用于特定目标?还是有一种典型的方式来完成这项工作?看起来 cmake pull request to add support for glslc as a compiler 大约在 2016 年没有进入 cmake,所以无论我做什么都是一种解决方法。

【问题讨论】:

    标签: cmake glsl ninja


    【解决方案1】:

    当与 ninja 结合使用时,CMake 可以理解 depfile。

    DEPFILE

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

    add_custom_command(
        OUTPUT ${source}.h
        DEPENDS ${source}
        COMMAND
            glslc
            -MD -MF ${source}.d
            -o ${source}.h -mfmt=num
            --target-env=opengl
            ${CMAKE_CURRENT_SOURCE_DIR}/${source}
        DEPFILE ${source}.d
    )
    
      -M                Generate make dependencies. Implies -E and -w.
      -MM               An alias for -M.
      -MD               Generate make dependencies and compile.
      -MF <file>        Write dependency output to the given file.
      -MT <target>      Specify the target of the rule emitted by dependency
                        generation.
    

    编辑:变得更漂亮

    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()
    
    add_executable(dummy dummy.c)
    compile_shader(dummy
        ENV opengl
        FORMAT num
        SOURCES
            dummy.vert
            dummy.frag
    )
    

    【讨论】:

    • CMake Error at src/GUI_glfw3/vulkan/CMakeLists.txt:23 (target_sources): Cannot specify sources for target "dummy" which is not built by this project. Call Stack (most recent call first): src/GUI_glfw3/vulkan/CMakeLists.txt:27 (compile_shader) 是否有更完整的示例说明如何使用它?
    • @CarloWood 你错过了一个目标。我已经扩展了使用示例。
    • 这似乎不起作用,虽然我没有收到 cmake 错误,但更改包含文件中的依赖项不会启动重新编译着色器。 .d 文件确实生成正确。
    • 似乎此更改:“3.13 版更改:相对源文件路径被解释为相对于当前源目录(即 CMAKE_CURRENT_SOURCE_DIR)。请参阅策略 CMP0076。”表示 target_sources 应为: target_sources(${target} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/${source}.${arg_FORMAT}) 见cmake.org/cmake/help/latest/command/target_sources.html
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多