This shows you the differences between two versions of the page.
rpm [2014/11/21 18:14] k2patel [General RPM Command] |
rpm [2020/08/10 02:35] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== RPM ====== | ||
- | Package management system few tips / trick to build / modify / work with packages. \\ | ||
- | Many hints information taken from original site [[http://rpm.org/ | RPM]] | ||
- | |||
- | ==== RPM Common Command ==== | ||
- | |||
- | ^ Syntax ^Description^ | ||
- | | rpm -ivh {rpm-file} | Install the package | | ||
- | | rpm -Uvh {rpm-file} | Upgrade package | | ||
- | | rpm -ev {package} | Erase/remove/ an installed package | | ||
- | | rpm -ev --nodeps {package} | Erase/remove/ an installed package without checking for dependencies | | ||
- | | rpm -qa | Display list all installed packages | | ||
- | | rpm -qi {package} | Display installed information along with package version and short description | | ||
- | | rpm -qf {/path/to/file} | Find out what package a file belongs to i.e. find what package owns the file | | ||
- | | rpm -qc {pacakge-name} | Display list of configuration file(s) for a package | | ||
- | | rpm -qcf {/path/to/file} | Display list of configuration files for a command | | ||
- | | rpm -qa --last | Display list of all recently installed RPMs | | ||
- | | rpm -qpR {.rpm-file} | Find out what dependencies a rpm file has | | ||
- | | rpm -qR {package} | ::: | | ||
- | | rpm -qR bash | ::: | | ||
- | ==== How to Print .spec file from RPM ==== | ||
- | |||
- | <code bash> | ||
- | rpm --scripts -qp <rpmfile> | ||
- | </code> | ||
- | |||
- | ==== First RPM ==== | ||
- | |||
- | Name of Package : libtorrent\\ | ||
- | Building it in folder "/usr/local/src/libtorrent"\\ | ||
- | <code bash> | ||
- | mkdir /usr/local/src/libtorrent | ||
- | cd /usr/local/src/libtorrent | ||
- | mkdir BUILD RPMS SOURCES SPECS SRPMS | ||
- | </code> | ||
- | |||
- | Creating macro not bad idea. | ||
- | <code bash | /usr/local/src/libtorrent/.rpmmacros> | ||
- | %packager Ketan Patel | ||
- | </code> | ||
- | |||
- | Get Sources from [[http://libtorrent.rakshasa.no/ | libtorrent]]\\ | ||
- | Place it in "/usr/local/src/libtorrent/SOURCES"\\ | ||
- | I have used following method. | ||
- | <code bash> | ||
- | cd /usr/local/src/libtorrent/SOURCES | ||
- | svn co svn://rakshasa.no/libtorrent/trunk/libtorrent libtorrent | ||
- | tar -cvf /usr/local/src/libtorrent/SOURCES/libtorrent.tar.gz libtorrent | ||
- | </code> | ||
- | Considering building rtorrent at non standard location. | ||
- | |||
- | NOTE : **Please make sure code below has some SUSE Based Customization** | ||
- | |||
- | <code bash | /usr/local/src/libtorrent/SPECS/libtorrent.spec> | ||
- | %define name libtorrent | ||
- | %define srcdir /usr/local/src | ||
- | %define _topdir %{srcdir}/libtorrent | ||
- | |||
- | |||
- | summary: rTorrent | ||
- | name: libtorrent | ||
- | Source: libtorrent.tar.gz | ||
- | License: GPL | ||
- | version: 1 | ||
- | release: 1 | ||
- | Group: System/Utils | ||
- | Prefix: /opt/libtorrent | ||
- | buildarch: x86_64 | ||
- | BuildRoot: %{prefix}/%{name}-%{version}-%{release}-%{buildarch}-root | ||
- | %define lib %{prefix}/lib64 | ||
- | %define include %{prefix}/include | ||
- | Provides: libtorrent | ||
- | Requires: ncurses, libcppunit-devel | ||
- | AutoReqProv: no | ||
- | |||
- | |||
- | %description | ||
- | libtorrent is a BitTorrent client for ncurses, using | ||
- | the libtorrent library. The client and library is | ||
- | written in C++ with emphasis on speed and efficiency, while delivering | ||
- | equivalent features to those found in GUI based clients in an ncurses | ||
- | client. | ||
- | |||
- | %prep | ||
- | %setup -q -n libtorrent | ||
- | |||
- | |||
- | %build | ||
- | chmod 755 autogen.sh | ||
- | ./autogen.sh | ||
- | %{suse_update_config -f} | ||
- | autoreconf -fiv | ||
- | ./configure --prefix=%{prefix} --libdir=%{lib} | ||
- | make prefix=$RPM_BUILD_ROOT | ||
- | |||
- | %install | ||
- | rm -rf %{buildroot} | ||
- | make DESTDIR=$RPM_BUILD_ROOT install | ||
- | rm -rf $RPM_BUILD_ROOT/%{prefix}/usr | ||
- | |||
- | |||
- | %clean | ||
- | make clean | ||
- | rm -rf %{buildroot} | ||
- | |||
- | %files | ||
- | %defattr(-,root,root,-) | ||
- | %doc README | ||
- | /opt/libtorrent/lib64/* | ||
- | /opt/libtorrent/include/* | ||
- | |||
- | %post | ||
- | echo "/opt/libtorrent/lib64/" > /etc/ld.so.conf.d/libtorrent.conf | ||
- | ldconfig | ||
- | |||
- | %postun | ||
- | rm -rf %{prefix} | ||
- | rm /etc/ld.so.conf.d/libtorrent.conf | ||
- | ldconfig | ||
- | |||
- | %Changelog | ||
- | * Mon Nov 08 2010 Seriously, Check release son!! | ||
- | Initial Build | ||
- | </code> | ||
- | |||
- | == Building Actual RPM == | ||
- | <code bash> | ||
- | cd /usr/local/src/libtorrent | ||
- | </code> | ||
- | <code bash> | ||
- | rpmbuild -v -bb --clean SPECS/libtorrent.spec | ||
- | </code> | ||
- | OR | ||
- | <code bash> | ||
- | rpmbuild -ba SPECS/libtorrent.spec | ||
- | </code> | ||
- | == Test Your RPM == | ||
- | <code bash> | ||
- | rpm -Vp RPMS/x86_64/libtorrent-1-1.x86_64.rpm | ||
- | </code> | ||
- | |||
- | ==== Sample RPM ==== | ||
- | <code bash | sample.spec> | ||
- | Name: xgauguin-support | ||
- | Summary: xGauguin support metapackage | ||
- | Version: 20110513 | ||
- | Release: 1.blip | ||
- | Vendor: lithiumfox | ||
- | License: none | ||
- | Group: Applications | ||
- | URL: http://lithiumfox.com | ||
- | BuildRoot: %{_tmppath}/%{name}-%{version}-%(id -u -n) | ||
- | BuildArch: noarch | ||
- | Requires: nginx, perl(Image::Size), perl(Params::Validate), perl(DateTime::Locale), perl(Class::Load), perl(parent), perl(DateTime::TimeZone), perl(Class::Singleton), perl(Test::Exception), perl(DateTime), perl(Image::Magick), perl(GD), perl(LWP), ImageMagick, gd, yum-utils | ||
- | |||
- | %description | ||
- | Gauguin supporting packages | ||
- | |||
- | %install | ||
- | [ "%{buildroot}" != "/" ] && %{__rm} -rf %{buildroot} | ||
- | %{__mkdir_p} %{buildroot}%{_localstatedir}/www/releases | ||
- | %{__mkdir_p} %{buildroot}%{_localstatedir}/tmp/cache | ||
- | |||
- | %pretrans | ||
- | ## Force installation of conflicts | ||
- | # libxml2.i386, perl-Locale-Codes | ||
- | if $( ! rpm -q libxml2.i386 > /dev/null 2>&1) | ||
- | then | ||
- | | ||
- | yumdownloader libxml2.i386 > /dev/null 2>&1 | ||
- | %{__rm} /var/lib/rpm/__db.000 > /dev/null 2>&1 | ||
- | rpm --force -ivh libxml2*.rpm | ||
- | %{__rm} libxml2*.rpm > /dev/null 2>&1 | ||
- | fi | ||
- | |||
- | if $( ! rpm -q perl-Locale-Codes > /dev/null 2>&1) | ||
- | then | ||
- | set -m | ||
- | yumdownloader perl-Locale-Codes > /dev/null 2>&1 | ||
- | %{__rm} /var/lib/rpm/__db.000 > /dev/null 2>&1 | ||
- | rpm --force -ivh perl-Locale-Codes*.rpm > /dev/null 2>&1 | ||
- | %{__rm} libxml2*.rpm > /dev/null 2>&1 | ||
- | fi | ||
- | |||
- | %pre | ||
- | ## Check if vlad user exists, if not add them | ||
- | if $( ! id vlad >/dev/null 2>&1) | ||
- | then | ||
- | groupadd -g 1029 vlad > /dev/null 2>&1 ||: | ||
- | useradd -u 1029 -g 1029 -d /home/vlad -s /bin/bash -p '$1asdf0' -m vlad > /dev/null 2>&1 | ||
- | fi | ||
- | |||
- | ##Add user to sudoers | ||
- | if $( ! grep vlad /etc/sudoers >/dev/null 2>&1) | ||
- | then | ||
- | echo "vlad ALL=NOPASSWD: /etc/init.d/nginx" >> /etc/sudoers | ||
- | fi | ||
- | |||
- | %post | ||
- | ##Add nginx to startup | ||
- | chkconfig --level 345 nginx on | ||
- | |||
- | ##Create symlink for nginx.conf | ||
- | if [ ! -h /etc/nginx/nginx.conf ] | ||
- | then | ||
- | ln -f -s %{_localstatedir}/www/prod/gauguin/current/conf/nginx-prod.conf %{_sysconfdir}/nginx/nginx.conf | ||
- | fi | ||
- | |||
- | |||
- | %files | ||
- | %defattr(-,root,root) | ||
- | %attr(-,vlad,-) %{_localstatedir}/www/prod/xgauguin | ||
- | %attr(777,-,-) %{_localstatedir}/tmp/xgauguin-cache | ||
- | |||
- | %changelog | ||
- | * Fri May 13 2010 Jason Thomas <jason@lithiumfox.com> - %{version} | ||
- | - Initial package creation | ||
- | </code> | ||
- | |||
- | === changelog === | ||
- | You can use following one liner for changelog. | ||
- | <code bash> | ||
- | awk '{print "*", $1, $2, $3, $6, "Jason Thomas <jason@lithiumfox.com>","-", "%{version}""\n""- initial rpm creation"}' <(date) | ||
- | </code> | ||
- | |||
- | |||
- | ==== Good Reading ==== | ||
- | |||
- | [[http://fedoraproject.org/wiki/How_to_create_an_RPM_package | Fedora Package]]\\ | ||
- | [[http://en.opensuse.org/openSUSE:Build_Service_Tutorial | OpenSUSE Build Service]]\\ | ||
- | [[http://rpm.org/wiki/Docs#PackagerDocumentation | RPM Official]] | ||
- | |||
- | ==== General RPM Command ==== | ||
- | |||
- | === List Content === | ||
- | <code bash> | ||
- | rpm -qpl file.rpm | ||
- | </code> | ||
- | |||
- | |||
- | ==== Error on Building ==== | ||
- | === module: command not found === | ||
- | Try running following command and then execute rpmbuild will resolve the issue. | ||
- | <code bash> | ||
- | source /etc/profile.d/modules.sh | ||
- | </code> | ||
- | ==== MOCK ==== | ||
- | |||
- | Mock is a really nice tool to generate RPM cleanly.\\ | ||
- | I used KVM / MOCK to build RPM for my own reasons but you can use just mock and clean env. after every build.\\ | ||
- | |||
- | General Details Available at [[ http://fedoraproject.org/wiki/Projects/Mock | Mock Project Page ]] | ||
- | |||
- | Rather then guessing i have pasted all the command i have used to build RPM from srpm.\\ | ||
- | Using / Generating Spec require another tutorial this is strictly about some work around and keeping env. between transaction. | ||
- | |||
- | |||
- | == Install Mock == | ||
- | <code bash> | ||
- | yum install mock | ||
- | </code> | ||
- | |||
- | == Add user to group == | ||
- | I am using rpmbuild user. | ||
- | <code bash> | ||
- | usermod -a -G mock rpmbuild | ||
- | </code> | ||
- | |||
- | == Initialize Mock == | ||
- | Before you work on anything Please initialize the environment.\\ | ||
- | It is good practice to initialize Environment between every build cycle to clean any possible left over or unforeseen issue. | ||
- | |||
- | <code bash> | ||
- | mock --init -r epel-5-x86_64 | ||
- | </code> | ||
- | |||
- | === su to user === | ||
- | You can not run mock as root so .... | ||
- | <code bash> | ||
- | su rpmbuild | ||
- | </code> | ||
- | |||
- | == Install required packages == | ||
- | I found that installed package stays installed during cycles.\\ | ||
- | So you do not require to install packages every time unless you initialize env. | ||
- | |||
- | <code bash> | ||
- | /usr/bin/mock --install -r epel-5-x86_64 perl-libwww-perl.noarch | ||
- | </code> | ||
- | |||
- | == Building SRPM == | ||
- | <code bash> | ||
- | mock -r epel-6-x86_64 --spec icinga-web.spec --sources=../SOURCES/ --resultdir=../RPMS/ --buildsrpm | ||
- | </code> | ||
- | ==== Copying Files ==== | ||
- | <note important>Dont scratch over --copyin check spelling one more time</note> | ||
- | <code bash> | ||
- | /usr/bin/mock -r epel-5-x86_64 --copyin pgpool-II-3.1.2.tar.gz /tmp/ | ||
- | </code> | ||
- | |||
- | |||
- | == Get SRPM == | ||
- | <code bash> | ||
- | cd ~ | ||
- | wget http://ftp.arix.com/cpan2rpm-2.028-1.src.rpm | ||
- | </code> | ||
- | |||
- | == Finally Building RPM == | ||
- | <note> | ||
- | --no-clean : this will keep your files intact in build env.\\ | ||
- | --no-cleanup-after : i wanted to keep all work file so i used this just incase. | ||
- | </note> | ||
- | |||
- | <code bash> | ||
- | /usr/bin/mock --rebuild --no-clean --no-cleanup-after -r epel-5-x86_64 cpan2rpm-2.028-1.src.rpm | ||
- | </code> | ||
- | |||
- | In general case result will be stored in '/var/lib/mock/epel-5-x86_64/result/' | ||
- | |||
- | ==== SPEC file Overview ==== | ||
- | |||
- | This is mostly from following URL [[http://fedoraproject.org/wiki/How_to_create_an_RPM_package | Fedora Project]] | ||
- | |||
- | <code text> | ||
- | |||
- | Other useful guides: | ||
- | |||
- | RPM Guide describes how to write a SPEC file. | ||
- | The IBM series "Packaging software with RPM" Part 1, Part 2, and Part 3. | ||
- | Maximum RPM has the most complete information, but is dated. | ||
- | You will need to follow the Fedora guidelines: Package Naming Guidelines, Packaging guidelines, and Package review guidelines. | ||
- | |||
- | Insert comments with a leading "#" character, but avoid macros (beginning with %) that are potentially multiline (as they are expanded first). | ||
- | If commenting out a line, double the percent signs (%%). Also avoid inline comments on the same line as a script command. | ||
- | |||
- | The major tags are listed below. Note that the macros %{name}, %{version} and %{release} can be used to refer to the Name, | ||
- | Version and Release tags respectively. When you change the tag, the macros automatically update to use the new value. | ||
- | |||
- | Name: The (base) name of the package, which should match the SPEC file name. | ||
- | It must follow the Package Naming Guidelines and generally be lowercase. | ||
- | Version: The upstream version number. See Version tag section of the packaging guidelines. | ||
- | If the version contains tags that are non-numeric (contains tags that are not numbers), | ||
- | you may need to include the additional non-numeric characters in the Release tag. | ||
- | If upstream uses full dates to distinguish versions, consider using version numbers of the form yy.mm[dd] (e.g. 2008-05-01 becomes 8.05). | ||
- | |||
- | Release: The initial value should normally be 1%{?dist}. | ||
- | Increment the number every time you release a new package for the same version of software. | ||
- | When a new upstream version is released, change the Version tag to match and reset the Release number to 1. | ||
- | See Release tag section of the packaging guidelines. The optional Dist tag might be useful. | ||
- | |||
- | Summary: A brief, one-line summary of the package. Use American English. Do not end in a period. | ||
- | |||
- | Group: This needs to be a pre-existing group, like "Applications/Engineering"; | ||
- | run "less /usr/share/doc/rpm-*/GROUPS" to see the complete list. | ||
- | Use the group "Documentation" for any sub-packages (e.g. kernel-doc) containing documentation. | ||
- | |||
- | License: The license, which must be an open source software license. | ||
- | Do not use the old Copyright tag. Use a standard abbreviation (e.g. "GPLv2+") and be specific | ||
- | (e.g. use "GPLv2+" for GPL version 2 or greater instead of just "GPL" or "GPLv2" where it's true). | ||
- | See Licensing and the Licensing Guidelines. | ||
- | You can list multiple licenses by combining them with "and" and "or" (e.g. "GPLv2 and BSD"). | ||
- | |||
- | URL: The full URL for more information about the program (e.g. the project website). | ||
- | |||
- | Note: This is not where the original source code came from which is meant for the Source0 tag below. | ||
- | |||
- | Source0: The full URL for the compressed archive containing the (original) pristine source code, | ||
- | as upstream released it. "Source" is synonymous with "Source0". | ||
- | If you give a full URL (and you should), its basename will be used when looking in the SOURCES directory. | ||
- | If possible, embed %{name} and %{version}, so that changes to either will go to the right place. | ||
- | Preserve timestamps when downloading source files. If there is more than one source, name them Source1, | ||
- | Source2 and so on. If you're adding whole new files in addition to the pristine sources, | ||
- | list them as sources after the pristine sources. A copy of each of these sources will be included in any SRPM you create, | ||
- | unless you specifically direct otherwise. See Source URL for more information on special cases (e.g. revision control). | ||
- | |||
- | Patch0: The name of the first patch to apply to the source code. | ||
- | If you need to patch the files after they've been uncompressed, | ||
- | you should edit the files and save their differences as a "patch" file in your ~/rpmbuild/SOURCES directory. | ||
- | Patches should make only one logical change each, so it's quite possible to have multiple patch files. | ||
- | |||
- | BuildArch: If you're packaging files that are architecture-independent (e.g. shell scripts, data files), | ||
- | then add "BuildArch: noarch". The architecture for the binary RPM will then be "noarch". | ||
- | |||
- | BuildRoot: This is where files will be "installed" during the %install process (after the %build process). | ||
- | This is now redundant in Fedora and is only needed for EPEL5. By default, the build root is placed in "%{_topdir}/BUILDROOT/". | ||
- | |||
- | BuildRequires: A comma-separated list of packages required for building (compiling) the program. | ||
- | This field can be (and is commonly) repeated on multiple lines. These dependencies are not automatically determined, | ||
- | so you need to include everything needed to build the program. Some common packages can be omitted, such as gcc. | ||
- | You can specify a minimum version if necessary (e.g. "ocaml >= 3.08"). | ||
- | If you need the file /EGGS, determine the package that owns it by running "rpm -qf /EGGS". | ||
- | If you need the program EGGS, determine the package that owns it by running "rpm -qf `which EGGS`". | ||
- | Keep dependencies to a minimum (e.g. use sed instead of perl if you don't really need perl's abilities), | ||
- | but beware that some applications permanently disable functions if the associated dependency is not present; | ||
- | in those cases you may need to include the additional packages. The "auto-br-rpmbuild" command may be helpful. | ||
- | |||
- | Requires: A comma-separate list of packages that are required when the program is installed. | ||
- | Note that the BuildRequires tag lists what is required to build the binary RPM, | ||
- | while the Requires tag lists what is required when installing/running the program; | ||
- | a package may be in one list or in both. In many cases, | ||
- | rpmbuild automatically detects dependencies so the Requires tag is not always necessary. | ||
- | However, you may wish to highlight some specific packages as being required, or they may not be automatically detected. | ||
- | |||
- | %description: A longer, multi-line description of the program. | ||
- | Use American English. All lines must be 80 characters or less. | ||
- | Blank lines indicate a new paragraph. Some graphical user interface installation programs will reformat paragraphs; | ||
- | lines that start with whitespace will be treated as preformatted text and displayed as is, normally with a fixed-width font. | ||
- | See RPM Guide. | ||
- | |||
- | %prep: Script commands to "prepare" the program (e.g. to uncompress it) so that it will be ready for building. | ||
- | Typically this is just "%setup -q"; a common variation is "%setup -q -n NAME" if the source file unpacks into NAME. | ||
- | See the %prep section below for more. | ||
- | |||
- | %build: Script commands to "build" the program (e.g. to compile it) and get it ready for installing. | ||
- | The program should come with instructions on how to do this. See the %build section below for more. | ||
- | |||
- | %check: Script commands to "test" the program. This is run between the %build and %install procedures, | ||
- | so place it there if you have this section. Often it simply contains "make test" or "make check". | ||
- | This is separated from %build so that people can skip the self-test if they desire. | ||
- | |||
- | %install: Script commands to "install" the program. | ||
- | The commands should copy the files from the BUILD directory %{_builddir} into the buildroot directory, | ||
- | %{buildroot}. See the %install section below for more. | ||
- | |||
- | %clean: Instructions to clean out the build root. Note that this section is now redundant in Fedora and is only necessary for EPEL. | ||
- | Typically this contains only: | ||
- | rm -rf %{buildroot} | ||
- | |||
- | %files: The list of files that will be installed. See the %files section below for more. | ||
- | |||
- | %changelog: Changes in the package. Use the format example above. | ||
- | |||
- | ExcludeArch: If the package does not successfully compile, build or work on a particular architecture, | ||
- | list those architectures under this tag. | ||
- | You can add sections so that code will run when packages are installed or removed on the real system | ||
- | (as opposed to just running the %install script, which only does a pseudo-install to the build root). | ||
- | These are called "scriptlets", and they are usually used to update the running system with information from the package. | ||
- | See the "Scriptlets" section below for more. RPM also supports the creation of several packages (called subpackages) | ||
- | from a single SPEC file, such as name-libs and name-devel packages. | ||
- | |||
- | Do not use these tags: | ||
- | |||
- | Packager | ||
- | Vendor | ||
- | Copyright | ||
- | Do not create a "relocatable" package; they don't add value in Fedora and make things more complicated. | ||
- | </code> | ||
- | |||
- | ==== SPEC file sections explained ==== | ||
- | |||
- | <code text> | ||
- | %prep section | ||
- | The %prep section describes how to unpack the compressed packages so that they can be built. | ||
- | Typically, this includes the "%setup" and "%patch" commands with reference to the Source0 | ||
- | (and Source1 etc.) lines. See the Maximum RPM section on %setup and %patch for more details. | ||
- | |||
- | The %{patches} and %{sources} macros are available since RPM 4.4.2 and are useful | ||
- | if you have a large list of patches or sources: | ||
- | |||
- | for p in %{patches}; do | ||
- | ... | ||
- | done | ||
- | However, keep in mind that using these will make your SPEC incompatible with RPMS | ||
- | used in RHEL and other RPM-based dirstributions. | ||
- | |||
- | %prep section: %setup command | ||
- | The "%setup" command unpacks a source package. Switches include: | ||
- | |||
- | -q : Suppress unecessary output. This is commonly used. | ||
- | |||
- | -n name : If the Source tarball unpacks into a directory whose name is not the RPM name, | ||
- | |||
- | this switch can be used to specify the correct directory name. For example, | ||
- | if the tarball unpacks into the directory FOO, use "%setup -q -n FOO". | ||
- | |||
- | -c name : If the Source tarball unpacks into multiple directories instead of a single directory, | ||
- | this switch can be used to create a directory named name and then unpack into it. | ||
- | There are more %spec options if you are unpacking multiple files, | ||
- | which is primarily useful if you are creating subpackages (see below). The key ones are: | ||
- | |||
- | -a number Only unpack the Source directive of the given number after changing directory | ||
- | (e.g. "–a 0" for Source0). | ||
- | -b number Only unpack the Source directive of the given number before changing directory | ||
- | (e.g. "–b 0" for Source0). | ||
- | -D Do not delete the directory before unpacking. | ||
- | -T Disable the automatic unpacking of the archives. | ||
- | |||
- | %prep section: %patch commands | ||
- | The "%patch0" command applies Patch0 (and %patch1 applies Patch1 etc.). | ||
- | Patches are the normal method of making necessary changes to the source code for packaging. | ||
- | The usual "-pNUMBER" option applies, which passes that argument onto the program patch. | ||
- | |||
- | Patch file names often look like "telnet-0.17-env.patch", | ||
- | which is the format %{name} - %{version} - REASON.patch" (though sometimes version is omitted). | ||
- | Patch files are typically the result of "diff -u"; | ||
- | if you do this from the subdirectory of ~/rpmbuild/BUILD then you won't have to specify a -p level later. | ||
- | |||
- | This is a typical procedure for creating a patch for a single file: | ||
- | |||
- | cp foo/bar foo/bar.orig | ||
- | vim foo/bar | ||
- | diff -u foo/bar.orig foo/bar > ~/rpmbuild/SOURCES/PKGNAME.REASON.patch | ||
- | If editing many files, one easy method is to copy the | ||
- | whole subdirectory underneath BUILD and then do subdirectory diffs. | ||
- | After you have changed directory to "~rpmbuild/BUILD/NAME", do the following: | ||
- | |||
- | cp -pr ./ ../PACKAGENAME.orig/ | ||
- | ... many edits ... | ||
- | diff -u ../PACKAGENAME.orig . > ~/rpmbuild/SOURCES/NAME.REASON.patch | ||
- | If you edit many files in one patch, you can also copy the original files | ||
- | using some consistent ending such as ".orig" before editing them. | ||
- | Then, you can use "gendiff" (in the rpm-build package) to create a patch with the differences. | ||
- | |||
- | Try to ensure that your patch match the context exactly. | ||
- | The default "fuzz" value is "0", requiring matches to be exact. | ||
- | You can work around this by adding "%global _default_patch_fuzz 2" | ||
- | to revert to the value found in older versions of RPM in Fedora, | ||
- | but it is generally recommended to avoid doing this. | ||
- | |||
- | As explained in Packaging/PatchUpstreamStatus, | ||
- | all patches should have a comment above them in the SPEC file about their upstream status. | ||
- | This should document the upstream bug/email that includes it (including the date). | ||
- | If it is unique to Fedora, you should mention why it is unique. | ||
- | The Fedora Project tries not to deviate from upstream; | ||
- | see PackageMaintainers/WhyUpstream for the importance of this. | ||
- | |||
- | %prep section: Unmodified files | ||
- | Sometimes, one or more of the Source files do not need to be uncompressed. | ||
- | You can "prep" those into the build directory like this (where SOURCE1 refers to the relevant Source file): | ||
- | |||
- | cp -p %SOURCE1 . | ||
- | %build section | ||
- | The "%build" section is sometimes complicated; | ||
- | here you configure and compile/build the files to be installed. | ||
- | |||
- | Many programs follow the GNU configure approach (or some variation). | ||
- | By default, they will install to a prefix of "/usr/local", which is reasonable for unpackaged files. | ||
- | However, since you are packaging it, change the prefix to "/usr". | ||
- | Libraries should be installed to either /usr/lib or /usr/lib64 depending on the architecture. | ||
- | |||
- | Since GNU configure is so common, the macro "%configure" can be used to automatically | ||
- | invoke the correct options (e.g. change the prefix to /usr). Some variation of this often works: | ||
- | |||
- | %configure | ||
- | make %{?_smp_mflags} | ||
- | To override makefile variables, pass them as parameters to make: | ||
- | |||
- | make %{?_smp_mflags} CFLAGS="%{optflags}" BINDIR=%{_bindir} | ||
- | More more information, see "GNU autoconf, automake, and libtool" | ||
- | and | ||
- | "Open Source Development Tools: An Introduction to Make, Configure, Automake, Autoconf" by Stefan Hundhammer. | ||
- | |||
- | Some programs use cmake. See Packaging/cmake. | ||
- | |||
- | %check section | ||
- | If self-tests are available, it is generally a good idea to include them. | ||
- | They should be placed in the %check section (which immediately follows the %build section) | ||
- | instead of within the %build section itself, so that they can be easily skipped when necessary. | ||
- | |||
- | Often, this section contains: | ||
- | |||
- | make test | ||
- | %install section | ||
- | This section involves script commands to "install" the program, | ||
- | copying the relevant files from %{_builddir} to %{buildroot} | ||
- | (which usually means from ~/rpmbuild/BUILD to ~/rpmbuild/BUILDROOT) | ||
- | and creating directories inside %{buildroot} as necessary. | ||
- | |||
- | Some of the terminology can be misleading: | ||
- | |||
- | The "build directory", also known as %{_builddir} is not the same as the "build root", | ||
- | also known as %{buildroot}. Compilation occurs in the former directory, | ||
- | while files to be packaged are copied from the former to the latter. | ||
- | |||
- | During the %build section, the current directory will start at %{buildsubdir}, | ||
- | which is the subdirectory within %{_builddir} that was created during %prep stage. | ||
- | This is usually something like ~/rpmbuild/BUILD/%{name}-%{version}. | ||
- | The %install section is not run when the binary RPM package is installed by the end-user, | ||
- | but is only run when creating a package. | ||
- | Normally, some variation of "make install" is performed here: | ||
- | |||
- | %install | ||
- | rm -rf %{buildroot} | ||
- | make DESTDIR=%{buildroot} install | ||
- | Removal of %{buildroot} is no longer necessary, except for EPEL 5. | ||
- | |||
- | Ideally you should use DESTDIR=%{buildroot} if the program supports it, | ||
- | as it redirects file installations to the specified directory and is exactly | ||
- | what we want to happen during the %install section. | ||
- | |||
- | If the program does not support DESTDIR (and only if), | ||
- | you can workaround it in one of several (inferior) ways: | ||
- | |||
- | Patch the makefile so that is supports DESTDIR. | ||
- | Create directories inside DESTDIR where necessary and submit the patch upstream. | ||
- | |||
- | Use the "%makeinstall" macro. This method might work, but can lead to subtle failures. | ||
- | It expands to something like | ||
- | "make prefix=%{buildroot}%{_prefix} bindir=%{buildroot}%{_bindir} ... install", | ||
- | which can result in some programs failing to work properly. | ||
- | Create directories inside %{buildroot} where necessary. | ||
- | |||
- | Consider using the auto-destdir package. This requires | ||
- | "BuildRequires: auto-destdir", and changing "make install" to "make-redir DESTDIR=%{buildroot} install". | ||
- | This only works well if the installation uses only certain common commands to install files, | ||
- | like cp and install. | ||
- | |||
- | Perform the installation by hand. This would involve creating the necessary directories under | ||
- | %{buildroot} and copying files from %{_builddir} to %{buildroot}. | ||
- | Be especially careful with updates, which often contain new or changed filenames. | ||
- | An example of this procedure: | ||
- | |||
- | %install | ||
- | rm -rf %{buildroot} | ||
- | mkdir -p %{buildroot}%{_bindir}/ | ||
- | cp -p mycommand %{buildroot}%{_bindir}/ | ||
- | As noted in Packaging:Guidelines#Timestamps, | ||
- | try to preserve timestamps if the makefile lets you override commands: | ||
- | |||
- | make INSTALL="install -p" CP="cp -p" DESTDIR=%{buildroot} install | ||
- | |||
- | %files section | ||
- | This section declares which files and directories are owned by the package, | ||
- | and thus which files and directories will be placed into the binary RPM. | ||
- | |||
- | %files basics | ||
- | The %defattr set the default file permissions, and is often found at the start of the %files section. | ||
- | Note that this is no longer necessary unless the permissions need to be altered. The format of this is: | ||
- | |||
- | %defattr(<file permissions>, <user>, <group>, <directory permissions>) | ||
- | The fourth parameter is often omitted. | ||
- | Usually one uses %defattr(-,root,root,-), where "-" uses the default permissions. | ||
- | |||
- | You should then list all the files and directories to be owned by the package. | ||
- | Use macros for directory names where possible, | ||
- | which can be viewed at Packaging:RPMMacros (e.g. use %{_bindir}/mycommand instead of /usr/bin/mycommand). | ||
- | If the pattern begins with a "/" (or when expanded from the macro) | ||
- | then it is taken from the %{buildroot} directory. Otherwise, | ||
- | the file is presumed to be in the current directory (e.g. inside %{_builddir} | ||
- | (such as documentation files that you wish to include). | ||
- | If your package only installs a single file /usr/sbin/mycommand, | ||
- | then the %files section can simply be: | ||
- | |||
- | %files | ||
- | %{_sbindir}/mycommand | ||
- | To make your package less sensitive to upstream changes, | ||
- | declare all files within a directory to be owned by the package with a pattern match: | ||
- | |||
- | %{_bindir}/* | ||
- | To include a single directory: | ||
- | |||
- | %{_datadir}/%{name}/ | ||
- | Note that %{_bindir}/* does not claim that this package owns the /usr/bin directory, | ||
- | but only the files contained within. If you list a directory, | ||
- | then you are claiming that the package owns that directory and | ||
- | all files and subdirectories contained within. Thus, do not list %{_bindir} and | ||
- | be careful of directories that may be shared with other packages. | ||
- | |||
- | An error will occur if: | ||
- | |||
- | a pattern match does not match any file or directory | ||
- | a file or directory is listed or matched more than once | ||
- | a file or directory in the %{buildroot} has not been listed | ||
- | It is also possible to exclude files from a previous match by using the %exclude glob. | ||
- | This can be useful for including almost all of the files included by a different pattern match, | ||
- | but note that it will also fail if it does not match anything. | ||
- | |||
- | %files prefixes | ||
- | You may need to add one or more prefixes to lines in the %files section; | ||
- | seperate them with a space. See Max RPM section on %files directives. | ||
- | |||
- | Usually, "%doc" is used to list documentation files within | ||
- | %{_builddir} that were not copied to %{buildroot}. | ||
- | A README and INSTALL file is usually included. | ||
- | They will be placed in the directory /usr/share/doc/%{name}-%{version}, | ||
- | whose ownership does not need to be declared. | ||
- | |||
- | Note: If specifying a %doc entry, | ||
- | then you can't copy files into the documentation directory during the %install section. | ||
- | If, for example, you want an "examples" subdirectory within the documentation directory, | ||
- | don't use %doc, but instead create the directories and copy files over manually | ||
- | into %{buildroot}%{_defaultdocdir}/%{name}-%{version} during the %install section. | ||
- | They will be correctly marked as documentation. | ||
- | Make sure you include %{_defaultdocdir}/%{name}-%{version}/ as an entry in the %files section. | ||
- | |||
- | Configuration files should be placed in /etc and are normally specified like this | ||
- | (which makes sure user changes aren't overwritten on update): | ||
- | |||
- | %config(noreplace) %{_sysconfdir}/foo.conf | ||
- | If the update uses a non-backwards-compatible configuration format, then specify them like this: | ||
- | |||
- | %config %{_sysconfdir}/foo.conf | ||
- | "%attr(mode, user, group)" can be used for finer control over permissions, | ||
- | where a "-" means use the default: | ||
- | |||
- | %attr(0644, root, root) FOO.BAR | ||
- | If a file is in particular natural language, use %lang to note that: | ||
- | |||
- | %lang(de) %{_datadir}/locale/de/LC_MESSAGES/tcsh* | ||
- | Programs using Locale files should follow the recommended method of handling i18n files: | ||
- | |||
- | find the filenames in the %install step: %find_lang ${name} | ||
- | add the required build dependencies: BuildRequires: gettext | ||
- | use the found filenames: %files -f ${name}.lang | ||
- | These prefixes are not valid in Fedora: %license and %readme. | ||
- | |||
- | %files and Filesystem Hierarchy Standard (FHS) | ||
- | You should follow the Filesystem Hierarchy Standard (FHS). | ||
- | Executables go in /usr/bin, global configuration files go in /etc, | ||
- | libraries go into /usr/lib (or /usr/lib64) and so on. | ||
- | There is one exception: executables that should not normally be executed | ||
- | directly by users or administrators should go in a subdirectory of /usr/libexec, | ||
- | which is referred to as %{_libexecdir}/%{name}. | ||
- | |||
- | Do not install files into /opt or /usr/local. | ||
- | |||
- | Unfortunately, many programs do not follow the FHS by default. | ||
- | In particular, architecture-independent libraries get placed in /usr/lib instead of /usr/share. | ||
- | The former is for architecture-dependent libraries, | ||
- | while the latter is for architecture-independent libraries, | ||
- | which means that systems with different CPU architectures can share /usr/share. | ||
- | There are many exceptions in Fedora (such as Python and Perl), | ||
- | but Fedora applies this rule more strictly than some distributions. | ||
- | rpmlint will generally complain if you put anything other than ELF files into /usr/lib. | ||
- | |||
- | %files example | ||
- | Here's a simple example of a %files section: | ||
- | |||
- | %files | ||
- | %doc README LICENSE | ||
- | %{_bindir}/* | ||
- | %{_sbindir}/* | ||
- | %{_datadir}/%{name}/ | ||
- | %config(noreplace) %{_sysconfdir}/*.conf | ||
- | Finding duplicates | ||
- | You can list any duplicates of two binary packages by doing: | ||
- | |||
- | cd ~/rpmbuild/RPMS/ARCH # Substitute "ARCH" for your architecture | ||
- | rpm -qlp PACKAGE1.*.rpm | sort > ,1 | ||
- | rpm -qlp PACKAGE2.*.rpm | sort > ,2 | ||
- | comm -12 ,1 ,2 | ||
- | Scriptlets | ||
- | When an end-user installs the RPM, you may want some commands to be run. | ||
- | This can be achieved through scriptlets. See Packaging/ScriptletSnippets. | ||
- | |||
- | Scriptlets can be run: | ||
- | |||
- | before (%pre) or after (%post) a package is installed | ||
- | before (%preun) or after (%postun) a package is uninstalled | ||
- | at the start (%pretrans) or end (%posttrans) of a transaction | ||
- | For example, every binary RPM package that stores shared library files | ||
- | in any of the dynamic linker's default paths, must call ldconfig in %post and %postun. | ||
- | If the package has multiple subpackages with libraries, | ||
- | each subpackage should also perform the same actions. | ||
- | |||
- | %post -p /sbin/ldconfig | ||
- | %postun -p /sbin/ldconfig | ||
- | If only running a single command, then the "-p" option runs the adjacent | ||
- | command without invoking the shell. However, for several commands, | ||
- | omit this option and include the shell commands beneath. | ||
- | |||
- | If you run any programs within the scriptlets, then you must specify any | ||
- | requirements in the form "Requires(CONTEXT)" (e.g. Requires(post)). | ||
- | |||
- | %pre, %post, %preun, and %postun provide the argument $1, | ||
- | which is the number of packages of this name which will be left on the system | ||
- | when the action completes. Don't compare for equality with 2, | ||
- | but instead check if they are greater than or equal to 2. | ||
- | For %pretrans and %posttrans, $1 is always 0. | ||
- | |||
- | For example, if the package installs an info manual, | ||
- | then the info manual index must be updated with install-info from the info package. | ||
- | Firstly, there is no guarantee that the info package will be available unless | ||
- | we explicitly declare it as required, and secondly, | ||
- | we don't want to fail completely if install-info fails: | ||
- | |||
- | 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 | ||
- | There is one other glitch related to installing info manuals. | ||
- | The install-info command will update the info directory, | ||
- | so we should delete the useless empty directory from the %{buildroot} during the %install section: | ||
- | |||
- | rm -f %{buildroot}%{_infodir}/dir | ||
- | Another scriptlet-like abilility are "triggers", | ||
- | which can be run for your package when other packages are installed or uninstalled. | ||
- | See RPM Triggers. | ||
- | |||
- | Macros | ||
- | Macros are text in the format %{string}. Typical macros: | ||
- | </code> | ||
- | |||
- | |||
- | ^ Macro ^ Typical Expansion ^ Meaning ^ | ||
- | | %{_bindir} | /usr/bin | Binary directory: where executables are usually stored. | | ||
- | | %{_builddir} | ~/rpmbuild/BUILD | Build directory: files are compiled within a subdirectory of the build directory. See %buildsubdir. | | ||
- | | %{buildroot} | ~/rpmbuild/BUILDROOT | Build root: where files are "installed" during the %install stage, which copies files from a subdirectory of %{_builddir} to a subdirectory of %{buildroot}. (Historically, %{buildroot} was in "/var/tmp/".) | | ||
- | | %{buildsubdir} | %{_builddir}/%{name} | Build subdirectory: a subdirectory within %{_builddir} where files are compiled during the %build stage. It is set after %setup. | | ||
- | | %{_datadir} | /usr/share | Share directory. | | ||
- | | %{_defaultdocdir} | /usr/share/doc | Default documentation directory. | | ||
- | | %{dist} | .fcNUMBER | Distribution+version short name (e.g. ".fc9") | | ||
- | | %{fedora} | NUMBER | Number of fedora release (e.g. "9") | | ||
- | | %{_includedir} | /usr/include | | | ||
- | | %{_infodir} | /usr/share/info | | | ||
- | | %{_initrddir} | /etc/rc.d/init.d | | | ||
- | | %{_libdir} | /usr/lib | | | ||
- | | %{_libexecdir} | /usr/libexec | | | ||
- | | %{_localstatedir} | /var | | | ||
- | | %{_mandir} | /usr/share/man | | | ||
- | | %{name} | | Name of package, set by Name: tag | | ||
- | | %{_sbindir} | /usr/sbin | | | ||
- | | %{_sharedstatedir} | /var/lib | | | ||
- | | %{_sysconfdir} | /etc | | | ||
- | | %{version} | | Version of package, set by Version: tag | | ||
- | |||
- | |||
- | |||
- | |||
- | <code text> | ||
- | Learn more about macros by looking in /etc/rpm/* and /usr/lib/rpm, especially /usr/lib/rpm/macros. | ||
- | Also use rpm --showrc to show values that RPM will use for macros (altered by rpmrc and macro configuration files). | ||
- | |||
- | You can set your own macro values using %global, | ||
- | but be sure to define them before you use them. | ||
- | (Macro definitions can also refer to other macros.) For example: | ||
- | |||
- | %global date 2012-02-08 | ||
- | Use the "-E" option of rpmbuild to find the value of a macro in a SPEC file: | ||
- | |||
- | rpmbuild -E '%{_bindir}' myfile.spec | ||
- | Also see Packaging/RPMMacros and RPM Guide chapter 9. | ||
- | </code> |