Skip to main content

Overview

RPM spec files define how packages are built, installed, and packaged. In Terra, spec files follow Fedora conventions with some Terra-specific additions.

Basic Structure

Every spec file contains these main sections:
  1. Preamble - Metadata (Name, Version, License, etc.)
  2. %prep - Prepare source code
  3. %build - Compile the software
  4. %install - Install into buildroot
  5. %files - List of files to package
  6. %changelog - Version history

Complete Example

%define debug_package %{nil}
%global _build_id_links none

# Exclude private libraries
%global __requires_exclude libffmpeg.so
%global __provides_exclude_from %{_datadir}/%{name}/.*\\.so

Name:           discord
Version:        0.0.127
Release:        1%?dist
Summary:        Free Voice and Text Chat for Gamers
URL:            https://discord.com
Source0:        https://dl.discordapp.net/apps/linux/%{version}/discord-%{version}.tar.gz
License:        https://discord.com/terms
Requires:       glibc GConf2
Requires:       nspr >= 4.13
Requires:       nss >= 3.27
Requires:       libX11 >= 1.6
Requires:       libXtst >= 1.2
Group:          Applications/Internet
ExclusiveArch:  x86_64

%description
All-in-one voice and text chat for gamers that's free, secure, and works on
both your desktop and phone.

%prep
%autosetup -n Discord

%build

%install
rm -rf $RPM_BUILD_ROOT
mkdir -p %{buildroot}%{_bindir}
mkdir -p %{buildroot}%{_datadir}/discord
cp -rv * %{buildroot}%{_datadir}/discord
mkdir -p %{buildroot}%{_datadir}/applications/
mkdir -p %{buildroot}%{_datadir}/pixmaps
ln -s %_datadir/discord/discord.desktop %{buildroot}%{_datadir}/applications/discord.desktop
ln -s %_datadir/discord/discord.png %{buildroot}%{_datadir}/pixmaps/discord.png
ln -s %_datadir/discord/Discord %buildroot%_bindir/discord

%files
%_bindir/discord
%{_datadir}/discord/
%{_datadir}/applications/discord.desktop
%{_datadir}/pixmaps/discord.png

%changelog
* Thu Jan 19 2023 madonuko <[email protected]> - 0.0.143-1
- Initial package

Preamble Section

Required Fields

Name
string
required
Package name. Must match the spec filename and be lowercase with hyphens.
Name:           discord
Version
string
required
Upstream version number. Use actual version, not git commits.
Version:        25.09.2
Release
string
required
Package release number. Increment for package-only changes.
Release:        1%?dist
Always use %?dist macro to ensure distribution-specific releases.
Summary
string
required
One-line description. Should not end with a period.
Summary:        Free Voice and Text Chat for Gamers
License
string
required
SPDX license identifier(s). Use AND for multiple licenses.
# Single license
License:        GPL-3.0-or-later

# Multiple licenses
License:        AGPL-3.0-or-later AND GPL-3.0-or-later AND MIT AND BSD-3-Clause
URL
string
required
Project homepage or repository URL.
URL:            https://discord.com

Source Files

Source0
string
Primary source archive URL. Use %{version} macro.
Source0:        https://dl.discordapp.net/apps/linux/%{version}/discord-%{version}.tar.gz
SourceN
string
Additional source files (Source1, Source2, etc.).
Source0:        terra.repo
Source1:        terra-extras.repo
Source2:        terra-nvidia.repo
PatchN
string
Patch files to apply during %prep.
Patch0:         0001-No-update.patch

Dependencies

BuildRequires
string
Packages needed to build. Can be specified multiple times.
BuildRequires:  cmake >= 3.15
BuildRequires:  gcc-c++
BuildRequires:  python3-devel
Requires
string
Runtime dependencies. Auto-detected for libraries, but must specify others.
Requires:       python3-sqlalchemy
Requires:       libX11 >= 1.6
Recommends
string
Suggested packages that enhance functionality but aren’t required.
Recommends:     (mpv or mpv-nightly)
Recommends:     java-21-openjdk
Suggests
string
Weak suggestions for additional functionality.
Suggests:       gamemode
Obsoletes
string
Older package names this replaces.
Obsoletes:      anki <= 2.1.15
Conflicts
string
Packages that cannot be installed alongside this one.
Conflicts:      anki-qt5
Provides
string
Virtual packages or capabilities this package provides.
Provides:       %{name}-toolkit-%{major_package_version} = %{?epoch:%{epoch}:}%{version}

Architecture Control

ExclusiveArch
string
Only build on specified architectures.
ExclusiveArch:  x86_64 aarch64
ExcludeArch
string
Do not build on specified architectures.
ExcludeArch:    s390x
BuildArch
string
For architecture-independent packages.
BuildArch:      noarch

Global Variables

Common Macros

# Disable debug package generation
%global debug_package %{nil}

# Disable build-id links
%global _build_id_links none

# Define custom variables
%global real_name prismlauncher
%global nice_name PrismLauncher
%global qt_version 6

# Version-based conditionals
%global dist %{nil}

Filtering Dependencies

# Exclude specific requirements
%global __requires_exclude libffmpeg.so

# Exclude provides from specific paths
%global __provides_exclude_from %{_datadir}/%{name}/.*\.so

