首页 > 其他分享 >RPM打包

RPM打包

时间:2023-01-07 19:44:50浏览次数:59  
标签:RPM rpmbuild usr install path rpm spec 打包

禁止自动分析源码添加不应该加入的依赖 在spec文件中加入Autoreq: 0即可
opnvswitch源码打包需要加入,否则会解析代码中的依赖,在ISO中安装检测失败/bin/python3
%post 部分如果有shell 则依赖关系会自动增加/bin/sh , 如果合并入镜像是不能有/bin/sh /bin/python等

目录

一、打包工具安装

执行命令安装所需的rpm包:
yum install rpmdevtools rpmlint make gcc -y
rpmdevtools包里包括了rpmbuild ,安装好工具后,使用命令rpmdev-setuptree 生成~/rpmbuild目录及其子目录
tree rpmbuild

rpmbuild
├── BUILD
├── RPMS 
├── SOURCES
├── SPECS 
└── SRPMS

或者手动生成目录,命令如下:
mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
Fedora的文档建议不使用root用户进行RPM打包

二、使用spec文件创建rpm包

切换路径至SPECS文件夹,使用命令创建spec文件(rpm打包的脚本规则文件),执行命令
rpmdev-newspec myrpm
在当前目录生成了myrpm.spec文件,内容如下(增加了说明和其他部分,源文件比较简单)

Name:  myrpm
Version: 
Release:  1%{?dist}
Summary:

License:  # GPLBSDMITor
URL:
Source0:  SOURCES/%{name}-%{version}.tar.gz
BuildRequires:  # rpm
Requires:       # rpm -ivh
%description
#

%prep
# %prep  %setup -q SOURCES${Source0} BUILD  %{name}-%{version}
%setup -q

# %patch0 -p1

%build
# %build %build
# cdBUILD/%{name}-%{version}()
%configure                                                  # %configureconfigureautoconfconfigure ,
make %{?_smp_mflags}                                 # %{_smp_mflags} cpuCPUmake ,  ~/.rpmmacros

%install
# %install
#  BUILD/%{name}-%{version}()
# BUILDROOTBUILDROOT
rm -rf $RPM_BUILD_ROOT                         #BUILDROOTcentos6 $RPM_BUILD_ROOT  %{buildroot}  BUILDROOT/%{name}-%{version}-%{release}.%{_arch}
%make_install                                           # %make_installmake install

%clean


#RPMBUILD
rm -rf %{buildroot}

%files
# BUILDROOT/package/ ,  /usr/bin/test
%config(noreplace) %{_sysconfdir}/foo.conf                                #   *.rpmsave  *.rpmnew
%config %{_sysconfdir}/foo.conf                                                #  /etc
%attr(755, root, root) %{_sysconfdir}/foo.conf
%attr(mode, user, group) %{_sysconfdir}/foo.conf                        # ”-”
/usr/bin/test

%doc


%changelog
## rpm -q package --changelog

开始部分里开头是大写字母的字段,可以被当做变量引用 %{name} %{version} %{release} ...
rpmlint xx.spec可以检测spec语法正确性
spec 中不需要的部分直接删除即可
%build和%install部分都是先cd到BUILD/包名的目录下, 在执行其他命令

三、 SPEC规则注解

rpmbuild
├── BUILD
├── BUILDROOT 
├── RPMS
├── SOURCES 
├── SPECS
└── SRPMS

rpmdev-setuptree 执行完之后缺少一个BUILDROOT目录, 实际执行 还要用到该目录, 但不需手动创建,在rpmbuild的过程中会 自动创建。
rpmbuild的规则里有一些内置宏变量,以%开头的, 查看方法rpmbuild --showrc 或者rpm --showrc 几种方式都可以查看;
要查看具体某个宏的值可以使用rpm --eval/-E , 比如 (规范宏写法应该是%{_name})

$ rpm -E %{_topdir}
/home/wanglin/rpmbuild
路径 名称 用途
~/rpmbuild/BUILD %_builddir 构建目录 源代码包从SOURCES目录解压缩后放到该目录,并在该目录进行编译即configure 和 make命令
~/rpmbuild/BUILDROOT %_buildrootdir 最终安装目录 保存%install阶段安装的文件,即make install执行后产生的文件
~/rpmbuild/RPMS %_rpmdir 标准rpm包目录 生成的二进制rpm包会存放在该目录
~/rpmbuild/SOURCES %_sourcedir 源代码目录 源码tar.gz包放到该目录
~/rpmbuild/SPECS %_specdir Spec文件目录 Spec文件存放路径
~/rpmbuild/SRPMS %_srcrpmdir 源码RPM包目录 生成的srpm包存放在该目录

