Centos使用checkinstall制作RPM包的方法

作者:简简单单 2014-05-06

一、checkinstall的安装
目前最新版本是1.6.2,可以按下面的方式下载安装。

 代码如下 复制代码
wget http://asic-linux.com.mx/~izto/checkinstall/files/source/checkinstall-1.6.2.tar.gz
tar  zxvf checkinstall-1.6.2.tar.gz
cd checkinstall-1.6.2
make  && make install

不过我在centos6.5 X64上安装时,并不像上面写的那么简单就可以使用,在安装过程中可能会遇到如下的问题,需要解决。

问题1、make时msgfmt报错

报错内容为:

/bin/sh: line 5: msgfmt: command not found
make: *** [all] Error 1
这里可以通过安装gettext包解决:

 代码如下 复制代码
[root@localhost ~]# rpm -qf /usr/bin/msgfmt
gettext-0.17-16.el6.x86_64

问题2、make时installwatch报错

报错内容如下:

 代码如下 复制代码
[root@localhost checkinstall-1.6.2]# make
for file in locale/checkinstall-*.po ; do
                case ${file} in
                        locale/checkinstall-template.po)  ;;
                        *)
                                out=`echo $file | sed -s 's/po/mo/'` ;
                                msgfmt -o ${out} ${file} ;
                                if [ $? != 0 ] ; then
                                        exit 1 ;
                                fi ;
                        ;;
                esac ;
        done
make -C installwatch
make[1]: Entering directory `/usr/local/src/checkinstall-1.6.2/installwatch'
gcc -Wall -c -D_GNU_SOURCE -DPIC -fPIC -D_REENTRANT -DVERSION="0.7.0beta7" installwatch.c
installwatch.c:2942: error: conflicting types for ‘readlink’
/usr/include/unistd.h:828: note: previous declaration of ‘readlink’ was here
installwatch.c:3080: error: conflicting types for ‘scandir’
/usr/include/dirent.h:252: note: previous declaration of ‘scandir’ was here
make[1]: *** [installwatch.o] Error 1
make[1]: Leaving directory `/usr/local/src/checkinstall-1.6.2/installwatch'
make: *** [all] Error 2

出现该错误需要修改installwatch/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 **));
将2941行修改:

