如果第三方库无法使用find_package来找到(有可能是第三方库没设置好或者没有Findxxx.cmake等,但是有pkgconfig目录,有.pc文件),此时通过pkgconfig也能找到库路径以及头文件路径(虽然可以直接通过find_library的方式来找,但是总感觉别人都提供了,为啥不用别人提供的呢,哈哈)
# 首先设置pkgconfig环境变量路径(路径必须包含对应的*.pc文件,少一层路径都不行):
# 如果有多个路径,可以使用";"
set(ENV{PKG_CONFIG_PATH} "/opt/glog/glog_arm_gcc9/lib/pkgconfig")
# 使用find_package来找pkgconfig
find_package(PkgConfig REQUIRED)
#获取库变量前缀,这个MYLIBS会是后面各个路径的前缀,libglog是库文件的pc文件中的名称
pkg_check_modules(MYLIBS REQUIRED libglog)
message(STATUS "${MYLIBS_FOUND}" # 是否搜索到此库
message(STATUS "${MYLIBS_INCLUDE_DIRS}" # 头文件路径
message(STATUS "${MYLIBS_LINK_LIBRARIES}" # 库文件完整路径
pkg_check_modules的用法:
pkg_check_modules原文链接
pkg_check_modules(<prefix>
[REQUIRED] [QUIET]
[NO_CMAKE_PATH]
[NO_CMAKE_ENVIRONMENT_PATH]
[IMPORTED_TARGET [GLOBAL]]
<moduleSpec> [<moduleSpec>...])
REQUIRED
表示找不到就报错停止;QUIET
即使找不到也不报错停止;NO_CMAKE_PATH
和NO_CMAKE_ENVIRONMENT_PATH
就是指定不包含默认的一些路径,还有其他路径设置可以从原文链接里看;IMPORTED_TARGET
表示要输出一个target,可以直接用于target_link_libraries()函数中,比如:pkg_check_modules(MYLIBS REQUIRED IMPORTED_TARGET lib_name) # 也就是不需要直接获取库的路径变量,直接将路径变量变成了PkgConfig::MYLIBS这个target, # 直接依赖即可 target_link_libraries(main PkgConfig::MYLIBS)
GLOBAL
表示上述的IMPORTED_TARGET
输出的target是不是全局的;
如果后面跟的模块有多个,也就是有多个lib,都找到才算找到。比如:
# 要找到多个lib库,libavcodec libavformat libavutil都找到才算真的找到
pkg_check_modules(ffmpeg REQUIRED IMPORTED_TARGET libavcodec libavformat libavutil)
另外,上述的moduleSpec
可以设置版本,比如:
# 表示搜索到任意版本的lib_name都行
pkg_check_modules(MYLIBS REQUIRED IMPORTED_TARGET lib_name)
# 表示搜索到的库的版本号必须大于1.2.3
pkg_check_modules(MYLIBS REQUIRED IMPORTED_TARGET lib_name=1.2.3)
# 表示只匹配1.2版本之前的版本
pkg_check_modules(MYLIBS REQUIRED IMPORTED_TARGET lib_name<1.2)
# 表示只匹配1.2以及之后的版本
pkg_check_modules(MYLIBS REQUIRED IMPORTED_TARGET lib_name>=1.2)
此函数执行成功后,会返回哪些变量:
<XXX>_FOUND
:如果找到,则此值为1;<XXX>_LIBRARIES
:找到的库名称,不包含路径,如glog
;<XXX>_LINK_LIBRARIES
:包含完整路径的库名称,如/opt/lib/libglog.a
;<XXX>_LIBRARY_DIRS
:库路径,不包含名称;<XXX>_LDFLAGS
:所需要的链接选项,如-L/opt//lib;-lglog
;<XXX>_LDFLAGS_OTHER
:其他链接选项;<XXX>_INCLUDE_DIRS
:头文件路径;<XXX>_CFLAGS
:C或C++编译参数;<XXX>_CFLAGS_OTHER
:其他C或C++编译参数;<YYY>_VERSION
:实际找到的版本号;<YYY> _PREFIX
:模块的前缀目录;<YYY> _INCLUDEDIR
:包含模块的目录;<YYY> _LIBDIR
:模块的Lib目录;