四、spec中的脚本

脚本片段 类似kickstart文件,使用shell编写

  • %pre: 在rpm包安装之前执行
  • %post: 在安装rpm包之后执行
  • %preun: 在卸载rpm包之前执行
  • %postun: 在卸载rpm包之后执行
  • %pretrans: 在事务开始时执行
  • %posttrans: 在事务结束时执行

通常所有安装脚本和触发器脚本都是使用 /bin/sh 来执行的,如果想使用其他脚本,如 perl,可使用 -p /usr/bin/perl 来告诉 rpm 使用perl解释器
如果仅执行一个命令,则 “-p” 选项会直接执行,而不启用 shell。然而,若有许多命令时,不要使用此选项,按正常编写 shell 脚 本即可。
%pre、%post、%preun 和 %postun 提供 $1 参数,表示动作完成后,系统中保留的此名称的软件包数量。
因此可用于检查软件安装情况,不过不要比较此参数值是否等于 2,而是比较是否大于等于 2。对于%pretrans 和 %posttrans,$1 的值恒为 0。

- install upgrade uninstall
%pretrans $1 == 0 $1 == 0 (N/A)
%pre $1 == 1 $1 == 2 (N/A)
%post $1 == 1 $1 == 2 (N/A)
%preun (N/A) $1 == 1 $1 == 0
%postun (N/A) $1 == 1 $1 == 0
%posttrans $1 == 0 $1 == 0 (N/A)

示例1:

%post
if [ "$1" = 1 ]; then
$1 == 0 $1 == 2 $1 == 2 $1 == 1 $1 == 1 $1 == 0
(N/A) (N/A) (N/A) $1 == 0 $1 == 0 (N/A)
# rpm1  if
if [ ! -f %{_sysconfdir}/shells ] ; then
    echo "%{_bindir}/foo" > %{_sysconfdir}/shells
    echo "/bin/foo" >> %{_sysconfdir}/shells
  else
    grep -q "^%{_bindir}/foo$" %{_sysconfdir}/shells || echo "%{_bindir}/foo" >> %{_sysconfdir}/shells
    grep -q "^/bin/foo$" %{_sysconfdir}/shells || echo "/bin/foo" >> %{_sysconfdir}/shells
fi
%postun #0
if [ "$1" = 0 ] && [ -f %{_sysconfdir}/shells ] ; then
  sed -i '\!^%{_bindir}/foo$!d' %{_sysconfdir}/shells
  sed -i '\!^/bin/foo$!d' %{_sysconfdir}/shells
fi

示例2:
例如,如果软件包安装了一份 info 手册,那么可以用 info 包提供的 install-info 来更新 info 手册索引。 首先,我们不保证系统已安装 info 软件包,除非明确声明需要它;其次,我们不想在 install-info 执行失败时,使软件包安装失败:

Requires(post): info
Requires(preun): info
... %post
/sbin/install-info %{_infodir}/%{name}.info %{_infodir}/dir || :
%preun
if [ $1 = 0 ] ; then
   /sbin/install-info --delete %{_infodir}/%{name}.info %{_infodir}/dir || :
fi

上边的示例中还有一个安装 info 手册时的小问题需要解释一下。install-info 命令会更新 info 目录,所以我们应该在 %install 阶段删 除 %{buildroot} 中无用的空目录:

rm -f %{buildroot}%{_infodir}/dir

一般最后一条命令的exit状态就是脚本的exit状态,除一些特殊情况,一般脚本都是以exit 0状态退出所以大部分脚本片段都会使用 "||:" 退出

五、执行打包命令生成rpm

SPEC 编写完毕,执行以下命令来构建 SRPM 和 RPM 包:
rpmbuild -ba myrpm.spec
如果成功,RPM 会保存至 ~/rpmbuild/RPMS,SRPM 会保存至 ~/rpmbuild/SRPMS。
如果失败,请查看 BUILD 目录的相应编译日志。为了帮助调试,可以用 --short-circuit 选项来忽略成功的阶段。例如,若想要(略过更早的阶段)重新从 %install 阶段开始,请执行:
rpmbuild -bi --short-circuit myrpm.spec
如果只想创建 RPM,请执行:
rpmbuild -bb myrpm.spec

