Bazel构建Emscripten应用如何启用C++异常支持
问题原因
编译报错cannot use 'throw' with exceptions disabled是C编译阶段触发的错误。你之前添加的-s EXCEPTION_CATCHING_ALLOWED=[..]属于Emscripten链接阶段参数,仅控制链接时的异常捕获逻辑,不会修改编译阶段的异常开关。Emscripten的Bazel工具链默认在编译时关闭C异常支持,编译器检测到源码中的throw关键字就会直接报错,流程不会走到链接阶段,因此该配置无法解决问题。
解决步骤
- 给编译阶段添加异常支持参数
在cc_binary规则的copts配置项中追加-fexceptions,该参数会告知Emscripten使用的Clang编译器启用C++异常语法支持,从根源消除编译阶段的throw语法报错。 - 替换链接阶段的异常配置
将原有linkopts中的-s EXCEPTION_CATCHING_ALLOWED=[..]替换为-s DISABLE_EXCEPTION_CATCHING=0,该参数会在链接阶段全局启用WASM异常捕获逻辑,匹配编译阶段开启的异常能力。
修改后的BUILD.bazel配置参考如下:
load("@rules_cc//cc:defs.bzl", "cc_binary") load("@emsdk//emscripten_toolchain:wasm_rules.bzl", "wasm_cc_binary") cc_binary( name = "index", srcs = ["main.cpp"], copts = [ "-Wno-unused-variable", "-Wno-unused-but-set-variable", "-Wno-unused-function", "-fexceptions", ], data = ["index.html"], linkopts = [ "-s USE_GLFW=3", "-s USE_WEBGPU=1", "-s WASM=1", "-s ALLOW_MEMORY_GROWTH=1", "-s NO_EXIT_RUNTIME=0", "-s ASSERTIONS=1", "-s DISABLE_EXCEPTION_CATCHING=0", ], tags = ["manual"], ) wasm_cc_binary( name = "index-wasm", cc_target = ":index", )
补充说明
- 上述配置适配你当前使用的Bazel 5.2.0、emsdk 3.1.13版本,参数会通过
wasm_cc_binary规则正常透传到编译和链接流程,不需要额外修改WORKSPACE配置。 - 如果仅需要部分源文件支持异常,不需要全局添加
-fexceptions,可以通过Bazel的per-file copts能力单独给对应源文件配置该参数,减小最终WASM包体积。
内容的提问来源于stack exchange,提问作者Vertexwahn
相关产品推荐
相关产品推荐