#if (GLIBC_MINOR <= 4)
改为
#if (0)
将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 **) ) {

完成后再进行make即可。

在ubuntu上安装时,由于可以直接使用apt进行安装,所以没有遇到上面所说的问题,在centos上遇到的问题参考了:http://www.patrickmin.com/linux/tip.php?name=checkinstall_fedora_13

问题3、rpmbuild报错

前面两个问题解决完成后,checkinstall看起来已经正常,不过在使用过程中还会遇到如下的报错。

/root/rpmbuild has no SOURCES directory. Please write the path to
the RPM source directory tree:
出现该问题的原因,是因为checkinstall还是需要rpmbuild做底层支撑,如果没有安装rpmbuild时,会出现上面的报错。解决方法如下:

 代码如下 复制代码
yum install gcc rpm-build pcre-devel rpmdevtools

安装完成后,需要再运行rpmdev-setuptree命令创建目录查看,具体如下:

#rpmdev-setuptree
#cd /root
#tree -L 1 rpmbuild/
rpmbuild/
├── BUILD
├── RPMS
├── SOURCES
├── SPECS
└── SRPMS
问题4、ld.so报错

该出错是出现在x64系统下的,x86系统下没有该问题。此处的报错也是在checkinstall生成rpm包的过程中,报错内容为:

ERROR: ld.so: object '/usr/local/lib64/installwatch.so' from LD_PRELOAD cannot be preloaded: ignored.
解决方法如下:

[root@localhost ~]# echo "/usr/local/lib64" >/etc/ld.so.conf.d/installwatch.conf
[root@localhost ~]# ln -s /usr/local/lib/installwatch.so /usr/local/lib64/installwatch.so
[root@localhost ~]# ldconfig
二、checkinstall制作rpm包
这里以tengine为例,制作一个tengine的rpm包,具体步骤如下:

 代码如下 复制代码
[root@localhost src]tar zxvf tengine-2.0.1.tar.gz
[root@localhost src]cd tengine-2.0.1
[root@localhost tengine-2.0.1]# ./configure --prefix=/usr/local --sbin-path=/usr/sbin/nginx
--conf-path=/etc/nginx/nginx.conf
--error-log-path=/var/log/nginx/error.log
--http-log-path=/var/log/nginx/access.log
--pid-path=/var/run/nginx.pid
--lock-path=/var/run/nginx.lock
--user=nginx --group=nginx
--with-http_ssl_module --with-http_flv_module
--with-http_stub_status_module
--with-http_gzip_static_module
--http-client-body-temp-path=/var/cache/nginx/client_temp
--http-proxy-temp-path=/var/cache/nginx/proxy_temp
--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp
--http-scgi-temp-path=/var/cache/nginx/scgi_temp
--with-pcre --with-http_realip_module
--with-http_addition_module
--with-http_sub_module --with-http_dav_module
--with-http_mp4_module --with-http_random_index_module
--with-http_secure_link_module --with-file-aio --with-http_upstream_check_module
--with-http_limit_conn_module=shared
--with-http_limit_req_module=shared
[root@localhost tengine-2.0.1]#make
[root@localhost tengine-2.0.1]# checkinstall
checkinstall 1.6.2, Copyright 2009 Felipe Eduardo Sanchez Diaz Duran
           This software is released under the GNU GPL.
The package documentation directory ./doc-pak does not exist.
Should I create a default set of package docs?  [y]: y
Preparing package documentation...OK
Please choose the packaging method you want to use.
Slackware [S], RPM [R] or Debian [D]? R
Please write a description for the package.
End your description with an empty line or EOF.
>> tengine for 361way.com order by yang
>>
**************************************
**** RPM package creation selected ***
**************************************
This package will be built according to these values:
1 -  Summary: [ tengine for 361way.com order by yang ]
2 -  Name:    [ tengine ]
3 -  Version: [ 2.0.1 ]
4 -  Release: [ 1 ]
5 -  License: [ GPL ]
6 -  Group:   [ Applications/System ]
7 -  Architecture: [ x86_64 ]
8 -  Source location: [ tengine-2.0.1 ]
9 -  Alternate source location: [  ]
10 - Requires: [  ]
11 - Provides: [ tengine ]
Enter a number to change any of them or press ENTER to continue:
Installing with make install...
========================= Installation results ===========================
make -f objs/Makefile install
make[1]: Entering directory `/usr/local/src/tengine-2.0.1'
test -d '/usr/local' || mkdir -p '/usr/local'
……………………………………………………省略
**********************************************************************
 Done. The new package has been saved to
 /root/rpmbuild/RPMS/x86_64/tengine-2.0.1-1.x86_64.rpm
 You can install it in your system anytime using:
      rpm -i tengine-2.0.1-1.x86_64.rpm
**********************************************************************

完成后就可以取刚刚生成的rpm包到相同系统的主机上安装使用,安装前也可以通过以下命令查看详细的rpm包信息:

 代码如下 复制代码
[root@kvm ~]# rpm -qpi tengine-2.0.1-1.x86_64.rpm
Name        : tengine                      Relocations: (not relocatable)
Version     : 2.0.1                             Vendor: (none)
Release     : 1                             Build Date: Tue 06 May 2014 10:39:02 AM CST
Install Date: (not installed)               Build Host: localhost
Group       : Applications/System           Source RPM: tengine-2.0.1-1.src.rpm
Size        : 2345906                          License: GPL
Signature   : (none)
Packager    : checkinstall-1.6.2
Summary     : tengine for 361way.com order by yang
Description :
tengine for 361way.com order by yang

注:此时的rpm包在其他主机上通过rpm -i 安装使用时可能会遇到错误,因为在编译的时候我们自定义了很多参数。例出上面的tengine rpm 在使用时就会报错如下:

#nginx
nginx: [emerg] getpwnam("nginx") failed
报错原因很简单,因为我们编译的时候使用了--user=nginx --group=nginx 参数,而在新的主机上因为不存在该用户所以会报错 。如果想完会解决此类问题,可以在编译前修改下install文件或make文件,将新建用户,新建一些自定义目录都添加下,再编译生成rpm包就OK了。

相关文章

精彩推荐