make编译安装
本节内容来源鸟哥私房菜,第二十二章、软件安装:原始码与 Tarball,有兴趣朋友建议看原版。
gcc相关知识
先编写一个C文件,其第一行表示包含文件在/usr/include/stdio.h下,如果没有申明,则需要使用参数-I /usr/include指定。
1 | [root@home ~]#cat sin.c |
gcc sin.c全产生a.out运行文件,加上参数-c则生成二进制文件sin.o,再加上-o则生成运行档sin。
但是如果出现以下错误,这是因为 C 语言里面的 sin 函示是写在 libm.so 这个函式库中,而我们并没有在原始码里面将这个函式库功能加进去,可以使用以下命令gcc -c sin.c -lm -L /lib/64 -L /usr/lib64
gcc -O 为产生最佳化的参数
gcc -Wall 为产生更详细的编译过程资讯
-l :是『加入某个函式库(library)』的意思,
- m :则是 libm.so 这个函式库,其中, lib 与扩展名(.a 或 .so)不需要写
- -I /path 后面接的路径( Path )就是配置要去搜寻相关的 include 文件的目录啦
- -L 后面接的路径表示函式库 libm.so 请到 /lib 或 /usr/lib 里面搜寻
总结:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 仅将原始码编译成为目标档,并不制作连结等功能:
[root@www ~]# gcc -c hello.c
会自动的产生 hello.o 这个文件,但是并不会产生 binary 运行档。
在编译的时候,依据作业环境给予最佳化运行速度
[root@www ~]# gcc -O hello.c -c
会自动的产生 hello.o 这个文件,并且进行最佳化喔!
在进行 binary file 制作时,将连结的函式库与相关的路径填入
[root@www ~]# gcc sin.c -lm -L/usr/lib -I /usr/include
这个命令较常下达在最终连结成 binary file 的时候,
-lm 指的是 libm.so 或 libm.a 这个函式库文件;
-L 后面接的路径是刚刚上面那个函式库的搜寻目录;
-I 后面接的是原始码内的 include 文件之所在目录。
将编译的结果输出成某个特定档名
[root@www ~]# gcc -o hello hello.c
-o 后面接的是要输出的 binary file 档名
在编译的时候,输出较多的信息说明
[root@www ~]# gcc -o hello hello.c -Wall
加入 -Wall 之后,程序的编译会变的较为严谨一点,
所以警告信息也会显示出来!
另外,我们通常称 -Wall 或者 -O 这些非必要的参数为旗标 (FLAGS),因为我们使用的是 C 程序语言,所以有时候也会简称这些旗标为 CFLAGS。
makefile介绍
实例
首先,下载wget http://linux.vbird.org/linux_basic/0520source/main.tgz然后开始编译:
1 | [root@localhost main]# cat makefile |
makefile 的基本语法与变量
make 会主动的去判断每个目标档相关的原始码文件,并直接予以编译,最后再直接进行连结的动作。
- 在 makefile 当中的 # 代表注解;
需要在命令行 (例如 gcc 这个编译器命令) 的第一个字节; - 标的 (target) 与相依文件(就是目标档)之间需以『:』隔开。就是可执行程序的文件名。
1
2标的(target): 目标档1 目标档2
gcc -o 欲创建的运行档 目标档1 目标档2
如下,makefile 里面就具有至少两个标的,分别是 main 与 clean ,如果我们想要创建 main 的话,输入『make main』,如果想要清除有的没的,输入『make clean』即可!而如果想要先清除目标档再编译 main 这个程序的话,就可以这样输入:『make clean main』
还可以进行简化,使用变量来减少程序的修改量。$@:代表目前的标的(target);gcc 在进行编译的行为时,会主动的去读取 CFLAGS 这个环境变量,可以写到makefile1
2
3
4
5
6
7
8[root@www ~]# cat makefile
LIBS = -lm
OBJS = main.o haha.o sin_value.o cos_value.o
CFLAGS = -Wall
main: ${OBJS}
gcc -o $@ ${OBJS} ${LIBS}
clean:
rm -f $@ ${OBJS}
由於 gcc 在进行编译的行为时,会主动的去读取 CFLAGS 这个环境变量,所以,你可以直接在 shell 定义出这个环境变量,也可以在 makefile 文件里面去定义:1
2[root@www ~]# CFLAGS="-Wall" make clean main
这个动作在上 make 进行编译时,会去取用 CFLAGS 的变量内容!
make与Dockerfile相接合
此小节内容来源于 high-iowait-process 。
如有下列Makefile文件内容:
1 | .PHONY: build |
这样写好之后,就可以使用 make bulid 来生成镜像,使用 make run 来运行镜像,使用 make clean 来删除镜像。所以这看上去就有点像脚本的函数一样了。
变量的基本语法
- 变量与变量内容以『=』隔开,同时两边可以具有空格;
- 变量左边不可以有
,例如上面范例的第一行 LIBS 左边不可以是 ; - 变量与变量内容在『=』两边不能具有『:』;
- 在习惯上,变量最好是以『大写字母』为主;
- 运用变量时,以 ${变量} 或 $(变量) 使用;
- 在该 shell 的环境变量是可以被套用的,例如提到的 CFLAGS 这个变量!
- 在命令列模式也可以给予变量。
yum安装相关环境
- 如果是要安装 gcc 等软件发展工具,请使用『 yum groupinstall “Development Tools” 』
- 若待安装的软件需要图形介面支持,一般还需要『 yum groupinstall “X Software Development” 』
- 若安装的软件较旧,可能需要『 yum groupinstall “Legacy Software Development” 』
编译软件步骤
- ./configure 创建Makefile文件
- make clean 会读取 Makefile 中关於 clean 的工作,可有可无
- make make 会依据 Makefile 当中的默认工作进行编译的行为
- make install
如果未指定安装路径,则编译安装的目录是放在/usr/local/etc、/usr/local/bin、/usr/local/lib、/usr/local/man下。
rpm知识
此内容与编译无关。可以跳过,同时此内容也来自于鸟哥私房菜,是一本好本啊~
RPM 安装 (install)
1 | [root@www ~]# rpm -ivh package_name |
rpm 安装时常用的选项与参数说明
- —nodeps:当发生软件属性相依问题而无法安装,但你执意安装时
- —replacefiles:如果在安装的过程当中出现了『某个文件已经被安装在你的系统上面』的资讯,又或许出现版本不合的信息 (confilcting files) 时,可以使用这个参数来直接覆盖文件。
- —replacepkgs:重新安装某个已经安装过的软件!如果你要安装一堆 RPM 软件文件时,可以使用 rpm -ivh *.rpm ,但若某些软件已经安装过了, 此时系统会出现『某软件已安装』的资讯,导致无法继续安装。此时可使用这个选项来重复安装喔!
- —force:这个参数其实就是 —replacefiles 与 —replacepkgs 的综合体!
- —test: 想要测试一下该软件是否可以被安装到使用者的 Linux 环境当中,可找出是否有属性相依的问题。
- —justdb 使用时机: 由於 RPM 数据库破损或者是某些缘故产生错误时,可使用这个选项来升级软件在数据库内的相关资讯。
- —nosignature 使用时机: 想要略过数码签章的检查时,可以使用这个选项。
- —prefix 新路径 使用时机: 要将软件安装到其他非正规目录时。举例来说,你想要将某软件安装到 /usr/local 而非正规的 /bin, /etc 等目录, 就可以使用『 —prefix /usr/local 』来处理了。
- —noscripts 使用时机:不想让该软件在安装过程中自行运行某些系统命令。
RPM 查询 (query)
RPM 在查询的时候,其实查询的地方是在 /var/lib/rpm/ 这个目录下的数据库文件。1
2
3
4[root@www ~]# rpm -qa <==已安装软件
[root@www ~]# rpm -q[licdR] 已安装的软件名称 <==已安装软件
[root@www ~]# rpm -qf 存在於系统上面的某个档名 <==已安装软件
[root@www ~]# rpm -qp[licdR] 未安装的某个文件名称 <==查阅RPM文件
- -q :仅查询,后面接的软件名称是否有安装;
- -qa :列出所有的,已经安装在本机 Linux 系统上面的所有软件名称;
- -qi :列出该软件的详细资讯 (information),包含开发商、版本与说明等;
- -ql :列出该软件所有的文件与目录所在完整档名 (list);
- -qc :列出该软件的所有配置档 (找出在 /etc/ 底下的档名而已)
- -qd :列出该软件的所有说明档 (找出与 man 有关的文件而已)
- -qR :列出与该软件有关的相依软件所含的文件 (Required 的意思)
- -qf :由后面接的文件名称,找出该文件属於哪一个已安装的软件
- -qp[icdlR]:注意 -qp 后面接的所有参数以上面的说明一致。但用途仅在於找出某个 RPM 文件内的资讯,即未安装的名称
RPM 验证与数码签章
验证
验证 (Verify) 的功能主要在於提供系统管理员一个有用的管理机制!作用的方式是『使用 /var/lib/rpm 底下的数据库内容来比对目前 Linux 系统的环境下的所有软件文件 』也就是说,当你有数据不小心遗失, 或者是因为你误杀了某个软件的文件,或者是不小心不知道修改到某一个软件的文件内容
1 | [root@www ~]# rpm -Va |
第一列的含义有以下几种:1
2
3
4
5
6
7
8S :(file Size differs) 文件的容量大小是否被改变
M :(Mode differs) 文件的类型或文件的属性 (rwx) 是否被改变?如是否可运行等参数已被改变
5 :(MD5 sum differs) MD5 这一种指纹码的内容已经不同
D :(Device major/minor number mis-match) 装置的主/次代码已经改变
L :(readLink(2) path mis-match) Link 路径已被改变
U :(User ownership differs) 文件的所属人已被改变
G :(Group ownership differs) 文件的所属群组已被改变
T :(mTime differs) 文件的创建时间已被改变
第二列的含义有以下几种:
1 | c :配置档 (config file) |
数码签章
软件开发厂商可以数码签章系统产生一个专属於该软件的签章,并将该签章的公钥 (public key) 释出。 当你要安装一个 RPM 文件时:
首先你必须要先安装原厂释出的公钥文件;实际安装原厂的 RPM 软件时, rpm 命令会去读取 RPM 文件的签章资讯,与本机系统内的签章资讯比对,若签章相同则予以安装,若找不到相关的签章资讯时,则给予警告并且停止安装喔。
1 | [root@localhost ~]# ll /etc/pki/rpm-gpg/RPM-GPG-KEY-* |
SRPM相关知识
rpm的全称是Redhat Package Manager,SRPM是指 Source RPM 的意思,这个 RPM 文件里面含有原始码,特别注意的是,这个 SRPM 所提供的软件内容『并没有经过编译』。通常 SRPM 的扩展名是以 *.src.rpm 这种格式来命名的。srpm跟tarball的区别就是srpm提供了这个软件所需要的相依性软件说明、以及所有 RPM 文件所提供的数据。
rebuild直接安装
下载src.rpm包之后,可以在不修改配置的情况下,直接使用以下参数直接操作:
- —rebuild:这个选项会将后面的SRPM进行『编译』与『打包』的动作,最后会产生RPM的档案,但是产生的RPM档案并没有安装到系统上。当你使用—rebuild的时候,最后通常会发现一行字体:
Wrote: /root/rpmbuild/RPMS/x86_64/pkgname.x86_64.rpm这个就是编译完成的RPM档案啰!这个档案就可以用来安装啦!安装的时候请加绝对路径来安装即可 - —recompile:这个动作会直接的『编译』『打包』并且『安装』啰!请注意, rebuild 仅『编译并打包』而已,而recompile 不但进行编译跟打包,还同时进行『安装』了
示例:
1 | 先下载软体: |
SPEC编译安装
目录说明
如果你的rpm的版本<=4.4.x,那么rpmbuid工具其默认的工作路径是/usr/src/redhat,这就使得普通用户不能制作rpm包,因为权限的问题,在制作rpm软件包时必须切换到root身份才可以。所以,rpm从4.5.x版本开始,将rpmbuid的默认工作路径移动到用户家目录下的rpmbuild目录里,即$HOME/rpmbuild。
首先yum -y install rpm-build rpmdevtools,然后rpmdev-setuptree来创建工作目录,也可以不安装rpmdevtools,直接使用mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}来创建。具体的各目录的含义如下:
| 默认位置 | 宏代码 | 名称 | 用途 |
|---|---|---|---|
| ~/rpmbuild/SPECS | %_specdir | Spec 文件目录 | 保存 RPM 包配置(.spec)文件 |
| ~/rpmbuild/SOURCES | %_sourcedir | 源代码目录 | 保存源码包(如 .tar 包)和所有 patch 补丁 |
| ~/rpmbuild/BUILD | %_builddir | 构建目录 | 源码包被解压至此,并在该目录的子目录完成编译 |
| ~/rpmbuild/BUILDROOT | %_buildrootdir | 最终安装目录 | 保存 %install 阶段安装的文件 |
| ~/rpmbuild/RPMS | %_rpmdir | 标准 RPM 包目录 | 生成/保存二进制 RPM 包 |
| ~/rpmbuild/SRPMS | %_srcrpmdir | 源代码 RPM 包目录 | 生成/保存源码 RPM 包(SRPM) |
使用rpm -ivh来安装srpm包时,会生成很多文件在/root/rpmbuild下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16[root@localhost ~]# rpm -ivh ntp-4.2.6p5-19.el7.centos.1.src.rpm
Updating / installing...
1:ntp-4.2.6p5-19.el7.centos.1 ################################# [100%]
[root@localhost ~]# tree /root/rpmbuild/
/root/rpmbuild/
├── BUILD
├── BUILDROOT
├── RPMS
├── SOURCES
│ ├── ntp-4.2.4p7-getprecision.patch
│ ├── ntp-4.2.6p1-cmsgalign.patch
。。。
│ └── sntp.sysconfig
├── SPECS
│ └── ntp.spec
└── SRPMS
解压完成之后,srpm本身就提供了spec文件,可以直接通过以下方式直接安装:
1 | [root@study ~]# rpmbuild -ba ntp.spec <==编译并同时产生RPM与SRPM档案 |
spec打包流程
SPECS下是RPM包的配置文件,是RPM打包的“图纸”,这个文件会告诉rpmbuild命令如何去打包。“宏代码”这一列就可以在SPEC文件中用来代指所对应的目录,类似于编程语言中的宏或全局变量。当然~/rpmbuild这个文件夹也是有宏代码的,叫做%_topdir。
打包的过程有点像是流水线,分好几个工序:
- 首先,需要把源代码放到%_sourcedir中;
- 然后,进行编译,编译的过程是在
%_builddir(~/rpmbuild/BUILD)中完成的,所以需要先把源代码复制到这个目录下边,一般情况下,源代码是压缩包格式,那么就解压过来即可; - 第三步,进行“安装”,这里有点类似于预先组装软件包,把软件包应该包含的内容(比如二进制文件、配置文件、man文档等)复制到
%_buildrootdir(~/rpmbuild/BUILDROOT)中,并按照实际安装后的目录结构组装,比如二进制命令可能会放在/usr/bin下,那么就在%_buildrootdir下也按照同样的目录结构放置; - 然后,需要配置一些必要的工作,比如在实际安装前的准备啦,安装后的清理啦,以及在卸载前后要做的工作啦等等,这样也都是通过配置在SPEC文件中来告诉rpmbuild命令;
- 还有一步可选操作,那就是检查软件是否正常运行;
- 最后,生成的RPM包放置到%_rpmdir,源码包放置到%_srpmdir下。
spec文件内容
使用vim a.spec之后,会自动生成spec的结构体,内容如下:
1 | Name: ==>软件包的名字,后续可以用%{name}来引用 |
除了以上这些,还是以下阶段:
- %pre 在目标系统上安装软件包之前执行的Scriptlet。注意跟%prep的区别。
- %post 在目标系统上安装软件包完成之后执行的Scriptlet。
- %preun 在从目标系统卸载软件包之前执行的Scriptlet。
- %postun 从目标系统卸载软件包完成之后执行的Scriptlet。
以下介绍一下比较重要的阶段。
%prep阶段
这个阶段里主要完成对源代码包的解压和打补丁(如果有的话),而解压时最常见到的就是一句指令:%setup -q。这句指令可以成功执行的前提是你位于SOURCES目录下的源码包必须是name-version.tar.gz的格式才行,它还会完成后续阶段目录的切换和设置。如果在这个阶段你不用这条指令,那么后面每个阶段都要自己手动去改变相应的目录。
如果在%prep阶段,只使用了%setup这个宏变量,代表了会运行以下操作(假设Source为cdplayer-1.0.tgz):
1 | cd /usr/src/redhat/BUILD |
可以看到,默认操作为先进入BUILD目录,然后再删除%{name}-%{version},再解压,最后再修改权限、属主等。参数-q是指不输出运行的过程,还有其他参数如下:
1 | setup -n newdir 先删除/usr/src/redhat/BUILD/newdir目录,然后将软件包解压在newdir目录;再进行这个目录进行权限设置 |
实例,如果%prep的内容如下:
1 | prep |
其运行的过程如下:
1 | [root@localhost SPECS]# rpmbuild -bb nginx.spec |
需要注意的是,%setup -q 是指解压不输出任何提示消息,只会解压source0的文件,即第0个source文件。%setup -T -a num 先进入目录再解压第num个source文件,进入目录的意思是进入%{name}-%{version}这个目录,即spec前面定义好的Name以及Version。
https://book.huihoo.com/maximum-rpm/s1-rpm-inside-macros.html
%build阶段
这个阶段就是执行常见的configure和make操作,如果有些软件需要最先执行bootstrap之类的,可以放在configure之前来做。这个阶段我们最常见只有两条指令:
1 | %configure |
这里的%configure是个宏常量,会自动将prefix设置成/usr。另外,这个宏还可以接受额外的参数,如果某些软件有某些高级特性需要开启,可以通过给%configure宏传参数来开启。如果不用 %configure这个宏的话,就需要完全手动指定configure时的配置参数了。同样地,我们也可以给make传递额外的参数,例如: make %{?_smp_mflags} CFLAGS="" …
%install阶段
这个阶段就是执行make install操作。这个阶段会在%_buildrootdir目录里建好目录结构,然后将需要打包到rpm软件包里的文件从%_builddir里拷贝到%_buildrootdir里对应的目录里。这个阶段最常见的两条指令是:
1 | rm -rf $RPM_BUILD_ROOT |
其中$RPM_BUILD_ROOT也可以换成我们前面定义的BuildRoot变量,不过要写成%{buildroot}才可以,必须全部用小写,不然要报错。
如果软件有配置文件或者额外的启动脚本之类,就要手动用copy命令或者install命令你给将它也拷贝到%{buildroot}相应的目录里。用copy命令时如果目录不存在要手动建立,不然也会报错,所以推荐用install命令。
制作rpm软件包的阶段
这个阶段必须引出下面一个叫做%files的阶段。它主要用来说明会将%{buildroot}目录下的哪些文件和目录最终打包到rpm包里。
1 | %files |
%defattr 表示的意思是: %defattr(文件权限,用户名,组名,目录权限) ,如果不牵扯到文件、目录权限的改变则一般用%defattr(-,root,root,-)这条指令来为其设置缺省权限。
关于%files阶段有两个特性要牢记:
- %{buildroot}里的所有文件都要明确被指定是否要被打包到rpm里。什么意思呢?假如,%{buildroot}目录下有4个目录a、b、c和d,在%files里仅指定a和b要打包到rpm里,如果不把c和d用exclude声明是要报错的;
- 如果声明了%{buildroot}里不存在的文件或者目录也会报错。
代表路径的宏列表
如果您看到一个不熟悉的宏,您可以使用rpm --showrc 或者 rpm --eval %{_bindir}以下方法对其进行查看:1
2
3
4
5
6 rpm --eval %{_bindir}
/usr/bin
[root@localhost noarch]# rpm --showrc |grep buildrootdir
-14: _buildrootdir %{_topdir}/BUILDROOT
-14: buildroot %{_buildrootdir}/%{name}-%{version}-%{release}.%{_arch}
也可以直接查看/usr/lib/rpm/macros文件,以下是常见的宏:
1 | %{_sysconfdir} /etc |
要注意的是%{buildroot} 跟%{_buildrootdir}不同。%{_buildrootdir}对应的目录是~/rpmbuild/BUILDROOT;而%{buildroot}是%{_buildrootdir}/%{name}-%{version}-%{release}.%{_arch},有关其他内容可以参考 https://fedoraproject.org/wiki/Packaging:RPMMacros?rd=Packaging/RPMMacros#RPM_directory_macros
实例1:打包shell
可以把一个平时写的一个脚本打包成一个rpm包,spec文件如下:
1 | [root@localhost SPECS]# cat disk.spec |
开始编译:
1 | [root@localhost SPECS]# rpmbuild -bb disk.spec |
可以看到编译成功了,文件保存在Wrote: /root/rpmbuild/RPMS/x86_64/showdiskinfo-1.0-1.el7.x86_64.rpm下,开始查看:
1 | [root@localhost SPECS]# cd ../RPMS/x86_64/ |
此内容参考了 https://rpm-packaging-guide.github.io/#hello-world ,可以阅读原版。
实例2:打包main
此代码来源鸟哥私房菜,先来处理原始码的部份:
1 | [root@study ~]# cd /root/rpmbuild/SOURCES |
到SPECS目录下创建main.spec文件,建议使用vim创建,会自动生成格式。也可以用rpmdev-newspec -o Name-version.spec命令来生成SPEC文件的模板
1 | [root@localhost SPECS]# cat main.spec |
然后就直接编译rpmbuild -ba main.spec,再安装rpm -ivh main-0.1-1.el7.x86_64.rpm
1 | [root@localhost x86_64]# rpm -qi main |
实例3:打包hello
使用区域语言(Locale)文件的程序应遵循 处理 i18n 文件的建议方法:
- 在 %install 步骤中找出文件名: %find_lang ${name}
- 添加必要的编译依赖: BuildRequires: gettext
- 使用找到的文件名: %files -f ${name}.lang
%find_lang此宏将找到属于您的包的所有语言环境文件(按名称),并将此列表放在一个文件中。然后,您可以使用该文件包含所有语言环境。1
2
3
4[root@localhost SPECS]# rpm --eval %find_lang
/usr/lib/rpm/find-lang.sh /root/rpmbuild/BUILDROOT/%{name}-%{version}-%{release}.x86_64
[root@localhost SPECS]# rpm --eval %make_install
/usr/bin/make install DESTDIR=/root/rpmbuild/BUILDROOT/%{name}-%{version}-%{release}.x86_64
%find_lang %{name}在这个spec里面等价于/usr/lib/rpm/find-lang.sh /root/rpmbuild/BUILDROOT/hello-2.10-1.el7.x86_64 hello
而引用的方法是:%files -f %{name}.lang即可。
%make_install是等价于make install DESTDIR=%{buildroot}。
1 | [root@localhost SPECS]# cat hello.spec |
然后直接rpmbuild -bb hello.spec进行编译,此实例来源于:https://fedoraproject.org/wiki/How_to_create_a_GNU_Hello_RPM_package/zh-cn
实例4:打包smartmontools
smartmontools 7.0已经支持json格式的输出,对于采集的话,有很大的优势。目前在centos官方上面可以找到centos7的包,如https://cbs.centos.org/koji/buildinfo?buildID=25069,但是还没有centos6的,所以需要自己写一个spec。
访问https://cbs.centos.org/koji/buildinfo?buildID=25069,先下载src.rpm包,然后`rpm -ivh smartmontools-7.0-3.el7.src.rpm`就可以提取到smartmontools.spec,这个是centos7下面环境编译的,不能直接使用。需要再下载 http://yum.aclub.net/pub/linux/centos/6/umask/SRPMS/smartmontools-6.3-1.el6.src.rpm smartmontools 6.x的版本,就可以对比开工改写spec文件了。
1 | [root@7ftbv7mdz7cdpc ~]# cat smartmontools.spec |
注意,Source这几个文件一定要存在,从上可以得知,加入了启动脚本、配置文件等,准备好了之后就可以使用rpmbuild -bb smartmontools.spec来编译,经过多次失败后,根据报错信息进行调整之后,终于编译成功了。
1 | [root@7ftbv7mdz7cdpc SPECS]# rpm -qp --changelog /root/rpmbuild/RPMS/x86_64/smartmontools-7.0-3.el6.x86_64.rpm |
另外,在%preun阶段有使用了if [ "$1" = "0" ],表示的意思是uninstall,如下图:

