c++通过编程方式排除不必要的函数来减小库的大小
c++ reduce library size by excluding unnecessary functions programmatically?
通过只选择需要的函数和消除不必要的文件来减小库大小的更简单的方法是什么?有一个脚本来完成这个任务的c++库吗?
您可能应该首先尝试将编译设置为最小化大小。你的问题的答案很大程度上取决于编译器,链接器,什么操作系统,优化标志等…
使用Linux上最新的GCC编译器(g++
),您应该尝试编译和链接,优化大小(-Os
)和链接时间(-flto
)。
所以把
CXX=g++ -flto -Os
在Makefile
开头附近,或者在make clean
后面运行make CXX='g++ -flto -Os'
顺便说一句,Clang/LLVM也知道-flto
(并且像GCC一样使用GOLD)
请注意,共享库(或者可能是Microsoft世界中的DLL)需要包含所有代码(确切地说,因为它在几个进程和程序之间共享)。您可以静态地链接库(然后在构建静态库和将其链接到主程序时都使用g++ -flto -Os
)
通常,共享库比减少它们的空间更有价值。
如果在Linux上,请阅读程序库。
在典型的c++应用程序中,模板代表了很大一部分功能(例如STL vector
, string
等)。这些函数仅在使用时作为代码生成(尽管它们可能作为内联函数生成,这在某些情况下可能导致大量代码)。
链接器将只"挑选"你的应用程序所需的代码(当然包括你所使用的函数调用的函数)。但是,例如Linux上的基本运行时非常大,因为它调用了许多功能,而这些功能又使用了相当多的其他函数—因此基本可执行文件的大小非常大。在通常情况下,添加更多自己的代码不会显著增加大小。
如果大小很重要,那么使用"小型c++库"可能是一个选择——不同的操作系统有不同的此类库。使用-Os
等选项让编译器告诉它"使代码更小"(换句话说,不要内联函数,除非内联函数比调用函数更短,不要展开循环,等等——但是只调用一次内联函数,因为这确实使代码更短)
如果你不想对库进行大量重构(假设你可以访问源代码,但这并不总是一个现实的假设),可以将其链接为静态库,或者作为应用程序的一部分编译:所有编译器都将从中受益。
请注意,与其他编译器相比,Clang有一个特殊的行为,它能够在静态链接时做很多优化。
如果你因为某些原因不得不使用DLL,你可以尝试调整导出符号的可见性(你可以隐藏在客户端代码中不可见的符号,只导出你使用的符号):注意,这可能会在速度和二进制大小方面实现一些优化,但可能是一项乏味的工作(我认为这是一个主要的重构,因为有可能破坏东西)。
如果你正在使用依赖注入容器,你可能会对未使用的依赖项发出警告,这样你就可以轻松地将它们连接出来,而不需要接触源代码(你对容器进行了一些重构,但不是对整个代码库进行重构),除了复合根中的源代码。
1,使用
2,使用版本脚本控制哪些符号被导出
3,使用
CFLAGS="-Os -ffunction-sections -fdata-sections
-fno-unwind-tables -fno-asynchronous-unwind-tables -flto"
LDFLAGS="-Wl,-s -Wl,-Bsymbolic -Wl,--gc-sections"
4、条带库
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 为什么虚函数不能是静态的和全局的?
- 用callgrind追踪不必要的副本
- g++ 说函数不存在,即使包含正确的标头
- 当调用switch语句中的函数时(即使函数不包含循环),似乎是永不结束的循环的问题
- C++Brute Force攻击函数不会返回结果
- 不必要的C++代码最终会出现在我完成的程序中吗?
- 仅包含可移动 std::map 的类的移动构造函数不起作用
- 为什么我的数组双精度函数不起作用?
- std::unordered_map析构函数不释放内存?
- 函数不接受 X 参数,函数使用默认参数
- 总和的不必要行为C++?
- C++:将初始化的对象传递给另一个类的构造函数;需要不必要的构造函数吗?
- 为什么用户定义的函数不按照给定的顺序对相同长度的元素进行排序?
- 函数签名与调用的函数不匹配,常量字符[]和字符*之间的区别?
- 避免对临时、R 值析构函数进行不必要的分配
- 通过使用不同的参数调用每个元素的非默认构造函数来初始化std::vector,而不需要进行不必要的复制
- 函数中不必要的弹出指令,前面有if语句
- c++通过编程方式排除不必要的函数来减小库的大小
- 在向std::unordered_map插入元素时避免不必要的构造函数调用