From Fedora Project Wiki
(Correct some grammar in the Naming section.)
(Spec-file updated)
 
(11 intermediate revisions by 3 users not shown)
Line 5: Line 5:
= Naming =
= Naming =


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


= Building =
= Building =


Normally we're using {{package|erlang-rebar|Rebar}} to build packages. This is a de-facto standard tool for Erlang application building. Ususally it bundled along with the sources. Packager must ensure that we don't use bundled version. We recommend to use our build macros for building - %{erlang_compile} or less generic %{rebar_compile}. However some old software cannot be built with rebar - this is an issue which better be addressed.
{{package|erlang-rebar|Rebar}} is usually used to build Erlang packages, as it is the de-facto standard Erlang build tool. It is often bundled along with the sources, so the packager must ensure that the system installed rebar is used instead of the one included with the package. We recommend using our build macros for building (%{erlang_compile} or less generic %{rebar_compile}) to ensure that the correct rebar is used. However some old software cannot be built with rebar - this is an outstanding issue to be addressed.


= Debug symbols / source installation / dialyzer =
= Debug symbols / source installation / dialyzer =


Erlang package should not install its original sources. Instead packages should ensure that it's built with +debug_info flag. It does NOT impact the runtime performance of the application at all (beam loader disregards debug symbols before loading to VM). Dialyzer requires either this debug info or original sources. if the package was built with our recommended macros (%{erlang_compile} or less generic %{rebar_compile}), then debug_info generated automatically.
Erlang packages should not install their original sources. Instead packages should ensure that they are built with +debug_info flag. It does NOT impact the runtime performance of the application at all (beam loader disregards debug symbols before loading the build images into the VM). Dialyzer requires either this debug info or original sources. If the package was built with our recommended macros (%{erlang_compile} or less generic %{rebar_compile}), then the needed debug_info is generated automatically.


If Erlang package doesn't contain any NIF-libraries, port-applications, or driver libraries, it must contain "%global debug_package %{nil}" directive to suppress building an empty debuginfo sub-package. Unfortunately this adds two additional rpmlint messages:
<s>If the Erlang package doesn't contain any NIF-libraries, port-applications, or driver libraries, it must contain the "%global debug_package %{nil}" directive to suppress building an empty debuginfo sub-package. Unfortunately, this adds two additional rpmlint messages:</s>


<nowiki>Auriga ~: rpmlint ~/rpmbuild/RPMS/x86_64/erlang-cowboy-2.0.0-0.1.pre.3.fc24.x86_64.rpm  
<s><pre><code>Auriga ~: rpmlint ~/rpmbuild/RPMS/x86_64/erlang-cowboy-2.0.0-0.1.pre.3.fc24.x86_64.rpm  
erlang-cowboy.x86_64: E: no-binary
erlang-cowboy.x86_64: E: no-binary
erlang-cowboy.x86_64: W: only-non-binary-in-usr-lib
erlang-cowboy.x86_64: W: only-non-binary-in-usr-lib
1 packages and 0 specfiles checked; 1 errors, 1 warnings.
1 packages and 0 specfiles checked; 1 errors, 1 warnings.
Auriga ~:</nowiki>  
Auriga ~:</code></pre></s>


What rpmlint it trying to say here is that we're installing arch-independent data into arch-dependent library. That's expected. Just ignore these messages for now.
<s>What rpmlint it trying to say here is that we're installing arch-independent data into arch-dependent library space. This is expected, and these messages can be ignored for now.</s>


= File Locations =
= File Locations =


Erlang packages should install theirselves to %{_erllibdir}/%{realname}-%{version}. A packager can use handy macro - %{erlang_appdir}. Big applications, such as {{package|ejabberd}}, {{package|rabbitmq-server}}, {{package|riak}} install their content somewhere else due to historical reasons.
Erlang packages should be installed to %{_erllibdir}/%{realname}-%{version}. The handy macro %{erlang_appdir} has been provided as a shorthand expression of this path for spec files that define %{realname}. Large applications such as {{package|rabbitmq-server}} or {{package|riak}} install their content somewhere else for historical reasons.


= Header files =
= Header files =


