2016-01-24 13 views
6

Mam problem z nowym ABI wprowadzonym dla C++ 11 w GCC. Po aktualizacji do GCC 5.3 mój projekt nie jest już kompilowany. Komunikaty o błędach dostaję są proste:G + nowe problemy ABI

undefined reference to `tokenize(std::__cxx11::basic_string' ...more characters 

lub

undefined reference to `extract(std::string const&)' 

Tak, wygląda na to, że zawiedli coś i GCC jest w stanie zdecydować, czy chcę starego ABI lub nowej jeden (Brakuje części z niektórych komunikatów o błędach i występuje w innych)?

Próbowałem kilka rozwiązań, aby rozwiązać ten problem:

  • przechodzącego -D_GLIBCXX_USE_CXX11_ABI=0 do GCC,
  • przechodząc -D_GLIBCXX_USE_CXX11_ABI=1 do GCC,
  • ustawieniu makro bezpośrednio w kodzie źródłowym,
  • ustawienie atrybutu abi_tag w sprawie oświadczeń złożonych przez GCC na skargę po przyjęciu flagi -Wabi-tag,

Niestety, żaden z nich nie działał (tj. zezwolono na kompilację kodu). Jedyne, co wiem to to, że tylko funkcje zwracające std::string lub przyjmowanie go jako parametru nie dają się połączyć. Które można się spodziewać, biorąc pod uwagę to, co czytałem o problemie w Internecie. Nie udało mi się odtworzyć problemu w prostym, przykładowym programie do przedstawienia go tutaj.

Czy istnieje jakieś oczywiste rozwiązanie mojego problemu, którego mi brakuje?

+2

To błąd łącznika, a nie błąd kompilatora. Sugeruje to, że skompilowane obiekty i biblioteki, które próbujesz połączyć, zostały skompilowane z różnymi ABI. – rici

+0

@rici Tak, masz rację. Mam świadomość, że problem występuje podczas łączenia. Jednak to kompilator emituje kod, który ma być połączony (lub brakuje mi mojego zrozumienia?). To, czego nie wiem, to dlaczego G ++ emituje kod czasami używając nowego, a czasem starego ABI, nawet gdy robię pełne rekompilacje kodu. – Mael

Odpowiedz

8

Ten błąd oznacza, że ​​łączysz się z jakimś kodem lub biblioteką, która nie została przekompilowana przez gcc 5.3 i została skompilowana przez starszą wersję gcc, używając wcześniejszej wersji ABI.

Jeśli łączysz się z bibliotekami zewnętrznymi, oprócz standardowej biblioteki C++, te biblioteki zewnętrzne muszą zostać ponownie skompilowane (i ponownie zainstalowane).

Jeśli nie łączysz się z żadnymi zewnętrznymi bibliotekami, a łączysz tylko swój własny kod, niektóre z Twoich modułów źródłowych nie zostały jeszcze ponownie skompilowane. Przekompiluj wszystko. Należy wyczyścić wszystkie istniejące moduły obiektów za pomocą make clean lub odpowiednika dowolnego systemu kompilacji, którego używasz.

+0

Łączę tylko mój własny kod. Ja również 'make clean''d i' make recompile''d.Turns out musi mieć błąd w moim Makefile. Po ręcznym usunięciu wszystkich plików '.o' otrzymałem ładną, czystą, testową kompilację. Akceptuję twoją odpowiedź. Dzięki! – Mael

+0

Zastanawiam się, jakie było twoje ostateczne rozwiązanie. Czy musisz ręcznie dodawać znaczniki abi do dowolnej klasy lub metody? Zastanawiam się, czy stary kod mógł zostać skompilowany tak jak poprzednio (łamanie abi bez generowania jakichkolwiek błędów). – Georg

+0

@Georg Przepraszamy za * bardzo * spóźnioną odpowiedź. Nie musiałem nic robić, tylko pełną rekompilację. Okazało się, że mam błąd w Makefile (napisany ręcznie) i usuwał wszystkie pliki '.o'; więc miałem mieszankę plików, które zostały skompilowane przy użyciu starego ABI i nowego. Okazuje się, że to naprawdę nic tajemniczego.Stary kod "mógł zostać skompilowany jak wcześniej" bez zerwania ABI. – Mael