一、下载并安装CheckInstall
- RPM安装包
目前最新的包为1.62版,CentOS 6.X的RPM安装包可以下载checkinstall-1.6.2-1.cnt6.x86_64.rpm
然后:
sudo rpm -ivh checkinstall-1.6.2-1.cnt6.x86_64.rpm
sudo ln -s /usr/lib64/checkinstall/installwatch.so /usr/lib64/installwatch.so
sudo ln -s /usr/lib64/checkinstall/checkinstallrc /etc/checkinstallrc
- 源码包
从官网下载源码checkinstall-1.6.2.tar.gz
解压:
tar xvf checkinstall-1.6.2.tar.gz
编译会报错:
installwatch.c:2942:5: 错误:与‘readlink’类型冲突
int readlink(const char *path,char *buf,size_t bufsiz) {
^
In file included from installwatch.c:41:0:
/usr/include/unistd.h:828:16: 附注:‘readlink’的上一个声明在此
extern ssize_t readlink (__const char *__restrict __path,
^
installwatch.c:3080:5: 错误:与‘scandir’类型冲突
int scandir( const char *dir,struct dirent ***namelist,
^
In file included from installwatch.c:49:0:
/usr/include/dirent.h:252:12: 附注:‘scandir’的上一个声明在此
extern int scandir (__const char *__restrict __dir,
^
installwatch.c:3692:5: 错误:与‘scandir64’类型冲突
int scandir64( const char *dir,struct dirent64 ***namelist,
^
In file included from installwatch.c:49:0:
/usr/include/dirent.h:275:12: 附注:‘scandir64’的上一个声明在此
extern int scandir64 (__const char *__restrict __dir,
修改源文件installwatch.c:
101行:
static int (*true_scandir)( const char *,struct dirent ***,
int (*)(const struct dirent *),
int (*)(const void *,const void *));
改为:
static int (*true_scandir)( const char *,struct dirent ***,
int (*)(const struct dirent *),
int (*)(const struct dirent **,const struct dirent **));
121行:
static int (*true_scandir64)( const char *,struct dirent64 ***,
int (*)(const struct dirent64 *),
int (*)(const void *,const void *));
改为:
static int (*true_scandir64)( const char *,struct dirent64 ***,
int (*)(const struct dirent64 *),
int (*)(const struct dirent64 **,const struct dirent64 **));
2529行:
FILE *fopen(const char *pathname, const char *mode) {
FILE *result;
改为:
FILE *fopen(const char *pathname, const char *mode) {
FILE *result=0;
2941行:
#if (GLIBC_MINOR <= 4)
int readlink(const char *path,char *buf,size_t bufsiz) {
int result;
#else
ssize_t readlink(const char *path,char *buf,size_t bufsiz) {
ssize_t result;
#endif
改为:
#if 0
int readlink(const char *path,char *buf,size_t bufsiz) {
int result;
#else
ssize_t readlink(const char *path,char *buf,size_t bufsiz) {
ssize_t result;
#endif
3080行:
int scandir( const char *dir,struct dirent ***namelist,
int (*select)(const struct dirent *),
int (*compar)(const void *,const void *) ) {
改为:
int scandir( const char *dir,struct dirent ***namelist,
int (*select)(const struct dirent *),
int (*compar)(const struct dirent **,const struct dirent **) ) {
3692行:
int scandir64( const char *dir,struct dirent64 ***namelist,
int (*select)(const struct dirent64 *),
int (*compar)(const void *,const void *) ) {
改为:
int scandir64( const char *dir,struct dirent64 ***namelist,
int (*select)(const struct dirent64 *),
int (*compar)(const struct dirent64 **,const struct dirent64 **) ) {
来一个直观的修改对比:
修改完成后再重新编译。
二、使用CheckInstall
这里使用的CheckInstall的RPM安装包进行安装的。
在使用checkinstall之前需要做一点小修改,以免在执行的过程中报错:
error: File not found: /root/rpmbuild/BUILDROOT/
编辑/usr/bin/checkinstall
sudo vim /usr/bin/checkinstall
搜索关键词-bb,笔者的是在2451行,将:
$RPMBUILD -bb ${RPM_TARGET_FLAG}${ARCHITECTURE} "$SPEC_PATH" &> ${TMP_DIR}/rpmbuild.log
改为:
$RPMBUILD -bb ${RPM_TARGET_FLAG}${ARCHITECTURE} --buildroot=$BUILD_DIR "$SPEC_PATH" &> ${TMP_DIR}/rpmbuild.log
下面以制作GCC 9.2的安装包为例,在make完成后,使用checkinstall:
sudo checkinstall
中途可能会出现:
======================== Installation successful ==========================
Copying files to the temporary directory...OK
Stripping ELF binaries...OK
Compressing man pages...OK
Building file list...OK
/root/rpmbuild has no SOURCES directory. Please write the path to
the RPM source directory tree:
可以安装rpmdevtools:
sudo yum install rpm-build -y
sudo yum install rpmdevtools -y
sudo rpmdev-setuptree
可以看到/root/rpmbuild目录了
再重新执行前面的checkinstall命令,可以看到成功生成RPM安装包,路径在/root/rpmbuild/RPMS/x86_64目录中,并且已经执行了一次RPM安装包的安装,通过
rpm -qa | grep gcc
可以看到,如图所示。
从上图中可以看到
Install RPM package... OK
以及
Writing backup package... OK
即会自动安装RPM包以及备份,同时生成的安装包默认是在/root/rpmbuild/RPMS/目录,我们可以在执行sudo checkinstall的时候添加参数改变这些行为,改为:
sudo checkinstall --install=no --backup=no --pakdir=.
这样就会在将生成的RPM包放在当前目录,并且不会在制作RPM完成后自动安装和备份。
每次都这样写岂不是很麻烦,修改/usr/lib64/checkinstall/checkinstallrc中的内容即可:
PAK_DIR="."
BACKUP=0
INSTALL=0
本文所用系统为Centos 6.10