it-swarm.com.de

STD-Linker-Fehler bei Apple LLVM 4.1

Ich habe eine große statische Bibliothek in C++ mit Objective-C-Bits, die ursprünglich für iOS (armv7) erstellt wurden.

Ich baute eine OS X (64-Bit Intel x86_64) -Version davon auf, aber sobald ich versuchte, es in einem OS X-App-Projekt (an Lion 10.7 gerichtet) zu verwenden, traten Dutzende von Linker-Fehlern auf, die meisten davon über Standardbibliothek Symbole.

Ich weiß, wie man "meine" Linker-Probleme löst, aber die unten aufgeführten STDs stören mich.

"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"

Ich habe meine Build-Einstellungen überprüft, mein Projekt verlinkt auf die Standardbibliothek (-stdlib=libc++) und ich kann std :: cout problemlos in meiner main.cpp verwenden.

Ich habe den Compiler in den Build-Einstellungen von Apple LLVM 4.1 zu LLVM GCC 4.2 geändert, und das Problem ist verschwunden ... Ich möchte Apple LLVM 4.1 weiterhin verwenden. Wie kann ich das beheben? 

Vielen Dank!

23
antho

Ändern Sie die verknüpfte Standardbibliothek, um libstdc++ anstelle von libc++ zu verwenden. Das Problem ist, dass die andere Bibliothek mit dem g++-Modus kompiliert wurde, der die libstdc++-Bibliothek verwendet.

Betrachten Sie den folgenden Beispielcode:

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&)

Sie erhalten zwei völlig unterschiedliche exportierte Symbole. Wenn Sie versuchen, das Symbol zu verwenden, kann die App, die dasselbe -stdlib-Flag verwendet, eine Verknüpfung herstellen, während bei der App, die keinen Link-Fehler anzeigt.

45
Petesh

In iOS 7 verwende ich eine Bibliothek für Diagramme und habe das gleiche Problem. In diesem Fall löst lib stdc ++ das Problem nicht.

Ich füge der Buildphase das stdc ++. 6.dylib hinzu und die Symbole werden gefunden.

46
gzfrancisco

Ich hatte dieses Problem, nachdem ich alle C++ - Dateien in eine separate Bibliothek gestellt hatte. Ich habe die Einstellungen aller Projekte für die Verwendung von libc ++ festgelegt, der Linker stellt jedoch keine Verknüpfung mit libc ++ her. Wenn ich dem Hauptprojekt eine C++ - Datei hinzufüge, würde das Problem verschwinden. Um dies zu beheben, können Sie im Abschnitt "Other Linker Flags" des Hauptprojekts "-lc ++" hinzufügen. Dies würde XCode dazu zwingen, mit libc ++ zu verknüpfen.

BEARBEITEN: Wie das andere Poster sagte, verhält sich XCode möglicherweise korrekt. Ich hatte erwartet, dass es bekannt ist, eine C++ - Verknüpfung hinzuzufügen, da sich der C++ - Quellcode auf demselben Arbeitsbereich befindet.

11
jlukanta

Ich hatte gerade ein ähnliches Problem und musste zu "Build Settings" und dann zu "Apple LLVM 5.1 - Language - C++" gehen und dann die "C++ - Standardbibliothek" in libstdc ++ ändern.

3
djacobs7

sie können auch versuchen, eine leere .cpp-Datei zu Ihrem Projekt hinzuzufügen. Dadurch wird Xcode dazu verleitet, C++ - std-Bibliotheken zu laden

1
Lee Irvine

Antwort auf jlukanta: Ich hatte das gleiche Problem. Ich habe sorgfältig die richtige STD ausgewählt, aber ich habe immer noch diese Fehler erhalten. Aber das ist kein Fehler, es macht tatsächlich Sinn: Warum sollte Xcode mit der C++ - stdlib verknüpft werden, wenn Sie keinen C++ - Code in Ihrem Projekt haben?

Dies ist natürlich ein Problem, wenn Sie in Ihrem Projekt keinen C++ - Code, aber immer noch C++ - Bibliotheken haben.

0
user2073196