最近、開発マシンをUbuntu 16.04にアップグレードしました(新規インストール、14.04をワイプ)
gccのデフォルトバージョンはgcc-5.3.1
です。 。
私が抱えている問題は、ベンダー提供のライブラリがgcc-4.9を使用してのみ構築されていることです。これは、gcc-5と互換性がありません。
ベンダーに新しいバージョンのライブラリを提供するように依頼しましたが、それがすぐに行われる可能性はほとんどありません。
その間に、gcc-4.9.3
をインストールしました Ubuntuのパッケージリポジトリから。
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の問題に直面しましたが、逆になりました。
私が抱えている問題は、通常、distroパッケージからインストールする依存関係がたくさんあることです
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.a
に対してリンクするとリンカーエラーが発生するようになりました 、libprotobuf.a
など
したがって、私が試した次のステップは、ディストリビューションリポジトリからインストールされているすべての依存関係を削除し、ソースから依存関係の構築を開始することでした。
CC=/usr/bin/gcc-4.9 CXX=/usr/bin/g++-4.9 ./configure
make -j8
sudo make install
ここでの問題は、私がうさぎの穴に向かい始めていることです。各依存関係には他の依存関係があり、どこで終了するかわかりません。
もう1つのオプションは、Ubuntu14.04またはgcc-5ではなくgcc-4.9に同梱されているバージョンにダウングレードすることです。
このthurmonuclearオプションを試す前に、これを行うためのより良い方法があるかどうか疑問に思いましたか?
たぶん、gcc-4.9でビルドされたリポジトリから、または他の方法でインストールすることは可能ですか?
承認された回答:
あなたが抱えている問題は、C ++文字列(およびリスト)タイプの異なる実装を必要とするC++11標準に関連しています。互換性のために、g ++ 5.2以降では、デフォルトで新しいC ++ 11準拠の型がコンパイルされますが(-std =c ++ 11を指定するかどうかに関係なく)、マクロを設定できます
-D_GLIBCXX_USE_CXX11_ABI=0
古いC++文字列タイプに戻します。新しいlibstdc++実装には、両方が含まれています ABI。したがって、古い非準拠のABIとリンクする必要のあるバイナリがある場合は、g++コンパイルで上記のマクロを設定する必要があります。これにより、古いABIと互換性のあるバイナリが生成されます。
関連:MacのVirtualBox内で2560×1440の解像度を取得するにはどうすればよいですか?残念ながら、C ++標準ライブラリ以外のOSのライブラリを使用している場合、これらのライブラリが両方で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, ...
その中で、その新しい ABI。