Skip to content

Commit 3aeb58b

Browse files
committed
Function for targeted GLSL shader file compilation
GLSL shader source files can be linked to a specified target and compiled for, complete with only re-compiling only files modified since last compilation. Also includes documentation both in-file and in the repo README.
1 parent 5c3221d commit 3aeb58b

File tree

2 files changed

+144
-2
lines changed

2 files changed

+144
-2
lines changed

README.md

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,17 @@ This is a collection of quite useful scripts that expand the possibilities for b
2323
- [ADD_TO_DEP_GRAPH](#add_to_dep_graph)
2424
- [TARGET_NAME *STR*](#target_name-str)
2525
- [OUTPUT_DIR *STR*](#output_dir-str)
26-
- [Doxygen `doxygen.cmake`](#doxygen-doxygencmake)
26+
- [GLSL Shader File Targeted Compilation`glsl_shaders.cmake`](#glsl-shader-file-targeted-compilationglsl_shaderscmake)
27+
- [Example](#example)
28+
- [Required Arguments](#required-arguments-1)
29+
- [TARGET_NAME](#target_name)
2730
- [Optional Arguments](#optional-arguments-1)
31+
- [INTERFACE *FILES*](#interface-files)
32+
- [PUBLIC *FILES*](#public-files)
33+
- [PRIVATE *FILES*](#private-files)
34+
- [COMPILE_OPTIONS *OPTIONS*](#compile_options-options)
35+
- [Doxygen `doxygen.cmake`](#doxygen-doxygencmake)
36+
- [Optional Arguments](#optional-arguments-2)
2837
- [ADD_TO_DOC](#add_to_doc)
2938
- [INSTALLABLE](#installable)
3039
- [PROCESS_DOXYFILE](#process_doxyfile)
@@ -33,7 +42,7 @@ This is a collection of quite useful scripts that expand the possibilities for b
3342
- [INSTALL_PATH *STR*](#install_path-str)
3443
- [DOXYFILE_PATH *STR*](#doxyfile_path-str)
3544
- [Prepare the Catch Test Framework `prepare_catch.cmake`](#prepare-the-catch-test-framework-prepare_catchcmake)
36-
- [Optional Arguments](#optional-arguments-2)
45+
- [Optional Arguments](#optional-arguments-3)
3746
- [COMPILED_CATCH](#compiled_catch)
3847
- [CATCH1](#catch1)
3948
- [CLONE](#clone)
@@ -205,6 +214,41 @@ The name to give the doc target. (Default: doc-${PROJECT_NAME})
205214
#### OUTPUT_DIR *STR*
206215
The directory to place the generated output
207216

217+
## GLSL Shader File Targeted Compilation[`glsl_shaders.cmake`](glsl_shaders.cmake)
218+
219+
This function acts much like the 'target_sources' function, as in raw GLSL shader files can be passed in and will be compiled using 'glslangValidator', provided it is available, where the compiled files will be located where the sources files are but with the '.spv' suffix appended.
220+
221+
The first argument is the target that the files are associated with, and will be compiled as if it were a source file for it. All provided shaders are also only recompiled if the source shader file has been modified since the last compilation.
222+
223+
### Example
224+
When calling `make vk_lib` the shaders will also be compiled with the library's `.c` files.
225+
226+
```
227+
add_library(vk_lib lib.c, shader_manager.c)
228+
target_glsl_shaders(vk_lib
229+
PRIVATE test.vert test.frag
230+
COMPILE_OPTIONS --target-env vulkan1.1)
231+
```
232+
233+
### Required Arguments
234+
235+
#### TARGET_NAME
236+
Name of the target the shader files are associated with and to be compiled for.
237+
238+
### Optional Arguments
239+
240+
#### INTERFACE *FILES*
241+
When the following shader files are added to a target, they are done so as 'INTERFACE' type files
242+
243+
#### PUBLIC *FILES*
244+
When the following shader files are added to a target, they are done so as 'PUBLIC' type files
245+
246+
#### PRIVATE *FILES*
247+
When the following shader files are added to a target, they are done so as 'PRIVATE' type files
248+
249+
#### COMPILE_OPTIONS *OPTIONS*
250+
These are other options passed straight to the 'glslangValidator' call with the source shader file
251+
208252
## Doxygen [`doxygen.cmake`](doxygen.cmake)
209253

210254
Builds doxygen documentation with a default 'Doxyfile.in' or with a specified one, and can make the results installable (under the `doc` install target)

glsl_shaders.cmake

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
#
2+
# Copyright (C) 2020 by George Cave - [email protected]
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
5+
# use this file except in compliance with the License. You may obtain a copy of
6+
# the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
# License for the specific language governing permissions and limitations under
14+
# the License.
15+
16+
#
17+
# glslangValidator
18+
#
19+
find_program(GLSLANGVALIDATOR_EXE "glslangValidator")
20+
mark_as_advanced(FORCE GLSLANGVALIDATOR_EXE)
21+
if(GLSLANGVALIDATOR_EXE)
22+
message(STATUS "glslangValidator found: ${GLSLANGVALIDATOR_EXE}")
23+
else()
24+
message(STATUS "glslangValidator not found!")
25+
endif()
26+
27+
# This function acts much like the 'target_sources' function, as in raw GLSL
28+
# shader files can be passed in and will be compiled using 'glslangValidator',
29+
# provided it is available, where the compiled files will be located where the
30+
# sources files are but with the '.spv' suffix appended.
31+
#
32+
# The first argument is the target that the files are associated with, and will
33+
# be compiled as if it were a source file for it. All provided shaders are also
34+
# only recompiled if the source shader file has been modified since the last
35+
# compilation.
36+
#
37+
# ~~~
38+
# Required:
39+
# TARGET_NAME - Name of the target the shader files are associated with and to be compiled for.
40+
#
41+
# Optional:
42+
# INTERFACE <files> - When the following shader files are added to a target, they are done so as 'INTERFACE' type files
43+
# PUBLIC <files> - When the following shader files are added to a target, they are done so as 'PUBLIC' type files
44+
# PRIVATE <files> - When the following shader files are added to a target, they are done so as 'PRIVATE' type files
45+
# COMPILE_OPTIONS <options> - These are other options passed straight to the 'glslangValidator' call with the source shader file
46+
#
47+
# Example:
48+
# When calling `make vk_lib` the shaders will also be compiled with the library's `.c` files.
49+
#
50+
# add_library(vk_lib lib.c, shader_manager.c)
51+
# target_glsl_shaders(vk_lib
52+
# PRIVATE test.vert test.frag
53+
# COMPILE_OPTIONS --target-env vulkan1.1)
54+
# ~~~
55+
function(target_glsl_shaders TARGET_NAME)
56+
if(NOT GLSLANGVALIDATOR_EXE)
57+
message(
58+
FATAL_ERROR "Cannot compile GLSL to SPIR-V is glslangValidator not found!"
59+
)
60+
endif()
61+
62+
set(OPTIONS)
63+
set(SINGLE_VALUE_KEYWORDS)
64+
set(MULTI_VALUE_KEYWORDS INTERFACE PUBLIC PRIVATE COMPILE_OPTIONS)
65+
cmake_parse_arguments(
66+
target_glsl_shaders "${OPTIONS}" "${SINGLE_VALUE_KEYWORDS}"
67+
"${MULTI_VALUE_KEYWORDS}" ${ARGN})
68+
69+
foreach(GLSL_FILE IN LISTS target_glsl_shaders_INTERFACE)
70+
add_custom_command(
71+
OUTPUT ${GLSL_FILE}.spv
72+
COMMAND ${GLSLANGVALIDATOR_EXE} ${target_glsl_shaders_COMPILE_OPTIONS} -V
73+
"${GLSL_FILE}" -o "${GLSL_FILE}.spv"
74+
MAIN_DEPENDENCY ${GLSL_FILE})
75+
76+
target_sources(${TARGET_NAME} INTERFACE ${GLSL_FILE}.spv)
77+
endforeach()
78+
79+
foreach(GLSL_FILE IN LISTS target_glsl_shaders_PUBLIC)
80+
add_custom_command(
81+
OUTPUT ${GLSL_FILE}.spv
82+
COMMAND ${GLSLANGVALIDATOR_EXE} ${target_glsl_shaders_COMPILE_OPTIONS} -V
83+
"${GLSL_FILE}" -o "${GLSL_FILE}.spv"
84+
MAIN_DEPENDENCY ${GLSL_FILE})
85+
86+
target_sources(${TARGET_NAME} PUBLIC ${GLSL_FILE}.spv)
87+
endforeach()
88+
89+
foreach(GLSL_FILE IN LISTS target_glsl_shaders_PRIVATE)
90+
add_custom_command(
91+
OUTPUT ${GLSL_FILE}.spv
92+
COMMAND ${GLSLANGVALIDATOR_EXE} ${target_glsl_shaders_COMPILE_OPTIONS} -V
93+
"${GLSL_FILE}" -o "${GLSL_FILE}.spv"
94+
MAIN_DEPENDENCY ${GLSL_FILE})
95+
96+
target_sources(${TARGET_NAME} PRIVATE ${GLSL_FILE}.spv)
97+
endforeach()
98+
endfunction()

0 commit comments

Comments
 (0)