find_library 选择静态库而不是共享库

find_library chooses the static library instead of the shared library

这个has been asked on SO before and there's even a related bug on this in CMAKE。但是,我的问题是变体,答案不清楚。

我的问题是我正在使用 MinGW 在 Linux 上针对 Windows 进行交叉编译。对于 DLL libGLESv2.dlliconv.dll,静态库分别这样命名 libGLESv2.dll.alibiconv.dll.a

示例:

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()?)

CMake 在搜索库时在迭代库名称和目录之间使用确定顺序。例如,根据 documentation

When more than one value is given to the NAMES option this command by default will consider one name at a time and search every directory for it.

也就是说,图书馆位于 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.

尝试库的前缀和后缀时情况有所不同:

Each library name given to the NAMES option is first considered as a library file name and then considered with platform-specific prefixes (e.g. lib) and suffixes (e.g. .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/ ,指定为 PATH 选项,仅在第 6 步搜索。

找到你想要的最简单的方法是使用 NO_DEFAULT_PATH 选项,所以根本不会在 lib/ 中搜索:

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