web-dev-qa-db-fra.com

Erreur de l'éditeur de liens STD avec Apple LLVM 4.1

J'ai une grande bibliothèque statique en C++ avec des éléments Objective-C conçus à l'origine pour iOS (armv7).

J'en ai construit une version OS X (Intel x86_64 64 bits), mais dès que j'ai essayé de l'utiliser dans un projet d'application OS X (ciblé sur Lion 10.7), des dizaines d'erreurs de l'éditeur de liens sont apparues, la plupart concernant la bibliothèque standard symboles.

Je sais comment résoudre "mes" problèmes de lieur, mais les problèmes de STD copiés ci-dessous me posent problème.

"std::basic_filebuf<char, std::char_traits<char> >::is_open() const"
"std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::str() const"
"std::basic_ios<char, std::char_traits<char> >::widen(char) const"
"std::istream& std::istream::_M_extract<double>(double&)"
"std::ostream::put(char)"
"std::ostream::flush()"
"std::ostream& std::ostream::_M_insert<void const*>(void const*)"
"std::ostream& std::ostream::_M_insert<bool>(bool)"
"std::ostream& std::ostream::_M_insert<double>(double)"
"std::ostream& std::ostream::_M_insert<unsigned long>(unsigned long)"
"std::ostream::operator<<(int)"
"std::ostream::operator<<(short)"
"std::string::_Rep::_M_destroy(std::allocator<char> const&)"
"std::string::_Rep::_S_terminal"
"std::string::_Rep::_S_empty_rep_storage"
"std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&)"
"std::string::append(char const*, unsigned long)"
"std::string::append(std::string const&)"
"std::string::assign(std::string const&)"
"std::string::reserve(unsigned long)"
"std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)"
"std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&)"
"std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()"
"std::basic_ofstream<char, std::char_traits<char> >::open(char const*, std::_Ios_Openmode)"
"std::basic_ofstream<char, std::char_traits<char> >::close()"
"std::basic_ofstream<char, std::char_traits<char> >::basic_ofstream()"
"std::basic_ofstream<char, std::char_traits<char> >::~basic_ofstream()"
"std::_List_node_base::hook(std::_List_node_base*)"
"std::_List_node_base::unhook()"
"std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream(std::string const&, std::_Ios_Openmode)"
"std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream(std::_Ios_Openmode)"
"std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::~basic_stringstream()"
"std::basic_ostringstream<char, std::char_traits<char>, std::allocator<char> >::basic_ostringstream(std::_Ios_Openmode)"
"std::basic_ostringstream<char, std::char_traits<char>, std::allocator<char> >::~basic_ostringstream()"
"std::ios_base::Init::Init()"
"std::ios_base::Init::~Init()"
"std::basic_ios<char, std::char_traits<char> >::clear(std::_Ios_Iostate)"
"std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long)"
"std::_Rb_tree_decrement(std::_Rb_tree_node_base*)"
"std::_Rb_tree_increment(std::_Rb_tree_node_base const*)"
"std::_Rb_tree_increment(std::_Rb_tree_node_base*)"
"std::__throw_logic_error(char const*)"
"std::__throw_length_error(char const*)"
"std::__throw_out_of_range(char const*)"
"std::_Rb_tree_rebalance_for_erase(std::_Rb_tree_node_base*, std::_Rb_tree_node_base&)"
"std::_Rb_tree_insert_and_rebalance(bool, std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::_Rb_tree_node_base&)"
"std::cerr"
"std::cout"

J'ai vérifié mes paramètres de construction, mes liens de projet avec la bibliothèque standard (-stdlib=libc++) et je peux utiliser std :: cout sans aucun problème dans mon main.cpp.

J'ai changé le compilateur dans les paramètres de construction d'Apple LLVM 4.1 à LLVM GCC 4.2 et le problème a disparu .. Je veux continuer à utiliser Apple LLVM 4.1. Comment puis-je résoudre ce problème? 

Merci!

23
antho

Modifiez la bibliothèque standard liée en utilisant libstdc++ au lieu de libc++. Le problème est que l'autre bibliothèque a été compilée à l'aide du mode g++ qui utilise la bibliothèque libstdc++.

Considérez l'exemple de code suivant:

dhcp-191:~/Development/testy/fred% cat fred.cpp
#include <iostream>
#include <string>
#include "fred.h"

using namespace std;

bool dofred(string &x)
{
    cout << x << endl;
    return true;
}
dhcp-191:~/Development/testy/fred% cat fred.h

#include <iostream>
#include <string>

bool dofred(std::string &x);

dhcp-191:~/Development/testy/fred% clang++ -stdlib=libc++ -shared -o fred.dylib fred.cpp
dhcp-191:~/Development/testy/fred% nm fred.dylib | c++filt | grep dofred
0000000000000fa0 T dofred(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&)
dhcp-191:~/Development/testy/fred% clang++ -stdlib=libstdc++ -shared -o fred.dylib fred.cpp
dhcp-191:~/Development/testy/fred% nm fred.dylib | c++filt | grep dofred                     
0000000000000e30 T dofred(std::string&)

Vous obtenez deux symboles exportés complètement différents. Lorsque vous essayez d'utiliser le symbole, l'application qui utilise le même drapeau -stdlib pourra créer un lien, tandis que l'application qui n'en affichera pas affichera une erreur de lien.

45
Petesh

Dans iOS 7, j'utilise une bibliothèque pour les graphiques et j'ai le même problème. Dans ce cas, lib stdc ++ ne résout pas le problème.

J'ajoute le stdc ++. 6.dylib à ma phase de construction et les symboles sont trouvés.

46
gzfrancisco

J'ai eu ce problème après avoir placé tous les fichiers C++ dans une bibliothèque séparée. J'ai défini les paramètres de tous les projets pour utiliser libc ++, mais l'éditeur de liens ne fait pas le lien avec libc ++. Si j'ajoute un fichier C++ au projet principal, le problème disparaîtrait. Pour résoudre ce problème, vous pouvez ajouter '-lc ++' dans la section "Autres drapeaux de l'éditeur de liens" du projet principal. Cela obligerait XCode à se connecter à libc ++.

EDIT: Comme l'a dit l'autre affiche, XCode peut se comporter correctement. Je m'attendais à ce qu'il sache ajouter une liaison C++, car le code source de la bibliothèque C++ se trouve sur le même espace de travail.

11
jlukanta

Je viens d'avoir un problème similaire, et je devais aller dans "Paramètres de construction" puis "Apple LLVM 5.1 - Langage - C++" et ensuite changer la "bibliothèque standard C++" à libstdc ++.

3
djacobs7

vous pouvez également essayer d'ajouter un fichier .cpp vide à votre projet. Cela trompera xcode en chargeant des bibliothèques C++ std

1
Lee Irvine

En réponse à jlukanta: J'ai eu le même problème. J'ai pris soin de choisir la bonne MST, mais j'ai toujours ces erreurs. Mais ce n’est pas un bug, c’est logique: Pourquoi Xcode devrait-il être lié à la bibliothèque stdlib c ++ si vous n’avez pas de code C++ dans votre projet?

Bien sûr, c'est un problème lorsque vous n'avez pas de code C++ dans votre projet, mais des bibliothèques C++.

0
user2073196