# Complex filtering
%global __requires_exclude ^lib-.*.so
%global __provides_exclude ^lib-.*.so

Spec Sections

%description

Provides detailed package description:
%description
Audacity is a cross-platform multitrack audio editor. It allows you to
record sounds directly or to import files in various formats. It features
a few simple effects, all of the editing features you should need, and
unlimited undo.

%prep

Prepares source code for building:
%prep
%autosetup -n Discord
%autosetup automatically extracts source and applies patches. The -p1 flag strips one directory level from patch paths.

%build

Compiles the software:
%build
%cmake \
  -DLauncher_QT_VERSION_MAJOR="%{qt_version}" \
  -DLauncher_BUILD_PLATFORM="%{build_platform}" \
  -DBUILD_TESTING=OFF

%cmake_build

%install

Installs files into buildroot:
%install
%cmake_install

%check

Runs test suite:
%check
%ctest

# Or for other test systems
desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop
appstream-util validate-relax --nonet %{buildroot}%{_metainfodir}/*.xml

%files

Lists files included in the package:
%files
%license LICENSE*
%doc README*
%{_bindir}/anki
%{_datadir}/applications/anki.desktop
%{_datadir}/pixmaps/anki.png

%changelog

Version history in reverse chronological order:
%changelog
* Tue Jan 06 2026 Owen Zimmerman <[email protected]> - 10.0.0-1
- Update to 10.0.0, remove Qt5 version

* Wed Apr 03 2024 seth <getchoo at tuta dot io> - 8.2-2
- move JREs to weak deps, add java 21 for snapshots

* Tue Jan 3 2023 madonuko <[email protected]> - 2.1.60
- Initial package
Format: * Day Month Date Year Name <email> - version-releaseUse %autochangelog for automatic changelog generation in some cases.

Subpackages

Create multiple packages from one spec:
%package cli-tools
Summary:        Compute Unified Device Architecture command-line tools
Requires:       %{name} = %{?epoch:%{epoch}:}%{version}-%{release}
Requires:       %{name}-cupti%{?_isa}
Requires:       %{name}-gdb%{?_isa}

%description cli-tools
Contains the command line tools to debug and profile CUDA applications.

%package libs
Summary:        Compute Unified Device Architecture native run-time library
Requires(post): ldconfig
Requires:       %{name}-cudart%{?_isa}
Requires:       libcublas%{?_isa}

%description libs
Contains the CUDA run-time library required to run CUDA application natively.

%package devel
Summary:        Development files for %{name}
Requires:       %{name}%{_isa} = %{?epoch:%{epoch}:}%{version}-%{release}
Requires:       %{name}-libs%{_isa} = %{?epoch:%{epoch}:}%{version}-%{release}

%description devel
This package provides the development files of the %{name} package.

%files
%license LICENSE
%doc README

%files cli-tools
# Empty metapackage

%files libs
# Empty metapackage

%files devel
%{_libdir}/pkgconfig/cuda.pc

Standard File Paths

Use RPM macros for standard directories:
MacroPathPurpose
%{_bindir}/usr/binUser executables
%{_sbindir}/usr/sbinSystem executables
%{_libdir}/usr/lib64 (x86_64)Libraries
%{_includedir}/usr/includeHeader files
%{_datadir}/usr/shareArchitecture-independent data
%{_sysconfdir}/etcConfiguration files
%{_mandir}/usr/share/manMan pages
%{_docdir}/usr/share/docDocumentation
%{_localstatedir}/varVariable data

Best Practices

Security:
  • Never disable GPG signature verification without good reason
  • Validate desktop and appstream files in %check
  • Use %config(noreplace) for user-editable configuration files
Dependencies:
  • Let RPM auto-detect library dependencies when possible
  • Use Recommends for optional features, not Requires
  • Version dependencies only when necessary
  • Use boolean dependencies: (mpv or mpv-nightly)
File Lists:
  • Use wildcards carefully - be specific when possible
  • Always include %license and %doc markers
  • Use %dir for directories without all contents
  • Configuration files need %config(noreplace)

Common Patterns

Desktop Applications

BuildRequires:  desktop-file-utils
BuildRequires:  libappstream-glib

%install
desktop-file-install --dir %{buildroot}%{_datadir}/applications \
  %{buildroot}%{_datadir}/applications/app.desktop

%check
desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop
appstream-util validate-relax --nonet %{buildroot}%{_metainfodir}/*.xml

%files
%{_datadir}/applications/app.desktop
%{_datadir}/icons/hicolor/*/apps/app.png
%{_metainfodir}/app.metainfo.xml

Python Packages

BuildRequires:  python3-devel
BuildRequires:  python3-setuptools

%install
for file in out/wheels/*.whl; do
    python -m installer --destdir="%{buildroot}" $file
done

find %{buildroot} -iname __pycache__ | xargs -r rm -rf

%files
%_libdir/python*/site-packages/package/
%_libdir/python*/site-packages/package-%{version}.dist-info/

Library Packages

%package libs
Summary:        Runtime libraries for %{name}

%package devel
Summary:        Development files for %{name}
Requires:       %{name}-libs%{?_isa} = %{version}-%{release}

%files libs
%{_libdir}/lib*.so.*

%files devel
%{_includedir}/*
%{_libdir}/lib*.so
%{_libdir}/pkgconfig/*.pc

Build docs developers (and LLMs) love