实例5:打包nginx
用tar包打包成rpm的最简单的方法就是在网上找到相对应src.rpm的版本,这里面有包括了spec文件,可以少走很多弯路。nginx官方在释放tar包之后,也会相应提供的rpm以及srpm包,这次我们先在 http://nginx.org/packages/centos/7/SRPMS/ 下载好nginx-1.16.1-1.el7.ngx.src.rpm,使用rpm -ivh nginx-1.16.1-1.el7.ngx.src.rpm进行安装。有生成了如下内容:
1 | [root@localhost rpmbuild]# tree |
主要是SPECS以及SOURCES这些文件。查看nginx.spec之后,大部分都有写好了,并且都兼容了centos 6/7。添加了gperftools GeoIP-devel ngx_cache_purge nginx-http-concat这四个模块,修改如下:
1 | [root@localhost SPECS]# cat nginx.spec |
编译完成之后,查看changelog,是成功了。
1 | [root@localhost SPECS]# rpm --changelog -qp /root/rpmbuild/RPMS/x86_64/nginx-1.16.1-1.el7.ngx.x86_64.rpm |
fpm打包方法
使用fpm这个方式也是可以将tar打包为rpm包,其打包流程大致是这样的:
- 编译安装被打包软件,指定安装的临时目录,如指定
--prefix=/fpmbulid - 创建安装脚本、卸载脚本
- 安装FPM工具
- 使用fpm打包
具体的细节,请参考:FPM,更快捷方便的制作rpm包
参考资料
官方文档:https://rpm-packaging-guide.github.io/
RPM打包原理、示例、详解及备查 https://blog.csdn.net/get_set/article/details/53453320
RPM 包制作(详细):https://jin-yang.github.io/post/linux-create-rpm-package.html
spec文件查找:https://git.centos.org/
rpm Scriptlets变量说明: https://docs.fedoraproject.org/en-US/packaging-guidelines/Scriptlets/
spec中的 Install命令:https://www.cnblogs.com/wangziyi0513/p/10252458.html