2016-09-25 105 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 
)