Arch Linux recently changed their Haskell packages (no more static linking), which broke a bunch of stuff. Specifically, upgrading
xmonad-0.13-9 produces errors when recompiling xmonad, and only downgrading seems to fix the issue; and using
cabal install xmonad) with Arch’s
ghc likewise produces errors, failing to install xmonad. For those of you coming from Google, the errors are of the format
Could not find module .... See here and here, for example.
In addition, Arch’s xmobar (with
xmonad-0.13-8) has been crashing sporadically (segmentation faults), for some reason. See here, for instance.
In this post, I’ll explain how I got xmonad (and xmonad-contrib) and xmobar installed and working – and no xmobar crashes, so far – via stack. I’ll try to keep it as short and simple as possible. No in-depth explanations; just a straightforward, step-by-step rundown of what I did. The usual disclaimers (YMMV, etc.) apply.
I’ll assume you already have an
~/.xmonad directory with an
xmonad.hs config file. If you don’t use xmobar, this post can still be useful; just ignore the lines/steps that refer to xmobar.
Step 1: Get stack
There are couple ways to get stack. I installed stack-static from the AUR, because it doesn’t come with any Haskell dependencies.
If you don’t care about tracking stack with your package manager, then, as the stack how-to-install explains, just run
Step 2: Install GHC with stack
To build and install Haskell packages, we need GHC. Simply run
to install GHC into
~/.stack. Useful for the kind of sandboxing projects that we’re doing with xmonad.
NB: You can run
stack ghc to do things with GHC,
stack ghci to fire up interactive GHC, and so on.
Step 3: Get xmonad, xmonad-contrib, and xmobar
We’ll be turning our
~/.xmonad directory into a stack project, so first, head over there.
For the remainder of this post, I’ll assume you’re inside
Next, download the xmonad, xmonad-contrib, and xmobar Git repositories, which contain the
.yaml files that stack will look for in the next step. I like to add
-git to their directory names, just as a reminder.
~/.xmonad directory should now contain
xmobar-git, each of which contains a
.cabal file and a
Step 4: Initialize stack
This step is easy: just run
Stack will find the
.yaml files and auto-create the file
stack.yaml for you. It’ll look like this:
At this point, you can modify
stack.yaml to add flags, etc. The only change I made was to add the flag
all_extensions to xmobar, by changing
This flag provides all the xmobar bells & whistles, like support for xft, mpd, battery, wifi, etc.
NB: If you add the
with_iwlib flag (or
all_extensions), you’ll need to also install the iwlib C library and headers. In Arch Linux, just install
wireless_tools; in Debian-based systems,
libiw-dev. Or, in your
(The specific version you’ll need will change over time. If
stack install from step 5 produces an error, just see what stack recommends.)
Step 5: Build and install everything
to build and install xmonad, xmonad-contrib, and xmobar (and all their dependencies). You’ll now have two new binaries,
xmobar, installed into
NB: You’ll want to add
~/.local/bin to your
PATH, if it isn’t already. (If you use a login manager, see Step 9 below.)
Step 6: Write a build file
Since we’re doing everything via stack, rather than ghc directly,
xmonad --recompile won’t quite work yet. As of xmonad 0.13, we can write a custom build script, named
build and located inside
~/.xmonad, which will use stack ghc to recompile xmonad. (Borrowed from pbrisbin.)
Make sure it’s executable:
Step 7: Recompile and restart xmonad
You should now be able to recompile and restart xmonad (and xmobar) with
NB: I had to restart my computer in order for xmobar to start up properly – probably because xmonad couldn’t find the xmobar binary.
Step 8: Updating
Whenever you update your xmonad, xmonad-contrib, or xmobar repositories, just
cd ~/.xmonad and run
to rebuild and reinstall everything.
NB: If you add a new flag or extra dependencies (in
stack.yaml), you may need to run
stack clean first.
(Step 9: Loose ends with login managers)
If you use a login manager, such as LightDM, then you may need to take some additional steps. I don’t use a login manager, nor do I know much about them, but I’ll use LightDM as the working example since I’ve read a little about it.
First off, LightDM uses
*.desktop files located
/usr/share/xsessions to know which desktop environments (or window managers) you have available to choose from. So, you’ll probably need to create
xmonad.desktop. The xmonad package from the official Arch repos installs the following file, so you can just copy it verbatim and place it into
[Desktop Entry] Encoding=UTF-8 Type=Application Name=Xmonad Comment=Lightweight X11 tiled window manager written in Haskell Exec=xmonad Icon=xmonad Terminal=false StartupNotify=false Categories=Application;
xmonad --recompile may not work yet. If it doesn’t, make sure that you’ve added
~/.local/bin to your
PATH by adding it to one of your shell profile files, such as
~/.profile or (if you only use one shell, e.g. Bash)
~/.bash_profile, and not to your shell’s configuration file (e.g.
~/.bashrc). The reason is that LightDM (and by extension xmonad) is invoked from a login shell, which sources profile files like
~/.profile, but not (necessarily) shell config files like
~/.bashrc. See this SE thread and this Quora answer to learn more about the difference.
If that still doesn’t work, then it’s possible that your login manager doesn’t even source
~/.profile (see the end of the SE thread linked above). In that case, a possible fix is to just manually symlink
/usr/bin (since the latter is definitely in your
PATH; thanks to Ashesh in the comments below for this fix):