Difference between revisions of "Haskell"

From ArchWiki
Jump to: navigation, search
(Use stack-static from AUR instead of upstream)
(Building statically linked packages with Cabal (without using shared libraries): rewrite confusing note, see User_talk:Lahwaacz#https:.2F.2Fwiki.archlinux.org.2Findex.php.2FHaskell.23Using_Cabal_with_static_linking)
Line 37: Line 37:
 
This section explains how to install {{ic|cabal-install}} but from [https://hackage.haskell.org/package/cabal-install Hackage] instead of the official {{Pkg|cabal-install}} package from the repositories. This {{ic|cabal-install}} will build Haskell packages without using [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/shared_libs.html shared libraries] unlike the official {{Pkg|cabal-install}} which requires you to link dynamically.
 
This section explains how to install {{ic|cabal-install}} but from [https://hackage.haskell.org/package/cabal-install Hackage] instead of the official {{Pkg|cabal-install}} package from the repositories. This {{ic|cabal-install}} will build Haskell packages without using [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/shared_libs.html shared libraries] unlike the official {{Pkg|cabal-install}} which requires you to link dynamically.
  
{{Note|This section is about how {{Pkg|ghc}} is able to build Haskell code into shared libraries allowing pre-compiled code to be shared between several programs, mind that it isn't related to generating completely statically linked ELF binaries on Linux.}}
+
{{Note|In the context of this section, static linking does not mean generating completely static ELF binaries. Only Haskell code will be linked statically into a single ELF binary, which may be dynamically linked to other system libraries such as ''glibc''.}}
  
 
In theory with any {{ic|cabal-install}} you could choose between both methods, static and dynamic, for linking your Haskell code. In practice because in Arch some basic Haskell libraries ({{ic|haskell-*}} packages) are provided as shared objects ({{ic|.so}} files) and those libraries are globally registered in Cabal, it has trouble using the same libraries for static linking. To avoid linking [https://bugs.archlinux.org/task/54563#comment158826 errors], it's also especially important to not to mix statically and dynamically Haskell packages installed on the same system, as Cabal doesn't fetch a required package once it has been globally registered (check them with the command {{ic|ghc-pkg list}}) in one of its forms and not the other (independently of the linking type of the package that it's needed).
 
In theory with any {{ic|cabal-install}} you could choose between both methods, static and dynamic, for linking your Haskell code. In practice because in Arch some basic Haskell libraries ({{ic|haskell-*}} packages) are provided as shared objects ({{ic|.so}} files) and those libraries are globally registered in Cabal, it has trouble using the same libraries for static linking. To avoid linking [https://bugs.archlinux.org/task/54563#comment158826 errors], it's also especially important to not to mix statically and dynamically Haskell packages installed on the same system, as Cabal doesn't fetch a required package once it has been globally registered (check them with the command {{ic|ghc-pkg list}}) in one of its forms and not the other (independently of the linking type of the package that it's needed).

Revision as of 18:17, 29 August 2017

Haskell is a general purpose, purely functional, programming language.

Installation

Haskell generates machine code that can be run natively on Linux. There is nothing special required to run a binary (already compiled) software, like the ones provided in the official repositories or by the ArchHaskell group. On the other side, AUR packages or source codes requires a compiler to build the software.

Installing the compiler alone permits to build Haskell source code. A few additional tools are needed for development work.

Compiler

To build a Haskell source–code into native–code, a compiler must be installed. There are several implementations available, but the one used most (which is now de facto the reference) is the GHC (Glasgow Haskell Compiler). It is available in the official repositories as ghc.

You can try it with the following file:

Main.hs
main = putStrLn "Hello, World"

and by running:

$ ghc -dynamic Main.hs
$ ./Main 
Hello, World

Problems with linking

GHC uses static linking by default and the -dynamic flag is needed to select dynamic linking. Since version 8.0.2-1, the Arch ghc package no longer contains static versions of the GHC boot libraries by default, nor do any of the haskell-* packages . Static versions of the GHC boot libraries may be installed separately through the ghc-static package, but no such equivalent exists for the haskell-* packages. Therefore, without -dynamic Haskell code and packages will generally fail to link unless the program depends only on boot packages and locally installed packages and ghc-static is installed.

This also causes issues with Cabal trying to use the default static linking. To force dynamic linking in Cabal, edit ~/.cabal/config and add the line executable-dynamic: True.

Dynamic linking is used for most Haskell modules packaged through pacman and is common for packages in the AUR. Since GHC provides no ABI compatibility between compiler releases, static linking is often the preferred option for local development outside of the package system.

Building statically linked packages with Cabal (without using shared libraries)

This section explains how to install cabal-install but from Hackage instead of the official cabal-install package from the repositories. This cabal-install will build Haskell packages without using shared libraries unlike the official cabal-install which requires you to link dynamically.

Note: In the context of this section, static linking does not mean generating completely static ELF binaries. Only Haskell code will be linked statically into a single ELF binary, which may be dynamically linked to other system libraries such as glibc.

In theory with any cabal-install you could choose between both methods, static and dynamic, for linking your Haskell code. In practice because in Arch some basic Haskell libraries (haskell-* packages) are provided as shared objects (.so files) and those libraries are globally registered in Cabal, it has trouble using the same libraries for static linking. To avoid linking errors, it's also especially important to not to mix statically and dynamically Haskell packages installed on the same system, as Cabal doesn't fetch a required package once it has been globally registered (check them with the command ghc-pkg list) in one of its forms and not the other (independently of the linking type of the package that it's needed).

For these reasons, you have to make sure that the only two related Haskell packages you have installed are ghc, the compiler, and ghc-static, the boot libraries on its static form, (not stack, cabal-helper, cabal-install and none of the haskell-* dynamic libraries available in the official repositories).

You can also use Stack as an alternative build tool for Haskell packages, which will link statically by default. But if you still want to use Cabal to build using static linking, follow the next steps of this section to install your own compiled cabal-install from Hackage. For this purpose we are going to use the tool Stack that will help us fetching all the dependencies required and building your own cabal-install.

First you have to install stack-staticAUR because you'll use it to bootstrap the compilation of your own Cabal and you don't want to pull as dependencies those packages from the official Arch repositories containing the haskell-* dynamic libraries.

Then prepare Stack downloading the package index. Stack will be used with the only purpose of bootstrapping the compilation of your own cabal-install but using the already installed ghc compiler:

$ stack setup --system-ghc

Now install your own cabal-install:

$ stack install --system-ghc cabal-install

This newly installed cabal-install has been compiled without shared libraries and won't use them when building packages by default. Also, this cabal-install will use the installed ghc compiler.

Haskell development tools

To start developing in Haskell easily, one option is the haskell-platform bundle which is described as:

The easiest way to get started with programming Haskell. It comes with all you need to get up and running. Think of it as "Haskell: batteries included".

Although an AUR package exists (haskell-platformAUR[broken link: archived in aur-mirror]), the Haskell Platform can be advantageously replaced by installing the following packages from the official repositories:

Alternatively, you can use stack to manage your Haskell environment by following the Arch Linux install instructions.

Managing Haskell packages

Tango-view-fullscreen.pngThis article or section needs expansion.Tango-view-fullscreen.png

Reason: Stack utility and Stackage repository already have adoption in Haskell world. If you familiar with them, please provide description. (Discuss in Talk:Haskell#)

Many Haskell libraries and executables are grouped in packages. They are all available on Hackage. To install and manage these packages, several methods are available and unusual ones are explained in the rest of this section.

The recommended workflow is the following:

cblrepo is a tool used for maintaining Haskell packages for Linux distributions. A wrapper around this, cabal2pkgbuild-gitAUR[broken link: archived in aur-mirror], can create PKGBUILD files from Hackage packages. See Haskell package guidelines for more information on creating new Haskell packages.

Pros/Cons of the different methods

The following table documents the advantages and disadvantages of different package management styles.

Method Pros Cons
Official repositories Provided by ArchLinux developers, consistent versions of packages, already compiled Only a few packages available
ArchHaskell repository Provided by ArchHaskell group, consistent versions of packages, already compiled Need manual intervention to get started with
cabal-install All packages available Installed in home folder, cabal-install is not a package manager, incompatible versions of packages possible (aka. cabal hell)
Arch User Repository Simple to get started Risk of unmaintained or orphaned packages, incompatible versions of packages possible

ArchHaskell repository

See ArchHaskell for details.

cabal-install

Warning: Discouraged method, keep in mind that cabal-install is not a package manager.
Note: The only exception is for Haskell development, where cabal-install is the recommended tool. Since version 1.18, cabal provides a sandbox system that permits to isolate different versions of libraries for different projects. There is an introduction to cabal sandbox here.

Preparation and $PATH

Install cabal-install from the official repositories.

To run installed executables without specifying the path, the cabal binary folder ~/.cabal/bin must be added to the $PATH variable. That can be done by putting the following line in your shell configuration file, for instance ~/.bashrc for bash or ~/.zshrc for zsh:

PATH=$PATH:~/.cabal/bin
To run executables within a cabal sandbox, you must also add
PATH=$PATH:.cabal-sandbox/bin

Installing packages

$ cabal update

$ # When using ghc-static
$ cabal install <pkg>

$ # When using ghc
$ cabal install\
	--enable-shared
	--enable-executable-dynamic
	--ghc-options≈-dynamic
	<pkg>

It is possible to install a package system–wide with the --global flag, but this is strongly discouraged. With the user–wide install, all files are kept in ~/.cabal and libraries are registered to ~/.ghc, offering the possibility to do a clean-up easily by simply removing these folders. With system–wide install, the files will be dispersed in the file system and difficult to manage.

Removing packages

There is no easy way to do it. Cabal does not have removing process.

One thing to make your life easier is use zsh auto completion to find all the haskell packages.

If you want/can fix/reinstall whole Haskell package system - remove ~/.cabal and ~/.ghc and start from scratch.

See also