RPM Spec File: Complete Syntax & Options Guide

An RPM .spec file is a recipe for building, installing and packaging software. It’s divided into sections, each with specific purposes.

Header Tags (metadata)

TagPurposeExample
NameName of the packageName: hello
VersionUpstream versionVersion: 1.0
ReleasePackage release (increment on changes)Release: 1%{?dist}
SummaryShort descriptionSummary: Simple hello world program
LicenseLicense typeLicense: MIT
URLProject websiteURL: https://example.com
Source0Main source file (tarball, etc)Source0: hello-1.0.tar.gz
Patch0Patch filePatch0: fix-type.patch
BuildRequiresBuild-time dependenciesBuildRequires: glibc
RequiresRuntime dependenciesRequires: glibc
GroupPacakge group (legacy; rarely needed)Group: Development/Tools
ProvidesVirtual providesProvides: hello-binary
ObsoletesOld pacakge gets replaces with the currentObsoletes: old-hello
ConflictsRaises conflicts and can’t be installedConflicts: hello-beta

%description Section

A longer, multi-line description of your package.

%description
A simple hello world program writter in C programming language for demonstration purposes.

%prep Section

Prepare sources, unpack files, apply patches, etc.

Common Macros:

  • %setup - Unpacks source tarball
    • -q = quite mode; less output
    • -n <dirLocation> = unpacks source into custom directory
    • -c = Create directory before unpacking
    • -a <number> = Unpack additional sources (Source0, etc.)
  • %patch - Apply patches

Example:

%prep
%setup -q
%patch0 -p1

%build Section

Build/Compile the software.

Common Macros:

  • %{optflags} = Compiler optimization flags; distro-recommended flags.
  • %configure = Runs ./configure with standard options.
  • %make_build = Runs make with parallel jobs.

Example:

%build
%make_install

%install Section

Install files into a temporary buildroot.

Common Macros:

  • %{buildroot} = Path to the temporary install root.
  • %make_install = Runs make install DESTDIR=%{buildroot}

Example:

%install
%make_install
# or the manual installation would look like,
%install
mkdir -p %{buildroot}/usr/bin
install -m 0755 hello %{buildroot}/usr/bin/hello

%check Section

Runs the tests to verify the build is successfull or not.

%check
make test
#if that's a binary file to test, we do something like
./hello | grep "Hello"

%clean Section (Legacy)

%clean
rm -rf %{buildroot}

Modern RPM tools clean up automatically, so this is mostly obsolete.

%files Section

List all files to include in the pacakge. Options & Macros:

  • %doc <file>= Marks documentation files.
  • %license <file> = Marks license files.
  • %config <file> = Marks config files (preserved on upgrade).
  • %attr(mode, user, group) <file> = Set permissions/ownership.
  • %dir <dir> = Include a directory (not contents).
  • %ghost <file> = File created at runtime, not in pacakge.

Example:

%files
%doc README.md
%licese LICENSE
%config{noreplace} /etc/hello.conf
/usr/bin/hello
%attr(0755,root,root) /usr/bin/hello

%changelog Section

Document package changes.

* DATE NAME <email> - VERSION-RELEASE
- Change description

Example:

%changelog
* Sat Jul 05 2025 Yashwanth Rathakrishnan <iamyaash@example.com> - 1.0-1
- Initial package

Scriptlets

Executes shell code at specific points

ScriptletWhen it runs
%preBefore install
%postAfter install
%preunBefore uninstall
%postunAfter uninstall
%trigger --<pkgName>On package upgrade

Example using %post:

%post
echo "Installation complete!"

Special Macros & Usage

  • %{name}, %{version}, %{release}: Expand to package name, version, release
  • %{_bindir}, %{_libdir}, %{_datadir}: Standard directories (/usr/bin, /usr/lib, /usr/share)
  • %{_sysconfdir}: /etc
  • %{_mandir}: /usr/share/man
  • %{_docdir}: /usr/share/doc
  • %{?_smp_mflags}: Parallel make flags (e.g., -j4)

.spec File Structure

Name:           hello
Version:        1.0
Release:        1%{?dist}
Summary:        Simple Hello World program
License:        MIT
URL:            https://example.com
Source0:        hello-1.0.tar.gz
BuildRequires:  gcc

%description
A simple Hello World program written in C.

%prep
%setup -q

%build
gcc %{optflags} -o hello hello.c

%install
mkdir -p %{buildroot}/usr/bin
install -m 0755 hello %{buildroot}/usr/bin/hello

%check
./hello | grep "Hello"

%files
%doc README.md
%license LICENSE
/usr/bin/hello

%post
echo "Thank you for installing hello!"

%changelog
* Sat Jul 05 2025 Yashwanth Rathakrishnan <you@example.com> - 1.0-1
- Initial package

Tips

  • Macros make your spec file portable and maintainable.
  • Always use %{buildroot} in %install to avoid polluting the real system.
  • Use %doc, %license, and %config to properly classify files.
  • Scriptlets should be used sparingly and only when necessary.
  • Test your RPM with rpmbuild -ba <specfile> and install with rpm -i <rpmfile>.