RPM CREATION
This is a guide on how to create a RPM package from source code or another source-rpm (SRPM)
PREP SYSTEM TO EASILY CREATE RPMs
-
First we need to install all the packages necessary to start building RPM packages (as root):
#For Fedora: $ dnf install @development-tools fedora-packager fedora-review #For EL $ yum install @"Development Tools" fedora-packager fedora-review
-
Create a custom user specifically for packaging. Good idea especially for not accidentally leaking your private keys to the world. Do the following as root:
$ /usr/sbin/useradd makerpm $ usermod -a -G mock makerpm $ passwd makerpm
-
Setup your directory structure for the build environment. Do this on the makerpm user if you created one.
$ rpmdev-setuptree
WORKFLOW
-
Get source and save it to ~/rpmbuild/SOURCES
-
Open a terminal in ~/rpmbuild/SPECS and run the following command
$ rpmdev-newspec NAMEOFSOURCEFILE
-
Edit and add in the necessary data into the SPEC
-
In a terminal goto your SPEC folder if you left it and run the following command. Install missing packages if need be and rerun the command if necessary.
$ rpmbuild -ba SPECFILE.spec
-
Once you have an SRPM in ~/rpmbuild/SRPMS you can turn around and test it out completely with mock. If you cannot run this as your build user add it to the mock user group.
$ mock -r MOCK_PROFILE ~/rpmbuild/SRPMS/PACKAGENAME.srpm
Mock will create a fake build chroot and start chugging away at installing dependencies and then fire off the build. If it fails, fix what is broken in the SPEC and rebuild the SRPM and then rerun mock. A package built on EL should build on Fedora but this is not guaranteed without some edits, and vice-versa. Easiest method if you are building for both is to have two separate user accounts with separate SPEC files.
WORKING WITH THE .SPEC FILE
First off for completeness, create your spec using rpmdev-newspec. This will ensure that all the necessary sections are defined and all the macros to facilitate a proper SPEC are present. You won't always need all them, but its simpler to delete what isn't needed rather than fidget for hours before you realize what you missed.
GLOBAL VARIABLES
These are the following variables that are preset based off what is in the spec. You can use these as shorthand.
- RPM_SOURCE_DIR
- RPM_BUILD_DIR
- RPM_DOC_DIR
- RPM_OPT_FLAGS
- RPM_ARCH
- RPM_OS
- RPM_ROOT_DIR
- RPM_BUILD_ROOT
- RPM_PACKAGE_NAME
- RPM_PACKAGE_VERSION
**Name: **
Fill in the package name here.
Version:
Fill in the version information here
Release: 1%{?dist}
This is the iterative release. If you are making a small change, increment this. Don't blow this off, as if you release two packages that are the same iteration, the new changes will not be pushed in the repo to users with the original. So if your first release is 1.0.0-1 and you found a glitch in your rpm that was published to the repo, fix it, and iterate it as 1.0.0-2.
Summary:
A summary of what this software does.
License:
Fill in what license the code is under. Can be found in the source download or on the github page.
URL:
The link to the page where the software was obtained
Source0:
You can have a seriers of these but need at least one. All source code files need to be listed here. You can include compressed archives. If you have external files such as icons, .desktop files, or premade configurations, list each as Source1, Source2, etc.
BuildRequires:
The required packages for building the package go here. One package per line, with successive ones also having the BuildRequires: leadin.
Requires:
Same as BuildRequires: but instead of building, this is for running the program(s) compiled from the source. Again, one entry per line, and successive entries also require the Requires: leadin
%description
This is the description of the package as you would see it in the repo query (such as yum info gedit). Personally I prefer to copy and paste from the website since they are better marketers and descriptors than what I can come up with
%prep
The %prep script is the first script RPM executes during a build. Prior to the %prep script, RPM has performed preliminary consistency checks, such as whether the spec file's source tag points to files that actually exist. Just prior to passing control over to the %prep script's contents, RPM changes directory into RPM's build area, which, by default, is ~/rpmbuild/BUILD.
%setup -q
The %setup macro, which is used to unpack the original sources.
%build
The %build script picks up where the %prep script left off. Once the %prep script has gotten everything ready for the build, the %build script is usually somewhat anti-climactic — normally invoking make, maybe a configuration script, and little else.
Like %prep before it, the %build script has the same assortment of environment variables to draw on. Also, like %prep, %build changes directory into the software's top-level build directory (located in RPM_BUILD_DIR, or usually called
Unlike %prep, there are no macros available for use in the %build script. The reason is simple: Either the commands required to build the software are simple (such as a single make command), or they are so unique that a macro wouldn't make it easier to write the script.
%configure
Optional macro for automating the usual ./configure. This is not always the case, and you should consult the documentation in the source or on their website for how one actually builds the source.
make %{?_smp_mflags}
The actual build command. This presumes that you are able to build with a simple make. This is not always the case, and you should consult the documentation in the source or on their website for how one actually builds the source.
%install
Macro for setting up the installation of your application in the fake build environment
rm -rf $RPM_BUILD_ROOT
Leave this alone. This cleans up for the following macro %make_install.
%make_install
The macro for installing the software. This is going to assume that the usual ./configure && make && make install is the correct build steps. This is not always the case, and you should consult the documentation in the source or on their website for how one actually builds the source.
%files
This is where all the files of the finished package are declared. A simple cheat is to leave this blank and copy over the files that are complained about in the rpmbuild -ba specfile command's error output.
%doc
This is where you declare the documentation
%changelog
A changelog from version to version. Helps to keep track of what happened when and by whom.
ADDITIONAL RESOURCES
- My Youtube Video
- RPM.org Packager Docs
- MaxRPM
- Fedora Project's How to create an RPM package
- Fedora Project's Packagers Guide
- Copr-cli
CHEATSHEET
-
To take the source and spec and feed it into mock in one fell swoop to do a build:
``` cd ~/rpmbuild mock -r TARGET_PLATFORM --spec=SPECS/program.spec --sources=SOURCES/program-ver.tar.gz ```
-
One can use copr-cli to do the build from the cli with copr. The package can be a local file that is uploaded or an URL.
``` copr-cli build REPONAME package.src.rpm ```