[cmake] Make DAWN_BUILD_MONOLITHIC_LIB control STATIC vs. SHARED.
Due to how the bundling process works, the monolithic library will only
be monolithic if BUILD_SHARED_LIBS=OFF, otherwise we don't bundle
objects from other SHARED libraries. Make the flag a tri-state:
OFF/STATIC/SHARED and make it control the type of bundled library that
is produced.
Bug:
Change-Id: I9b507d5965c6c088b1c2b3d438690fca6194e2e7
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/254234
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 30c8f59..c0c373b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -329,10 +329,22 @@
message(STATUS "Go exe: ${GO_EXECUTABLE}")
message(STATUS "")
-option(DAWN_FETCH_DEPENDENCIES "Use fetch_dawn_dependencies.py as an alternative to using depot_tools" OFF)
-option(DAWN_BUILD_MONOLITHIC_LIBRARY "Build one big monolithic library file" ON)
+# Handling of the type of monolithic library to build, if any.
+set(DAWN_BUILD_MONOLITHIC_LIBRARY "OFF" CACHE STRING "Build monolithic library: SHARED, STATIC, or OFF.")
+set_property(CACHE DAWN_BUILD_MONOLITHIC_LIBRARY PROPERTY STRINGS SHARED SHARED STATIC)
+string(TOUPPER "${DAWN_BUILD_MONOLITHIC_LIBRARY}" _option_upper)
+if(NOT _option_upper STREQUAL "OFF" AND
+ NOT _option_upper STREQUAL "SHARED" AND
+ NOT _option_upper STREQUAL "STATIC")
+ message(FATAL_ERROR "DAWN_BUILD_MONOLITHIC_LIBRARY must be SHARED, STATIC, or OFF, but was \"${DAWN_BUILD_MONOLITHIC_LIBRARY}\".")
+endif()
+if (DAWN_BUILD_MONOLITHIC_LIBRARY AND BUILD_SHARED_LIBS)
+ message(FATAL_ERROR "DAWN_BUILD_MONOLITHIC_LIBRARY SHARED/STATIC requires BUILD_SHARED_LIBS=OFF. Otherwise the bundled library will depend on other shared libraries which defeats the purpose.")
+endif()
message(STATUS "Dawn build monolithic library: ${DAWN_BUILD_MONOLITHIC_LIBRARY}")
+
+option(DAWN_FETCH_DEPENDENCIES "Use fetch_dawn_dependencies.py as an alternative to using depot_tools" OFF)
message(STATUS "Dawn fetch dependencies: ${DAWN_FETCH_DEPENDENCIES}")
message(STATUS "")
diff --git a/src/cmake/BundleLibraries.cmake b/src/cmake/BundleLibraries.cmake
index 0e93c9b..682a739 100644
--- a/src/cmake/BundleLibraries.cmake
+++ b/src/cmake/BundleLibraries.cmake
@@ -25,7 +25,7 @@
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-function(bundle_libraries output_target)
+function(bundle_libraries output_target library_type)
# This function recursively finds all dependencies of a given target.
# It populates a list variable named 'all_dependencies' in the parent scope.
# Note: This recursive approach with PARENT_SCOPE works but can be a bit
@@ -45,12 +45,9 @@
return()
endif()
- # Add the current target to the list in the parent scope
- # list(APPEND) modifies the variable in the current scope.
- # set(... PARENT_SCOPE) copies the current scope's variable to the parent scope.
- # This pattern, while slightly verbose, works for recursive list building across scopes.
+ # Add the current target to the list of dependencies that we have seen. It will be copied
+ # to the parent scope before returning at the end of this function.
list(APPEND all_dependencies ${input_target})
- set(all_dependencies ${all_dependencies} PARENT_SCOPE) # Propagate change up
# Get dependencies from LINK_LIBRARIES (Private and Public linkage)
get_target_property(link_libraries ${input_target} LINK_LIBRARIES)
@@ -72,6 +69,7 @@
# The final 'all_dependencies' list is available in the parent scope
# after the initial call to get_dependencies completes.
+ set(all_dependencies ${all_dependencies} PARENT_SCOPE) # Propagate change up
endfunction()
# ARGN contains all arguments after the named parameters so it is the list of
@@ -113,10 +111,9 @@
# Create the output library using the validated type and collected objects
# If all_objects is empty, add_library will still create an empty library of the specified type.
- add_library(${output_target} ${all_objects})
+ add_library(${output_target} ${library_type} ${all_objects})
# Add dependencies to ensure input targets are built before the bundled library.
# This handles the build order correctly.
add_dependencies(${output_target} ${ARGN})
-
endfunction()
diff --git a/src/dawn/native/CMakeLists.txt b/src/dawn/native/CMakeLists.txt
index 0719eb47..c160cfc 100644
--- a/src/dawn/native/CMakeLists.txt
+++ b/src/dawn/native/CMakeLists.txt
@@ -934,44 +934,59 @@
# Note that this library name is referenced in several places, search for it and things like:
# "{{.*}}_dawn" when you rename it.
###############################################################################
+
+ # First make an object library for webgpu_dawn_native_proc sources for the export macros to
+ # get applied as well as backend-specific dawn_native entrypoints that also use export macros.
+ # This is essentially the same as dawn_native but using OBJECT as a library type and the
+ # DAWN_BUILD_MONOLITHIC_LIBRARY option to choose the export macros.
DawnJSONGenerator(
TARGET "webgpu_dawn_native_proc"
PRINT_NAME "Dawn native WebGPU procs"
OUTPUT_SOURCES WEBGPU_DAWN_NATIVE_PROC_GEN_SOURCES
)
- # Bundle all objects of dawn_native, it's public dependencies and private dependencies.
- include(BundleLibraries)
- bundle_libraries(webgpu_dawn dawn::dawn_native_objects)
- add_library(dawn::webgpu_dawn ALIAS webgpu_dawn)
- # Compile backend specific sources along with webgpu_dawn_native_proc sources for export macros to get applied.
- target_sources(webgpu_dawn
- PRIVATE
+ dawn_add_library(
+ webgpu_dawn_objects
+ UTILITY_TARGET dawn_internal_config
+ FORCE_OBJECT
+ SOURCES
${WEBGPU_DAWN_NATIVE_PROC_GEN_SOURCES}
${dawn_component_srcs}
+ DEPENDS
+ ${dawn_native_public_depends}
+ PRIVATE_DEPENDS
+ dawn::dawn_native_objects
+ ${dawn_native_private_depends}
+ ${conditional_private_platform_depends}
)
- target_compile_definitions(webgpu_dawn
+
+ target_compile_definitions(webgpu_dawn_objects
PRIVATE
"WGPU_IMPLEMENTATION"
"DAWN_NATIVE_IMPLEMENTATION"
)
- if (BUILD_SHARED_LIBS)
- target_compile_definitions(webgpu_dawn
+ if (DAWN_BUILD_MONOLITHIC_LIBRARY STREQUAL SHARED)
+ target_compile_definitions(webgpu_dawn_objects
PUBLIC
- "$<$<BOOL:BUILD_SHARED_LIBS>:WGPU_SHARED_LIBRARY>"
- "$<$<BOOL:BUILD_SHARED_LIBS>:DAWN_NATIVE_SHARED_LIBRARY>"
+ "WGPU_SHARED_LIBRARY"
+ "DAWN_NATIVE_SHARED_LIBRARY"
)
endif()
- # Apart from dawn_public_config, everything else goes inside PRIVATE, otherwise install rules will complain that they were not exported.
- target_link_libraries(webgpu_dawn
- PUBLIC
- dawn_public_config
- PRIVATE
- dawn_internal_config
- ${dawn_native_public_depends}
- ${dawn_native_private_depends}
- ${conditional_private_platform_depends}
+
+ # Do the bundling of all the objects and dependencies together.
+ include(BundleLibraries)
+ bundle_libraries(webgpu_dawn ${DAWN_BUILD_MONOLITHIC_LIBRARY} webgpu_dawn_objects)
+ add_library(dawn::webgpu_dawn ALIAS webgpu_dawn)
+
+ # Since this is a bundled library, the only dependency is the config needed to use it.
+ target_link_libraries(
+ webgpu_dawn
+ PUBLIC
+ dawn_public_config
+ PRIVATE
+ ${conditional_private_platform_depends}
)
+
set(webgpu_dawn_public_headers)
foreach(dawn_target_name IN ITEMS dawn_headers dawncpp_headers dawn_native_objects)
get_target_property(headers "${dawn_target_name}" INTERFACE_SOURCES)