Create an RPM package
Summary
Rpm: RedHat package manager is a binary file and is installed (it may be more suitable for decompression, but it also includes database operations and dependency judgment) software packages that can be run directly, so they are platform-related, that is, software packages that exactly correspond to the operating system of the architecture.
This document mainly introduces the following aspects:
L simple RPM command
L RPM package creation process
L dynamic library analysis cannot be found
L relationship between RPM package and yum
1. Simple RPM usage command
Installation: rpm-ivh xxxxx. RPM // one of the -- prefix parameters may (explained later) be used to modify the installation path.
View: rpm-q xxxx // note that only the RPM package name does not contain the suffix.
View package information: rpm-qip xxxx [. RPM] // you can view information about installed packages and uninstalled packages.
View the files in the package: rpm-qlp XXXX [. RPM] // view the files in the package, and you can know the installation path of the package.
Uninstall: rpm-e xxxx
2. Create an RPM package
The rpmbuild tool is used to create rpm. The common usage is as follows:
Rpmbuild-v-bb xxx. spec //-V indicates the output details.-BB indicates only binary files, and-Ba indicates source code and binary files.
Spec file: defines the specific specifications of the packaging process, such as the package to be packaged, the package to be packaged, and the compilation process.
The general creation of the RPM package requires the following folders:
Mkdir-P ~ /Rpmbuild/{build, rpms, srpms, Specs, sources} // The upper-level directory of rpmbuild is not required, but the structure is clearer in general.
Build: This directory is the one that can be decompressed after source code extraction. The configure, make, and install files in the decompressed source code file are RPMs: this directory is used to save the binary RPM package after the package is successful. Generally, the system creates a directory such as RPMS/x86_86 Based on the Architecture During the packaging process.
Srpms: This directory is used to save the generated source code RPM package (in fact, the same as the tar package)
Specs: Save the spec File
Sources: Saving source code file xxx.tar.gz
In fact, there is also a buildroot directory, but it does not exist on Redhat by default. This folder is used as the install directory during the packaging process, these directories are defined by the corresponding macro, such as _ builddir. You can use the RPM -- showrc command to view the macros used by rpmbuild. Or directly use rpm -- eval % _ bindir
To view a single definition.
Let's take a look at the example below: (pack MySQL)
% Define debug_package % {nil} // No debug package
% Define installpath/usr/local
Summary: MySQL open source database
Name: Tb-mysql-server // name of the package to be played
Version: 5.1.48 // version
Release: 78. EL5 // This is mainly modified by SVN.
Source0: zookeeper name=-zookeeper version=.tar.gz // source code package
License: GPL
GROUP: Applications/databases
# Perfix:/usr/local // If the label is defined, the package can be relocate, that is, when installing the RPM package, you can specify the installation path (which may cause dynamic library search problems). Otherwise, it will be installed in the directory specified by the configure prefix.
Autoreqprov: No // automatic dependent package and packet detection. This is canceled because some dependent packages are not installed through RPM (actually installed ), if rpm is not installed, the installation of the installation package may fail. You can also use -- nodeps to forcibly cancel these dependencies for installation.
Provides: MySQL, MySQL-server, mysqld
Buildroot: % {_ topdir}/build/% {name}-root // define the install directory during RPM Creation
% Description
The MySQL (TM) software delivers a very fast, multi-threaded, multi-user,
And robust SQL (Structured Query Language) databaseserver. MySQL Server
Is intended for mission-critical, heavy-loadproduction systems as well
As for embedding into mass-deployed software.
% Prep
% Setup-Q // decompress the source code package to the build directory.
% Build
Cflags = "-O3-G" cxx = gcccxxflags = "-O3-g-felide-constructors \
-Fno-exceptions-fno-rtti "ldflags ="-R % installpath/lib/MySQL "./configure -- prefix = % installpath \
-- With-extra-charsets = all \
-- With-plugins = partition, heap, Innobase, innodb_plugin, MyISAM, myisammrg, CSV -- enable-plugin er
Make-J 8
% Install
Rm-RF $ rpm_build_root // when the buildroot field is defined, rpm_build_root corresponds to this variable.
Make destdir = $ rpm_build_root install // destdir specifies the installation steps during packaging and where the file is installed. This is not the path where the software package was last installed on the computer by rpm-IVH. You can also use the -- prefix option here. The two methods are different, when destdir is used, the system will add the -- prefix specified by configure (this is the path for the RPM package to be installed on our computer, if not specified, the default value of configure is/usr/local, while the -- prefix of make install is an absolute value. to use it, you must use all paths instead of destdir, that is, it must be prefix = destdir/usr/local (/usr/local is the prefix option of configure)
Install-D-m644 support-files/my-medium.cnf $ rpm_build_root/% installpath/share/MySQL/My. CNF // copy frequently used preparation files to the installation package
% Post // script executed after installation
#/Sbin/ldconfig
% Postun // script executed after uninstallation
#/Sbin/ldconfig
% Clean
# Rm-RF $ rpm_build_root // clear the installation directory during packaging
% Files
% Defattr (-, root, root) // specify the default attribute of the file to be packaged.-indicates the default value of the system, indicating the mode, owner, and group.
% Installpath // specify the files after install and hit the RPM package. $ rpm_build_root will be added to the Path Matching here,
Then level-1 matching is performed to find the corresponding file.
Note: The RPM packaging process has nothing to do with its installation process. Therefore, all the paths specified here are only in the packaging process (except for the -- prefix option of configure ), if destdir = $ rpm_build_root is not specified during make install, the install path during packaging is the -- prefix path of configure. This is generally not what we want, so we will re-specify it. There are many identifiers in the files phase. For example, if the file is defined as config and the Dir is different, their behavior may be different. With rpmbuild, the file name of the source code package is strictly in the form of name-version.tar.gz, And the decompressed folder must be name-version, because rpmbild uses this information to enter the corresponding directory (which environment variables can be modified by setting, not found yet ).
3. Why the dynamic library cannot be found
When the MySQL RPM package is installed and the client is started, the system prompts that the dynamic library file libmysqlclient. So cannot be found. The simplest solution to this problem is to export LD_LIBRARY_PATH = $ LD_LIBRARY_PATH:/**/lib/MySQL/(directory of the file) before startup)
A better method may be to encapsulate the script, but if the original Startup file is a script, we seem to have to modify the script file. This operation is troublesome. (This variable is a session variable. Therefore, after the session is completed, the variable is cleared, and the variable is safer)
Solution 2: When the program looks for the library file, in addition to the path specified by LD_LIBRARY_PATH, it will also find/usr/lib in the system directory, /usr/lib64 directory (files in the/usr/local/lib directory are not searched by default ), therefore, we often install the yum library files in the/usr/lib system directory. The root cause of this method is/sbin/ldconf, this tool will put/etc/lD. so. all the dynamic library files under the directory specified in the conf file are loaded to the lD. so. in the cache system cache file, the content of this file is probably in the form of K-V, the key is to specify a new name for this library file, and the value is the location of this file, so we can simply guess that when we install a dynamic library file using Yum or rpm, they will execute ldconfig once in the % post phase. In this way, you can load the new library file to lD. So. cache. So the process of searching for the dynamic library is as follows: first, find the directory of the Environment Variable LD_LIBRARY_PATH. If the directory lD. So. cache is not found, an error will be reported if it is not found.
That is, when this error is reported, we can first check whether the library file exists and what the path is, and then check whether LD_LIBRARY_PATH has this path. If not, then run ldcofig-p | grep XXX. If neither of them exists, run ldconfig-V to check which directories are loaded by ldconfig and whether the directories of the library files are in it.
Therefore, the second solution is to write the directory to the lD. So. conf file, and then execute ldconfig again;
Note: You can directly load the path to LD by executing ldconfg/path. so. cache file, but this is not persistent. When someone runs ldconfig again, this information will be lost because it is not written to lD. so. CONF file.
Now there is a problem. Do we need to write lD. So. conf + ldconfig in the directory specified by ourselves after installing the library file through the source code? The following describes how to install MySQL. After I directly installed MySQL through the source code, I found that the lD. So. conf file does not contain the directory of its library file ~ /Mymysql/lib/MySQL (of course ldconfig-P is not found), and LD_LIBRARY_PATH is empty at this time, but it can run normally (Note: Only MySQL, mysqladmin will use these library files, and mysqld will not use [both of them can be used to specify whether to use dynamic libraries during Configure. Here we assume that mysqld uses static resources and MySQL uses dynamic resources, this is also the default configuration]). It is strange why the file cannot be found in the above two methods, but it can run normally (and when I install my package binary installation package, during installation, you have specified a directory for installation, but cannot run MySQL or libmysqlclien. so: No
Found ~~~). Finally, a-rpath compilation option is found by viewing the MySQL MAKEFILE file, and its function is known through the network lookup: during the compilation process, the path of the dynamic library is directly written to the target program, this is because the location of the library file must be specified during the connection operation (-L/xxxx/lib, which only refers to the search during the connection, but cannot be effective for the search during the runtime ), when we use the source code for installation, configure specifies where the program is installed. This is an absolute path, so it can be written into the final executable file. This option can also be specified through ldflags = "-r/XXX/lib.
This is why the source code package can be installed to the specified location, but the Binary Package cannot. Of course, we can also implement this by writing lD. So. conf:
% Post
Target = 'rpm-QL rel_mysql | head-N 1'
Conffile =/etc/lD. So. conf
If! Grep-Q $ target/lib/MySQL $ conffile; then
# Append
Echo $ target/lib/mysql> $ conffile
Fi
/Sbin/ldconfig
% Postun
/Sbin/ldconfig
After the package is successfully installed, run the following command to lD. so. the conf file is written to the lib directory. The directory of this row is not cleared when the package is uninstalled, because the directory will not be loaded to the LD once the file is deleted. so. cache. This method has advantages and disadvantages. For example, when we compile mysql-proxy, we need a higher version of glib library, and this basic library does not dare to be upgraded at will, although their versions are different, however, when a library file is installed, an ln-s operation will be executed to remove the version information and only provide a relative major version information, such as 2.12 and 2.86, in the end, ln is used as a 2.0 connection file, and ldconfig uses the 2.0 name to create a K-V, that is, ldconfig.
There will be two identical K in the cache. Which one will be used in the end? (No answer yet) Will you find that the first real version cannot meet your requirements? If so, this can meet our requirements for the higher version, but the previous use of the lower version of the software will not fail to find the higher version, so it is possible to directly use the higher version of
Library, which may be incompatible.
Therefore, you may want to update the basic library unless you are sure to delete the old one and use the new one. Otherwise, it is best not to update the basic library to make a software available, in this case, using-rpath may be a better choice.
In summary, we can conclude that the program can search for dynamic libraries in three ways during running, the first method is specified by-rpath during compilation (the relocate function of the RPM package cannot be used); the second method is LD_LIBRARY_PATH (this method must be specified every time it is run and can be encapsulated by scripts ); third, install them to the/usr directory, run ldconfig, or install them to another directory, and then write the Directory into lD. so. CONF file, and then ldconfig.
If the current software uses its own library files, it generally uses the-rpath method, the RPM package method generally does not support relocate (the reason is also the possible cause of problems caused by dynamic libraries ).
Note: You must also search for dynamic library files during compilation. This has nothing to do with the runtime search. To make the compilation pass, you must use-I,-l to specify it, however, you must specify the default mode for running search. It has nothing to do with compilation.
4. Conditional dependency
% If % {ERL} = 0
Buildrequires: cmake, boost-devel = 1.33.1
% Else
Buildrequires: cmake, boost-devel = 1.41.0
% Endif
Then, in rpmbuild -- Define "_ topdir $ {home}/rpmbuild"-d "ERL $ ERL", define the variable through-D.
5. Relationship between rpm and yum
Yum is only used to solve the RPM package dependency. It will automatically download and install the RPM dependent package, and yum is absolutely unrelocate.
References
Http://www.linuxfly.org/post/137/