From Fedora Project Wiki

THIS DOCUMENT IS A DRAFT PENDING OFFICIAL PROMOTION

This document seeks to document the conventions and customs surrounding the proper packaging of Erlang modules and applications in Fedora and EPEL. It does not intend to cover all situations, but to codify those practices which have served the Fedora Erlang community well.

Naming

Erlang packages should be named as erlang-something, except for applications which can be named without the erlang- prefix (e.g. couchdb, rabbitmq-server, wings).

In spec files, the short upstream name (without the erlang- prefix) is typically stored in a global macro for reuse throughout the spec. Both %{realname} and %{srcname} are in common use across Fedora Erlang packages — either is acceptable. Consistency within a single spec file is what matters. We may standardize on one convention in the future once the broader Fedora packaging community converges across language ecosystems.

Building

Rebar3 must be used to build Erlang packages whenever possible, as it is the de-facto standard Erlang build tool. If a project supports multiple build tools (e.g. both erlang.mk and rebar3), the packager must use rebar3. Projects written in Elixir may use mix instead. We recommend using our build macros (%{erlang3_compile}, %{erlang3_install}, %{erlang3_test}) to ensure correct behavior.

Rebar2 (erlang-rebar) is deprecated and must not be used for new packages. Existing packages using rebar2 should be migrated to rebar3.

Declarative BuildSystem

Starting with Fedora 45, a declarative BuildSystem: rebar3 directive is available via erlang-srpm-macros ≥ 0.3.11. Its use is recommended for new packages targeting Fedora 45 and later, but is not yet required.

Note for EPEL maintainers: The declarative BuildSystem: rebar3 is not available in EPEL 9 or EPEL 10. Continue using the explicit macro approach (%{erlang3_compile} etc.) for packages targeting EPEL. Additionally, be aware that the Erlang packages available in EPEL repositories are aging — the CentOS Messaging SIG provides more up-to-date Erlang and RabbitMQ packages for EL9/EL10 via centos-release-messaging.

Debug symbols

Erlang packages should be built with the +debug_info flag. This does NOT impact runtime performance (the BEAM loader discards debug symbols before loading). Dialyzer requires either this debug info or original sources. If the package was built with our recommended macros, the needed debug_info is generated automatically.

Erlang packages should not install their original sources.

File Locations

Erlang packages should be installed to %{_erllibdir}/%{realname}-%{version} (or equivalently %{_erllibdir}/%{srcname}-%{version} depending on which macro the spec uses). The handy macro %{erlang_appdir} has been provided as a shorthand expression of this path for spec files that define %{realname} or %{srcname}. Large applications such as rabbitmq-server install their content elsewhere for historical reasons.

Header files

Header files for Erlang modules stored in the source ./include directory must be bundled with the main package (not in a *-devel subpackage). They are used by system administrators sometimes right from the REPL console. Headers from ./src directory normally should not be packaged; however sometimes it is required. In this case you must package them, but consider reporting an issue upstream about their include file placements.

Dependencies

Erlang packagers need to build the list of BuildRequires by hand, but RPM builds a list of Requires for the packager automatically (except in a few rare cases). Please check the Koji build log. If you see messages like the following, the packager either missed a BuildRequires or the package contains an error:

error: invalid dependency (bad format): ERROR: Can't find lager:error/2 while
processing '/builddir/build/BUILDROOT/erlang-ibrowse-4.2.4-1.fc45.x86_64/
usr/lib64/erlang/lib/ibrowse-4.2.4/ebin/ibrowse.beam'

In the case cited above, the packager should try running:

sudo dnf provides "*/lager.beam"

Changelog

We recommend using %autorelease and %autochangelog for new packages, as they reduce spec file maintenance and are well-supported in Fedora rawhide and stable branches. Maintainers who maintain the same spec file across multiple RPM-based distributions may prefer to manage %changelog manually — this is acceptable.

An example spec file

Here is an example of a typical Erlang package's spec file using recommended modern conventions. The RPM macros use %{realname}, so please be sure to include this definition.

# Use either %%{realname} or %%{srcname} — both are acceptable conventions
%global realname foo

Name:           erlang-%{realname}
Version:        1.2.3
Release:        %autorelease
Summary:        Erlang library for doing cool things
License:        Apache-2.0
URL:            https://github.com/awesomeperson/%{realname}
VCS:            git:%{url}.git
Source0:        %{url}/archive/%{version}/%{realname}-%{version}.tar.gz

# rebar3 installs almost everything required for building. Sometimes
# extra packages are required — check the Koji build log for hints.
BuildRequires:  erlang-rebar3

# RPM detects Erlang dependencies automatically when built with rebar3.
# In rare cases, list missing dependencies manually:
# Requires: erlang-bar

%description
Erlang library for doing cool things.

%prep
%autosetup -p1 -n %{realname}-%{version}

%build
%{erlang3_compile}

%install
%{erlang3_install}

# Install additional runtime files if needed, e.g.:
# cp -arv priv/ %{buildroot}%{erlang_appdir}/

%check
%{erlang3_test}
# For packages with a non-standard rebar config for testing:
# %{erlang3_test -C rebar-test.config}

%files
%license LICENSE.txt
%doc README.md
%{erlang_appdir}/

%changelog
%autochangelog

Declarative variant (Fedora 45+ only)

For packages targeting Fedora 45 and later, the declarative form is available:

# Use either %%{realname} or %%{srcname} — both are acceptable conventions
%global realname foo

Name:           erlang-%{realname}
Version:        1.2.3
Release:        %autorelease
Summary:        Erlang library for doing cool things
License:        Apache-2.0
URL:            https://github.com/awesomeperson/%{realname}
VCS:            git:%{url}.git
Source0:        %{url}/archive/%{version}/%{realname}-%{version}.tar.gz
BuildSystem:    rebar3
BuildOption(install): -n %{realname}

%description
Erlang library for doing cool things.

%files
%license LICENSE.txt
%doc README.md
%{erlang_appdir}/

%changelog
%autochangelog

Note: BuildSystem: rebar3 requires erlang-srpm-macros ≥ 0.3.11 and RPM ≥ 4.20 (Fedora 45+). Do not use this form in packages targeting EPEL or Fedora 44 and earlier.