这是CMake中用于管理第三方库的命令。本文使用的CMake版本是3.22.1。
文本介绍了ExternalProject的CMake命令,并且基于此安装了boost。
官方文档:https://cmake.org/cmake/help/v3.22/module/ExternalProject.html
这个库需要include(ExternalProject)
。
ExternalProject_Add
定义一个target,这个target包括以下的步骤:
- download
- update/patch
- configure
- build
- install
- test
这些步骤会顺序执行。configure、build、install都有默认操作,这些默认操作是针对构建支持CMake的第三方库的。如果安装的第三方库不支持CMake,有特定的配置、构建流程,则需要覆盖这些构建步骤。
download
URL
download内有很多参数,这里主要讲URL。URL支持指定网络压缩包的url,也支持本地的压缩包。
这里提供了个boost本地压缩包的案例(正常安装boost还需要配置其他参数,在后面章节会陆续加入):
include(ExternalProject)
SET(DOWNLOAD_DIR "/root/downloads")
SET(BOOST_PATH ${DOWNLOAD_DIR}/boost_1_78_0.tar.gz)
ExternalProject_Add(boost
URL "${BOOST_PATH}"
)
上面URL只有一个本地路径,但根据文档,自从3.7版本,URL可以提供多个url。如果提供了多个url,会依次尝试,直到其中一个成功。
因为我目前网络不方便,就不放多url的案例了。
URL_MD5
顾名思义,用于校验压缩包的MD5值。
include(ExternalProject)
SET(DOWNLOAD_DIR "/root/downloads")
SET(BOOST_PATH ${DOWNLOAD_DIR}/boost_1_78_0.tar.gz)
SET(BOOST_MD5 c2f6428ac52b0e5a3c9b2e1d8cc832b5)
ExternalProject_Add(boost
URL "${BOOST_PATH}"
URL_MD5 "${BOOST_MD5}"
)
如果压缩包和指定md5值不匹配,则会报错。
安装路径
PREFIX
用于配置下载、解压、安装等路径。
PREFIX相当于配置了整体的根目录,其他的路径会基于PREFIX自动适配。
当然其他路径也可以按需自由配置。
BUILD_IN_SOURCE
如PREFIX章节的截图所示,SOURCE_DIR和BINARY_DIR是不同路径的。
但是对于boost而言,首先boost不是基于CMake来构建的,其次boost的安装过程大概为:
1、bootstrap.sh
2、b2 install
在执行b2 install
的时候,会依赖之前解压至SOURCE_DIR的文件(boost-build.jam),因此希望b2
(BINARY_DIR)和解压路径(SOURCE_DIR)是同一个路径。在执行完bootstrap.sh
之后,b2
是会被放到BINARY_DIR中的,BUILD_IN_SOURCE的作用就是让BINARY_DIR等于SOURCE_DIR。
因此目前boost的安装内容为:
include(ExternalProject)
SET(DOWNLOAD_DIR "/root/downloads")
SET(BOOST_PATH ${DOWNLOAD_DIR}/boost_1_78_0.tar.gz)
SET(BOOST_MD5 c2f6428ac52b0e5a3c9b2e1d8cc832b5)
ExternalProject_Add(boost
URL "${BOOST_PATH}"
URL_MD5 "${BOOST_MD5}"
PREFIX "${CMAKE_CURRENT_BINARY_DIR}"
# 因为执行b2的时候,需要在同目录下读取boost-build.jam,因此BUILD_IN_SOURCE
BUILD_IN_SOURCE true
)
COMMAND
如一开始说的,会有configure、build、install步骤。也就对应CONFIGURE_COMMAND
、BUILD_COMMAND
、INSTALL_COMMAND
。
因为boost不依赖CMake,所以需要覆盖这三个COMMAND。
覆盖的命令也就是boost正常安装的步骤了。这里先放上完整的CMake配置:
include(ExternalProject)
SET(DOWNLOAD_DIR "/root/downloads")
SET(BOOST_PATH ${DOWNLOAD_DIR}/boost_1_78_0.tar.gz)
SET(BOOST_MD5 c2f6428ac52b0e5a3c9b2e1d8cc832b5)
SET(BOOST_CONFIGURE <SOURCE_DIR>/bootstrap.sh --prefix=<SOURCE_DIR>)
SET(BOOST_INSTALL <SOURCE_DIR>/b2 install --prefix=<BINARY_DIR>/../build)
ExternalProject_Add(boost
URL "${BOOST_PATH}"
URL_MD5 "${BOOST_MD5}"
PREFIX "${CMAKE_CURRENT_BINARY_DIR}"
# 因为执行b2的时候,需要在同目录下读取boost-build.jam,因此BUILD_IN_SOURCE
BUILD_IN_SOURCE true
CONFIGURE_COMMAND "${BOOST_CONFIGURE}"
BUILD_COMMAND ""
INSTALL_COMMAND "${BOOST_INSTALL}"
)
1、SET
里面的<SOURCE_DIR>
和<BINARY_DIR>
,是用于在ExternalProject_Add
中获取路径变量的。
2、BOOST_INSTALL
中的--preifx
指定了项目内的安装路径,而非默认安装至/usr/local中,是为了让这个第三方库不影响外部,这里可酌情修改。
3、BUILD_COMMAND
中没有需要用的命令,但为了让默认的命令失效,也需要覆盖一个空命令。
4、这个名为boost的target,在cmake
的时候是没有操作的,要在make
之后才能会执行 解压、md5判断… 等一系列操作。(这部分卡了我很久,当时一直很困惑为什么cmake
完没反应)当然这也印证了我对CMake还不够熟悉,CMake只是预处理器,真正的执行者是make
。
以上就是基于ExternalProject_Add安装boost的内容了,基于这个案例,安装了一个非CMake的第三方库,这样能接触到更多的内容,相信后面安装CMake库会更容易上手。