-
Notifications
You must be signed in to change notification settings - Fork 101
Packaging Fpm
Non-comprehensive guide on packaging fpm itself and packaging with fpm.
MSYS2 (Windows)
The MSYS2 project is a packaging ecosystem build around compiling against the MinGW library.
The toolchain is based on the Cygwin fork MSYS2, hence its name, for providing difficult to port Unix tools on Windows.
It uses pacman
as package manager, which is based on Arch Linux' package manager with the same name.
Package files use the PKGBUILD
format with MSYS2 specific extensions.
PKGBUILD
files are written in bash and provide entry points for the makepkg
program to build a package with can be installed by pacman
.
Important: before starting to use any PKGBUILD
install the respective toolchains:
pacman -S base-devel mingw-w64-<arch>-toolchain
Where <arch>
is one of i686
(mingw32), x86_64
(mingw64), ucrt-x86_64
(ucrt64), clang-i686
(clang32), or clang-x86_64
(clang64).
This package file will create a binary package for fpm 0.4.0, a few specialties of MSYS2's toolchain should be noted:
- All packages build against MinGW, i.e. for native Windows, are prefixed with
mingw-w64-
. Therefore, we define the variable_realname
before with the actual package name. - The variables
MINGW_PACKAGE_PREFIX
,MINGW_PREFIX
andCARCH
are defined by MSYS2'smakepkg
. - The arch entry is always
'any'
, instead the mingw_arch is used to specify the MinGW backend. Available mingw_arch entries are'mingw32'
,'mingw64'
,'ucrt64'
,'clang32'
and'clang64'
. - The pkgver entry reflects the actual package version, while pkgrel is the build number (start counting from 1, reset at each release)
- The pkgdesc entry should contain
(mingw-w64)
for packages build against MinGW. - The
build()
andpackage()
function are the most important hooks to define for creating a package. - Always add a comment line with yourself as maintainer to the
PKGBUILD
- For building Fortran packages you have to have
"${MINGW_PACKAGE_PREFIX}-gcc-fortran"
in your makedepends entries and both"${MINGW_PACKAGE_PREFIX}-gcc-libs"
"${MINGW_PACKAGE_PREFIX}-gcc-libgfortran"
in depends entries
# Maintainer: Sebastian Ehlert <[email protected]>
_realname=fpm
pkgbase=mingw-w64-${_realname}
pkgname="${MINGW_PACKAGE_PREFIX}-${_realname}"
pkgver=0.4.0
pkgrel=1
arch=('any')
mingw_arch=('mingw32' 'mingw64' 'ucrt64')
pkgdesc="Fortran package manager (mingw-w64)"
url="https://github.com/fortran-lang/fpm"
depends=("${MINGW_PACKAGE_PREFIX}-gcc-libs" "${MINGW_PACKAGE_PREFIX}-gcc-libgfortran")
makedepends=("${MINGW_PACKAGE_PREFIX}-gcc-fortran" "${MINGW_PACKAGE_PREFIX}-curl" "git")
options=('strip')
license=('MIT')
source=(${_realname}-${pkgver}.tar.gz::"https://github.com/fortran-lang/fpm/archive/refs/tags/v${pkgver}.tar.gz")
sha256sums=('6c1574273164f859591547b7aae3b2d39471cf8a1d901cf1e453e607fbe9757a')
build() {
cd "${srcdir}/${_realname}-${pkgver}"
local _build="build_${CARCH}"
local _fc="${MINGW_PREFIX}/bin/gfortran"
FC="${_fc}" ./install.sh --prefix="${_build}"
}
package() {
cd "${srcdir}/${_realname}-${pkgver}/build_${CARCH}"
install -Dm755 bin/fpm "${pkgdir}"${MINGW_PREFIX}/bin/fpm
}
Save the above file as PKGBUILD
.
In the same directory you can now start makepkg
to build the package:
❯ MINGW_ARCH=mingw64 makepkg-mingw --syncdeps --cleanbuild --log --force
The final package will be placed in the same directory and can be installed with pacman
using:
❯ pacman -U mingw-w64-x86_64-fpm-0.4.0-1-any.pkg.tar.zst
It is possible to package directly from version controlled repositories, while discouraged in the actual distribution, using git packaged version can be practical for personal use.
A few notes about packages build from git repositories:
- The
-git
suffix is used for the package name - Additional provides and conflicts entries ensure that the git package cannot be installed when a normal version of the same package is already installed
- There is no checksum to test the integrity of the repository, using
'SKIP'
disables the check - The pkgver is determined by a function rather than a static entry
# Maintainer: Sebastian Ehlert <[email protected]>
_realname=fpm
pkgbase=mingw-w64-${_realname}
pkgname="${MINGW_PACKAGE_PREFIX}-${_realname}-git"
pkgver=0.4.0
pkgrel=1
arch=('any')
mingw_arch=('mingw32' 'mingw64' 'ucrt64')
pkgdesc="Fortran package manager (mingw-w64)"
url="https://github.com/fortran-lang/fpm"
provides=("${MINGW_PACKAGE_PREFIX}-${_realname}")
conflicts=("${MINGW_PACKAGE_PREFIX}-${_realname}")
depends=("${MINGW_PACKAGE_PREFIX}-gcc-libs" "${MINGW_PACKAGE_PREFIX}-gcc-libgfortran")
makedepends=("${MINGW_PACKAGE_PREFIX}-gcc-fortran" "${MINGW_PACKAGE_PREFIX}-curl" "git")
options=('strip')
license=('MIT')
source=(${_realname}-git::"git+https://github.com/fortran-lang/fpm.git#branch=main")
sha256sums=('SKIP')
pkgver() {
cd "${_realname}-git"
_parent_ver=$(git describe --tags --abbrev=0 | sed 's/\([^-]*-\)g/r\1/;s/-//g' | tr -d '[:alpha:]' )
printf "%s.r%s.%s" \
"${_parent_ver}" \
"$(git rev-list --count HEAD)" \
"$(git rev-parse --short HEAD)"
}
build() {
cd "${_realname}-git"
local _build="build_${CARCH}"
local _fc="${MINGW_PREFIX}/bin/gfortran"
FC="${_fc}" ./install.sh --prefix="${_build}"
}
package() {
cd "${_realname}-git/build_${CARCH}"
install -Dm755 bin/fpm "${pkgdir}"${MINGW_PREFIX}/bin/fpm
}
As before save the above file as PKGBUILD
.
In the same directory you can now start makepkg
to build the package:
❯ MINGW_ARCH=mingw64 makepkg-mingw --syncdeps --cleanbuild --log --force
The final package will be placed in the same directory and can be installed with pacman
using:
❯ pacman -U mingw-w64-x86_64-fpm-git-0.4.0-r*-g*-1-any.pkg.tar.zst
Homebrew (MacOS)
brew
is a package manager for MacOS.
The nomenclature for all components in brew
is oriented at home brewing.
Package files are called formulas and are written as Ruby classes.
The final package is called a bottle, individual channels are called taps, the main tap for brew
is homebrew/homebrew-core
.
This package file will create a binary package for fpm 0.4.0, a few specialties of brew
toolchain are noted.
- to set a lower bound on the supported GCC version all lower versions must be marked using fails_with.
- there is no easy way to get a correct Fortran compiler version, a hacky solution seems to produce it from the C compiler
class Fpm < Formula
desc "Fortran Package Manager (fpm)"
homepage "https://fpm.fortran-lang.org"
url "https://github.com/fortran-lang/fpm/archive/refs/tags/v0.4.0.tar.gz"
sha256 "6c1574273164f859591547b7aae3b2d39471cf8a1d901cf1e453e607fbe9757a"
license "MIT"
depends_on "curl" => :build
depends_on "gcc" # for gfortran
fails_with gcc: "4"
fails_with gcc: "5"
fails_with gcc: "6"
fails_with :clang
def install
# ENV.fc is not defined and setting it up with ENV.fortran will yield default gfortran
ENV["FC"] = ENV.cc.gsub(/gcc/, "gfortran")
# Compile arguments need some tweaking
system "./install.sh", "--prefix=#{prefix}"
end
test do
system "#{bin}/fpm", "--version"
end
end
A comprehensive guide to get started with packaging for brew
can be found here.