CMake 关于 includes/dependencies 的 GLSLC 调用
CMake invocation of GLSLC with respect to includes/dependencies
我正在使用 glslc
编译带有 #include
s 的 GLSL 着色器(不是核心规范 IIRC 的一部分,但在 shaderc 中受支持,它是 glslc
背后的引擎,分布式使用 LunarG Vulkan SDK) 到 SPIR-V for Vulkan 和 GL 4.5。 glslc
发出包含依赖信息的 gcc 风格的 depsfiles ([my_shader].[ext].d
) 文件。
我的项目是用 cmake/ninja/MSVC 2017 构建的。
今天,当磁盘上的着色器发生更改时,我使用 cmake custom_command
调用 glslc
,作为对我的主要目标的 post 构建步骤。但是,这不会捕捉到包含文件中的更改(根本不知道 .d 文件或其内容),因此当包含的 glsl 文件发生更改时重建着色器可能会使我自己和我团队中的其他人绊倒。
看起来 ninja 可以调用任意编译器,并且由于 ninja 知道如何处理 deps 文件,我应该能够强制 ninja 进入 运行 glslc -- 不确定其他构建系统,因为现在我们'重新标准化忍者。
那么我如何告诉 cmake 将 ninja 配置为对特定目标使用 glslc?还是有一种典型的方法来完成这项工作?看起来 cmake pull request to add support for glslc as a compiler 并没有在 2016 年左右进入 cmake,所以无论我做什么都将是一个解决方法。
CMake 在与 ninja 结合使用时可以理解 depfiles。
DEPFILE
Specify a .d depfile for the Ninja generator. A .d file holds dependencies usually emitted by the custom command itself. Using DEPFILE with other generators than Ninja is an error.
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
)
我正在使用 glslc
编译带有 #include
s 的 GLSL 着色器(不是核心规范 IIRC 的一部分,但在 shaderc 中受支持,它是 glslc
背后的引擎,分布式使用 LunarG Vulkan SDK) 到 SPIR-V for Vulkan 和 GL 4.5。 glslc
发出包含依赖信息的 gcc 风格的 depsfiles ([my_shader].[ext].d
) 文件。
我的项目是用 cmake/ninja/MSVC 2017 构建的。
今天,当磁盘上的着色器发生更改时,我使用 cmake custom_command
调用 glslc
,作为对我的主要目标的 post 构建步骤。但是,这不会捕捉到包含文件中的更改(根本不知道 .d 文件或其内容),因此当包含的 glsl 文件发生更改时重建着色器可能会使我自己和我团队中的其他人绊倒。
看起来 ninja 可以调用任意编译器,并且由于 ninja 知道如何处理 deps 文件,我应该能够强制 ninja 进入 运行 glslc -- 不确定其他构建系统,因为现在我们'重新标准化忍者。
那么我如何告诉 cmake 将 ninja 配置为对特定目标使用 glslc?还是有一种典型的方法来完成这项工作?看起来 cmake pull request to add support for glslc as a compiler 并没有在 2016 年左右进入 cmake,所以无论我做什么都将是一个解决方法。
CMake 在与 ninja 结合使用时可以理解 depfiles。
DEPFILE
Specify a .d depfile for the Ninja generator. A .d file holds dependencies usually emitted by the custom command itself. Using DEPFILE with other generators than Ninja is an error.
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
)