如何阻止wasi-sdk clang++为每个导出函数插入__wasm_call_ctors调用?
如何阻止clang++为WASM导出函数插入静态对象构造函数调用?
问题场景
使用wasi-sdk 17/20版本的clang构建C WASM应用,在自定义嵌入式运行时通过WAMR执行代码。核心约束:
- 采用WAMR内置libc,弃用wasi-sdk自带libc
- 应用无
main()函数,仅导出若干供运行时按需调用的函数
当前遇到的问题:clang++会为每个导出函数自动生成一层包装函数,每次调用导出函数时都会执行__wasm_call_ctors(静态全局对象的构造函数),导致重复初始化。
示例代码
struct Bar { Bar() {} }; Bar bar; extern "C" void foo() {}
构建命令
/opt/wasi-sdk/bin/clang++ -Wl,--no-entry -Wl,--allow-undefined -Wl,--export=foo -nostdlib -lc++ -lc++abi test.cpp
生成的WASM问题代码(导出部分)
(func $foo (type 0) return) (func $foo.command_export (type 0) call $__wasm_call_ctors <<<< 重复执行的构造函数调用 call $foo) (export "foo" (func $foo.command_export)))
注:若不使用
-nostdlib -lc++ -lc++abi参数,导出结果符合预期(直接导出$foo),但无法满足替换libc的需求。
解决方案
在构建命令中添加链接器参数--no-wasmctor-func,强制禁用链接器为导出函数自动生成构造函数调用包装的行为。
修改后的构建命令
/opt/wasi-sdk/bin/clang++ -Wl,--no-entry -Wl,--allow-undefined -Wl,--export=foo -Wl,--no-wasmctor-func -nostdlib -lc++ -lc++abi test.cpp
补充说明
- 添加该参数后,导出函数会直接映射到原始的
$foo函数,不再包含__wasm_call_ctors调用 - 若需要执行静态对象构造,可在运行时主动调用
__wasm_call_ctors函数(需确保仅调用一次) - 未使用
-nostdlib时,wasi-sdk的libc会统一处理初始化逻辑,因此链接器不会生成这类包装;但启用-nostdlib后,链接器默认认为每个入口点都需要初始化,因此必须显式禁用该行为
内容的提问来源于stack exchange,提问作者jviita
相关产品推荐
相关产品推荐

