利用cmake打deb包
2019-11-06 22:53:07 +08 字数:1335 标签: Linux C手动打包一个deb,是一件非常复杂的事。 好在有一些工具可以代劳,只需要输入文件和metadata。 对C/C++项目来说,cmake是一个非常好用且流行的编译控制软件。 其中自带的cpack功能,专门用来打包各大平台的软件发布包,包括Debian系的deb。
本文以一个demo项目,展示了如何利用cmake自带的cpack,打包一个deb。
示例项目 ¶
这就是一个非常简单的打印示例。
唯一比helloworld
复杂的,在于多了链接的过程。
项目结构 ¶
$ tree .
.
├── CMakeLists.txt
├── build
│ └── cmake
│ └── deb.cmake
├── include
│ └── greet.h
└── src
├── cli
│ └── main.c
└── lib
└── greet.c
项目代码 ¶
一共两个源文件,一个头文件。
greet.c ¶
#include "greet.h"
void greet(char *name)
{
printf("Hello, %s!\n", name);
}
main.c ¶
#include "greet.h"
int main(int args, char **argv)
{
if (args > 1) {
greet(argv[1]);
} else {
greet("World");
}
return 0;
}
greet.h ¶
#include <stdio.h>
void greet(char *);
CMakeList.txt ¶
项目代码本身没有什么好说的,关键是编译部分。
以下CMakeList.txt
实现了上述文件,编译成一个动态链接库libgreet.so
,和一个可执行文件hello
。
cmake_minimum_required(VERSION 3.10.2)
set(CMAKE_BUILD_TYPE Release)
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${CMAKE_CURRENT_SOURCE_DIR}/build/cmake")
execute_process(
COMMAND git describe --abbrev=0
OUTPUT_VARIABLE PACKAGE_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
project(greet VERSION ${PACKAGE_VERSION})
add_library(greet SHARED "src/lib/greet.c")
include_directories(greet PUBLIC include)
add_executable(hello "src/cli/main.c")
target_link_libraries(hello greet)
install(
TARGETS greet
COMPONENT libraries
DESTINATION "lib"
)
install(
TARGETS hello
COMPONENT applications
DESTINATION "bin"
)
install(
FILES "include/greet.h"
DESTINATION "include"
COMPONENT headers
)
include(deb) # build/cmake/deb.cmake
include(CPack)
在后半部分的三个install
,是分别对动态链接库libgreet.so
、可执行文件hello
和头文件greet.h
进行了打包。
可执行文件是执行入口,由于链接了动态链接库,所以运行时依赖于libgreet.so
。
greet.h
是开发时需要的文件,安装后,用户可以在自己的C/C++项目中#include
使用。
其中,DESTINATION
如果是相对路径,其prefix默认是/usr
。
在debian:buster
镜像中执行效果如下:
# cmake .
-- The C compiler identification is GNU 8.3.0
-- The CXX compiler identification is GNU 8.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /root/demo
# make
Scanning dependencies of target greet
[ 25%] Building C object CMakeFiles/greet.dir/src/lib/greet.c.o
[ 50%] Linking C shared library libgreet.so
[ 50%] Built target greet
Scanning dependencies of target hello
[ 75%] Building C object CMakeFiles/hello.dir/src/cli/main.c.o
[100%] Linking C executable hello
[100%] Built target hello
deb.cmake ¶
单独把Debian的配置放在一个文件,是考虑后续兼容其它系统打包的需要。 (当然,目前的demo是不行的。)
set(CPACK_GENERATOR "DEB")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Yan QiDong")
set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "This is a demo package from Yan QiDong.")
set(CPACK_DEBIAN_PACKAGE_VERSION ${PACKAGE_VERSION})
set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT)
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.3.1-6), libc6 (<< 3)")
这里分别对一些比较重要的deb包metadata进行设置。
以下是执行cpack
的效果,以及运行hello
的情况:
# cpack
CPack: Create package using DEB
CPack: Install projects
CPack: - Run preinstall target for: greet
CPack: - Install project: greet
CPack: Create package
CPack: - package: /root/demo/greet_0.0.1_amd64.deb generated.
# dpkg -i greet_0.0.1_amd64.deb
(Reading database ... 21360 files and directories currently installed.)
Preparing to unpack greet_0.0.1_amd64.deb ...
Unpacking greet (0.0.1) over (0.0.1) ...
Setting up greet (0.0.1) ...
# hello
Hello, World!
# hello Yan QiDong
Hello, Yan!
# which hello
/usr/bin/hello
查看安装效果 ¶
以下查看deb包与实际安装到系统的文件。
# dpkg -c greet_0.0.1_amd64.deb
drwxr-xr-x root/root 0 2019-11-06 14:31 ./usr/
drwxr-xr-x root/root 0 2019-11-06 14:31 ./usr/bin/
-rwxr-xr-x root/root 16592 2019-11-06 14:18 ./usr/bin/hello
drwxr-xr-x root/root 0 2019-11-06 14:31 ./usr/include/
-rw-r--r-- root/root 40 2019-11-03 11:05 ./usr/include/greet.h
drwxr-xr-x root/root 0 2019-11-06 14:31 ./usr/lib/
-rw-r--r-- root/root 15984 2019-11-06 14:18 ./usr/lib/libgreet.so
# dpkg -L greet
/usr
/usr/bin
/usr/bin/hello
/usr/include
/usr/include/greet.h
/usr/lib
/usr/lib/libgreet.so
查看metadata:
# dpkg --info greet_0.0.1_amd64.deb
new Debian package, version 2.0.
size 4438 bytes: control archive=401 bytes.
222 bytes, 10 lines control
156 bytes, 3 lines md5sums
Architecture: amd64
Depends: libc6 (>= 2.3.1-6), libc6 (<< 3)
Description: This is a demo package from Yan QiDong.
Maintainer: Yan QiDong
Package: greet
Priority: optional
Section: devel
Version: 0.0.1
Installed-Size: 48
# apt show greet
Package: greet
Version: 0.0.1
Status: install ok installed
Priority: optional
Section: devel
Maintainer: Yan QiDong
Installed-Size: 49.2 kB
Depends: libc6 (>= 2.3.1-6), libc6 (<< 3)
Download-Size: unknown
APT-Manual-Installed: yes
APT-Sources: /var/lib/dpkg/status
Description: This is a demo package from Yan QiDong.
结语 ¶
cpack
打包的效果,还是值得称赞的。
最新demo版本,请查看cmake-cpack-demo。