С++ 11 потоков с clang

Я хотел научиться использовать потоки C++11 для ускорения компиляции моего языка (да, я создаю компилятор: x). Первый образец, который я попробовал, выдал несколько ошибок с clang (3.3 SVN). Он отлично скомпилирован под GCC (4.6.3).

Я скачал clang и libc++ с SVN llvm.org. clang был скомпилирован с помощью GCC (4.6.3), а libc++ был скомпилирован с clang. Оба make-файла были сгенерированы с помощью CMake.

Для clang я следовал этому руководству: http://llvm.org/docs/GettingStarted.html#checkout< /а>

Для libc++ я следовал этому руководству: http://libcxx.llvm.org/

Фрагмент кода, который я хочу скомпилировать (foobar.cpp):

#include <iostream>
#include <thread>

using namespace std;

int main(void) {
    thread t1([](void)->void {
        cout << "foobar" << endl;
    });
}

Он отлично компилируется с clang --std=c++0x -stdlib=libc++ -lpthread foobar.cpp, но я получаю много ошибок компоновщика:

/tmp/foobar-59W5DR.o: In function `main':
foobar.cpp:(.text+0x21): undefined reference to `std::__1::thread::~thread()'
/tmp/foobar-59W5DR.o: In function `_ZNSt3__16threadC2IZ4mainE3$_0JEvEEOT_DpOT0_':
foobar.cpp:(.text+0x5c): undefined reference to `operator new(unsigned long)'
foobar.cpp:(.text+0x186): undefined reference to `operator delete(void*)'
foobar.cpp:(.text+0x19b): undefined reference to `std::__1::__throw_system_error(int, char const*)'
/tmp/foobar-59W5DR.o: In function `_ZNSt3__114__thread_proxyINS_5tupleIJZ4mainE3$_0EEEEEPvS4_':
foobar.cpp:(.text+0x200): undefined reference to `std::__1::__thread_local_data()'
foobar.cpp:(.text+0x211): undefined reference to `operator new(unsigned long)'
foobar.cpp:(.text+0x23b): undefined reference to `std::__1::__thread_struct::__thread_struct()'
foobar.cpp:(.text+0x31b): undefined reference to `operator delete(void*)'
/tmp/foobar-59W5DR.o: In function `_ZNSt3__110unique_ptrINS_5tupleIJZ4mainE3$_0EEENS_14default_deleteIS3_EEED2Ev':
foobar.cpp:(.text+0x3dd): undefined reference to `operator delete(void*)'
/tmp/foobar-59W5DR.o: In function `main::$_0::operator()() const':
foobar.cpp:(.text+0x3fc): undefined reference to `std::__1::cout'
/tmp/foobar-59W5DR.o: In function `_ZNSt3__110unique_ptrINS_5tupleIJZ4mainE3$_0EEENS_14default_deleteIS3_EEEC2EPS3_':
foobar.cpp:(.text+0x4e9): undefined reference to `std::terminate()'
/tmp/foobar-59W5DR.o: In function `std::__1::__thread_specific_ptr<std::__1::__thread_struct>::reset(std::__1::__thread_struct*)':
foobar.cpp:(.text._ZNSt3__121__thread_specific_ptrINS_15__thread_structEE5resetEPS1_[_ZNSt3__121__thread_specific_ptrINS_15__thread_structEE5resetEPS1_]+0x57): undefined reference to `std::__1::__thread_struct::~__thread_struct()'
foobar.cpp:(.text._ZNSt3__121__thread_specific_ptrINS_15__thread_structEE5resetEPS1_[_ZNSt3__121__thread_specific_ptrINS_15__thread_structEE5resetEPS1_]+0x60): undefined reference to `operator delete(void*)'
/tmp/foobar-59W5DR.o: In function `std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::operator<< <std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*)':
foobar.cpp:(.text._ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc[_ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc]+0x28): undefined reference to `std::__1::basic_ostream<char, std::__1::char_traits<char> >::sentry::sentry(std::__1::basic_ostream<char, std::__1::char_traits<char> >&)'
foobar.cpp:(.text._ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc[_ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc]+0x1ec): undefined reference to `std::__1::ios_base::getloc() const'
foobar.cpp:(.text._ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc[_ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc]+0x1fe): undefined reference to `std::__1::ctype<char>::id'
foobar.cpp:(.text._ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc[_ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc]+0x206): undefined reference to `std::__1::locale::use_facet(std::__1::locale::id&) const'
foobar.cpp:(.text._ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc[_ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc]+0x272): undefined reference to `std::__1::locale::~locale()'
foobar.cpp:(.text._ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc[_ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc]+0x294): undefined reference to `std::__1::locale::~locale()'
foobar.cpp:(.text._ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc[_ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc]+0x378): undefined reference to `std::__1::ios_base::clear(unsigned int)'
foobar.cpp:(.text._ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc[_ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc]+0x3d0): undefined reference to `std::__1::basic_ostream<char, std::__1::char_traits<char> >::sentry::~sentry()'
foobar.cpp:(.text._ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc[_ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc]+0x3dc): undefined reference to `__cxa_begin_catch'
foobar.cpp:(.text._ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc[_ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc]+0x3f9): undefined reference to `std::__1::ios_base::__set_badbit_and_consider_rethrow()'
foobar.cpp:(.text._ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc[_ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc]+0x403): undefined reference to `__cxa_end_catch'
foobar.cpp:(.text._ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc[_ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc]+0x424): undefined reference to `std::__1::basic_ostream<char, std::__1::char_traits<char> >::sentry::~sentry()'
foobar.cpp:(.text._ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc[_ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc]+0x43d): undefined reference to `__cxa_end_catch'
foobar.cpp:(.text._ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc[_ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc]+0x466): undefined reference to `std::terminate()'
/tmp/foobar-59W5DR.o: In function `std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::endl<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&)':
foobar.cpp:(.text._ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_[_ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_]+0x38): undefined reference to `std::__1::ios_base::getloc() const'
foobar.cpp:(.text._ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_[_ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_]+0x49): undefined reference to `std::__1::ctype<char>::id'
foobar.cpp:(.text._ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_[_ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_]+0x55): undefined reference to `std::__1::locale::use_facet(std::__1::locale::id&) const'
foobar.cpp:(.text._ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_[_ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_]+0xac): undefined reference to `std::__1::locale::~locale()'
foobar.cpp:(.text._ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_[_ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_]+0xbe): undefined reference to `std::__1::locale::~locale()'
foobar.cpp:(.text._ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_[_ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_]+0xcd): undefined reference to `std::__1::basic_ostream<char, std::__1::char_traits<char> >::put(char)'
foobar.cpp:(.text._ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_[_ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_]+0xdd): undefined reference to `std::__1::basic_ostream<char, std::__1::char_traits<char> >::flush()'
/tmp/foobar-59W5DR.o: In function `std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> > std::__1::__pad_and_output<char, std::__1::char_traits<char> >(std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> >, char const*, char const*, char const*, std::__1::ios_base&, char)':
foobar.cpp:(.text._ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_[_ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_]+0x215): undefined reference to `std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__init(unsigned long, char)'
foobar.cpp:(.text._ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_[_ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_]+0x389): undefined reference to `std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::~basic_string()'
foobar.cpp:(.text._ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_[_ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_]+0x3a4): undefined reference to `std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::~basic_string()'
/tmp/foobar-59W5DR.o:(.eh_frame+0x47): undefined reference to `__gxx_personality_v0'
clang-3: error: linker command failed with exit code 1 (use -v to see invocation)

