cmake查找包的方式
在编写CMakeLists.txt时,常常通过find_package引入需要的库,此时需要填入库的名称,库的名称是区分大小写的,如何确定库的准确名称,就显得至关重要了。find_package在根据填入的名称查找库时,将按照优先级顺序在指定的搜索路径进行查找FindXXX.cmake文件和XXXConfig.cmake文件(其中XXX代表填入的库名称,例如FindSQLite3.cmake、Qt5WidgetsConfig.cmake)。如果找到了对应的 .camke 文件,则引入该库成功,对应的,能够成功引入该库的头文件和库文件的路径信息。最常用的几个变量如下:
<NAME>_FOUND
<NAME>_INCLUDE_DIRS or <NAME>_INCLUDES
<NAME>_LIBRARIES or <NAME>_LIBRARIES or <NAME>_LIBS
<NAME>_DEFINITIONS
例如:Qt5Widgets_FOUND、Qt5Widgets_INCLUDES、Qt5Widgets_LIBS
find_package查找库分为两种模式,即Module模式和Config模式,分别对应于查找上述的FindXXX.cmake文件和XXXConfig.cmake文件。
Module模式
在Module模式下,find_package将只查找FindXXX.cmake文件。在实际的查找过程中,cmake的第一优先级搜索CMAKE_MODULE_PATH指定的路径,如果在CMakeLists.txt中没有设置CMAKE_MODULE_PATH为变量为Findxxx.cmake的路径(即:set(CMAKE_MODULE_PATH “Findxxx.cmake文件所在的路径”),那么此时将会搜索第二优先级的路径,也就是CMAKE_ROOT/share/cmake-x.y/Mdodules (注:x.y为cmake的版本号)。其中CMAKE_ROOT是cmake的安装路径,例如usr目录,则查找路径为 /usr/share/cmake-3.22/Modules。
如果在第二优先级的路径下仍然没有搜索到Findxxx.cmake文件,则cmake将会进入Config模式,进行XXXConfig.cmake文件查找。
Config模式
在Config模式下,find_package将只查找XXXConfig.cmake文件。在实际的查找过程中,cmake的第一优先级搜索xxx_DIR指定的路径,如果在CMakeLists.txt中没有设置这个变量(即: set(xxx_DIR “xxxConfig.cmkae文件所在的路径”)),那么此时将会搜索第二优先级的路径(与系统具体环境有关),例如 /usr/lib/x86_64-linux-gnu/cmake/xxx/,其中xxx为填入的库名称,也即是xxxConfig.cmake中的名称,例如引入库为Qt5Widgets,则查找到的文件为 /usr/lib/x86_64-linux-gnu/cmake/Qt5Widgets/Qt5WidgetsConfig.cmake。
如果cmake在以上两种模式下均没有找到对应的Findxxx.cmake和xxxConfig.cmake文件,则将会报找不到库的错误信息。
所以,当你需要引入一个库的时候,可以去CMAKE_ROOT/share/cmake-x.y/Mdodules目录或 /usr/lib/x86_64-linux-gnu/cmake/ 目录下查找到准确的库名称,再填入到CMakeLists.txt的find_package中。