首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我该如何处理gcc-4.9和gcc-5之间的ABI问题?

我该如何处理gcc-4.9和gcc-5之间的ABI问题?
EN

Ask Ubuntu用户
提问于 2016-05-10 17:03:37
回答 3查看 12.1K关注 0票数 4

我最近升级了我的开发机器到Ubuntu16.04(新安装,擦除14.04)

gcc的默认版本是gcc-5.3.1

我遇到的一个问题是,一个供应商提供的库只使用gcc-4.9构建,这是不兼容gcc-5的。

我已经要求供应商提供一个新版本的库,但这不太可能在短期内发生。

同时,我已经从Ubuntu的软件包repos中安装了gcc-4.9.3

我现在安装了gcc-4.9和gcc-5:

代码语言:javascript
复制
ls -l /usr/bin/gcc*
lrwxrwxrwx 1 root root      5 May  9 11:49 /usr/bin/gcc -> gcc-5
-rwxr-xr-x 1 root root 838008 Apr 13 23:23 /usr/bin/gcc-4.9
-rwxr-xr-x 1 root root 915704 Apr 13 11:29 /usr/bin/gcc-5

我试着用gcc-4.9建立我们的资料来源,但是现在我遇到了同样的ABI问题,但我的想法却是相反的。

我遇到的问题是,我们有很多依赖项,我们通常从发行版包中安装这些依赖项。

代码语言:javascript
复制
sudo apt-get install \
    python-dev \
    libbz2-dev \
    libboost-all-dev \
    libprotobuf-dev \
    libgoogle-perftools-dev \
    postgresql \
    libpqxx-dev

虽然我可以将我的构建配置为使用gcc-4.9

代码语言:javascript
复制
mkdir build && cd build
CC=/usr/bin/gcc-4.9 CXX=/usr/bin/g++-4.9 cmake ..
make -j8

我现在得到链接错误时,链接到libtcmalloc_minimal.alibprotobuf.a等。

因此,我尝试的下一步是删除发行版repos中安装的所有依赖项,并开始从源构建依赖项。

代码语言:javascript
复制
CC=/usr/bin/gcc-4.9 CXX=/usr/bin/g++-4.9 ./configure
make -j8
sudo make install

问题是我开始掉进兔子洞里了。每个依赖项都有其他依赖项,我不知道它将在哪里结束。

另一个选择是降级到Ubuntu 14.04或一些版本,其中gcc-4.9,而不是gcc-5。

在我尝试这个核选项之前,我想知道是否有更好的方法来做到这一点?

也许可以用gcc-4.9建造的回购来安装,或者以其他方式安装?

EN

回答 3

Ask Ubuntu用户

回答已采纳

发布于 2016-09-13 09:52:32

您遇到的问题与C++11标准有关,该标准要求C++字符串(和列表)类型(S)的不同实现。为了兼容性,g++5.2和更高版本默认编译新的符合C++11的类型(无论您是否指定-std=c++11),但是可以设置宏。

代码语言:javascript
复制
-D_GLIBCXX_USE_CXX11_ABI=0

若要恢复到旧的C++字符串类型,请执行以下操作。新的libstdc++实现包含两个ABI。因此,如果您有二进制文件,您必须与旧的不兼容ABI链接,您必须在您的g++编译中设置上面的宏。这应该会产生与旧ABI兼容的二进制文件。

不幸的是,如果您使用的是来自操作系统的库,而不是C++标准库,那么除非这些库在提供两个ABI的所有不同功能的意义上都是三部曲,否则您就完了,因为它们可能只拥有新的ABI。

话虽如此,我对于一个老Ubuntu下载一个不受信任的现代g++有一个问题,它只是拒绝生产新的ABI。因此,根据新的ABI,来自ppa:ubuntu-toolchain-r/test的后端实际上已经坏了,因为它拒绝产生二进制文件。

总之,底线是,当你把所有的东西连接在一起时,要么是旧的ABI,要么是新的ABI。下面将说明您使用的是什么:

代码语言:javascript
复制
g++ --version
echo '#include <string>' > test.cpp
echo 'void f(std::string s) {}' >> test.cpp
cat test.cpp
g++ -std=gnu++11 -c -o test.o test.cpp
nm test.o | c++filt

如果那样的话

代码语言:javascript
复制
std::basic_string<char, ....

在它里面,它是旧的ABI。如果它有

代码语言:javascript
复制
std::__cxx11::basic_string<char, ...

在它里面,它是新的ABI。

票数 9
EN

Ask Ubuntu用户

发布于 2016-05-10 17:07:25

按: tty1转到CTRL+ALT+F1

清除gcc-5.3.1使用如下:

代码语言:javascript
复制
sudo apt-get purge gcc-5.3.1*

并使用以下方法安装gcc-4.9.3:

代码语言:javascript
复制
sudo apt-get install gcc-4.9.3

注:这需要互联网连接!

票数 0
EN

Ask Ubuntu用户

发布于 2019-10-08 04:58:00

使用-D_GLIBCXX_USE_CXX11_ABI=0是很好的。但是您也可以使用g++的这个选项,这可能会更好

代码语言:javascript
复制
       -fabi-version=n
           Use version n of the C++ ABI.  The default is version 0.

           Version 0 refers to the version conforming most closely to the C++ ABI specification.  Therefore, the ABI obtained using version 0 will change in different versions of G++ as ABI bugs are
           fixed.

           Version 1 is the version of the C++ ABI that first appeared in G++ 3.2.

           Version 2 is the version of the C++ ABI that first appeared in G++ 3.4, and was the default through G++ 4.9.

           Version 3 corrects an error in mangling a constant address as a template argument.

           Version 4, which first appeared in G++ 4.5, implements a standard mangling for vector types.

           Version 5, which first appeared in G++ 4.6, corrects the mangling of attribute const/volatile on function pointer types, decltype of a plain decl, and use of a function parameter in the
           declaration of another parameter.

           Version 6, which first appeared in G++ 4.7, corrects the promotion behavior of C++11 scoped enums and the mangling of template argument packs, const/static_cast, prefix ++ and --, and a class
           scope function used as a template argument.

           Version 7, which first appeared in G++ 4.8, that treats nullptr_t as a builtin type and corrects the mangling of lambdas in default argument scope.

           Version 8, which first appeared in G++ 4.9, corrects the substitution behavior of function types with function-cv-qualifiers.

           Version 9, which first appeared in G++ 5.2, corrects the alignment of "nullptr_t".

           See also -Wabi.

       -fabi-compat-version=n
           On targets that support strong aliases, G++ works around mangling changes by creating an alias with the correct mangled name when defining a symbol with an incorrect mangled name.  This switch
           specifies which ABI version to use for the alias.

           With -fabi-version=0 (the default), this defaults to 2.  If another ABI version is explicitly selected, this defaults to 0.

           The compatibility version is also set by -Wabi=n.
票数 0
EN
页面原文内容由Ask Ubuntu提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://askubuntu.com/questions/770358

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档