You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 03:27:32