Make DawnGenerator output names of headers and sources in separate variables

Change-Id: Ie99e5aedc3874bf3fa009586c957e40beb28c599
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/195476
Commit-Queue: Jaswant Panchumarti <jaswant.panchumarti@kitware.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Auto-Submit: Jaswant Panchumarti <jaswant.panchumarti@kitware.com>
diff --git a/generator/CMakeLists.txt b/generator/CMakeLists.txt
index 2393198..50d2a87 100644
--- a/generator/CMakeLists.txt
+++ b/generator/CMakeLists.txt
@@ -42,25 +42,34 @@
 
 # Function to invoke a generator_lib.py generator.
 #  - SCRIPT is the name of the script to call
+#  - OUTPUT_HEADERS will be modified to contain the list of header files (*.h, *.hpp) generated by this generator
+#  - OUTPUT_SOURCES will be modified to contain the list of all other files generated by this generator
 #  - ARGS are the extra arguments to pass to the script in addition to the base generator_lib.py arguments
 #  - PRINT_NAME is the name to use when outputting status or errors
-#  - RESULT_VARIABLE will be modified to contain the list of files generated by this generator
 function(DawnGenerator)
-    set(oneValueArgs SCRIPT RESULT_VARIABLE PRINT_NAME)
-    set(multiValueArgs ARGS)
-    cmake_parse_arguments(G "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+    cmake_parse_arguments(PARSE_ARGV 0 arg
+        ""
+        "SCRIPT;OUTPUT_HEADERS;OUTPUT_SOURCES;PRINT_NAME"
+        "EXTRA_PARAMETERS"
+    )
+
+    if (arg_UNPARSED_ARGUMENTS)
+      message(FATAL_ERROR
+        "Unparsed arguments for DawnGenerator: "
+        "${arg_UNPARSED_ARGUMENTS}")
+    endif ()
 
     # Build the set of args common to all invocation of that generator.
     set(BASE_ARGS
         ${Python3_EXECUTABLE}
-        ${G_SCRIPT}
+        ${arg_SCRIPT}
         --template-dir
         "${DAWN_TEMPLATE_DIR}"
         --root-dir
         "${Dawn_SOURCE_DIR}"
         --output-dir
         "${DAWN_BUILD_GEN_DIR}"
-        ${G_ARGS}
+        ${arg_EXTRA_PARAMETERS}
     )
     if (DAWN_JINJA2_DIR)
         list(APPEND BASE_ARGS --jinja2-path ${DAWN_JINJA2_DIR})
@@ -76,7 +85,7 @@
         RESULT_VARIABLE RET
     )
     if (NOT RET EQUAL 0)
-        message(FATAL_ERROR "Dawn: Failed to get the dependencies for ${G_PRINT_NAME}. Base args are '${BASE_ARGS}'.")
+        message(FATAL_ERROR "Dawn: Failed to get the dependencies for ${arg_PRINT_NAME}. Base args are '${BASE_ARGS}'.")
     endif()
 
     # Ask CMake to re-run if any of the dependencies changed as it might modify the build graph.
@@ -89,7 +98,7 @@
         RESULT_VARIABLE RET
     )
     if (NOT RET EQUAL 0)
-        message(FATAL_ERROR "Dawn: Failed to get the outputs for ${G_PRINT_NAME}. Base args are '${BASE_ARGS}'.")
+        message(FATAL_ERROR "Dawn: Failed to get the outputs for ${arg_PRINT_NAME}. Base args are '${BASE_ARGS}'.")
     endif()
 
     # Add the custom command that calls the generator.
@@ -97,11 +106,35 @@
         COMMAND ${BASE_ARGS}
         DEPENDS ${DEPENDENCIES}
         OUTPUT ${OUTPUTS}
-        COMMENT "Dawn: Generating files for ${G_PRINT_NAME}."
+        COMMENT "Dawn: Generating files for ${arg_PRINT_NAME}."
     )
 
