2016-01-24 9 views
6

Ho riscontrato un problema con la nuova ABI introdotta per C++ 11 in GCC. Dopo l'aggiornamento a GCC 5.3 il mio progetto non viene più compilato. I messaggi di errore che ricevo sono semplici:G + nuovi problemi ABI

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

o

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

Così, sembra che ho incasinato qualcosa e GCC è in grado di decidere se voglio il vecchio ABI o quello nuovo (il __cxx11:: manca parte di alcuni messaggi di errore e presente in altri)?

Ho provato varie soluzioni per risolvere il problema:

  • passando -D_GLIBCXX_USE_CXX11_ABI=0 a GCC,
  • passando -D_GLIBCXX_USE_CXX11_ABI=1 a GCC,
  • modificando la macro direttamente nel codice sorgente,
  • impostando l'attributo abi_tag sulle dichiarazioni che il GCC ha contestato quando ha superato la bandiera -Wabi-tag,

Sfortunatamente, nessuno di loro ha funzionato (ad es. ha permesso al codice di compilare). L'unica cosa che so è che solo le funzioni che restituiscono std::string o come parametro non riescono a collegarsi. Che c'è da aspettarselo, visto quello che ho letto sul problema su Internet. Non ero in grado di riprodurre il problema in un semplice programma di esempio per presentarlo qui.

C'è qualche soluzione ovvia al mio problema, che mi manca?

+2

Questo è un errore del linker, non un errore del compilatore. Suggerisce che gli oggetti compilati e le librerie che stai cercando di collegare sono stati compilati con ABI diversi. – rici

+0

@rici Sì, hai ragione. Sono consapevole che il problema si verifica durante il collegamento. Tuttavia, è il compilatore che emette il codice da collegare (o la mia comprensione è carente?). Quello che non so è perché G ++ emette il codice a volte usando un ABI nuovo, a volte vecchio, anche quando eseguo ricompilazioni complete del codice. – Mael

risposta

8

Questo errore indica che si sta eseguendo il collegamento a un codice o una libreria che non è stato ricompilato da gcc 5.3 ed è stato compilato da una versione precedente di gcc, utilizzando la versione precedente dell'ABI.

Se si effettua il collegamento con alcune librerie esterne, oltre alla libreria C++ standard, tali librerie esterne devono essere ricompilate (e reinstallate).

Se non si collega a nessuna libreria esterna e si collega solo il proprio codice, alcuni dei moduli sorgente non devono essere stati ricompilati. Ricompilare tutto Assicurati di cancellare tutti i moduli oggetto esistenti, con make clean o l'equivalente per qualsiasi sistema di generazione che stai utilizzando.

+0

Sto collegando solo il mio codice. Ho anche 'make clean''d e' make recompile''d. Si scopre che devo avere un bug nel mio Makefile. Dopo che ho cancellato manualmente tutti i file '.o' ho ottenuto un bel, pulito, test-passando build. Sto accettando la tua risposta. Grazie! – Mael

+0

Mi chiedo quale sia stata la tua soluzione finale. Hai dovuto aggiungere manualmente i tag abi a qualsiasi classe o metodo? Mi chiedo se il vecchio codice possa essere compilato come prima (interrompere abi senza generare errori) – Georg

+0

@Georg Ci scusiamo per una * risposta * tardiva. Non dovevo fare nulla, solo una ricompensa completa. Si è scoperto che avevo un bug nel mio Makefile (scritto a mano) e stava cancellando tutti i file '.o'; così ho avuto una mistura di file che sono stati compilati usando il vecchio ABI e il nuovo. Risulta che non era niente di arcano, davvero.Il vecchio codice "potrebbe essere compilato come prima" senza interrompere l'ABI. – Mael