同一个服务器做两个网站,绍兴网站制作价格,搬瓦工建wordpress,浙江省建设信息港查spec 文件
制作 rpm 软件包并不是一件复杂的工作#xff0c;其中的关键在于编写软件包的 spec 描述文件。
要想制作一个 rpm 软件包就必须写一个软件包描述文件 spec。这个文件中包含了软件包的诸多信息#xff0c;如#xff1a;软件包的名字、版本、类别、说明摘要、创建…spec 文件制作 rpm 软件包并不是一件复杂的工作其中的关键在于编写软件包的 spec 描述文件。要想制作一个 rpm 软件包就必须写一个软件包描述文件 spec。这个文件中包含了软件包的诸多信息如软件包的名字、版本、类别、说明摘要、创建时要执行什么指令、安装时要执行什么操作、以及软件包所要包含的文件列表等等。实际过程中最关键的地方是要清楚虚拟路径的位置以及宏的定义。文件头这个区域定义的Name、Version这些字段对应的值可以在后面通过%{name},%{version}这样的方式来引用类似于 C 语言中的宏Summary用一句话概括该软件s包尽量多的信息。Name软件包的名字最终 rpm 软件包是用该名字与版本号Version、释出号(Release及体系号来命名软件包的后面可使用%{name}的方式引用Version软件版本号。仅当软件包比以前有较大改变时才增加版本号后面可使用%{version}引用Release软件包释出号/发行号。一般我们对该软件包做了一些小的补丁的时候就应该把释出号加 1后面可使用%{release}引用Packager打包的人一般喜欢写个人邮箱Vendor软件开发者的名字发行商或打包组织的信息例如RedFlagCo,LtdLicense软件授权方式通常是GPL自由软件或GPLv2,BSDCopyright软件包所采用的版权规则。具体有GPL自由软件BSDMITPublic Domain公共域Distributable贡献commercial商业Share共享等一般的开发都写GPL。Group软件包所属类别Development/System 开发/系统System Environment/Daemons 系统环境/守护Source源程序软件包的名字/源代码包的名字如stardict-2.0.tar.gz。可以带多个用Source1、Source2等源后面也可以用%{source1}、%{source2}引用Source0: %{name}-boost-%{version}.tar.gz ← 源码包名称(可以使用URL)可以用SourceN指定多个如配置文件 #Patch0: some-bugs0.patch ← 如果需要打补丁则依次填写 #Patch1: some-bugs1.patch ← 如果需要打补丁则依次填写BuildRequires: 制作过程中用到的软件包构建依赖Requires: 安装时所需软件包Requires(pre): 指定不同阶段的依赖BuildRoot: 这个是安装或编译时使用的「虚拟目录」打包时会用到该目录下文件可查看安装后文件路径例如BuildRoot: %_topdir/BUILDROOT。Prefix: %{_prefix}这个主要是为了解决今后安装 rpm 包时并不一定把软件安装到 rpm 中打包的目录的情况。这样必须在这里定义该标识并在编写%install脚本的时候引用才能实现 rpm 安装时重新指定位置的功能BuildArch: 指编译的目标处理器架构noarch标识不指定但通常都是以/usr/lib/rpm/marcros中的内容为默认值%description软件包详细说明可写在多个行上。这样任何人使用rpm -qi查询您的软件包时都可以看到它。您可以解释这个软件包做什么描述任何警告或附加的配置指令等等。URL软件的主页RPM 包信息查看我通过命令查看了 nginx 包的信息如下RPM 包依赖#依赖关系定义了一个包正常工作需要依赖的其他包RPM在升级、安装和删除的时候会确保依赖关系得到满足。BuildRequires#定义构建时依赖的软件包在构建机器编译 rpm 包时需要的辅助工具以逗号分隔。假如要求编译myapp时gcc 的版本至少为 4.4.2则可以写成gcc 4.2.2Requires#定义安装时的依赖包该 rpm 包所依赖的软件包名称就是指编译好的 rpm 软件在其他机器上安装时需要依赖的其他软件包。可以用或表示大于或小于某一特定版本。号两边需用空格隔开而不同软件名称也用空格分开。格式CopyRequires: libpng-devel 1.0.20 zlib其它写法例如CopyRequires: bzip2 %{version}, bzip2-libs %{version}还有例如PreReq、Requires(pre)、Requires(post)、Requires(preun)、Requires(postun)、BuildRequires等都是针对不同阶段的依赖指定。关于pre、post、preun、postun含义理解感觉post有一种“完成”的意思Copy# 安装前执行的脚本语法和shell脚本的语法相同 %pre # 安装后执行的脚本 %post # 卸载前执行的脚本 %preun # 卸载完成后执行的脚本 %postun # 清理阶段在制作完成后删除安装的内容例如CopyPreReq: capabilityversion #capability包必须先安装 Conflicts:bash2.0 #该包和所有不小于2.0的bash包有冲突BuildRoot#该参数非常重要因为在生成 rpm 的过程中执行make install时就会把软件安装到上述的路径中在打包的时候同样依赖“虚拟目录”为“根目录”进行操作。后面可使用$RPM_BUILD_ROOT方式引用。考虑到多用户的环境一般定义为Copy%{_tmppath}/%{name}-%{version}-%{release}-root # OR %{_tmppath}/%{name}-%{version}-%{release}-buildroot-%(%{__id_u} -n}下面介绍 spec 脚本主体%prep 阶段#这个阶段是「预处理」通常用来执行一些解开源程序包的命令为下一步的编译安装作准备。%prep和下面的%build%install段一样除了可以执行 rpm 所定义的宏命令以%开头以外还可以执行SHELL命令命令可以有很多行如我们常写的tar解包命令。功能上类似于./configure。%prep阶段进行实际的打包准备工作它是使用节前缀%prep表示的。主要功能有将文件 (SOURCES/) 解压到构建目录 (BUILD/)应用Patch打补丁 (SOURCES/ BUILD/)描述rm -rf $RPM_BUILD_ROOT描述或编辑本部分用到的命令到PreReq通过-b .XXX描述补丁备份它一般包含%setup与%patch两个命令。%setup用于将软件包打开执行%patch可将补丁文件加入解开的源程序中。示例Copy%prep %setup -q ← 宏的作用是解压并切换到目录 #%patch0 -p1 ← 如果需要打补丁则依次写 #%patch1 -p1 ← 如果需要打补丁则依次写%setup#这个宏解压源代码将当前目录改为源代码解压之后产生的目录。这个宏还有一些选项可以用。例如在解压后%setup宏假设产生的目录是%{name}-%{version}Copy%setup -n %{name}-%{version} #把源码包解压并放好主要的用途就是将%sourcedir目录下的源代码解压到%builddir目录下也就是将~/rpmbuild/SOURCES里的包解压到~/rpmbuild/BUILD/%{name}-%{version}中。一般用%setup -c就可以了但有两种情况一就是同时编译多个源码包二就是源码的 tar 包的名称与解压出来的目录不一致此时就需要使用-n参数指定一下。Copy%setup 不加任何选项仅将软件包打开。 %setup -a 切换目录前解压指定 Source 文件例如 -a 0 表示解压 Source0 %setup -n newdir 将软件包解压在newdir目录。 %setup -c 解压缩之前先产生目录。 %setup -b num 将第 num 个 source 文件解压缩。 %setup -D 解压前不删除目录 %setup -T 不使用default的解压缩操作。 %setup -T -b 0 将第 0 个源代码文件解压缩。 %setup -c -n newdir 指定目录名称 newdir并在此目录产生 rpm 套件。 %patch 最简单的补丁方式自动指定patch level。 %patch 0 使用第0个补丁文件相当于%patch ?p 0。 %patch -s 不显示打补丁时的信息。 %patch -T 将所有打补丁时产生的输出文件删除应该-q参数给%setup宏。这会显著减少编译日志文件的输出尤其是源代码包会解压出一堆文件的时候。在~/rmpbuild/BUILD/%{name}-%{version}目录中进行 使用标准写法会引用/usr/lib/rpm/marcros中定义的参数。%patch#这个宏将头部定义的补丁应用于源代码。如果定义了多个补丁它可以用一个数字的参数来指示应用哪个补丁文件。它也接受-b extension参数指示 RPM 在打补丁之前将文件备份为扩展名是extension的文件。通常补丁都会一起在源码tar.gz包中或放到SOURCES目录下。一般参数为%patch -p1使用前面定义的Patch补丁进行-p1是忽略patch的第一层目录%Patch2 -p1 -b xxx.patch打上指定的补丁-b是指生成备份文件%build 阶段#本段是「构建」阶段这个阶段会在%_builddir目录下执行源码包的编译。一般是执行执行常见的configure和make操作。该阶段一般由多个make命令组成。与%prep段落一样这些命令可以是shell命令也可以是宏。记住两点%build和%install的过程中都必须把编译和安装的文件定义到“虚拟根目录” 中%file中必须明白用的是相对目录这个阶段我们最常见只有两条指令Copy%configure make %{?_smp_mflags} OPTIMIZE%{optflags} ← 多核则并行编译%configure这个不是关键字而是 rpm 定义的标准宏命令。意思是执行源代码的configure配置。会自动将prefix设置成/usr。这个%{?_smp_mflags} %{optflags}是什么意思呢Copy$ rpm --eval %{?_smp_mflags} -j4 $ rpm --eval %{optflags} -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE2 -fexceptions -fstack-protector-strong --paramssp-buffer-size4 -grecord-gcc-switches -m64 -mtunegeneric所以上面那个命令就是make -j4。问题又来了make -j4表示什么意思都是一些优化参数Linux kernel 笔记 26——利用“make -j”提高编译kernel速度CSDB-make -j4是什么意思%install 阶段#「安装」阶段就是执行make install命令操作。开始把软件安装到虚拟的根目录中。这个阶段会在%buildrootdir目录里建好目录结构然后将需要打包到 rpm 软件包里的文件从%builddir里拷贝到%_buildrootdir里对应的目录里。在~/rpmbuild/BUILD/%{name}-%{version}目录中进行make install的操作。%install很重要因为如果这里的路径不对的话则下面%file中寻找文件的时候就会失败。特别需要注意的是%install部分使用的是绝对路径而%file部分使用则是相对路径虽然其描述的是同一个地方。千万不要写错。当用户最终用rpm -ivh name-version.rpm安装软件包时这些文件会安装到用户系统中相应的目录里。Copy%install if [-d %{buildroot}]; then rm -rf %{buildroot} ← 清空下安装目录实际会自动清除 fi make install DESTDIR%{buildroot} ← 安装到buildroot目录下 %{__install} -Dp -m0755 contrib/init.d %{buildroot}%{_initrddir}/foobar %{__install} -d %{buildroot}%{_sysconfdir}/foobar.d/「翻译」一下Copymake install DESTDIR/root/rpmbuild/BUILDROOT/%{name}-%{version}-%{release}.x86_64 make install DESTDIR/root/rpmbuild/BUILDROOT/%{name}-%{version}-%{release}.x86_64 /usr/bin/install -d /root/rpmbuild/BUILDROOT/%{name}-%{version}-%{release}.x86_64/etc/foobar.d/需要说明的是这里的%install主要就是为了后面的%file服务的。所以还可以使用常规的系统命令Copyinstall -d $RPM_BUILD_ROOT/ cp -a * $RPM_BUILD_ROOT/其中%{buildroot}和$RPMBUILDROOT是等价的%{buildroot}必须全部用小写不然要报错。注意区分$RPM_BUILD_ROOT和$RPM_BUILD_DIR$RPM_BUILD_ROOT是指开头定义的BuildRoot是%file需要的。$RPM_BUILD_DIR通常就是指~/rpmbuild/BUILDscripts section 没必要可以不填#%pre安装前执行的脚本%post安装后执行的脚本%preun卸载前执行的脚本%postun卸载后执行的脚本%pretrans在事务开始时执行脚本%posttrans在事务结束时执行脚本%preun%postun的区别是什么呢前者在升级的时候会执行后者在升级 rpm 包的时候不会执行%files 阶段#本段是文件段主要用来说明会将%{buildroot}目录下的哪些文件和目录最终打包到rpm包里。定义软件包所包含的文件分为三类说明文档doc配置文件config执行程序还可定义文件存取权限拥有者及组别。这里会在虚拟根目录下进行千万不要写绝对路径而应用宏或变量表示相对路径。在%files阶段的第一条命令的语法是Copy%defattr(文件权限,用户名,组名,目录权限)注意点同时需要在%install中安装。Copy%files %defattr (-,root,root,0755) ← 设定默认权限 %config(noreplace) /etc/my.cnf ← 表明是配置文件noplace表示替换文件 %doc %{src_dir}/Docs/ChangeLog ← 表明这个是文档 %attr(644, root, root) %{_mandir}/man8/mysqld.8* ← 分别是权限属主属组 %attr(755, root, root) %{_sbindir}/mysqld%exclude列出不想打包到 rpm 中的文件。注意如果%exclude指定的文件不存在也会出错的。在安装 rpm 时会将可执行的二进制文件放在/usr/bin目录下动态库放在/usr/lib或者/usr/lib64目录下配置文件放在/etc目录下并且多次安装时新的配置文件不会覆盖以前已经存在的同名配置文件。关于%files阶段有两个特性%{buildroot}里的所有文件都要明确被指定是否要被打包到 rpm里。什么意思呢假如%{buildroot}目录下有 4 个目录 a、b、c和d在%files里仅指定 a 和 b 要打包到 rpm 里如果不把 c 和 d 用exclude声明是要报错的如果声明了%{buildroot}里不存在的文件或者目录也会报错。关于%doc宏所有跟在这个宏后面的文件都来自%{_builddir}目录当用户安装 rpm 时由这个宏所指定的文件都会安装到/usr/share/doc/name-version/目录里。%clean#清理段可以通过--clean删除BUILD编译完成后一些清理工作主要包括对%{buildroot}目录的清空(这不是必须的)通常执行诸如make clean之类的命令。%changelog#本段是修改日志段记录 spec 的修改日志段。你可以将软件的每次修改记录到这里保存到发布的软件包中以便查询之用。每一个修改日志都有这样一种格式第一行是* 星期 月 日 年 修改人 电子信箱。其中星期、月份均用英文形式的前 3 个字母用中文会报错。接下来的行写的是修改了什么地方可写多行。一般以减号开始便于后续的查阅。Copy%changelog * Fri Dec 29 2012 foobar foobarkidding.com - 1.0.0-1 - Initial version宏#在定义文件的安装路径时通常会使用类似%_sharedstatedir的宏这些宏一般会在/usr/lib/rpm/macros中定义。关于宏的语法可以查看 Macro syntaxRPM 内建宏定义在/usr/lib/rpm/redhat/macros文件中这些宏基本上定义了目录路径或体系结构等等同时也包含了一组用于调试 spec 文件的宏。所有宏都可以在/usr/lib/rpm/macros找到附录一些常见的宏Copy%{_sysconfdir} /etc %{_prefix} /usr %{_exec_prefix} %{_prefix} %{_bindir} %{_exec_prefix}/bin %{_lib} lib (lib64 on 64bit systems) %{_libdir} %{_exec_prefix}/%{_lib} %{_libexecdir} %{_exec_prefix}/libexec %{_sbindir} %{_exec_prefix}/sbin %{_sharedstatedir} /var/lib %{_datadir} %{_prefix}/share %{_includedir} %{_prefix}/include %{_oldincludedir} /usr/include %{_infodir} /usr/share/info %{_mandir} /usr/share/man %{_localstatedir} /var %{_initddir} %{_sysconfdir}/rc.d/init.d %{_topdir} %{getenv:HOME}/rpmbuild %{_builddir} %{_topdir}/BUILD %{_rpmdir} %{_topdir}/RPMS %{_sourcedir} %{_topdir}/SOURCES %{_specdir} %{_topdir}/SPECS %{_srcrpmdir} %{_topdir}/SRPMS %{_buildrootdir} %{_topdir}/BUILDROOT %{_var} /var %{_tmppath} %{_var}/tmp %{_usr} /usr %{_usrsrc} %{_usr}/src %{_docdir} %{_datadir}/doc %{buildroot} %{_buildrootdir}/%{name}-%{version}-%{release}.%{_arch} $RPM_BUILD_ROOT %{buildroot}利用 rpmbuild 构建 rpm 安装包时通过命令rpm --showrc|grep prefix查看。通过rpm --eval %{macro}来查看具体对应路径。比如我们要查看%{_bindir}的路径就可以使用命令rpm --eval %{ _bindir}来查看。Copy%{_topdir} %{getenv:HOME}/rpmbuild %{_builddir} %{_topdir}/BUILD %{_rpmdir} %{_topdir}/RPMS %{_sourcedir} %{_topdir}/SOURCES %{_specdir} %{_topdir}/SPECS %{_srcrpmdir} %{_topdir}/SRPMS %{_buildrootdir} %{_topdir}/BUILDROOT Note: On releases older than Fedora 10 (and EPEL), %{_buildrootdir} does not exist. Build flags macros %{_global_cflags} -O2 -g -pipe %{_optflags} %{__global_cflags} -m32 -marchi386 -mtunepentium4 # if redhat-rpm-config is installed变量#define定义的变量类似于局部变量只在%{!?foo: ... }区间有效不过 SPEC 并不会自动清除该变量只有再次遇到%{}时才会清除define vs. global#两者都可以用来进行变量定义不过在细节上有些许差别简单列举如下define用来定义宏global用来定义变量如果定义带参数的宏 (类似于函数)必须要使用define在%{}内部必须要使用global而非definedefine在使用时计算其值而global则在定义时就计算其值可以简单参考如下的示例。Copy#--- %prep之前的参数是必须要有的 Name: mysql Version: 5.7.17 Release: 1%{?dist} Summary: MySQL from FooBar. License: GPLv2 and BSD %description It is a MySQL from FooBar. %prep #--- 带参数时必须使用%define定义 %define myecho() echo %1 %2 %{!?bar: %define bar defined} echo 1: %{bar} %{myecho 2: %{bar}} echo 3: %{bar} # 如下是输出内容 #1: defined #2: defined #3: %{bar}3 的输出是不符合预期的可以将%define修改为global即可%{?dist} 表示什么含义#不加问号如果dist有定义那么就会用定义的值替换否则就会保%{dist};加问好如果dist有定义那么也是会用定义的值替换否则就直接移除这个tag%{?dist}举例Copy$ rpm -E foo:%{foo}$\nbar:%{?bar} foo:%{foo} bar: $ rpm -Dfoo foov -E foo:%{foo}$\nbar:%{?bar} foo:foov bar: $ rpm -Dfoo foov -Dbar barv -E foo:%{foo}$\nbar:%{?bar} foo:foov bar:barv小结#看了以上SPEC的总结以为了解差不多了结果看了网络域的SPEC文件自己真实too young too simple。参考#开源中国-RPM包的制作 对 rpmbuild 目录的创建及生成介绍比较详细夜鸣猪-RPM包rpmbuild SPEC文件深度说明OpenSUSE-spec 文件指南CSDN-RPM打包原理、示例、详解及备查 很详细有示例Fedora-WIKI-How to create an RPM package/zh-cn 中文介绍IBM-RPM 打包技术与典型 SPEC 文件分析JIN-YANG-RPM 包制作 总结很全还介绍了签名CSDN-RPM构建 - SPEC文件参数解析 该博主总共围绕 RPM 构建写了几篇文章的原-关于rpm打包中的条件判断 介绍了 spec 中条件判断的语法Whats the meaing of 1%{?dist} in SPEC file in RPM package分类: Linux标签: rpm, spec, build« 上一篇 RPM Yum 相关命令及参数» 下一篇 RPM 包的构建 - 实例posted 2019-03-06 00:04 Michael翔 阅读(38655) 评论(3) 收藏 举报