我有一个 Arduino Uno R3。我正在使用 C++ 为每个传感器制作逻辑对象。 Arduino 的板载内存非常有限,为 32KB*,平均而言,我编译的对象大约为 6KB*。
我已经在使用所需的尽可能最小的数据类型,以尽量减少内存占用。是否有编译器标志来最小化二进制文件的大小,或者我是否需要使用更短的变量和函数名称、更少的函数等来最小化我的代码库?
此外,任何其他关于最小化二进制大小的提示或建议也将不胜感激。
*它可能不是以 KB 为单位来衡量的(因为我面前没有它),但 1 个对象大约是我总内存大小的 1/5,这引起了我的担忧。
除了
us2012
和其他人在评论中提到的之外,还有很多减少二进制大小的技术,用我自己的一些观点总结一下:
-Os
使 gcc/g++ 优化大小。-ffunction-sections -fdata-sections
将每个函数或数据分成翻译单元内的不同部分。将其与链接器选项 -Wl,--gc-sections
结合使用以消除任何未引用的部分。strip
:-s -R .comment -R .gnu.version
。它可以与 --strip-unneeded
结合使用,删除所有重定位处理不需要的符号。如果您的代码不包含 c++-异常处理,您可以节省大量空间(在 Tuxdude 提到的所有优化步骤之后最多可节省 30k 空间)。 因此您必须提供以下标志:
-fno-exceptions
但是甚至如果你不使用异常,也可以包含异常处理! 检查以下步骤:
no usage of new, delete
。如果您确实需要它,请用 malloc/free 包装器替换它们。例如搜索“tinynew.cpp”提供纯虚拟调用的功能,例如
extern "C" void __cxa_pure_virtual() { while(1); }
干杯 弗洛
对于需要快速构建和良好错误消息的调试,请使用
-Og -g3 -fsanitize=address -fno-omit-frame-pointer -Wall -Werror
对于您想要最小最快的二进制文件的生产:
-Os -fwrapv -fomit-frame-pointer -ffunction-sections -fdata-sections -fno-asynchronous-unwind-tables
开始吧,这是非常安全的。单独添加 -Wl,--gc-sections -fwhole-program -s -Wl,--build-id=none
_only_ 到最后一个 gcc 步骤,将所有内容链接在一起。 (如果您将其添加到中间步骤中,事情就会崩溃并且无法正常工作。)grep -rnwe throw -e catch
显示您没有使用例外情况时,才添加 -fno-exceptions
grep -rnwe dynamic_cast -e virtual
显示您不使用虚拟方法或动态转换时,添加 -fno-rtti
grep -rnwe errno -e virtual
显示您不使用 errno 时,才添加 -fno-math-errno
grep -rnwe std:
显示您不使用动态标准库方法(类似于宏的 std,如 std::max
可以使用),添加 -nodefaultlibs -lc -lgcc_s
您现在应该拥有可以获得的最小二进制文件免费/最小努力。