2016-09-25 33 views
0

這個has been asked on SO before甚至有a related bug on this in CMAKE。但是,我的問題是一個變化,答案並不明確。find_library選擇靜態庫而不是共享庫

我的問題是我使用MinGW在Linux上交叉編譯Windows。靜態庫分別命名爲libGLESv2.dll.alibiconv.dll.a,分別用於DLL libGLESv2.dlliconv.dll

例子:

find_library(FOUND_LIB_X NAMES "zlib1.dll" PATHS ${CMAKE_FIND_ROOT_PATH}/bin/) 
finds this: zlib1.dll 

find_library(FOUND_LIB_Y NAMES "libGLESv2.dll" PATHS ${CMAKE_FIND_ROOT_PATH}/bin/) 
finds this: libGLESv2.dll.a 

find_library(FOUND_LIB_Y NAMES "iconv.dll" PATHS ${CMAKE_FIND_ROOT_PATH}/bin/) 
finds this: libiconv.dll.a 

The CMAKE bug似乎是指在靜態庫被命名爲blah.lib傳統的情況下(Windows)或blah.a(Linux)的。在Linux上使用mingw的交叉編譯器情況下,它們被命名爲blah.dll.a

我需要它來查找字面上被稱爲iconv.dll的文件,而不是其他任何東西。如果它沒有字面上的發現,然後中止。我是否使用錯誤的CMAKE功能? (請勿使用find_library()?)

+0

奇怪。根據[文檔](https://cmake.org/cmake/help/v3.6/command/find_library.html),「給NAMES選項的每個庫名稱首先被視爲庫文件名,然後考慮平臺特定的前綴(例如lib)和後綴(例如.so).'。你確定它找到'libiconv.dll.a' **在同一個目錄**,其中包含'iconv.dll'嗎?最後,您可以在調用find_library之前清理變量'CMAKE_FIND_LIBRARY_PREFIXES'或'CMAKE_FIND_LIBRARY_SUFFIXES'。 – Tsyvarev

+1

順便說一下,在每次重新配置之前清理CMake緩存,以允許'find_library'找到* new *,不是嗎? – Tsyvarev

+1

@Tsyvarev - 一個名爲iconv.dll的文件位於PATHS參數中指定的/ bin文件夾中。另一個字面上稱爲libiconv.dll.a的文件位於/ lib中,與/ bin平行。是的,我清除了緩存。 – 010110110101

回答

0

CMake使用確定次序在搜索庫時迭代庫名和目錄之間。例如,根據documentation

當不止一個值默認給的名稱選項這個命令會在同一時間考慮一個名字,然後搜索每個目錄它。

也就是說,與圖書館在dir1/name2dir2/name1

find_library(MYLIB NAMES name1 name2 PATHS dir1 dir2) 
message(${MYLIB}) 

將打印dir2/name1

指定NAMES_PER_DIR選擇反向選擇:

find_library(MYLIB NAMES name1 name2 NAMES_PER_DIR PATHS dir1 dir2) 
message(${MYLIB}) 

將打印dir1/name2

事情,試圖庫的前綴和後綴不同:

給予names選項每個庫的名字第一次被視爲一個庫文件名,然後用特定於平臺的前綴考慮(如LIB)和後綴(例如.so)。

看來,檢查lib<name>.so遍歷目錄時後立即<name>進行。

也就是說,與圖書館在dir1/libname.sodir2/name

find_library(MYLIB NAMES name PATHS dir1 dir2) 
message(${MYLIB}) 

將打印dir1/libname.so

那就是爲什麼libiconv.dll.a你的情況中發現:lib/目錄中搜索作爲系統的具體路徑在find_library搜索算法的步驟5中,但目錄bin/,指定爲路徑選項中,搜索僅在第6步

找到你想要的東西,最簡單的方法是使用NO_DEFAULT_PATH選項,在lib/所以搜索不會在所有執行:

find_library(FOUND_LIB_Y 
    NAMES "iconv.dll" 
    PATHS ${CMAKE_FIND_ROOT_PATH}/bin/ 
    NO_DEFAULT_PATH 
)