学习rpm的打包

新公司线上业务都是基于红帽的系统, 这几天闲着, 那就先学习以下红帽系的打包吧.

有关rpm的打包的学习资料相比deb的要多很多, 因此还是蛮容易上手的. 自己根据这个hello world教程学习了一下. 下面按照自己的思路简单整理下.

准备

先准备一个小工程. 工程里面里面包含一个类似hello world的小程序和一个简单的Makefile.

fun.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>

int main(void)
{
    char *env[] = {"Y=\"() {'not';} echo 'L'\""};

    execle("/bin/bash", "bash", "-c", "echo \"it's good\"", (char *)NULL,
            env);

    printf("not good: %s\n", strerror(errno));
    return 0;
}

这个小程序是仿照之前的一个bash安全漏洞测试代码改的, 详情可以看一下陈皓大哥的这篇文章. OK, 然后是一个Makefile

Makefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
target := fun
bindir := /bin

CFLAGS := -g -Wall
LFLAGS :=

all: fun

forfun: fun.o
    gcc $^ -o $@ $(LFLAGS)

%.o: %.c
    gcc -c $< -o $@ $(CFLAGS)

.PHONY: install clean

install:
    install -p -D $(target) $(DESTDIR)/$(bindir)/$(target)

clean:
    rm -f *.o $(target)

不同于deb的打包风格, rpm一般都是直接在tar包的基础上打的, 因此我们把需要打包的程序打成一个包: fun-0.1.tar.gz(打包的目录名为fun-0.1).

接下来在某个打包用户下执行下rpmdev-setuptree. 这个指令会在该用户目录下创建一个名为rpmbuild的目录, 里面包含若干个目录, 之后的所有打包都在该目录下完成.

开始打包

既然已经有了源码包, 我们就可以开始打包了. 将对应包放到SOURCES目录下. 接下来我们仅仅需要一个spec文件即可完成打包. 这个spec文件有点类似与deb打包时的rules文件, 主要用于控制打包的各个步骤, 例如编译, 构建, 安装等. 我们使用rpmdev-newspec fun来创建一个spec文件. 具体的文件解释可以参考这个文档. 简单修改成这样:

fun.spec
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Name:           fun
Version:        0.1
Release:        1%{?dist}
Summary:        fun program
License:        none
Source0:        fun-0.1.tar.gz

%description
a fun program

%prep
%setup -q


%build
make %{?_smp_mflags}

%install
rm -rf $RPM_BUILD_ROOT
%make_install


%files
/bin/fun
%doc

%changelog
* Fri Oct 09 2014 akawhy
- First release

里面的%build%install%files是比较关键的3个阶段, 可以根据自己的需求改动. 当碰到%make_install这样的指令时, 使用rpm -E '%make_install'来看看到底执行的是什么, 很方便.

一切都准备好后, 可以使用rpmbuild -ba --clean SPECS/fun.spec指令来进行打包. 对应包会存在RPMS目录下面, 可以使用rpmls来查看包中的文件.

最后

以上是一个比较简单的打包, 实际的应用会远远比这个复杂, 比如会有对应的配置文件, 启动脚本之类的, 此时的spec文件绝非如此简单. 我觉得最快的学习手段就是参考现有的包, 比如nginx的rpm包.

1
2
3
yum -y install yum-utils              # 安装工具
yumdownloader --source nginx          # 获取包
rpm -ivh nginx-1.4.7-1.fc20.src.rpm   # 解压包至rpmbuild目录

接下来我们就可以模仿nginx的rpm来进行打包了(spec文件确实比较长).

相比deb, 我觉得rpm打包还是比较好上手的~ keep on learning~

Comments