Terra
Guidelines

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:

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 <[email protected]>

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-macros
    • BuildRequires: cargo-rpm-macros
    • BuildRequires: rust-srpm-macros
  • You MAY generate the spec file using rust2rpm.
  • You SHOULD NOT use the tradtional Fedora %cargo_prep macro. Instead, use %cargo_prep_online from anda-srpm-macros. Also, you SHOULD remove the %generate_buildrequires macro, as it is useless.
  • It is RECOMMENDED to use %cargo_license_online and %cargo_license_summary_online, although they are not a strict requirement.
  • You SHOULD NOT use both %cargo_build and %cargo_install in the same spec file as anything that calls cargo install might cause a rebuild due to a cargo bug. You SHOULD only include %cargo_build or %cargo_install. In most cases, you can just omit %cargo_build entirely and it will build just fine.

Example:

%prep
%autosetup -n %{crate}-%{version} -p1
%cargo_prep_online
 
%build
%{cargo_license_online} > LICENSE.dependencies
 
%install
%cargo_install

In 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_bin

If 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-macros
    • BuildRequires: 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 by go2rpm in the Provides: field.
  • You SHOULD remove the %generate_buildrequires section, and add either add %global gomodulesmode GO111MODULE=on OR use %goprep_online instead of %goprep in the %prep section.
    • You SHOULD add BuildRequires: anda-srpm-macros to your spec if using %goprep_online.

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-macros
    • BuildRequires: 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%_bindir

The 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/netto

Zig

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: zig
    • BuildRequires: zig-rpm-macros
    • BuildRequires: 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 is x86_64_v2 instead of baseline due 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_target with appropriate flags instead of %zig_build. You however SHOULD use %zig_build instead if none of the above apply.
    • If using %zig_build_target, you SHOULD add BuildRequires: anda-srpm-macros to your spec.
    • For more information on %zig_build_target, please see its documentation on our macros page.

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-docs

Example using %zig_build_target:

%build
%{zig_build_target -r fast -c x86_64_v2} \
  -Demit-docs
  • Note that ReleaseFast and especially ReleaseSmall will 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

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.).
  • 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.
  • If you are unsure if a bump is needed, bump it.
  • You SHOULD add a %changelog entry 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 %changelog entry.

Patches

  • Packages SHOULD apply patches (usually via the -p* flag) in %autosetup. If this is not possible (typically when %autosetup is 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=Application

The 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:

  1. Add it to your package's folder
  2. Add it as a Source: in the .spec file
  3. Install it
  4. List it in the %files section

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.desktop
Validating 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=Application

All 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.desktop

Usage 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-
%endif

Correct:

%ifarch x86_64
%define arch %{nil}
%elifarch aarch64
%define arch arm64-
%endif

Footnotes

Footnotes

  1. https://github.com/terrapkg/packages/blob/e65a762352246f918d12e7c5a0e032ba0b1be73b/anda/langs/nim/dive/umdive.spec (opens in a new tab)

  2. https://github.com/terrapkg/packages/blob/e65a762352246f918d12e7c5a0e032ba0b1be73b/anda/langs/nim/netto/netto.spec (opens in a new tab)