使用CheckInstall從原始碼製作RPM安裝包

witton發表於2020-10-29

一、下載並安裝CheckInstall

  1. 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
  1. 原始碼包
    從官網下載原始碼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 rpmdevtools
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

可以在執行sudo checkinstall的時候新增引數不執行這兩個操作,改為:

sudo checkinstall --install=no --backup=no

這樣就不會在製作RPM完成後自動安裝和備份。

PS:本文所用系統為Centos 6.10

相關文章