使用emsdk:3.1.64编译报‘expected top-level entity’,3.1.26正常求助
emsdk 3.1.64编译报错但3.1.26正常的问题排查
问题现象
- 使用emsdk:3.1.64编译代码时出现报错,但emsdk:3.1.26版本可正常编译。
执行命令及报错情况
第一次执行命令
emcc C:\test\hello_world.cpp -O3 -r -o C:\test\libar.bc && emcc C:\test\libar.bc -O3 -o C:\testtest_wasm.js
报错信息:
C:\test\libar.bc:1:2: error: expected top-level entity 1 | <U+0000>asm<U+0001><U+0000><U+0000><U+0000><U+0001>0<U+0008>`<U+0002><U+007F><U+007F><U+0001><U+007F>`<U+0003>... | ^ 1 error generated. emcc: error: 'C:/Users/user/Documents/habr/emsdk-main/upstream/bin\clang.exe -target wasm32-unknown-emscripten -fignore-exceptions -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --sysroot=C:\Users\user\Documents\habr\emsdk-main\upstream\emscripten\cache\sysroot -DEMSCRIPTEN -Werror=implicit-function-declaration -Xclang -iwithsysroot/include\fakesdl -Xclang -iwithsysroot/include\compat -O3 C:\test\libar.bc -c -o C:\Users\user\AppData\Local\Temp\emscripten_temp_tvmixm4o\libar_0.o' failed (returned 1)
第二次执行(移除-r和-O3)
命令:
emcc C:\test\hello_world.cpp -o C:\test\libar.bc && emcc C:\test\libar.bc -o C:\testtest_wasm.js
出现警告:
emcc: warning: object file output extension (.bc) used for non-object output. If you meant to build an object file please use `-c, `-r`, or `-shared` [-Wemcc]
报错信息:
C:\test\libar.bc:1:1: error: expected top-level entity 1 | // include: shell.js | ^ 1 error generated. emcc: error: 'C:/Users/user/Documents/habr/emsdk-main/upstream/bin\clang.exe -target wasm32-unknown-emscripten -fignore-exceptions -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --sysroot=C:\Users\user\Documents\habr\emsdk-main\upstream\emscripten\cache\sysroot -DEMSCRIPTEN -Werror=implicit-function-declaration -Xclang -iwithsysroot/include\fakesdl -Xclang -iwithsysroot/include\compat C:\test\libar.bc -c -o C:\Users\user\AppData\Local\Temp\emscripten_temp_m43yxogd\libar_0.o' failed (returned 1)
测试代码(C:\test\hello_world.cpp)
#include <iostream> int main() { std::cout << "Hello world"; return 0; }
原因分析
核心问题是新版本Emscripten对输出类型的规则收紧,导致生成的.bc文件并非预期的LLVM字节码:
- 第二次报错显示
.bc文件第一行是// include: shell.js,说明该文件实际是Emscripten默认生成的JS包装脚本,不是LLVM位码文件。 - emsdk 3.1.26版本中,
emcc对.bc后缀的处理更宽松,默认会生成LLVM位码;但3.1.64版本要求必须通过明确参数指定输出类型,仅靠后缀无法触发位码生成逻辑。 - 第一次执行时虽然加了
-r参数,但可能因为新版本的参数兼容性问题,生成的.bc文件损坏,导致后续编译失败。
解决方法
要正确生成LLVM位码文件,需在编译时添加明确的输出类型参数:
- 生成单个目标位码文件:使用
-c参数
emcc C:\test\hello_world.cpp -O3 -c -o C:\test\libar.bc
- 生成可重定位的位码文件(用于后续链接):使用
-r参数
emcc C:\test\hello_world.cpp -O3 -r -o C:\test\libar.bc
之后再用生成的.bc文件编译生成JS/WASM(注意修正路径笔误):
emcc C:\test\libar.bc -O3 -o C:\test\test_wasm.js
内容的提问来源于stack exchange,提问作者Rita
相关产品推荐
相关产品推荐

