Files
tinyusdz/web/CMakeLists.txt
Syoyo Fujita c66a71428e Add TINYUSDZ_WASM_COROUTINE cmake option for C++20 coroutine async loading
- Add CMake option TINYUSDZ_WASM_COROUTINE (default OFF) to enable/disable
  C++20 coroutine-based async loading
- Add TINYUSDZ_USE_COROUTINE compile definition for conditional compilation
- Wrap coroutine helper functions (yieldToEventLoop, reportAsyncPhaseStart)
  with #if defined(TINYUSDZ_USE_COROUTINE)
- Wrap loadFromBinaryAsync method with #if defined(TINYUSDZ_USE_COROUTINE)
- Wrap EMSCRIPTEN_BINDINGS registration with same guard

To enable coroutine support:
  cmake .. -DTINYUSDZ_WASM_COROUTINE=ON

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 00:40:52 +09:00

220 lines
7.3 KiB
CMake

# Assume this project is invoked by emcmake.
cmake_minimum_required(VERSION 3.16)
# cmake modules
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../cmake)
#list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../cmake/sanitizers)
#find_package(Sanitizers) # Address sanitizer (-DSANITIZE_ADDRESS=ON)
option(TINYUSDZ_WASM64 "Use wasm64(memory64). Available only for Chrome and Firefox as of 2025 Jul" OFF)
option(TINYUSDZ_WASM_DEBUG "Enable WASM debug mode with source maps and assertions" OFF)
option(TINYUSDZ_WASM_SIMD "Enable WebAssembly SIMD (128-bit, widely supported since 2021)" ON)
option(TINYUSDZ_WASM_RELAXED_SIMD "Enable WebAssembly Relaxed SIMD (requires recent browsers)" OFF)
option(TINYUSDZ_WASM_COROUTINE "Enable C++20 coroutine-based async loading (allows browser repaint during loading)" OFF)
if (TINYUSDZ_WASM64)
set(BUILD_TARGET "tinyusdz_64")
else()
set(BUILD_TARGET "tinyusdz")
endif()
project(${BUILD_TARGET} CXX C)
# Make C++20 default to use C++20 coroutine.
# Emscripten 4.0 or above supports(C++20)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# SIMD configuration
# WebAssembly SIMD is widely supported (Chrome 91+, Firefox 89+, Safari 16.4+, Edge 91+)
# See: https://caniuse.com/wasm-simd
set(TINYUSDZ_SIMD_FLAGS "")
if (TINYUSDZ_WASM_SIMD)
message(STATUS "TinyUSDZ WASM: SIMD enabled (-msimd128)")
set(TINYUSDZ_SIMD_FLAGS "-msimd128")
if (TINYUSDZ_WASM_RELAXED_SIMD)
message(STATUS "TinyUSDZ WASM: Relaxed SIMD enabled (-mrelaxed-simd)")
set(TINYUSDZ_SIMD_FLAGS "${TINYUSDZ_SIMD_FLAGS} -mrelaxed-simd")
endif()
endif()
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
if (TINYUSDZ_WASM_DEBUG)
# Enhanced debug mode with source maps
if (TINYUSDZ_WASM64)
set(CMAKE_CXX_FLAGS_DEBUG "-g -gsource-map -sMEMORY64 ${TINYUSDZ_SIMD_FLAGS}")
set(CMAKE_C_FLAGS_DEBUG "-g -gsource-map -sMEMORY64 ${TINYUSDZ_SIMD_FLAGS}")
else()
set(CMAKE_CXX_FLAGS_DEBUG "-g -gsource-map ${TINYUSDZ_SIMD_FLAGS}")
set(CMAKE_C_FLAGS_DEBUG "-g -gsource-map ${TINYUSDZ_SIMD_FLAGS}")
endif()
else()
# Standard debug mode
if (TINYUSDZ_WASM64)
set(CMAKE_CXX_FLAGS_DEBUG "-g4 -sMEMORY64 ${TINYUSDZ_SIMD_FLAGS}")
set(CMAKE_C_FLAGS_DEBUG "-g4 -sMEMORY64 ${TINYUSDZ_SIMD_FLAGS}")
else()
set(CMAKE_CXX_FLAGS_DEBUG "-g4 ${TINYUSDZ_SIMD_FLAGS}")
set(CMAKE_C_FLAGS_DEBUG "-g4 ${TINYUSDZ_SIMD_FLAGS}")
endif()
endif()
elseif (CMAKE_BUILD_TYPE STREQUAL "MinSizeRel")
# Use Oz to reduce size further than Os
if (TINYUSDZ_WASM64)
set(CMAKE_CXX_FLAGS_MINSIZEREL "-O3 -Oz -DNDEBUG -sMEMORY64 ${TINYUSDZ_SIMD_FLAGS}")
set(CMAKE_C_FLAGS_MINSIZEREL "-O3 -Oz -DNDEBUG -sMEMORY64 ${TINYUSDZ_SIMD_FLAGS}")
else()
set(CMAKE_CXX_FLAGS_MINSIZEREL "-O3 -Oz -DNDEBUG ${TINYUSDZ_SIMD_FLAGS}")
set(CMAKE_C_FLAGS_MINSIZEREL "-O3 -Oz -DNDEBUG ${TINYUSDZ_SIMD_FLAGS}")
endif()
else()
# Release mode (default)
if (TINYUSDZ_WASM64)
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -sMEMORY64 ${TINYUSDZ_SIMD_FLAGS}")
set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG -sMEMORY64 ${TINYUSDZ_SIMD_FLAGS}")
else()
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG ${TINYUSDZ_SIMD_FLAGS}")
set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG ${TINYUSDZ_SIMD_FLAGS}")
endif()
endif()
if (NOT EMSCRIPTEN)
message(FATAL "Must be compiled with emscripten")
endif()
option(TINYUSDZ_WASM_DEMODEV "Demo developer mode(install WASM modules to demo/node_modules/tinyusdz." OFF)
if (TINYUSDZ_WASM_DEMODEV)
message(STATUS "demodev build")
endif()
# [tinyusdz]
add_subdirectory(../ tinyusdz)
list(
APPEND
SOURCES
binding.cc
)
add_executable(${BUILD_TARGET} ${SOURCES})
add_sanitizers(${BUILD_TARGET})
target_compile_options(${BUILD_TARGET} PRIVATE ${EXT_COMPILE_OPTIONS})
if (TINYUSDZ_WASM64)
set_target_properties(${BUILD_TARGET} PROPERTIES COMPILE_FLAGS "-sMEMORY64=1")
target_compile_definitions(${BUILD_TARGET} PRIVATE TINYUSDZ_WASM_MEMORY64=1)
endif()
# Pass through compile definitions for feature flags
if (TINYUSDZ_WITH_EXR)
target_compile_definitions(${BUILD_TARGET} PRIVATE TINYUSDZ_WITH_EXR=1)
endif()
# C++20 coroutine support for async loading
if (TINYUSDZ_WASM_COROUTINE)
message(STATUS "TinyUSDZ WASM: C++20 coroutine async loading enabled")
target_compile_definitions(${BUILD_TARGET} PRIVATE TINYUSDZ_USE_COROUTINE=1)
endif()
# tinyusdz dir
target_include_directories(${BUILD_TARGET}
PRIVATE "${PROJECT_SOURCE_DIR}/../src/")
target_link_libraries(${BUILD_TARGET} PRIVATE tinyusdz::tinyusdz_static
${EXT_LIBRARIES} PUBLIC ${CMAKE_DL_LIBS})
source_group("Source Files" FILES ${SOURCES})
if (EMSCRIPTEN)
if (TINYUSDZ_WASM_DEMODEV)
set(OUTPUT_WASM_DIR ${PROJECT_SOURCE_DIR}/demo/node_modules/tinyusdz/)
else()
set(OUTPUT_WASM_DIR ${PROJECT_SOURCE_DIR}/js/src/tinyusdz/)
endif()
set_target_properties(
${BUILD_TARGET}
PROPERTIES OUTPUT_NAME ${BUILD_TARGET}
SUFFIX ".js"
RUNTIME_OUTPUT_DIRECTORY ${OUTPUT_WASM_DIR})
#set(CMAKE_EXECUTABLE_SUFFIX ".html")
endif()
# for debugging
# --memoryprofiler
# --source-map-base http://localhost:8021/
# flags = try to lower heap memory use
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
if (TINYUSDZ_WASM_DEBUG)
# Enhanced debug mode with source maps, stack traces, and runtime checks
set(TINYUSDZ_EMCC_LINK_FLAGS "-g -gsource-map -sENVIRONMENT='web,worker,node' \
-sMALLOC=emmalloc \
-sSTACK_SIZE=1024000 \
-sALLOW_MEMORY_GROWTH=1 \
-sFILESYSTEM=0 \
-sSAFE_HEAP=1 \
-sSTACK_OVERFLOW_CHECK=2 \
-sASSERTIONS=2 \
-sWASM_BIGINT=1 \
-sMODULARIZE=1 -sEXPORT_ES6 \
-sINVOKE_RUN=0 --bind \
-sDISABLE_EXCEPTION_CATCHING=0 \
-sNO_DISABLE_EXCEPTION_CATCHING \
--source-map-base http://localhost:5173/ ")
else()
# Standard debug mode
set(TINYUSDZ_EMCC_LINK_FLAGS "-g4 -sENVIRONMENT='web,worker,node' \
-sMALLOC=emmalloc \
-sSTACK_SIZE=1024000 \
-sALLOW_MEMORY_GROWTH=1 \
-sFILESYSTEM=0 \
-sSAFE_HEAP=1 \
-sWASM_BIGINT=1 \
-sMODULARIZE=1 -sEXPORT_ES6 \
-sINVOKE_RUN=0 --bind \
-sDISABLE_EXCEPTION_CATCHING=0 \
-sNO_DISABLE_EXCEPTION_CATCHING \
--source-map-base http://localhost:5173/ ")
endif()
else()
set(TINYUSDZ_EMCC_LINK_FLAGS "-Oz -sENVIRONMENT='web,worker,node' \
-sMALLOC=emmalloc \
-sSTACK_SIZE=512000 \
-sALLOW_MEMORY_GROWTH=1 \
-sFILESYSTEM=0 \
-sSAFE_HEAP=0 \
-sWASM_BIGINT=1 \
-sMODULARIZE=1 -sEXPORT_ES6 \
-sINVOKE_RUN=0 --bind ")
endif()
if (TINYUSDZ_WASM64)
# assertion=1 cause runtime error(Cannot mix BigInt and ... in assert()), so use 2
string(APPEND TINYUSDZ_EMCC_LINK_FLAGS " -sASSERTIONS=2 -sMEMORY64 -sMAXIMUM_MEMORY=8GB")
else()
string(APPEND TINYUSDZ_EMCC_LINK_FLAGS " -sASSERTIONS=1 ")
endif()
# Export HEAPU8 for zero-copy streaming transfer from JS to WASM
string(APPEND TINYUSDZ_EMCC_LINK_FLAGS " -sEXPORTED_RUNTIME_METHODS=['HEAPU8']")
message(STATUS ${TINYUSDZ_EMCC_LINK_FLAGS})
set_target_properties(${BUILD_TARGET} PROPERTIES LINK_FLAGS "${TINYUSDZ_EMCC_LINK_FLAGS}")
# ENVIRONMENT=web
# SINGLE_FILE=1