我有一个用C编写的项目,要部署的平台有256 KB二进制大小的限制。
工具链是wasi-sdk-16.0 clang,我们使用此编译器将源代码编译为WASM格式的二进制代码。在此步骤中,我们使用以下CXX_FLAGS编译源代码。
-fstack-protector-strong -Os -D_FORTIFY_SOURCE=2 -fPIC -Wformat -Wformat-security -Wl,-z,relro,-z,now -Wno-psabi
然后我们用strip
二进制
strip -s output_binary.wasm
经过以上步骤,本步骤编译后的二进制文件大小为254 KB。
然后我们在WAMR中使用wamrc
,使用AOT运行时编译WASM二进制文件,命令如下所示。
wamrc --enable-indirect-mode --disable-llvm-intrinsics -o output.aot output.wasm
输出二进制大小变为428 KB,远大于限制(256 KB)。
谷歌搜索后,我使用wasm-opt
来缩小尺寸,
wasm-opt -Oz output.wasm -o output.wasm
大小变小4KB.(几乎无用)
我试着确认我的代码对二进制大小的影响有多大,所以我写了简单的最小样本代码,就叫标准c++库,如下所示,
#include <vector>
#include <iostream>
int main() {
std::vector<int> vec = {1,2,3,4,5};
for (auto v: vec) {
std::cout << v << " ";
}
}
编译后的二进制大小已变为205 KB。
我还尝试使用二进制大小分析器(twiggy
)来跟踪bianry每个部分的大小,但是该工具无法打开此二进制文件。
所以我想问
1.虽然只包含两个标准C头文件会使二进制大小达到大小限制,但我如何才能用我真正使用的函数剥离C标准库(我不能使用剥离未使用的函数标志,因为我的项目是一个提供给其他人的库),或者C++标准库真的会受到二进制大小的影响?
1.是否有其他编译器标志、strip标志或其他优化工具可以显著减少二进制文件的大小?
2条答案
按热度按时间50few1ms1#
有一件事我没有看到你的文章中提到的是wabt的
wasm-strip
。我对它不够熟悉,不知道它是否比简单的strip
命令更有用,但也许它值得一试。你可以在Debian系统上安装apt install wasm-strip
。从我在互联网上看到的一些微基准测试来看,C++ wasm二进制代码有很大的开销。对于一个完全不科学的幻灯片,你可以看this。
如果由于某种原因,您无法使用该语言生成更小的二进制文件,您可以尝试在链接级别进行优化,就像busybox所做的那样。
jdgnovmf2#
| 使用
iostream
|函数计数(使用readelf -Ws
)|二进制文件的大小|| - ------| - ------| - ------|
| 是的|六百八十五|254千字节|
| 没有|七十六|85千字节|
虽然指定编译器标志(如-Oz)也会减少一些大小,但主要因素是从模板生成了太多代码。因此,当存在二进制大小限制时,不要使用C++流API(以及任何其他模板密集的通用库)。(C库总是值得相信的。)