2015-08-27 6 views
2

У меня есть проект, который использует CMake для выполнения сборки на платформах Linux и Windows. Некоторые из компонентов проекта требуют некоторых библиотек Boost. Многие из компонентов построены как общие библиотеки (.dll/.so). Когда я установил Boost, я решил создать общие библиотеки.CMake: сборка Visual Studio ищет неправильную библиотеку

Вот проблема:

После запуска CMake на Windows, openening решение VS генерироваться и запуска сборки, компоненты, которые имеют зависимость от Boost, завершаться с ошибкой, что библиотека не может быть найден. Например:

LINK : fatal error LNK1104: cannot open file 'libboost_thread-vc100-mt-gd-1_58.lib' 

Достаточно, нет файла с таким именем в каталоге Boost lib. Там являются файлы общей библиотеки для этой библиотеки: boost_thread-vc100-mt-gd-1_58.dll.lib).

Я предполагаю, что вариант «lib ...» представляет собой статическую библиотеку. Почему он ищет это, когда я указал не использовать статические библиотеки из Boost? На стороне Linux нет проблем.

Вот некоторые выдержки из моих файлов CMakeLists.txt: уровень

Проект:

... 
# Set to use shared libraries from Boost. 
set(Boost_USE_STATIC_LIBS OFF) 
#set(Boost_USE_STATIC_RUNTIME OFF) <- I also tried with this uncommented - no difference 
#set(Boost_DEBUG ON) 

if(WIN32) 
    find_package(Boost 1.58 REQUIRED system thread date_time chrono) 
elseif(UNIX) 
    find_package(Boost 1.58 REQUIRED) 
endif() 

include_directories(${Boost_INCLUDE_DIRS}) 
... 

компонент, который нуждается в форсиро-

set(source_files 
    ...) 

# Create library from source files. 
add_library(lib_target SHARED ${source_files}) 

target_link_libraries(lib_target ${Boost_LIBRARIES}) 

Похоже, кто-то еще было то же самое (или аналогичный) проблема: cmake can't find boost libraries because it looks for the wrong file names. Я построил Boost с помощью link=shared.

+0

Какую версию CMake вы используете? Вы заглянули в Модули/FindBoost.cmake, чтобы узнать, как они на самом деле находят библиотеки? Иногда скрипты CMake могут быть ошибочными; альтернативно, вы можете реализовать поиск библиотек в сценарии своего приложения вместо того, чтобы полагаться на FindBoost из CMake. – Archie

+0

Я использую CMake 3.2.2. Я не смотрел модуль - не уверен, что пойму, на что я смотрю. –

ответ

3

Проблема заключается в том, что Boost использует функцию автоссылки link.exe и факт, что для выбора между статической и динамической компоновкой вы должны установить некоторые определения препроцессора. То есть, заголовки по-прежнему будут пытаться тянуть в статических библиотеках, если вы либо отключить автоматическое сшивание, или определить -DBOOST_ALL_DYN_LINK (или различные определения -DBOOST_<WHATEVER>_DYN_LINK препроцессора.)

Чтобы отключить бустер заголовки типа автосвязывающий, установите препроцессор определить -DBOOST_ALL_NO_LIB , Поскольку CMake уже заботится о поиске библиотек и установке флагов, автосоединение действительно не очень полезно с CMake. Однако вам не нужно отключать его, чтобы получить динамическую связь для работы.

Если вы хотите использовать динамическое связывание, установите Boost_USE_STATIC_LIBS на OFF и добавьте определение препроцессора -DBOOST_ALL_DYN_LINK. -DBOOST_ALL_DYN_LINK активирует __declspec(dllimport) на объявлениях в заголовках форматирования и делает функцию автоматической привязки (если включена) зависящей от dll вместо статических библиотек.

Обратите внимание, что некоторые библиотеки ускорения не предлагают выбор между статическим и динамическим связыванием и не будут затронуты -DBOOST_ALL_DYN_LINK. Я не пробовал, поэтому я не знаю, справляется ли с этим модуль CMake FindBoost.

Если вы хотите использовать статическое связывание, установите Boost_USE_STATIC_LIBS в ON. Заголовки Boost используют статическое связывание по умолчанию, поэтому не имеет значения, включен ли режим автоматической привязки или нет, если вы хотите статическое связывание.

Если вы хотите узнать, какие библиотеки требуется для автоматической привязки Boost, установите препроцессор -DBOOST_LIB_DIAGNOSTIC или используйте модуль FindBoost ${Boost_LIB_DIAGNOSTIC_DEFINITIONS}". Это приведет к тому, что заголовки выдадут имена библиотек, которые они запрашивают при их обработке.


Пример CMakeLists.txt фрагмент:

set(Boost_USE_STATIC_LIBS OFF) 
find_package(Boost 1.58 REQUIRED system thread date_time chrono) 

set(source_files ...) 
add_library(lib_target SHARED ${source_files}) 

target_compile_definitions(lib_target PRIVATE -DBOOST_ALL_NO_LIB -DBOOST_ALL_DYN_LINK) 

target_include_directories(lib_target PRIVATE ${Boost_INCLUDE_DIRS}) 
target_link_libraries(lib_target PRIVATE ${Boost_LIBRARIES}) 
Смежные вопросы