我们最近被要求提供其中一个库的Linux版本,以前我们是在Linux下开发的,并且是针对Windows发行的,在Windows上通常更容易部署库。我们遇到的问题是将导出的符号剥离为仅暴露界面中的符号。想要这样做的三个很好的理由
然后举一个简单的例子:
test.cpp
#include <cmath>
float private_function(float f)
{
return std::abs(f);
}
extern "C" float public_function(float f)
{
return private_function(f);
}
与(g ++ 4.3.2,ld 2.18.93.20081009编译)
g++ -shared -o libtest.so test.cpp -s
并使用以下符号检查符号>>
nm -DC libtest.so
给予
w _Jv_RegisterClasses 0000047c T private_function(float) 000004ba W std::abs(float) 0000200c A __bss_start w __cxa_finalize w __gmon_start__ 0000200c A _edata 00002014 A _end 00000508 T _fini 00000358 T _init 0000049b T public_function
显然不足。因此,接下来我们将公共函数重新声明为
extern "C" float __attribute__ ((visibility ("default"))) public_function(float f)
并编译为
g++ -shared -o libtest.so test.cpp -s -fvisibility=hidden
给出
。另外,当我们开始使用STL容器时:w _Jv_RegisterClasses 0000047a W std::abs(float) 0000200c A __bss_start w __cxa_finalize w __gmon_start__ 0000200c A _edata 00002014 A _end 000004c8 T _fini 00000320 T _init 0000045b T public_function
这很好,除了std :: abs被暴露。更有问题的是,当我们开始链接控件之外的其他(静态)库时,我们从这些库中使用的所有符号都将导出
#include <vector> struct private_struct { float f; }; void other_private_function() { std::vector<private_struct> v; }
我们最终从C ++库中获得了许多其他导出结果
00000b30 W __gnu_cxx::new_allocator<private_struct>::deallocate(private_struct*, unsigned int) 00000abe W __gnu_cxx::new_allocator<private_struct>::new_allocator() 00000a90 W __gnu_cxx::new_allocator<private_struct>::~new_allocator() 00000ac4 W std::allocator<private_struct>::allocator() 00000a96 W std::allocator<private_struct>::~allocator() 00000ad8 W std::_Vector_base<private_struct, std::allocator<private_struct> >::_Vector_impl::_Vector_impl() 00000aaa W std::_Vector_base<private_struct, std::allocator<private_struct> >::_Vector_impl::~_Vector_impl() 00000b44 W std::_Vector_base<private_struct, std::allocator<private_struct> >::_M_deallocate(private_struct*, unsigned int) 00000a68 W std::_Vector_base<private_struct, std::allocator<private_struct> >::_M_get_Tp_allocator() 00000b08 W std::_Vector_base<private_struct, std::allocator<private_struct> >::_Vector_base() 00000b6e W std::_Vector_base<private_struct, std::allocator<private_struct> >::~_Vector_base() 00000b1c W std::vector<private_struct, std::allocator<private_struct> >::vector() 00000bb2 W std::vector<private_struct, std::allocator<private_struct> >::~vector()
NB:启用优化后,您需要确保实际使用了向量,因此编译器不会将未使用的符号进行优化。
[我相信我的同事已经设法构建了一个临时解决方案,该方案涉及版本文件并修改了似乎有用的STL标头(!),但我想问一下:
是否有一种干净的方法可以从linux共享库中剥离所有不必要的符号(即那些不是公开库功能的一部分的IE符号?
)我已经尝试了很多使用g ++和ld的选项很少有成功,所以我宁愿选择已知有效的答案,而不是相信的答案。特别是:
我们的导出接口是C。
我知道关于SO的其他类似问题:
但在答案方面收效甚微。
我们最近被要求提供其中一个库的Linux版本,以前我们是在Linux下开发的,并且是针对Windows发行的,在Windows上通常更容易部署库。 ...