-    # Return the list of outputs.
-    set(${G_RESULT_VARIABLE} ${OUTPUTS} PARENT_SCOPE)
+    # Populate the list of outputs.
+    set(headers)
+    set(sources)
+    foreach (filename IN LISTS OUTPUTS)
+        get_filename_component(extension "${filename}" EXT)
+        if (extension MATCHES "(h|hpp)")
+            list(APPEND headers "${filename}")
+        else ()
+            list(APPEND sources "${filename}")
+        endif ()
+    endforeach ()
+
+    if (sources AND NOT arg_OUTPUT_SOURCES)
+        message(FATAL_ERROR
+            "This function generated source files, although an output variable was not defined!"
+            "Please provide a variable name for OUTPUT_SOURCES.")
+    endif ()
+
+    if (headers AND NOT arg_OUTPUT_HEADERS)
+        message(FATAL_ERROR
+            "This function generated header files, although an output variable was not defined!"
+            "Please provide a variable name for OUTPUT_HEADERS.")
+    endif ()
+
+    set(${arg_OUTPUT_SOURCES} ${sources} PARENT_SCOPE)
+    set(${arg_OUTPUT_HEADERS} ${headers} PARENT_SCOPE)
 
     # Prior to CMake 3.20 the GENERATED property is local to a directory which means that putting
     # generated headers in INTERFACE properties causes dependent targets to complain that they
@@ -116,35 +149,58 @@
     endforeach()
 
     if (${needToGenerate})
-        message(STATUS "Dawn: Generating initial versions of files for ${G_PRINT_NAME}.")
+        message(STATUS "Dawn: Generating initial versions of files for ${arg_PRINT_NAME}.")
         execute_process(COMMAND ${BASE_ARGS} RESULT_VARIABLE RET)
         if (NOT RET EQUAL 0)
-            message(FATAL_ERROR "Dawn: Failed to generate the initial version of files for ${G_PRINT_NAME}. Base args are '${BASE_ARGS}'.")
+            message(FATAL_ERROR "Dawn: Failed to generate the initial version of files for ${arg_PRINT_NAME}. Base args are '${BASE_ARGS}'.")
         endif()
     endif()
 endfunction()
 
 # Helper function to call dawn_generator.py:
 #  - TARGET is the generator target to build
-#  - PRINT_NAME and RESULT_VARIABLE are like for DawnGenerator
+#  - OUTPUT_HEADERS, OUTPUT_SOURCES, and PRINT_NAME are like for DawnGenerator
 function(DawnJSONGenerator)
