C++源文件通过CMake编译安装成库文件供其它程序使用,核心是如何通过find_package()找到其他库

调用C++库,一般需要其库文件和头文件

可以通过CMake编译C++源文件,然后自行生成C++库文件和头文件供其它程序调用

cmake -D CMAKE_INSTALL_PREFIX="/some/where/local" ..
安装:使用cmake命令,把C++源文件编译生成的bin文件和lib文件安装在了/some/where/local下

使用:在调用这个C++库的时候,CMakeLists.txt 中使用 find_package(Ceres REQUIRED PATHS "/some/where/local/ ")才会找到 Ceres 库的头文件、库文件。

注意: 这种安装方式可以适用于多版本 Ceres 的使用,如果安装了两个 Ceres 在不同的目录中,那么在使用的过程中,我们只要在 find_package( ) 中 PATHS 后面指定其中一个版本的安装路径即可。

cmake -D EXPORT_BUILD_DIR=ON ..
安装:使用cmake命令,对C++源文件编译安装,这种方式会让 HOME 目录下的 .cmake 中出现 packages/Ceres 文件夹。

.cmake文件有什么用:Ceres 文件夹里有一个文件,该文件记录了包含 CeresConfig.cmake 的地址,一般是编译 Ceres 的原始目录地址,比如这里的 build 目录所在的绝对路径,然后CMake 会根据该文件提供的路径找到CeresConfig.cmake文件,进而利用CeresConfig.cmake中的语句,找到 Ceres 库的头文件和库文件。这个是 cmake 特有的搜索方式。即.cmake文件中包含了该库的头文件和库文件的路径。

使用:可以直接在 CMakeLists.txt 中 find_package(Ceres REQUIRED) 了。

调用:find_package() 本质上是在查找 CeresConfig.cmake 这个文件,有不同的 cmake 搜索路径,也可以直接在 CMakeLists.txt 中加上 set(Ceres_DIR "包含 CeresConfig.cmake文件的绝对路径,一般编译后的文件夹中"),然后在 find_package(Ceres),CMake 就会自动的在这个路径下查找执行 CeresConfig.cmake 文件,之后这个 Ceres 库我们就可以使用了。即使多个版本,我们只要把上面 set 语句的路径部分替换一下就能使用不同版本 Ceres了。

注意:如果我们有多个 Ceres 编译好的源码版本,我们可以在 .cmake/packages/Ceres /xxx_filename 文件中修改为不同 Ceres 源码版本目录地址,这样就可以使用不同的 Ceres 版本了。

如何生成C++库的.cmake文件

为什么要生成.cmake文件:生成C++文件编译后的.cmake文件,便于被其它程序通过find_package()调用

如何生成:CMakeLists.txt 中都有 export(PACKAGE Sopus/Pangolin),然后 cmake 会自动将包含 SopusConfig.cmake 和 PangolinConfig.cmake 文件的路径分别放到 ./cmake/packages/Sophus/xxx_filename 和 .cmake/packages/Pangolin/xxx_filename,然后系统会自动找到。

这种方式其实我们可以推广到其他的库,比如 OpenCV 库,我们可以仅编译 OpenCV 的源码不安装。然后在 .cmake/packages/ 中建立 OpenCV 文件夹和一个任意名字的文件,里面写上 OpenCV 源码中包含 OpenCVConfig.cmake 文件的目录地址, 一般是 build 目录

注意:这种方式只适用于源码库在编译后提供了 xxxConfig.cmake 文件。这种方式属于 Config 模式。对于经常用到的 g2o 库,因为库的作者没有提供 G2OConfig.cmake 文件。所以没法用这种方式。只能用 Module 模式

find_package() 怎么找到库的头文件和库文件?

包含库的头文件和库文件的变量都在 Findxxx.cmake 或者 xxxConfig.cmake 中定义着,所以我们只要找到当中的**一种 **.cmake 文件即可。然后执行这个 .cmake 文件,我们就能得到库来使用。对于 CMake 而言,有两种查找方式。

(1)、Module 模式(查找Findxxx.cmake文件)
CMake 会优先搜索 CMAKE_MODULE_PATH 指定的路径,然后搜索自己自带的 Modules 路径。所以一般来说,最常用就是在自己工程的 CMakeLists.txt 文件中更改 CMAKE_MODULE_PATH 这个变量值,或者把包含 Findxxx.cmake 文件的路径附加到这个变量中。之后就可以使用 find_package() 查找到对应的库。两种方式对应如下代码:

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake_modules/") # 后面这个路径就是在自己的工程目录中添加一个 cmake_modules 文件

# 一般推荐使用这个方式添加
LIST(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules)

对于 CMake 本身自带的模块路径,我们没必要添加 Findxxx.cmake 文件到其中。只要利用好 CMake 为我们提供的 CMAKE_MODULE_PATH 这个变量即可。

(2)、Config 模式(查找xxxConfig.cmake文件)
这个文件是库的作者提供的,或者你看明白库作者写的 CMakeLists.txt 文件后,修改生成 xxxConfig.cmake 文件),上面讲解的 Ceres 安装方式就是利用这种模式。CMake 会优先搜索 xxx_DIR 指定的路径,然后第二优先级才是搜索 /usr/lib/cmake/xxx/ 中对应的xxxConfig.cmake 文件。因此最常使用的做法,指定 xxx_DIR 到包含 xxxConfig.cmake 文件的路径。下面是最常用的命令。

set(xxx_DIR "dir") # dir 是包含 xxxConfig.cmake 文件的路径 
find_package() 

对于一些库,作者没有提供 xxxConfig.cmake 文件,只有 Findxxx.cmake 文件,那么我们只能用 Module 模式,然后推荐用 LIST(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules),把当前工程用到的 .cmake 文件放在 cmake_modules 文件夹中。这样我们就可以顺利使用 find_package() 查找使用库了。

参考:
https://cslam.cn/archives/7dcb4bb9.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容