dawn: Add install command to CMakeLists files

Change-Id: I39503bb0f53c1932e3bf7925b38203c60e458a2e
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/136500
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 21b833c..4db6cd0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -76,6 +76,45 @@
     endif()
 endfunction()
 
+function (install_if_enabled target)
+    if(NOT DAWN_ENABLE_INSTALL)
+        return()
+    endif()
+
+    install(TARGETS ${target}
+        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    )
+
+    get_target_property(targetHeaders ${target} INTERFACE_SOURCES)
+    if (NOT targetHeaders)
+        return()
+    endif()
+
+    foreach(headerFile ${targetHeaders})
+        # Starting from CMake 3.20 there is the cmake_path command that could simplify this code.
+        # Compute the install subdirectory for the header by stripping out the path to
+        # the include / gen/include directory...
+        string(FIND "${headerFile}" "${DAWN_INCLUDE_DIR}" foundIndex)
+        if (foundIndex EQUAL 0)
+            string(LENGTH "${DAWN_INCLUDE_DIR}/" lengthToRemove)
+        endif()
+        string(FIND "${headerFile}" "${DAWN_BUILD_GEN_DIR}/include/" foundIndex)
+        if (foundIndex EQUAL 0)
+            string(LENGTH "${DAWN_BUILD_GEN_DIR}/include/" lengthToRemove)
+        endif()
+        string(SUBSTRING "${headerFile}" "${lengthToRemove}" -1 headerRelDir)
+
+        # ... then remove everything after the last /
+        string(FIND "${headerRelDir}" "/" foundIndex REVERSE)
+        string(SUBSTRING "${headerRelDir}" 0 ${foundIndex} headerRelDir)
+
+        install(FILES "${headerFile}" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${headerRelDir})
+    endforeach()
+endfunction()
+
+
 # Default values for the backend-enabling options
 set(ENABLE_D3D11 OFF)
 set(ENABLE_D3D12 OFF)
@@ -121,6 +160,7 @@
 endif()
 
 option_if_not_defined(DAWN_ENABLE_ASAN "Enable address sanitizer" OFF)
+option_if_not_defined(DAWN_ENABLE_INSTALL "Enable install step for Dawn libraries" OFF)
 option_if_not_defined(DAWN_ENABLE_TSAN "Enable thread sanitizer" OFF)
 option_if_not_defined(DAWN_ENABLE_MSAN "Enable memory sanitizer" OFF)
 option_if_not_defined(DAWN_ENABLE_UBSAN "Enable undefined behaviour sanitizer" OFF)
@@ -155,6 +195,7 @@
   set(TINT_DEFAULT_GLSL OFF)
 endif()
 
+option_if_not_defined(TINT_ENABLE_INSTALL "Enable install step for Tint libraries" OFF)
 option_if_not_defined(TINT_BUILD_CMD_TOOLS "Build the Tint command line tools" ON)
 option_if_not_defined(TINT_BUILD_DOCS "Build documentation" ON)
 option_if_not_defined(TINT_DOCS_WARN_AS_ERROR "When building documentation, treat warnings as errors" OFF)
diff --git a/generator/CMakeLists.txt b/generator/CMakeLists.txt
index 6b9c0f4..fe30f97 100644
--- a/generator/CMakeLists.txt
+++ b/generator/CMakeLists.txt
@@ -92,6 +92,8 @@
         COMMENT "Dawn: Generating files for ${G_PRINT_NAME}."
     )
 
+    set_source_files_properties(${OUTPUTS} PROPERTIES GENERATED TRUE)
+
     # Return the list of outputs.
     set(${G_RESULT_VARIABLE} ${OUTPUTS} PARENT_SCOPE)
 endfunction()
diff --git a/src/dawn/CMakeLists.txt b/src/dawn/CMakeLists.txt
index 6a32109..a6913d4 100644
--- a/src/dawn/CMakeLists.txt
+++ b/src/dawn/CMakeLists.txt
@@ -73,8 +73,13 @@
 # because the file doesn't exist on disk.
 add_library(dawn_headers STATIC ${DAWN_PLACEHOLDER_FILE})
 common_compile_options(dawn_headers)
