diff --git a/_topic_map.yml b/_topic_map.yml index 7cd94c7..e4cbb71 100644 --- a/_topic_map.yml +++ b/_topic_map.yml @@ -28,7 +28,9 @@ Topics: File: /modules/proc_enabling-third-party-repository - Name: (FIX ME!) Configuring Sudo File: configure-sudo - - Name: (FIX ME!) How to create an RPM package + - Name: (FIX ME!) How to create and use a Live CD + File: create-and-use-livecd + - Name: How to create an RPM package File: create-an-rpm - Name: (FIX ME!) Creating GPG Keys File: create-gpg-keys diff --git a/en-US/create-an-rpm-old.adoc b/en-US/create-an-rpm-old.adoc new file mode 100644 index 0000000..cf80778 --- /dev/null +++ b/en-US/create-an-rpm-old.adoc @@ -0,0 +1,1514 @@ +[[building-in-mock]] +Building in mock +^^^^^^^^^^^^^^^^ + +The next interesting thing to do would be to see if our package will +build in the way that the Fedora build system would do it. To do this, +just run: + +`fedpkg --release f`` mockbuild` + +This will build your package in . Running mock will set up a complete +minimal Fedora installation inside a directory and then build the +package within that. + +The end result should be a significant amount of output, a results_howdy +directory, and a couple of levels deep a three log files and two +packages. Feel free to look at those. + +You can also build for other releases in this manner, by changing what +you pass to the `--release` option. This can be useful for testing, but +it takes another big download so we'll skip that now. + +[[building-in-koji]] +Building in koji +^^^^^^^^^^^^^^^^ + +If you had your Fedora account set up at the time you started following +this document, you can build your package in the central Fedora build +system, though the syntax can be a bit odd: + +`fedpkg --release f`` scratch-build --target f`` --srpm` + +This will create a source package, upload it to the build servers, and +give you some output including a URL you can visit to watch the process +and download the built packages afterwards. This can be useful to test +that your package builds on the various different architectures that +Fedora supports, although your current test package doesn't need such +testing. + +[[running-fedora-review]] +Running fedora-review +^^^^^^^^^^^^^^^^^^^^^ + +Package reviewers use as part of the process of accepting new packages +into the distribution. You can run this tool yourself as a useful set of +informative checks. First, clean up your package directory: + +`rm -rf *rpm results*` + +Then create a source package and run the utility: + +`fedpkg --release f`` srpm` + +`fedora-review -n howdy` + +This will use mock to build your package and run a number of checks on +it. It will be silent while mock runs, so it may appear as if it has +hung when in reality it is doing a large amount of downloading. You can +add `-v` to make it somewhat more verbose. + +When done, you should have a `review-howdy` directory with various files +and directories. `rpmlint.txt` should have some additional rpmlint +output for you. `review.txt` is the template that a reviewer would fill +in (in addition to checking the functionality of the software in your +package, etc.) Most of that is probably not of interest to you, but it +doesn't hurt to have a look. + +[[on-to-a-more-complex-program]] +On to a more complex program +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Now that we've covered the absolute basics, we can move on to packaging +something more complicated, which comes from a real upstream and has to +be unpacked and built. A good package to use as an example is +https://www.gnu.org/software/hello/[GNU Hello]. Have a look there, note +the current version of Hello (2.10 as this document is being written) +and the download URL, licensing information and such. It's helpful to +keep that page open for referenceLet's create a directory and work in +it: + +` mkdir -p ~/packaging-work/hello` + +` cd ~/packaging-work/hello` + +And create the following specfile named `hello.spec`: + +.... +Name: hello +Version: 2.10 +Release: 1%{?dist} +Summary: GNU Hello +URL: https://www.gnu.org/software/hello/ +License: GPLv3+ + +Source0: https://ftp.gnu.org/gnu/hello/hello-%{version}.tar.gz + +%description +The GNU hello program produces a familiar, friendly greeting. It allows +nonprogrammers to use a classic computer science tool which would otherwise be +unavailable to them. Because it is protected by the GNU General Public License, +users are free (in perpetuity) to share and change it. + +%prep + +%build + +%install + +%files + +%changelog +.... + +We've filled in a few things here. There's now a `URL:` tag, pointing to +the Hello homepage. The `%description` was cribbed from the homepage. +The `License:` tag has changed, since the bottom of the homepage says +that the license is "under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 3 of the +License, or (at your option) any later version.". Licensing is a +difficult subject, and we'll cover it in more depth later, but for now +it's sufficient to note that Fedora indicates this type of license with +"GPLv3+". + +Perhaps the most interesting change is to the `Source0:` tag. It now has +a URL instead of a filename: using a URL tells everyone, including the +relevant Fedora utilities, where to actually get the source. And there's +a macro in there: `%{version}` is automatically set to whatever you used +for the `Version:` tag. Combining the two lets things automatically get +an updated copy of the source whenever the version changes. But how do +we actually get that source, since now we can't cut and paste that URL? +Try `spectool`: + +`spectool -g *spec` + +This quickly grabs all of the sources mentioned in the spec, and will +leave us with `hello-2.10.tar.gz` in our package directory. Have a look +with that file: + +`less *tar.gz` + +and we see that everything in there unpacks unto a single directory +named `hello-2.10`. We'll need to tell RPM how to unpack that archive +and how to find the files within. Add this to the `%prep` section: + +`%autosetup` + +This is a rather complicated macro which RPM will replace with plain old +shell code to unpack the archive, change into a directory and fix up +some permissions. It by default expects the directory to be named +`%{name}-%{version}` (where `%{name}` is, you guessed it, what you gave +for the `Name:` tag). This can be changed by passing the `-n` option, +but in our case the default is just what we need. You can see exactly +what it does by executing the `%prep` section with: + +`fedpkg --release f`` prep` + +This will call just the `%prep` section of your specfile, and should +leave you with a directory named `hello-2.10` in your package directory. +Have a look around in there. You'll see this is a standard GNU package +with a `configure` file, and that tells us most of what we need to know +in order to build it. Add this to the `%build` section: + +`%configure` + +`%make_build` + +This just calls the `configure` file with all of the arguments necessary +to build in Fedora, and then calls `make` with the necessary options. +And while we're at it, let's add this to `%install`: + +`%make_install` + +This calls the usual `make install` with Fedora's special macros to get +everything into the buildroot. If you do a mockbuild at this point, +you'll see that the build fails, just like with the previous package, +there are installed but unpackaged files. The list of files below the +error heading in the output, tells us what we need to do next, but +because there's an info page, a manpage and some locale files, we have a +few different rules to follow. + +[[old-document-below]] +Old document below +~~~~~~~~~~~~~~~~~~ + +If there are special programs that are required to build or run the +program you are packaging, install those other programs and write down +what they are. + +To package a program for the Fedora repository, you must package +pristine (original) sources, along with the patches and build +instructions; it's *not* okay to start with pre-compiled code. Install +the file with the original source (usually a `.tar.gz` file) in the +`~/rpmbuild/SOURCES` directory (of the RPM building user account). + +Read through the manual installation instructions for your program. It's +often a good idea to do a "dry run" by manually building the program +before attempting to do so via RPM. With a few exceptions, all binaries +and libraries included in Fedora packages must be built from the source +code that is included in the source package. + +[[creating-a-spec-file]] +Creating a SPEC file +~~~~~~~~~~~~~~~~~~~~ + +You now need to create a SPEC file in the `~/rpmbuild/SPECS` directory. +You should name it after the program name (e.g. "`program.spec`"). Use +the archive name or the name advocated by the software author where you +can, but be sure to follow the link:Packaging/NamingGuidelines[Package +Naming Guidelines]. + +[[spec-templates-and-examples]] +SPEC templates and examples +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +[[templates]] +Templates ++++++++++ + +You may use the `rpmdev-newspec` command to create a SPEC file for you. +`rpmdev-newspec ` can create an initial SPEC file for a +new package, tailored to various types of packages. It will guess what +kind of template to use based on the package name, or you can specify a +particular template. See `/etc/rpmdevtools/spectemplate-*.spec` for +available templates, and see `rpmdev-newspec --help` for more +information. For example, to create a new SPEC file for a python module: + +`cd ~/rpmbuild/SPECS` + +`rpmdev-newspec python-antigravity` + +`vim python-antigravity.spec` + +According to the +Packaging:Guidelines#Writing_a_package_from_scratch[packaging +guidelines], new spec files should be created this way. Vim and emacs +can automatically create simple templates, but these are different than +those made with `rpmdev-newspec`. This is especially true for templates +with names beginning with `python-` or `-perl`. + +Here is an example auto-generated `.spec` template: + +`Name:           testprogram` + +`Version:        ` + +`Release:        1%{?dist}` + +`Summary:        ` + + + +`License:        ` + +`URL:            ` + +`Source0:        ` + + + +`BuildRequires:  ` + +`Requires:       ` + + + +`%description` + + + + + +`%prep` + +`%setup -q` + + + + + +`%build` + +`%configure` + +`%make_build` + + + + + +`%install` + +`%make_install` + + + + + +`%files` + +`%doc` + + + + + + + +`%changelog` + +`* Sun Apr  3 2016 makerpm` + +`-` + +[[examples]] +Examples +++++++++ + +[[eject]] +eject + +Here's a simple example showing a Fedora specfile for the `eject` +program: + +.... +Summary: A program that ejects removable media using software control +Name: eject +Version: 2.1.5 +Release: 21%{?dist} +License: GPLv2+ +Source: %{name}-%{version}.tar.gz +Patch1: eject-2.1.1-verbose.patch +Patch2: eject-timeout.patch +Patch3: eject-2.1.5-opendevice.patch +Patch4: eject-2.1.5-spaces.patch +Patch5: eject-2.1.5-lock.patch +Patch6: eject-2.1.5-umount.patch +URL: http://www.pobox.com/~tranter +ExcludeArch: s390 s390x +BuildRequires: gettext +BuildRequires: libtool + +%description +The eject program allows the user to eject removable media (typically +CD-ROMs, floppy disks or Iomega Jaz or Zip disks) using software +control. Eject can also control some multi-disk CD changers and even +some devices' auto-eject features. + +Install eject if you'd like to eject removable media using software +control. + +%prep +%autosetup -n %{name} + +%build +%configure +%make_build + +%install +%make_install + +install -m 755 -d %{buildroot}/%{_sbindir} +ln -s ../bin/eject %{buildroot}/%{_sbindir} + +%find_lang %{name} + +%files -f %{name}.lang +%license COPYING +%doc README TODO ChangeLog +%{_bindir}/* +%{_sbindir}/* +%{_mandir}/man1/* + +%changelog +* Tue Feb 08 2011 Fedora Release Engineering - 2.1.5-21 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Fri Jul 02 2010 Kamil Dudka 2.1.5-20 +- handle multi-partition devices with spaces in mount points properly (#608502) +.... + +[[section]] + +[[spec-file-overview]] +SPEC file overview +~~~~~~~~~~~~~~~~~~ + +Other useful guides: + +* http://docs-old.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch-creating-rpms.html[RPM +Guide] describes how to write a SPEC file. +* The IBM series "Packaging software with RPM" +http://www.ibm.com/developerworks/library/l-rpm1/[Part 1], +http://www.ibm.com/developerworks/library/l-rpm2/[Part 2], and +http://www.ibm.com/developerworks/library/l-rpm3/[Part 3]. +* http://ftp.rpm.org/max-rpm/[Maximum RPM] has the most complete +information, but is dated. + +You will need to follow the Fedora guidelines: +link:Packaging/NamingGuidelines[Package Naming Guidelines], +link:Packaging/Guidelines[Packaging guidelines], and +link:Packaging/ReviewGuidelines[Package review guidelines]. + +Insert comments with a leading "`#`" character, and beware of macros +(beginning with `%`) that are potentially multi-line, as they are +expanded first. When commenting out a line, double the percent signs +(`%%`) of the macros appearing after the "`#`". Also avoid inline +comments on the same line as script commands. + +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 link:Packaging/NamingGuidelines[Package +Naming Guidelines] and generally be lowercase. +* *Version*: The upstream version number. See +link:Packaging/NamingGuidelines#Version_Tag[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 +link:Packaging/NamingGuidelines#Release_Tag[Release tag section] of the +packaging guidelines. The optional link:Packaging/DistTag[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. __'__Note: +This tag is deprecated since Fedora 17. See +https://docs-old.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/Packagers_Guide/chap-Packagers_Guide-Spec_File_Reference-Preamble.html[Spec +File Reference Preamble] _'_ +* *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 link:Packaging/LicensingGuidelines[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. Packaging:Guidelines#Timestamps[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 link:Packaging/SourceURL[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. It is possible to ensure you have specified all necessary build +requires by link:Using_Mock_to_test_package_builds[performing a "mock +build"] of your package. 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 package 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 +https://docs-old.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch09s03.html[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 +"`%autosetup`"; a common variation is "`%autosetup -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. +* *%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. +* *%check*: Script commands to "test" the program. This is run after the +%install procedure, 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. +* *%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. +*Do NOT put software's changelog at here.This changelog is for RPM +itself.* +* *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 +link:How_to_create_an_RPM_package#Subpackages[subpackages]) from a +single SPEC file, such as `name-libs` and `name-devel` packages. + +Do *not* create a "relocatable" package; they don't add value in Fedora +and make things more complicated. + +[[spec-file-sections-explained]] +SPEC file sections explained +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +[[prep-section]] +%prep section +^^^^^^^^^^^^^ + +The %prep section describes how to unpack the compressed packages so +that they can be built. Typically, this includes the "`%autosetup`" +command. Alternatively, you can use "`%setup`" and "`%patch`" commands +with reference to the Source0 (and Source1 etc.) lines. See the +http://ftp.rpm.org/max-rpm/s1-rpm-inside-macros.html[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 and %autosetup +is not what you want, then you can do: + +`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-autosetup-command]] +%prep section: %autosetup command ++++++++++++++++++++++++++++++++++ + +The "`%autosetup`" command unpacks a source package. Switches include: + +* *`-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 "`%autosetup -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. + +If you use "`%setup`" command instead, then _`-q`_' is commonly used to +suppress unecessary output. + +There are http://ftp.rpm.org/max-rpm/s1-rpm-inside-macros.html[more +%setup options if you are unpacking multiple files], which is primarily +useful if you are creating subpackages (see below). The key ones are: + +[cols=",",] +|======================================================================= +|`-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]] +%prep section: %patch commands +++++++++++++++++++++++++++++++ + +If you have used "`%autosetup`" command, the following manual patch +management is not necessary. If you have complex requirements or need +compatibility with EPEL, you may still need this. 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 -ur ../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]] +%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]] +%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_build` + +To override makefile variables, pass them as parameters to `make`: + +` %make_build CFLAGS="%{optflags}" BINDIR=%{_bindir}` + +More more information, see http://sourceware.org/autobook/["GNU +autoconf, automake, and libtool"] and +http://web.archive.org/web/20090411003817/http://www.suse.de/~sh/automake/automake.pdf["Open +Source Development Tools: An Introduction to Make, Configure, Automake, +Autoconf" by Stefan Hundhammer]. + +Some programs use `cmake`. See Packaging/cmake. + +[[install-section]] +%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` + +`%make_install` + +Ideally you should use %make_install which is equivalent to +http://www.gnu.org/prep/standards/html_node/DESTDIR.html[`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` + +`mkdir -p %{buildroot}%{_bindir}/` + +`cp -p mycommand %{buildroot}%{_bindir}/` + +[[check-section]] +%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 %install section, since files in %buildroot may be tested) +instead of within the %build section itself, so that they can be easily +skipped when necessary. + +Often, this section contains: + +`make test` + +Sometimes it can be: + +`make check` + +Please explore the Makefile and choose the appropriate way. + +[[files-section]] +%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]] +%files basics ++++++++++++++ + +The `%defattr` sets 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(``, ``, ``, ``)` + +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]] +%files prefixes ++++++++++++++++ + +You may need to add one or more prefixes to lines in the `%files` +section; seperate them with a space. See +http://ftp.rpm.org/max-rpm/s1-rpm-inside-files-list-directives.html[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 an +appropriate directory under `/usr/share/doc`, whose ownership does not +need to be declared. + +*Note:* If specifying a `%doc` entry, rpmbuild < 4.9.1 removes the doc +directory it installs files into before installing them. This means that +files already in it, for example installed in the `%install` section, +are removed and do not end up in the package. If you want to install +some files in the `%install` section, install them into a temporary +staging directory inside the build dir (not build root), for example +`_docs_staging`, and include them in the in the `%files` list like +`%doc _docs_staging/*`. + +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(0600, 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 +Packaging:Guidelines#Handling_Locale_Files[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` + +The `%readme` prefix is *not* valid in Fedora. + +[[files-and-filesystem-hierarchy-standard-fhs]] +%files and Filesystem Hierarchy Standard (FHS) +++++++++++++++++++++++++++++++++++++++++++++++ + +You should follow the http://www.pathname.com/fhs/[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. Executables that should not normally be executed directly by +users or administrators should (but are executed by other parts of your +package) go in a subdirectory of `/usr/libexec`, which is referred to as +`%{_libexecdir}/%{name}`. + +Do *not* install files into `/opt` or `/usr/local`. +(Packaging:Guidelines#Limited_usage_of_.2Fopt.2C_.2Fetc.2Fopt.2C_and_.2Fvar.2Fopt[reference]) + +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, Perl +and Systemd), 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]] +%files example +++++++++++++++ + +Here's a simple example of a %files section: + +`%files` + +`%doc README` + +`%license LICENSE COPYING` + +`%{_bindir}/*` + +`%{_sbindir}/*` + +`%{_datadir}/%{name}/` + +`%config(noreplace) %{_sysconfdir}/*.conf` + +[[finding-duplicates]] +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]] +Scriptlets +^^^^^^^^^^ + +When an end-user installs the RPM, you may want some commands to be run. +This can be achieved through scriptlets. See Packaging:Scriptlets. + +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 ability are "triggers", which can be run for your +package when other packages are installed or uninstalled. See +http://ftp.rpm.org/api/4.4.2.2/triggers.html[RPM Triggers]. + +[[macros]] +Macros +^^^^^^ + +Macros are text in the format `%{string}`. Typical macros: + +[cols=",,",options="header",] +|======================================================================= +|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/%{name}...` |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 `%autosetup`. + +|`%{_datadir}` |`/usr/share` |Share directory. + +|`%{_defaultdocdir}` |`/usr/share/doc` |Default documentation directory. + +|`%{dist}` |`.fc`__`NUMBER`__ |Distribution+version short name (e.g. +"`.fc`") + +|`%{fedora}` |_`NUMBER`_ |Number of fedora release (e.g. "") + +|`%{_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 +|======================================================================= + +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 +https://docs-old.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch09s07.html[RPM +Guide chapter 9]. + +[[other-tags]] +Other tags +^^^^^^^^^^ + +In addition to Requires and BuildRequires tags, you can also use these +for controlling dependencies: + +* *Provides*: list virtual package names that this package provides. For +example, there might be a package "`foo`" that demands a particular +functionality "bar" from another program. If there are several packages +that can satisfy that demand, those packages can specify +"`Provides: bar`" and the "`foo`" package can specify "`Requires: bar`". +You could also use the +http://dailypackage.fedorabook.com/index.php?/archives/6-Wednesday-Why-The-Alternatives-System.html["alternatives" +system], but avoid if multiple users on the same system might want +different default, as these settings are system-wide. Use +"`rpm -q --provides PACKAGENAME`" to see what a given package provides. +Some examples of virtual packages in Fedora: +** MTA: Used for mail transport agents, such as sendmail. +** tex(latex): Used for latex +* *Obsoletes*: remove another named package(s) when this package is +installed. Use when the package name changes or when it totally replaces +a different package. +* *Conflicts*: state what other packages cannot be installed +simultaneously to this one. Avoid this if you can. See +Packaging/Conflicts. +* *BuildConflicts*: state what packages cannot be installed when +building this package. Avoid this if you can. + +To manage different architectures, there are two tags: + +* *ExcludeArch*: to exclude an architecture on which the package doesn't +build. For example: + +`ExcludeArch: ppc` + +* *ExclusiveArch*: to include only the specified architecture. Avoid +this unless absolutely correct. + +Valid architectures are listed at Architectures. + +[[subpackages]] +Subpackages +^^^^^^^^^^^ + +A SPEC file can define several binary package. In other words, one SRPM +with one SPEC file can result in several RPMS. Note that there is still +only one creation (%prep, %build, %install etc.) process. `name-doc` and +`name-devel` subpackages are common for documentation and development +files respectively. + +Use the `%package` directive to start defining a subpackage: + +`%package subpackage_name` + +After each `%package` directive, list the tags for the subpackage. This +should at least include the Summary and Group tags, as well as the +`%description subpackage_name` and `%files subpackage_name` directives: + +Anything not specified by the subpackage will be inherited from its +parent. + +By default, if the package name is "`foo`" and the subpackage name is +"`bar`", then the resulting subpackage will be "`foo-bar`". You can +override it with the "`-n`" option (but you'll need to use it in all +other directives too if you specify it here): + +`%package -n new_subpackage_name` + +http://docs-old.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch10s04.html[See +the RPM Guide section on subpackages] for more information. + +[[conditionals]] +Conditionals +^^^^^^^^^^^^ + +You can insert conditional statements, for example to test if you are +creating a binary for a certain architecture: + +`%ifarch ARCHITECTURE_NAME` + +the negated version with: + +`%ifnarch ARCHITECTURE_NAME` + +or the more general conditional: + +`%if TRUE_OR_FALSE` + +There is an optional "`%else`" section; all of these are closed with +"`%endif`". + +[[application-specific-guidelines]] +Application Specific Guidelines +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +There are many application-specific guidelines that can help you (e.g., +for specific programming languages, applications, libraries, and build +systems). Many of them are listed as part of the +link:Packaging/Guidelines#Application_Specific_Guidelines[Application +Specific Guidelines of Packaging/Guidelines]. Examples of +application-specific guidelines are those for: + +* Packaging:Cmake[Cmake] +* Packaging:Emacs[Emacs] + +Failing that, some other ways of finding application-specific help are: + +* The 'SEARCH' command on Fedoraproject.org. +* PackagingDrafts +* A link:SIGs[Special Interest Group (SIG)] +* Special:PrefixIndex/Packaging[Wiki pages prefixed with 'Packaging'] + +[[miscellaneous-hints]] +Miscellaneous hints +^^^^^^^^^^^^^^^^^^^ + +Packaging/FrequentlyMadeMistakes has information on frequently-made +mistakes. There are also some recommendations and controversial tricks +on link:PackageMaintainers/Packaging_Tricks[PackageMaintainers/Packaging +Tricks]. + +Try to write your SPEC files so that it is likely to work when a new +release is made upstream, without any changes aside from bumping the +version number and refreshing the source files. For example, if it +contains *.txt files with execute bits, instead of doing + +` chmod a-x Filename1.txt Filename2.txt Filename3.txt` + +consider doing this, which will handle new filenames that use the same +file naming convention: + +` chmod a-x *.txt` + +If you want to see lots of examples of scriptlets, you can show all the +scriptlets on installed programs using: + +` rpm -qa --queryformat "\n\nPACKAGE: %{name}\n" --scripts | less` + +Don't try to interact with the user; RPM is designed to support batch +installs. If an application needs to show a EULA, that needs to be part +of its initial execution, not its installation. + +You might not want to start services, because in a big install that +could slow things down. If you install an init or systemd script, +consider using `chkconfig` or `systemctl` to arrange for the service to +be started/stopped on the next reboot. Before uninstalling, you should +normally try to stop its services if they are running. + +Uninstalling should reverse most changes made during installation, but +don't remove any user-created files. + +Normally, if there are binary executables, then debugging symbols are +stripped from the normal binary packages and placed into a `name-debug` +subpackage. If this shouldn't happen, you can disable the stripping and +creation of this subpackage by putting this at the top of your SPEC: + +`%global _enable_debug_package 0` + +`%global debug_package %{nil}` + +`%global __os_install_post /usr/lib/rpm/brp-compress %{nil}` + +To prevent stripping you may also need to do this in the `%install` +section: + +`export DONT_STRIP=1` + +A way to check for the version of Fedora in a SPEC file for conditional +builds is: + +`%if 0%{?fedora} <= ` + +The `?` causes the macro to evaluate to evaluate to blank if `%fedora` +is not defined. This causes the end result to be the `0` (which is a +number and thus fine), while not interfering with the result if there is +actually a value for `%fedora`. (Note that this trick does not work in +Koji "scratch" builds, where `%fedora` is set during the creation of a +SRPM.) + +GUI programs must have a desktop entry so that people can invoke it from +the graphical desktop menu. For `.desktop` files, see +link:Packaging/Guidelines#Desktop_files[Fedora packaging guidelines for +desktop files] and +http://standards.freedesktop.org/desktop-entry-spec/latest/[desktop +entry spec]. For icons within `/usr/share/icons`, see +http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html[icon +theme spec]. + +[[building-the-binary-package]] +Building the binary package +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +[[test-with-rpmlint]] +Test with rpmlint +^^^^^^^^^^^^^^^^^ + +To catch many common errors early, run `rpmlint` on your SPEC file +before trying to build anything from it: + +`$ rpmlint program.spec` + +If the reported error doesn't make sense, run it again with the "`-i`" +option for longer messages. + +Aim to have no errors, but sometimes `rpmlint` reports false positives. +The link:Packaging/Guidelines#Use_rpmlint[Fedora packaging guidelines] +explains which ones to ignore. + +[[create-binary-rpms-from-the-spec-file]] +Create binary RPMS from the SPEC file +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Once you've created your SPEC file, build the SRPM and binary RPMS by +running this: + +`$ rpmbuild -ba program.spec` + +If successful, RPMS will be created within `~/rpmbuild/RPMS` and SRPMS +will be created within `~/rpmbuild/SRPMS`. + +If it fails, go to the appropriate directory and see what is left over. +To help debug, you can skip earlier stages that succeeded with the +"`--short-circuit`" option. For example, to restart at the `%install` +stage (skipping earlier stages), do this: + +`$ rpmbuild -bi --short-circuit program.spec` + +If you just want to create an SRPM (which does not run the `%prep` or +`%build` or other stages), run this: + +`rpmbuild -bs program.spec` + +[[testing-binary-rpms-with-rpmlint]] +Testing binary RPMS with rpmlint +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +`rpmlint` can be run on SPEC files, RPMS and SRPMS to check for errors. +You need to eliminate or justify warnings before posting a package. +link:Common_Rpmlint_issues[This page] offers explanations for some of +the common issues that come up. If you are in the SPECS directory, do +this: + +`$ rpmlint `__`NAME`__`.spec ../RPMS/*/`__`NAME`__`*.rpm ../SRPMS/`__`NAME`__`*.rpm` + +Enter the `~/rpmbuild/RPMS` directory and into the architecture +subdirectory. You will find some binary RPMS. Quickly see their files +and permissions (to check whether they are correct) by doing: + +`$ rpmls *.rpm` + +If they look fine, install them as root: + +`# rpm -ivp package1.rpm package2.rpm package3.rpm ...` + +Test the programs in a few different ways to see if everything works +correctly. If it is a GUI tool, make sure it shows up in the desktop +menu, otherwise the `.desktop` entry is wrong. + +Uninstall packages later by doing: + +`# rpm -e package1 package2 package3` + +[[mock-and-koji]] +Mock and Koji +~~~~~~~~~~~~~ + +link:Projects/Mock[Mock] is a powerful tool that uses the SRPM you have +created to build binary packages within a nearly empty environment. This +can reveal if you have accurate build dependencies. If it fails, then +you forgot to list something in BuildRequires. See +link:Using_Mock_to_test_package_builds[Using Mock to test package +builds]. Once your account is a member of the "`mock`" group, you can +run commands like this to do local testing: + +`$ mock -r fedora-23-i386 rebuild path_to_source_RPM` + +You can use Koji (which uses `mock`) to do builds on many different +systems, some of which you may not have. PackageMaintainers/Join and +PackageMaintainers/UsingKoji have more information about Koji. Once it's +set up, you can test your SRPM on a variety of platforms by running +commands like: + +`$ koji build --scratch f23 path_to_source_RPM` + +Replace `f23` with any later release of Fedora, or `rawhide`. + +Your Koji builds can only depend on packages that are actually in the +TARGET distribution repository. Thus, you can't use Koji to build for +released distributions if your package depends on other new packages +that Bodhi hasn't released yet. If you need to build against a package +that is not yet a stable released update, submit a Koji buildroot +override request via Bodhi. If it's not your own package you depend on, +contact its maintainer(s). [Before Bodhi could handle Koji buildroot +override requests, the old method has been to file a ticket with rel-eng +at: https://fedorahosted.org/rel-eng/newticket and request that that +package be added as a buildroot override.] + +[[helpful-tools]] +Helpful tools +~~~~~~~~~~~~~ + +The `rpmdevtools` package has a number of helpful tools; +"`rpm -qil rpmdevtools`" will show you what it installs. + +* `rpmdev-bumpspec` : bump the release tag in the spec file and add a +changelog comment with the right date and version format: + +`rpmdev-bumpspec --comment=COMMENT --userstring=NAME+EMAIL_STRING SPECFILES` + +DNF download plugin (from core DNF plugins) is also useful: + +* `dnf download` : download the SRPM of the package by running: + +`dnf download --source PACKAGENAME` + +The `auto-buildrequires` package has a pair of nice tools for helping to +figure out the proper BuildRequires entries. After installing this +package, replace "`rpmbuild`" with "`auto-br-rpmbuild`" and you'll see +an automatically generated BuildRequires list. + +You might find http://rust.sourceforge.net/[RUST] useful (GPL), though +it does not create SPEC files of suitable quality for Fedora packages. +http://kitenet.net/~joey/code/alien/[Alien] converts between package +formats. It won't produce clean SRPMS, but converting an existing +package might provide helpful information. + +If you are thinking about packing your rpm for Fedora, be sure you run +your packages through https://fedorahosted.org/FedoraReview/[Fedora +Review], which helps ensure that you comply to the +Packaging:Guidelines[Packaging Guidelines]. + +Finally, +https://github.com/alanfranz/docker-rpm-builder[docker-rpm-builder] (APL +2.0) uses http://www.docker.com[Docker] to build RPM packages; while +using rpmbuild requires building on the same host distro as the target, +and mock works fine on Fedora/Centos/RHEL distributions for any target, +*this last tool works fine whenever Docker can run*. + +If you want to build your package for diferent distribution and +architectures and to have publicly accesible dnf repository, you can +submit your src.rpm to https://copr.fedoraproject.org[Copr]. + +If you need to sign your new package, use `rpmsign` tool from `rpm-sign` +package. + +[[guidelines-and-rules]] +Guidelines and rules +~~~~~~~~~~~~~~~~~~~~ + +When you create your packages, you'll need to follow the following rules +and guidelines: + +* link:Join_the_package_collection_maintainers[How to join the Fedora +Package Collection Maintainers] +* Packaging:Guidelines[Packaging Guidelines] +* Packaging:NamingGuidelines[Package Naming Guidelines] +* Packaging:LicensingGuidelines[Package Licensing Guidelines] +* Packaging:DistTag[Dist Tag Guidelines] +* Packaging:ReviewGuidelines[Package Review Guidelines] + +There are many official guidelines that will help you with specific +circumstances (e.g. Java programs, OCaml programs, GNOME programs). You +can also learn more from the SIGs and +:Category:Package_Maintainers[Package Maintainers] sections. + +Special:Prefixindex/Packaging[You can also see the list of all Wiki +pages about Packaging] to see if any apply. + +Failing that, you might find some useful recommendations in the +unofficial :Category:Packaging_guidelines_drafts[draft guidelines +category] and link:PackagingDrafts[Packaging Drafts To Do]. + +You might find ideas from http://en.opensuse.org/Packaging[SuSE], +http://www.debian.org/doc/debian-policy/[Debian], but +http://www.mail-archive.com/distributions@lists.freedesktop.org/msg00156.html[distributions +differ in their rules], so do not presume they can be used directly. + +*The .spec files that you create must be open source software, as noted +in the Legal:Fedora_Project_Contributor_Agreement[FPCA].* + +[[maintaining-the-package]] +Maintaining the package +~~~~~~~~~~~~~~~~~~~~~~~ + +Once your package has been accepted, you and your co-maintainers will +need to maintain it. See link:Package_update_HOWTO[Package update HOWTO] +and link:Package_update_guidelines[Package update guidelines]. If you +update the version in multiple releases of Fedora, do it backwards in +time (e.g. release for Fedora N, then once that's accepted, Fedora N-1). +The system presumes that later versions of Fedora have the same or later +versions of programs. + +Encourage the upstream developers to use standard source code release +conventions. Using standard conventions makes packaging much easier. For +more information, see: + +* http://www.dwheeler.com/essays/releasing-floss-software.html[Releasing +Free/Libre/Open Source Software (FLOSS) for Source Installation] (a +quick summary) +* http://www.gnu.org/prep/standards/html_node/Managing-Releases.html[GNU +Coding Standards release process] +* http://en.tldp.org/HOWTO/Software-Release-Practice-HOWTO/[Software +Release Practice HOWTO] +* http://www.pathname.com/fhs/[Filesystem Hierarchy Standard (FHS)] +* http://offog.org/articles/packaging/[Packaging Unix software] + +[[for-more-information]] +For more information +~~~~~~~~~~~~~~~~~~~~ + +The :Category:Package_Maintainers[Package Maintainers] page links to +many other useful pages, and the link:Package_update_HOWTO[Package +update HOWTO] describes how to update an existing package you already +maintain in Fedora. + +For more information, outside of the Fedora Wiki, see: + +* https://developer.fedoraproject.org/deployment/rpm/about.html[A brief +RPM Packaging overview] on the Fedora Developer Portal +* http://www.g-loaded.eu/2006/04/05/how-to-build-rpm-packages-on-fedora/[How +to build RPM packages on Fedora] - very brief run-through +* Packaging software with RPM (developerWorks) +http://www.ibm.com/developerworks/library/l-rpm1/[Part 1], +http://www.ibm.com/developerworks/library/l-rpm2/[Part 2], and +http://www.ibm.com/developerworks/library/l-rpm3.html[Part 3] +* Fedora Classroom had an IRC session on packaging and you can refer to +the logs at +https://fedoraproject.org/wiki/Building_RPM_packages_%2820090405%29 + +* http://ftp.rpm.org/max-rpm/[Maximum RPM Book] - most complete +information, but in some cases old/obsolete +* http://docs-old.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch-creating-rpms.html[RPM +Guide, section on creating RPMs] - this has lots of good information, +and is slightly more up-to-date, but is a draft +* http://web.archive.org/web/20100109050207/http://docs.fedoraproject.org/developers-guide/ch-rpm-building.html[Developer's +guide, section on building RPMs] - via archive.org, disappeared in 2010 + +* http://freshrpms.net/docs/fight/["The fight", Mattias Saou's first +attempt to make a readable rpm package building introduction. ca. 2003] + +* http://en.tldp.org/HOWTO/RPM-HOWTO/index.html[RPM HOWTO: RPM at Idle +by Donnie Barnes] + +* http://en.opensuse.org/Build_Service/cross_distribution_package_how_to[Cross-distribution +package HOWTO] has hints if you're building one RPM for many +distributions. + +* http://linuxshellaccount.blogspot.com/2008/03/creating-your-own-linux-rpms-initial.html[Creating +Your Own Linux RPM's - The Initial Software Build] is another brief +intro, but it makes the point that "The process of building RPM's is +much simpler than creating packages for Solaris... Fewer steps, and the +ability to add all of your software information into one specification +file, makes for a much tighter (and easier to modify or reproduce) +software packaging system." +* http://fedoranews.org/alex/tutorial/rpm/[All you need to know about +RPM] (more about installing packages than creating them) +* The http://wiki.rpm.org/[rpm.org Wiki] has some useful information, +such as the http://wiki.rpm.org/Problems[list of known RPM problems] + +Note: The http://rpm5.org/[rpm5.org] site has some documentation, but do +not depend on it; that is the home of a _fork_ of RPM maintained by Jeff +Johnson. The RPM used by Fedora (and Novell/SuSE) is instead based at +http://www.rpm.org[rpm.org]. http://lwn.net/Articles/236029/[lwn.net has +a brief article] about this. + +Category:Package_Maintainers[Category:Package Maintainers] +Category:How_to[Category:How to] +''' + +See a typo, something missing or out of date, or anything else which can be +improved? Edit this document at https://pagure.io/fedora-docs/quick-docs. diff --git a/en-US/create-an-rpm.adoc b/en-US/create-an-rpm.adoc index baf19cd..7928f79 100644 --- a/en-US/create-an-rpm.adoc +++ b/en-US/create-an-rpm.adoc @@ -1,1951 +1,11 @@ -= How to create an RPM package +include::modules/con_rpm_packaging_overview.adoc[] -''' +include::modules/proc_rpm_preparing_your_system.adoc[] -[IMPORTANT] -====== +include::modules/proc_rpm_creating_a_rpm.adoc[] -This page was automatically converted from https://fedoraproject.org/wiki/How_to_create_an_RPM_package +include::modules/con_rpm_spec_file_overview.adoc[] -It is probably +include::create-an-rpm-old.adoc[] -* Badly formatted -* Missing graphics and tables that do not convert well from mediawiki -* Out-of-date -* In need of other love -Please fix it, remove this notice, and then add to `_topic_map.yml` - -Pull requests accepted at https://pagure.io/fedora-docs/quick-docs - -Once that is live, go to the original wiki page and add an `{{old}}` -tag, followed by a note like - -.... -{{admon/note|This page has a new home!| -This wiki page is no longer maintained. Please find the up-to-date -version at: https://docs.fedoraproject.org/whatever-the-url -}} -.... - -====== - -''' - - -__TOC__ - -[[introduction]] -Introduction -~~~~~~~~~~~~ - -This page describes in detail how to create an RPM package, and in -particular how to create a specfile. Unlike other RPM guides, this page -explains the specifics for Fedora with links to Fedora-specific -guidelines and usage of Fedora-specific utilities. Despite the focus on -Fedora, much of this document does apply to other RPM-based -distributions. - -Fedora Documentation had released a draft guide for packagers, see -http://docs-old.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/Packagers_Guide[Packagers -Guide]. It is archived. - -Please note that this document is merely a gentle introduction and will -leave out many of the details which you may need in order to package -more complicated software. It also assumes that you have familiarity -with the shell and are familiar with the process of building and -installing (outside of RPM) the software you wish to package. Finally, -this document is *NOT* an official Fedora packaging guideline. This page -is open for editing by the general Fedora packaging community, while the -actual packaging guidelines are managed by the -Packaging:Committee[Packaging Committee]. For reference, here are some -of the most referenced guideline pages: - -* Packaging:Guidelines[Packaging Guidelines] -* Packaging:LicensingGuidelines[Licensing Guidelines] -* Packaging:Naming[ Package Naming Guidelines] -* Packaging:DistTag[ Dist Tag Guidelines] -* Packaging:ReviewGuidelines[ Package Review Guidelines] -* Packaging:Scriptlets[ Recipes for RPM scriptlets] - -Packaging:Guidelines and Packaging:Naming contain the main guidelines. -Having said that, this page should be compatible with them, though the -guidelines do change over time and this page may diverge from them on -occasion. - -If you plan to submit a package to the official Fedora repository, you -will also want to follow the procedure depicted in -link:Join_the_package_collection_maintainers[Join the package collection -maintainers]. - -[[some-terminology]] -Some terminology -^^^^^^^^^^^^^^^^ - -RPM:: - The package manager used by Fedora, Red Hat Enterprise Linux, Mageia, - OpenSUSE and others. Originally RPM stood for "Red Hat Package - Manager" but now it's just the recursive acronym "RPM Package - Manager". - -specfile:: - A plain text file containing information about a package and - instructions used by RPM for actually compiling the included software. - It is named by appending `.spec` to the name of the package. - -tag:: - A string, generally capitalized and followed by a colon, which appears - at the top of the specfile to provide some important data about the - RPM, such as `Name:`, `Version:` or `Summary:`. - -section:: - A segment of the specfile which tells RPM how to perform some portion - of the package construction process. Many, but not all, sections - contain code that is simply passed to the shell, though RPM has - significant flexibility around this which will not be covered at all - in this document. - -section header:: - A short string, starting with `%` at the beginning of a line, which - introduces a section. Examples include `%description`, `%prep` and - `%files`. - -macro:: - A short string, always prefixed by `%` and generally surrounded by - curly brackets (`{}`) which RPM will convert to a different and - usually longer string. Some macros can take arguments and some can be - quite complex. Some macros are provided by RPM, some are part of and , - but many other packages also provide them. If you're curious, running - `rpm --showrc` will show you all of the macros currently available on - your system, but note that you really don't want to use most of the - ones you see there. Note that some macros have named prefixed by - underscores; the reasons for this are mostly lost to time. - + - The packaging guidelines have various - Packaging:Guidelines#Macros[suggestions and restrictions] regarding - the use of various sets of macros. This document will use what the - guidelines recommend, but won't necessarily explain the reasons in - detail. - + - You may, in looking at other packages, see macros used without curly - brackets. There are situations where this isn't strictly necessary, - but these guidelines will use them wherever possible to make it more - obvious when macros are being used and to avoid going into the rules - about when the brackets are needed and when they aren't. - -mock:: - A system for building RPMs within their own separate small Fedora - installation. This avoids the need to have a full set of build - dependencies installed into your regular operating system - installation, allows you to build packages for different Fedora - releases, and in general is a good thing. - -koji:: - The main Fedora build system: https://koji.fedoraproject.org[1]. - -[[editors-for-editing-rpm-spec-files]] -Editors for editing RPM spec files -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Many editors (like text editors and IDEs) that are in the official -repositories of Fedora have out-of-the-box syntax-highlighting support -for RPM spec files, these include: - -* CodeEditor. It does not syntax-highlight the shell script code found -in RPM spec files. -* gedit. It does not syntax-highlight the shell script code found in RPM -spec files. -* link:GNU_nano[GNU nano]. It does not syntax-highlight the shell script -code found in RPM spec files. -* Joe. It does not syntax-highlight the shell script code found in RPM -spec files. -* Kate. It does not syntax-highlight the shell script code found in RPM -spec files. -* KWrite. It does not syntax-highlight the shell script code found in -RPM spec files. -* Pluma. It does not syntax-highlight the shell script code found in RPM -spec files. -* Vim (and, of course, its graphical counterpart, gVim). It also -syntax-highlights the shell script code found in RPM spec files. - -while the following are present in the official Fedora repositories but -do not come with out-of-the-box syntax-highlighting for RPM Spec files, -but do gain said support when optional packages/plugins are installed: - -* Eclipse can develop RPM spec file editing support when the -https://apps.fedoraproject.org/packages/eclipse-rpm-editor[RPM Spec file -editor] package is also installed. This package also provides code -linting (checking for RPM packaging errors) and make it easier to -navigate the spec file. -* link:GNU_Emacs[GNU Emacs] has editing support for RPM spec files when -the https://apps.fedoraproject.org/packages/emacs-rpm-spec-mode[RPM spec -mode] package is installed. - -Editors that are not in the official repositories of Fedora but are -available for Fedora and, with the appropriate plugins, can -syntax-highlight RPM spec files include: - -* Atom, with the -https://atom.io/packages/language-rpm-spec[language-rpm-spec] package. -* link:Visual_Studio_Code[Visual Studio Code], with the -https://marketplace.visualstudio.com/items?itemName=1dot75cm.RPMSpec[RPM -Spec] extension. - -[[preparing-your-system]] -Preparing your system -~~~~~~~~~~~~~~~~~~~~~ - -Before you create RPM packages on Fedora, you need to install some -packaging tools and set up the account(s) you will use. Run this as -root: - -`dnf install fedora-packager fedora-review` - -This will install the utilities needed to work with and build packages -in the same manner used to maintain official Fedora packages, including -the tool used by package reviewers to check package quality. - -As root, add yourself to the mock group: - -`usermod -a -G mock yourusername` - -This should be the last time you need root unless you wish to install -packages you have developed. - -You may afterwards need to run `newgrp` or log out and back in for this -change to take effect. Run the `id` command to see if the "mock" group -appears in your group list. - -If you have already obtained a Fedora account and accepted the -contributor agreement, you can also set up your fedora certificates and -such. Just run (as your user, not as root): - -`fedora-packager-setup` - -If you wish, you can also create a separate user and use it for doing -RPM development. You should make sure that user is part of the "mock" -group and has run `fedora-packager-setup`. - -[[first-steps]] -First steps -~~~~~~~~~~~ - -To create an RPM package, you will need to create a directory to hold -the package and, within that directory, the specfile. This file provides -information about the software being packaged, instructions for -unpacking it, building it and installing it, as well as a list of files -which will be included in the package. You then run the `fedpkg` command -with appropriate options, which will go through a series of steps to -produce your package. - -The construction of the specfile is often done iteratively (one relevant -piece at a time), and that's what we'll do here. But first we'll need -someplace to make our package as well as something to package. Run the -following to create a directory to hold packaging work (called -`packaging-work`), within it a place to hold our package (called -"`howdy`), and within that a simple program to package (also called -"`howdy`). You can use any location you like but the directory name for -the package should match the name of the package. - -`mkdir -p ~/packaging-work/howdy` + -`cd ~/packaging-work/howdy` + -`cat << EOF > howdy` + -`#!/bin/bash` + -`echo "Howdy, partner!"` + -`EOF` + -`chmod 644 howdy` - -You should be able to run `bash howdy` and receive the expected output. -Now we have something we can package, so let's start making a specfile. -We'll start with a very minimal template (which will have to be expanded -for anything more complicated than this example). Just start your editor -on a new file called `howdy.spec`" and paste this in. Please use spaces -and not tabs. It's not necessary to have everything like up but it does -make it look nice. - -.... -Name: howdy -Version: 1 -Release: 1%{?dist} -Summary: Say hello, Texas style - -License: Public Domain -Source0: howdy - -%description -A simple program to greet the user, Texas style. - -%install - -%files - -%changelog -.... - -So we've described the package, indicated a version and listed the one -source file we have. We have an `%install` and a `%files` section, both -of which are empty. Save your edits and run - -`fedpkg --release f`` local` - -This is called a "local build". Assuming no typos or other issues, you -should get some output and two RPM files. One should be the source -package, which contains everything necessary for someone else (or the -Fedora build system) to build their own copy of your package. The other -is a binary package. It doesn't actually have anything in it at this -point, though, because we didn't tell RPM to actually include any files. -(It would not even have been created if we hadn't included the empty -`%files` section.) - -If you like, you can look at either package using `rpm -qip`, or just -`less`. - -[[a-useful-package]] -A useful package -~~~~~~~~~~~~~~~~ - -So now we have a minimally functional specfile which builds and produces -a rather useless binary package. - -In order to actually make a package which does something, we must tell -RPM how to install the program. Edit the specfile and add this to the -`%install` section (immediately after the line containing `%install`): - -`mkdir -p %{buildroot}/%{_bindir}` + -`install -p -m 755 %{SOURCE0} %{buildroot}/%{_bindir}` - -The contents of the `%install` section is just a shell script! Note that -we've used three macros: - -* `%{buildroot}` is set to a temporary directory called "the buildroot" -that's set up by RPM to hold the complete tree of files we'll install. -* `%{_bindir}` is just /usr/bin. -* `%{SOURCE0}` refers to the file listed earlier in the spec with the -`Source0:` tag. - -This saves us from having to care about exactly where those files and -directories are located on the filesystem while the package is built; -instead we only care about where those files are ending up. And without -`%{buildroot}` we'd end up installing those files directly onto our -development machine, which would be bad, especially if running as root. - -Now do a local build. It failed! But why? Well, because of this: - -`error: Installed (but unpackaged) file(s) found:` + -`   /usr/bin/howdy` - -We installed a file but didn't tell RPM about it. RPM maybe could just -include everything we install, but there are plenty of good reasons why -it doesn't just do that. So tell RPM about that file, by adding this to -the `%files` section: - -`%{_bindir}/howdy` - -Note that `%files` is generally about files we've actually installed -into the buildroot. You do not use the `%{buildroot}` macro when listing -files there. - -Now do another local build. If all goes well, you should have two -updated RPMs, and the binary one should contain a file. But there's one -more thing we should add to the spec to make this a complete package. -Since all we're packaging is a shell script, there is no reason at all -for this to be built separately on each architecture Fedora supports. So -edit the spec once more and add the following immediately after the -`Source0:` line: - -`BuildArch: noarch` - -This tells RPM that there's nothing architecture-specific about a -particular package. You can reindent the spec if you like to make things -line up, but please use spaces and not tabs. Delete the existing `.rpm` -files in this directory and do another local build. Now you should have -a pair of rpms: one with the updated source, and one ending in -`.noarch.rpm` indicating an architecture-independent package. You should -now have your first complete package that you built yourself! If you -like, install it and try it out. You'll probably want to remove it once -you're done, unless you just like Texas-style greetings. - -[[further-things-to-do-with-our-package]] -Further things to do with our package -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Have a glance at our current spec if you like. - -.... - -Name: howdy -Version: 1 -Release: 1%{?dist} -Summary: Say hello, Texas style - -License: Public Domain -Source0: howdy -BuildArch: noarch - -%description -A simple program to greet the user, Texas style. - -%install -mkdir -p %{buildroot}/%{_bindir} -install -p -m 755 %{SOURCE0} %{buildroot}/%{_bindir} - -%files -%{_bindir}/howdy - -%changelog -.... - -You may recall that RPM handles dependencies, but we didn't indicate -anything about that in the specfile. Let's look. - -` rpm -qp --requires howdy-1-1.fc``.noarch.rpm` - -You'll see that RPM added some internal `rpmlib` dependencies, plus one -on `/bin/bash` which matches up with the first line of the howdy -program. Often RPM will handle dependencies for your binary packages -automatically. Often times it won't, and we'll look into that later. - -You can also replace `--requires` by `--provides` to see the other side -of the dependency equation. There's not much of interest there, but if -something did depend on `howdy` then this package would provide it. - -Next thing to do is run some checks on our package: - -` fedpkg --release f`` lint` - -This will spit out a few complaints. Four total about the lack of -`%prep` and `%build` sections, one about the lack of a `URL:` tag, and -one about the lack of a proper changelog. You may also see other -complaints, perhaps about permissions. The full set of complaints may -change over time as the checking program, itself changes. You may even -have noticed these complaints earlier if your editor was configured to -automatically check specfiles as you edit them. - -We will ignore the complaints about the lack of the two sections and a -URL. We could make the complaints go away by adding empty sections and a -dummy URL, but that's not productive and our next experiment will have -them. - -It would indeed be nice to have a changelog section, though. Your editor -may have the capability to add one automatically; in it's (unless you've -changed the leader key) and in it's . If you want to do it manually, -have a look at the relevant Packaging:Guidelines#Changelogs[guidelines]. -I'll add mine here: - -`* Mon Sep 19 2016 Jason L Tibbitts III  - 1-1` + -`- Initial packaging.` - -[[building-in-mock]] -Building in mock -^^^^^^^^^^^^^^^^ - -The next interesting thing to do would be to see if our package will -build in the way that the Fedora build system would do it. To do this, -just run: - -`fedpkg --release f`` mockbuild` - -This will build your package in . Running mock will set up a complete -minimal Fedora installation inside a directory and then build the -package within that. - -The end result should be a significant amount of output, a results_howdy -directory, and a couple of levels deep a three log files and two -packages. Feel free to look at those. - -You can also build for other releases in this manner, by changing what -you pass to the `--release` option. This can be useful for testing, but -it takes another big download so we'll skip that now. - -[[building-in-koji]] -Building in koji -^^^^^^^^^^^^^^^^ - -If you had your Fedora account set up at the time you started following -this document, you can build your package in the central Fedora build -system, though the syntax can be a bit odd: - -`fedpkg --release f`` scratch-build --target f`` --srpm` - -This will create a source package, upload it to the build servers, and -give you some output including a URL you can visit to watch the process -and download the built packages afterwards. This can be useful to test -that your package builds on the various different architectures that -Fedora supports, although your current test package doesn't need such -testing. - -[[running-fedora-review]] -Running fedora-review -^^^^^^^^^^^^^^^^^^^^^ - -Package reviewers use as part of the process of accepting new packages -into the distribution. You can run this tool yourself as a useful set of -informative checks. First, clean up your package directory: - -`rm -rf *rpm results*` - -Then create a source package and run the utility: - -`fedpkg --release f`` srpm` + -`fedora-review -n howdy` - -This will use mock to build your package and run a number of checks on -it. It will be silent while mock runs, so it may appear as if it has -hung when in reality it is doing a large amount of downloading. You can -add `-v` to make it somewhat more verbose. - -When done, you should have a `review-howdy` directory with various files -and directories. `rpmlint.txt` should have some additional rpmlint -output for you. `review.txt` is the template that a reviewer would fill -in (in addition to checking the functionality of the software in your -package, etc.) Most of that is probably not of interest to you, but it -doesn't hurt to have a look. - -[[on-to-a-more-complex-program]] -On to a more complex program -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Now that we've covered the absolute basics, we can move on to packaging -something more complicated, which comes from a real upstream and has to -be unpacked and built. A good package to use as an example is -https://www.gnu.org/software/hello/[GNU Hello]. Have a look there, note -the current version of Hello (2.10 as this document is being written) -and the download URL, licensing information and such. It's helpful to -keep that page open for referenceLet's create a directory and work in -it: - -` mkdir -p ~/packaging-work/hello` + -` cd ~/packaging-work/hello` - -And create the following specfile named `hello.spec`: - -.... -Name: hello -Version: 2.10 -Release: 1%{?dist} -Summary: GNU Hello -URL: https://www.gnu.org/software/hello/ -License: GPLv3+ - -Source0: https://ftp.gnu.org/gnu/hello/hello-%{version}.tar.gz - -%description -The GNU hello program produces a familiar, friendly greeting. It allows -nonprogrammers to use a classic computer science tool which would otherwise be -unavailable to them. Because it is protected by the GNU General Public License, -users are free (in perpetuity) to share and change it. - -%prep - -%build - -%install - -%files - -%changelog -.... - -We've filled in a few things here. There's now a `URL:` tag, pointing to -the Hello homepage. The `%description` was cribbed from the homepage. -The `License:` tag has changed, since the bottom of the homepage says -that the license is "under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 3 of the -License, or (at your option) any later version.". Licensing is a -difficult subject, and we'll cover it in more depth later, but for now -it's sufficient to note that Fedora indicates this type of license with -"GPLv3+". - -Perhaps the most interesting change is to the `Source0:` tag. It now has -a URL instead of a filename: using a URL tells everyone, including the -relevant Fedora utilities, where to actually get the source. And there's -a macro in there: `%{version}` is automatically set to whatever you used -for the `Version:` tag. Combining the two lets things automatically get -an updated copy of the source whenever the version changes. But how do -we actually get that source, since now we can't cut and paste that URL? -Try `spectool`: - -`spectool -g *spec` - -This quickly grabs all of the sources mentioned in the spec, and will -leave us with `hello-2.10.tar.gz` in our package directory. Have a look -with that file: - -`less *tar.gz` - -and we see that everything in there unpacks unto a single directory -named `hello-2.10`. We'll need to tell RPM how to unpack that archive -and how to find the files within. Add this to the `%prep` section: - -`%autosetup` - -This is a rather complicated macro which RPM will replace with plain old -shell code to unpack the archive, change into a directory and fix up -some permissions. It by default expects the directory to be named -`%{name}-%{version}` (where `%{name}` is, you guessed it, what you gave -for the `Name:` tag). This can be changed by passing the `-n` option, -but in our case the default is just what we need. You can see exactly -what it does by executing the `%prep` section with: - -`fedpkg --release f`` prep` - -This will call just the `%prep` section of your specfile, and should -leave you with a directory named `hello-2.10` in your package directory. -Have a look around in there. You'll see this is a standard GNU package -with a `configure` file, and that tells us most of what we need to know -in order to build it. Add this to the `%build` section: - -`%configure` + -`%make_build` - -This just calls the `configure` file with all of the arguments necessary -to build in Fedora, and then calls `make` with the necessary options. -And while we're at it, let's add this to `%install`: - -`%make_install` - -This calls the usual `make install` with Fedora's special macros to get -everything into the buildroot. If you do a mockbuild at this point, -you'll see that the build fails, just like with the previous package, -there are installed but unpackaged files. The list of files below the -error heading in the output, tells us what we need to do next, but -because there's an info page, a manpage and some locale files, we have a -few different rules to follow. - -[[old-document-below]] -Old document below -~~~~~~~~~~~~~~~~~~ - -If there are special programs that are required to build or run the -program you are packaging, install those other programs and write down -what they are. - -To package a program for the Fedora repository, you must package -pristine (original) sources, along with the patches and build -instructions; it's *not* okay to start with pre-compiled code. Install -the file with the original source (usually a `.tar.gz` file) in the -`~/rpmbuild/SOURCES` directory (of the RPM building user account). - -Read through the manual installation instructions for your program. It's -often a good idea to do a "dry run" by manually building the program -before attempting to do so via RPM. With a few exceptions, all binaries -and libraries included in Fedora packages must be built from the source -code that is included in the source package. - -[[creating-a-spec-file]] -Creating a SPEC file -~~~~~~~~~~~~~~~~~~~~ - -You now need to create a SPEC file in the `~/rpmbuild/SPECS` directory. -You should name it after the program name (e.g. "`program.spec`"). Use -the archive name or the name advocated by the software author where you -can, but be sure to follow the link:Packaging/NamingGuidelines[Package -Naming Guidelines]. - -[[spec-templates-and-examples]] -SPEC templates and examples -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -[[templates]] -Templates -+++++++++ - -You may use the `rpmdev-newspec` command to create a SPEC file for you. -`rpmdev-newspec ` can create an initial SPEC file for a -new package, tailored to various types of packages. It will guess what -kind of template to use based on the package name, or you can specify a -particular template. See `/etc/rpmdevtools/spectemplate-*.spec` for -available templates, and see `rpmdev-newspec --help` for more -information. For example, to create a new SPEC file for a python module: - -`cd ~/rpmbuild/SPECS` + -`rpmdev-newspec python-antigravity` + -`vim python-antigravity.spec` - -According to the -Packaging:Guidelines#Writing_a_package_from_scratch[packaging -guidelines], new spec files should be created this way. Vim and emacs -can automatically create simple templates, but these are different than -those made with `rpmdev-newspec`. This is especially true for templates -with names beginning with `python-` or `-perl`. - -Here is an example auto-generated `.spec` template: - -`Name:           testprogram` + -`Version:        ` + -`Release:        1%{?dist}` + -`Summary:        ` + - + -`License:        ` + -`URL:            ` + -`Source0:        ` + - + -`BuildRequires:  ` + -`Requires:       ` + - + -`%description` + - + - + -`%prep` + -`%setup -q` + - + - + -`%build` + -`%configure` + -`%make_build` + - + - + -`%install` + -`%make_install` + - + - + -`%files` + -`%doc` + - + - + - + -`%changelog` + -`* Sun Apr  3 2016 makerpm` + -`-` - -[[examples]] -Examples -++++++++ - -[[eject]] -eject - -Here's a simple example showing a Fedora specfile for the `eject` -program: - -.... -Summary: A program that ejects removable media using software control -Name: eject -Version: 2.1.5 -Release: 21%{?dist} -License: GPLv2+ -Source: %{name}-%{version}.tar.gz -Patch1: eject-2.1.1-verbose.patch -Patch2: eject-timeout.patch -Patch3: eject-2.1.5-opendevice.patch -Patch4: eject-2.1.5-spaces.patch -Patch5: eject-2.1.5-lock.patch -Patch6: eject-2.1.5-umount.patch -URL: http://www.pobox.com/~tranter -ExcludeArch: s390 s390x -BuildRequires: gettext -BuildRequires: libtool - -%description -The eject program allows the user to eject removable media (typically -CD-ROMs, floppy disks or Iomega Jaz or Zip disks) using software -control. Eject can also control some multi-disk CD changers and even -some devices' auto-eject features. - -Install eject if you'd like to eject removable media using software -control. - -%prep -%autosetup -n %{name} - -%build -%configure -%make_build - -%install -%make_install - -install -m 755 -d %{buildroot}/%{_sbindir} -ln -s ../bin/eject %{buildroot}/%{_sbindir} - -%find_lang %{name} - -%files -f %{name}.lang -%license COPYING -%doc README TODO ChangeLog -%{_bindir}/* -%{_sbindir}/* -%{_mandir}/man1/* - -%changelog -* Tue Feb 08 2011 Fedora Release Engineering - 2.1.5-21 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild - -* Fri Jul 02 2010 Kamil Dudka 2.1.5-20 -- handle multi-partition devices with spaces in mount points properly (#608502) -.... - -[[section]] - -[[spec-file-overview]] -SPEC file overview -~~~~~~~~~~~~~~~~~~ - -Other useful guides: - -* http://docs-old.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch-creating-rpms.html[RPM -Guide] describes how to write a SPEC file. -* The IBM series "Packaging software with RPM" -http://www.ibm.com/developerworks/library/l-rpm1/[Part 1], -http://www.ibm.com/developerworks/library/l-rpm2/[Part 2], and -http://www.ibm.com/developerworks/library/l-rpm3/[Part 3]. -* http://ftp.rpm.org/max-rpm/[Maximum RPM] has the most complete -information, but is dated. - -You will need to follow the Fedora guidelines: -link:Packaging/NamingGuidelines[Package Naming Guidelines], -link:Packaging/Guidelines[Packaging guidelines], and -link:Packaging/ReviewGuidelines[Package review guidelines]. - -Insert comments with a leading "`#`" character, and beware of macros -(beginning with `%`) that are potentially multi-line, as they are -expanded first. When commenting out a line, double the percent signs -(`%%`) of the macros appearing after the "`#`". Also avoid inline -comments on the same line as script commands. - -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 link:Packaging/NamingGuidelines[Package -Naming Guidelines] and generally be lowercase. -* *Version*: The upstream version number. See -link:Packaging/NamingGuidelines#Version_Tag[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 -link:Packaging/NamingGuidelines#Release_Tag[Release tag section] of the -packaging guidelines. The optional link:Packaging/DistTag[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. __'__Note: -This tag is deprecated since Fedora 17. See -https://docs-old.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/Packagers_Guide/chap-Packagers_Guide-Spec_File_Reference-Preamble.html[Spec -File Reference Preamble] _'_ -* *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 link:Packaging/LicensingGuidelines[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. Packaging:Guidelines#Timestamps[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 link:Packaging/SourceURL[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. It is possible to ensure you have specified all necessary build -requires by link:Using_Mock_to_test_package_builds[performing a "mock -build"] of your package. 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 package 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 -https://docs-old.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch09s03.html[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 -"`%autosetup`"; a common variation is "`%autosetup -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. -* *%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. -* *%check*: Script commands to "test" the program. This is run after the -%install procedure, 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. -* *%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. -*Do NOT put software's changelog at here.This changelog is for RPM -itself.* -* *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 -link:How_to_create_an_RPM_package#Subpackages[subpackages]) from a -single SPEC file, such as `name-libs` and `name-devel` packages. - -Do *not* create a "relocatable" package; they don't add value in Fedora -and make things more complicated. - -[[spec-file-sections-explained]] -SPEC file sections explained -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -[[prep-section]] -%prep section -^^^^^^^^^^^^^ - -The %prep section describes how to unpack the compressed packages so -that they can be built. Typically, this includes the "`%autosetup`" -command. Alternatively, you can use "`%setup`" and "`%patch`" commands -with reference to the Source0 (and Source1 etc.) lines. See the -http://ftp.rpm.org/max-rpm/s1-rpm-inside-macros.html[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 and %autosetup -is not what you want, then you can do: - -`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-autosetup-command]] -%prep section: %autosetup command -+++++++++++++++++++++++++++++++++ - -The "`%autosetup`" command unpacks a source package. Switches include: - -* *`-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 "`%autosetup -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. - -If you use "`%setup`" command instead, then _`-q`_' is commonly used to -suppress unecessary output. - -There are http://ftp.rpm.org/max-rpm/s1-rpm-inside-macros.html[more -%setup options if you are unpacking multiple files], which is primarily -useful if you are creating subpackages (see below). The key ones are: - -[cols=",",] -|======================================================================= -|`-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]] -%prep section: %patch commands -++++++++++++++++++++++++++++++ - -If you have used "`%autosetup`" command, the following manual patch -management is not necessary. If you have complex requirements or need -compatibility with EPEL, you may still need this. 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 -ur ../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]] -%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]] -%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_build` - -To override makefile variables, pass them as parameters to `make`: - -` %make_build CFLAGS="%{optflags}" BINDIR=%{_bindir}` - -More more information, see http://sourceware.org/autobook/["GNU -autoconf, automake, and libtool"] and -http://web.archive.org/web/20090411003817/http://www.suse.de/~sh/automake/automake.pdf["Open -Source Development Tools: An Introduction to Make, Configure, Automake, -Autoconf" by Stefan Hundhammer]. - -Some programs use `cmake`. See Packaging/cmake. - -[[install-section]] -%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` + -`%make_install` - -Ideally you should use %make_install which is equivalent to -http://www.gnu.org/prep/standards/html_node/DESTDIR.html[`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` + -`mkdir -p %{buildroot}%{_bindir}/` + -`cp -p mycommand %{buildroot}%{_bindir}/` - -[[check-section]] -%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 %install section, since files in %buildroot may be tested) -instead of within the %build section itself, so that they can be easily -skipped when necessary. - -Often, this section contains: - -`make test` - -Sometimes it can be: - -`make check` - -Please explore the Makefile and choose the appropriate way. - -[[files-section]] -%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]] -%files basics -+++++++++++++ - -The `%defattr` sets 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(``, ``, ``, ``)` - -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]] -%files prefixes -+++++++++++++++ - -You may need to add one or more prefixes to lines in the `%files` -section; seperate them with a space. See -http://ftp.rpm.org/max-rpm/s1-rpm-inside-files-list-directives.html[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 an -appropriate directory under `/usr/share/doc`, whose ownership does not -need to be declared. - -*Note:* If specifying a `%doc` entry, rpmbuild < 4.9.1 removes the doc -directory it installs files into before installing them. This means that -files already in it, for example installed in the `%install` section, -are removed and do not end up in the package. If you want to install -some files in the `%install` section, install them into a temporary -staging directory inside the build dir (not build root), for example -`_docs_staging`, and include them in the in the `%files` list like -`%doc _docs_staging/*`. - -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(0600, 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 -Packaging:Guidelines#Handling_Locale_Files[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` - -The `%readme` prefix is *not* valid in Fedora. - -[[files-and-filesystem-hierarchy-standard-fhs]] -%files and Filesystem Hierarchy Standard (FHS) -++++++++++++++++++++++++++++++++++++++++++++++ - -You should follow the http://www.pathname.com/fhs/[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. Executables that should not normally be executed directly by -users or administrators should (but are executed by other parts of your -package) go in a subdirectory of `/usr/libexec`, which is referred to as -`%{_libexecdir}/%{name}`. - -Do *not* install files into `/opt` or `/usr/local`. -(Packaging:Guidelines#Limited_usage_of_.2Fopt.2C_.2Fetc.2Fopt.2C_and_.2Fvar.2Fopt[reference]) - -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, Perl -and Systemd), 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]] -%files example -++++++++++++++ - -Here's a simple example of a %files section: - -`%files` + -`%doc README` + -`%license LICENSE COPYING` + -`%{_bindir}/*` + -`%{_sbindir}/*` + -`%{_datadir}/%{name}/` + -`%config(noreplace) %{_sysconfdir}/*.conf` - -[[finding-duplicates]] -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]] -Scriptlets -^^^^^^^^^^ - -When an end-user installs the RPM, you may want some commands to be run. -This can be achieved through scriptlets. See Packaging:Scriptlets. - -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 ability are "triggers", which can be run for your -package when other packages are installed or uninstalled. See -http://ftp.rpm.org/api/4.4.2.2/triggers.html[RPM Triggers]. - -[[macros]] -Macros -^^^^^^ - -Macros are text in the format `%{string}`. Typical macros: - -[cols=",,",options="header",] -|======================================================================= -|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/%{name}...` |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 `%autosetup`. - -|`%{_datadir}` |`/usr/share` |Share directory. - -|`%{_defaultdocdir}` |`/usr/share/doc` |Default documentation directory. - -|`%{dist}` |`.fc`__`NUMBER`__ |Distribution+version short name (e.g. -"`.fc`") - -|`%{fedora}` |_`NUMBER`_ |Number of fedora release (e.g. "") - -|`%{_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 -|======================================================================= - -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 -https://docs-old.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch09s07.html[RPM -Guide chapter 9]. - -[[other-tags]] -Other tags -^^^^^^^^^^ - -In addition to Requires and BuildRequires tags, you can also use these -for controlling dependencies: - -* *Provides*: list virtual package names that this package provides. For -example, there might be a package "`foo`" that demands a particular -functionality "bar" from another program. If there are several packages -that can satisfy that demand, those packages can specify -"`Provides: bar`" and the "`foo`" package can specify "`Requires: bar`". -You could also use the -http://dailypackage.fedorabook.com/index.php?/archives/6-Wednesday-Why-The-Alternatives-System.html["alternatives" -system], but avoid if multiple users on the same system might want -different default, as these settings are system-wide. Use -"`rpm -q --provides PACKAGENAME`" to see what a given package provides. -Some examples of virtual packages in Fedora: -** MTA: Used for mail transport agents, such as sendmail. -** tex(latex): Used for latex -* *Obsoletes*: remove another named package(s) when this package is -installed. Use when the package name changes or when it totally replaces -a different package. -* *Conflicts*: state what other packages cannot be installed -simultaneously to this one. Avoid this if you can. See -Packaging/Conflicts. -* *BuildConflicts*: state what packages cannot be installed when -building this package. Avoid this if you can. - -To manage different architectures, there are two tags: - -* *ExcludeArch*: to exclude an architecture on which the package doesn't -build. For example: - -`ExcludeArch: ppc` - -* *ExclusiveArch*: to include only the specified architecture. Avoid -this unless absolutely correct. - -Valid architectures are listed at Architectures. - -[[subpackages]] -Subpackages -^^^^^^^^^^^ - -A SPEC file can define several binary package. In other words, one SRPM -with one SPEC file can result in several RPMS. Note that there is still -only one creation (%prep, %build, %install etc.) process. `name-doc` and -`name-devel` subpackages are common for documentation and development -files respectively. - -Use the `%package` directive to start defining a subpackage: - -`%package subpackage_name` - -After each `%package` directive, list the tags for the subpackage. This -should at least include the Summary and Group tags, as well as the -`%description subpackage_name` and `%files subpackage_name` directives: - -Anything not specified by the subpackage will be inherited from its -parent. - -By default, if the package name is "`foo`" and the subpackage name is -"`bar`", then the resulting subpackage will be "`foo-bar`". You can -override it with the "`-n`" option (but you'll need to use it in all -other directives too if you specify it here): - -`%package -n new_subpackage_name` - -http://docs-old.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch10s04.html[See -the RPM Guide section on subpackages] for more information. - -[[conditionals]] -Conditionals -^^^^^^^^^^^^ - -You can insert conditional statements, for example to test if you are -creating a binary for a certain architecture: - -`%ifarch ARCHITECTURE_NAME` - -the negated version with: - -`%ifnarch ARCHITECTURE_NAME` - -or the more general conditional: - -`%if TRUE_OR_FALSE` - -There is an optional "`%else`" section; all of these are closed with -"`%endif`". - -[[application-specific-guidelines]] -Application Specific Guidelines -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -There are many application-specific guidelines that can help you (e.g., -for specific programming languages, applications, libraries, and build -systems). Many of them are listed as part of the -link:Packaging/Guidelines#Application_Specific_Guidelines[Application -Specific Guidelines of Packaging/Guidelines]. Examples of -application-specific guidelines are those for: - -* Packaging:Cmake[Cmake] -* Packaging:Emacs[Emacs] - -Failing that, some other ways of finding application-specific help are: - -* The 'SEARCH' command on Fedoraproject.org. -* PackagingDrafts -* A link:SIGs[Special Interest Group (SIG)] -* Special:PrefixIndex/Packaging[Wiki pages prefixed with 'Packaging'] - -[[miscellaneous-hints]] -Miscellaneous hints -^^^^^^^^^^^^^^^^^^^ - -Packaging/FrequentlyMadeMistakes has information on frequently-made -mistakes. There are also some recommendations and controversial tricks -on link:PackageMaintainers/Packaging_Tricks[PackageMaintainers/Packaging -Tricks]. - -Try to write your SPEC files so that it is likely to work when a new -release is made upstream, without any changes aside from bumping the -version number and refreshing the source files. For example, if it -contains *.txt files with execute bits, instead of doing - -` chmod a-x Filename1.txt Filename2.txt Filename3.txt` - -consider doing this, which will handle new filenames that use the same -file naming convention: - -` chmod a-x *.txt` - -If you want to see lots of examples of scriptlets, you can show all the -scriptlets on installed programs using: - -` rpm -qa --queryformat "\n\nPACKAGE: %{name}\n" --scripts | less` - -Don't try to interact with the user; RPM is designed to support batch -installs. If an application needs to show a EULA, that needs to be part -of its initial execution, not its installation. - -You might not want to start services, because in a big install that -could slow things down. If you install an init or systemd script, -consider using `chkconfig` or `systemctl` to arrange for the service to -be started/stopped on the next reboot. Before uninstalling, you should -normally try to stop its services if they are running. - -Uninstalling should reverse most changes made during installation, but -don't remove any user-created files. - -Normally, if there are binary executables, then debugging symbols are -stripped from the normal binary packages and placed into a `name-debug` -subpackage. If this shouldn't happen, you can disable the stripping and -creation of this subpackage by putting this at the top of your SPEC: - -`%global _enable_debug_package 0` + -`%global debug_package %{nil}` + -`%global __os_install_post /usr/lib/rpm/brp-compress %{nil}` - -To prevent stripping you may also need to do this in the `%install` -section: - -`export DONT_STRIP=1` - -A way to check for the version of Fedora in a SPEC file for conditional -builds is: - -`%if 0%{?fedora} <= ` - -The `?` causes the macro to evaluate to evaluate to blank if `%fedora` -is not defined. This causes the end result to be the `0` (which is a -number and thus fine), while not interfering with the result if there is -actually a value for `%fedora`. (Note that this trick does not work in -Koji "scratch" builds, where `%fedora` is set during the creation of a -SRPM.) - -GUI programs must have a desktop entry so that people can invoke it from -the graphical desktop menu. For `.desktop` files, see -link:Packaging/Guidelines#Desktop_files[Fedora packaging guidelines for -desktop files] and -http://standards.freedesktop.org/desktop-entry-spec/latest/[desktop -entry spec]. For icons within `/usr/share/icons`, see -http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html[icon -theme spec]. - -[[building-the-binary-package]] -Building the binary package -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -[[test-with-rpmlint]] -Test with rpmlint -^^^^^^^^^^^^^^^^^ - -To catch many common errors early, run `rpmlint` on your SPEC file -before trying to build anything from it: - -`$ rpmlint program.spec` - -If the reported error doesn't make sense, run it again with the "`-i`" -option for longer messages. - -Aim to have no errors, but sometimes `rpmlint` reports false positives. -The link:Packaging/Guidelines#Use_rpmlint[Fedora packaging guidelines] -explains which ones to ignore. - -[[create-binary-rpms-from-the-spec-file]] -Create binary RPMS from the SPEC file -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Once you've created your SPEC file, build the SRPM and binary RPMS by -running this: - -`$ rpmbuild -ba program.spec` - -If successful, RPMS will be created within `~/rpmbuild/RPMS` and SRPMS -will be created within `~/rpmbuild/SRPMS`. - -If it fails, go to the appropriate directory and see what is left over. -To help debug, you can skip earlier stages that succeeded with the -"`--short-circuit`" option. For example, to restart at the `%install` -stage (skipping earlier stages), do this: - -`$ rpmbuild -bi --short-circuit program.spec` - -If you just want to create an SRPM (which does not run the `%prep` or -`%build` or other stages), run this: - -`rpmbuild -bs program.spec` - -[[testing-binary-rpms-with-rpmlint]] -Testing binary RPMS with rpmlint -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -`rpmlint` can be run on SPEC files, RPMS and SRPMS to check for errors. -You need to eliminate or justify warnings before posting a package. -link:Common_Rpmlint_issues[This page] offers explanations for some of -the common issues that come up. If you are in the SPECS directory, do -this: - -`$ rpmlint `__`NAME`__`.spec ../RPMS/*/`__`NAME`__`*.rpm ../SRPMS/`__`NAME`__`*.rpm` - -Enter the `~/rpmbuild/RPMS` directory and into the architecture -subdirectory. You will find some binary RPMS. Quickly see their files -and permissions (to check whether they are correct) by doing: - -`$ rpmls *.rpm` - -If they look fine, install them as root: - -`# rpm -ivp package1.rpm package2.rpm package3.rpm ...` - -Test the programs in a few different ways to see if everything works -correctly. If it is a GUI tool, make sure it shows up in the desktop -menu, otherwise the `.desktop` entry is wrong. - -Uninstall packages later by doing: - -`# rpm -e package1 package2 package3` - -[[mock-and-koji]] -Mock and Koji -~~~~~~~~~~~~~ - -link:Projects/Mock[Mock] is a powerful tool that uses the SRPM you have -created to build binary packages within a nearly empty environment. This -can reveal if you have accurate build dependencies. If it fails, then -you forgot to list something in BuildRequires. See -link:Using_Mock_to_test_package_builds[Using Mock to test package -builds]. Once your account is a member of the "`mock`" group, you can -run commands like this to do local testing: - -`$ mock -r fedora-23-i386 rebuild path_to_source_RPM` - -You can use Koji (which uses `mock`) to do builds on many different -systems, some of which you may not have. PackageMaintainers/Join and -PackageMaintainers/UsingKoji have more information about Koji. Once it's -set up, you can test your SRPM on a variety of platforms by running -commands like: - -`$ koji build --scratch f23 path_to_source_RPM` - -Replace `f23` with any later release of Fedora, or `rawhide`. - -Your Koji builds can only depend on packages that are actually in the -TARGET distribution repository. Thus, you can't use Koji to build for -released distributions if your package depends on other new packages -that Bodhi hasn't released yet. If you need to build against a package -that is not yet a stable released update, submit a Koji buildroot -override request via Bodhi. If it's not your own package you depend on, -contact its maintainer(s). [Before Bodhi could handle Koji buildroot -override requests, the old method has been to file a ticket with rel-eng -at: https://fedorahosted.org/rel-eng/newticket and request that that -package be added as a buildroot override.] - -[[helpful-tools]] -Helpful tools -~~~~~~~~~~~~~ - -The `rpmdevtools` package has a number of helpful tools; -"`rpm -qil rpmdevtools`" will show you what it installs. - -* `rpmdev-bumpspec` : bump the release tag in the spec file and add a -changelog comment with the right date and version format: - -`rpmdev-bumpspec --comment=COMMENT --userstring=NAME+EMAIL_STRING SPECFILES` - -DNF download plugin (from core DNF plugins) is also useful: - -* `dnf download` : download the SRPM of the package by running: - -`dnf download --source PACKAGENAME` - -The `auto-buildrequires` package has a pair of nice tools for helping to -figure out the proper BuildRequires entries. After installing this -package, replace "`rpmbuild`" with "`auto-br-rpmbuild`" and you'll see -an automatically generated BuildRequires list. - -You might find http://rust.sourceforge.net/[RUST] useful (GPL), though -it does not create SPEC files of suitable quality for Fedora packages. -http://kitenet.net/~joey/code/alien/[Alien] converts between package -formats. It won't produce clean SRPMS, but converting an existing -package might provide helpful information. - -If you are thinking about packing your rpm for Fedora, be sure you run -your packages through https://fedorahosted.org/FedoraReview/[Fedora -Review], which helps ensure that you comply to the -Packaging:Guidelines[Packaging Guidelines]. - -Finally, -https://github.com/alanfranz/docker-rpm-builder[docker-rpm-builder] (APL -2.0) uses http://www.docker.com[Docker] to build RPM packages; while -using rpmbuild requires building on the same host distro as the target, -and mock works fine on Fedora/Centos/RHEL distributions for any target, -*this last tool works fine whenever Docker can run*. - -If you want to build your package for diferent distribution and -architectures and to have publicly accesible dnf repository, you can -submit your src.rpm to https://copr.fedoraproject.org[Copr]. - -If you need to sign your new package, use `rpmsign` tool from `rpm-sign` -package. - -[[guidelines-and-rules]] -Guidelines and rules -~~~~~~~~~~~~~~~~~~~~ - -When you create your packages, you'll need to follow the following rules -and guidelines: - -* link:Join_the_package_collection_maintainers[How to join the Fedora -Package Collection Maintainers] -* Packaging:Guidelines[Packaging Guidelines] -* Packaging:NamingGuidelines[Package Naming Guidelines] -* Packaging:LicensingGuidelines[Package Licensing Guidelines] -* Packaging:DistTag[Dist Tag Guidelines] -* Packaging:ReviewGuidelines[Package Review Guidelines] - -There are many official guidelines that will help you with specific -circumstances (e.g. Java programs, OCaml programs, GNOME programs). You -can also learn more from the SIGs and -:Category:Package_Maintainers[Package Maintainers] sections. - -Special:Prefixindex/Packaging[You can also see the list of all Wiki -pages about Packaging] to see if any apply. - -Failing that, you might find some useful recommendations in the -unofficial :Category:Packaging_guidelines_drafts[draft guidelines -category] and link:PackagingDrafts[Packaging Drafts To Do]. - -You might find ideas from http://en.opensuse.org/Packaging[SuSE], -http://www.debian.org/doc/debian-policy/[Debian], but -http://www.mail-archive.com/distributions@lists.freedesktop.org/msg00156.html[distributions -differ in their rules], so do not presume they can be used directly. - -*The .spec files that you create must be open source software, as noted -in the Legal:Fedora_Project_Contributor_Agreement[FPCA].* - -[[maintaining-the-package]] -Maintaining the package -~~~~~~~~~~~~~~~~~~~~~~~ - -Once your package has been accepted, you and your co-maintainers will -need to maintain it. See link:Package_update_HOWTO[Package update HOWTO] -and link:Package_update_guidelines[Package update guidelines]. If you -update the version in multiple releases of Fedora, do it backwards in -time (e.g. release for Fedora N, then once that's accepted, Fedora N-1). -The system presumes that later versions of Fedora have the same or later -versions of programs. - -Encourage the upstream developers to use standard source code release -conventions. Using standard conventions makes packaging much easier. For -more information, see: - -* http://www.dwheeler.com/essays/releasing-floss-software.html[Releasing -Free/Libre/Open Source Software (FLOSS) for Source Installation] (a -quick summary) -* http://www.gnu.org/prep/standards/html_node/Managing-Releases.html[GNU -Coding Standards release process] -* http://en.tldp.org/HOWTO/Software-Release-Practice-HOWTO/[Software -Release Practice HOWTO] -* http://www.pathname.com/fhs/[Filesystem Hierarchy Standard (FHS)] -* http://offog.org/articles/packaging/[Packaging Unix software] - -[[for-more-information]] -For more information -~~~~~~~~~~~~~~~~~~~~ - -The :Category:Package_Maintainers[Package Maintainers] page links to -many other useful pages, and the link:Package_update_HOWTO[Package -update HOWTO] describes how to update an existing package you already -maintain in Fedora. - -For more information, outside of the Fedora Wiki, see: - -* https://developer.fedoraproject.org/deployment/rpm/about.html[A brief -RPM Packaging overview] on the Fedora Developer Portal -* http://www.g-loaded.eu/2006/04/05/how-to-build-rpm-packages-on-fedora/[How -to build RPM packages on Fedora] - very brief run-through -* Packaging software with RPM (developerWorks) -http://www.ibm.com/developerworks/library/l-rpm1/[Part 1], -http://www.ibm.com/developerworks/library/l-rpm2/[Part 2], and -http://www.ibm.com/developerworks/library/l-rpm3.html[Part 3] -* Fedora Classroom had an IRC session on packaging and you can refer to -the logs at -https://fedoraproject.org/wiki/Building_RPM_packages_%2820090405%29 - -* http://ftp.rpm.org/max-rpm/[Maximum RPM Book] - most complete -information, but in some cases old/obsolete -* http://docs-old.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch-creating-rpms.html[RPM -Guide, section on creating RPMs] - this has lots of good information, -and is slightly more up-to-date, but is a draft -* http://web.archive.org/web/20100109050207/http://docs.fedoraproject.org/developers-guide/ch-rpm-building.html[Developer's -guide, section on building RPMs] - via archive.org, disappeared in 2010 - -* http://freshrpms.net/docs/fight/["The fight", Mattias Saou's first -attempt to make a readable rpm package building introduction. ca. 2003] - -* http://en.tldp.org/HOWTO/RPM-HOWTO/index.html[RPM HOWTO: RPM at Idle -by Donnie Barnes] - -* http://en.opensuse.org/Build_Service/cross_distribution_package_how_to[Cross-distribution -package HOWTO] has hints if you're building one RPM for many -distributions. - -* http://linuxshellaccount.blogspot.com/2008/03/creating-your-own-linux-rpms-initial.html[Creating -Your Own Linux RPM's - The Initial Software Build] is another brief -intro, but it makes the point that "The process of building RPM's is -much simpler than creating packages for Solaris... Fewer steps, and the -ability to add all of your software information into one specification -file, makes for a much tighter (and easier to modify or reproduce) -software packaging system." -* http://fedoranews.org/alex/tutorial/rpm/[All you need to know about -RPM] (more about installing packages than creating them) -* The http://wiki.rpm.org/[rpm.org Wiki] has some useful information, -such as the http://wiki.rpm.org/Problems[list of known RPM problems] - -Note: The http://rpm5.org/[rpm5.org] site has some documentation, but do -not depend on it; that is the home of a _fork_ of RPM maintained by Jeff -Johnson. The RPM used by Fedora (and Novell/SuSE) is instead based at -http://www.rpm.org[rpm.org]. http://lwn.net/Articles/236029/[lwn.net has -a brief article] about this. - -Category:Package_Maintainers[Category:Package Maintainers] -Category:How_to[Category:How to] -''' - -See a typo, something missing or out of date, or anything else which can be -improved? Edit this document at https://pagure.io/fedora-docs/quick-docs. diff --git a/en-US/modules/con_rpm_packaging_overview.adoc b/en-US/modules/con_rpm_packaging_overview.adoc new file mode 100644 index 0000000..e6ab44b --- /dev/null +++ b/en-US/modules/con_rpm_packaging_overview.adoc @@ -0,0 +1,60 @@ +[[introduction]] +== RPM Packaging Overview + +Use this guide to create RPM packages and `.spec` files. Despite the focus on Fedora, you can apply much of this document to other RPM-based +distributions. + +Fedora Documentation had released a draft guide for packagers, see +http://docs-old.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/Packagers_Guide[Packagers +Guide]. It is archived. + + +[NOTE] +This document is not an official Fedora packaging guideline. This page +is open for editing by the general Fedora packaging community. For a general-purpose RPM building guide for packagers on Fedora, CentOS and Red Hat Enterprise Linux, see the https://rpm-packaging-guide.github.io/[RPM Packaging Guide]. + +For more information about packaging guidelines, see the following guides: + +* https://fedoraproject.org/wiki/Packaging:Guidelines[Packaging Guidelines] +* http://fedoraproject.org/wiki/Packaging:LicensingGuidelines[Licensing Guidelines] +* http://fedoraproject.org/wiki/Packaging:Naming[ Package Naming Guidelines] +* http://fedoraproject.org/wiki/Packaging:DistTag[ Dist Tag Guidelines] +* http://fedoraproject.org/wiki/Packaging:ReviewGuidelines[ Package Review Guidelines] +* http://fedoraproject.org/wiki/Packaging:Scriptlets[ Recipes for RPM scriptlets] + + +If you plan to submit a package to the official Fedora repository, follow the procedure in http://fedoraproject.org/wiki/Join_the_package_collection_maintainers[Join the package collection +maintainers]. + +Before you begin, select a text editor that you want to use, and ensure that you understand the following terminology. + +[[some-terminology]] +== RPM terminology + +.RPM +The package manager used by Fedora, Red Hat Enterprise Linux, Mageia, OpenSUSE and others. Originally RPM stood for "Red Hat Package Manager" but now it is a recursive acronym "RPM Package Manager". + +.spec file +A plain text file that contains information about a package and instructions that RPM uses for compiling the package's software. To name the file, use the name of the package with the file extension `.spec`. + +.tag +A string, generally capitalized and followed by a colon, which appears at the top of the `.spec` file to provide some important data about the RPM, such as `Name:`, `Version:` or `Summary:`. + +.section +A segment of the `.spec` file that tells RPM how to perform some portion of the package construction process. Many, but not all, sections contain code that is simply passed to the shell, though RPM has significant flexibility around this that is outside of the scope of this document. + +.section header +A short string, starting with `%` at the beginning of a line, which introduces a section. Examples include `%description`, `%prep` and `%files`. + +.macro +A short string, always prefixed by `%` and generally surrounded by curly brackets `{}` which RPM converts to a different and usually longer string. Some macros can take arguments and some arguments are quite complex. Some macros are provided by RPM, some are part of https://apps.fedoraproject.org/packages/redhat-rpm-config[redhat-rpm-config] and https://apps.fedoraproject.org/packages/fedora-rpm-macros[fedora-rpm-macros] packages, but many other packages also provide macros. You can run `rpm --showrc` to view all of the macros currently available on your system, but you do not need to run most of the macros you see there. + + +For a full list of guidelines related to macros, see http://fedoraproject.org/wiki/Packaging:Guidelines#Macros[Macros] in the Packaging Guidelines. + + +.mock +A system for building RPMs locally within your own Fedora installation. This avoids the need to install a full set of build dependencies on your operating system installation, and allows you to build packages for different Fedora releases. + +.koji +The main Fedora build system: https://koji.fedoraproject.org[1]. + diff --git a/en-US/modules/con_rpm_spec_file_overview.adoc b/en-US/modules/con_rpm_spec_file_overview.adoc new file mode 100644 index 0000000..63d93f4 --- /dev/null +++ b/en-US/modules/con_rpm_spec_file_overview.adoc @@ -0,0 +1,123 @@ +== Spec file overview +[[con_rpm_spec_file_overview]] + +Use this guide for information about the specific macros in a `.spec` file. + + +[NOTE] +You can use the macros `%{name}`, `%{version}` and `%{release}` 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 +Add the base name of the package, which must match the `.spec` file name. Follow the http://fedoraproject.org/wiki/Packaging:Naming[Package Naming Guidelines] and write the file name in lower-case letters. + +.Version +Add the upstream version number. See http://fedoraproject.org/wiki/Packaging:Versioning[Package Versioning]. If the version contains tags that are non-numeric, you might need to include the non-numeric characters in the `Release` tag. If upstream uses full dates to distinguish versions, consider using version numbers of the form. For example, `yy.mm[dd]` where `2008-05-01` becomes `8.05`. + +.Release +Set the initial value to `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`. For more information, see the http://fedoraproject.org/wiki/Packaging:Versioning[Versioning Guide] of the packaging guidelines. + +.Summary +Enter a brief, one-line summary of the package. Use American English. Do not end with a period. + +.Group +This tag is deprecated since Fedora 17. See https://docs-old.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/Packagers_Guide/chap-Packagers_Guide-Spec_File_Reference-Preamble.html[Spec +File Reference Preamble] + +.License +Enter an open source software license. Do not use the old Copyright tag. Use a standard abbreviation, for example, "`GPLv2+`" and be specific. For example, use "`GPLv2+`" for GPL version 2 or greater rather than "`GPL`" or "`GPLv2`" where it's true). For more information, see the http://fedoraproject.org/wiki/Packaging:LicensingGuidelines[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. For example, the project website. + +[NOTE] +Do not add a link to the original source code. Add the link to the source code to the `Source0` tag. + +.Source0 +Enter the full URL for the compressed archive that contains the original, pristine source code, as upstream released it. "`Source`" is synonymous with "`Source0`". + +The full URL basename is used when looking in the `SOURCES` directory. If possible, embed `%{name}` and `%{version}`, so that changes to the go to the right place. Preserve the timestamps when downloading source files. For more information, see http://fedoraproject.org/wiki/Packaging:Guidelines#Timestamps[Preserve timestamps]. + +If there is more than one source, name them `Source1`, `Source2`. + +If you add whole new files in addition to the pristine sources, list them as sources after the pristine sources. A copy of each of these sources is included in any source RPM (SRPM) you create, unless you specifically direct otherwise. For more information on special cases, for example, revision control, see https://fedoraproject.org/wiki/Packaging:SourceURL?rd=Packaging/SourceURL[Source URL]. + +.Patch0 +Enter the name of the first patch to apply to the source code. If you must patch the files after you extract them, edit the files and save their differences as a `.patch` file in your `~/rpmbuild/SOURCES` directory. Patches must make only one logical change each, so it's quite possible to have multiple patch files. + +.BuildArch +If you package files that are architecture-independent, for example shell scripts, data files, then add `BuildArch: noarch`. The architecture for the binary RPM is then `noarch`. + +.BuildRoot +This is now redundant in Fedora and is only needed for EPEL5. By default, the build root is placed in "`%{_topdir}/BUILDROOT/`". + +In EPEL5, this is where files are installed during the %install process (after the %build process). + +.BuildRequires +Add a comma-separated list of packages that are required for compiling the program. Usually, this field is repeated on multiple lines. These dependencies are not automatically determined. You must include everything that the package needs to build the program. + +Verify that you have specified all the necessary build requirementss by link:Using_Mock_to_test_package_builds[performing a "mock +build"] of your package. You can specify a minimum version if necessary, for example, `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. For example, use `sed` instead of `perl` if you do not need perl, but note that some applications permanently disable functions if the associated dependency is not present; in those cases you might need to include the additional packages. + +.Requires +Enter 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 and running the program; a package may be in one list or in both. + + +.%description +Enter 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 reformat paragraphs; lines that start with whitespace might be treated as preformatted text and displayed as is, normally with a fixed-width font. See +https://docs-old.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch09s03.html[RPM +Guide]. + +.%prep +Add script commands to "prepare" the program. For example, to extract the program, so that it is ready for building. Typically this is just "`%autosetup`"; a common variation is "`%autosetup -n NAME`" if the +source file unpacks into `NAME`. + +.%build +Add script commands to compile the program and get it ready for installing. The program must come with instructions on how to do this. + +.%install +Add script commands to "install" the program. The commands must copy the files from the `BUILD` directory `%{_builddir}` into the buildroot directory, `%{buildroot}`. + +.%check +Add script commands to "test" the program. This is run after the `%install` procedure, so place it there if you have this section. Often it contains `make test` or `make check`. This is separated from `%build` so that people can skip the self-test if they desire. + +.%clean +Note that this section is now redundant in Fedora and is only necessary for EPEL. +Typically this contains only the following command: + +`rm -rf %{buildroot}` + +.%files +Add the list of files to be installed. + +.%changelog +Add changes in the package. Use the format example above. + +Do not put software's change log here. This change log is only for the RPM. + +.ExcludeArch +If the package does not successfully compile, build or work on a particular architecture, list those architectures under this +tag. + + +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* create a "relocatable" package; they do not add value in Fedora and make things more complicated. + + +.Inserting comments + +Insert comments with a leading "`#`" character, and beware of macros (beginning with `%`) that are potentially multi-line, as they are expanded first. + +When commenting out a line, double the percent signs (`%%`) of the macros appearing after the "`#`". + +Also avoid inline comments on the same line as script commands. + + diff --git a/en-US/modules/proc_rpm_creating_a_rpm.adoc b/en-US/modules/proc_rpm_creating_a_rpm.adoc new file mode 100644 index 0000000..63c1ad3 --- /dev/null +++ b/en-US/modules/proc_rpm_creating_a_rpm.adoc @@ -0,0 +1,139 @@ +[[creating_rpm_package]] +== Creating an RPM package + +.Overview + +To create an RPM package, you must complete the following steps: + +. Create a directory to store the package. Within the package directory, create a `.spec` file. +. In the `.spec` file, add information about your software, instructions for unpacking it, building it, and installing it, as well as a list of files that are in the package. +. Run the `fedpkg` command with the appropriate options to build your package. + +. To create a directory, add a package, and within the package, create a simple program, enter the following commands: ++ +----------- +mkdir -p ~/packaging-work/howdy +cd ~/packaging-work/howdy +cat << EOF > howdy +#!/bin/bash +echo "Howdy, partner!" +EOF +chmod 644 howdy +----------- ++ +[NOTE] +The directory `packaging-work`, the package `howdy`, and program `howdy` names are for example purposes. Edit these names to suit your project. +You can use any location you want but the directory name for the package should match the name of the package. ++ +. To verify that everything built correctly, enter the following command: ++ +------- +$ bash ./howdy +------- ++ +. Create a new file `howdy.spec` and open `howdy.spec` in your text editor. Populate the `howdy.spec` file using the following example as a guide but change anything you require: ++ +[NOTE] +When you create the file, use spaces and do not use tabs to align the text. ++ +--------- +.... +Name: howdy +Version: 1 +Release: 1%{?dist} +Summary: Say hello, Texas style + +License: Public Domain +Source0: howdy + +%description +A simple program to greet the user, Texas style. + +%install + +%files + +%changelog +.... +--------- ++ +. To instruct the package how to install the program, add thie following information to the `%install` section of the `.spec` file. Add the information to the line that follows `%install`: ++ +-------- +mkdir -p %{buildroot}/%{_bindir} +install -p -m 755 %{SOURCE0} %{buildroot}/%{_bindir} +-------- ++ +[NOTE] +In this example, we use the following three macros: `%{buildroot}`, `%{_bindir}`, and `%{SOURCE0}`. This method ignores the origin of the files and directories and focuses on the destination of the files. Without `%{buildroot}` the files might install directly onto your development machine. This is not recommended, especially if you run as root. For more information on macros and `.spec` file entries, see xref:con_rpm_spec_file_overview[]. ++ +. To tell RPM about the file, enter the following information to the `%files` section: ++ +------- + %{_bindir}/howdy +------- ++ +[NOTE] +In general, the `%files` section is about files you have installed into the buildroot. You do not use the `%{buildroot}` macro when listing +files there. ++ +. Save your edits and to run a local build, enter the following command: ++ +----- +$ fedpkg --release f27 local +----- + +This updates the two RPMs. + +.Adding no architecture dependencies + +In this example, the package is a shell script and there is no requirement for the package to build separately on every architecture that Fedora supports. + +. To specify that this package independent of architectures, open the file in your text editor and add the following information after the `Source0:` line: ++ +--------- +BuildArch: noarch +--------- ++ +. Delete the existing `.rpm` files in this directory and run another local build: ++ +----- +$ fedpkg --release f27 local +----- + +.Result + +After you complete the procedure, ensure that you have the following two files: + +. One source file that contains the latest source. +. One binary file with the `.noarch.rpm`. + +.What to do next + +Validate your RPM package with RPM lint, using the following command: + +---- +fedpkg --release f27 lint +---- + +At this stage, there are four or more errors because of the lack of `%prep`, `%build` sections, and `URL` tag. + +To view the list of dependencies, enter the following command: + +----- +rpm -qp --requires howdy-1-1.fc``.noarch.rpm +----- + +RPM adds some internal `rpmlib` dependencies, and one in `/bin/bash` which matches up with the first line of the howdy program. + + +To view a list of what the RPM provides, enter the following commnad: + +----- +rpm -qp --provides howdy-1-1.fc``.noarch.rpm +----- + +This command is more important when your RPM package gains complexity and has dependencies. + +For more information about building a more complete and complex RPM package, see https://fedoraproject.org/wiki/How_to_create_a_GNU_Hello_RPM_package[How to create a GNU Hello RPM package]. + diff --git a/en-US/modules/proc_rpm_preparing_your_system.adoc b/en-US/modules/proc_rpm_preparing_your_system.adoc new file mode 100644 index 0000000..cdcff98 --- /dev/null +++ b/en-US/modules/proc_rpm_preparing_your_system.adoc @@ -0,0 +1,43 @@ +[[preparing-your-system]] +== Preparing your system to create RPM packages + +Before you create RPM packages on Fedora, you must install packaging tools and set up any accounts that you want to use. + +For general information about preparing your environment, understanding source code, building and patching software, see the https://rpm-packaging-guide.github.io/#preparing-software-for-packaging[Preparing Software for Packaging] section in the RPM packaging guide. + +This installs the utilities that you require to work with and build packages in the same manner as official Fedora packages, including the tool that the package reviewers use to check package quality. + +To prepare your build environment to create RPM packages, complete the following steps: + +[NOTE] +You must run the following two commands as the root user. + +. To install the `fedora-packager` and `fedora-review` tools, enter the following command: ++ +------------ +# dnf install fedora-packager fedora-review` +------------ ++ +. To add yourself to the mock group, run the following command: ++ +----------- +# usermod -a -G mock yourusername +----------- ++ +. Change from the root user to your user name and enter the `newgrp` command or log in and out for this change to take effect: ++ +------------- +$ newgrp +------------- ++ +. Run the `id` command to verify that the "mock" group appears in your group list, enter the following command: ++ +---------------- +$ id +---------------- ++ + + +[NOTE] +You can also create a separate user and use it for doing RPM development. Ensure that the user is part of the "mock" +group and enters the `fedora-packager-setup` command.