I have a project written in C++, and the platform to be deployed in has a limitation of 256KB of binary size.
The toolchain is wasi-sdk-16.0 clang++, we use this compiler to compile the source code into binary in WASM format. In this step we compile the sources with the following CXX_FLAGS.
-fstack-protector-strong -Os -D_FORTIFY_SOURCE=2 -fPIC -Wformat -Wformat-security -Wl,-z,relro,-z,now -Wno-psabi
Then we strip
the binary with
strip -s output_binary.wasm
After steps above, the compiled binary size in this step is 254KB.
Then we use wamrc
in WAMR to compile the WASM binary with AOT runtime, the command is shown below.
wamrc --enable-indirect-mode --disable-llvm-intrinsics -o output.aot output.wasm
the output binary size become 428KB, much bigger than the limitation (256KB).
After google'd, I use wasm-opt
to reduce size,
wasm-opt -Oz output.wasm -o output.wasm
The size become 4KB smaller. (almost useless)
I tried to comfirm how much does my code affects the binary size, so I write simple minimum sample code just called the standard c++ library, as the following,
#include <vector>
#include <iostream>
int main() {
std::vector<int> vec = {1,2,3,4,5};
for (auto v: vec) {
std::cout << v << " ";
}
}
The binary size after compiled has alrealy become 205KB.
I also tried to use a binary size profiler (twiggy
) to track the size of each part of the bianry, but the tool failed to open this binary.
So I want to ask
While just including two standard C++ headers makes the binary size reach the size limitation, how can I strip the C++ standard library with the function I really use(I cannot use strip unused function flag because my project is a library provide to others), or is really the c++ standard library affected the binary size?
Is there any other compiler flags, or strip flags, or any other optimization tools can significantly reduce the binary size?
I solve this issue with just replacing iostream and fstream to cstdio. It reduces size from 254KB to 85KB, because there contains too many templates in iostream.
Using iostream |
Count of functions (with readelf -Ws ) |
Size of Binary |
---|---|---|
Yes | 685 | 254KB |
No | 76 | 85KB |
While specifying compiler flags such as -Oz also reduces some size, but the main factor is too many codes were generated from templates. So, do not use C++ stream API (and any other template-heavy general-purpose libraries) when there are binary size limitations. (C libraries are always worth to believe.)