簡體   English   中英

CMake:Visual Studio構建查找錯誤的庫

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM