C++编译之(4)-进阶-cmake设置install及package配置
引言
上一节我们介绍到了如何使用cmake快速构建项目,实现c/c++的构建自动化;那么项目构建完成后往往需要安装
或者打包发布
这一节,我们将介绍,如何用cmake实现安装及打包
相关系列文章内容:
C++编译之(1)-g++单/多文件/库的编译及
C++编译之(2)-make及makefile编译过程
C++编译之(3)-camke/CMakeLists.txt的编译使用
一、cmake设置install安装参数
install的本质核心就是文件拷贝以,此外还有些需要添加或配置环境变量。而我们常用的源码编译后的安装命令是make install
,其实这个命令又回到了前两节课的Makefile
的制作上,make install
中的install
本质就是Makefile
定义的一个目标名称或者就是一个构建标签。这个install
标签下包含一系列的安装指令(其实主要就是文件拷贝shell
指令)
1、基本的安装配置命令
cmake设置install主要是在CMakeLists.txt配置install命令
set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}/install/rknn_yolov5_demo)
install(DIRECTORY model DESTINATION ./)
首先安装最重要的就是安装路径的设置CMakeLists.txt通过设置CMAKE_INSTALL_PREFIX
定义统一的安装前缀;而具体安装的相对路径则是通过安装指令CMakeLists.txt中的安装指令install中的DESTINATION 关键字。如下所示
# 设置统一安装路径前缀
set(CMAKE_INSTALL_PREFIX /usr/local)
# 定义安装对象及安装路径
install(TARGETS mainPro DESTINATION testPro/bin)
上面的目标文件main
安装最终路径为${cmake_install_prefix}/<destination定义的路径>
即/usr/local/testPro/bin
目录下
通常我们会把可执行文件、静态库、动态库会分别放在不同的路径,如下:
文件类型 | 路径 | 备注 |
---|---|---|
可执行文件 | usr/bin 、usr/local/bin |
- |
静态库*.a | usr/lib 、usr/local/lib |
- |
动态库(*.so) | usr/lib 、usr/local/lib |
- |
头文件(*.h) | usr/include 、usr/local/include |
- |
install命令允许我们可以根据文件类型自动地分别指向不同的路径,通过给定RUNTIME
、LIBRARY
、ARCHIVE
,如下所示:
install(TARGETS exec_cmd static_lib shared_lib
RUNTIME DESTINATION bin # 可执行文件的目标路径
LIBRARY DESTINATION lib # 共享库的目标路径
ARCHIVE DESTINATION lib # 静态库的目标路径
)
而对于头文件,我们通常指定一个安装一整个目录到指定的路径中,如下所示:
install(DIRECTORY "${PROJECT_SOURCE_DIR}/include/"
DESTINATION ./include/testPro)
2、安装文件
有时,我们需要安装一些特定的非编译的文件(如:某些预定的数据文件),这时我们可以采用下面的命令
install(FILES my.sql DESTINATION ./testPro/db)
3、自定义安装脚本配置
当然,有时我们需要更加自定义的安装,这时,我们可以采用自定义安装脚本命令
install(SCRIPT ${PROJECT_SOURCE_DIR}/testProInstall.sh)
4、如何执行安装?
完成CMakeLists.txt的安装配置编写后,我们还是一样,首先执行cmake构建出Makefile,然后执行make构建项目,最后执行我们经常看到的安装指令make install
# 创建临时构建目录 build
mkdir build
cd build
# 构建Makefile
cmake ..
# 编译
make
# 安装
make install
当然,如果你需要的话,还可以在使用cmake
命令构建Makefile文件时,修改这个覆盖上面的安装路径,使新生成的Makefile设置的安装路径是你需要的安装路径
cmake -DCMAKE_INSTALL_PREFIX="../install" ..
当然,我们这里假设你不打算修改直接修改原始的
CMakeLists.txt
文件中的CMAKE_INSTALL_PREFIX
变量
或者你已经执行了cmake ..
,而且执行了make
构建命令,还有没办法修改安装路径呢(比较我们都是控制狂,总是想稍微多控制一点点)。我们可以在执行make install
时,增加参数,如下所示
make install prefix=/your/dir
完整的实战练习
首先看看上一节的目录解构
- mutilFilesDemo
- include // 头文件目录
- HelloTools.h
- Prints.h
- libs // 库子项目目录
- ToolLibs.h
- ToolLibs.cpp
- CMakeLists.txt // 子项目CMakeLists.txt
- src // 源码目录
- module // 源码模块
- Prints.cpp // Prints类
- HelloTools.cpp // HelloTools类
- main.cpp // main类
- CMakeLists.txt // 主项目CMakeLists
接着我们看看主项目的CMakeLists.txt
cmake_minimum_required(VERSION 3.4.1)
# 项目名称
project(mainPro)
# 设置子项目目录变量-libs
set(SUB_PROJ_LIBS_DIR libs)
# 设置主项目依赖的库名变量-libToolLibs.a
set(MAIN_LIBS ToolLibs)
# 添加子项目
add_subdirectory(${
SUB_PROJ_LIBS_DIR})
# 搜索主项目源码
file(GLOB SRC_LIST "*.cpp" "src/*.cpp" "src/modules/*.cpp")
# 生成可执行目标
add_executable(${
PROJECT_NAME} ${
SRC_LIST})
# 添加库目录
link_directories(${
PROJECT_NAME} ${
SUB_PROJ_LIBS_DIR})
# 添加链接库
target_link_libraries(${
PROJECT_NAME} ${
MAIN_LIBS})
# 设置统一安装路径前缀
set(CMAKE_INSTALL_PREFIX /usr/local)
# 定义安装对象及目标安装路径
install(TARGETS ${
PROJECT_NAME} DESTINATION ./bin)
上面的CMakeLists.txt我们实际上,只添加了最后两行代码,我们执行测试一下;测试前,先删除原来build目录中的所有文件(如果有)
$ cd build
$ cmake ..
$ make
$ make install
[ 33%] Built target ToolLibs
[100%] Built target mainPro
Install the project...
-- Install configuration: ""
-- Installing: /usr/local/bin/./mainPro
安装成功,我查看一下/usr/local/bin目录下,是否存在我们的可执行文件mainPro
如果安装成功,可直接执行运行命令行mainPro
$ mainPro
Hello world!
MAX_NUM+n:110
=================================
使用静态库-add(a,b)
结果为:a+b=500
二、cmake设置package打包安装参数
作为生产用的工程项目,我们往往需要在编译构建完成后,打包项目,而不是安装项目;尤其是在自动构建环境下构建项目,安装是没有意义; 因此我们需要的做的是将构建好的资源,打包成deb包(Ubuntu下)
如何通过cmake设置打包指令呢?通过CPack
.
CPack 是 CMake 2.4.2 之后的一个内置工具,用于创建软件的二进制包和源代码包。需要使用这个工具我们需要在CMakeLists.txt
中,添加包含指令include(CPack)
,并设置一些包需要用的变量即可,
#说明要生成的是deb包
SET(CPACK_GENERATOR "DEB")
#设置版本
set(CPACK_PACKAGE_VERSION "1.0.0")
# 还可用通过设置每个版本字段号设置版本
#设置版本信息如下
#SET(CPACK_PACKAGE_VERSION_MAJOR "1")
#SET(CPACK_PACKAGE_VERSION_MINOR "0")
#SET(CPACK_PACKAGE_VERSION_PATCH "0")
#设置安装包的包名,打好的包将会是<packagename>-<version>-<sys>.deb,如果不设置,默认是工程名
set(CPACK_PACKAGE_NAME "mainPro")
#设置程序名,就是程序安装后的名字
set(CPACK_DEBIAN_PACKAGE_NAME "bulbasaur")
#设置架构
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64")
#设置依赖
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.3.1-6)")
#设置description
SET(CPACK_PACKAGE_DESCRIPTION "pro-cc service")
#设置联系方式
SET(CPACK_PACKAGE_CONTACT "[email protected]")
#设置维护人
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "mx.bing")
# 包含Cpack
include(CPack)
常用的deb变量列表如下:
变量名 | 功能 | 说明 |
---|---|---|
CPACK_GENERATOR | 生成的包类型 | "DEB"为deb包 |
CPACK_PACKAGE_NAME | 包名字 | --linux.deb |
CPACK_PACKAGE_FILE_NAME | 包名 | 默认:<CPACK_PACKAGE_NAME>-<CPACK_PACKAGE_VERSION>-<CPACK_SYSTEM_NAME>.deb |
CPACK_DEBIAN_PACKAGE_VERSION | 包版本 | 1.0.0 |
CPACK_DEBIAN_PACKAGE_ARCHITECTURE | 架构 | “amd64” |
CPACK_DEBIAN_PACKAGE_DEPENDS | 包依赖设置 | 如:libc6 (>= 2.3.1-6) |
CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA | 设置包的安装脚本文件路径 | 只能是 四种脚本:preinst(安装前执行), postinst(安装后执行), prerm(删除前执行), postrm(删除后执行) |
CPACK_DEBIAN_PACKAGE_SECTION | 软件类别 | utils, net, mail, text, x11 |
CPACK_DEBIAN_PACKAGE_MAINTAINER | 维护人 | - |
CPACK_PACKAGE_DESCRIPTION_SUMMARY | 包简介 | - |
CPACK_PACKAGE_DESCRIPTION | 包描述 | - |
CPACK_PACKAGE_CONTACT | 联系方式 | - |
CPACK_OUTPUT_FILE_PREFIX | 输出的deb包路径 | 默认在Makefile目录 |
CPACK_INSTALL_PREFIX | 安装路径前缀 | 默认为空 |
注意:使用CPack打包,必须要设置install指令,而打包的内容即为install设置的安装的内容
我们还是以前面的目录结构为例,使用主项目的CMakeLists.txt
继续介绍;
cmake_minimum_required(VERSION 3.4.1)
# 项目名称
project(mainPro)
# 设置子项目目录变量-libs
set(SUB_PROJ_LIBS_DIR libs)
# 设置主项目依赖的库名变量-libToolLibs.a
set(MAIN_LIBS ToolLibs)
# 添加子项目
add_subdirectory(${SUB_PROJ_LIBS_DIR})
# 搜索主项目源码
file(GLOB SRC_LIST "*.cpp" "src/*.cpp" "src/modules/*.cpp")
# 生成可执行目标
add_executable(${PROJECT_NAME} ${SRC_LIST})
# 添加库目录
link_directories(${PROJECT_NAME} ${SUB_PROJ_LIBS_DIR})
# 添加链接库
target_link_libraries(${PROJECT_NAME} ${MAIN_LIBS})
# =====================安装指令=======================================
# 设置统一安装路径前缀
set(CMAKE_INSTALL_PREFIX /usr/local)
# 定义安装对象及目标安装路径
install(TARGETS ${PROJECT_NAME} DESTINATION ./bin)
# ======================deb打包配置===================================
SET(CPACK_GENERATOR "DEB")
#设置架构
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64")
#设置程序名,就是程序安装后的名字
set(CPACK_DEBIAN_PACKAGE_NAME "mainPro-beta")
#设置安装包的包名,打好的包将会是<packagename>-<version>-<sys>.deb,如果不设置,默认是工程名
set(CPACK_PACKAGE_NAME "mainPro")
#设置版本号
set(CPACK_PACKAGE_VERSION "1.0.0")
#系统名
set(CPACK_SYSTEM_NAME "Linux_amd64")
#设置description
SET(CPACK_PACKAGE_DESCRIPTION "这是一个mainPro 项目包")
#设置联系方式
SET(CPACK_PACKAGE_CONTACT "[email protected]")
#设置维护人
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "mx.bing")
#设置包的安装脚本
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_SOURCE_DIR}/DEBIAN/postinst;${CMAKE_SOURCE_DIR}/DEBIAN/postrm;")
# 注意,这条指令一般需要放在设置CPack指令之后
include(CPack)
我们测试一下
cd build
cmake ..
make
make package
[ 33%] Built target ToolLibs
[100%] Built target mainPro
Run CPack packaging tool...
CPack: Create package using DEB
CPack: Install projects
CPack: - Run preinstall target for: mainPro
CPack: - Install project: mainPro []
CPack: Create package
-- CPACK_DEBIAN_PACKAGE_DEPENDS not set, the package will have no dependencies.
CPack: - package: /home/mutilFilesDemo/build/mainPro-1.0.0-Linux_amd64.deb generated.
成功生成deb包
我们用pkdg查看一下deb包的基本信息
$ dpkg --info mainPro-1.0.0-Linux_amd64.deb
new Debian package, version 2.0.
size 5260 bytes: control archive=341 bytes.
201 bytes, 10 lines control
50 bytes, 1 lines md5sums
Architecture: amd64
Description: mainPro built using CMake
这是一个mainPro 项目包
Maintainer: mx.bing
Package: mainpro-beta
Priority: optional
Section: devel
Version: 1.0.0
Installed-Size: 27
我们还可以看看deb包将要安装的路径所在
$ dpkg-deb -c mainPro-1.0.0-Linux_amd64.deb
drwxrwxr-x root/root 0 2023-01-26 00:52 ./usr/
drwxrwxr-x root/root 0 2023-01-26 00:52 ./usr/bin/
-rwxr-xr-x root/root 18816 2023-01-26 00:34 ./usr/bin/mainPro
与我们前面设置的install路径一样
最后分享一些dpkg相关常用命令
命令格式 | deb安装状态 | 功能介绍 |
---|---|---|
dpkg -i <package.deb> | 未安装 | 默认安装deb包 |
dpkg -i --instdir=<path/to/you/dir> <package.deb> | 未安装 | 指定安装路径安装deb包 |
dpkg --force-depends -i <package.deb> | 未安装 | 强制安装deb包 |
dpkg --info <package.deb> | 未安装 | 查看deb包信息 |
dpkg-deb -c <package.deb> | 未安装 | 查看安装路径 |
dpkg -x <package.deb> <dist/dir> | 未安装 | 解压包到指定路径 |
dpkg -e <package.deb> <dist/dir/DEBIAN> | 未安装 | 提取deb包中的control文件 |
dpkg -r | 安装后 | 删除包,保留配置文件 |
dpkg -r | 安装后 | 彻底删除(含配置文件) |
dpkg -s | 安装后 | 查看包的状态 |
dpkg -L | 安装后 | 查看安装后的路径所在 |
至此,我们完成整个cmake的所有基本介绍!