如果只想创建 SRPM(不需要执行 %prep 或 %build 或其他阶段),请执行:
rpmbuild -bs myrpm.spec

rpmlint检查
为避免常见错误,请先使用 rpmlint 查找 SPEC 文件的错误:
rpmlint program.spec

如果返回错误/警告,使用 “-i” 选项查看更详细的信息。
也可以使用 rpmlint 测试已构建的 RPM 包,检查 SPEC/RPM/SRPM 是否存在错误。你需要在发布软件包之前,解决这些警告。此 页面 提供一些常见问题的解释。如果你位于 SPEC 目录中,请执行:
rpmlint myrpm.spec ../RPMS/*/NAME*.rpm ../SRPMS/NAME*.rpm
进入 ~/rpmbuild/RPMS 下的特定架构目录中,您会发现有许多二进制 RPM 包。使用以下命令快速查看 RPM 包含的文件和权限:
rpmls *.rpm

六、部分宏变量

%{_sysconfdir}        /etc
%{_prefix}              /usr
%{_exec_prefix}      %{_prefix}
%{_bindir}              %{_exec_prefix}/bin
%{_libdir}                %{_exec_prefix}/%{_lib}
%{_libexecdir}          %{_exec_prefix}/libexec
%{_sbindir}              %{_exec_prefix}/sbin
%{_sharedstatedir}    /var/lib
%{_datarootdir}        %{_prefix}/share
%{_datadir}              %{_datarootdir}
%{_includedir}        %{_prefix}/include
%{_infodir}            /usr/share/info
%{_mandir}          /usr/share/man
%{_localstatedir}     /var
%{_initddir}          %{_sysconfdir}/rc.d/init.d
%{_var}                /var
%{_tmppath}        %{_var} /tmp
%{_usr}              /usr
%{_usrsrc}          %{_usr}/src
%{_lib}              lib (lib64 on 64bit multilib systems)
%{_docdir}        %{_datadir}/doc
%{buildroot}      %{_buildrootdir}/%{name}-%{version}-%{release}.%{_arch}
$RPM_BUILD_ROOT  %{buildroot}
%{_unitdir}                               /usr/lib/systemd/system
%define Macro Value  Macro=Value

七、一个只打包文件的spec实例

Name: cvk_tools
Version: 1.1
Release: 1%{?dist}
Summary: cvk_tools by wanglin
License: GPLv3
URL:
Source: %{name}-%{version}.tar.gz
BuildArch: %{_arch}
Autoreq: 0
%prep
%setup -q
%description
init cvk

%define pack_path root/%{name}-%{version}
%define ca_path etc/pki/CA
%install
install -d %{buildroot}/%{pack_path}
install -d %{buildroot}/%{ca_path}
for i in `ls ./`;do
    if [ -f $i ];then
        install ./$i %{buildroot}/%{pack_path}
    elif [ -d $i ];then
        if [[ $i =~ "ca" ]];then
             install -m 444 -o root -g root ./ca/cacert.pem %{buildroot}/%{ca_path}
        else
            install -d %{buildroot}/%{pack_path}/$i
            for f in `ls $i`;do
                install $i/$f %{buildroot}/%{pack_path}/$i
            done
        fi 
    fi
done
# Upgarde${conf}.old
%pre
conf=/%{pack_path}/tools.conf
if (( $1 == 2 ));then
     [ -f $conf ] && mv $conf ${conf}.old || :
fi

# Upgrade
%post
conf=/%{pack_path}/tools.conf
if (( $1 == 2 ));then
    [ -f ${conf}.old ] && mv ${conf}.old ${conf} || :
fi

%postun
if (( $1 == 0 ));then
    [ -d /%{ca_path} ] && rm -rf /%{ca_path} || :
    [ -d $(dirname /%{ca_path}) ] && rm -rf $(dirname /%{ca_path}) || :
    [ -d /%{pack_path} ] && rm -rf /%{pack_path} || :
fi

%files
%attr(-, root, root)
# first method
/%{pack_path}
/%{ca_path}
#----second method
#%dir /%{pack_path}
#/%{pack_path}/*
#%dir /%{ca_path}
#/%{ca_path}/*


%doc
%changelog
* Fri Jul 1 2022 cvk_tools Release - 1.1-1
- Second Version release
* Thu Nov 25 2021 cvk_tools Release - 1.0-1
- Initial first version

附录: 打包遇到的问题

  • fle段缺少文件
Checking for unpackaged file(s): /usr/lib/rpm/check-files /root/rpmbuild/BUILDROOT/lldpad-1.1-1.el7.x86_64
error: Installed (but unpackaged) file(s) found:
   /usr/etc/bash_completion.d/lldpad
   /usr/etc/bash_completion.d/lldptool
   /usr/include/lldpad/clif.h
   /usr/include/lldpad/clif_msgs.h
   /usr/include/lldpad/clif_sock.h
   ...
RPM build errors:
    Installed (but unpackaged) file(s) found:
   /usr/etc/bash_completion.d/lldpad
   /usr/etc/bash_completion.d/lldptool
   /usr/include/lldpad/clif.h
   /usr/include/lldpad/clif_msgs.h
   /usr/include/lldpad/clif_sock.h
   ...

这个意思是说发现了制作RPM包的spec脚本中没有包含但又被安装的文件
如果显示很多文件,将这些文件你可以分门别类,用%doc、%config这些宏来指定,其实如果它报错的时候,只显示一两个文件,可 以直接把那个文件写在%file下面
vi /usr/lib/rpm/macros,找到%__check_files %{_rpmconfigdir}/check-files %{buildroot} 这一行,把这一行注释掉,然后重新编 译。

  • file段重复包含
warning: File listed twice: /etc/pki/CA/cacert.pem
warning: File listed twice: /root/cvk_tools-1.1/README.md
warning: File listed twice: /root/cvk_tools-1.1/config_ca.sh
...

重复包含了文件
去掉file段重复目录或者文件的包含关系

参考链接

Fedora
链接2
链接3

标签:RPM,rpmbuild,usr,install,path,rpm,spec,打包
From: https://www.cnblogs.com/ishmaelwanglin/p/17033333.html

相关文章

  • Android程序签名打包
    1.什么是签名,有什么用AndroidAPP都需要我们用一个证书对应用进行数字签名,不然的话是无法安装到Android手机上的,平时我们调试运行时到手机上时,是AS会自动用默认的密钥和证书......
  • Electron打包错误的踩坑小记
    windows墙内打包失败办法在网络环境不好(无科学上网)的条件下,项目可能可以启动成功却无法打包,注意查看报错信息,如下图所示:这种都是缺少相关包导致的问题,根据报错信息手动下......
  • 项目的打包上线部署
    默认端口号是多少:80构建项目运行的命令package.json的  每次运行,就会在在项目的根目录生成一个dist文件,如果原来有,就删除重新创建 本地模拟上线/测试使用n......
  • maven打包报错:Malformed \uxxxx encoding
    @echooff::maven打包报错:Malformed\uxxxxencoding::REPOSITORY_PATH更换成自己的maven地址setREPOSITORY_PATH=/Work/MyMavenRepositoryecho%REPOSITORY_PATH%f......
  • rpm
    一、说明RMP是LINUX下的一种软件的可执行程序,你只要安装它就可以了。这种软件安装包通常是一个RPM包(RedhatLinuxPacketManager,就是Redhat的包管理器)。RPM是一种......
  • Java生成二维码并浏览器下载,也可打包成zip下载
    不说废话,直接上代码1.单个生成二维码并下载codeNo为前端传的需要生产二维码的内容publicvoidqrCode(HttpServletRequestrequest,HttpServletResponseresponse,Stri......
  • webpack打包中path.resolve(__dirname,“dist“)的含义【转载】
    今天学了webpack打包,在配置里面有这样一句话是path.resolve(__dirname,"dist")varpath=require("path")module.exports={//打包的入口配置""打包的路径ent......
  • 解决react typescript项目中引入js库项目打包报错问题
    描述在reacttypescript项目中,在打包的过程中会报错抛出couldnotfindadeclarationfileformodule的错误,报错内容如图所示原因JS库无法在TS中正常的加载,需要修改......
  • 使用IDEA打包项目(jar包和war包) pom.xml
      介绍jar包假设将整个项目视为一堵墙,那么jar包就是砖块,将写好的类进行打包的过程就是烧制砖块的过程。jar包是class文件和部署文件的归档,不包含静态文件,它不仅用于......
  • springboot 资源分离 打包
    <build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</a......