Jenkins构建deb包遇到的错误
背景:
最近公司在部署Jenkins,需要我们把公司项目使用的内部包和常用的外部包进行构建打包成deb文件上传到内部apt源中,在构建打包过程,遇到了一些问题,记录如下, 其中构建的节点服务器系统为:16.04.1-Ubuntu
打包:
打包命令很简单,一般是两步:
echo "s" | sudo dh_make --packagename "$JOB_BASE_NAME"_"$TAG" -n sudo dpkg-buildpackage -d
注意事项:dh_make 安装的时候的名字是dh-make(apt install dh-make)
1.第一条命令:
- echo "s" 输入dh_make的提示参数,s表示这个包的类型是single binary,
- 可供选择的有single binary,indep binary, multiple binary, library, kernel module, kernel patch。分别对应:[s/i/m/l/k/n]
- --packagename 后接包名,其中
- $JOB_BASE_NAME是Jenkins自带的可用参数,表示本次构建的项目名(所以我们一般把项目名与软件包的名字设置为一样)。
- $TAG是我们设置的git参数,表示构建的git标签。这个参数可以让我们在更新版本构建时,选择对应的版本即可。
- -n, --native the program is Debian native, don't generate .orig
- 更多参数可以使用dh_make --help命令查看
- 这条命令执行结束后,会生成debian目录,里面有两个重要的文件:rules和control
- rules相当于一个makefile文件,是我们第二条命令执行的逻辑。
- control定义了我们包的版本、描述以及编译和运行依赖信息。
2.第二条命令
- 这条命令时正常的打包命令,执行结束后会在上一层目录中生成deb文件(还有包括.tar.gz的源码文件)。
- 打包好的deb文件可以使用 dpkg -c xxx.deb 来查看这个这个包的内容来判断是否正确完整,完整的包应该包括.so和.a以及.pc文件。
3.上传到apt源服务器
执行完上述命令,拿到deb包后就只用把其上传到apt源服务器更新索引文件即可, 选择构建的Send files or execute commands over SSH
遇到的错误
错误1:dpkg-shlibdeps: error: no dependency information found for /usr/lib/x86_64-linux-gnu/libprotoc.so.10 (used by debian/protobuf-c/usr/bin/protoc-gen-c)
原因:
dpkg-shlibdeps是一种工具,它通过动态链接的方式找出新包所依赖的所有包。它通过检查所有新的二进制文件,查看它们链接到哪些库,
以及使用了哪些来自这些库的符号,然后检查dpkg数据库,查看哪些包拥有这些库,并找到所需的最低包版本来提供所需的符号。
在上面的例子中,它会看到我们本次的应用程序链接到libprotoc.so。所以它检查哪些包拥有这个库。哦,但没有找到这个库。这就是错误的来源。
解决方法:忽略检查,在debian/rules中添加
override_dh_shlibdeps: dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info
注意:第一行前不能有空格,第二行要用前用的是tab
错误2:
如果该包的编译是cmake && make形式
%:
dh $@ --buildsystem=cmake
如果该包的编译是./configure && make && make install形式
%:
./autogen.sh dh $@ --with autotools-dev
错误3:dh_usrlocal: XXX is not a directory
原因:因为我们把包的文件放到了/usr/local/下,但通常不应该将文件放在那里,解决方法是将文件迁移或跳过这个检查:
override_dh_usrlocal:
# Do nothing
错误4:因为我们打包的时候会检查测试,这个过程很容易出错,除了一一将检查项解决,还就是去掉这个检查,不建议这么做,在此提供一个方案:
override_dh_auto_test:
dh_auto_test --no-act