22 ноября 2010 г.

Проблемы линковки библиотек clang и llvm

При линковке приложения с библиотеками clang и llvm может возникнуть такая проблема, что нужно передавать линковщику список библиотек в строгом порядке, иначе может возникнуть ошибка "undefined reference" даже если нужная библиотека указана в параметрах линковки. (Как здесь, например. Правда, там у человека еще и строка линковки некорректна.)

Пример:

$ g++ -o ./a.out main.o `llvm-config --ldflags` -lclangFrontend -lclangBasic -lclangDriver -lclangSerialization -lclangCodeGen -lclangSema -lclangChecker -lclangAnalysis -lclangIndex -lclangRewrite -lclangAST -lclangParse -lclangLex `llvm-config --libs`

libclangParse.a(Parser.o): In function `clang::Parser::ExpectAndConsume(clang::tok::TokenKind, unsigned int, char const*, clang::tok::TokenKind)':
Parser.cpp:151: undefined reference to `clang::tok::getTokenSimpleSpelling(clang::tok::TokenKind)'
libclangLex.a(Preprocessor.o): In function `clang::Preprocessor::DumpToken(clang::Token const&, bool) const':
Preprocessor.cpp:155: undefined reference to `clang::tok::getTokenName(clang::tok::TokenKind)'
collect2: ld returned 1 exit status



Все нужные библиотеки указаны, но не в том порядке, в каком хотелось бы линковщику. Проблема в том, что линковщик ищет в каждой библиотеке по одному разу и именно в том порядке, в каком они указаны в командной строке. Например, символ clang::tok::getTokenName находится в библиотеке libclangBasic.a, которая в списке линковки указана раньше.

Можно попытаться поискать правильный порядок (долгая и неблагодарная работа), а можно воспользоваться возможностью группировки библиотек:

$ g++ -o ./a.out ../build/obj/testclang.o `llvm-config --ldflags` -lgtest -lgtest_main -Wl,--start-group -lclangFrontend -lclangBasic -lclangDriver -lclangSerialization -lclangCodeGen -lclangSema -lclangChecker -lclangAnalysis -lclangIndex -lclangRewrite -lclangAST -lclangParse -lclangLex `llvm-config --libs` -Wl,--end-group

Линковщик будет перебирать библиотеки, указанные между ключами --start-group и --end-group снова и снова, пока не отыщет все требуемые символы.

Теперь всё ОК.

Комментариев нет:

Отправить комментарий