gcc-4.9와 gcc-5 간의 ABI 비호환성을 어떻게 처리해야 합니까?

gcc-4.9와 gcc-5 간의 ABI 비호환성을 어떻게 처리해야 합니까?

최근에 내 개발 컴퓨터를 Ubuntu 16.04로 업그레이드했습니다(새로 설치, 14.04 삭제).

gcc의 기본 버전은 gcc-5.3.1.

내가 가진 문제는 공급업체에서 제공한 라이브러리가 gcc-5와 호환되지 않는 gcc-4.9를 통해서만 구축된다는 것입니다.

나는 공급업체에 새 버전의 라이브러리를 제공해 달라고 요청했지만, 그것이 곧 이루어질 가능성은 거의 없습니다.

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

그래서 제가 시도한 다음 단계는 distro 저장소에서 설치된 모든 종속성을 제거하고 소스에서 종속성 구축을 시작하는 것이었습니다.

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++ 문자열(및 목록) 유형의 다른 구현을 요구하는 C++11 표준과 관련되어 있습니다. 호환성을 위해 g++5.2 이상에서는 기본적으로 (-std=c++11 지정 여부에 관계없이) 새로운 C++11 호환 유형을 컴파일하지만 매크로를 설정할 수 있습니다.

-D_GLIBCXX_USE_CXX11_ABI=0

이전 C++ 문자열 유형으로 되돌리려면 새로운 libstdc++ 구현에는 다음이 포함됩니다.둘 다ABI. 따라서 이전 비호환 ABI와 연결해야 하는 바이너리가 있는 경우 g++ 컴파일에서 위의 매크로를 설정해야 합니다. 그러면 이전 ABI와 호환되는 바이너리가 생성됩니다.

불행하게도 C++ 표준 라이브러리가 아닌 OS의 라이브러리를 사용하는 경우 이러한 라이브러리가 ABI에 따라 다른 모든 기능을 제공한다는 의미에서 다중 아키텍처가 아닌 한둘 다ABI를 사용한다면 새로운 ABI만 갖게 될 것이기 때문에 망할 것입니다.

새로운 ABI 생성을 거부하는 신뢰할 수 없는 최신 g++를 다운로드하는 오래된 Ubuntu에 문제가 있다고 말했습니다. 따라서 새로운 ABI에 따라 바이너리 생성을 거부하기 때문에 백포트가 ppa:ubuntu-toolchain-r/test실제로 심하게 손상된 것 같습니다.

어쨌든 결론은 함께 연결할 때 모든 것이 이전 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.

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

관련 정보