-target_sources(dawn_headers PRIVATE ${DAWN_HEADERS_GEN_SOURCES})
+target_sources(dawn_headers INTERFACE
+    "${DAWN_INCLUDE_DIR}/webgpu/webgpu.h"
+    PRIVATE
+    ${DAWN_HEADERS_GEN_SOURCES}
+)
 target_link_libraries(dawn_headers INTERFACE dawn_public_config)
+install_if_enabled(dawn_headers)
 
 ###############################################################################
 # Dawn C++ headers
@@ -90,12 +95,14 @@
 # dawn_headers above.
 add_library(dawncpp_headers STATIC ${DAWN_PLACEHOLDER_FILE})
 common_compile_options(dawncpp_headers)
-target_sources(dawncpp_headers PRIVATE
+target_sources(dawncpp_headers INTERFACE
+    "${DAWN_INCLUDE_DIR}/webgpu/webgpu_cpp.h"
     "${DAWN_INCLUDE_DIR}/dawn/EnumClassBitmasks.h"
+    PRIVATE
     ${DAWNCPP_HEADERS_GEN_SOURCES}
 )
 target_link_libraries(dawncpp_headers INTERFACE dawn_headers)
-
+install_if_enabled(dawncpp_headers)
 ###############################################################################
 # Dawn C++ wrapper
 ###############################################################################
@@ -113,6 +120,8 @@
 
 add_library(webgpu_cpp ALIAS dawncpp)
 
+install_if_enabled(dawncpp)
+
 ###############################################################################
 # libdawn_proc
 ###############################################################################
@@ -129,9 +138,17 @@
 if(BUILD_SHARED_LIBS)
     target_compile_definitions(dawn_proc PRIVATE "WGPU_SHARED_LIBRARY")
 endif()
-target_sources(dawn_proc PRIVATE ${DAWNPROC_GEN_SOURCES})
+target_sources(dawn_proc
+  INTERFACE
+    "${DAWN_INCLUDE_DIR}/dawn/dawn_thread_dispatch_proc.h"
+    "${DAWN_INCLUDE_DIR}/dawn/dawn_proc.h"
+  PRIVATE
+    ${DAWNPROC_GEN_SOURCES}
+)
 target_link_libraries(dawn_proc PUBLIC dawn_headers)
 
+install_if_enabled(dawn_proc)
+
 ###############################################################################
 # Other generated files (upstream header, emscripten header, emscripten bits)
 ###############################################################################
diff --git a/src/dawn/glfw/CMakeLists.txt b/src/dawn/glfw/CMakeLists.txt
index a564501..d612f01 100644
--- a/src/dawn/glfw/CMakeLists.txt
+++ b/src/dawn/glfw/CMakeLists.txt
@@ -16,7 +16,10 @@
 
 add_library(dawn_glfw STATIC ${DAWN_PLACEHOLDER_FILE})
 common_compile_options(dawn_glfw)
-target_sources(dawn_glfw PRIVATE
+target_sources(dawn_glfw
+  INTERFACE
+    "${DAWN_INCLUDE_DIR}/webgpu/webgpu_glfw.h"
+  PRIVATE
     "utils.cpp"
 )
 target_link_libraries(dawn_glfw
diff --git a/src/dawn/native/CMakeLists.txt b/src/dawn/native/CMakeLists.txt
index 145e48f..dbe1021 100644
--- a/src/dawn/native/CMakeLists.txt
+++ b/src/dawn/native/CMakeLists.txt
@@ -26,9 +26,11 @@
     target_compile_definitions(dawn_native PRIVATE "DAWN_NATIVE_SHARED_LIBRARY")
 endif()
 
-target_sources(dawn_native PRIVATE
+target_sources(dawn_native
+  INTERFACE
     "${DAWN_INCLUDE_DIR}/dawn/native/DawnNative.h"
     "${DAWN_INCLUDE_DIR}/dawn/native/dawn_native_export.h"
+  PRIVATE
     ${DAWN_NATIVE_UTILS_GEN_SOURCES}
     "Adapter.h"
     "Adapter.cpp"
@@ -268,8 +270,10 @@
 endif()
 
 if (DAWN_ENABLE_D3D11 OR DAWN_ENABLE_D3D12)
-    target_sources(dawn_native PRIVATE
+    target_sources(dawn_native
+      INTERFACE
         "${DAWN_INCLUDE_DIR}/dawn/native/D3DBackend.h"
+      PRIVATE
         "d3d/BackendD3D.cpp"
         "d3d/BackendD3D.h"
         "d3d/BlobD3D.cpp"
@@ -305,8 +309,10 @@
 endif()
 
 if (DAWN_ENABLE_D3D11)
-    target_sources(dawn_native PRIVATE
+    target_sources(dawn_native
+      INTERFACE
         "${DAWN_INCLUDE_DIR}/dawn/native/D3D11Backend.h"
+      PRIVATE
         "d3d11/BackendD3D11.cpp"
         "d3d11/BackendD3D11.h"
         "d3d11/BindGroupD3D11.cpp"
@@ -360,8 +366,10 @@
 endif()
 
 if (DAWN_ENABLE_D3D12)
-    target_sources(dawn_native PRIVATE
+    target_sources(dawn_native
+      INTERFACE
         "${DAWN_INCLUDE_DIR}/dawn/native/D3D12Backend.h"
+      PRIVATE
         "d3d12/BackendD3D12.cpp"
         "d3d12/BackendD3D12.h"
         "d3d12/BindGroupD3D12.cpp"
@@ -445,8 +453,10 @@
 endif()
 
 if (DAWN_ENABLE_METAL)
-    target_sources(dawn_native PRIVATE
+    target_sources(dawn_native
+      INTERFACE
         "${DAWN_INCLUDE_DIR}/dawn/native/MetalBackend.h"
+      PRIVATE
         "Surface_metal.mm"
         "metal/BackendMTL.h"
         "metal/BackendMTL.mm"
@@ -498,8 +508,10 @@
 endif()
 
 if (DAWN_ENABLE_NULL)
-    target_sources(dawn_native PRIVATE
+    target_sources(dawn_native
+      INTERFACE
         "${DAWN_INCLUDE_DIR}/dawn/native/NullBackend.h"
+      PRIVATE
         "null/DeviceNull.cpp"
         "null/DeviceNull.h"
     )
@@ -524,8 +536,10 @@
         RESULT_VARIABLE "DAWN_NATIVE_OPENGL_AUTOGEN_SOURCES"
     )
 
-    target_sources(dawn_native PRIVATE
+    target_sources(dawn_native
+      INTERFACE
         "${DAWN_INCLUDE_DIR}/dawn/native/OpenGLBackend.h"
+      PRIVATE
         ${DAWN_NATIVE_OPENGL_AUTOGEN_SOURCES}
         "opengl/BackendGL.cpp"
         "opengl/BackendGL.h"
@@ -589,7 +603,9 @@
 
 if (DAWN_ENABLE_VULKAN)
     target_sources(dawn_native PRIVATE
+       INTERFACE
         "${DAWN_INCLUDE_DIR}/dawn/native/VulkanBackend.h"
+      PRIVATE
         "vulkan/BackendVk.cpp"
         "vulkan/BackendVk.h"
         "vulkan/BindGroupLayoutVk.cpp"
@@ -721,3 +737,6 @@
     target_compile_definitions(webgpu_dawn PRIVATE "WGPU_SHARED_LIBRARY")
 endif()
 target_sources(webgpu_dawn PRIVATE ${WEBGPU_DAWN_NATIVE_PROC_GEN})
+
+install_if_enabled(dawn_native)
+install_if_enabled(webgpu_dawn)
diff --git a/src/dawn/platform/CMakeLists.txt b/src/dawn/platform/CMakeLists.txt
index 5aa9ee0..58a3520 100644
--- a/src/dawn/platform/CMakeLists.txt
+++ b/src/dawn/platform/CMakeLists.txt
@@ -21,8 +21,10 @@
 endif()
 
 target_sources(dawn_platform PRIVATE
+  PUBLIC
     "${DAWN_INCLUDE_DIR}/dawn/platform/DawnPlatform.h"
     "${DAWN_INCLUDE_DIR}/dawn/platform/dawn_platform_export.h"
+  PRIVATE
     "DawnPlatform.cpp"
     "WorkerThread.cpp"
     "WorkerThread.h"
@@ -33,3 +35,5 @@
     "tracing/TraceEvent.h"
 )
 target_link_libraries(dawn_platform PUBLIC dawn_headers PRIVATE dawn_internal_config dawn_common)
+
+install_if_enabled(dawn_platform)
diff --git a/src/dawn/wire/CMakeLists.txt b/src/dawn/wire/CMakeLists.txt
index d1a1f3c..da030bb 100644
--- a/src/dawn/wire/CMakeLists.txt
+++ b/src/dawn/wire/CMakeLists.txt
@@ -27,10 +27,12 @@
 endif()
 
 target_sources(dawn_wire PRIVATE
+  INTERFACE
     "${DAWN_INCLUDE_DIR}/dawn/wire/Wire.h"
     "${DAWN_INCLUDE_DIR}/dawn/wire/WireClient.h"
     "${DAWN_INCLUDE_DIR}/dawn/wire/WireServer.h"
     "${DAWN_INCLUDE_DIR}/dawn/wire/dawn_wire_export.h"
+  PRIVATE
     ${DAWN_WIRE_GEN_SOURCES}
     "BufferConsumer.h"
     "BufferConsumer_impl.h"
@@ -95,3 +97,5 @@
     PUBLIC dawn_headers
     PRIVATE dawn_common dawn_internal_config
 )
+
+install_if_enabled(dawn_wire)
diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt
index 2da7f95..8741ed9 100644
--- a/src/tint/CMakeLists.txt
+++ b/src/tint/CMakeLists.txt
@@ -347,6 +347,12 @@
 
   if(${KIND} STREQUAL lib)
     add_library(${TARGET} STATIC EXCLUDE_FROM_ALL)
+    if (TINT_ENABLE_INSTALL)
+      install(TARGETS ${TARGET}
+        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+      )
+    endif()
     tint_default_compile_options(${TARGET})
 
     if(TINT_BUILD_FUZZERS)
@@ -355,6 +361,12 @@
       set(FUZZ_TARGET "${TARGET}${TINT_FUZZ_SUFFIX}")
       add_library(${FUZZ_TARGET} STATIC EXCLUDE_FROM_ALL)
       target_sources(${FUZZ_TARGET} PRIVATE ${SOURCES})
+      if (TINT_ENABLE_INSTALL)
+        install(TARGETS ${FUZZ_TARGET}
+                LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+                ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+                )
+      endif()
       tint_default_compile_options(${FUZZ_TARGET})
     endif()
   elseif(${KIND} STREQUAL cmd)
@@ -587,3 +599,17 @@
 # Target aliases
 ################################################################################
 add_library(libtint ALIAS tint_api)
+
+if (TINT_ENABLE_INSTALL)
+  # We need to recurse all folders and include all headers because tint.h includes most headers from src/tint
+  file(GLOB TINT_HEADERS "${DAWN_INCLUDE_DIR}/tint/*.h")
+
+  install(FILES ${TINT_HEADERS}  DESTINATION  ${CMAKE_INSTALL_INCLUDEDIR}/tint/)
+
+  file(GLOB_RECURSE TINT_SRC_HEADERS RELATIVE ${CMAKE_SOURCE_DIR}/src/tint/ "*.h")
+
+  foreach(TINT_HEADER_FILE ${TINT_SRC_HEADERS})
+      get_filename_component(TINT_HEADER_DIR ${TINT_HEADER_FILE} DIRECTORY)
+      install(FILES ${CMAKE_SOURCE_DIR}/src/tint/${TINT_HEADER_FILE}  DESTINATION  ${CMAKE_INSTALL_INCLUDEDIR}/src/tint/${TINT_HEADER_DIR})
+  endforeach ()
+endif()