Вот стандартные каталоги поиска в двух стандартных библиотеках. В результате 'clang -Wp,-v -x c++ - -fsyntax-only' я получил это:

Я попробовал clang --std=c++11 -stdlib=libc++ -llibc++ -lpthread -o foobar foobar.cpp, но компоновщик снова не находит libc++. У меня не получается связать с libС++ или это что-то более сложное?


person bash0r    schedule 09.01.2013    source источник
comment
Рассмотрите возможность связывания с -pthread вместо -lpthread   -  person Zaffy    schedule 09.01.2013
comment
Zaffy опубликовал ответ, который должен решить вашу проблему. Но когда вы запустите программу, вы получите дамп ядра. Вы должны присоединиться к треду, иначе он рухнет. Пожалуйста, добавьте: t1.join();   -  person Philipp Claßen    schedule 09.01.2013
comment
@PhilippClaßen Ах, спасибо, это исправило комментарий, который я разместил в ответе Заффи... ^.^   -  person bash0r    schedule 09.01.2013
comment
Попытка -llibc++ не сработала, потому что это должно было быть -lc++, библиотека добавляется компоновщиком, точно так же, как -lpthread подразумевает libpthread.so. Я думаю, если бы вы использовали -lc++, это сработало бы.   -  person Jonathan Wakely    schedule 09.01.2013
comment
Я просто немного запутался, что именно делает -stdlib=libc++. Использование «clang++» вместо «clang» устранило проблему. Теперь он ссылается на «libc++» и использует его заголовки. Мне даже не нужно ссылаться на «pthread».   -  person bash0r    schedule 09.01.2013


