Rework CMake rules for building grammar tables.
Use add_custom_command() to generate all .inc files and manage
dependency with set_source_files_properties().
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5c89b22..d6d57f0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -139,41 +139,6 @@
${spirv-tools_SOURCE_DIR}
COMMENT "Update build-version.inc in the Spirv-tools build directory (if necessary).")
-function(spvtools_core_tables VERSION)
- add_custom_target(spirv-tools-build-core-tables-${VERSION}
- ${PYTHON_EXECUTABLE}
- ${CMAKE_CURRENT_SOURCE_DIR}/utils/generate_grammar_tables.py
- --spirv-core-grammar=${spirv-tools_SOURCE_DIR}/source/spirv-${VERSION}.core.grammar.json
- --core-insts-output=${spirv-tools_BINARY_DIR}/core.insts-${VERSION}.inc
- --operand-kinds-output=${spirv-tools_BINARY_DIR}/operand.kinds-${VERSION}.inc
- COMMENT "Generate info tables for SPIR-V v${VERSION} core instructions and operands.")
-endfunction(spvtools_core_tables)
-
-function(spvtools_glsl_tables VERSION)
- add_custom_target(spirv-tools-build-glsl-tables-${VERSION}
- ${PYTHON_EXECUTABLE}
- ${CMAKE_CURRENT_SOURCE_DIR}/utils/generate_grammar_tables.py
- --spirv-core-grammar=${spirv-tools_SOURCE_DIR}/source/spirv-${VERSION}.core.grammar.json
- --extinst-glsl-grammar=${spirv-tools_SOURCE_DIR}/source/extinst-${VERSION}.glsl.std.450.grammar.json
- --glsl-insts-output=${spirv-tools_BINARY_DIR}/glsl.std.450.insts-${VERSION}.inc
- COMMENT "Generate info tables for GLSL extended instructions and operands v${VERSION}.")
-endfunction(spvtools_glsl_tables)
-
-function(spvtools_opencl_tables VERSION)
- add_custom_target(spirv-tools-build-opencl-tables-${VERSION}
- ${PYTHON_EXECUTABLE}
- ${CMAKE_CURRENT_SOURCE_DIR}/utils/generate_grammar_tables.py
- --spirv-core-grammar=${spirv-tools_SOURCE_DIR}/source/spirv-${VERSION}.core.grammar.json
- --extinst-opencl-grammar=${spirv-tools_SOURCE_DIR}/source/extinst-${VERSION}.opencl.std.grammar.json
- --opencl-insts-output=${spirv-tools_BINARY_DIR}/opencl.std.insts-${VERSION}.inc
- COMMENT "Generate info tables for OpenCL extended instructions and operands v${VERSION}.")
-endfunction(spvtools_opencl_tables)
-
-spvtools_core_tables("1-0")
-spvtools_core_tables("1-1")
-spvtools_opencl_tables("1-0")
-spvtools_glsl_tables("1-0")
-
# Defaults to OFF if the user didn't set it.
option(SPIRV_SKIP_EXECUTABLES
"Skip building the executable and tests along with the library"
diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt
index 781173e..c7c07f5 100644
--- a/source/CMakeLists.txt
+++ b/source/CMakeLists.txt
@@ -24,6 +24,84 @@
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+set(GRAMMAR_PROCESSING_SCRIPT "${spirv-tools_SOURCE_DIR}/utils/generate_grammar_tables.py")
+
+# macro() definitions are used in the following because we need to append .inc
+# file paths into some global lists (*_CPP_DEPENDS). And those global lists are
+# later used by set_source_files_properties() calls.
+# function() definitions are not suitable because they create new scopes.
+macro(spvtools_core_tables VERSION)
+ set(GRAMMAR_JSON_FILE "${CMAKE_CURRENT_SOURCE_DIR}/spirv-${VERSION}.core.grammar.json")
+ set(GRAMMAR_INSTS_INC_FILE "${spirv-tools_BINARY_DIR}/core.insts-${VERSION}.inc")
+ set(GRAMMAR_KINDS_INC_FILE "${spirv-tools_BINARY_DIR}/operand.kinds-${VERSION}.inc")
+ add_custom_command(OUTPUT ${GRAMMAR_INSTS_INC_FILE} ${GRAMMAR_KINDS_INC_FILE}
+ COMMAND ${PYTHON_EXECUTABLE} ${GRAMMAR_PROCESSING_SCRIPT}
+ --spirv-core-grammar=${GRAMMAR_JSON_FILE}
+ --core-insts-output=${GRAMMAR_INSTS_INC_FILE}
+ --operand-kinds-output=${GRAMMAR_KINDS_INC_FILE}
+ DEPENDS ${GRAMMAR_PROCESSING_SCRIPT} ${GRAMMAR_JSON_FILE}
+ COMMENT "Generate info tables for SPIR-V v${VERSION} core instructions and operands.")
+ list(APPEND OPCODE_CPP_DEPENDS ${GRAMMAR_INSTS_INC_FILE})
+ list(APPEND OPERAND_CPP_DEPENDS ${GRAMMAR_KINDS_INC_FILE})
+endmacro(spvtools_core_tables)
+
+macro(spvtools_glsl_tables VERSION)
+ set(CORE_GRAMMAR_JSON_FILE "${CMAKE_CURRENT_SOURCE_DIR}/spirv-${VERSION}.core.grammar.json")
+ set(GLSL_GRAMMAR_JSON_FILE "${CMAKE_CURRENT_SOURCE_DIR}/extinst-${VERSION}.glsl.std.450.grammar.json")
+ set(GRAMMAR_INC_FILE "${spirv-tools_BINARY_DIR}/glsl.std.450.insts-${VERSION}.inc")
+ add_custom_command(OUTPUT ${GRAMMAR_INC_FILE}
+ COMMAND ${PYTHON_EXECUTABLE} ${GRAMMAR_PROCESSING_SCRIPT}
+ --spirv-core-grammar=${CORE_GRAMMAR_JSON_FILE}
+ --extinst-glsl-grammar=${GLSL_GRAMMAR_JSON_FILE}
+ --glsl-insts-output=${GRAMMAR_INC_FILE}
+ DEPENDS ${GRAMMAR_PROCESSING_SCRIPT} ${CORE_GRAMMAR_JSON_FILE} ${GLSL_GRAMMAR_JSON_FILE}
+ COMMENT "Generate info tables for GLSL extended instructions and operands v${VERSION}.")
+ list(APPEND EXTINST_CPP_DEPENDS ${GRAMMAR_INC_FILE})
+endmacro(spvtools_glsl_tables)
+
+macro(spvtools_opencl_tables VERSION)
+ set(CORE_GRAMMAR_JSON_FILE "${CMAKE_CURRENT_SOURCE_DIR}/spirv-${VERSION}.core.grammar.json")
+ set(OPENCL_GRAMMAR_JSON_FILE "${CMAKE_CURRENT_SOURCE_DIR}/extinst-${VERSION}.opencl.std.grammar.json")
+ set(GRAMMAR_INC_FILE "${spirv-tools_BINARY_DIR}/opencl.std.insts-${VERSION}.inc")
+ add_custom_command(OUTPUT ${GRAMMAR_INC_FILE}
+ COMMAND ${PYTHON_EXECUTABLE} ${GRAMMAR_PROCESSING_SCRIPT}
+ --spirv-core-grammar=${CORE_GRAMMAR_JSON_FILE}
+ --extinst-opencl-grammar=${OPENCL_GRAMMAR_JSON_FILE}
+ --opencl-insts-output=${GRAMMAR_INC_FILE}
+ DEPENDS ${GRAMMAR_PROCESSING_SCRIPT} ${CORE_GRAMMAR_JSON_FILE} ${OPENCL_GRAMMAR_JSON_FILE}
+ COMMENT "Generate info tables for OpenCL extended instructions and operands v${VERSION}.")
+ list(APPEND EXTINST_CPP_DEPENDS ${GRAMMAR_INC_FILE})
+endmacro(spvtools_opencl_tables)
+
+spvtools_core_tables("1-0")
+spvtools_core_tables("1-1")
+spvtools_opencl_tables("1-0")
+spvtools_glsl_tables("1-0")
+
+# The following .cpp files include the above generated .inc files.
+# Add those .inc files as their dependencies.
+#
+# Why using such an awkward way?
+# * If we use add_custom_target() to define a target to generate all .inc files
+# and let ${SPIRV_TOOLS} depend on it, then we need to run ninja twice every
+# time the grammar is updated: the first time is for generating those .inc
+# files, and the second time is for rebuilding .cpp files, when ninja finds
+# out that .inc files are updated.
+# * If we use add_custom_command() with PRE_BUILD, then the grammar processing
+# script will always run no matter whether the grammar is updated.
+# * add_dependencies() is used to add *target* dependencies to a target.
+# * The following solution only generates .inc files when the script or the
+# grammar files is updated, and in a single ninja run.
+set_source_files_properties(
+ ${CMAKE_CURRENT_SOURCE_DIR}/opcode.cpp
+ PROPERTIES OBJECT_DEPENDS "${OPCODE_CPP_DEPENDS}")
+set_source_files_properties(
+ ${CMAKE_CURRENT_SOURCE_DIR}/operand.cpp
+ PROPERTIES OBJECT_DEPENDS "${OPERAND_CPP_DEPENDS}")
+set_source_files_properties(
+ ${CMAKE_CURRENT_SOURCE_DIR}/operand.cpp
+ PROPERTIES OBJECT_DEPENDS "${EXTINST_CPP_DEPENDS}")
+
set(SPIRV_SOURCES
${spirv-tools_SOURCE_DIR}/include/spirv-tools/libspirv.h
${spirv-tools_SOURCE_DIR}/include/spirv/spirv.h
@@ -76,9 +154,6 @@
PUBLIC ${spirv-tools_SOURCE_DIR}/include
PRIVATE ${spirv-tools_BINARY_DIR}
)
-add_dependencies(${SPIRV_TOOLS}
- spirv-tools-build-core-tables-1-0 spirv-tools-build-core-tables-1-1
- spirv-tools-build-glsl-tables-1-0 spirv-tools-build-opencl-tables-1-0)
install(TARGETS ${SPIRV_TOOLS}
RUNTIME DESTINATION bin