Header files for erlang modules stored in ./include directory must be bundled with main package (not in a *-devel subpackage). They are used by system administrators sometimes [http://erlang.org/doc/man/shell.html right from the REPL console]. Headers from ./src directory normally shouldn't be packaged, however sometimes it's required. In this case you have to package it but pconsider reporting upstream about wrong include files placement.
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 [http://erlang.org/doc/man/shell.html right from the REPL console]. Headers from ./src directory normally shouldn't be packaged, however sometimes it's required. In this case you have to package them, but consider reporting an issue upstream about their include file placements.


= Dependencies =
= Dependencies =


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


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


In this case the package contains an error, which was addressed upstream already. But it also might mean that the packager forgot to add "BuildRequires: erlang-lager". We can't give packager a hint on what's missing, but in the case of this message the poackager should try running ''"sudo dnf provides "*/lager.beam"'' first.
In the case cited above, the package contained an error which was addressed upstream already. Errors like this could also mean that the packager forgot to add "BuildRequires: erlang-lager". We can't give packagers a hint on what's missing, but in the case of this message the packager should try running ''"sudo dnf provides "*/lager.beam"''.


= An example of spec-file =
= An example of spec-file =


A typical Erlang package's spec-file looks like that. We're using %{realname} and  %{upstream} macro in RPM scripts, so please fill it properly. Otherwise you have to do a lot of manual work.
Here is an example of a typical Erlang package's spec-file. The RPM macro script use %{realname} and  %{upstream}, so please be sure to include these definitions in your spec files.




<nowiki>%global realname foo
<pre><code>%global realname foo
%global upstream bar
# Technically, we're noarch; but erlang whose directories we install into is not.
# This should be removed if a package contains NIF, or driver.
%global debug_package %{nil}
 


Name: erlang-%{realname}
Name: erlang-%{realname}
Line 57: Line 52:
Release: 1%{?dist}
Release: 1%{?dist}
Summary: Erlang library for doing cool things
Summary: Erlang library for doing cool things
Group: Development/Libraries
License: Apache-2.0
License: ASL 2.0
URL: https://github.com/awesomeperson/%{realname}
URL: https://github.com/%{upstream}/%{realname}
Source0: %{url}/archive/%{version}/%{realname}-%{version}.tar.gz
Source0: https://github.com/%{upstream}/%{realname}/archive/%{version}/%{realname}-%{version}.tar.gz
#Source0: %{url}/archive/<long git hash>/%{realname}-%{version}.tar.gz
# Normally erlang-rebar install almost everything required for building. But sometimes some extra packages required.
# Normally erlang-rebar3 installs almost everything required for building. But sometimes some extra packages are required.
# Please try building in Koji - you'll likely see some hints.
# Please try building in Koji - you'll likely see some hints.
BuildRequires: erlang-rebar
BuildRequires: erlang-rebar3
 
# If the package contains NIF-library or driver, then you have to include one or both of the following lines.
# This has to be done manually - we don't detect them automatically (for now).
%{?__erlang_nif_version:Requires: %{__erlang_nif_version}}
%{?__erlang_drv_version:Requires: %{__erlang_drv_version}}


# Normally RPM detects Erlang dependencies automatically (if built with erlang-rebar). However in some rare cases it can't be detected.
# Normally RPM detects Erlang dependencies automatically (if built with erlang-rebar3). However in some rare cases it can't be detected,
# and you have to list those dependencies manually.
Requires: erlang-bar
Requires: erlang-bar


%description
%description
Erlang library for doing cool things.
Erlang library for doing cool things.


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


%build
%build
%{erlang_compile}
%{erlang3_compile}
 


%install
%install
%{erlang_install}
%{erlang3_install}


# Additionally install some cool stuff required to run application properly
# Additionally install some cool stuff required to run application properly
cp -arv priv/ %{buildroot}%{erlang_appdir}/
cp -arv priv/ %{buildroot}%{erlang_appdir}/


%check
%check
%{erlang_test}
%{erlang3_test}
 
#
# Sometimes upstream uses different config-file for testing
#%%{erlang3_test -C rebar-test.config}


%files
%files
Line 101: Line 90:
%{erlang_appdir}/
%{erlang_appdir}/


* Wed Nov  6 2024 Peter Lemenkov <lemenkov@gmail.com> - 1.2.3-1
- Initial build</code></pre>


* Wed Mar 16 2016 Peter Lemenkov <lemenkov@gmail.com> - 1.2.3-1
[[Category:Packaging guidelines drafts]]
- Initial build</nowiki>
 
[[Category:Packaging guidelines]]

Latest revision as of 09:29, 6 November 2024

THIS DOCUMENT IS WIP

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).

Building

Rebar is usually used to build Erlang packages, as it is the de-facto standard Erlang build tool. It is often bundled along with the sources, so the packager must ensure that the system installed rebar is used instead of the one included with the package. We recommend using our build macros for building (%{erlang_compile} or less generic %{rebar_compile}) to ensure that the correct rebar is used. However some old software cannot be built with rebar - this is an outstanding issue to be addressed.

Debug symbols / source installation / dialyzer

Erlang packages should not install their original sources. Instead packages should ensure that they are built with +debug_info flag. It does NOT impact the runtime performance of the application at all (beam loader disregards debug symbols before loading the build images into the VM). Dialyzer requires either this debug info or original sources. If the package was built with our recommended macros (%{erlang_compile} or less generic %{rebar_compile}), then the needed debug_info is generated automatically.

If the Erlang package doesn't contain any NIF-libraries, port-applications, or driver libraries, it must contain the "%global debug_package %{nil}" directive to suppress building an empty debuginfo sub-package. Unfortunately, this adds two additional rpmlint messages:

<code>Auriga ~: rpmlint ~/rpmbuild/RPMS/x86_64/erlang-cowboy-2.0.0-0.1.pre.3.fc24.x86_64.rpm 
erlang-cowboy.x86_64: E: no-binary
erlang-cowboy.x86_64: W: only-non-binary-in-usr-lib
1 packages and 0 specfiles checked; 1 errors, 1 warnings.
Auriga ~:</code>

What rpmlint it trying to say here is that we're installing arch-independent data into arch-dependent library space. This is expected, and these messages can be ignored for now.

File Locations

Erlang packages should be installed to %{_erllibdir}/%{realname}-%{version}. The handy macro %{erlang_appdir} has been provided as a shorthand expression of this path for spec files that define %{realname}. Large applications such as rabbitmq-server or riak install their content somewhere else 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 shouldn't be packaged, however sometimes it's required. In this case you have to 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 for few rare cases). Please take a look at the Koji build log. If you see messages like the following one, then the packager either missed one of the BuildRequires or the package contains an error:

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

