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:
Preamble - Metadata (Name, Version, License, etc.)
%prep - Prepare source code
%build - Compile the software
%install - Install into buildroot
%files - List of files to package
%changelog - Version history
Complete Example
Simple Binary Package (discord.spec)
Source Build Package (anki.spec)
%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
Package name. Must match the spec filename and be lowercase with hyphens.
Upstream version number. Use actual version, not git commits.
Package release number. Increment for package-only changes. Always use %?dist macro to ensure distribution-specific releases.
One-line description. Should not end with a period. Summary: Free Voice and Text Chat for Gamers
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
Project homepage or repository URL.
Source Files
Primary source archive URL. Use %{version} macro. Source0: https://dl.discordapp.net/apps/linux/%{version}/discord-%{version}.tar.gz
Additional source files (Source1, Source2, etc.). Source0: terra.repo
Source1: terra-extras.repo
Source2: terra-nvidia.repo
Patch files to apply during %prep. Patch0: 0001-No-update.patch
Dependencies
Packages needed to build. Can be specified multiple times. BuildRequires: cmake >= 3.15
BuildRequires: gcc-c++
BuildRequires: python3-devel
Runtime dependencies. Auto-detected for libraries, but must specify others. Requires: python3-sqlalchemy
Requires: libX11 >= 1.6
Suggested packages that enhance functionality but aren’t required. Recommends: (mpv or mpv-nightly)
Recommends: java-21-openjdk
Weak suggestions for additional functionality.
Older package names this replaces. Obsoletes: anki <= 2.1.15
Packages that cannot be installed alongside this one.
Virtual packages or capabilities this package provides. Provides: %{name}-toolkit-%{major_package_version} = %{?epoch:%{epoch}:}%{version}
Architecture Control
Only build on specified architectures. ExclusiveArch: x86_64 aarch64
Do not build on specified architectures.
For architecture-independent packages.
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:
Standard Tarball
With Patches
Git Clone
No Source
%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:
CMake Build
Autotools Build
Custom Build
No Build
%build
%cmake \
-DLauncher_QT_VERSION_MAJOR="%{qt_version}" \
-DLauncher_BUILD_PLATFORM="%{build_platform}" \
-DBUILD_TESTING=OFF
%cmake_build
%install
Installs files into buildroot:
CMake Install
Manual Install
Configuration Files
Python Wheels
%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:
Basic Files
With Wildcards
Configuration Files
With Directories
%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-release Use %autochangelog for automatic changelog generation in some cases.
Subpackages
Create multiple packages from one spec:
Metapackage Structure (cuda.spec)
Repository Subpackages (terra-release.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:
Macro Path Purpose %{_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