cmake使用教程(实操版)(六)

本文详细介绍了如何使用CMake的Find模块,特别是预定义的FindCURL模块,以及如何编写和使用自定义的FindHello模块。通过示例展示了在CMakeLists.txt中如何添加依赖库,如何处理库未找到的情况,并讨论了FIND_PACKAGE指令的不同参数用法。此外,还探讨了当依赖库缺失时,设置REQUIRED参数如何影响构建过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、复杂的例子:模块的使用和自定义模块

本节着重介绍系统预定义的Find模块的使用以及自己编写Find模块,系统中提供了其他各种模块,一般情况需要使用INCLUDE指令显示的调用,FIND_PACKAGE指令是一个特例,可以直接调用预定义的模块。
其实使用纯粹依靠cmake本身提供的基本指令来管理工程是一件非常复杂的事件,所以,cmake设计成了可扩展的架构,可以通过编写一些通用的模块来扩展cmake.
在本章,我们准备首先介绍一下cmake提供的FindCURL模块的使用。然后,基于我们的libhello共享库,编写一个FindHello.cmake模块。

1、使用FindCURL模块

建立t5目录,用于存放我们的例子,建立src目录,并建立src/main.c,内容如下:
在这里插入图片描述
作用是使用curl取回www.linux-ren.org的首页并写入/tmp/curl-test文件中。
建立主工程文件:
在这里插入图片描述
src/CMakeLists.txt:
在这里插入图片描述
现在需要添加curl的头文件和库文件。
方法一:
直接在src/CMakeLists.txt中添加:

INCLUDE_DIRECTORIES(/usr/include)
TARGET_LINK_LIBRARIES(curltest curl)

方法二:使用FindCURL模块
向src/CMakeLists.txt中添加:

FIND_PACKAGE(CURL)
IF(CURL_FOUND)
			INCLUDE_DIRECTORIES(${CURL_INCLUDE_DIR})
			TARGET_LINK_LIBRARIES(curltest ${CURL_LIBRARY})
ELSE(CURL_FOUND)
			MESSAGE(FATAL_ERROR "CURL library not found")
ENDIF(CURL_FOUND)

对于系统预定义的Find<name>.cmake模块,使用的方法一般如上例所示:
每一个模块都会定义以下几个变量

<name>_FOUND
<name>_INCLUDE_DIR or <name>_INCLUDES
<name>_LIBRARY or <name>_LIBRARIES

你可以通过< name >_FOUND来判断模块是否被找到,如果没有找到,按照工程的需要关闭某些特性、给出提醒或者终止编译,上面的额例子就是给=给出致命的错误并且终止构建。

如果<naem>_FOUND为真,则将<name>_INCLUDE_DIR加入INCLUDE_DIRECTORIES,将<name>_LIBRARY加入TARGET_LINK_LIBRARIES中。

举例:通过判断系统是否提供了 JPEG 库来决定程序是否支持 JPEG 功能。

SET(mySources viewer.c)
SET(optionalSources)SET(optionalLibs)
FIND_PACKAGE(JPEG)
IF(JPEG_FOUND)
	SET(optionalSources ${optionalSources} jpegview.c)
	INCLUDE_DIRECTORIES( ${JPEG_INCLUDE_DIR} )
	SET(optionalLibs ${optionalLibs} ${JPEG_LIBRARIES} )
	ADD_DEFINITIONS(-DENABLE_JPEG_SUPPORT)
ENDIF(JPEG_FOUND)
IF(PNG_FOUND)
	SET(optionalSources ${optionalSources} pngview.c)
	INCLUDE_DIRECTORIES( ${PNG_INCLUDE_DIR} )
	SET(optionalLibs ${optionalLibs} ${PNG_LIBRARIES} )
	ADD_DEFINITIONS(-DENABLE_PNG_SUPPORT)
ENDIF(PNG_FOUND)
ADD_EXECUTABLE(viewer ${mySources} ${optionalSources} )
TARGET_LINK_LIBRARIES(viewer ${optionalLibs}

2、编写属于自己的FindHello模块

在t6中演示如何使用自定义FindHello模块并使用这个模块构建工程:
请在/backup/cmake中建立t6目录,并在其中建立cmake目录用于存放我们的源文件。

(1) 定义cmake/FindHELLO.camke模块

在这里插入图片描述
解释一下FIND_PACKAGE指令:

FIND_PACKAGE(< name > [malor.minor] [QUIET] [NOMODULE] [[REQUIRED|COMPONENTS] [compents ...]])

前面的 CURL 例子中我们使用了最简单的 FIND_PACKAGE 指令,其实他可以使用多种参数,
QUIET 参数,对应与我们编写的 FindHELLO 中的 HELLO_FIND_QUIETLY,如果不指定
这个参数,就会执行:

MESSAGE(STATUS "Found Hello: ${HELLO_LIBRARY}")

REQUIRED 参数,其含义是指这个共享库是否是工程必须的,如果使用了这个参数,说明这
个链接库是必备库,如果找不到这个链接库,则工程不能编译。对应于
FindHELLO.cmake 模块中的 HELLO_FIND_REQUIRED 变量。

建立src/main.c内容:
在这里插入图片描述
建立src/CMakeLists.txt文件,内容:
在这里插入图片描述
主工程文件CMakeLists.txt中加入:
在这里插入图片描述

(3) 使用自定义的FindHELLO模块构建工程

仍然采用外部编译的方式,建立 build 目录,进入目录运行:

cmake ..

我们可以从输出中看到:

Found Hello: /usr/lib/libhello.so

如果我们把上面的 FIND_PACKAGE(HELLO)修改为 FIND_PACKAGE(HELLO QUIET),则
不会看到上面的输出。
接下来就可以使用 make 命令构建工程,运行:
./src/hello 可以得到输出
Hello World。
说明工程成功构建。

(4)如果没有找到 hello library 呢?

我们可以尝试将/usr/lib/libhello.x 移动到/tmp 目录,这样,按照 FindHELLO 模块
的定义,就找不到 hello library 了,我们再来看一下构建结果:

cmake ..

仍然可以成功进行构建,但是这时候是没有办法编译的。
修改 FIND_PACKAGE(HELLO)为 FIND_PACKAGE(HELLO REQUIRED),将 hello
library 定义为工程必须的共享库。
这时候再次运行 cmake …
我们得到如下输出:
CMake Error: Could not find hello library.
因为找不到 libhello.x,所以,整个 Makefile 生成过程被出错中止

(5)小结

在本节中,我们学习了如何使用系统提供的 Find<NAME>模块并学习了自己编写
Find<NAME>模块以及如何在工程中使用这些模块。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值