Cmake命令之find_package介绍

作者&投稿:蔽恒 (若有异议请与网页底部的电邮联系)
~

   find_package 用于查找包(通常是使用三方库),并返回关于包的细节(使用包所依赖的头文件、库文件、编译选项、链接选项等)
  与 find_libaray 直接在指定搜索目录下搜索库不同, find_package 命令可以获取更多的信息,那么它的搜索方式也是与 find_libaray 不一样,它有两种不同的搜索方式,因此在介绍这个命令的细节之前,先简单介绍一下 find_package 命令的两种搜索模式: 模块模式 ( Module mode )和 配置模式 ( Config mode )。

  在该模式下, Cmake 会搜索一个名为 Find<PackageName>.cmake 的文件,其中 <PackageName> 为待搜索包的名称。
  搜索路径的顺序依次是:

  如果找到文件 Find<PackageName>.cmake , Cmake 会读取并处理该文件,简而言之,它负责检查一些条件(如版本号是否满足等)是否满足,并在找到包后,返回给调用者一些变量,用以获取包的详细信息。
  一般来说, Find<PackageName>.cmake 文件不是随包本身一起提供的,更多的是外部针对已有包的重新包装,例如操作系统、 Cmake 程序、甚至是调用 find_package 命令的工程针对已有的包提供针对该包的 .cmake 文件。

  该模式下, CMake 会搜索 <lowercasePackageName>-config.cmake 文件或 <PackageName>Config.cmake 文件。如果 find_package 命令中指定了具体的版本,也会搜索 <lowercasePackageName>-config-version.cmake 或 <PackageName>ConfigVersion.cmake 文件,因此配置模式下通常会提供配置文件和版本文件(注意形式上要保持一致),并且作为包的一部分一起提供给使用者。

  该模式下对 .cmake 文件的搜索路径的顺序比较复杂,具体见本文的 4.1 节。

   find_package 命令有两种格式, 基本命令格式 完整命令格式

  几个重要的参数介绍:

  这里介绍一下与基本命令有差异的地方:

   <PackageName>_FOUND 变量用来表示包是否找到, True 表示包找到了, False 表示未找到满足条件的包。如果包被找到,那么还会提供其他与这个包相关的变量供调用者使用,例如包的头文件、库文件等。这些变量都是以 <PackageName>_ 开头的,具体的命名格式请参考 Cmake中find_package命令的搜索模式之模块模式(Module mode) 的 四、对标准变量名称的更多说明 章节。

  搜索模式有两种:模块模式和配置模式。命令有两种形式:基本命令和完整命令。他们之间的关系是:

  我们将以两个例子分别展示两种搜索模式。本例中会利用我自己系统( macOS )已经安装的库 LibLZMA (如何编写自己的库并让 find_package 两种模式能搜索到,请参考另外两篇文章看 Cmake中find_package命令的搜索模式之模块模式(Module mode) 和 Cmake中find_package命令的搜索模式之配置模式(Config mode) ,尝试搜索这个库,并利用这个库提供的接口 lzma_version_string (在头文件 lzma.h 中提供)来获取它的版本号,并打印出来,测试程序如下:

  模块模式的 CMakeLists.txt 内容如下:

  由于 lzma 库本身未提供 lzmaConfig.cmake ,我们简单的编写一个,内容就是为 find_package 提供 lzma 库所在的头文件和库文件,并在 find_package 中指定查找该 .cmake 所在的路径:

  配置模式的 CMakeLists.txt 内容如下:

   CMake 会从如下从几个目录中取搜索配置文件,下面列出了将会搜索的目录,每一个目录后面通过字母来标记不同的操作系统( W 表示 Windows , U 表示 UNIX , A 表示 Apple ),目录中的 <prefix> 是目录的前缀,将在 4.1.2 介绍是怎么生成的:

  在支持 macOS 的 FRAMEWORK 和 BUNDLE 系统中,会搜索如下框架和应用程序包目录是否包含配置文件:

  上面列举的目录中, <name> 是大小写不敏感的,并且会跟 <PackageName> 或者 NAMES 指定的名字进行匹配。

   CMAKE_LIBRARY_ARCHITECTURE 变量指定的时候,也会搜索 lib/<arch> 相关的路径,会按照如下顺序搜索:

  可以通过 PATH_SUFFIXES 变量指定搜索路径的后缀,会在上述的每一个路径中都添加后缀路径进行查找。

  如果 NO_DEFAULT_PATH 选项指定了的话,那么所有以 NO_* 开头的命令都会使能, <prefix> 的查找顺序依次如下:

   CMAKE_FIND_ROOT_PATH 用于指定搜索的根路径。

  在 find_package 命令调用之前设置 CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS 为 TRUE ,这样如果查找到的路径是一个符号链接,会将符号链接对应的真实路径存起来。

  当指定 version 参数,配置模式将仅会查找能兼容指定版本的包,如果指定了 EXACT ,则只会查找精确匹配指定版本的包。 CMake 本身不会对版本号做任何转换,而是通过查找到包的版本校验文件(包自身提供的) <PackageName>ConfigVersion.cmake (或 <PackageName>-config-version.cmake ),调用版本配置文件做校验,版本配置文件可以通过 CMakePackageConfigHelpers 模块来辅助创建。可以参考 Cmake中find_package命令的搜索模式之配置模式(Config mode) 中的例子。

  当 find_package 命令中指定 version 参数后,会把 version 参数分解出来,赋值到 PACKAGE_FIND_XXX 中,供版本配置文件校验版本号使用,具体赋值的变量如下:

  当指定的版本是一个范围时,上述变量会存放范围中较小的那个版本号,这个主要是为了保证对没有实现版本范围的兼容,此外,也会赋值如下变量:

  当版本配置文件完成版本校验后,会设置如下 PACKAGE_VERSION_XXX 变量供 find_package 使用,具体的变量如下:

  上面的 PACKAGE_VERSION_XXX 几个变量仅用于 find_package 命令检查配置文件是否提供了一个可接受的版本,一旦 find_package 命令返回后,这些变量就失效了。如果版本校验通过,那么如下 <PackageName>_VERSION_XXX 变量会被设置,供 find_package 调用者使用:




最近在学习Makefile,有一些疑问。 (1) if 中各参数的含义, 有些在test...
fi是 if的结束标志 相当于#end 想那些参数 应该是shell编程上能找到 太复杂 应该不用记

linux makefile或命令前的@有什么意义
在Makefile一般用来解析shell命令,如 if [ ! -d $(CPU) ]; then mkdir $(CPU); fi 后面跟的是shell的判断语句。你可以用@把shell命令放在Makefile中执行。

Makefile里怎样检查一个目录是否存在
-d — 检查目录是否存在 几乎所有的判断都可以用这些比较运算符实现。脚本中常用-f命令选项在执行某一文件之前检查它是否存在。

在makefile里面,有一段这样的代码是什么意思?@(if ! access -rwx $(ob...
如果$(obj)文件不可读\/写\/执行,则创建以$(obj)命名的文件夹。

makefile里怎么表达elseif
用嵌套吧 ifeq ...else ifeq ...else ...endif endif 答案仅供参考。

makefile中怎么判断一个文件是否存在
1. 调用shell的函数进行判断 exist = $(shell if [ -f $(FILE) ]; then echo "exist"; else echo "notexist"; fi;)ifeq (exist, "exist")do something here endif当然,这个方法很土,但是能够工作!!2. 使用makefile的函数进行判断ifeq ($(FILE), $(wildcard $(FILE)))do something...

linux中用C语言编写完模块后怎么编写makefile文件?用到什么命令?以什么...
filename:filename.c 是指filename文件的生成要依赖filename.c文件 然后换行后按Tab键,然后编写编译规则 make命令一般是同时编译多个文件时才使用,以下是同时编写多个独立的C文件 filename1和filename2……没有依赖关系 filename1:filename1.c gcc -o filename1 filename1.c filename2:filename2....

linux 的 shell脚本编程中,如何确保一条指令指令执行成功了之后再进行下...
使用echo $?接收上条命令的标准输出,如果返回的是0就代表上条命令是成功的,如果是错误输出或者没有输出,那个返回的都不是0。例:判断httpd是否启动 pidof httpd &>\/dev\/nullif [[ $? != 0 ]]then \/etc\/init.d\/httpd startelse echo “httpd服务启动成功”fi刚才没看下面 make && mak...

makefile里有两个地方不懂
-d 是档案存在且属性是目录时,返回TRUE -e 是当档案存在时,返回TRUE 这些是Bshell的test express,可用来得到文件或文件夹的存在状态,在if,while等条件判断语句中非常多的使用,“-”应该不是你说的那个意思。

linux查看驱动是否安装linux查看驱动
(MAKE)-C$(KERNELDIR)M=$(PWD)modules endif 比较两者可以发现,该两个Makefi二Makefile文件有两种写法:一种是:Addyourdebuggingflag(ornot)toCFLAGS ifneq($(KERNELRELEASE),)obj-m:=boot.o else KERNELDIR?=\/lib\/modules\/$(shelluname-r)\/build PWD:=$(shellpwd)default:(MAKE)-C$(KERNEL...

理塘县13238328572: CLion 怎么链接外部库 比如boost -
徐珊欣洫: CMakeLists.txt 决定了 CLion 对项目的所有配置,一定要修改它.为了便于跨平台(甚至只是跨机器),不建议指定具体的库目录,而是使用 find_package 让 CMake 去寻找这个库.当然 find_package 没有带对应的 .cmake 模块的时候,可以...

理塘县13238328572: 使用clion为什么cmake引入boost不成功 -
徐珊欣洫: find_package(Boost 1.62.0)应该改成find_package(Boost REQUIRED COMPONENTS system) 再加上target_link_libraries(untitled1 ${Boost_LIBRARIES}) 让cmake去搞定Boost.另外,再加上链接Ws2_32.lib库.if(WIN32) target_link_libraries(untitled wsock32 ws2_32) endif()

理塘县13238328572: 求教,cmake找不到库,帮帮忙,感激 -
徐珊欣洫: 需要什么库 就把相应库的路径 添加到CMAKE寻找的目录中

理塘县13238328572: 如何使用CMake进行交叉编译 -
徐珊欣洫: cmake交叉编译配置 很多时候,我们在开发的时候是面对嵌入式平台,因此由于资源的限制需要用到相关的交叉编译.即在你host宿主机上要生成target目标机的程序.里面牵扯到相关头文件的切换和编译器的选择以及环境变量的改变等,我今...

理塘县13238328572: 如何在linux下使用Clion开发Qt的Gui程序 -
徐珊欣洫: 准备工作:已安装好的QtCreator环境,但是觉得QtCreator不好用,转用其他开发工具 第一步,使用Clion创建一个C++项目,如下图:第二步,修改CMakeLists.txt和main.cpp文件:1). CMakeLists.txt修改如下:cmake_minimum_required(...

理塘县13238328572: findboost.cmake 脚本在哪 -
徐珊欣洫: 把lib文件夹中的libboost_thread-vc100-mt-1_49.lib和libboost_thread-vc100-mt-gd-1_49.lib的lib头去掉 变成boost_thread-vc100-mt-1_49.lib和boost_thread-vc100-mt-gd-1_49.lib就能找到了

理塘县13238328572: ros中的节点用c++编写的时候直接调用就可以了吗 -
徐珊欣洫: 一、首先建一个包 我的工作空间catkin_ws事先建好了,路径是/home/siat/catkin_ws 然后运行以下命令在src文件夹下建立test包$ cd ~/catkin_ws/src$ catkin_create_pkg test roscpp1212 注意在包的名字后加上一些基本的依赖,比如roscpp和...

理塘县13238328572: Ubuntu安装软件错误 -
徐珊欣洫: 首先选好源(系统-系统管理-软件源),然后sudo apt-get update更新软件列表,之后就可以用新立德、软件中心(9.10才有),“sudo apt-get install 软件名”来安装了.尽量不要用dpkg,有些依赖关系解决不了,apt-get可以自动解决依赖问题.

理塘县13238328572: ubuntu 14.04 怎么安装geant4 10.02 -
徐珊欣洫: 在BIOS设置设置光驱启动(本人是用光盘装的).这些都不是重点,用Ubantu的不至于不会重装系统吧 选择语言 安装环境 足够的磁盘空间,电脑接入电源,已经连接互联网 选项:安装中下载更新,安装第三方软件 Ps:a.互联网可以不连接,连...

理塘县13238328572: ubuntu下安装neper报错 -
徐珊欣洫: 没有安装NLopt,需要手动下载安装 详细安装过程见http://ab-initio.mit.edu/wiki/index.php/NLopt_Installation./congfigure make sudo make install

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网