странные ошибки компоновщика mingw с boost? - PullRequest
4 голосов
/ 12 июля 2011

Я уже некоторое время работаю над этим и, похоже, не могу понять ситуацию - отчасти потому, что я не до конца понимаю, что происходит (именно поэтому я и пришел сюда).

Я делаю что-то вроде «Привет, мир!» Следующим образом:

#include <boost/thread/thread.hpp>
#include <cstdio>


void helloworld() {
    std::printf("HELLO FROM A BOOST THREAD!");
}

int main(int argc, char **argv) {
    boost::thread t(&helloworld);
    t.join();
}

Это на Windows. Я сохранил каталог Boost в C: \ Boost. Я запустил bootstrap и bjam, и теперь у меня есть папка stage / lib, которая содержит все файлы .lib. Файлы lib, относящиеся к библиотеке boost / thread:

libboost_thread-vc100-mt.lib
libboost_thread-vc100-mt-1_46_1.lib
libboost_thread-vc100-mt-gd.lib
libboost_thread-vc100-mt-gd-1_46_1.lib

Теперь я компилирую:

g++ -c main.cpp -I/Boost

эта строка работает нормально, я получаю main.o. Тогда:

g++ -o test.exe main.o -L/Boost/stage/lib -llibboost_thread-vc100-mt

И вот тут возникает проблема. Прежде всего, если бы я не набрал аргумент -l так, как я это сделал, MinGW даже не смог бы найти файл. Значение, если бы я попытался:

-lboost_thread-vc100-mt

вместо того, как я набрал его выше (и как я думал, что это должно быть сделано), ld завершит работу без такого файла. Во всяком случае, теперь это вывод, который я получаю из этой строки:

main.o:main.cpp:(.text+0x47): undefined reference to `_imp___ZN5boost6thread4joinEv'
main.o:main.cpp:(.text+0x55): undefined reference to `_imp___ZN5boost6threadD1Ev'
main.o:main.cpp:(.text+0x70): undefined reference to `_imp___ZN5boost6threadD1Ev'
main.o:main.cpp:(.text$_ZN5boost6threadC1IPFvvEEET_NS_10disable_ifINS_14is_convertibleIRS4_NS_6detail13thread_move_tIS4_EEEEPNS0_5dummyEE4typeE[boost::thread::thread<void (*)()>(void (*)(), boost::disable_if<boost::is_convertible<void (*&)(), boost::detail::thread_move_t<void (*)()> >, boost::thread::dummy*>::type)]+0x23): undefined reference to `_imp___ZN5boost6thread12start_threadEv'
collect2: ld returned 1 exit status

Теперь где-то там, я могу сказать, что это, очевидно, функции, которые я должен получать из boost / thread, и, очевидно, он находит файл lib, так почему он не связывается правильно?

Большое спасибо за любую помощь!

EDIT:

Я перестроил буст, используя опцию bjam "stage"

bjam toolset=gcc stage

Теперь, после завершения сборки, у меня остается папка stage / lib с файлами .a, как и следовало ожидать. Это библиотеки, связанные с бустом / потоком:

libboost_thread-mgw45-mt-1_46_1.a
libboost_thread-mgw45-mt-d-1_46_1.a

Тем не менее, связывание следующим образом:

g++ -o test.exe main.o -L/Boost/stage/lib -lboost_thread-mgw45-mt-1_46_1

выводит точно такие же ошибки. Также попробовал:

g++ -o test.exe main.o -L/Boost/stage/lib -lboost_thread-mgw45-mt-1_46_1 -static

Я все еще в растерянности.

Ответы [ 2 ]

5 голосов
/ 12 июля 2011

Решил проблему. Заголовки Boost настроены на динамическое связывание, но динамические библиотеки (dll) не создаются, если вы не укажете:

--build-type=complete

при вызове bjam. После этого скопируйте соответствующий dll в каталог вашего приложения, но все равно используйте

-L/BOOST_DIR/stage/lib -lname

при связывании.

5 голосов
/ 12 июля 2011

Этот набор библиотечных файлов:

libboost_thread-vc100-mt.lib
libboost_thread-vc100-mt-1_46_1.lib
libboost_thread-vc100-mt-gd.lib
libboost_thread-vc100-mt-gd-1_46_1.lib

для компилятора Visual Studio 2010. Они не будут работать с GCC. Если вы хотите использовать gcc / MinGW, вам нужно скачать / собрать набор библиотек наддува для этого компилятора. В качестве альтернативы вы можете установить VS 2010 и использовать этот компилятор (бесплатная версия VC ++ 2010 Express должна нормально работать, если стоимость является проблемой).

Вы можете получить дистрибутив MinGW с Boost уже в пакете от http://nuwen.net/mingw.html (я полагаю, только 32-битная цель).


Чтобы ответить на вопрос об ошибках с использованием библиотек MinGW:

Префикс _imp_ на символах указывает на то, что g++ ищет ссылку на библиотеку dll / shared. Файл .lib, который у вас есть, предназначен для статических библиотек (что я и получаю, выполняя прямую сборку библиотек bjam). Если вы посмотрите на boost/thread/detail/config.hpp, то увидите, что для сборок Win32 он по умолчанию строится на основе библиотеки DLL, если не используется компилятор MSVC или Intel.

Я даже не уверен, как именно собрать библиотеки DLL - мне придется поискать это. Тем временем вы можете использовать следующую команду, чтобы построить свой пример так, чтобы он связывался со статической библиотекой. Макрос BOOST_THREAD_USE_LIB создает файл .cpp таким образом, чтобы он ожидал связывания со статической библиотекой:

g++ -I/Boost -DBOOST_THREAD_USE_LIB -c main.cpp
...