Ошибка компоновщика STD в Apple LLVM 4.1

У меня есть большая статическая библиотека на C ++ с кусочками Objective-C, изначально созданными для iOS (armv7).

Я создал версию для OS X (64-разрядная версия Intel x86_64), но как только я попытался использовать ее в проекте приложения для OS X (нацеленный на Lion 10.7), появились десятки ошибок компоновщика, большинство из которых касалось стандартной библиотеки символы.

Я знаю, как решить «мои» проблемы с компоновщиком, но STD, скопированные ниже, вызывают у меня проблемы.

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

Я проверил мои настройки сборки, мой проект ссылается на стандартную библиотеку (-stdlib=libc++) и я могу использовать std :: cout без проблем в моем main.cpp.

Я изменил компилятор в настройках сборки с Apple LLVM 4.1 на LLVM GCC 4.2 и проблема исчезла.
Я хочу продолжать использовать Apple LLVM 4.1. Как я могу это исправить?

Спасибо!

23

Решение

Изменить стандартную библиотеку, которая связана с использованием libstdc++ вместо libc++ — проблема в том, что другая библиотека была скомпилирована с использованием g++ режим, который использует libstdc++ библиотека.

Рассмотрим следующий пример кода:

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

Вы получаете два совершенно разных экспортируемых символа. При попытке использовать символ, приложение, которое использует тот же -stdlib Флаг сможет ссылаться, а приложение, которое не будет отображать ошибку ссылки.

45

Другие решения

В iOS 7 я использую библиотеку для диаграмм и имею ту же проблему. В этом случае lib stdc ++ не решает проблему.

Я добавляю stdc ++. 6.dylib к моей фазе сборки, и символы найдены.

46

У меня была эта проблема после помещения всех файлов C ++ в отдельную библиотеку. Я установил настройки всех проектов для использования libc ++, но компоновщик не связывается с libc ++. Если я добавлю файл C ++ в основной проект, проблема исчезнет. Чтобы это исправить, вы можете добавить ‘-lc ++’ в раздел «Другие флаги компоновщика» основного проекта. Это заставит XCode ссылаться на libc ++.

РЕДАКТИРОВАТЬ: Как сказал другой плакат, XCode может вести себя правильно. Я ожидал, что он узнает, чтобы добавить связь C ++, потому что исходный код C ++ lib находится в той же рабочей области.

11

У меня просто была похожая проблема, и мне пришлось перейти в «Настройки сборки», а затем «Apple LLVM 5.1 — Язык — C ++», а затем изменить «Стандартная библиотека C ++» на libstdc ++.

3

Вы также можете попробовать добавить пустой файл .cpp в ваш проект. Это обманом заставит xcode загружать стандартные библиотеки C ++.

1

В ответ на jlukanta: у меня была такая же проблема. Я был осторожен, чтобы выбрать правильный ЗППП, но я все еще получил эти ошибки. Но это не ошибка, на самом деле это имеет смысл: зачем XCode ссылаться на c ++ stdlib, если в вашем проекте нет кода C ++?

Конечно, это проблема, когда у вас нет кода C ++ в вашем проекте, но все еще есть библиотеки C ++.

0
По вопросам рекламы [email protected]