-    set(oneValueArgs TARGET RESULT_VARIABLE)
-    cmake_parse_arguments(G "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
-
+    cmake_parse_arguments(PARSE_ARGV 0 arg
+        ""
+        "TARGET;OUTPUT_SOURCES;OUTPUT_HEADERS;PRINT_NAME"
+        ""
+    )
     DawnGenerator(
         SCRIPT "${Dawn_SOURCE_DIR}/generator/dawn_json_generator.py"
-        ARGS --dawn-json
+        OUTPUT_HEADERS HEADERS
+        OUTPUT_SOURCES SOURCES
+        EXTRA_PARAMETERS
+             --dawn-json
              "${Dawn_SOURCE_DIR}/src/dawn/dawn.json"
              --wire-json
              "${Dawn_SOURCE_DIR}/src/dawn/dawn_wire.json"
              --kotlin-json
              "${Dawn_SOURCE_DIR}/src/dawn/dawn_kotlin.json"
              --targets
-             ${G_TARGET}
-        RESULT_VARIABLE RET
-        ${G_UNPARSED_ARGUMENTS}
+             ${arg_TARGET}
+             ${arg_UNPARSED_ARGUMENTS}
     )
 
+    if (SOURCES AND NOT arg_OUTPUT_SOURCES)
+        message(FATAL_ERROR
+            "This function generated source files, although an output variable was not defined!"
+            "Please provide a variable name for OUTPUT_SOURCES.")
+    elseif (arg_OUTPUT_SOURCES AND NOT SOURCES)
+        message(WARNING
+            "This function did not generate source files. The OUTPUT_SOURCES argument is unnecessary.")
+    endif ()
+
+    if (HEADERS AND NOT arg_OUTPUT_HEADERS)
+        message(FATAL_ERROR
+            "This function generated header files, although an output variable was not defined!"
+            "Please provide a variable name for OUTPUT_HEADERS.")
+    elseif (arg_OUTPUT_HEADERS AND NOT HEADERS)
+        message(WARNING
+            "This function did not generate header files. The OUTPUT_HEADERS argument is unnecessary.")
+    endif ()
+
     # Forward the result up one more scope
-    set(${G_RESULT_VARIABLE} ${RET} PARENT_SCOPE)
+    set(${arg_OUTPUT_SOURCES} ${SOURCES} PARENT_SCOPE)
+    set(${arg_OUTPUT_HEADERS} ${HEADERS} PARENT_SCOPE)
 endfunction()
diff --git a/src/dawn/CMakeLists.txt b/src/dawn/CMakeLists.txt
index 6e0932e..bc8d6fb 100644
--- a/src/dawn/CMakeLists.txt
+++ b/src/dawn/CMakeLists.txt
@@ -56,13 +56,13 @@
 DawnJSONGenerator(
     TARGET "headers"
     PRINT_NAME "Dawn headers"
-    RESULT_VARIABLE "DAWN_HEADERS_GEN_SOURCES"
+    OUTPUT_HEADERS DAWN_HEADERS_GEN_HEADERS
 )
 
 add_library(dawn_headers INTERFACE)
 target_sources(dawn_headers PUBLIC
     "${DAWN_INCLUDE_DIR}/webgpu/webgpu.h"
-    ${DAWN_HEADERS_GEN_SOURCES}
+    ${DAWN_HEADERS_GEN_HEADERS}
 )
 target_link_libraries(dawn_headers INTERFACE dawn_public_config)
 install_if_enabled(dawn_headers)
@@ -74,14 +74,14 @@
 DawnJSONGenerator(
     TARGET "cpp_headers"
     PRINT_NAME "Dawn C++ headers"
-    RESULT_VARIABLE "DAWNCPP_HEADERS_GEN_SOURCES"
+    OUTPUT_HEADERS DAWNCPP_HEADERS_GEN_HEADERS
 )
 
 add_library(dawncpp_headers INTERFACE)
 target_sources(dawncpp_headers PUBLIC
     "${DAWN_INCLUDE_DIR}/webgpu/webgpu_cpp.h"
     "${DAWN_INCLUDE_DIR}/webgpu/webgpu_enum_class_bitmasks.h"
-    ${DAWNCPP_HEADERS_GEN_SOURCES}
+    ${DAWNCPP_HEADERS_GEN_HEADERS}
 )
 target_link_libraries(dawncpp_headers INTERFACE dawn_headers)
 install_if_enabled(dawncpp_headers)
@@ -96,7 +96,7 @@
 DawnJSONGenerator(
     TARGET "proc"
     PRINT_NAME "Dawn C++ wrapper"
-    RESULT_VARIABLE "DAWNPROC_GEN_SOURCES"
+    OUTPUT_SOURCES DAWNPROC_GEN_SOURCES
 )
 
 add_library(dawn_proc)
@@ -129,17 +129,20 @@
 DawnJSONGenerator(
     TARGET "webgpu_headers"
     PRINT_NAME "WebGPU headers"
-    RESULT_VARIABLE "WEBGPU_HEADERS_GEN_SOURCES"
+    OUTPUT_HEADERS WEBGPU_HEADERS_GEN_HEADERS
 )
 add_custom_target(webgpu_headers_gen
-    DEPENDS ${WEBGPU_HEADERS_GEN_SOURCES}
+    DEPENDS ${WEBGPU_HEADERS_GEN_HEADERS}
 )
 
 DawnJSONGenerator(
     TARGET "emscripten_bits"
     PRINT_NAME "Emscripten WebGPU bits"
-    RESULT_VARIABLE "EMSCRIPTEN_BITS_GEN_SOURCES"
+    OUTPUT_HEADERS EMSCRIPTEN_BITS_GEN_HEADERS
+    OUTPUT_SOURCES EMSCRIPTEN_BITS_GEN_SOURCES
 )
 add_custom_target(emscripten_bits_gen
-    DEPENDS ${EMSCRIPTEN_BITS_GEN_SOURCES}
+    DEPENDS
+        ${EMSCRIPTEN_BITS_GEN_HEADERS}
+        ${EMSCRIPTEN_BITS_GEN_SOURCES}
 )
diff --git a/src/dawn/common/CMakeLists.txt b/src/dawn/common/CMakeLists.txt
index 615d3ec..5dc85a8 100644
--- a/src/dawn/common/CMakeLists.txt
+++ b/src/dawn/common/CMakeLists.txt
@@ -28,23 +28,25 @@
 DawnGenerator(
     SCRIPT "${Dawn_SOURCE_DIR}/generator/dawn_version_generator.py"
     PRINT_NAME "Dawn version based utilities"
-    ARGS "--dawn-dir"
+    OUTPUT_HEADERS DAWN_VERSION_AUTOGEN_HEADERS
+    EXTRA_PARAMETERS "--dawn-dir"
          "${Dawn_SOURCE_DIR}"
-    RESULT_VARIABLE "DAWN_VERSION_AUTOGEN_SOURCES"
 )
 
 DawnGenerator(
     SCRIPT "${Dawn_SOURCE_DIR}/generator/dawn_gpu_info_generator.py"
     PRINT_NAME "Dawn GPU info utilities"
-    ARGS "--gpu-info-json"
+    OUTPUT_HEADERS DAWN_GPU_INFO_AUTOGEN_HEADERS
+    OUTPUT_SOURCES DAWN_GPU_INFO_AUTOGEN_SOURCES
+    EXTRA_PARAMETERS "--gpu-info-json"
          "${Dawn_SOURCE_DIR}/src/dawn/gpu_info.json"
-    RESULT_VARIABLE "DAWN_GPU_INFO_AUTOGEN_SOURCES"
 )
 
 add_library(dawn_common STATIC)
 common_compile_options(dawn_common)
 target_sources(dawn_common PRIVATE
-    ${DAWN_VERSION_AUTOGEN_SOURCES}
+    ${DAWN_VERSION_AUTOGEN_HEADERS}
+    ${DAWN_GPU_INFO_AUTOGEN_HEADERS}
     ${DAWN_GPU_INFO_AUTOGEN_SOURCES}
     "AlignedAlloc.cpp"
     "AlignedAlloc.h"
diff --git a/src/dawn/native/CMakeLists.txt b/src/dawn/native/CMakeLists.txt
index 81ff638..8b2babc 100644
--- a/src/dawn/native/CMakeLists.txt
+++ b/src/dawn/native/CMakeLists.txt
@@ -28,7 +28,8 @@
 DawnJSONGenerator(
     TARGET "native_utils"
     PRINT_NAME "Dawn native utilities"
-    RESULT_VARIABLE "DAWN_NATIVE_UTILS_GEN_SOURCES"
+    OUTPUT_HEADERS DAWN_NATIVE_UTILS_GEN_HEADERS
+    OUTPUT_SOURCES DAWN_NATIVE_UTILS_GEN_SOURCES
 )
 
 add_library(dawn_native)
@@ -44,6 +45,7 @@
     "${DAWN_INCLUDE_DIR}/dawn/native/DawnNative.h"
     "${DAWN_INCLUDE_DIR}/dawn/native/dawn_native_export.h"
   PRIVATE
+    ${DAWN_NATIVE_UTILS_GEN_HEADERS}
     ${DAWN_NATIVE_UTILS_GEN_SOURCES}
     "Adapter.h"
     "Adapter.cpp"
@@ -568,17 +570,19 @@
     DawnGenerator(
         SCRIPT "${Dawn_SOURCE_DIR}/generator/opengl_loader_generator.py"
         PRINT_NAME "OpenGL function loader"
-        ARGS "--gl-xml"
+        EXTRA_PARAMETERS "--gl-xml"
              "${Dawn_SOURCE_DIR}/third_party/khronos/OpenGL-Registry/xml/gl.xml"
              "--supported-extensions"
              "${Dawn_SOURCE_DIR}/src/dawn/native/opengl/supported_extensions.json"
-        RESULT_VARIABLE "DAWN_NATIVE_OPENGL_AUTOGEN_SOURCES"
+        OUTPUT_HEADERS DAWN_NATIVE_OPENGL_AUTOGEN_HEADERS
+        OUTPUT_SOURCES DAWN_NATIVE_OPENGL_AUTOGEN_SOURCES
     )
 
     target_sources(dawn_native
       INTERFACE
         "${DAWN_INCLUDE_DIR}/dawn/native/OpenGLBackend.h"
       PRIVATE
+        ${DAWN_NATIVE_OPENGL_AUTOGEN_HEADERS}
         ${DAWN_NATIVE_OPENGL_AUTOGEN_SOURCES}
         "opengl/BackendGL.cpp"
         "opengl/BackendGL.h"
@@ -772,7 +776,7 @@
 DawnJSONGenerator(
     TARGET "webgpu_dawn_native_proc"
     PRINT_NAME "Dawn native WebGPU procs"
-    RESULT_VARIABLE "WEBGPU_DAWN_NATIVE_PROC_GEN"
+    OUTPUT_SOURCES WEBGPU_DAWN_NATIVE_PROC_GEN_SOURCES
 )
 
 # A convenience target that bundles dawn_native and procs calling it directly so that
@@ -789,7 +793,10 @@
 if(BUILD_SHARED_LIBS)
     target_compile_definitions(webgpu_dawn PRIVATE "WGPU_SHARED_LIBRARY")
 endif()
-target_sources(webgpu_dawn PRIVATE ${WEBGPU_DAWN_NATIVE_PROC_GEN})
+target_sources(webgpu_dawn
+    PRIVATE
+        ${WEBGPU_DAWN_NATIVE_PROC_GEN_SOURCES}
+)
 
 install_if_enabled(dawn_native)
 install_if_enabled(webgpu_dawn)
diff --git a/src/dawn/wire/CMakeLists.txt b/src/dawn/wire/CMakeLists.txt
index f61d68d..7c100c6 100644
--- a/src/dawn/wire/CMakeLists.txt
+++ b/src/dawn/wire/CMakeLists.txt
@@ -28,7 +28,8 @@
 DawnJSONGenerator(
     TARGET "wire"
     PRINT_NAME "Dawn wire"
-    RESULT_VARIABLE "DAWN_WIRE_GEN_SOURCES"
+    OUTPUT_HEADERS DAWN_WIRE_GEN_HEADERS
+    OUTPUT_SOURCES DAWN_WIRE_GEN_SOURCES
 )
 
 add_library(dawn_wire)
@@ -46,6 +47,7 @@
     "${DAWN_INCLUDE_DIR}/dawn/wire/WireServer.h"
     "${DAWN_INCLUDE_DIR}/dawn/wire/dawn_wire_export.h"
   PRIVATE
+    ${DAWN_WIRE_GEN_HEADERS}
     ${DAWN_WIRE_GEN_SOURCES}
     "BufferConsumer.h"
     "BufferConsumer_impl.h"