Skip to content

Commit 1193fb1

Browse files
authored
Merge pull request #76 from MichealReed/origin/dev
CMake + Dawn + Emscripten Build Refactor
2 parents 6447d85 + 6197322 commit 1193fb1

File tree

12 files changed

+279
-239
lines changed

12 files changed

+279
-239
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
build/*
22
# any build subdirectory in the tree
33
**/build/
4+
**/build_web/
45
examples/hello_gpu/build/*
56
examples/raymarch/build/*
67
docs/html
78
source
89
.DS_Store
910
third_party/lib/*
1011
third_party/local/*
12+
third_party/dawn/*
1113

1214
# formatter files
1315
.cmake-format.py
@@ -20,3 +22,6 @@ build
2022
.cache
2123
compile_commands.json
2224

25+
# editor specific
26+
.vscode/*
27+

CMakeLists.txt

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,13 @@
1+
# This only builds a shared lib, see cmake/example.cmake
2+
# and cmake/gpu.cmake for more details
13
cmake_minimum_required(VERSION 3.28)
24
project(gpu)
35

4-
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/webgpu.cmake")
5-
66
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # export compile_commands.json to use with
77
# LSP
8-
set(CMAKE_CXX_STANDARD 17)
8+
set(CMAKE_CXX_STANDARD 20)
99
set(CMAKE_CXX_STANDARD_REQUIRED ON)
1010

11-
option(USE_LOCAL_LIBS
12-
"Use local libraries instead of fetching from the internet" OFF)
13-
14-
# Ensure the build type is set
15-
if(NOT CMAKE_BUILD_TYPE)
16-
set(CMAKE_BUILD_TYPE
17-
Release
18-
CACHE STRING "Choose the type of build: Debug or Release" FORCE)
19-
endif()
20-
2111
option(FASTBUILD "Option to enable fast builds" OFF)
2212
if(FASTBUILD)
2313
set(CMAKE_BUILD_TYPE None) # Avoid default flags of predefined build types
@@ -30,21 +20,9 @@ if(DEBUG)
3020
set(CMAKE_CXX_FLAGS "-O0 -g")
3121
endif()
3222

33-
if(WIN64)
34-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWEBGPU_BACKEND_DAWN")
35-
endif()
36-
23+
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/dawn.cmake")
3724
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/gpu.cmake")
3825

39-
message(STATUS "CMAKE_CURRENT_SOURCE_DIR: ${CMAKE_CURRENT_SOURCE_DIR}")
40-
message(
41-
STATUS
42-
"Include directories for wgpu: ${CMAKE_CURRENT_SOURCE_DIR}/third_party/headers"
43-
)
44-
4526
add_library(gpud SHARED gpu.hpp)
4627
set_target_properties(gpud PROPERTIES LINKER_LANGUAGE CXX)
47-
target_link_libraries(gpud PRIVATE wgpu)
48-
target_link_libraries(gpud PRIVATE webgpu)
4928
target_link_libraries(gpud PRIVATE gpu)
50-
install(TARGETS gpud)

cmake/dawn.cmake

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# Setup directories
2+
set(FETCHCONTENT_BASE_DIR "${PROJECT_ROOT}/third_party")
3+
set(DAWN_DIR "${FETCHCONTENT_BASE_DIR}/dawn" CACHE INTERNAL "")
4+
set(DAWN_BUILD_DIR "${DAWN_DIR}/build" CACHE INTERNAL "")
5+
6+
if(EMSCRIPTEN)
7+
set(EM_SDK_DIR $ENV{EMSDK} CACHE INTERNAL "")
8+
set(DAWN_BUILD_DIR "${DAWN_DIR}/build_web" CACHE INTERNAL "")
9+
set(DAWN_EMSCRIPTEN_TOOLCHAIN ${EM_SDK_DIR}/upstream/emscripten CACHE INTERNAL "" FORCE)
10+
endif()
11+
12+
# Enable find for no dawn rebuilds with flutter run
13+
set(ENABLE_DAWN_FIND OFF CACHE BOOL "Enable finding Dawn" FORCE)
14+
set(DAWN_BUILD_FOUND OFF CACHE BOOL "Dawn build found" FORCE)
15+
if(ENABLE_DAWN_FIND)
16+
# find_library, windows adds extra folder
17+
if(MSVC)
18+
find_library(WEBGPU_DAWN_DEBUG webgpu_dawn
19+
NAMES webgpu_dawn
20+
HINTS "${DAWN_BUILD_DIR}/src/dawn/native/Debug"
21+
)
22+
find_library(WEBGPU_DAWN_RELEASE webgpu_dawn
23+
NAMES webgpu_dawn
24+
HINTS "${DAWN_BUILD_DIR}/src/dawn/native/Release"
25+
)
26+
set(DAWN_BUILD_FOUND ON)
27+
elseif(NOT EMSCRIPTEN AND NOT MSVC)
28+
find_library(WEBGPU_DAWN_LIB
29+
NAMES webgpu_dawn
30+
PATHS "${DAWN_BUILD_DIR}/src/dawn/native"
31+
REQUIRED
32+
)
33+
set(DAWN_BUILD_FOUND ON)
34+
else()
35+
set(DAWN_BUILD_FOUND ON)
36+
endif()
37+
endif()
38+
39+
# Dawn options for more,
40+
# see https://dawn.googlesource.com/dawn/+/refs/heads/main/CMakeLists.txt
41+
set(DAWN_ALWAYS_ASSERT OFF CACHE INTERNAL "Always assert in Dawn" FORCE)
42+
set(DAWN_BUILD_MONOLITHIC_LIBRARY ON CACHE INTERNAL "Build Dawn monolithically" FORCE)
43+
set(DAWN_BUILD_EXAMPLES OFF CACHE INTERNAL "Build Dawn examples" FORCE)
44+
set(DAWN_BUILD_SAMPLES OFF CACHE INTERNAL "Build Dawn samples" FORCE)
45+
set(DAWN_BUILD_TESTS OFF CACHE INTERNAL "Build Dawn tests" FORCE)
46+
set(DAWN_ENABLE_INSTALL OFF CACHE INTERNAL "Enable Dawn installation" FORCE)
47+
set(DAWN_FETCH_DEPENDENCIES ON CACHE INTERNAL "Fetch Dawn dependencies" FORCE)
48+
set(TINT_BUILD_TESTS OFF CACHE INTERNAL "Build Tint Tests" FORCE)
49+
set(TINT_BUILD_IR_BINARY OFF CACHE INTERNAL "Build Tint IR binary" FORCE)
50+
set(TINT_BUILD_CMD_TOOLS OFF CACHE INTERNAL "Build Tint command line tools" FORCE)
51+
52+
if(NOT DAWN_BUILD_FOUND)
53+
include(FetchContent)
54+
message("webgpu_dawn not found start building")
55+
if(EMSCRIPTEN)
56+
set(EMSCRIPTEN_DIR "${EM_SDK_DIR}/upstream/emscripten" CACHE INTERNAL "" FORCE)
57+
set(DAWN_EMSCRIPTEN_TOOLCHAIN ${EMSCRIPTEN_DIR} CACHE INTERNAL "" FORCE)
58+
endif()
59+
60+
FetchContent_Declare(
61+
dawn
62+
DOWNLOAD_DIR ${DAWN_DIR}
63+
SOURCE_DIR ${DAWN_DIR}
64+
SUBBUILD_DIR ${DAWN_BUILD_DIR}/tmp
65+
BINARY_DIR ${DAWN_BUILD_DIR}
66+
DOWNLOAD_COMMAND
67+
cd ${DAWN_DIR} &&
68+
git init &&
69+
git fetch --depth=1 https://dawn.googlesource.com/dawn &&
70+
git reset --hard FETCH_HEAD
71+
)
72+
73+
# Download the repository and add it as a subdirectory.
74+
FetchContent_MakeAvailable(dawn)
75+
76+
# attempt fix flutter rebuilds
77+
set(CMAKE_INCLUDE_PATH "${CMAKE_INCLUDE_PATH};${DAWN_DIR}/src" CACHE INTERNAL "")
78+
79+
execute_process(
80+
WORKING_DIRECTORY ${DAWN_DIR}
81+
COMMAND ${CMAKE_COMMAND} -S ${DAWN_DIR}
82+
-B ${DAWN_BUILD_DIR}
83+
)
84+
85+
# Build Dawn
86+
execute_process(
87+
COMMAND ${CMAKE_COMMAND} --build ${DAWN_BUILD_DIR}
88+
)
89+
90+
# find_library, windows adds extra folder
91+
if(MSVC)
92+
find_library(WEBGPU_DAWN_DEBUG webgpu_dawn
93+
NAMES webgpu_dawn
94+
HINTS "${DAWN_BUILD_DIR}/src/dawn/native/Debug"
95+
)
96+
find_library(WEBGPU_DAWN_RELEASE webgpu_dawn
97+
NAMES webgpu_dawn
98+
HINTS "${DAWN_BUILD_DIR}/src/dawn/native/Release"
99+
)
100+
set(DAWN_BUILD_FOUND ON)
101+
elseif(NOT EMSCRIPTEN AND NOT MSVC)
102+
find_library(WEBGPU_DAWN_LIB
103+
NAMES webgpu_dawn
104+
PATHS "${DAWN_BUILD_DIR}/src/dawn/native"
105+
REQUIRED
106+
)
107+
set(DAWN_BUILD_FOUND ON)
108+
else()
109+
set(DAWN_BUILD_FOUND ON)
110+
endif()
111+
endif()
112+
113+
if(EMSCRIPTEN)
114+
add_library(webgpu_dawn INTERFACE IMPORTED)
115+
target_include_directories(webgpu_dawn INTERFACE ${DAWN_BUILD_DIR}/gen/src/emdawnwebgpu/include)
116+
target_include_directories(webgpu_dawn INTERFACE ${DAWN_BUILD_DIR}/gen/src/emdawnwebgpu/include/webgpu/webgpu.h)
117+
target_link_libraries(webgpu_dawn INTERFACE ${DAWN_BUILD_DIR}/gen/src/emdawnwebgpu/library_webgpu_enum_tables.js)
118+
target_link_libraries(webgpu_dawn INTERFACE ${DAWN_BUILD_DIR}/gen/src/emdawnwebgpu/library_webgpu_generated_struct_info.js)
119+
target_link_libraries(webgpu_dawn INTERFACE ${DAWN_BUILD_DIR}/gen/src/emdawnwebgpu/library_webgpu_generated_sig_info.js)
120+
target_link_libraries(webgpu_dawn INTERFACE ${DAWN_DIR}/third_party/emdawnwebgpu/library_webgpu.js)
121+
else()
122+
endif()

cmake/example.cmake

Lines changed: 81 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,97 @@
1-
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # export compile_commands.json to use with
2-
# LSP
3-
set(CMAKE_CXX_STANDARD 17)
4-
set(CMAKE_CXX_STANDARD_REQUIRED ON)
1+
# Getting Started with CMAKE
2+
# Each example includes this and sets PROJECT_NAME.
3+
#
4+
# Example usage:
5+
# cd examples/hello_world
6+
# cmake -S . build/ -DCMAKE_BUILD_TYPE=Release
7+
# cmake --build build/ --config Release
8+
# ./build/hello_world (or serve the output .js/.wasm for Emscripten)
9+
# or for emscripten
10+
# emcmake cmake -S . -B ./build_web -DCMAKE_BUILD_TYPE=Release
11+
# cmake --build build_web --config Release
12+
# python3 -m http.server 8080 --d build_web
513

14+
if(NOT MSVC)
15+
set(CMAKE_CXX_STANDARD 17)
16+
else()
17+
set(CMAKE_CXX_STANDARD 20)
18+
endif()
19+
20+
# Locate the project root (two levels up from the current source dir)
621
get_filename_component(PROJECT_ROOT ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
722
get_filename_component(PROJECT_ROOT ${PROJECT_ROOT} DIRECTORY)
823

9-
# Construct potential paths
10-
set(FILEPATH_CURRENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}")
11-
set(FILEPATH_PROJECT_ROOT "${PROJECT_ROOT}/${FILENAME}")
24+
# Include external libraries and helper scripts (dawn and gpu)
25+
include("${PROJECT_ROOT}/cmake/dawn.cmake")
26+
include("${PROJECT_ROOT}/cmake/gpu.cmake")
1227

13-
# Include file finding utility script
14-
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/find_gpu.cmake")
28+
# Create the executable
29+
add_executable(${PROJECT_NAME} run.cpp)
1530

16-
# Check if the file exists in the current directory
17-
find_project_root(${CMAKE_CURRENT_SOURCE_DIR} ${FILENAME}
18-
TARGET_FILE_PATH)
19-
if("${TARGET_FILE_PATH}" STREQUAL "")
20-
find_project_root(${FILEPATH_CURRENT_DIR} ${FILENAME}
21-
TARGET_FILE_PATH)
22-
if("${TARGET_FILE_PATH}" STREQUAL "")
23-
message(
24-
FATAL_ERROR
25-
"File ${FILENAME} not found in either ${CMAKE_CURRENT_SOURCE_DIR} or ${CMAKE_CURRENT_SOURCE_DIR}/../../"
26-
)
27-
endif()
28-
endif()
31+
# Platform-specific linking & build settings
32+
if(EMSCRIPTEN)
33+
# Emscripten-specific configuration
2934

30-
# Ensure the build type is set
31-
if(NOT CMAKE_BUILD_TYPE)
32-
set(CMAKE_BUILD_TYPE
33-
Release
34-
CACHE STRING "Choose the type of build: Debug or Release" FORCE)
35-
endif()
35+
# Define a web output directory (adjust as needed)
36+
set(WEB_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/web_build")
3637

37-
# Define architecture and build type directories or file names
38-
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
39-
set(ARCH "x64")
40-
else()
41-
set(ARCH "x86")
42-
endif()
38+
# If necessary, include the generated WebGPU include dirs first.
39+
include_directories(BEFORE "${DAWN_BUILD_DIR}/gen/src/emdawnwebgpu/include/")
4340

44-
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
45-
set(BUILD_TYPE "Debug")
46-
else()
47-
set(BUILD_TYPE "Release")
48-
endif()
41+
# Create a helper library for WebGPU support.
42+
add_library(webgpu_web "${DAWN_DIR}/third_party/emdawnwebgpu/webgpu.cpp")
43+
target_link_libraries(${PROJECT_NAME} PRIVATE webgpu_web)
44+
45+
# Set Emscripten-specific link flags that enable WASM output and expose certain symbols.
46+
# Needed to use updated version, emdawnwebgpu
47+
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "\
48+
-sUSE_WEBGPU=0 \
49+
-sWASM=1 \
50+
-DDAWN_EMSCRIPTEN_TOOLCHAIN=${EMSCRIPTEN_DIR} \
51+
-sEXPORTED_FUNCTIONS=_main,_malloc,_free,_memcpy \
52+
-sEXPORTED_RUNTIME_METHODS=ccall \
53+
-sUSE_GLFW=3 \
54+
-sALLOW_MEMORY_GROWTH=1 -sSTACK_SIZE=5MB \
55+
-sASYNCIFY \
56+
--js-library=${DAWN_BUILD_DIR}/gen/src/emdawnwebgpu/library_webgpu_enum_tables.js \
57+
--js-library=${DAWN_BUILD_DIR}/gen/src/emdawnwebgpu/library_webgpu_generated_struct_info.js \
58+
--js-library=${DAWN_BUILD_DIR}/gen/src/emdawnwebgpu/library_webgpu_generated_sig_info.js \
59+
--js-library=${DAWN_DIR}/third_party/emdawnwebgpu/library_webgpu.js \
60+
--closure-args=--externs=${EMSCRIPTEN_DIR}/src/closure-externs/webgpu-externs.js \
61+
")
4962

50-
if(NOT TARGET gpu)
51-
message(STATUS "GPU_LIB not found")
52-
include("${TARGET_FILE_PATH}/cmake/webgpu.cmake")
53-
include("${TARGET_FILE_PATH}/cmake/gpu.cmake")
63+
else()
64+
# Non-Emscripten (desktop) linking
65+
if(MSVC)
66+
target_link_libraries(gpu
67+
PRIVATE
68+
$<$<CONFIG:Debug>:${WEBGPU_DAWN_DEBUG}>
69+
$<$<CONFIG:Release>:${WEBGPU_DAWN_RELEASE}>
70+
)
71+
else()
72+
target_link_libraries(gpu PRIVATE webgpu_dawn)
73+
endif()
5474
endif()
5575

56-
add_executable(${PROJECT_NAME} run.cpp)
76+
# Link the gpu/dawn library to the executable.
5777
target_link_libraries(${PROJECT_NAME} PRIVATE gpu)
58-
target_link_libraries(${PROJECT_NAME} PRIVATE wgpu)
59-
target_link_libraries(${PROJECT_NAME} PRIVATE webgpu)
6078

61-
if(WIN32)
62-
# Ensure DLL is copied if on Windows
79+
# Platform-specific post-build actions (e.g. copying DLLs for MSVC)
80+
if(MSVC)
6381
add_custom_command(
64-
TARGET ${PROJECT_NAME}
65-
POST_BUILD
66-
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${DLL_PATH}
67-
$<TARGET_FILE_DIR:${PROJECT_NAME}>)
82+
TARGET ${PROJECT_NAME} POST_BUILD
83+
COMMAND ${CMAKE_COMMAND} -E copy
84+
${DAWN_BUILD_DIR}/$<CONFIG>/webgpu_dawn.dll
85+
$<TARGET_FILE_DIR:${PROJECT_NAME}>
86+
COMMENT "Copying webgpu_dawn.dll to the build directory"
87+
)
88+
endif()
89+
90+
if(EMSCRIPTEN)
91+
92+
# Configure the HTML file by replacing @PROJECT_NAME@ with the actual target name.
93+
configure_file(${PROJECT_ROOT}cmake/templates/index.html.in
94+
${CMAKE_CURRENT_BINARY_DIR}/index.html
95+
@ONLY)
96+
6897
endif()

cmake/find_gpu.cmake

Lines changed: 0 additions & 30 deletions
This file was deleted.

0 commit comments

Comments
 (0)