связывание с clang ++ в OS X генерирует много ошибок, не связанных с символом

Я пытаюсь скомпилировать код C ++ (включая функции C ++ 11) в OS X 10.8 с помощью компилятора clang ++. У меня есть make-файл, который генерирует объектные файлы ОК, затем по команде:

clang++  -o Analysis.so -shared DataFile.o CR39DataFile.o

Я получаю массу ошибок о символах, которые не найдены для архитектуры x86_64. Код отлично работает в системе * nix с использованием g ++ и соответствующим изменением флагов компилятора для поддержки C ++ 11. Чтобы скомпилировать * .o, я делаю это так:

clang++ -c -Wall -std=c++11 -stdlib=libc++ -I../src ../src/DataFile.cc

Изменить: вывод команды связывания:

clang++  -o Analysis.so -shared DataFile.o CR39DataFile.o
Undefined symbols for architecture x86_64:
"std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::find(char const*, unsigned long, unsigned long) const", referenced from:
CR39DataFile::read_thread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) in CR39DataFile.o
"std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::find(char, unsigned long) const", referenced from:
CR39DataFile::trim(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) in CR39DataFile.o
"std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::compare(char const*) const", referenced from:
CR39DataFile::read_thread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) in CR39DataFile.o
"std::__1::__vector_base_common<true>::__throw_length_error() const", referenced from:
std::__1::vector<frame*, std::__1::allocator<frame*> >::__append(unsigned long) in CR39DataFile.o
std::__1::vector<std::__1::vector<frame*, std::__1::allocator<frame*> >*, std::__1::allocator<std::__1::vector<frame*, std::__1::allocator<frame*> >*> >::__append(unsigned long) in CR39DataFile.o
"std::__1::__vector_base_common<true>::__throw_out_of_range() const", referenced from:
std::__1::vector<std::__1::vector<frame*, std::__1::allocator<frame*> >*, std::__1::allocator<std::__1::vector<frame*, std::__1::allocator<frame*> >*> >::at(unsigned long) in CR39DataFile.o
std::__1::vector<frame*, std::__1::allocator<frame*> >::at(unsigned long) in CR39DataFile.o
"std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::erase(unsigned long, unsigned long)", referenced from:
CR39DataFile::trim(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) in CR39DataFile.o
"std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::assign(char const*)", referenced from:
CR39DataFile::CR39DataFile() in CR39DataFile.o
CR39DataFile::clear() in CR39DataFile.o
"std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::insert(unsigned long, unsigned long, char)", referenced from:
CR39DataFile::read_thread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) in CR39DataFile.o
"std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::resize(unsigned long, char)", referenced from:
CR39DataFile::read_thread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) in CR39DataFile.o
"std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::reserve(unsigned long)", referenced from:
CR39DataFile::read_thread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) in CR39DataFile.o
"std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::basic_string(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
DataFile::read(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool) in DataFile.o
DataFile::write(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool) in DataFile.o
std::__1::thread::thread<bool (DataFile::*)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >), DataFile*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, void>(bool (DataFile::*)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)&&, DataFile*&&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&&&) in DataFile.o
CR39DataFile::read_thread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) in CR39DataFile.o
CR39DataFile::write_thread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) in CR39DataFile.o
CR39DataFile::write_thread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, float, float, float, float, float, float, float, float, float, float) in CR39DataFile.o
CR39DataFile::write_thread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, float, float, float, float, float, float) in CR39DataFile.o
...
"std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::basic_string(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long, unsigned long, std::__1::allocator<char> const&)", referenced from:
CR39DataFile::read_thread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) in CR39DataFile.o
"std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::~basic_string()", referenced from:
DataFile::~DataFile() in DataFile.o
DataFile::read(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool) in DataFile.o
DataFile::write(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool) in DataFile.o
std::__1::thread::thread<bool (DataFile::*)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >), DataFile*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, void>(bool (DataFile::*)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)&&, DataFile*&&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&&&) in DataFile.o
void* std::__1::__thread_proxy<std::__1::tuple<bool (DataFile::*)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >), DataFile*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >(void*) in DataFile.o
std::__1::__tuple_leaf<2ul, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, false>::~__tuple_leaf() in DataFile.o
CR39DataFile::CR39DataFile() in CR39DataFile.o
...
"std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::operator=(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
CR39DataFile::set_file_path(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) in CR39DataFile.o
CR39DataFile::set_file_auxpath(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) in CR39DataFile.o
"std::__1::__thread_struct::__thread_struct()", referenced from:
void* std::__1::__thread_proxy<std::__1::tuple<bool (DataFile::*)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >), DataFile*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >(void*) in DataFile.o
"std::__1::__thread_struct::~__thread_struct()", referenced from:
std::__1::__thread_specific_ptr<std::__1::__thread_struct>::reset(std::__1::__thread_struct*) in DataFile.o
"std::__1::__thread_local_data()", referenced from:
void* std::__1::__thread_proxy<std::__1::tuple<bool (DataFile::*)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >), DataFile*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >(void*) in DataFile.o
"std::__1::__throw_system_error(int, char const*)", referenced from:
std::__1::thread::thread<bool (DataFile::*)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >), DataFile*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, void>(bool (DataFile::*)(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)&&, DataFile*&&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&&&) in DataFile.o
"std::__1::thread::~thread()", referenced from:
DataFile::cleanup_file_io() in DataFile.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [Analysis.so] Error 1

person Alex Z    schedule 03.05.2013    source источник
comment
Было бы полезно узнать, какие символы не могут быть найдены ... Также MacOS использует .dylib, а не .so файлы, поэтому вам необходимо это изменить.   -  person trojanfoe    schedule 03.05.2013
comment
Да, на данный момент расширение не имеет значения. Я добавлю вывод выше.   -  person Alex Z    schedule 03.05.2013
comment
FWIW, у меня были очень похожие ошибки, когда я случайно использовал clang (компилятор c) вместо clang++   -  person Alec Jacobson    schedule 05.08.2015


Ответы (2)


Я подозреваю, что эта проблема связана с двумя библиотеками времени выполнения C ++, доступными в OS X. Используйте следующее, чтобы связать динамическую библиотеку:

clang++ -stdlib=libc++ -o Analysis.dylib -shared DataFile.o CR39DataFile.o

(-stdlib=libc++ является ключевым отличием). Я думаю, что среда выполнения C ++ по умолчанию - это реализация GNU, которая сбивает компоновщик с толку при компиляции с реализацией libc ++.

person trojanfoe    schedule 03.05.2013
comment
Спасибо, это сработало. Очень тонкое различие между двумя реализациями STL в OS X ... - person Alex Z; 03.05.2013
comment
Спасибо, у меня это тоже сработало. Мне пришлось использовать clang ++ вместо gcc. - person kisp; 01.04.2017
comment
Согласно этой странице, похоже, это указывает на то, что арка по умолчанию для gcc - 32-битная, если вы не укажете иное? developer.apple.com/library/content/documentation/Darwin/. - person Dan Hogan; 22.03.2018

В качестве побочного примечания, столкнувшись с тем же сообщением об ошибке, я обнаружил, что мне нужно использовать gcc -lstdc++ -lLibraryName ... (требуется часть stdc ++).

См. Также https://github.com/JonathanSalwan/Triton/issues/243.

person rogerdpack    schedule 29.10.2018