C++编译之(4)-进阶-cmake设置install及package配置

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/binusr/local/bin -
静态库*.a usr/libusr/local/lib -
动态库(*.so) usr/libusr/local/lib -
头文件(*.h) usr/includeusr/local/include -

install命令允许我们可以根据文件类型自动地分别指向不同的路径,通过给定RUNTIMELIBRARYARCHIVE,如下所示:

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的所有基本介绍!

猜你喜欢

转载自blog.csdn.net/youlinhuanyan/article/details/128762052