feat: Make C++ exceptions and RTTI configurable (#9913)

Introduced the FILAMENT_ENABLE_EXCEPTIONS (default ON) and
FILAMENT_ENABLE_RTTI (default OFF) CMake options to control these
features globally. This replaces previous hardcoded, platform-specific
overrides.

Added a -E flag to build.sh to easily disable exceptions during
build configuration.

Removed hardcoded -fno-exceptions and -fno-rtti from
android/build.gradle to allow CMake to control these flags, but kept
-fno-rtti enabled by default for the Java/Android build as requested.

Documented in CMakeLists.txt and BUILDING.md that the JNI library
(Android/Java build) requires exceptions to be enabled.

Enabled RTTI specifically for the assimp target in
third_party/libassimp/tnt/CMakeLists.txt to fix compilation errors
caused by its use of dynamic_cast.

SIZEGUARD_BYPASS
This commit is contained in:
Mathias Agopian
2026-04-23 09:52:26 -07:00
committed by GitHub
parent fd2684513e
commit f9e56a11d1
5 changed files with 46 additions and 23 deletions

View File

@@ -79,6 +79,10 @@ The following CMake options are boolean options specific to Filament:
- `FILAMENT_INSTALL_BACKEND_TEST`: Install the backend test library so it can be consumed on iOS
- `FILAMENT_USE_EXTERNAL_GLES3`: Experimental: Compile Filament against OpenGL ES 3
- `FILAMENT_SKIP_SAMPLES`: Don't build sample apps
- `FILAMENT_ENABLE_EXCEPTIONS`: Enable C++ exceptions (default: ON, OFF for iOS). Required for JNI bindings.
- `FILAMENT_ENABLE_RTTI`: Enable C++ RTTI (default: OFF).
Note: If you intend to use the JNI library (Android/Java build), you need to have `FILAMENT_ENABLE_EXCEPTIONS` enabled. If you are using Filament on Android as a pure native library and want to save space, you can disable it (e.g., using `./build.sh -E`).
To turn an option on or off:

View File

@@ -33,6 +33,20 @@ project(TNT C CXX ${EXTRA_LANGS})
# ==================================================================================================
option(FILAMENT_USE_EXTERNAL_GLES3 "Experimental: Compile Filament against OpenGL ES 3" OFF)
# Note: If you intend to use the JNI library (Android/Java build), you need to have
# exceptions enabled (the default). If you are using Filament on Android as a pure
# native library and want to save space, you can disable them.
# We disable exceptions on iOS by default. This fixes an availability error we see when using
# std::visit and std::get, which are not supported on iOS 11.0 when exceptions are enabled.
if (IOS)
set(FILAMENT_ENABLE_EXCEPTIONS_DEFAULT OFF)
else()
set(FILAMENT_ENABLE_EXCEPTIONS_DEFAULT ON)
endif()
option(FILAMENT_ENABLE_EXCEPTIONS "Enable C++ exceptions" ${FILAMENT_ENABLE_EXCEPTIONS_DEFAULT})
option(FILAMENT_ENABLE_RTTI "Enable C++ RTTI" OFF)
option(FILAMENT_ENABLE_LTO "Enable link-time optimizations if supported by the compiler" OFF)
option(FILAMENT_SKIP_SAMPLES "Don't build samples" OFF)
@@ -107,6 +121,15 @@ set(FILAMENT_OSMESA_PATH "" CACHE STRING
# Enable exceptions by default in spirv-cross.
set(SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS OFF)
if (NOT FILAMENT_ENABLE_EXCEPTIONS)
add_compile_options(-fno-exceptions)
set(SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS ON)
endif()
if (NOT FILAMENT_ENABLE_RTTI)
add_compile_options(-fno-rtti)
endif()
# ==================================================================================================
# CMake policies
# ==================================================================================================
@@ -416,8 +439,7 @@ if (ANDROID)
endif()
if (CYGWIN)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions -fno-rtti")
set(SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS ON)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
endif()
if (MSVC)
@@ -451,30 +473,17 @@ if (NOT MSVC)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffunction-sections -fdata-sections")
endif()
# On Android RELEASE builds, we disable exceptions and RTTI to save some space (about 75 KiB
# saved by -fno-exception and 10 KiB saved by -fno-rtti).
if (ANDROID OR IOS OR WEBGL)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-exceptions -fno-rtti")
set(SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS ON)
if (ANDROID OR WEBGL)
# Omitting unwind info prevents the generation of readable stack traces in crash reports on iOS
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-unwind-tables -fno-asynchronous-unwind-tables")
endif()
if (ANDROID OR WEBGL)
# On Android and WebGL RELEASE builds, we omit unwind info to save space.
# (We keep unwind info on iOS to allow readable stack traces in crash reports.)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-unwind-tables -fno-asynchronous-unwind-tables")
endif()
# Turn off exceptions on iOS debug as well. This fixes an availability error we see when using
# std::visit, which is not supported on iOS 11.0 when exceptions are enabled.
if (IOS)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-exceptions")
set(SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS ON)
endif()
# With WebGL, we disable RTTI even for debug builds because we pass emscripten::val back and forth
# With WebGL, we disable RTTI because we pass emscripten::val back and forth
# between C++ and JavaScript in order to efficiently access typed arrays, which are unbound.
# NOTE: This is not documented in emscripten so we should consider a different approach.
if (WEBGL)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-rtti")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
endif()
if (WEBGL_PTHREADS)

View File

@@ -145,7 +145,6 @@ buildscript {
ext.cppFlags = [
"-std=c++17",
"-fno-stack-protector",
"-fno-exceptions",
"-fno-unwind-tables",
"-fno-asynchronous-unwind-tables",
"-fno-rtti",

View File

@@ -44,6 +44,8 @@ function print_help {
echo " Run all unit tests, will trigger a debug build if needed."
echo " -v"
echo " Exclude Vulkan support from the Android build."
echo " -E"
echo " Disable C++ exceptions."
echo " -W"
echo " Include WebGPU support for the target platform. (NOT functional atm)."
echo " -s"
@@ -275,6 +277,7 @@ function build_tools_for_split_build {
-DCMAKE_BUILD_TYPE="${build_type_arg}" \
${WEBGPU_OPTION} \
${architectures} \
${EXCEPTIONS_OPTION} \
../..
${BUILD_COMMAND} ${WEB_HOST_TOOLS}
@@ -318,6 +321,7 @@ function build_desktop_target {
${BACKEND_DEBUG_FLAG_OPTION} \
${STEREOSCOPIC_OPTION} \
${OSMESA_OPTION} \
${EXCEPTIONS_OPTION} \
${architectures} \
../..
ln -sf "out/cmake-${lc_target}/compile_commands.json" \
@@ -378,6 +382,7 @@ function build_webgl_with_target {
-DWEBGL=1 \
${WEBGPU_OPTION} \
${BACKEND_DEBUG_FLAG_OPTION} \
${EXCEPTIONS_OPTION} \
../..
ln -sf "out/cmake-webgl-${lc_target}/compile_commands.json" \
../../compile_commands.json
@@ -457,6 +462,7 @@ function build_android_target {
${BACKEND_DEBUG_FLAG_OPTION} \
${STEREOSCOPIC_OPTION} \
${ENABLE_PERFETTO} \
${EXCEPTIONS_OPTION} \
../..
ln -sf "out/cmake-android-${lc_target}-${arch}/compile_commands.json" \
../../compile_commands.json
@@ -698,6 +704,7 @@ function build_ios_target {
${MATDBG_OPTION} \
${MATOPT_OPTION} \
${STEREOSCOPIC_OPTION} \
${EXCEPTIONS_OPTION} \
../..
ln -sf "out/cmake-ios-${lc_target}-${arch}/compile_commands.json" \
../../compile_commands.json
@@ -858,7 +865,7 @@ function check_debug_release_build {
pushd "$(dirname "$0")" > /dev/null
while getopts ":hacCfgimp:q:uvWslwedtk:bVx:S:X:Py:" opt; do
while getopts ":hacCfgimp:q:uvWslwedtk:bVx:S:X:Py:E" opt; do
case ${opt} in
h)
print_help
@@ -1009,6 +1016,9 @@ while getopts ":hacCfgimp:q:uvWslwedtk:bVx:S:X:Py:" opt; do
P) ENABLE_PERFETTO="-DFILAMENT_ENABLE_PERFETTO=ON"
echo "Enabled perfetto"
;;
E) EXCEPTIONS_OPTION="-DFILAMENT_ENABLE_EXCEPTIONS=OFF"
echo "Disabling exceptions."
;;
x) BACKEND_DEBUG_FLAG_OPTION="-DFILAMENT_BACKEND_DEBUG_FLAG=${OPTARG}"
;;
S) case $(echo "${OPTARG}" | tr '[:upper:]' '[:lower:]') in

View File

@@ -287,6 +287,7 @@ if(NOT MSVC)
endif()
target_compile_options(${TARGET} PRIVATE ${TARGET_FLAGS})
target_compile_options(${TARGET} PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-frtti>)
else()
target_compile_options(${TARGET} PRIVATE /bigobj)
endif()