Stack: Using stack for (re)compiling xmonad config

Created on 3 Aug 2015  路  16Comments  路  Source: commercialhaskell/stack

Wasn't sure how to make it work, XMonad assumes you have a user package-db and that you can install libraries there which will be in scope when you go to compile ~/.xmonad/xmonad.hs.

When I tried last night, I was trying to stack install xmonad and it complained about the old dependencies. Should I have unpacked xmonad and built from there? Will that be in scope if I invoke ghc --make?

I ended up having to use hvr's PPA and a conventional cabal install xmonad xmonad-config xmonad-extras to get my XMonad working on Linux.

I knew people dipping their toes into Haskell because of XMonad and having a good story here would be valuable.

Most helpful comment

That didn't get merged, instead https://github.com/xmonad/xmonad/pull/53 did. This means that you can just put something like the following in an executable script called ~/.xmonad/script (customize the location / the cd line if necessary):

#!/bin/sh
cd ~/.xmonad
stack --stack-yaml stack.yaml ghc -- --make xmonad.hs -i -ilib -fforce-recomp  -main-is main -v0 -o $1

I prefer to have the git repos for xmonad and xmonad-contrib in my ~/.xmonad (probably works to instead use the snapshot packages, but haven't tried that):

$ cd ~/.xmonad
$ git clone https://github.com/xmonad/xmonad-contrib
$ git clone https://github.com/xmonad/xmonad

So my ~/.xmonad/stack.yaml looks like

resolver: lts-8.5
flags:
  xmonad-contrib:
    testing: false
    use_xft: false
  xmonad:
    testing: false
packages:
- xmonad/
- xmonad-contrib/

I just need to run stack build when either of these, or the deps, have changed.

All 16 comments

@mgsloan, @drwebb: I think you've both at least tried to get xmonad working with stack. Did either of you get a good system going?

I had good success with something like stack exec xmonad. However, this meant all the programs run by xmonad have the environment variables that are setup by stack. So, for now I just do without the recompilation support.

Ideally, we'd be able to just provide the extra package DB arguments to ghc here https://github.com/xmonad/xmonad/blob/0cb0c6e035e36cd95f9896279e3b082c143fd5d5/XMonad/Core.hs#L462, or be able to set / override the environment it's run in.

I wish I had a better story myself, but my xmonad config has been neglected more than I care to admit (maybe that will change now that I have a trustworthy way to build it). So I haven't needed any recompilation issues.

I think it's a great story for stack, I mean you want to window manager configuration to compile the same way a year or further out. Maybe we can come up with some a best set of practices and then compile them and add as a wiki entry.

Is there anything concrete we can do here?

@snoyberg I can try to make it work, then write-up what I did to make it work. No time just right now, but if you leave this open for me, I can spin 'round to it. @mgsloan mentioned using stack exec xmonad - if they'd be willing to write something about how to reproduce what they did I'd happily call this resolved.

Ordinarily, xmonad just compiles ~/.xmonad/xmonad.hs in-place, right? So if you can set it up to do recompilation with stack, wouldn't stack --local-bin-path=~/.xmonad install make it work as it does normally, without any environment variables being brought in by stack exec?

Here's a hack that mostly works: https://github.com/mgsloan/compconfig/blob/master/xmonad.hs#L505

This is better than stack exec, because with that, the processes started by xmonad get the environment variables set by stack.

I say mostly, because it seems to nondeterministically fail to run stack path, which causes it to skip setting GHC_PACKAGE_PATH (and so use the standard dbs). However, trying recompilation again fixes it. I tried working out what's going on, but to no avail - I think the issue is related to https://ghc.haskell.org/trac/ghc/ticket/5212 ... For my purposes for now, this is good enough. If someone wants to figure out what's going on, that'd be highly appreciated.

@pavelkogan Yes, that would work, but would require modifying xmonad a fair amount to support it. Here's where xmonad recompiles xmonad: https://github.com/xmonad/xmonad/blob/master/src/XMonad/Core.hs#L474 .

@mgsloan Are you compiling with -threaded?

@snoyberg Ahh, that could indeed be related. XMonad does not recompile itself with -threaded.

Maybe it's best to just modify XMonad to work better for this, rather than hacking around it.

I'm not an XMonad using, but: if the whole problem with stack exec is that it sets GHC_PACKAGE_PATH for all your child processes, can you modify it to unset that environment variable when calling child processes (besides recompile, of course)?

The problem with stack exec for this case is that it also modifies PATH, and potentially sets STACK_EXE / whatever the utf8 env vars stuff is / HASKELL_PACKAGE_SANDBOX / HASKELL_PACKAGE_SANDBOXES / HASKELL_DIST_DIR. Instead of attempting to undo these changes or capture the environment before xmonad was started, I went with the approach of setting GHC_PACKAGE_PATH for the recompile, and then unsetting it.

Looks like we're not getting any farther on this one, closing.

@drwebb @pavelkogan @bitemyapp I have opened a PR on xmonad which adds direct support for stack: https://github.com/xmonad/xmonad/pull/50

I wish I'd just done that in the first place!

That didn't get merged, instead https://github.com/xmonad/xmonad/pull/53 did. This means that you can just put something like the following in an executable script called ~/.xmonad/script (customize the location / the cd line if necessary):

#!/bin/sh
cd ~/.xmonad
stack --stack-yaml stack.yaml ghc -- --make xmonad.hs -i -ilib -fforce-recomp  -main-is main -v0 -o $1

I prefer to have the git repos for xmonad and xmonad-contrib in my ~/.xmonad (probably works to instead use the snapshot packages, but haven't tried that):

$ cd ~/.xmonad
$ git clone https://github.com/xmonad/xmonad-contrib
$ git clone https://github.com/xmonad/xmonad

So my ~/.xmonad/stack.yaml looks like

resolver: lts-8.5
flags:
  xmonad-contrib:
    testing: false
    use_xft: false
  xmonad:
    testing: false
packages:
- xmonad/
- xmonad-contrib/

I just need to run stack build when either of these, or the deps, have changed.

@mgsloan do you do anything else other than this? I get this when running your build

~/.xmonad ./build 
ghc: on the commandline: missing argument for flag: -o
Usage: For basic information, try the `--help' option.

and this when I type stack build in that directory

~/.xmonad stack build
/home/fommil/.xmonad/xmonad/: canonicalizePath: does not exist (No such file or directory)

@fommil You need to clone https://github.com/xmonad/xmonad and https://github.com/xmonad/xmonad-contrib . Alternatively, don't have them in packages and instead specify via extra-deps.

Was this page helpful?
0 / 5 - 0 ratings