[rpm] Make rpm package from source code package|modify rpm and remake rpm package

Table of contents

foreword

install rpmbuild

rpmbuild makes rpm packages

Generate devel package at the same time

Prevent rpmbuid from stripping programs/libraries when packaging

Modify rpm, remake rpm package

RPM packaging tool

SPEC file

 Spec file keyword description

rpmbuild directory and Spec macro variable and parameter description

preamble part

body part

Title Macro Variables/Working Directory

Symbol Description

If the spec file does not write dependencies, there are still dependent libraries

CMake makes rpm package

HelloWorld

The role of the rpm debuginfo package

More SPEC examples

Error record

foreword

The things needed to make an rpm package include source code, spec files (scripts for making rpm packages), and rpmbuild tools.

Official website tutorial: RPM Packaging Guide--https://rpm-packaging-guide.github.io/#rpm

recommended article:

RPM packaging principles, examples, detailed explanations and reference: https://blog.csdn.net/get_set/article/details/53453320

install rpmbuild

$yum install rpmbuild
$yum install rpmdevtools 
$rpmdev-setuptree

rpmbuild makes rpm packages


1. Organize the source code
tar -zcvf hello-1.0.tar.gz hello-1.0

The hello-1.0 source code is packaged as a .tar.gz compressed package and placed in the SOURCE folder. Our source code may be a tar.gz package, or several files.
The name format of the tar.gz source package should be helloword-1.0.0.tar.gz (actually name-version number.tar.gz)

2. Write the spec file
Create a new xxx.spec packaging script under the SPECS folder, which is actually a process of compiling and packaging our source code into rpm.
(There is a rpmdev-newspec tool that can automatically generate a .spec template)

vi  xxx.spec 

Name:           hellorpm           #名字为源码tar.gz 包的名字 
Version:        1.0.0             #版本号,一定要与tar.gz包的一致哦 
Release:        1%{?dist}         #释出号,也就是第几次制作rpm 
Summary:       helloword   #描述信息/软件包简介,最好不超过50字符 

#生成rpm包名:${Name}-${Version}-${Release}.${BuildArch}.rpm

License:        GPL                   #许可,GPL还是BSD等  
URL:            #自定义该信息,可以写一个网址 
Packager:       abel 
Source0:        %{name}-%{version}.tar.gz   
#定义用到的source,也就是你的源码

BuildRoot:      %_topdir/BUILDROOT         
#这个是软件make install 的测试安装目录.

BuildRequires:  gcc,make                           #制作过程中用到的软件包 
Requires:       python-apscheduler >= 2.1.2-1.el7,python-daemon >= 1.6-1.el7  #软件运行依赖的软件包,也可以指定最低版本如 bash >= 1.1.1 
%description                #描述,随便写                 
%prep                          #打包开始                    
%setup -q                      #这个作用静默模式解压并cd                               


%build              #编译制作阶段,主要目的就是编译,如果不用编译就为空 
./configure \                                     
 %{?_smp_mflags}          #make后面的意思是:如果就多处理器的话make时并行编译 

