我有一个很大的问题。我有一个公共库,在我的项目中使用。此库密集使用boost.spirit
和boost.fusion
。不幸的是,图书馆约。 700Mb大小。使用了所有boost.spirit
- 重代码,它运行良好。可以采取哪些措施来减少其输出尺寸?是否有一个工具可以帮助确定哪些模板实例化会浪费大部分空间?
起初,我决定将所有精神感知代码移动到cpp文件。其次,我将尝试不同的编译器标志来优化大小。我不知道还能做什么。
更新(详细信息)
我正在使用GNU工具链。巨大的库实际上是一个静态库。使用这个700Mb库的可执行文件大小为200Mb。至少有一半的代码是* .h文件。一些boost.spirit
语法(非常模板重的东西)也位于* .h文件中。
干杯!
答案 0 :(得分:5)
将精神意识代码移动到.cpp
文件是一个很好的第一步,虽然你提到在头文件中有精神语法,但它可能是不完整的。
确保从未将任何语法/规则导出到库外。如果您有典型的include
/ src
目录,则在src
目录中移动这些文件(即使标题)。
将所有这些符号标记为库的内部符号。它们不应该从图书馆外面访问。根据您的编译器有特定的编译指示/属性,在gcc上查找visibility attribute:__attribute__ ((visibility ("internal")))
。这有助于编译器相应地优化它们,特别是编译器可以发出函数的代码,即使它在给定的调用站点上内联它,以防万一这个函数地址被采用。但是,通过内部可见性,因为它知道代码不会离开对象,所以它可能会忽略该功能。
我似乎记得有一个标志来融合相同的功能体但似乎无法再找到......
答案 1 :(得分:4)
--ffunction-sections
会将每个函数放在自己的细分中。它本身没有用,但链接器可以用--gc-sections
删除未使用的部分。现在没有--function-segments
这只有在整个源文件未被使用时才会起作用,即具有疯狂的粒度。
显然你需要Matthieu提到的visibility属性,否则库中的所有函数都会因为可见而被“使用”。
答案 2 :(得分:2)
一些建议:
在可能的情况下,尝试重复使用相同的模板实例化(作为一个简单且设计的示例,std::vector<int>
和std::vector<float>
具有相同的内部结构,并且可以只处理它们元素数据作为不透明的4字节blob,因此可以委托给另一个,并且只是作为一个东西包装器,它只是转换回正确的类型,因此向量的内部只需要实例化为一种类型,而不是不止两个。
尝试不同的编译器。一些编译器重用相同的模板实例,它不会影响程序语义,而其他编译实例更保守。
密切关注从库中导出的内容。链接器可以删除未导出且未在内部引用的符号。 (当然,如果你正在构建一个静态库,那么在它被链接到可执行文件之前不会启动。为了减小库本身的大小,你可以尝试将它变成一个动态库)
但最终,听起来你可能只需要使用模板量较少的库。 (或者写一个比你现在更简单的解析器)
答案 3 :(得分:2)
此处已讨论过:why my C++ output executable is so big?
基本上,查找调试符号,订单链接依赖关系,优化等等......