[英]CMake: Visual Studio build looks for wrong library
我有一個使用CMake在Linux和Windows平台上執行構建的項目。 項目的某些組件需要一些Boost庫。 許多組件都是作為共享庫(.dll / .so)構建的。 安裝Boost時,我選擇構建共享庫。
這是問題所在:
在Windows上運行CMake,打開生成的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})
...
需要Boost的組件:
set(source_files
...)
# Create library from source files.
add_library(lib_target SHARED ${source_files})
target_link_libraries(lib_target ${Boost_LIBRARIES})
似乎其他人有相同(或相似)的問題: cmake找不到boost庫,因為它查找錯誤的文件名 。 我用link=shared
建立了我的Boost。
問題是Boost使用了link.exe的自動鏈接功能,並且為了在靜態鏈接和動態鏈接之間進行選擇,您需要設置一些預處理器定義。 也就是說,除非禁用自動鏈接或定義-DBOOST_ALL_DYN_LINK
(或各種-DBOOST_<WHATEVER>_DYN_LINK
預處理程序定義),否則標頭仍將嘗試拉入靜態庫。
要禁用Boost頭的自動鏈接,請設置預處理器定義-DBOOST_ALL_NO_LIB
。 由於CMake已經負責查找庫和設置標志,因此自動鏈接對於CMake確實不是很有用。 但是,您不必禁用它即可使動態鏈接起作用。
如果要使用動態鏈接,則將Boost_USE_STATIC_LIBS
設置為OFF
並添加預處理器定義-DBOOST_ALL_DYN_LINK
。 -DBOOST_ALL_DYN_LINK
都將在boost頭中的聲明上啟用__declspec(dllimport)
,並使自動鏈接功能(如果啟用)依賴於dll,而不是靜態庫。
請注意,某些Boost庫無法在靜態鏈接和動態鏈接之間進行選擇,並且不會受到-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})
這是一個更新的示例,該示例僅使用目標而不是設置定義和包含目錄:
find_package(Boost 1.67 REQUIRED system thread date_time chrono)
set(source_files ...)
add_library(lib_target SHARED ${source_files})
target_link_libraries(lib_target PRIVATE
Boost::disable_autolinking
Boost::dynamic_linking
Boost::boost Boost::system Boost::thread Boost::date_time Boost::chrono)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.