arch-hs
A program generating PKGBUILD for hackage packages. Special thanks to felixonmars.
Notice that arch-hs
will always support only the latest GHC version.
Introduction
Given the name of a package in hackage, arch-hs
can generate PKGBUILD files, not only for the package
whose name is given, but also for all dependencies missing in community.
arch-hs
has a naive built-in dependency solver, which can fetch those dependencies and find out which are required to be packaged.
During the dependency calculation, all version constraints will be discarded due to the arch haskell packaging strategy,
thus there is no guarantee of dependencies' version consistency.
Prerequisite
arch-hs
is just a PKGBUILD text file generator, which is not integrated with pacman
, depending on nothing than:
-
Pacman database (community.db
)
-
Hackage index tarball (01-index.tar
, or 00-index.tar
previously) -- usually provided by cabal-install
Installation
Both arch-hs
and arch-hs-diff
are portable, which means that they are not restricted to Arch Linux.
However, if you want to run them in other systems, you have to build them from source.
Install the latest release
# pacman -S arch-hs
arch-hs
is available in community, so you can install it using pacman
.
Install the development version
# pacman -S arch-hs-git
The -git
version is available in archlinuxcn, following the latest git commit.
Build
$ git clone https://github.com/berberman/arch-hs
Then build it via stack or cabal.
Stack
$ stack build
Cabal (dynamic)
$ cabal configure --disable-library-vanilla --enable-shared --enable-executable-dynamic --ghc-options=-dynamic
$ cabal build
Usage
Just run arch-hs
in command line with options and a target. Here is an example:
we will create the archlinux package of accelerate:
$ arch-hs -o ~/test accelerate
......
ⓘ Recommended package order (from topological sort):
1. unique
2. tasty-kat
3. accelerate
......
ⓘ Write file: /home/berberman/test/haskell-accelerate/PKGBUILD
ⓘ Write file: /home/berberman/test/haskell-unique/PKGBUILD
ⓘ Write file: /home/berberman/test/haskell-tasty-kat/PKGBUILD
✔ Success!
This message tells us that in order to package accelerate
, we must package unique
and tasty-kat
first sequentially, because accelerate
dependens on them to build or test,
whereas they are not present in archlinux community repo.
$ tree ~/test
/home/berberman/Desktop/test
├── haskell-accelerate
│ └── PKGBUILD
├── haskell-tasty-kat
│ └── PKGBUILD
└── haskell-unique
└── PKGBUILD
arch-hs
will generate PKGBUILD for each package. Let's see what we have in ./haskell-accelerate/PKGBUILD
:
# This file was generated by arch-hs, please check it manually.
# Maintainer: Your Name <youremail@domain.com>
# This file was generated by arch-hs, please check it manually.
# Maintainer: Your Name <youremail@domain.com>
_hkgname=accelerate
pkgname=haskell-accelerate
pkgver=1.3.0.0
pkgrel=1
pkgdesc="An embedded language for accelerated array processing"
url="https://github.com/AccelerateHS/accelerate/"
license=("custom:BSD3")
arch=('x86_64')
depends=('ghc-libs' 'haskell-ansi-terminal' 'haskell-base-orphans' 'haskell-cryptonite' 'haskell-half' 'haskell-hashable' 'haskell-hashtables' 'haskell-hedgehog' 'haskell-lens' 'haskell-prettyprinter' 'haskell-prettyprinter-ansi-terminal' 'haskell-primitive' 'haskell-tasty' 'haskell-terminal-size' 'haskell-unique' 'haskell-unordered-containers' 'haskell-vector')
makedepends=('ghc' 'haskell-doctest')
source=("https://hackage.haskell.org/packages/archive/$_hkgname/$pkgver/$_hkgname-$pkgver.tar.gz")
sha256sums=('4b97161f145c81f7554679802059598587e06d49b2c153e7bafc4dd6974bad92')
build() {
cd $_hkgname-$pkgver
runhaskell Setup configure -O --enable-shared --enable-executable-dynamic --disable-library-vanilla \
--prefix=/usr --docdir=/usr/share/doc/$pkgname --enable-tests \
--dynlibdir=/usr/lib --libsubdir=\$compiler/site-local/\$pkgid \
--ghc-option=-optl-Wl\,-z\,relro\,-z\,now \
--ghc-option='-pie'
runhaskell Setup build
runhaskell Setup register --gen-script
runhaskell Setup unregister --gen-script
sed -i -r -e "s|ghc-pkg.*update[^ ]* |&'--force' |" register.sh
sed -i -r -e "s|ghc-pkg.*unregister[^ ]* |&'--force' |" unregister.sh
}
check() {
cd $_hkgname-$pkgver
runhaskell Setup test
}
package() {
cd $_hkgname-$pkgver
install -D -m744 register.sh "$pkgdir"/usr/share/haskell/register/$pkgname.sh
install -D -m744 unregister.sh "$pkgdir"/usr/share/haskell/unregister/$pkgname.sh
runhaskell Setup copy --destdir="$pkgdir"
install -D -m644 LICENSE -t "$pkgdir"/usr/share/licenses/$pkgname/
rm -f "$pkgdir"/usr/share/doc/$pkgname/LICENSE
}
arch-hs
will collect the information from hackage db, and apply it into a fixed template after some processing steps
including renaming, matching license, and filling out dependencies etc.
However, packaging haven't been done so far.
arch-hs
may does well statically, but we should guarantee that this package can be built by ghc with the latest dependencies;
hence some patchs may be required in prepare()
, such as uusi.
Options
Output
$ arch-hs -o ~/test TARGET
Using -o
can generate a series of PKGBUILD including TARGET
with its dependencies into the output dir. If you don't pass it, only dependency calculation will occur.
Flag Assignments
$ arch-hs -f TARGET:FLAG_A:true TARGET
Using -f
can pass flags, which may affect the results of resolving.
AUR Searching
$ arch-hs -a TARGET
With -a
, arch-hs
will regard AUR as another package provider, and it will try to search missing packages in AUR as well.
Skipping Components
$ arch-hs -s COMPONENT_A TARGET
Using -s
can force skip runnable components in dependency resolving.
This is useful when a package doesn't provide flag to disable its runnables, which will be built by default but are trivial in system level packaging.
Notice that this only makes sense in the lifetime of arch-hs
, whereas generated PKGBUILD and actual build processes will not be affected.
$ arch-hs -e ~/TARGET/TARGET.cabal TARGET
For Testing Purposes Only
Using -e
can include extra .cabal
files as supplementary. Useful when the TARGET
hasn't been released to hackage.
Trace
$ arch-hs --trace TARGET
With --trace
, arch-hs
can print the process of dependency resolving into stdout.
$ arch-hs --trace-file foo.log TARGET
Similar to --trace
, but the log will be written into a file.
Uusi
$ arch-hs -o ~/test --uusi TARGET
With --uusi
, arch-hs
will generate following snippet for each package:
prepare() {
uusi $_hkgname-$pkgver/$_hkgname.cabal
}
See uusi for details.
Help
$ arch-hs --help
arch-hs - a program generating PKGBUILD for hackage packages.
Usage: arch-hs [-h|--hackage PATH] [-c|--community PATH] [-o|--output PATH]
[-f|--flags package_name:flag_name:true|false,...]
[-s|--skip component_name,...] [-e|--extra PATH_1,...] [-a|--aur]
[--trace] [--trace-file PATH] [--uusi] TARGET
Try to reach the TARGET QAQ.
Available options:
-h,--hackage PATH Path to hackage index
tarball (default: "~/.cabal/packages/YOUR_HACKAGE_MIRROR/01-index.tar | 00-index.tar")
-c,--community PATH Path to
community.db (default: "/var/lib/pacman/sync/community.db")
-o,--output PATH Output path to generated PKGBUILD files (empty means
dry run)
-f,--flags package_name:flag_name:true|false,...
Flag assignments for packages - e.g.
inline-c:gsl-example:true (separated by ',')
-s,--skip component_name,...
Skip a runnable component (executable, test suit, or
benchmark) in dependency calculation
-e,--extra PATH_1,... Extra cabal files' path - e.g.
/home/berberman/arch-hs/arch-hs.cabal
-a,--aur Enable AUR searching
--trace Print trace to stdout
--trace-file PATH Path to trace file (empty means do not write trace to
file)
--uusi Splicing uusi into prepare()
-h,--help Show this help text
For all available options, have a look at the help message.
Diff
arch-hs
also provides a component called arch-hs-diff
. arch-hs-diff
can show the differences of package description between two versions of a package.
This is useful in the subsequent maintenance of a package. Example:
$ arch-hs-diff HTTP 4000.3.14 4000.3.15
▶ You didn't pass -f, different flag values may make difference in dependency resolving.
ⓘ Start running...
ⓘ Downloading cabal file from https://hackage.haskell.org/package/HTTP-4000.3.14/revision/0.cabal...
ⓘ Downloading cabal file from https://hackage.haskell.org/package/HTTP-4000.3.15/revision/0.cabal...
Package: HTTP
Version: 4000.3.14 ⇒ 4000.3.15
Synopsis: A library for client-side HTTP
URL: https://github.com/haskell/HTTP
Depends:
base >=4.3.0.0 && <4.14
time >=1.1.2.3 && <1.10
array >=0.3.0.2 && <0.6
bytestring >=0.9.1.5 && <0.11
mtl >=2.0 && <2.3
network >=2.6 && <3.2
network-uri ==2.6.*
parsec >=2.0 && <3.2
--------------------------------------
base >=4.3.0.0 && <4.15
time >=1.1.2.3 && <1.11
array >=0.3.0.2 && <0.6
bytestring >=0.9.1.5 && <0.11
mtl >=2.0 && <2.3
network >=2.6 && <3.2
network-uri ==2.6.*
parsec >=2.0 && <3.2
MakeDepends:
HUnit >=1.2.0.1 && <1.7
deepseq >=1.3.0.0 && <1.5
httpd-shed >=0.4 && <0.5
mtl >=1.1.1.0 && <2.3
pureMD5 >=0.2.4 && <2.2
split >=0.1.3 && <0.3
test-framework >=0.2.0 && <0.9
test-framework-hunit >=0.3.0 && <0.4
Flags:
HTTP
⚐ mtl1:
description:
Use the old mtl version 1.
default: False
isManual: False
⚐ warn-as-error:
description:
Build with warnings-as-errors
default: False
isManual: True
⚐ conduit10:
description:
Use version 1.0.x or below of the conduit package (for the test suite)
default: False
isManual: False
⚐ warp-tests:
description:
Test against warp
default: False
isManual: True
⚐ network-uri:
description:
Get Network.URI from the network-uri package
default: True
isManual: False
✔ Success!
arch-hs-diff
does not require hackage db, it downloads cabal files from hackage server instead.
Limitations
-
The dependency solver will ONLY expand the dependencies of executables , libraries and sub-libraries recursively, because
circular dependency lies ubiquitously involving test suites and their buildTools. arch-hs
is not able to handle with complicated situations:
the libraries of a package partially exist in hackage, some libraries include external sources, etc.
-
Currently, arch-hs
's functionality is limited to dependency processing, whereas necessary procedures like
file patches, loose of version constraints, etc. are need to be done manually, so DO NOT give too much trust in generated PKGBUILD files.
ToDoList
Contributing
Issues and PRs are always welcome. _(:з」∠)_