cmake文件下载解压第三方库并参与编译

该文介绍了一种在CMake配置阶段从GitHub下载库文件,然后在构建过程中一并编译到本地工程的方法。通过示例展示了如何下载并编译paho-mqtt库,避免了手动编译库和将库文件包含在项目中的不便。

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

我们构建自己的项目工程时,通常会引入第三库。比价简单的做法是用自己的编译工具链编译好对应的动态/静态库后再通过 TARGET_LINK_LIBRARIES 等函数链接到本地工程中。但将库放在自己的工程中,push到云端进行代码托管时就显得不优雅,并且自己编译的库所用到的工具链别人未必会用,这样上传的库就只能自己用了。

有没有一种方法可以在 cmake 的时候就把库从 github 中下载到本地,并make的时候一并编译到执行文件当中。

以下是从github中下载paho-mqtt库到本地路径并进行编译的例子。

mqtt.cmake

# mqtt library cmake function.

# 从当前可用的环境变量中移除< variable > 后续调用 $ENV{< variable >} 将返回空字符串
UNSET(LOCAL_MQTT_TAR_GZ CACHE)
UNSET(LOCAL_MQTT_DIR CACHE)
UNSET(LOCAL_LIBRARIES_PATH CACHE)

# MQTT文件夹名称
SET(MQTT_DIR_NAME "paho.mqtt.c-1.3.12")
# MQTT库压缩包名称
SET(MQTT_TAR_GZ_NAME "paho.mqtt.c-1.3.12.tar.gz")
# MQTT远程下载地址URL
SET(MQTT_DOWNLOAD_URL "https://codeload.github.com/eclipse/paho.mqtt.c/tar.gz/refs/tags/v1.3.12")
# 设置库远程下载超时时间
SET(DOWNLOAD_MQTT_TIMEOUT 300 CACHE STRING "Timeout in seconds when downloading mqtt_lib.")

MESSAGE(STATUS "Checking ${MQTT_TAR_GZ_NAME}...")

# 判断压缩包是否已经存在
FIND_FILE(LOCAL_MQTT_TAR_GZ
	NAMES ${MQTT_TAR_GZ_NAME}
	HINTS "${PROJECT_SOURCE_DIR}/libraries_path"
	NO_DEFAULT_PATH)

# 判断压缩包在文件夹libraries_path下是否已经解压
FIND_FILE(LOCAL_MQTT_DIR
	NAMES ${MQTT_DIR_NAME}
	HINTS "${PROJECT_SOURCE_DIR}/libraries_path"
	NO_DEFAULT_PATH)

FIND_FILE(LOCAL_LIBRARIES_PATH
	NAMES ""
	HINTS "libraries_path"
	NO_DEFAULT_PATH)

MESSAGE(STATUS "Checking url link ${MQTT_DOWNLOAD_URL} ...")

# 如果路径下没有压缩文件
IF(NOT LOCAL_MQTT_TAR_GZ)

	MESSAGE(STATUS "Downloading ${MQTT_TAR_GZ_NAME} to ${LOCAL_LIBRARIES_PATH} ...")
	# 从设定的 URL 地址下载相应的压缩包
	FILE(DOWNLOAD ${MQTT_DOWNLOAD_URL}
		${LOCAL_LIBRARIES_PATH}/${MQTT_TAR_GZ_NAME}
		TIMEOUT ${DOWNLOAD_MQTT_TIMEOUT}
		STATUS ERR
		SHOW_PROGRESS)

	# 判断下载是否存在错误
	IF(ERR EQUAL 0)
		# 如果下载无错误则设置压缩包名称标记下载成功
		SET(LOCAL_MQTT_TAR_GZ "${LOCAL_LIBRARIES_PATH}/${MQTT_TAR_GZ_NAME}")
	#下载错误输出相关的提示信息
	ELSE()
		MESSAGE(STATUS "Download failed, error: ${ERR}")
		MESSAGE(FATAL_ERROR
		"You can try downloading ${MQTT_DOWNLOAD_URL} manually"
		"using curl/wget or a similar tool")
	ENDIF()
	
ENDIF()

# 如果路径下存在压缩文件
IF(LOCAL_MQTT_TAR_GZ)

	# 输出相应的提示信息校验解压路径等
	MESSAGE(STATUS "Checking the direction of ${LOCAL_LIBRARIES_PATH}/${MQTT_DIR_NAME}")

	# 如果路径下没有减压文件
	IF(NOT EXISTS "${LOCAL_LIBRARIES_PATH}/${MQTT_DIR_NAME}")

		# 输出提示信息准备进行解压缩
		MESSAGE(STATUS "cd ${LOCAL_LIBRARIES_PATH} && tar -zxvf ${MQTT_TAR_GZ_NAME}")

		# 获取已下载的压缩包大小做基本的判断
		FILE(SIZE ${LOCAL_MQTT_TAR_GZ} MQTT_TAR_GZ_SIZE)
		MESSAGE(STATUS "${LOCAL_MQTT_TAR_GZ} size is ${MQTT_TAR_GZ_SIZE}")

		# 如果压缩包大小为0则输出对应的错误信息
		IF(${MQTT_TAR_GZ_SIZE} EQUAL 0)
			# 移除损坏压缩包,重置相应的参数
			FILE(REMOVE ${LOCAL_MQTT_TAR_GZ})
	 		MESSAGE(FATAL_ERROR "${MQTT_TAR_GZ_SIZE} is zero length. it had been deleted.")

		# 下载文件无问题,进入解压路径开始解压压缩包
		ELSE()

			# 解压文件
    		EXECUTE_PROCESS(COMMAND tar -zxvf ${LOCAL_MQTT_TAR_GZ} -C ${LOCAL_LIBRARIES_PATH}/
							WORKING_DIRECTORY "${LOCAL_LIBRARIES_PATH}"
							RESULT_VARIABLE 10
							RESULT_VARIABLE RESULT_TAR)
			# 如果解压操作返回值为0,说明解压成功
			IF(RESULT_TAR MATCHES 0)
				MESSAGE(STATUS "tar -zxvf ${LOCAL_MQTT_TAR_GZ} -C ${LOCAL_LIBRARIES_PATH}/")
			# 如果解压操作返回值非0,说明解压失败
			ELSE()
				MESSAGE(FATAL_ERROR "[ERROR] tar -zxvf ${LOCAL_MQTT_TAR_GZ} -C ${LOCAL_LIBRARIES_PATH}/ failed.\n")
			ENDIF()
			UNSET(RESULT_TAR)
		ENDIF()

	ENDIF()

ENDIF()

在 CMakeLists 将 mqtt.cmke 使用 INCLUDE 函数 包含进去即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值