Skip to content

Commit 6d60a95

Browse files
manuel5975pcopybara-github
authored andcommitted
Allow static building of the monolithic dawn library: (lib)webgpu_dawn
- Update BundleLibraries to take another argument (STATIC or SHARED) - Change DAWN_BUILD_MONOLITHIC_LIBRARY from OFF/ON to OFF/STATIC/SHARED This is an imported pull request from google#33 GITHUB_PR_HEAD_SHA=74b9f13d2c44fbdc8bc8cbede44325ff1f75b164 ORIGINAL_AUTHOR=Manuel <[email protected]> GitOrigin-RevId: 44f76ba Change-Id: I69dc673656e43c6c1a3c710ece00ecf16a8b9cde
1 parent dfc39c5 commit 6d60a95

File tree

3 files changed

+109
-21
lines changed

3 files changed

+109
-21
lines changed

CMakeLists.txt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -335,11 +335,10 @@ message(STATUS "Webgpu IDL path: ${WEBGPU_IDL_PATH}")
335335
message(STATUS "Go exe: ${GO_EXECUTABLE}")
336336
message(STATUS "")
337337

338-
option(DAWN_FETCH_DEPENDENCIES "Use fetch_dawn_dependencies.py as an alternative to using depot_tools" OFF)
339-
option(DAWN_BUILD_MONOLITHIC_LIBRARY "Bundle all dawn components into a single shared library." ON)
338+
option(DAWN_BUILD_MONOLITHIC_LIBRARY "Build one big monolithic library file" ON)
340339

341-
message(STATUS "Dawn fetch dependencies: ${DAWN_FETCH_DEPENDENCIES}")
342340
message(STATUS "Dawn build monolithic library: ${DAWN_BUILD_MONOLITHIC_LIBRARY}")
341+
message(STATUS "Dawn fetch dependencies: ${DAWN_FETCH_DEPENDENCIES}")
343342
message(STATUS "")
344343

345344
# Much of the backend code is shared among desktop OpenGL and OpenGL ES

src/cmake/BundleLibraries.cmake

Lines changed: 81 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,49 +25,121 @@
2525
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2626
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2727

28-
function(bundle_libraries output_target)
28+
function(bundle_libraries output_target library_type)
29+
30+
# 1. Validate the library_type argument
31+
string(TOUPPER ${library_type} upper_library_type)
32+
if(NOT (upper_library_type STREQUAL "STATIC" OR upper_library_type STREQUAL "SHARED"))
33+
message(FATAL_ERROR "bundle_libraries: Invalid library type specified '${library_type}'. Must be STATIC or SHARED for target '${output_target}'.")
34+
return() # Fatal error stops execution, but return is good practice
35+
endif()
36+
37+
# Use the validated type in upper case
38+
set(_target_type ${upper_library_type})
39+
40+
# --- Inner helper function to get dependencies ---
41+
# This function recursively finds all dependencies of a given target.
42+
# It populates a list variable named 'all_dependencies' in the parent scope.
43+
# Note: This recursive approach with PARENT_SCOPE works but can be a bit
44+
# tricky with variable lifetimes. It assumes 'all_dependencies' is
45+
# initialized in the calling scope.
2946
function(get_dependencies input_target)
47+
# Resolve aliases first
3048
get_target_property(alias ${input_target} ALIASED_TARGET)
3149
if(TARGET ${alias})
3250
set(input_target ${alias})
3351
endif()
52+
53+
# Avoid processing the same target multiple times (circular dependency check)
54+
# Checks if the current target is already in the list being built in the parent scope.
55+
# Note: all_dependencies is modified in parent scope below, so check works.
3456
if(${input_target} IN_LIST all_dependencies)
57+
#message("DEBUG: Already processed ${input_target}")
3558
return()
3659
endif()
60+
61+
# Add the current target to the list in the parent scope
62+
# list(APPEND) modifies the variable in the current scope.
63+
# set(... PARENT_SCOPE) copies the current scope's variable to the parent scope.
64+
# This pattern, while slightly verbose, works for recursive list building across scopes.
3765
list(APPEND all_dependencies ${input_target})
66+
set(all_dependencies ${all_dependencies} PARENT_SCOPE) # Propagate change up
3867

68+
# Get dependencies from LINK_LIBRARIES (Private and Public linkage)
3969
get_target_property(link_libraries ${input_target} LINK_LIBRARIES)
4070
foreach(dependency IN LISTS link_libraries)
71+
# Only recurse on actual targets
4172
if(TARGET ${dependency})
42-
get_dependencies(${dependency})
73+
#message("DEBUG: Recursing into LINK_LIBRARIES dependency: ${dependency}")
74+
get_dependencies(${dependency}) # Recursive call
4375
endif()
4476
endforeach()
4577

46-
get_target_property(link_libraries ${input_target} INTERFACE_LINK_LIBRARIES)
47-
foreach(dependency IN LISTS link_libraries)
78+
# Get dependencies from INTERFACE_LINK_LIBRARIES (Interface and Public linkage)
79+
get_target_property(interface_link_libraries ${input_target} INTERFACE_LINK_LIBRARIES)
80+
foreach(dependency IN LISTS interface_link_libraries)
81+
# Only recurse on actual targets
4882
if(TARGET ${dependency})
49-
get_dependencies(${dependency})
83+
get_dependencies(${dependency}) # Recursive call
5084
endif()
5185
endforeach()
5286

