gcc-4.9 と gcc-5 間の ABI の非互換性をどのように処理すればよいでしょうか?

gcc-4.9 と gcc-5 間の ABI の非互換性をどのように処理すればよいでしょうか?

最近、開発マシンをUbuntu 16.04にアップグレードしました(新規インストール、14.04を消去)

gcc のデフォルトのバージョンは ですgcc-5.3.1

私が抱えている問題は、ベンダーが提供するライブラリが gcc-4.9 のみを使用して構築されており、gcc-5 と互換性がないことです。

ベンダーにライブラリの新しいバージョンを提供するよう依頼しましたが、すぐに提供される可能性は低いです。

とりあえず、gcc-4.9.3Ubuntu のパッケージ リポジトリからインストールしました。

現在、gcc-4.9 と gcc-5 の両方がインストールされています。

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 の問題に直面しました。ただし、問題は逆方向です。

私が抱えている問題は、通常はディストリビューションパッケージからインストールする依存関係がたくさんあることです。

sudo apt-get install \
    python-dev \
    libbz2-dev \
    libboost-all-dev \
    libprotobuf-dev \
    libgoogle-perftools-dev \
    postgresql \
    libpqxx-dev

gcc-4.9を使用するようにビルドを構成することはできますが

mkdir build && cd build
CC=/usr/bin/gcc-4.9 CXX=/usr/bin/g++-4.9 cmake ..
make -j8

などにリンクするとリンカー エラーが発生するようになりましたlibtcmalloc_minimal.alibprotobuf.a

そこで私が試した次のステップは、ディストリビューション リポジトリからインストールされたすべての依存関係を削除し、ソースから依存関係の構築を開始することでした。

CC=/usr/bin/gcc-4.9 CXX=/usr/bin/g++-4.9 ./configure
make -j8
sudo make install

ここでの問題は、私が迷路に入り始めていることです。それぞれの依存関係には別の依存関係があり、それがどこで終わるのかわかりません。

他の選択肢としては、Ubuntu 14.04 または gcc-5 ではなく gcc-4.9 が搭載されているバージョンにダウングレードすることです。

この核融合オプションを試す前に、もっと良い方法はないかと考えていました。

gcc-4.9 でビルドされたリポジトリからインストールすることも、他の方法でインストールすることもできるでしょうか?

答え1

あなたが抱えている問題は、C++11標準がC++文字列(およびリスト)型の異なる実装を要求することに関係しています。互換性のため、g++5.2以降では、デフォルトで新しいC++11準拠の型をコンパイルします(-std=c++11を指定するかどうかに関係なく)。ただし、マクロを設定することもできます。

-D_GLIBCXX_USE_CXX11_ABI=0

古いC++文字列型に戻す。新しいlibstdc++実装には、両方ABI。したがって、古い非準拠の ABI にリンクする必要があるバイナリがある場合は、g++ コンパイル時に上記のマクロを設定する必要があります。これにより、古い ABI と互換性のあるバイナリが生成されます。

残念ながら、C++標準ライブラリ以外のOSのライブラリを使用している場合、これらのライブラリがABIによって異なるすべての機能を提供するという意味でマルチアーキテクチャでない限り、両方ABI の場合、おそらく新しい ABI しか存在しないため、困ったことになります。

そうは言っても、古い Ubuntu で信頼できない最新の g++ をダウンロードすると、新しい ABI の生成を拒否するという問題が発生します。そのため、新しいppa:ubuntu-toolchain-r/testABI に従ってバイナリを生成することを拒否しているため、バックポートは実際にはひどく壊れているようです。

いずれにせよ、肝心なのは、リンクするときにはすべてが古い ABI か新しい ABI のいずれかである必要があるということです。以下は、どちらを使用しているかを示します。

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

もしそれが

std::basic_string<char, ....

その中で、それは古いABI。

std::__cxx11::basic_string<char, ...

その中で、それは新しいABIO。

答え2

次を押して tty1 に移動します。CTRL+ALT+F1

次のコマンドを使用して gcc-5.3.1 を削除します。

sudo apt-get purge gcc-5.3.1*

次のコマンドを使用して gcc-4.9.3 をインストールします。

sudo apt-get install gcc-4.9.3

注意: インターネット接続が必要です。

答え3

使いやすい-D_GLIBCXX_USE_CXX11_ABI=0. しかし、g++のこのオプションを使うとさらに良い結果が得られる。

       -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.

関連情報