CMake вызов GLSLC в отношении include / dependencies

Я использую glslc для компиляции шейдеров GLSL с #includes (не является частью основной спецификации IIRC, но поддерживается в shaderc, который является движком glslc, распространяется с LunarG Vulkan SDK) в SPIR-V для Vulkan и GL 4.5. glslc генерирует файлы depsfiles ([my_shader].[ext].d) в стиле gcc, содержащие информацию о зависимостях.

Мой проект построен с помощью cmake / ninja / MSVC 2017.

Сегодня я использую cmake custom_command для вызова glslc при изменении шейдера на диске в качестве шага после сборки для моей основной цели. Однако это не улавливает изменения во включенных файлах (вообще не знает о файлах .d или их содержимом), поэтому перестройка шейдеров при изменении включенного файла glsl может сбить меня с толку и других людей в моей команде.

Похоже, что ниндзя может вызывать произвольные компиляторы, и, поскольку ниндзя знает, как обрабатывать файлы deps, я смогу заставить ниндзя запустить glslc - не уверен насчет других систем сборки, поскольку сейчас мы стандартизированы для ниндзя.

Итак, как я могу сказать cmake, чтобы настроить Ninja на использование glslc для определенной цели? Или есть парадигматический способ сделать это? Похоже, что запрос на извлечение cmake для добавления поддержки glslc в качестве компилятора не был не доживу до cmake примерно в 2016 году, так что все, что я сделаю, будет обходным решением.


person Alterscape    schedule 26.02.2020    source источник


Ответы (1)


CMake понимает деп-файлы при использовании вместе с ninja.

ДЕПФИЛЬ

Укажите депфайл .d для генератора Ninja. Файл .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()
compile_shader(dummy ENV opengl FORMAT num SOURCES dummy.vert dummy.frag)
person diapir    schedule 01.03.2020
comment
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) есть ли где-нибудь более полный пример того, как это использовать? - person Carlo Wood; 16.07.2021