Ответы (1)


Вы компилируете clang для C, а не для C++.

  • Для C используйте clang
  • Для C++ используйте clang++

Причина, по которой clang не предупредил вас, заключается в том, что вы явно определили стандарт.

person Zaffy    schedule 09.01.2013
comment
Это не приведет к ошибкам неопределенных ссылок, это приведет к ошибкам компилятора. Это правильное определение предполагаемого языка. - person Puppy; 09.01.2013
comment
@Zaffy Впервые я использовал «clang» вместо «clang ++» ... Какой я отсталый? Теперь я получаю «завершение вызова без активного исключения\n aborted», когда я запускаю вывод. Любая идея? - person bash0r; 09.01.2013
comment
@DeadMG Если вы будете использовать, например, стандартный С++ 0x и использовать его с файлом .c, это не сработает. Причина, по которой clang не выдавал ошибок компилятора, заключается в том, что он заставил стандарт быть С++ 0x и использовал его против файла cpp, поэтому он скомпилировался нормально, но не связывал стандартную библиотеку. - person Zaffy; 09.01.2013
comment
@bash0r Вы должны присоединиться к теме: t1.join(). (Так что это корректная программа на C++, вам следует return 0.) - person Philipp Claßen; 09.01.2013
comment
Хорошо, спасибо, ребята, вы помогли мне избавиться от головной боли. :x Я боролся с этим с 10 часов. :D - person bash0r; 09.01.2013
comment
Сказав это, я также получаю исключение с clang 3.2, даже с дополнительным соединением. Он отлично работает при компиляции с gcc 4.7.2. Я использую Arch Linux. - person Philipp Claßen; 09.01.2013
comment
@PhilippClaßen: Какое исключение? Я только что попробовал это (с t1.join()) в clang 3.1, и это сработало для меня (OS X). - person Lily Ballard; 09.01.2013
comment
Этот ответ почти правильный. clang определил язык по расширению файла, поэтому он скомпилировался как C++ (ничего общего с -std=c++11). Причина ошибок компоновщика в том, что clang++ автоматически ссылается на стандартную библиотеку C++, а clang — нет. Я не могу проверить это, но, вероятно, компиляция с clang и добавление -lc++ к команде ссылки тоже сработает. - person Jonathan Wakely; 09.01.2013
comment
@JonathanWakely Нет. Если вы передадите clang (не clang++) для компиляции файла C++ без явного -std, он будет спамить ошибки. - person Zaffy; 09.01.2013
comment
@Zaffy, ты действительно пробовал это? clang версии 3.3 (транк 168793) успешно компилирует для меня файл C++ без -std, если расширение файла указывает на файл C++. Это соответствует поведению GCC. - person Jonathan Wakely; 09.01.2013
comment
@JonathanWakely Такое поведение я получил в версии 3.2, вчера я обновил свой clang, и вы правы. - person Zaffy; 09.01.2013
comment
На самом деле, если я попробую clang c.cc -std=c99, я получу ошибку error: invalid argument '-std=c99' not allowed with 'C++/ObjC++', поэтому параметр -std даже не переопределит расширение файла. Расширение файла выигрывает. См. также gcc.gnu.org/onlinedocs/gcc/Overall-Options.html (документация clang, похоже, не распространяется на это, но я предполагаю, что в этом отношении они собираются для совместимости с GCC) - person Jonathan Wakely; 09.01.2013