blob: e6d8257f54c35a2e9a9236c17f34b4d565ecbdeb [file] [log] [blame]
Austin Engcc2516a2023-10-17 20:57:54 +00001# Copyright 2020 The Dawn & Tint Authors
Corentin Wallez7fe6efb2020-02-05 17:16:05 +00002#
Austin Engcc2516a2023-10-17 20:57:54 +00003# Redistribution and use in source and binary forms, with or without
4# modification, are permitted provided that the following conditions are met:
Corentin Wallez7fe6efb2020-02-05 17:16:05 +00005#
Austin Engcc2516a2023-10-17 20:57:54 +00006# 1. Redistributions of source code must retain the above copyright notice, this
7# list of conditions and the following disclaimer.
Corentin Wallez7fe6efb2020-02-05 17:16:05 +00008#
Austin Engcc2516a2023-10-17 20:57:54 +00009# 2. Redistributions in binary form must reproduce the above copyright notice,
10# this list of conditions and the following disclaimer in the documentation
11# and/or other materials provided with the distribution.
12#
13# 3. Neither the name of the copyright holder nor the names of its
14# contributors may be used to endorse or promote products derived from
15# this software without specific prior written permission.
16#
17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Corentin Wallez7fe6efb2020-02-05 17:16:05 +000027
Corentin Wallez7fe6efb2020-02-05 17:16:05 +000028# Check for Jinja2
29if (NOT DAWN_JINJA2_DIR)
30 message(STATUS "Dawn: Using system jinja2")
31 execute_process(
Corentin Wallez299ad592024-03-28 20:21:11 +000032 COMMAND ${Python3_EXECUTABLE} -c "import jinja2"
Corentin Wallez7fe6efb2020-02-05 17:16:05 +000033 RESULT_VARIABLE RET
34 )
35 if (NOT RET EQUAL 0)
36 message(FATAL_ERROR "Dawn: Missing dependencies for code generation, please ensure you have python-jinja2 installed.")
37 endif()
38else()
Corentin Wallezf9f1c4b2022-05-16 09:11:21 +000039 message(STATUS "Dawn: using jinja2 at ${DAWN_JINJA2_DIR}")
dan sinclair6b67a902023-04-07 07:52:36 +000040 message(STATUS "Dawn: using markupsafe at ${DAWN_MARKUPSAFE_DIR}")
Corentin Wallez7fe6efb2020-02-05 17:16:05 +000041endif()
42
43# Function to invoke a generator_lib.py generator.
44# - SCRIPT is the name of the script to call
Jaswant Panchumarti6c70e262024-06-25 14:55:55 +000045# - OUTPUT_HEADERS will be modified to contain the list of header files (*.h, *.hpp) generated by this generator
46# - OUTPUT_SOURCES will be modified to contain the list of all other files generated by this generator
Corentin Wallez7fe6efb2020-02-05 17:16:05 +000047# - ARGS are the extra arguments to pass to the script in addition to the base generator_lib.py arguments
48# - PRINT_NAME is the name to use when outputting status or errors
Corentin Wallez7fe6efb2020-02-05 17:16:05 +000049function(DawnGenerator)
Jaswant Panchumarti6c70e262024-06-25 14:55:55 +000050 cmake_parse_arguments(PARSE_ARGV 0 arg
51 ""
Loko Kung90fdaa82024-07-24 00:59:58 +000052 "SCRIPT;OUTPUT_HEADERS;OUTPUT_SOURCES;OUTPUT_JSONS;OUTPUT_JS;PRINT_NAME"
Jaswant Panchumarti6c70e262024-06-25 14:55:55 +000053 "EXTRA_PARAMETERS"
54 )
Kai Ninomiya11784002024-07-03 19:46:03 +000055 message(STATUS "Dawn: Configuring DawnGenerator for ${arg_PRINT_NAME}.")
Jaswant Panchumarti6c70e262024-06-25 14:55:55 +000056
57 if (arg_UNPARSED_ARGUMENTS)
58 message(FATAL_ERROR
59 "Unparsed arguments for DawnGenerator: "
60 "${arg_UNPARSED_ARGUMENTS}")
61 endif ()
Corentin Wallez7fe6efb2020-02-05 17:16:05 +000062
63 # Build the set of args common to all invocation of that generator.
64 set(BASE_ARGS
Corentin Wallez299ad592024-03-28 20:21:11 +000065 ${Python3_EXECUTABLE}
Jaswant Panchumarti6c70e262024-06-25 14:55:55 +000066 ${arg_SCRIPT}
Corentin Wallez7fe6efb2020-02-05 17:16:05 +000067 --template-dir
68 "${DAWN_TEMPLATE_DIR}"
69 --root-dir
70 "${Dawn_SOURCE_DIR}"
71 --output-dir
72 "${DAWN_BUILD_GEN_DIR}"
Jaswant Panchumarti6c70e262024-06-25 14:55:55 +000073 ${arg_EXTRA_PARAMETERS}
Corentin Wallez7fe6efb2020-02-05 17:16:05 +000074 )
75 if (DAWN_JINJA2_DIR)
76 list(APPEND BASE_ARGS --jinja2-path ${DAWN_JINJA2_DIR})
77 endif()
dan sinclair6b67a902023-04-07 07:52:36 +000078 if (DAWN_MARKUPSAFE_DIR)
79 list(APPEND BASE_ARGS --markupsafe-path ${DAWN_MARKUPSAFE_DIR})
80 endif()
Corentin Wallez7fe6efb2020-02-05 17:16:05 +000081
82 # Call the generator to get the list of its dependencies.
83 execute_process(
84 COMMAND ${BASE_ARGS} --print-cmake-dependencies
85 OUTPUT_VARIABLE DEPENDENCIES
86 RESULT_VARIABLE RET
87 )
88 if (NOT RET EQUAL 0)
Jaswant Panchumarti6c70e262024-06-25 14:55:55 +000089 message(FATAL_ERROR "Dawn: Failed to get the dependencies for ${arg_PRINT_NAME}. Base args are '${BASE_ARGS}'.")
Corentin Wallez7fe6efb2020-02-05 17:16:05 +000090 endif()
91
92 # Ask CMake to re-run if any of the dependencies changed as it might modify the build graph.
Corentin Wallez299ad592024-03-28 20:21:11 +000093 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${DEPENDENCIES})
Corentin Wallez7fe6efb2020-02-05 17:16:05 +000094
95 # Call the generator to get the list of its outputs.
96 execute_process(
97 COMMAND ${BASE_ARGS} --print-cmake-outputs
98 OUTPUT_VARIABLE OUTPUTS
99 RESULT_VARIABLE RET
100 )
101 if (NOT RET EQUAL 0)
Jaswant Panchumarti6c70e262024-06-25 14:55:55 +0000102 message(FATAL_ERROR "Dawn: Failed to get the outputs for ${arg_PRINT_NAME}. Base args are '${BASE_ARGS}'.")
Corentin Wallez7fe6efb2020-02-05 17:16:05 +0000103 endif()
104
105 # Add the custom command that calls the generator.
106 add_custom_command(
107 COMMAND ${BASE_ARGS}
108 DEPENDS ${DEPENDENCIES}
109 OUTPUT ${OUTPUTS}
Jaswant Panchumarti6c70e262024-06-25 14:55:55 +0000110 COMMENT "Dawn: Generating files for ${arg_PRINT_NAME}."
Corentin Wallez7fe6efb2020-02-05 17:16:05 +0000111 )
112
Jaswant Panchumarti6c70e262024-06-25 14:55:55 +0000113 # Populate the list of outputs.
114 set(headers)
115 set(sources)
Loko Kung90fdaa82024-07-24 00:59:58 +0000116 set(jsons)
117 set(js)
Jaswant Panchumarti6c70e262024-06-25 14:55:55 +0000118 foreach (filename IN LISTS OUTPUTS)
119 get_filename_component(extension "${filename}" EXT)
120 if (extension MATCHES "(h|hpp)")
121 list(APPEND headers "${filename}")
Loko Kung90fdaa82024-07-24 00:59:58 +0000122 elseif (extension MATCHES "(json)")
123 list(APPEND jsons "${filename}")
124 elseif (extension MATCHES "(js)")
125 list(APPEND js "${filename}")
Jaswant Panchumarti6c70e262024-06-25 14:55:55 +0000126 else ()
127 list(APPEND sources "${filename}")
128 endif ()
129 endforeach ()
130
131 if (sources AND NOT arg_OUTPUT_SOURCES)
132 message(FATAL_ERROR
133 "This function generated source files, although an output variable was not defined!"
134 "Please provide a variable name for OUTPUT_SOURCES.")
135 endif ()
136
137 if (headers AND NOT arg_OUTPUT_HEADERS)
138 message(FATAL_ERROR
139 "This function generated header files, although an output variable was not defined!"
140 "Please provide a variable name for OUTPUT_HEADERS.")
141 endif ()
142
Loko Kung90fdaa82024-07-24 00:59:58 +0000143 if (jsons AND NOT arg_OUTPUT_JSONS)
144 message(FATAL_ERROR
145 "This function generated JSON files, although an output variable was not defined!"
146 "Please provide a variable name for OUTPUT_JSONS.")
147 endif ()
148
149 if (js AND NOT arg_OUTPUT_JS)
150 message(FATAL_ERROR
151 "This function generated JS files, although an output variable was not defined!"
152 "Please provide a variable name for OUTPUT_JS.")
153 endif ()
154
Jaswant Panchumarti6c70e262024-06-25 14:55:55 +0000155 set(${arg_OUTPUT_SOURCES} ${sources} PARENT_SCOPE)
156 set(${arg_OUTPUT_HEADERS} ${headers} PARENT_SCOPE)
Loko Kung90fdaa82024-07-24 00:59:58 +0000157 set(${arg_OUTPUT_JSONS} ${jsons} PARENT_SCOPE)
158 set(${arg_OUTPUT_JS} ${js} PARENT_SCOPE)
Corentin Wallez5406e9d2024-05-07 15:58:57 +0000159
Corentin Walleza3014cc2024-03-27 13:53:14 +0000160 # Prior to CMake 3.20 the GENERATED property is local to a directory which means that putting
161 # generated headers in INTERFACE properties causes dependent targets to complain that they
162 # cannot find the file. (because they don't see it as generated and want to check is is
163 # actually on the filesystem).
Corentin Wallez5406e9d2024-05-07 15:58:57 +0000164 # Work around this by generating the files once if they aren't present at configuration time.
165 set(needToGenerate OFF)
Corentin Walleza3014cc2024-03-27 13:53:14 +0000166 foreach(path ${OUTPUTS})
167 if (NOT EXISTS ${path})
Corentin Wallez5406e9d2024-05-07 15:58:57 +0000168 set(needToGenerate ON)
Corentin Walleza3014cc2024-03-27 13:53:14 +0000169 endif()
170 endforeach()
munozac511ffb2023-09-25 14:01:03 +0000171
Corentin Wallez5406e9d2024-05-07 15:58:57 +0000172 if (${needToGenerate})
Jaswant Panchumarti6c70e262024-06-25 14:55:55 +0000173 message(STATUS "Dawn: Generating initial versions of files for ${arg_PRINT_NAME}.")
Corentin Wallez5406e9d2024-05-07 15:58:57 +0000174 execute_process(COMMAND ${BASE_ARGS} RESULT_VARIABLE RET)
175 if (NOT RET EQUAL 0)
Jaswant Panchumarti6c70e262024-06-25 14:55:55 +0000176 message(FATAL_ERROR "Dawn: Failed to generate the initial version of files for ${arg_PRINT_NAME}. Base args are '${BASE_ARGS}'.")
Corentin Wallez5406e9d2024-05-07 15:58:57 +0000177 endif()
178 endif()
Corentin Wallez7fe6efb2020-02-05 17:16:05 +0000179endfunction()
180
181# Helper function to call dawn_generator.py:
182# - TARGET is the generator target to build
Jaswant Panchumarti6c70e262024-06-25 14:55:55 +0000183# - OUTPUT_HEADERS, OUTPUT_SOURCES, and PRINT_NAME are like for DawnGenerator
Corentin Wallez7fe6efb2020-02-05 17:16:05 +0000184function(DawnJSONGenerator)
Jaswant Panchumarti6c70e262024-06-25 14:55:55 +0000185 cmake_parse_arguments(PARSE_ARGV 0 arg
186 ""
Loko Kung90fdaa82024-07-24 00:59:58 +0000187 "TARGET;OUTPUT_SOURCES;OUTPUT_HEADERS;OUTPUT_JSONS;OUTPUT_JS;PRINT_NAME"
Jaswant Panchumarti6c70e262024-06-25 14:55:55 +0000188 ""
189 )
Corentin Wallez7fe6efb2020-02-05 17:16:05 +0000190 DawnGenerator(
191 SCRIPT "${Dawn_SOURCE_DIR}/generator/dawn_json_generator.py"
Jaswant Panchumartifa24f152024-06-26 11:26:43 +0000192 PRINT_NAME "${arg_PRINT_NAME}"
Jaswant Panchumarti6c70e262024-06-25 14:55:55 +0000193 OUTPUT_HEADERS HEADERS
194 OUTPUT_SOURCES SOURCES
Loko Kung90fdaa82024-07-24 00:59:58 +0000195 OUTPUT_JSONS JSONS
196 OUTPUT_JS JS
Jaswant Panchumarti6c70e262024-06-25 14:55:55 +0000197 EXTRA_PARAMETERS
198 --dawn-json
Jiawei Shaoa5059a62024-01-04 04:55:46 +0000199 "${Dawn_SOURCE_DIR}/src/dawn/dawn.json"
Corentin Wallez7fe6efb2020-02-05 17:16:05 +0000200 --wire-json
Jiawei Shaoa5059a62024-01-04 04:55:46 +0000201 "${Dawn_SOURCE_DIR}/src/dawn/dawn_wire.json"
Jim Blackler497df7b2024-05-31 17:00:58 +0000202 --kotlin-json
203 "${Dawn_SOURCE_DIR}/src/dawn/dawn_kotlin.json"
Corentin Wallez7fe6efb2020-02-05 17:16:05 +0000204 --targets
Jaswant Panchumarti6c70e262024-06-25 14:55:55 +0000205 ${arg_TARGET}
206 ${arg_UNPARSED_ARGUMENTS}
Corentin Wallez7fe6efb2020-02-05 17:16:05 +0000207 )
208
Jaswant Panchumarti6c70e262024-06-25 14:55:55 +0000209 if (SOURCES AND NOT arg_OUTPUT_SOURCES)
210 message(FATAL_ERROR
Loko Kung90fdaa82024-07-24 00:59:58 +0000211 "This function generated source files, although an output variable was not defined! "
Jaswant Panchumarti6c70e262024-06-25 14:55:55 +0000212 "Please provide a variable name for OUTPUT_SOURCES.")
213 elseif (arg_OUTPUT_SOURCES AND NOT SOURCES)
214 message(WARNING
215 "This function did not generate source files. The OUTPUT_SOURCES argument is unnecessary.")
216 endif ()
217
218 if (HEADERS AND NOT arg_OUTPUT_HEADERS)
219 message(FATAL_ERROR
Loko Kung90fdaa82024-07-24 00:59:58 +0000220 "This function generated header files, although an output variable was not defined! "
Jaswant Panchumarti6c70e262024-06-25 14:55:55 +0000221 "Please provide a variable name for OUTPUT_HEADERS.")
222 elseif (arg_OUTPUT_HEADERS AND NOT HEADERS)
223 message(WARNING
224 "This function did not generate header files. The OUTPUT_HEADERS argument is unnecessary.")
225 endif ()
226
Loko Kung90fdaa82024-07-24 00:59:58 +0000227 if (JSONS AND NOT arg_OUTPUT_JSONS)
228 message(FATAL_ERROR
229 "This function generated JSON files, although an output variable was not defined! "
230 "Please provide a variable name for OUTPUT_JSONS.")
231 elseif (arg_OUTPUT_JSONS AND NOT JSONS)
232 message(WARNING
233 "This function did not generate JSON files. The OUTPUT_JSONS argument is unnecessary.")
234 endif ()
235
236 if (JS AND NOT arg_OUTPUT_JS)
237 message(FATAL_ERROR
238 "This function generated JS files, although an output variable was not defined! "
239 "Please provide a variable name for OUTPUT_JS.")
240 elseif (arg_OUTPUT_JS AND NOT JS)
241 message(WARNING
242 "This function did not generate JS files. The OUTPUT_JS argument is unnecessary.")
243 endif ()
244
Corentin Wallez7fe6efb2020-02-05 17:16:05 +0000245 # Forward the result up one more scope
Jaswant Panchumarti6c70e262024-06-25 14:55:55 +0000246 set(${arg_OUTPUT_SOURCES} ${SOURCES} PARENT_SCOPE)
247 set(${arg_OUTPUT_HEADERS} ${HEADERS} PARENT_SCOPE)
Loko Kung90fdaa82024-07-24 00:59:58 +0000248 set(${arg_OUTPUT_JSONS} ${JSONS} PARENT_SCOPE)
249 set(${arg_OUTPUT_JS} ${JS} PARENT_SCOPE)
Corentin Wallez7fe6efb2020-02-05 17:16:05 +0000250endfunction()