53-
set(all_dependencies ${all_dependencies} PARENT_SCOPE)
54-
endfunction()
87+
# The final 'all_dependencies' list is available in the parent scope
88+
# after the initial call to get_dependencies completes.
89+
90+
endfunction() # End of get_dependencies helper function
91+
# --- End of inner helper function ---
92+
93+
# Initialize the list that the recursive function will populate.
94+
# This list will exist in the scope of the bundle_libraries function.
95+
set(all_dependencies "")
96+
97+
# 2. Get dependencies for all input targets provided in ARGN
98+
# ARGN contains all arguments *after* the named parameters (output_target, library_type)
99+
if(NOT ARGN)
100+
message(FATAL_ERROR "bundle_libraries: No input targets specified for '${output_target}'.")
101+
return()
102+
endif()
55103

56104
foreach(input_target IN LISTS ARGN)
57-
get_dependencies(${input_target})
105+
if(TARGET ${input_target})
106+
#message("DEBUG: Starting dependency analysis for input target: ${input_target}")
107+
get_dependencies(${input_target})
108+
else()
109+
message(WARNING "bundle_libraries: Input target '${input_target}' is not a valid target. Skipping.")
110+
endif()
58111
endforeach()
59112

113+
#message("DEBUG: Collected dependencies: ${all_dependencies}")
114+
115+
# 3. Collect $<TARGET_OBJECTS:...> from STATIC and OBJECT library dependencies
116+
set(all_objects "")
60117
foreach(dependency IN LISTS all_dependencies)
61118
get_target_property(type ${dependency} TYPE)
119+
# message("DEBUG: Checking dependency ${dependency} with type ${type}")
120+
121+
# We only want object files from static or object libraries.
122+
# This correctly excludes shared libraries, modules, executables, interfaces, etc.
62123
if(${type} STREQUAL "STATIC_LIBRARY")
63124
list(APPEND all_objects $<TARGET_OBJECTS:${dependency}>)
64125
elseif(${type} STREQUAL "OBJECT_LIBRARY")
65126
list(APPEND all_objects $<TARGET_OBJECTS:${dependency}>)
66127
endif()
67128
endforeach()
68129

69-
add_library(${output_target} SHARED ${all_objects})
130+
# message("DEBUG: Collected objects: ${all_objects}")
131+
132+
# Check if any object files were found
133+
if(NOT all_objects)
134+
message(WARNING "bundle_libraries: No object files found from the dependencies of ${ARGN}. Creating empty library '${output_target}' as ${_target_type}.")
135+
endif()
136+
137+
# 4. Create the output library using the validated type and collected objects
138+
# If all_objects is empty, add_library will still create an empty library of the specified type.
139+
add_library(${output_target} ${_target_type} ${all_objects})
70140

141+
# 5. Add dependencies to ensure input targets are built before the bundled library.
142+
# This handles the build order correctly.
71143
add_dependencies(${output_target} ${ARGN})
72144

73145
endfunction()

src/dawn/native/CMakeLists.txt

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -920,22 +920,39 @@ if (DAWN_BUILD_MONOLITHIC_LIBRARY)
920920
)
921921
# Bundle all objects of dawn_native, it's public dependencies and private dependencies.
922922
include(BundleLibraries)
923-
bundle_libraries(webgpu_dawn dawn::dawn_native_objects)
923+
if(BUILD_SHARED_LIBS)
924+
bundle_libraries(webgpu_dawn SHARED dawn::dawn_native_objects)
925+
else()
926+
bundle_libraries(webgpu_dawn STATIC dawn::dawn_native_objects)
927+
endif()
928+
924929
add_library(dawn::webgpu_dawn ALIAS webgpu_dawn)
925930
# Compile backend specific sources along with webgpu_dawn_native_proc sources for export macros to get applied.
926931
target_sources(webgpu_dawn
927932
PRIVATE
928933
${WEBGPU_DAWN_NATIVE_PROC_GEN_SOURCES}
929934
${dawn_component_srcs}
930935
)
931-
target_compile_definitions(webgpu_dawn
932-
PRIVATE
933-
"WGPU_IMPLEMENTATION"
934-
"DAWN_NATIVE_IMPLEMENTATION"
935-
PUBLIC
936-
"WGPU_SHARED_LIBRARY"
937-
"DAWN_NATIVE_SHARED_LIBRARY"
938-
)
936+
if(BUILD_SHARED_LIBS)
937+
target_compile_definitions(webgpu_dawn
938+
PRIVATE
939+
"WGPU_IMPLEMENTATION"
940+
"DAWN_NATIVE_IMPLEMENTATION"
941+
PUBLIC
942+
"WGPU_SHARED_LIBRARY"
943+
"DAWN_NATIVE_SHARED_LIBRARY"
944+
)
945+
946+
else()
947+
target_compile_definitions(webgpu_dawn
948+
PRIVATE
949+
"WGPU_IMPLEMENTATION"
950+
"DAWN_NATIVE_IMPLEMENTATION"
951+
PUBLIC
952+
"WGPU_STATIC_LIBRARY" # Here it's simply important that we do not define WGPU_SHARED_LIBRARY, as this will set dllimport / export attributes on windows.
953+
"DAWN_NATIVE_STATIC_LIBRARY"
954+
)
955+
endif()
939956
# Apart from dawn_public_config, everything else goes inside PRIVATE, otherwise install rules will complain that they were not exported.
940957
target_link_libraries(webgpu_dawn
941958
PUBLIC

0 commit comments

Comments
 (0)