web-dev-qa-db-ja.com

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

最近、開発用マシンをUbuntu 16.04にアップグレードしました(フレッシュインストール、ワイプ14.04)

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

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

ベンダーに新しいバージョンのライブラリを提供するように依頼しましたが、すぐにそれが発生する可能性はほとんどありません。

それまでの間、Ubuntuのパッケージリポジトリからgcc-4.9.3をインストールしました。

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

ここでの問題は、私がうさぎの穴に向かい始めていることです。各依存関係には他の依存関係があり、どこで終了するのかわかりません。

もう1つのオプションは、Ubuntu 14.04またはgcc-5ではなくgcc-4.9に付属するバージョンにダウングレードすることです。

このth核オプションを試す前に、これを行うためのより良い方法があるかどうか疑問に思っていましたか?

たぶん、gcc-4.9でビルドされたリポジトリからインストールすることは可能ですか?

3
Steve Lorimer

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

-D_GLIBCXX_USE_CXX11_ABI=0

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

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

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

とにかく、最後の行は、すべてをリンクするとき、すべてが古い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, ...

その中で、そのnew ABI。

8
Yttrill

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

これを使用してgcc-5.3.1をパージします。

Sudo apt-get purge gcc-5.3.1*

そして、これを使用してgcc-4.9.3をインストールします。

Sudo apt-get install gcc-4.9.3

注:これにはインターネット接続が必要です!

0
Eofla