C++静态连接与符号修改
原因
- 在做API(或者叫SDk开发包)时,客户要求跨平台即支持windows;故引入了boost库
- 在引入boost库后,客户开发环境就依赖boost库;有些开发者觉得依赖boost环境麻烦;
- 引入boost库可能与客户已经使用的boost库版本不同;
解决方法
- 针对客户不需要依赖boost库环境,将boost库进行静态连接,并对外提供的头文件不包含boost相关头文件的引用;
- 针对API与客户程序使用boost版本不同情况,linux下修改boost符号;
静态连接
- 编译生成boost库的.a文件,在编译API时使用该静态连接库替换动态链接库;
- 对于APi暴露出的头文件进行封装,即对外的接口(.h文件中)或者类型定义使用非boost类型,将boost相关的操作全部放在cpp文件中即可;
- 如:需要更加深层的操作,可对编译的so使用非导出方式(linux gcc默认符号是导出方式);cxxflags="-fvisibility=hidden",对.h中需要导出的符号使用导出符;
#define EXPORT __attribute__((visibility("default"))
修改符号
- 将boost库编译并链接;
- 查询所有的boost的.o文件,并将所有的.o文件打包成如:ar crv xxx.a ./*.o
- 将boost库的所有.o文件的global相关的boost符号过滤,并生成文件newsymbols内容为:boostxxx boostxxxA_
- 符号替换
objcopy --redefine-syms newsymbols
- 使用同样的方法,在编译API的.so时,先编译出.o以及链接成so(需记住此时的链接命令)
- 删除该so,使用同样的符号修改方法,将上述.o文件中boost符号修改成 boostxxxxA;
- 将修改后的.o文件,使用链接命令链接成.so,如此即可完成修改。