find_package的作用
在CMakeLists.txt如果需要使用第三方库,那么需要知道三个东西
去哪里找头文件(.h等) | 对应于GCC的参数 -I |
去哪里找库文件(.so/.lib/.ddl等) | 对应于GCC的参数 -L |
需要链接的库文件名称 | 对应于GCC的参数 -l |
比如我需要链接第三方库curl,那么在CMakeLists.txt中可以书写如下:
include_directories(/usr/include) # 对应于-I target_link_libraries(target curl) # 对应于 -L和-l
find_package的作用就是去寻找该库的头文件位置、库文件位置以及库文件名称,并将其设为变量,返回提供给CMakeLists.txt其他部分使用。
例如:
find_package(curl) include_directories(${CURL_INCLUDE_DIR}) target_link_libraries(curltest ${CURL_LIBRARY})
或者
find_package(CURL) if(CURL_FOUND) include_directories(${CURL_INCLUDE_DIR}) target_link_libraries(curltest ${CURL_LIBRARY}) else(CURL_FOUND) message(FATAL_ERROR "curl not found!") endif(CURL_FOUND)
那么find_package会去 ${CMAKE_MODULE_PATH}的所有路径中去寻找FindCURL.cmake(是的,一般会去查找Find<name>.cmake这种格式),并执行FindCURL.cmake里的代码。
实际上,find_package寻找.cmake文件的搜索规则为
- ${CMAKE_MODULE_PATH},该变量是CMake默认自带的一个路径,也可以通过语句添加自己的CMake的模块搜索路径,如:
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") # CMAKE_SOURCE_DIR是项目根目录
- <CMAKE_ROOT>/share/cmake-x.y/Modules/
- 如果Find<name>.cmake文件未找到,它将会尝试在系统路径中查找 <Name>Config.cmake 或 <lower-case-name>-config.cmake 文件。这两个文件是库文件安装时自己安装的,将自己的路径硬编码到其中。前者称为 module 模式,后者称为 config 模式。
通常FindCURL.cmake文件会提供以下几个变量:
<name>_FOUND => 表明是否查找到
<name>_INCLUDE_DIR 或 <name>_INCLUDES => 表示头文件位置
<name>_LIBRARY 或 <name>_LIBRARIES 或 <name>_LIBS => 表示库文件路径+名称
<name>_DEFINITIONS
编写Find<Name>.cmake文件
这里主要有两个函数,find_path和find_library.
find_path
find_path函数用法有两种,举例说明,例子如下,其中cmake_example的绝对路径为 /home/ruiy/cmake_example/
├─cmake_example % 用例根目录 └─find_path ├─CMakeLists.txt └─test.h
第一种
第一种用法是精简的命令格式,如下
find_path(<VAR> name1 [path1 path2 ...]) # <VAR>是查找的路径存储到变量, names是需要查找的文件名, path1等是搜索路径
例如
find_path(test_path find_path/test.h /home/ruiy/cmake_example) message(${test_path}) # ${test_path}的值为 /home/ruiy/cmake_example 结果: // Path to a file test_path:PATH=/home/ruiy/cmake_example
再比如
find_path(test_path test.h /home/ruiy/cmake_example/find_path) message(${test_path}) 结果: // Path to a file test_path:PATH=/home/ruiy/cmake_example/find_path
第二种
find_path( <VAR> name | NAMES name1 [name2 ...] [HINTS path1 [path2 ... ENV var]] [PATHS path1 [path2 ... ENV var]] [PATH_SUFFIXES suffix1 [suffix2 ...]] [DOC "cache documentation string"] [NO_DEFAULT_PATH] [NO_CMAKE_ENVIRONMENT_PATH] [NO_CMAKE_PATH] [NO_SYSTEM_ENVIRONMENT_PATH] [NO_CMAKE_SYSTEM_PATH] [CMAKE_FIND_ROOT_PATH_BOTH | ONLY_CMAKE_FIND_ROOT_PATH | NO_CMAKE_FIND_ROOT_PATH] )
例如
find_path(test_path NAMES test.h PATHS /home/ruiy/cmake_example/find_path DOC "this is a test for find_path") message(${test}) 结果: //this is a test for find_path test_path:PATH=/home/ruiy/cmake_example/find_path
这里用参考6里的话来解释该命令
该命令用于给定名字文件所在的路径。一条名为<VAR>的cache条目会被创建,并存储该命令的执行结果。如果在某个路径下发现了该文件,该结果会被存储到该变量中;除非该变量被清除,该次搜索不会继续进行。如果没有找到,存储的结果将会是<VAR>-NOTFOUND,并且当下一次以相同的变量名调用find_path命令时,该命令会再一次尝试搜索该文件。需要搜索的文件名通过在NAMES选项后面的列出来的参数来确定。附加的搜索位置可以在PATHS选项之后指定。如果在PATHS或者HINTS命令中还指定了ENV var选项,环境变量var将会被读取并从一个系统环境变量转换为一个cmake风格的路径list。比如,ENV PATH是列出系统path变量的一种方法。参数DOC将用来作为该变量在cache中的注释。PATH_SUFFIXES指定了在每个搜索路径下的附加子路径。
find_library
实际上,find_library
同find_path
等价,见参考【6】的内容
没有帐号?立即注册