Terra Guidelines
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 (opens in a new tab) and RFC 8174 (opens in a new tab).
Packagers and maintainers MUST follow the policies and guidelines listed in this document.
Everything covered here is one of 3 things:
- A difference from the Fedora Packaging Guidelines (opens in a new tab)
- In addition to the Fedora Packaging Guidelines (opens in a new tab)
- A Terra-exclusive guideline
It is highly recommended to read through the Fedora Packaging Guidelines (opens in a new tab) on langauges/sections not listed here, or for greater detail.
Terra Packaging Guidelines
Packager Field
The package maintainer of a package SHOULD be added to the Packager: preamble as follows:
Packager: Raboneko <raboneko@fyralabs.com>Usage of the mold Linker
We encourage the use of mold (opens in a new tab), which can speed up build times, especially in large projects.
You MAY enable it in C/++ projects by adding -fuse-ld=mold in CFLAGS/CXXFLAGS.
The %with_mold flag is enabled by default in anda-srpm-macros. mold is also preinstalled in the builders.
You can disable mold for Rust and Nim by using %bcond_with mold.
Interpreted Languages (Python, Ruby, etc.)
All packages using interpreted languages SHOULD follow the Fedora guidelines. All dependencies must be packaged individually as they are considered runtime dependencies.
Dynamically Compiled Languages (C, C++, Vala)
Dependencies required for runtime MUST be packaged separately.
Statically Compiled Languages
Terra does not strictly follow Fedora's reproducibility requirements, and we do not want large amounts of development libraries for them, packagers SHOULD vendor dependencies on build time.
Terra's Mock sandbox has networking enabled, so builders can download the dependencies directly on build time.
Rust
These are guidelines for packaging projects written in Rust (opens in a new tab).
For the official Rust language documentation, see here (opens in a new tab).
- You SHOULD add (at least!) the following build dependencies to your spec file:
BuildRequires: anda-srpm-macrosBuildRequires: cargo-rpm-macrosBuildRequires: rust-srpm-macros
- You MAY generate the spec file using
rust2rpm. - You SHOULD NOT use the tradtional Fedora
%cargo_prepmacro. Instead, use%cargo_prep_onlinefromanda-srpm-macros. Also, you SHOULD remove the%generate_buildrequiresmacro, as it is useless. - It is RECOMMENDED to use
%cargo_license_onlineand%cargo_license_summary_online, although they are not a strict requirement. - You SHOULD NOT use both
%cargo_buildand%cargo_installin the same spec file as anything that callscargo installmight cause a rebuild due to a cargo bug. You SHOULD only include%cargo_buildor%cargo_install. In most cases, you can just omit%cargo_buildentirely and it will build just fine.
Example:
%prep
%autosetup -n %{crate}-%{version} -p1
%cargo_prep_online
%build
%{cargo_license_online} > LICENSE.dependencies
%install
%cargo_installIn rare cases, you may need to use %cargo_build and %crate_install_bin instead:
%prep
%autosetup -n %{crate}-%{version}
%cargo_prep_online
%build
%{cargo_license_online} > LICENSE.dependencies
%{cargo_build} --locked
%install
# install the binary from target/rpm/%{crate} to %buildroot%_bindir
%crate_install_binIf Rust nightly is required, add the %rustup_nightly macro to %prep.
Check the Rust section on the SRPM page for more information on these macros.
Go
These are guidelines for packaging projects written in Go (opens in a new tab).
For the official Go language documentation, see here (opens in a new tab).
- You SHOULD add (at least!) the following build dependencies to your spec file:
BuildRequires: go-rpm-macrosBuildRequires: go-srpm-macros
- If you use
go2rpm, you SHOULD NOT use the default naming, as an unnecessarily long package name is bad for UX. You MAY put the name generated bygo2rpmin theProvides:field. - You SHOULD remove the
%generate_buildrequiressection, and add either add%global gomodulesmode GO111MODULE=onOR use%goprep_onlineinstead of%goprepin the%prepsection.- You SHOULD add
BuildRequires: anda-srpm-macrosto your spec if using%goprep_online.
- You SHOULD add
Nim
These are guidelines for packaging projects written in Nim (opens in a new tab).
For the official Nim language documentation, see here (opens in a new tab).
- You SHOULD add (at least!) the following build dependencies to your spec file:
BuildRequires: anda-srpm-macrosBuildRequires: nim
- You SHOULD use our Nim macros.
In most cases, use nimble to download dependencies in %prep,
then %build with nim, e.g.1:
%prep
%autosetup
%nim_prep
%build
%nim_c src/dive
%install
install -Dm755 src/dive -t %buildroot%_bindirThe use of the atlas (opens in a new tab) package cloner is also recognized, e.g.2:
%prep
%autosetup -Sgit
%build
atlas init
atlas rep atlas.lock
%nim_c src/nettoZig
These are guidelines for packaging projects written in Zig (opens in a new tab).
For the official Zig language documentation, see here (opens in a new tab).
- You SHOULD add (at least!) the following build dependencies to your spec file:
BuildRequires: zigBuildRequires: zig-rpm-macrosBuildRequires: zig-srpm-macros
- When building Zig projects you SHOULD keep in mind that Zig is an optimization centric language and some projects may rely on build arguments different than what the upstream Fedora macros (opens in a new tab) set. For example, many Zig projects rely on
ReleaseFast(or more rarely,ReleaseSmall) builds for runtime optimization. Additionally, some Zig projects only work correctly when built for certain microarchitectures or higher (usually, this isx86_64_v2instead ofbaselinedue to reliance on SIMD). - For these reasons, you SHOULD refer to upstream guidance when packaging Zig projects.
- If any of the scenarios above apply, you MAY use
%zig_build_targetwith appropriate flags instead of%zig_build. You however SHOULD use%zig_buildinstead if none of the above apply.- If using
%zig_build_target, you SHOULD addBuildRequires: anda-srpm-macrosto your spec. - For more information on
%zig_build_target, please see its documentation on our macros page.
- If using
Regardless of build macro in use, they should be used in either the %build or %install section depending on how the project is built (as some can be built directly into root by setting the DESTDIR=%{buildroot} variable).
Example using %zig_build:
%build
%{zig_build} \
-Demit-docsExample using %zig_build_target:
%build
%{zig_build_target -r fast -c x86_64_v2} \
-Demit-docs- Note that
ReleaseFastand especiallyReleaseSmallwill strip some debug info from the binaries. - Some Zig projects have enabled build flags to override this and those SHOULD be used if available (this will usually be
-Dstrip=false). - If they are not, you may need to disable debug packages using the global variable
%global debug_package %{nil}if not enough debug info is preserved to strip.
For projects where dynamic linking of all dependencies is simply not possible (such as the version in the Fedora repos is too new or too old) or that have no dependencies to link, you MAY use %zig_build_target with the -s flag. You SHOULD still dynamically link compatible dependencies by using -fsys=pkgname.
Shell Completions
- SHOULD be a subpackage.
- SHOULD use the
%pkg_completionmacro.
Development and Shared Libraries
You SHOULD try to use the %pkg_devel_files, %pkg_libs_files and %pkg_static_files macros.
Shared library packages SHOULD be suffixed with -libs.
These packages SHOULD NOT contain anything except:
%_libdir/*.so.*
%doc …
%license …Do not confuse the -libs file (*.so.*) with a -devel file (*.so).
Development library packages SHOULD be suffixed with -devel.
These packages SHOULD NOT contain anything except:
%doc …
%license …
%_includedir/*
# ^ source files, depending on the language, could be in other locations
%_libdir/*.so
%_libdir/*.a
%_libdir/pkgconfig/%{name}.pc
# and other development files (.vapi, .typelib, .gir, etc.).Miscellaneous
Fixing Packages
- If a PR is changing anything user-facing, the
Release:tag SHOULD be bumped. The only exception SHOULD be if you are fixing a package where the current version does not and has never built.- Some (not all!) examples of user-facing fixes requiring a
Release:bump:- Installing a missing file.
- Adding any build or non-build, hard or soft, forward or backward dependencies.
- Changing any user-facing tags (
URL:,License:,Summary:, etc.).
- Some (not all!) examples of user-facing fixes requiring a
- If a package fix PR is fixing/changing anything build-facing, the
Release:tag SHOULD NOT need to be bumped.- Some (not all!) examples changes NOT requiring a
Release:bump:- Fixing a package that failed to build when the
Version:tag is bumped. - Any changes that do not affect the final package.
- Fixing a package that failed to build when the
- Some (not all!) examples changes NOT requiring a
- If you are unsure if a bump is needed, bump it.
- You SHOULD add a
%changelogentry for large changes, such as file renames, new build process, etc. Small changes like adding build dependencies or adding one-liners to make a build work MAY be omitted from adding a%changelogentry.
Patches
- Packages SHOULD apply patches (usually via the
-p*flag) in%autosetup. If this is not possible (typically when%autosetupis not used), you SHOULD use %autopatch.
Providing Your Own .desktop File
If you are packaging a graphical app that doesn't provide its own .desktop file, you SHOULD create one.
Creating the .desktop File
Copy the following template:
[Desktop Entry]
Name=PACKAGE NAME
Exec=PROVIDED_BINARY
Icon=ICON NAME
Type=ApplicationThe Icon tag SHOULD NOT a contain full path, just the name of the icon file.
The Exec tag SHOULD be a full path if the binary placed in /usr/bin is a symlink.
If this is not the case, it is up to you if you want to use the full path or not (it will look in the user's $PATH).
You SHOULD name this file either package-name.desktop or package_app-ID.desktop.
You MAY add more tags, to see all possible tags, read through the freedesktop specification (opens in a new tab).
Installing the .desktop File
To install the .desktop file:
- Add it to your package's folder
- Add it as a
Source:in the .spec file - Install it
- List it in the
%filessection
It is RECOMMENDED to use the %_appsdir macro from Anda SRPM instead of %_datadir/applications/.
With NeoHtop package (opens in a new tab) as the example:
Source1: NeoHtop.desktop
...
%install
install -Dm644 %{SOURCE1} %{buildroot}%{_appsdir}/NeoHtop.desktop
...
%files
...
%{_appsdir}/NeoHtop.desktopValidating the .desktop File
You MUST validate your .desktop file. To do this, add the following to your spec file:
BuildRequires: desktop-file-utils
...
%check
desktop-file-validate %{buildroot}%{_appsdir}/NeoHtop.desktop
...Finished Example
NeoHtop.desktop:
[Desktop Entry]
Categories=Utility;
Comment=A cross-platform system monitor
Exec=NeoHtop
Icon=NeoHtop
Name=NeoHtop
Terminal=false
Type=ApplicationAll custom .desktop file portions of a spec file:
Source1: NeoHtop.desktop
...
BuildRequires: desktop-file-utils
%install
...
install -Dm644 %{SOURCE1} %{buildroot}%{_appsdir}/NeoHtop.desktop
%check
desktop-file-validate %{buildroot}%{_appsdir}/NeoHtop.desktop
%files
...
%{_appsdir}/NeoHtop.desktopUsage of Periods in Various Package Fields
You MUST NOT have a period at the end of any Summary: tags, and you SHOULD have a period at the end of all %descriptions.
Usage of %elifarch
To make specs easier to read, you SHOULD use %ifarch followed by %elifarch before %endif in specs where build steps are arch dependent.
Incorrect:
%ifarch x86_64
%define arch %{nil}
%endif
%ifarch aarch64
%define arch arm64-
%endifCorrect:
%ifarch x86_64
%define arch %{nil}
%elifarch aarch64
%define arch arm64-
%endif