%install                        #安装阶段//安装之前需初始化安装目录                        
 rm -rf %{buildroot}             #先删除原来的安装的,如果你不是第一次安装的话 
 cp -rp %_topdir/BUILD/%{name}-%{version}/*  $RPM_BUILD_ROOT 
#将需要需要打包的文件从BUILD 文件夹中拷贝到BUILDROOT文件夹下。

#下面的几步pre、post、preun、postun 没必要可以不写 
%pre        #rpm安装前制行的脚本 

%post       #安装后执行的脚本//安装之后需要执行的动作 
cp  /usr/local/httpd/bin/apachectl /etc/init.d/myhttpd
sed -i '1a # chkconfig:  2345 85 15' /etc/init.d/myhttpd

%preun      #卸载前执行的脚本//卸载该rpm包所执行的一些操作
/etc/init.d/myhttpd stop
%postun     #卸载后执行的脚本 

%clean #清理段,删除buildroot 
rm -rf %{buildroot} 

%files  #rpm要包含的文件//安装之后生成的文件 
%defattr (-,root,root,-)   #设定默认权限,如果下面没有指定权限,则继承默认 
/etc/hello/word/helloword.c           #将你需要打包的文件或目录写下来
/usr/local/httpd/bin/*
%dir  /usr/local/httpd/logs
%doc  /usr/local/httpd/man/*
%doc  /usr/local/httpd/manual/*

###  7.chagelog section //定义一些日志文件,可以使用:rpm -q  --changelog httpd查看到
%changelog 
* Wed Mar 26 2014  zhangzhg <[email protected]> 2.2.25
- first rpm from  httpd-2.2.25

(%build and %install in this spec are easy to write wrong and report an error, so we can not configure %build and %install, let rpmbuild execute build and install for us, we make install outside, and then rpmbuild packages the results)

Note:
If there is no operation in the above stage, it is empty, but there cannot be a blank line. For example, if the build stage is empty, it should be written as
 

%build              
%install  
xxxxxxxx   
错误示例:
%build   

%install  
xxxxxxxx

rpm package production stage
insert image description here

3, build rpm package

 After the spec file is written, it can be packaged.

Execute the command under the SPECS folder:
rpmbuild -ba hello.spec

If something goes wrong, you can use different commands to see that there is a problem in the packaging step.

rpmbuild -ba spec_name.spec <--compile, generate both source code src.rpm and binary rpm 
rpmbuild -bb spec_name.spec <--compile, only generate binary rpm 
rpmbuild  
-bs only generate src rpm 
-bp execute to pre 
-bc Execute to the build section 
-bi Execute the install section 
-bl Detect files that are not included 

You can rpmbuild -bp first, then -bc and then -bi If there is no problem, rpmbuild -ba will generate src packages and binary packages.
 

4, install
rpmbuild -ivh hello.rpm

5, Query
rpm -qi hello
 rpm -qa|grep hello

Reference for this article:
http://laoguang.blog.51cto.com/6013350/1103628/
http://blog.chinaunix.net/uid-23069658-id-3944462.html

Original link: https://blog.csdn.net/u012373815/article/details/73257754

Another packaging tutorial: https://blog.csdn.net/weixin_33875564/article/details/92785284
 

Generate devel package at the same time

devel appears in the form of subpackages, so you only need to add the %files devel configuration section in the spec file

Name:      kmymoney
Summary:   The Personal Finances Manager for KDE.
Version:   0.8
Release:   1.%{disttag}%{distver}
#生成rpm包名:${Name}-${Version}-${Release}.${BuildArch}.rpm
License:   GPL
Packager:  %packer
Group:     Productivity/Office/Finance
Source0:   %{name}2-%version.tar.bz2
BuildRoot: %{_tmppath}/%{name}2-%{version}-%{release}-build
BuildRequires: kdebase3-devel
Prereq: /sbin/ldconfig
 
%description
 
Description goes here...
 
%package devel
 
#Requires:
Summary: KMyMoney development files
Group: Productivity/Office/Finance
Provides: kmymoney-devel
 
%description devel
 
This package contains necessary header files for KMyMoney development.
 
... more to go here ...
 
%files
 
... some files ...
 
%files devel
 
... the devel files ...

Example:

http://kmymoney2.sourceforge.net/phb/rpm-example.html
Reference: https://stackoverflow.com/questions/2913130/building-both-devel-and-normal-version-of-a-rpm-package
(Excerpt from: https://phpor.net/blog/post/5673)

Prevent rpmbuid from stripping programs/libraries when packaging

By default, when rpmbuild is used to package, all installed files will be stripped, some debugging information of the files will be removed, and the debugging information will be placed in

In many cases, we don't need rpmbuild to execute strip for us, and we don't need to generate debuginfo package, so we can modify the spec file and turn off these options.

The strip operation for files is defined in the __os_install_post macro. We can run rpmbuild --showrc to see what the original __os_install_post did:

  1. ...
    -
    14: __os_install_
     
    /usr/lib/rpm/redhat/brp-compress
     
    %{!?__debug_package:/usr/lib/rpm/redhat/brp-stripq %{ __strip}}
  2.  /usr/lib/rpm/redhat/brp-strip-static-archive %{ __strip}
  3.  /usr/lib/rpm/redhat/brp-strip-comment-note %{ __strip} %{ __objdump}
  4.  /usr/lib/rpm/brp-python-bytecompile
  5.  /usr/lib/rpm/redhat/brp-python-hardlink
  6.  %{!?__jar_repack:/usr/lib/rpm/redhat/brp-java-repack-jars}
  7. ...

You can see that a series of operations are performed on the file during packaging, such as compression, strip, and compilation of Python scripts.

If you want not to strip, you must remove the statement with strip above, or make it invalid.

method 1:

Add in front of the spec file, do not do anything in __os_install_post directly

%global __os_install_post %{nil}

Method 2:

add in front

%define debug_package %{nil}

%define __strip /bin/true

Defining the __strip variable as /bin/true (originally /usr/bin/strip) is equivalent to doing nothing.

Excerpt from: https://www.cnblogs.com/LiuYanYGZ/p/9565861.html

$ rpm --showrc | grep -A 4 ': __os_install_post'
-14: __os_install_post  
    /usr/lib/rpm/brp-compress 
    /usr/lib/rpm/brp-strip 
    /usr/lib/rpm/brp-strip-static-archive 
    /usr/lib/rpm/brp-strip-comment-note

Recently, I had an uncommon requirement to disable this option. I do not want to reduce the file size of all files packaged in the rpm. This is achievable using any of 3 mechanisms.

  • Spec file
  • ~/.rpmmacros
  • /etc/rpm/macros

To prevent binary stripping for specific rpm, we could add following line at the top of any rpm spec file.

%global __os_install_post %{nil}

To prevent binary stripping for all rpms created by specific user, we could add following line in ~/.rpmmacros file:

%__os_install_post %{nil}

To prevent binary stripping for all rpms created by all users, we could add following line in /etc/rpm/macros file:

 %__os_install_post %{nil}

Modify rpm, remake rpm package


Extract the spec file
rpm rebuild -s helloworld.spec helloworld.x86_64.rpm

Unzip the original rpm package and get helloworld
rpm2cpio helloworld.rpm|cpio -div

Modify or replace the content in helloworld

create folder /tmp/rpmbuild
mkdir /tmp/buildrpm

Put both helloworld and helloworld.spec into it <----------------------This step is critical

cp -r helloworld helloworld.spec /tmp/buildrpm

Recompile the rpm package

rpmbuild -ba --buildroot /tmp/buildrpm/ /tmp/buildrpm/helloworld.spec
 

RPM packaging tool


Tools for packaging RPMs provided by the rpmdevtools package. To list the tools, run:
$ rpm -ql rpmdevtools | grep bin

Title Create a packaged working directory
Execute
rpmdev-setuptree

$ tree ~/rpmbuild/
/home/user/rpmbuild/
|-- BUILD
|-- RPMS
|-- SOURCES
|-- SPECS
`-- SRPMS

Directory name description Macro name in macros
BUILD Temporary directory for compiling rpm packages %_builddir
BUILDROOT Temporary installation directory for software generated after compiling %_buildrootdir Directory
for installable rpm packages finally generated by RPMS %_rpmdir
SOURCES Storage of all source codes and patch files Directory %_sourcedir
SPECS directory for storing SPEC files (important) %_specdir
SRPMS software final rpm source format storage path (ignored for now, don't worry about it) %_srcrpmdir

SPEC file


Spec files are used to tell rpmbuild how to build RPM or SRPM packages. (Refer to the difference between RPM and SRPM: http://cn.linux.vbird.org/linux_basic/0520rpm_and_srpm.php#intro_whatisrpm)
The Spec file contains two parts: preamble and body. The preamble part mainly contains metadata of some packages, and the body part mainly uses for packaging, installation, etc.

 Spec file keyword description

The main keywords are:

Name: The name of the software package, you can use %{name} to refer to it later Summary
: The content summary of the software package
Version: The actual version number of the software, for example: 1.0.1, etc., you can use %{version} to refer to it later
Release: Release The serial number, for example: 1%{?dist}, indicates the number of packages, and %{release} can be used later to refer to
Group: software grouping, it is recommended to use: Applications/System
License: software authorization method, usually GPL
Source: source code Package, can bring multiple sources such as Source1, Source2, etc., and you can also use %{source1}, %{source2} to refer to BuildRoot later
: This is the "virtual directory" used when installing or compiling. Considering the multi-user environment, generally Defined as:
%{_tmppath}/%{name}-%{version}-%{release}-root
or
%{_tmppath}/%{name}-%{version}-%{release}-buildroot-%(% {__id_u} -n}
This parameter is very important, because in the process of generating rpm, the software will be installed in the above path when executing make install. When packaging, it also depends on the "virtual directory" as the "root directory" Operate.
It can be referenced later by $RPM_BUILD_ROOT.


URL: The home page of the software
Vendor: Information about the publisher or packaging organization, packaging organization or personnel, such as RedFlag Co,Ltd
Distribution: Release version identification
Patch: Patch source code, you can use Patch1, Patch2, etc. to identify multiple patches, use %patch0 or %{patch0} quotes
Prefix: %{_prefix} This is mainly to solve the situation that when installing rpm packages in the future, it is not necessary to install the software into the packaged directory in rpm. In this way, the identifier must be defined here and referenced when writing the %install script, in order to realize the function of re-specifying the location during rpm installation


Prefix: %{_sysconfdir} The reason is the same as above, but because %{_prefix} refers to /usr, and for other files, such as configuration files under /etc, you need to use %{_sysconfdir} to identify Build Arch: refers to
compilation The target processor architecture, the noarch flag is not specified, but usually the content in /usr/lib/rpm/marcros is the default value
Requires: The name of the package that the rpm package depends on, which can be represented by >= or <= Greater or less than a specific version, for example: libpng-devel >= 1.0.20 zlib Note: ">=" needs to be separated by spaces, and different software names should also be separated by spaces.
There are also PreReq, Requires(pre), Requires(post), Requires(preun), Requires(postun), BuildRequires, etc. are all dependency specifications for different stages 

(The dependencies that are not written in the spec are also dependent? See the description in the following chapters)


Provides: Indicate some specific functions of this software so that other rpms can recognize
Packager: Information of the packager
%description Detailed description of the software

%define: Pre-defined variables, such as defining the log path: _logpath /var/log/weblog



The main body of the spec script 
The main body of the spec script also includes many keywords and descriptions, which will be listed one by one below. I will mark some places that need special attention.
%prep 

      Preprocessing script, this section is a preprocessing section, usually used to execute some commands to unpack the source package, and prepare for the next compilation and installation. %prep is the same as the %build and %install sections below. In addition to executing the macro commands (starting with %) defined by RPM, it can also execute SHELL commands. The commands can have many lines, such as the tar unpacking command we often write .

%setup

Unzip the source code package and put it away
, usually from the package in /usr/src/asianux/SOURCES to /usr/src/asianux/BUILD/%{name}-%{version}.

%setup -q %{name}-%{version}
is generally enough to use %setup -q, but there are two situations: one is to compile multiple source packages at the same time, and the other is the name of the tar package of the source code and the decompressed The directories are inconsistent. In this case, you need to use the -n parameter to specify it.

%setup opens the package without any options.

%setup -q in quiet mode with minimal output

%setup -D #Prohibit deleting the directory before decompression

%setup -a number #After changing the directory, only unzip the source code of the given number, such as -a 0 for source0
%setup -n newdir unzip the software package to the newdir directory.
%setup -c creates a directory before unpacking.
%setup -b num When multiple source files are included, decompress the numth source file.
%setup -T does not use the default decompression operation.
%setup -T -b 0 decompresses the 0th source code file SOURCE0.
%setup -c -n newdir specifies the directory name newdir, and generates rpm packages in this directory.


%patch Patching Patches
are usually included in the source code tar.gz package, or placed in the SOURCES directory.

The general parameters are:
%patch -p1 Use the Patch patch defined above, -p1 is to ignore the first layer directory of the patch
%Patch2 -p1 -b xxx.patch to apply the specified patch, -b means to generate a backup file
◎Supplement 
%patch The easiest way to patch, automatically specify the patch level. 
%patch 0 Use the 0th patch file, equivalent to %patch ?p 0. 
%patch -s does not display information when patching. 
%patch -T deletes all output files generated during patching.

%patch #Patch 0

%patch1 #Patch 1

%patch2 #Patch 2

%patch -P 2 #Patch 2

Before %build, the %prep part will prepare the compilation work, unpack the source code package, and put the corresponding patch into it.


%configure This is not a keyword, but a standard macro command defined by rpm. It means to execute the configure configuration of the source code
in the /usr/src/asianux/BUILD/%{name}-%{version} directory, use the standard notation, and refer to the parameters defined in /usr/lib/rpm/marcros.
Another non-standard way of writing is to refer to the parameter customization in the source code, for example:

quote

CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{_prefix}

%build starts building the package

Start to compile the source code build package, which is equivalent to the configure and make parts

The command to be executed is to generate the package service, such as

%configure This is not a keyword, but a standard macro command defined by rpm. It means to execute the configure configuration of the source code, you can use the rpm –eval '%configure' command to view the macro and
operate it in the /usr/src/asianux/BUILD/%{name}-%{version} directory, using the standard writing method, Will refer to the parameters defined in /usr/lib/rpm/marcros.
Another non-standard way of writing is to refer to the parameter customization in the source code, for example:

CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{_prefix}

The make command
performs the make work in the /usr/src/asianux/BUILD/%{name}-%{version} directory, common writing:

make %{?_smp_mflags} OPTIMIZE="%{optflags}"
are some optimization parameters, defined in /usr/lib/rpm/marcros


%install starts installing the software into the virtual root directory

This section is the installation section, and the commands in it will be executed when installing the software package, such as make install command, cp, mv, install, ln.
Perform make install in the /usr/src/asianux/BUILD/%{name}-%{version} directory. This is very important, because if the path here is wrong, it will fail when looking for the file in %file below. Common contents include:
%makeinstall This is not a keyword, but a standard macro command defined by rpm, which is equivalent to the step of executing the make install command.

You can also use non-standard notation:

make DESTDIR=$RPM_BUILD_ROOT install

make prefix=$RPM_BUILD_ROOT install

make INSTROOT=$RPM_BUILD_ROOT install
It should be noted that the %install here is mainly for the subsequent %file service. So, you can also use regular system commands:

rm -rf ${RPM_BUILD_ROOT}

mkdir -p $RPM_BUILD_ROOT/{%{_bindir},%{_mandir}/man1,%{_libdir},%{_includedir}}

install -m 755 bzlib.h $RPM_BUILD_ROOT/%{_includedir}

install -m 644 bzip2.1 bzdiff.1 bzgrep.1 bzmore.1  $RPM_BUILD_ROOT/%{_mandir}/man1/

install -d $RPM_BUILD_ROOT/
cp -a * $RPM_BUILD_ROOT/

ln -s file/magic  ${RPM_BUILD_ROOT}%{_datadir}/magic

%find_lang  %{name}

%files -f  %{name}.lang

The first sentence generates a file named %{name}.lang, the content is all %{name}.mo, the second sentence means that it is very troublesome to list the .mo files one by one, and the -f parameter is followed by it Files to merge into %files' list of files.


%clean cleans up temporary files
Usually the content is:

[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf "$RPM_BUILD_ROOT"
rm -rf $RPM_BUILD_DIR/%{name}-%{version}


※ Pay attention to the distinction between $RPM_BUILD_ROOT and $RPM_BUILD_DIR:
$RPM_BUILD_ROOT refers to the BuildRoot defined at the beginning, and $RPM_BUILD_DIR usually refers to /usr/src/asianux/BUILD, and the former is required by %file. 
%pre rpm script executed before installation
%post rpm script executed after rpm installation
%preun script executed before rpm uninstall
%postun script executed after rpm uninstall

What is the difference between %preun %postun?

The former will be executed when upgrading, and the latter will not be executed when upgrading the rpm package.

%files defines which files or directories to pack into the rpm
, and it will be performed under the virtual root directory. Do not write absolute paths, but use macros or variables for relative paths. If the description is a directory, it means all files in the directory except %exclude.
%defattr (-, root, root) specifies the attributes of the package file, respectively (mode, owner, group), - means the default value, 0644 for text files, and 0755 for executable files %exclude lists do not want to be packaged into

rpm ※ Be
careful, if the file specified by %exclude does not exist, an error will occur.

 
%changelog change log


※Special attention should be paid to: the %install part uses an absolute path, while the %file part uses a relative path, although it describes the same place. Don't make a mistake.

%file 
is what must be understood in %file, using relative directory references

Divided into three categories - description document (doc), configuration file (config) and execution program, you can also define file access permissions, owner and group

ile1 #The file can also contain wildcards, such as *

file2

directory #All files are placed in the directory directory

%dir /etc/xtoolwait #just an empty directory /etc/xtoolwait into the package

%doc indicates that this is a documentation file, so if you use --excludedocs when installing, the file will not be installed,

%doc /usr/X11R6/man/man1/xtoolwait.* #Install the document

%doc README NEWS #Install these documents to /usr/share/doc/%{name}-%{version} or /usr/doc or

%docdir #Define the directory of the documentation, such as /root, after this statement, all lines starting with /root are defined as documentation.

%config /etc/yp.conf #mark this file is a configuration file, during the upgrade process, RPM will have the following actions.

%config(missisgok) /etc/yp.conf This configuration file can be lost, even if it is lost, RPM will not consider it an error when uninstalling the software package, and will not report an error. It is generally used for symbolic link files created after the software package is installed, such as

/etc/rc.d/rc5.d/S55named file, this kind of file may need to be deleted after the software package is uninstalled, so it doesn’t matter if it is lost.

%config(noreplace) /etc/yp.conf

#This configuration file will not overwrite existing files (the files in the RPM package will exist in the system as .rpmnew, and the configuration file in the system will be saved as .rpmsave when uninstalling. If there is no such option, the files in the RPM package will be saved during installation. Exists in the system as .rpmorig )

Overwrite existing files (not modified), create new files with extension suffix .rpmnew (modified)

%{_load}/*

%config  /etc/aa.conf

%ghost /etc/yp.conf #This file should not be included in the package. It is generally a log file. Its file attributes are very important, but the file content is not important. After using this option, only its file attributes will be added to the package.

%attr(mode, user, group) filename #Control file permissions such as %attr(0644,root,root) /etc/yp.conf

If you don't want to specify a value, you can use -

%config %attr(-,root,root) filename #Set file type and permissions

%defattr (-,root,root,-) 、%defattr (0644,root,root,0644) #Set the default permissions of the file, - means the default value, 0644 for text files and 0755 for executable files

%lang(en) %{_datadir}/locale/en/LC_MESSAGES/tcsh* #mark files with specific language

%verify(owner group size) filename #Only test owner, group, size, all are tested by default

%verify(not owner) filename #Do not test owner, test other attributes

All certifications are as follows:

group: the group of the authentication file

maj: the major device number of the authentication file

md5: MD5 of the authentication file

min: minor device number of the authentication file

mode: authentication file permissions

mtime: The last modification time of the authentication file

owner: the owner of the authentication file

size: the size of the authentication file

symlink: authenticate symbolic links

If the description is a directory, it means all files in the directory except %exclude.

%files 
%defattr(-,root,root) 
%{_bindir} 
%{_libdir} 
%{_datadir} 
%exclude %{_libdir}/debug

Since all the files in the suite must be included in %file, we need to know which files are included in the compiled suite. A common practice is to manually simulate a compilation process:

./configrue --prefix=/usr/local/xxx
make
make DESTDIR=/usr/local/xxx install
or
make prefix=/usr/local/xxx install
In this way, the contents of the entire suite will be placed in /usr/local In /xxx, you can write the %file and %exclude sections according to the situation.
※Of course, this is only valid for the source code written in the GNU way and the package created with GNU autotool. If you customize the Makefile, it cannot be generalized.

%pre: tasks to be done before installation, such as: creating a user
%post: tasks to be done after installation, such as: tasks to be automatically started
%preun: tasks to be done before uninstallation, such as: stop tasks
%postun: tasks to be done after uninstallation Tasks such as: delete users, delete/backup business data

%changelog

Change log, this paragraph is the modification log segment. You can record every modification of the software here and save it in the released software package for query purposes. Each changelog has this format:

The first line is: * E-mail of the person who edited the week, month, day, and year.

Among them: the first three letters of the English form are used for the week and the month, and an error will be reported in Chinese. The next line writes what is modified, and multiple lines can be written. Generally, it starts with a minus sign, which is convenient for subsequent reference.

* Mon Mar 31 1997 Erik Troan <[email protected]>

- Fixed problems caused by 64 bit time_t.


See the reference for making patches 
in detail:  [Original] 
How to write the %file section  using the diff and patch tools
Since all files in the suite must be included in %file, we need to know which files are included in the compiled suite?
A common practice is to artificially simulate a compilation process: In this way, the contents of the entire suite will be placed in /usr/local/xxx, and the %file and %exclude sections can be written according to the situation. ※Of course, this is only valid for packages whose source code is written in the GNU way and created with GNU autotool. If you customize the Makefile, it cannot be generalized. 
About the execution script in rpm 
If the rpm package being produced is to be placed on the system installation CD, you need to consider whether there is a problem with the script defined in rpm. Since the system only depends on a small environment during installation, which is very different from the actual installed environment, most scripts cannot take effect in this installation environment, and may even cause trouble of.
Therefore, for such a suite that needs to be placed in the installation CD, it is a better method not to add an execution script.
In addition, in order to provide information that can be referred to in the operation, rpm also provides a signal mechanism: different operations will return different information, and put it in the default variable $1.

More: rpm packaging, rpmbuild SPEC file depth description_https://blog.csdn.net/u013425438/article/details/80417542

Detailed introduction at: https://www.cnblogs.com/ilanni/p/4312581.html

https://blog.51cto.com/luweiv998/2354385
https://blog.csdn.net/csdn_763871244/article/details/99937600

rpmbuild directory and Spec macro variable and parameter description

preamble part

SPEC directive

illustrate

Name

The base name of the package, which should match the SPEC file name.

The base name of the package, should match the SPEC file name.

Version

The upstream version number of the software.

Release

The number of times this version of the software was released. Normally, set the initial value to 1%{?dist}, and increment it with each new release of the package. Reset to 1 when a new Version of the software is built.

The number of releases for this version of the software. Typically, an initial value of 1%{?dist} is set and incremented for each new release of that version. Reset to 1 when generating a new version of the software.

Summary

A short, one-line package summary.

License

The license of the software being packaged. For packages distributed in community distributions such as Fedora this must be an open source license abiding by the specific distribution’s licensing guidelines.


​The license of the software being For packages distributed in community distributions such as Fedora, this must be an open source license, adhering to the specific distribution's licensing guidelines.

URL

The full URL for more information about the program. Most often this is the upstream project website for the software being packaged.

Full URL for more information about the program. Typically, this is the upstream project website for the packaged software.

Source0

Path or URL to the compressed archive of the upstream source code (unpatched, patches are handled elsewhere). This should point to an accessible and reliable storage of the archive, for example, the upstream page and not the packager’s local storage. If needed, more SourceX directives can be added, incrementing the number each time, for example: Source1, Source2, Source3, and so on.

Path or URL to upstream source tarball (unpatched, patches are handled elsewhere). This should point to an accessible and reliable package path, e.g. the upstream page, not the packager's local storage. If needed, more SourceX addresses can be added, incrementing the number each time, for example: Source1, Source2, Source3, etc.

Patch0

The name of the first patch to apply to the source code if necessary. If needed, more PatchX directives can be added, incrementing the number each time, for example: Patch1, Patch2, Patch3, and so on.

The name of the first patch to apply to the source code if necessary. If desired, more PatchXs can be added, incrementing the number each time, eg: Patch1, Patch2, Patch3, etc.

BuildArch

If the package is not architecture dependent, for example, if written entirely in an interpreted programming language, set this to BuildArch: noarch. If not set, the package automatically inherits the Architecture of the machine on which it is built, for example x86_64.

If the package does not depend on the platform architecture, such as hardware-independent scripts, please set it to BuildArch:noarch. If not set, the package is automatically set to the machine's platform architecture, eg x86_64.

BuildRequires

A comma- or whitespace-separated list of packages required for building the program written in a compiled language. There can be multiple entries of BuildRequires, each on its own line in the SPEC file.

编译程序用到的文件的列表,用逗号或空格分隔。在SPEC文件中,可以有多个BuildRequires条目,,每个条目单独一行

Requires

A comma- or whitespace-separated list of packages required by the software to run once installed. There can be multiple entries of Requires, each on its own line in the SPEC file.

软件安装后运行所依赖的rpm的文件列表,用逗号或空格分隔。在SPEC文件中,可以有多个Requires条目,每个条目单独一行

(spec没有写的依赖也依赖进来了?见后面的章节说明)

ExcludeArch

If a piece of software can not operate on a specific processor architecture, you can exclude that architecture here.

如果某个软件不能在特定的处理器架构上运行,则可以在此处排除该架构。

例如:要生成的包名是 python-2.7.5-34.el7.x86_64,则

Name:python,

Version:2.7.5,

Release:34.el7

最后一个标记是x86_64,表示体系结构。体系结构标记不受RPM打包器的直接控制,而是由rpmbuild构建环境定义。唯一的例外是要构建的RPM与硬件平台无关时,自己可以填写BuildArch:noarch.

Body 部分

SPEC 指令

说明

%description

A full description of the software packaged in the RPM. This description can span multiple lines and can be broken into paragraphs.

RPM中软件包的完整描述。此描述可以跨越多行,并可以拆分为段落。

%prep

Command or series of commands to prepare the software to be built, for example, unpacking the archive in Source0. This directive can contain a shell script.

构建之前的处理,例如,创建or删除目录,解压从Source0获取到的压缩包……可以包含shell脚本。

%build

Command or series of commands for actually building the software into machine code (for compiled languages) or byte code (for some interpreted languages).

编译生成程序的的命令或一系列命令。

%install

Command or series of commands for copying the desired build artifacts from the %builddir (where the build happens) to the %buildroot directory (which contains the directory structure with the files to be packaged). This usually means copying files from ~/rpmbuild/BUILD to ~/rpmbuild/BUILDROOT and creating the necessary directories in ~/rpmbuild/BUILDROOT. This is only run when creating a package, not when the end-user installs the package. See Working with SPEC files for details.


用于将所需的生成工件从%builddir(生成发生的位置)复制到%buildroot目录(包含要打包的文件的目录结构)的命令或一系列命令。这通常意味着将文件从~/rpmbuild/BILD复制到~/rpmuild/BILDROOT,并在~/rmbuild/BILDLOOT中创建必要的目录。这仅在创建包时运行,而不是在最终用户安装包时运行。有关详细信息,请参见使用SPEC文件:https://rpm-packaging-guide.github.io/#working-with-spec-files

%check

Command or series of commands to test the software. This normally includes things such as unit tests.

测试软件的命令或一系列命令。这通常包括单元测试等内容。

%files

The list of files that will be installed in the end user’s system.

将安装在最终用户系统中的文件列表。(也就是需要打包进rpm包的文件列表--绝对路径)

%changelog

A record of changes that have happened to the package between different Version or Release builds.

不同版本或发行版本之间对包所做更改的记录。

标题宏变量/工作目录


默认工作路径的确定,通常由在/usr/lib/rpm/macros这个文件里的一个叫做%_topdir的宏变量来定义。

在%_topdir目录下一般需要建立6个目录:
$_topdir /root/rpmbuild

目录名 说明 macros中的宏名
BUILD 编译rpm包的临时目录 %_builddir
BUILDROOT 编译后生成的软件临时安装目录 %_buildrootdir
RPMS 最终生成的可安装rpm包的所在目录 %_rpmdir
SOURCES 所有源代码和补丁文件的存放目录 %_sourcedir
SPECS 存放SPEC文件的目录(重要) %_specdir
SRPMS 软件最终的rpm源码格式存放路径(暂时忽略掉,别挂在心上) %_srcrpmdir

Spec文件的宏定义:
rpmbuild --showrc | grep topdir #工作车间目录:_topdir /root/rpmbuild
-14: _builddir %{_topdir}/BUILD
-14: _buildrootdir %{_topdir}/BUILDROOT
-14: _rpmdir %{_topdir}/RPMS
-14: _sourcedir %{_topdir}/SOURCES
-14: _specdir %{_topdir}/SPECS
-14: _srcrpmdir %{_topdir}/SRPMS
-14: _topdir /root/rpmbuild

rpmbuild --showrc显示所有的宏,以下划线开头:

一个下划线:定义环境的使用情况,
二个下划线:通常定义的是命令,
为什么要定义宏,因为不同的系统,命令的存放位置可能不同,所以通过宏的定义找到命令的真正存放位置

符号说明


什么是 1%{?dist} : 如果%{dist}未定义返回1,否则返回1%{dist},

if 0%{?flag}; then
foo
fi

如果%{flag}被定义了,条件语句为:0%{flag},执行if block; 反之,条件语句为:0, 不执行if block。
注意:%{?flag}前必须加0,否则如果%{?flag}未定义,if语句停止执行并退出。
%{?flag: …}:如果%{flag}被定义,则展开"…"部分

作者:weiee
链接:https://www.jianshu.com/p/f1e36e4a152c
 

Note:

rpm --eval %{kernel_module_package_buildreqs}->kernel-devel
rpm --eval %{kernel_module_package} 会输出一些关于制作linux驱动的一些代码和一些依赖
重要的是包含了%files 路径,%files包含了需要打包进入rpm包里的文件,如果是 / 开头那么其实是BUILDROOT路径
制作的时候%install 是安装到~/rpmbuild/BUILDROOT的,最后发布rpm后运行yum install rpm会
把驱动安装到lib/modules/( u n a m e − r ) / u p d a t e s B u i l d R o o t : 在 e x p o r t I N S T A L L M O D P A T H = (uname -r)/updates BuildRoot: 在 %install 阶段(%build 阶段后)文件需要安装至此位置。Fedora 不需要此标签,只有 EPEL5 还需要它。默认情况下,根目录为 “%{_topdir}/BUILDROOT/”。 %_buildrootdir 最终安装目录 ~/rpmbuild/BUILDROOT 保存 %install 阶段安装的文件 export INSTALL_MOD_PATH=(uname−r)/updatesBuildRoot:在exportINSTALL 
MOD PATH=RPM_BUILD_ROOT export INSTALL_MOD_DIR=updates 这两句话说明了安装的时候的路径,是~/rpmbuild/BUILDROOT ,最后里面会生成对应的lib/modules/$(uname -r)/updates 下面

insert image description here

如果%clean 不加会默认把BUILDROOT给删掉

原文链接:https://blog.csdn.net/Wang20122013/article/details/122498396

spec文件不写依赖的情况依然存在依赖库

由于很多东西需要保密,所以不放截图
rpm -qlp *.rpm查看rpm包中携带的文件
ldd file检测编译文件夹下的bin文件是否是bin文件带来的依赖
vi /usr/lib/rpm/micro编辑rpm的编译宏
找到455,456行,注释掉

    455 #%__find_provides       %{_rpmconfigdir}/find-provides
    456 #%__find_requires       %{_rpmconfigdir}/find-requires

重新编译,使用rpm -qpR *.rpm检测新生成的rpm是否带有依赖
如果问题未被解决,则在spec文件Requires下面加入一行AutoReqprv: no来规避掉二进制文件带来的依赖 AUTOREQ=0  (注意使用AutoReqprv:no 之后需要手工写spc 该rpm包的provider


链接:https://www.jianshu.com/p/3eff04b20f93

The AUTOREQPROV, AUTOREQ, and AUTOPROV tags are not available for use with --queryformat.

Available Tags For --queryformat---http://ftp.rpm.org/max-rpm/ch-queryformat-tags.html

rpm包是怎么自动搞进一些依赖项的:

答案是rpmbuild使用ldd命令对%files部分中包含的任何二进制文件生成自动依赖关系:

Automatic Dependencies


 

CMake制作rpm包


(摘自:https://blog.csdn.net/qq_29493353/article/details/90205415)

也可以使用cmake 制作rpm包,CMake中包含的三个工具(cmake cpack ctest)中的cpack工具。他可以帮助快速的打包发布你的程序。

HelloWorld


目录结构

insert image description here

CMakeList.txt

cmake_minimum_required(VERSION 2.8)
# 设置项目名称
project(HelloWorld)
 
# 设置安装路径, 默认/usr/local。也可以是idc经常安装的/data/home/user00/xxxserver等
# set(CPACK_PACKAGING_INSTALL_PREFIX /opt)
 
# 如果不是CMake构建的,设置CMAKE_CURRENT_BINARY_DIR为Makefile的构建目录
set(CMAKE_CURRENT_BINARY_DIR ..)
 
# 批量的安装指令,目录、程序、库文件、头文件等
install(PROGRAMS bin/hello DESTINATION bin)
install(FILES bin/hello.a DESTINATION lib)
install(FILES src/hello.h DESTINATION include)
 
# 以下为RPM信息的设置,包名,概述,供应者,版本, 分组等等信息,通过其变量名称可以知道意思
set(CPACK_PACKAGE_NAME "wetest-helloworld")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Simple CPack HelloWorld")
set(CPACK_PACKAGE_VENDOR "WeTest")
set(CPACK_PACKAGE_VERSION "1.0.0")
set(CPACK_PACKAGE_VERSION_MAJOR "1")
set(CPACK_PACKAGE_VERSION_MINOR "0")
set(CPACK_PACKAGE_VERSION_PATCH "0")
set(CPACK_RPM_PACKAGE_GROUP "WeTest")
set(CPACK_RPM_PACKAGE_URL "http://wetest.qq.com")
set(CPACK_RPM_PACKAGE_DESCRIPTION "WeTest Server Dependencies")
set(CPACK_PACKAGE_RELEASE 1)
set(CPACK_RPM_PACKAGE_LICENSE "WeTest Licence")
 
# 设置默认生成器,RPM生成器会构建RPM安装包,其它还有TGZ/ZIP等
set(CPACK_GENERATOR "RPM")
 
# 安装前和安装后执行的shell脚本, 会打包到RPM中,安装时执行。这里可扩展性很强, 放在源码目录下即可
# set(CPACK_RPM_PRE_INSTALL_SCRIPT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/pre_script.sh)
# set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/post_script.sh)
 
# 引入CPack模块,必须的
include(CPack)

构建

mkdir build && cd build
$ cmake …
$ make install
$ cpack

其中capck支持其他的打包格式,比如tar.gz和zip,只需要执行cpack -G TGZ 或者 cpack -G ZIP就可打包成相应的格式。

结论
以上主要是用cpack打包开发程序,其实可以针对很多东西制作rpm包,比如很多依赖已经用源码安装好的开发坏境,也可以打包,公司tlinux的提供了兼容性。比如mysql++已经装在系统/usr/local/当中,替换模板中的描述和install指令如下即可:

file(GLOB mysqlppso /usr/local/lib/libmysqlpp*)
install(DIRECTORY /usr/local/include/mysql++ DESTINATION include)
install(PROGRAMS ${mysqlppso} DESTINATION lib)
希望能够帮助大家快速部署,也推荐使用CMake来完成构建任务,如果有用的话之后介绍下ctest + boost unit test做单元测试。
 

rpm debuginfo包的作用

一般在linux上,编写一个软件后,都会用rpmbuild工具打包成rpm包,然后发给别人去部署。
rpm包里一般就是有一些可执行文件,静态库或者动态库,但是不包含源代码。
那么有时候为了调试方便,还会同时生成相应的rpm debuginfo包,这样就可以方便调试。只要客户安装了普通rpm包和相应版本的debuginfo包,就可以gdb调试了
更多详细请看原文《rpm debuginfo包的作用》:https://blog.csdn.net/chenj_freedom/article/details/84023885

更多SPEC例子

#前期准备:       yum -y install rpmdevtools pcre-devel   
#-------------------------------------------------------
# 查看默认宏:   rpmbuild --showrc  |  grep  "_topdir"
#  _builddir      %{_topdir}/BUILD
#  _buildrootdir %{_topdir}/BUILDROOT
#  _rpmdir       %{_topdir}/RPMS
#  _sourcedir    %{_topdir}/SOURCES    --->  原材料,如源码包,文档所在目录,需事先将打包的源文件或脚本存放在此目录内......
#  _specdir      %{_topdir}/SPECS   --->  管理rpm制作过程的描述文件所在的目录
#  _srcrpmdir    %{_topdir}/SRPMS
#  _topdir        %{getenv:HOME}/rpmbuild   --->  rpmbuild目录的顶层入口
#-------------------------------------------------------
#生成~/rpmbuild及子目录:    rpmdev-setuptree
#生成rpmbuild的spec模板:    rpmdev-newspec -o Name-version.spec  --->   生成的SPEC文件主要用于描述RPM包的制作和生成过程
#eg:
#[root@localhost ~]#  rpmdev-setuptree && cd rpmbuild ; tree
#.
#├── BUILD
#├── RPMS
#├── SOURCES
#├── SPECS
#└── SRPMS
#------------------------------------------------------------------------------------------------------------------------- 以下是spec文件内容:
 
#自定义宏,相当于Linux中"Key-Value"变量形式
%define Name nginx  #--->  名称
%define Version 1.2.2  #--->  版本
%define CONFIGFILE 1.conf   #--->   本rpm包中需更换的配置文件......
%define InstallPath /usr/local/nginx  #--->   本rpm包默认安装的路径
 
#定义软件包信息,即:"rpm -qi name.rpm " 查看到的内容
Name:           %{Name}   #--->   引用宏
Version:        %{Version}   #--->   引用宏
Release:        1%{?dist}   #--->   引用宏(自带宏)
Summary:        ....................................... #--->  一些描述信息
#生成rpm包名:${Name}-${Version}-${Release}.${BuildArch}.rpm
License:        GPLv2  #--->  授权协议
URL:            [email protected]
buildroot:      %{_topdir}/BUILDROOT   #--->  指定生产车间(非常重要,因在生成rpm过程中执行make install时会把软件安装到此路径,打包时同样依此目录为“根目录”进行操作)
Source0:        %{Name}-%{Version}.tar.gz   #---> 指定源码编译的文件,默认路径:%{_topdir}/SOURCES  
SOURCE1:        %{CONFIGFILE}  #---> 指定要替换的配置文件,默认路径:%{_topdir}/SOURCES  
BuildRequires:      gcc,make,automake,binutils  #--->  软件依赖信息
Requires:      bash >= 2.0 #--->  定义软件依赖信息,该rpm包所依赖的软件包名称,可用>=或<=表示大或小于特定版本
%description
This is %{Name} .....Just a test rpm suite.............
 
#安装前的准备工作,此处可写入执行脚本
%pre
useradd %{Name} -s /sbin/nologin
 
#安装前的准备:此段默认将Source目录内的源码包在BUILD目录解压为%{Name}-%{Version}格式的目录
%prep
%setup -q -n %{Name}-%{Version}  #---> 参数:-c 解压缩之前先产生目录,-n newdir 将软件包解压在newdir目录
 
#定义config动作
%build
./configure --prefix=%{InstallPath} --user=%{Name} --group=%{Name} 
make %{?_smp_mflags}
 
#定义执行make install时的动作
%install
rm -rf %{buildroot} #---> 删除生产车间内的残留文件
%{__make} install DESTDIR=%{buildroot} #---> 将软件安装至指定的目录
%{__install} -p -D -m 0755  %{SOURCE1} %{buildroot}/usr/local/nginx/conf/%{CONFIGFILE} #--->  替换指定的配置文件
 
#赋予文件的默认权限及设置需在RPM包中保留的文件
%files
%doc
%defattr(-,root,root,-)  #---> 指定包装文件属性,分别是(mode,owner,group),- 表示默认值,文本文件是0644,可执行文件0755
%attr(0755,root,root) /usr/local/nginx/sbin/nginx  #--->  针对单一文件设置权限
%{_prefix}/*
%{_prefix}/local/nginx/conf/%{CONFIGFILE}
 
#制作完成后的清理工作
%clean
rm -rf %{buildroot}
 
#安装后的执行工作,此处可写入执行脚本
%post
chkconfig --add nginx
chkconfig --level 345 nginx on
 
#变更日志
%changelog
 
#---------------------------------------------------------------------------------------------
#    2.1 介绍区域的SOURCE0下增加如下
#    Source0:        %{name}-%{version}.tar.gz 
#    Source1:        index.html 
#    Source2:        init.nginx 
#    Source3:        fastcgi_params 
#    Source4:        nginx.conf 
 
#    2.2 安装区域增加如下
#    make install DESTDIR=%{buildroot} 
#    %{__install} -p -D %{SOURCE1} %{buildroot}/usr/html/index.html  #%{__install}这个宏代表install命令
#    %{__install} -p -D -m 0755 %{SOURCE2} %{buildroot}/etc/rc.d/init.d/nginx 
#    %{__install} -p -D %{SOURCE3} %{buildroot}/etc/nginx/fastcgi_params 
#    %{__install} -p -D %{SOURCE4} %{buildroot}/etc/nginx/nginx.conf 
 
 
将脚本制作成为RPM包的例子:
 
Name: eee
Version: 1
Release: 1%{?dist}
Summary:1111
 
License:GPLv2
URL:    inmoonlighy.11.cn
Source0: eee
 
%description
.....
 
%install
rm -rf %{buildroot}
mkdir -p %{buildroot}/bin/
cp -rf  %{SOURCE0} %{buildroot}/bin
 
%files
/bin/eee
 
%changelog
 
#注:安装时失败应加“rpm -ivh --force ***.rpm 进行尝试”
#---------------------------------------------------------------------------------------------
#rpmbuild:
#    -bl          检查spec中的%file段来查看文件是否齐全
#    -ba         建立二进制包&源码
#    -bb         建立二进制包
#    -bp        执行到 prep 阶段
#    -bc         执行到 build 阶段
#    -bi         执行到 install 阶段

#制作:    cd /usr/src/redhat/SPECS/ ; rpmbuild -ba nginx.spec   --> 生成:/usr/src/redhat/RPMS/i386/nginx-1.2.1-1.el5.ngx.i386.rpm
#测试:    rpm -ivh /usr/src/redhat/RPMS/i386/nginx-1.2.1-1.el5.ngx.i386.rpm
 

《使用cpack打包源码并编写自动化脚本上传到仓库》
https://blog.csdn.net/weixin_34319640/article/details/87972767

报错记录


make: *** No rule to make target `install’


(摘自:https://www.cnblogs.com/chenyaling/p/5806965.html)

遇到最大的坑就是%install部分的make install

网上的资料是这样说的:

本段是安装段,其中的命令在安装软件包时将执行,如make install命令。
%makeinstall 这不是关键字,而是rpm定义的标准宏命令。也可以使用非标准写法:引用make DESTDIR=R P M B U I L D R O O T i n s t a l l 或引用 m a k e p r e f i x = RPM_BUILD_ROOT install或引用make prefix=RPM BUILD ROOTinstall或引用makeprefix=RPM_BUILD_ROOT install
需要说明的是,这里的%install主要就是为了后面的%file服务的。所以,还可以使用常规的系统命令:
引用install -d $RPM_BUILD_ROOT/
cp -a * $RPM_BUILD_ROOT/
但是我每次使用make install时候都会报错make: *** No rule to make target ‘install’。换成install -d的写好就可以,我也不明白是为什么。

后来发现,使用make install是在已经编写过Makefile的前提下进行的,报错中的install其实是Makefile中的写好的target。

举个例子,在Makefile中编写,如下:

install-oem:
mkdir -p $(LIBDIR)/xsconsole/plugins-oem
则在%install中就可以这样写:

%install
make install-oem DESTDIR=$RPM_BUILD_ROOT
否则,当然会报错找不到target。

Teacher Zhu said that using Makefile is a bit outdated now. I think the Makefile is very annoying. If I make a mistake, I have to repackage it to generate a compressed file. I can't stand it after making too many changes. It's better to write the content directly in %install, which is also convenient to change.
 

Error: unpacking of archive failed on file when installing rpm package

https://blog.csdn.net/qq_36911595/article/details/112668637

Guess you like

Origin blog.csdn.net/bandaoyu/article/details/128597343