jww*_*jww 13 c++ linux gcc abi clang
我们最近收到了一份报告,因为GCC 5.1,libstdc ++和Dual ABI.似乎Clang不知道GCC内联命名空间更改,因此它基于一组命名空间或符号生成代码,而GCC使用另一组命名空间或符号.在链接时,由于缺少符号而存在问题.
如果我正确地解析双ABI页面,它看起来像是一个转动的问题,_GLIBCXX_USE_CXX11_ABI并abi::cxx11带来一些额外的困难.Red Hat的博客可以在GCC5和C++ 11 ABI以及GCC-5.1案例和两个C++ ABI上阅读更多内容.
下面是一台Ubuntu 15机器.该机器提供GCC 5.2.1.
$ cat test.cxx
#include <string>
std::string foo __attribute__ ((visibility ("default")));
std::string bar __attribute__ ((visibility ("default")));
$ g++ -g3 -O2 -shared test.cxx -o test.so
$ nm test.so | grep _Z3
...
0000201c B _Z3barB5cxx11
00002034 B _Z3fooB5cxx11
$ echo _Z3fooB5cxx11 _Z3barB5cxx11 | c++filt
foo[abi:cxx11] bar[abi:cxx11]
Run Code Online (Sandbox Code Playgroud)
如何使用两个装饰生成带符号的二进制文件(红帽博客称之为"共存")?
或者,我们可以选择哪些选项?
我正试图为用户实现"它只是工作".我不在乎是否存在两个具有两种不同行为的弱符号(std::string缺少写时std::string[abi:cxx11]复制,同时提供写时复制).或者,一个可以是另一个的别名.
Debian在Debian Bug报告日志中有大量类似的bug :Bugs标记为libstdc ++ - cxx11.他们的解决方案是在新的ABI下重建所有内容,但它没有处理以ABI变化为模的混合/匹配编译器的极端情况.
在Apple世界中,我认为这接近于胖二进制文件.但我不确定在Linux/GCC世界中该怎么做.最后,我们不控制发行版构建库的方式,也不控制用于将应用程序与库链接的编译器.
免责声明,以下未经生产测试,使用风险自负.
您可以自己在双ABI下发布您的库.这或多或少类似于OSX"fat binary",但完全用C++构建.
最简单的方法是编译库两次:with -D_GLIBCXX_USE_CXX11_ABI=0和with -D_GLIBCXX_USE_CXX11_ABI=1.根据宏的值,将整个库放在两个不同的命名空间下:
#if _GLIBCXX_USE_CXX11_ABI
# define DUAL_ABI cxx11 __attribute__((abi_tag("cxx11")))
#else
# define DUAL_ABI cxx03
#endif
namespace CryptoPP {
inline namespace DUAL_ABI {
// library goes here
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您的用户可以CryptoPP::whatever像往常一样使用此映射到CryptoPP::cxx11::whatever或者CryptoPP::cxx03::whatever根据所选的ABI.
注意,GCC手册说这个方法将改变标记内联命名空间中定义的所有内容的错位名称.根据我的经验,这不会发生.
另一种方法是使用__attribute__((abi_tag("cxx11")))if _GLIBCXX_USE_CXX11_ABI非零来标记每个类,函数和变量.此属性很好地添加[cxx11]到demangler的输出.我认为使用命名空间的工作原理同样适用,并且对现有代码的修改要求较少.
从理论上讲,你不需要复制整个库,只是功能和使用类std::string和std::list,以及功能和使用类这些函数和类等递归.但在实践中,它可能不值得努力,特别是如果图书馆不是很大.
这是一种方法,但它不是很优雅.我也不清楚如何使GCC自动化,所以我不必做两次事情.
首先,将要转变为库的示例:
$ cat test.cxx
#include <string>
std::string foo __attribute__ ((visibility ("default")));
std::string bar __attribute__ ((visibility ("default")));
Run Code Online (Sandbox Code Playgroud)
然后:
$ g++ -D_GLIBCXX_USE_CXX11_ABI=0 -c test.cxx -o test-v1.o
$ g++ -D_GLIBCXX_USE_CXX11_ABI=1 -c test.cxx -o test-v2.o
$ ar cr test.a test-v1.o test-v2.o
$ ranlib test.a
$ g++ -shared test-v1.o test-v2.o -o test.so
Run Code Online (Sandbox Code Playgroud)
最后,看看我们得到了什么:
$ nm test.a
test-v1.o:
00000004 B bar
U __cxa_atexit
U __dso_handle
00000000 B foo
0000006c t _GLOBAL__sub_I_foo
00000000 t _Z41__static_initialization_and_destruction_0ii
U _ZNSsC1Ev
U _ZNSsD1Ev
test-v2.o:
U __cxa_atexit
U __dso_handle
0000006c t _GLOBAL__sub_I__Z3fooB5cxx11
00000018 B _Z3barB5cxx11
00000000 B _Z3fooB5cxx11
00000000 t _Z41__static_initialization_and_destruction_0ii
U _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1Ev
U _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev
Run Code Online (Sandbox Code Playgroud)
和:
$ nm test.so
00002020 B bar
00002018 B __bss_start
00002018 b completed.7181
U __cxa_atexit@@GLIBC_2.1.3
w __cxa_finalize@@GLIBC_2.1.3
00000650 t deregister_tm_clones
000006e0 t __do_global_dtors_aux
00001ef4 t __do_global_dtors_aux_fini_array_entry
00002014 d __dso_handle
00001efc d _DYNAMIC
00002018 D _edata
00002054 B _end
0000087c T _fini
0000201c B foo
00000730 t frame_dummy
00001ee8 t __frame_dummy_init_array_entry
00000980 r __FRAME_END__
00002000 d _GLOBAL_OFFSET_TABLE_
000007dc t _GLOBAL__sub_I_foo
00000862 t _GLOBAL__sub_I__Z3fooB5cxx11
w __gmon_start__
000005e0 T _init
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
00001ef8 d __JCR_END__
00001ef8 d __JCR_LIST__
w _Jv_RegisterClasses
00000690 t register_tm_clones
00002018 d __TMC_END__
00000640 t __x86.get_pc_thunk.bx
0000076c t __x86.get_pc_thunk.dx
0000203c B _Z3barB5cxx11
00002024 B _Z3fooB5cxx11
00000770 t _Z41__static_initialization_and_destruction_0ii
000007f6 t _Z41__static_initialization_and_destruction_0ii
U _ZNSsC1Ev@@GLIBCXX_3.4
U _ZNSsD1Ev@@GLIBCXX_3.4
U _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.21
U _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14975 次 |
| 最近记录: |