In the case cited above, the package contained an error which was addressed upstream already. Errors like this could also mean that the packager forgot to add "BuildRequires: erlang-lager". We can't give packagers a hint on what's missing, but in the case of this message the packager should try running "sudo dnf provides "*/lager.beam".

An example of spec-file

Here is an example of a typical Erlang package's spec-file. The RPM macro script use %{realname} and  %{upstream}, so please be sure to include these definitions in your spec files.


<code>%global realname foo

Name:		erlang-%{realname}
Version:	1.2.3
Release:	1%{?dist}
Summary:	Erlang library for doing cool things
License:	Apache-2.0
URL:		https://github.com/awesomeperson/%{realname}
Source0:	%{url}/archive/%{version}/%{realname}-%{version}.tar.gz
#Source0:	%{url}/archive/<long git hash>/%{realname}-%{version}.tar.gz
# Normally erlang-rebar3 installs almost everything required for building. But sometimes some extra packages are required.
# Please try building in Koji - you'll likely see some hints.
BuildRequires:	erlang-rebar3

# Normally RPM detects Erlang dependencies automatically (if built with erlang-rebar3). However in some rare cases it can't be detected,
# and you have to list those dependencies manually.
Requires: erlang-bar

%description
Erlang library for doing cool things.

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

%build
%{erlang3_compile}

%install
%{erlang3_install}

# Additionally install some cool stuff required to run application properly
cp -arv priv/ %{buildroot}%{erlang_appdir}/

%check
%{erlang3_test}
#
# Sometimes upstream uses different config-file for testing
#%%{erlang3_test -C rebar-test.config}

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

* Wed Nov  6 2024 Peter Lemenkov <lemenkov@gmail.com> - 1.2.3-1
- Initial build</code>