CMake中find_library的使用
Posted fengbingchun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CMake中find_library的使用相关的知识,希望对你有一定的参考价值。
CMake中的命令find_library用于库的查找,其格式如下:
find_library(
<VAR>
name | NAMES name1 [name2 ...] [NAMES_PER_DIR]
[HINTS [path | ENV var]... ]
[PATHS [path | ENV var]... ]
[REGISTRY_VIEW (64|32|64_32|32_64|HOST|TARGET|BOTH)]
[PATH_SUFFIXES suffix1 [suffix2 ...]]
[DOC "cache documentation string"]
[NO_CACHE]
[REQUIRED]
[NO_DEFAULT_PATH]
[NO_PACKAGE_ROOT_PATH]
[NO_CMAKE_PATH]
[NO_CMAKE_ENVIRONMENT_PATH]
[NO_SYSTEM_ENVIRONMENT_PATH]
[NO_CMAKE_SYSTEM_PATH]
[NO_CMAKE_INSTALL_PREFIX]
[CMAKE_FIND_ROOT_PATH_BOTH |
ONLY_CMAKE_FIND_ROOT_PATH |
NO_CMAKE_FIND_ROOT_PATH]
)
将创建一个由<VAR>命名的缓存条目即cache变量,将<VAR>的值存入CMakeCache.txt中);或如果指定了NO_CACHE,由<VAR>命名的普通变量来存储此命令的结果。如果找到库,则结果(绝对路径+库全名)将存储在<VAR>中,除非清除<VAR>,否则不会重复搜索。如果没找到库,结果将为<VAR>-NOTFOUND。示例代码段如下:
unset(var CACHE) # 清除变量,带有CACHE也从缓存文件CMakeCache.txt中清除,若不带CACHE则缓存文件CMakeCache.txt中仍然存在var的值
find_library(var NAMES opencv_core) # 查找默认路径,默认查找动态库?在/usr/lib/x86_64-linux-gnu/目录下既有libopencv_core.so也有libopencv_core.a
message("var: $var") # var: /usr/lib/x86_64-linux-gnu/libopencv_core.so
# 如果找到库,则结果将存储在变量中,除非清除变量,否则不会重复搜索
find_library(var NAMES opencv_highgui) # 注意:未清除变量,不会重复搜索,最终结果是不对的,并没有查找opencv_highgui
message("var: $var") # var: /usr/lib/x86_64-linux-gnu/libopencv_core.so
unset(var CACHE) # 若不带CACHE,var是/usr/local/lib/libopencv_core.so而不是/usr/lib/x86_64-linux-gnu/libopencv_highgui.so
find_library(var NAMES opencv_highgui)
message("var: $var") # var: /usr/lib/x86_64-linux-gnu/libopencv_highgui.so
unset(var CACHE)
find_library(var opencv_highgui) # 最简格式:find_library(<VAR> name)
message("var: $var") # var: /usr/lib/x86_64-linux-gnu/libopencv_highgui.so
unset(var CACHE)
find_library(var NAMES opencv_xxxx) # 如果没找到库,结果将为<VAR>-NOTFOUND
message("var: $var") # var: var-NOTFOUND
if($var STREQUAL "var-NOTFOUND")
message(WARNING "the specified library was not found")
endif()
if(NOT var) # 注意这里是var不是$var
message(WARNING "the specified library was not found")
endif()
unset(var) # 不带CACHE则缓存文件CMakeCache.txt中仍然存在var的值
选项包括:
(1).NAMES:为要查找的库指定一个或多个可能的名字。当使用它来指定带有和不带有版本后缀的名称时,建议首先指定不受版本控制的名字,以便在发行版(distributions)提供的软件包之前找到本地构建的软件包。名字既可以仅是库的名称,如opencv_core,NAMES选项提供的name首先被视为库文件名,然后与特定于平台(platform-specific)的前缀(如lib)和后缀(如.so)一起考虑;也可以是库全称(前缀+库名+后缀,前缀如lib,后缀如.so,.a等),如libopencv_core.a,这可用于在类UNIX系统上定位静态库。当给NAMES选项提供多个name时,默认情况下此命令将一次考虑一个name并在每个目录中搜索它。NAMES_PER_DIR选项告诉此命令一次考虑一个目录并搜索其中的所有名称。示例代码段如下:
unset(var CACHE)
find_library(var NAMES libopencv_core.a) # 前缀+库名+后缀生效:libopencv_core.a
message("var: $var") # var: /usr/lib/x86_64-linux-gnu/libopencv_core.a
unset(var CACHE)
find_library(var NAMES opencv_highgui.a) # 库名+后缀不生效:opencv_highgui.a
message("var: $var") # var: var-NOTFOUND
unset(var CACHE)
find_library(var NAMES libopencv_core) # 前缀+库名不生效:libopencv_core
message("var: $var") # var: var-NOTFOUND
unset(var CACHE)
find_library(var NAMES opencv_highgui) # 仅有库名生效:opencv_highgui
message("var: $var") # var: /usr/lib/x86_64-linux-gnu/libopencv_highgui.so
(2).HINTS, PATHS:指定除默认位置外要搜索的目录。"ENV var"子选项从系统环境变量读取路径。注意HINTS与PATHS区别:HINTS是在搜索系统路径之前先搜索HINTS指定的路径。PATHS是先搜索系统路径,然后再搜索PATHS指定的路径。示例代码段如下:
unset(var CACHE)
find_library(var NAMES opencv_core PATHS /opt/opencv3.1/lib/) # PATHS:先搜索系统路径,然后再搜索PATHS指定的路径
message("var: $var") # var: /usr/lib/x86_64-linux-gnu/libopencv_core.so
unset(var CACHE)
find_library(var NAMES opencv_core HINTS /opt/opencv3.1/lib/) # HINTS:先搜索HINTS指定的路径,然后再搜索系统路径
message("var: $var") # var: /opt/opencv3.1/lib/libopencv_core.so
(3).REGISTRY_VIEW:3.24版本中引入。指定必须要查询的注册表视图。此选项仅在Windows平台上有意义,在其它平台上将被忽略。
(4).PATH_SUFFIXES:若在PATHS或HINTS指定的路径中没有找到,则继续会在PATHS/PATH_SUFFIXES或HINTS/PATH_SUFFIXES指定的路径中搜索。示例代码段如下:
unset(var CACHE)
find_library(var NAMES opencv_core PATHS /opt/opencv3.1/ NO_DEFAULT_PATH) # 仅搜索:/opt/opencv3.1/
message("var: $var") # var: var-NOTFOUND
unset(var CACHE)
find_library(var NAMES opencv_core PATHS /opt/opencv3.1 PATH_SUFFIXES lib NO_DEFAULT_PATH) # 搜索:(1)./opt/opencv3.1/; (2)./opt/opencv3.1/lib/
message("var: $var") # var: /opt/opencv3.1/lib/libopencv_core.so
unset(var CACHE)
find_library(var NAMES opencv_core PATHS /opt/opencv3.4.2/ NO_DEFAULT_PATH) # 仅搜索:/opt/opencv3.4.2/
message("var: $var") # var: var-NOTFOUND
unset(var CACHE)
find_library(var NAMES opencv_core HINTS /opt/opencv3.4.2 PATH_SUFFIXES lib NO_DEFAULT_PATH) # 搜索:(1)./opt/opencv3.4.2/; (2)./opt/opencv3.4.2/lib/
message("var: $var") # var: /opt/opencv3.4.2/lib/libopencv_core.so
(5).DOC:指定由<VAR>命名的缓存条目的文档字符串,即在CMakeCache.txt文件中会增加对<VAR>的描述。示例代码段如下:
unset(var CACHE)
find_library(var NAMES opencv_core DOC "opencv core dynamic library") # CMakeCache.txt中会对var增加注释说明
message("var: $var") # var: /usr/lib/x86_64-linux-gnu/libopencv_core.so
在没有添加DOC选项时,CMakeCache.txt中var内容为:
//Path to a library.
var:FILEPATH=/usr/lib/x86_64-linux-gnu/libopencv_core.so
添加DOC选项后,CMakeCache.txt中var内容变为:
//opencv core dynamic library
var:FILEPATH=/usr/lib/x86_64-linux-gnu/libopencv_core.so
(6).NO_CACHE:3.21版本中引入。搜索结果将存储在普通变量中而不是缓存条目中。如果变量在调用之前已经设置(作为普通变量或缓存变量),则搜索将不会发生。应谨慎使用此选项,因为它会大大增加重复配置步骤的成本。示例代码段如下:
unset(var1 CACHE)
find_library(var1 NAMES opencv_core NO_CACHE) # 带有NO_CACHE后,var1的值将不会存入CMakeCache.txt中
message("var1: $var1") # var1: /usr/lib/x86_64-linux-gnu/libopencv_core.so
unset(var2 CACHE)
find_library(var2 NAMES opencv_core) # 不带NO_CACHE,var2的值将写入CMakeCache.txt中
message("var2: $var2") # var2: usr/lib/x86_64-linux-gnu/libopencv_core.so
(7).REQUIRED:3.18版本中引入。如果未找到任何内容,则停止处理并触发错误消息,否则下次使用相同的变量调用find_library时将再次尝试搜索。示例代码段如下:
unset(var CACHE)
find_library(var NAMES opencv_xxxx) # 找不到会继续后续的执行
message("var: $var") # var: var-NOTFOUND
unset(var CACHE)
find_library(var NAMES opencv_xxxx REQUIRED) # 将触发error,停止后续的执行:CMake Error at test_find_library.cmake:67 (find_library): Could not find var using the following names: opencv_xxxx
(8).NO_DEFAULT_PATH:如果指定了此选项,则不会向搜索中添加其它路径,默认搜索路径将失效,只会搜索PATHS和HINTS指定的路径。示例代码段如下:
unset(var CACHE)
find_library(var NAMES opencv_core PATHS /opt/opencv3.1/lib/ NO_DEFAULT_PATH) # 指定不使用默认路径,path最后带不带"/"均可
message("var: $var") # var: /opt/opencv3.1/lib/libopencv_core.so
unset(var CACHE)
find_library(var NAMES opencv_core HINTS /opt/opencv3.4.2/lib/ NO_DEFAULT_PATH)
message("var: $var") # var: /opt/opencv3.4.2/lib/libopencv_core.so
如果未指定NO_DEFAULT_PATH选项,则搜索过程如下:
(1).3.12版本中引入。如果调用来自于find module或通过调用find_package(<PackageName>)加载的任何其它脚本,搜索当前package唯一的前缀。具体来说,查看<PackageName>_ROOT CMake变量和<PackageName>_ROOT环境变量。package root变量作为堆栈维护,因此如果从嵌套的find modules或config packages中调用,则root paths from the parent's find module or config package will be searched after paths from the current module or package.换句话说,搜索顺序将是:<CurrentPackage>_ROOT, ENV<CurrentPackage>_ROOT, <ParentPackage>_ROOT, ENV<ParentPackage>_ROOT等。如果设置了NO_PACKAGE_ROOT_PATH或将CMAKE_FIND_USE_PACKAGE_ROOT_PATH设置为FALSE,则可以跳过此步骤。
(2).在特定于cmake(cmake-specific)的缓存变量中指定的搜索路径。这些旨在通过-DVAR=value在命令行上使用。这些值被解释为分号分割的列表。如果设置了NO_CMAKE_PATH或将CMAKE_FIND_USE_CMAKE_PATH设置为FALSE,则可以跳过此步骤。
(3).在特定于cmake(cmake-specific)的环境变量中指定的搜索路径。这些旨在用户的shell配置中设置。如果设置了NO_CMAKE_ENVIRONMENT_PATH或将CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH设置为FALSE,则可以跳过此步骤。
(4).搜索由HINTS选项指定的路径。这些应该是系统introspection计算的路径。
(5).在标准系统环境变量(standard system environment variables)中指定的搜索路径。如果设置了NO_SYSTEM_ENVIRONMENT_PATH或将CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH设置为FALSE,则可以跳过此操作。
(6).搜索当前系统的Platform文件中定义的cmake变量。如果设置了NO_CMAKE_INSTALL_PREFIX或将CMAKE_FIND_USE_INSTALL_PREFIX设置为FALSE,则可以跳过搜索CMAKE_INSTALL_PREFIX和CMAKE_STAGING_PREFIX。如果设置了NO_CMAKE_SYSTEM_PATH或将CMAKE_FIND_USE_CMAKE_SYSTEM_PATH设置为FALSE,则可以跳过所有这些位置。The platform paths that these variables contain are locations that typically include installed software. An example being /usr/local for UNIX based platforms.
(7).搜索由PATHS选项或in the short-hand version of the command指定的路径。These are typically hard-coded guesses.
CMAKE_IGNORE_PATH, CMAKE_IGNORE_PREFIX_PATH, CMAKE_SYSTEM_IGNORE_PATH和CMAKE_SYSTEM_IGNORE_PREFIX_PATH变量也可能导致上述某些位置被忽略。
以上示例代码搜索本机中的OpenCV库,本机中有多个版本的OpenCV库:
(1).4.5.4:库存放路径,系统默认的库安装路径,通过命令sudo apt install libopencv-dev安装:/usr/lib/x86_64-linux-gnu/; OpenCVConfig.cmake存放路径:/usr/lib/x86_64-linux-gnu/cmake/opencv4/
(2).3.1:库存放路径:/opt/opencv3.1/lib/; OpenCVConfig.cmake存放路径:/opt/opencv3.1/share/OpenCV/
(3).3.4.2:库存放路径:/opt/opencv3.4.2/lib/; OpenCVConfig.cmake存放路径:/opt/opencv3.4.2/share/OpenCV/
执行上述测试代码需要3个文件:./build.sh, CMakeLists.txt, test_find_library.cmake
build.sh内容如下:
#! /bin/bash
# supported input parameters
params=(function macro cmake_parse_arguments find_library)
usage()
echo "Error: $0 needs to have an input parameter"
echo "supported input parameters:"
for param in $params[@]; do
echo " $0 $param"
done
exit -1
if [ $# != 1 ]; then
usage
fi
flag=0
for param in $params[@]; do
if [ $1 == $param ]; then
flag=1
break
fi
done
if [ $flag == 0 ]; then
echo "Error: parameter \\"$1\\" is not supported"
usage
exit -1
fi
if [[ ! -d "build" ]]; then
mkdir build
cd build
else
cd build
fi
echo "==== test $1 ===="
cmake -DTEST_CMAKE_FEATURE=$1 ..
CMakeLists.txt内容如下:
CMAKE_MINIMUM_REQUIRED(VERSION 3.13)
PROJECT(cmake_feature_usage)
message("#### current cmake version: $CMAKE_MAJOR_VERSION.$CMAKE_MINOR_VERSION.$CMAKE_PATCH_VERSION")
if(TEST_CMAKE_FEATURE STREQUAL "function")
include(test_function.cmake)
elseif(TEST_CMAKE_FEATURE STREQUAL "macro")
include(test_macro.cmake)
elseif(TEST_CMAKE_FEATURE STREQUAL "cmake_parse_arguments")
include(test_cmake_parse_arguments.cmake)
elseif(TEST_CMAKE_FEATURE STREQUAL "find_library")
include(test_find_library.cmake)
endif()
message("==== test finish ====")
test_find_library.cmake内容:为上面所示代码段
执行结果如下所示:
GitHub: https://github.com/fengbingchun/Linux_Code_Test
以上是关于CMake中find_library的使用的主要内容,如果未能解决你的问题,请参考以下文章
'find_library'在CMake的循环中返回相同的值