GHC web dev considered harmful on ARM

This is to detail some of my recent experiences with trying to get some web stuff to work on ARM.  Verdict:  avoid!

Ed: with the correct llvm ghc 7.10.2 works!  Details here.

Ok, granted you can compile some haskell programs on ARM just fine.  If your code will compile with ghc 7.6 or earlier, for instance, chances are you’ll be ok.  On my ‘cyclophone’ instrument project the central control program (there are several small programs that run) can compile with older ghc and it seems to run ok.

But, I wanted a web component to the instrument, for controlling parameters, chord sequencing, etc.  I wrote something that ran fine on my laptop, using Yesod, which is not known for its light weight dependencies.  And eventually, with much struggle, I did get it to compile on arm!  But that turns out to not be repeatable, unfortunately, and I had to ignore some scary sounding error messages along the way.  Also, did I mention the hours of compiling?  Many hours.

But, you say, I think I can make it work, I’m a veteran haskell build tweaker.  Ok, I’ll tell you what worked for me.  Who knows, maybe it will work!  If so let me know how you did it.

  • first off, the newest working version of ghc that I’ve tried is 7.8.2, which is conveniently supplied as a package in arch linux.  Anything newer has fatal bugs.  That link is for a ghci illegal instruction error, but it turns out that executables that you build will also have this error.  On raspberry pi 2 with debian jessie, the recommended distro for the recent 7.10.2 ghc binary, this bug manifested while trying to bootstrap cabal.  You can’t use an older cabal because 7.10.2 requires a new one, and the bootstrapping fails, and that’s game over for ghc 7.10.2 on arm.  Actually its worse than that: 7.10.2 can’t compile a ‘hello world’ that doesn’t crash.  According to comments in the linked bug, anything from 7.8.4 on up has this bug as well.
  • That version of 7.8.2 in arch I mentioned?  Turns out llvm in arch is too new (3.6 as of this writing), and 7.8.2 won’t work with that.  You have to downgrade to an earlier llvm, and the llvm downgrade packages are not officially available.  Does this sketch you out yet?  Maybe ghc isn’t the best choice on arm?  Ok I have llvm downgrade packages for you, see the comments in my earlier post.  After downgrading you’ll have ghci working and fairly decent compiling stability compare to the nonfunctional 7.10.2.
  • Did you know cross compiling is broken for arm because of template haskell?  Something about ghc generating arm code which then has to be run during compilation, but you’re not compiling on arm so fail.  That’s the word on the street anyway, I didn’t try it myself.  So if you’re planning to use Yesod, it had better compile on your arm machine.  Make sure you have enough ram!  You could try a swap file, see the ‘swap file creation’ section here.  For me, it turns out lack of memory wasn’t a problem, and so the swap file didn’t help.
  • in its default mode, persistent-sqlite is broken on arm.  It has problems with compiling C code (that implements sqlite) that goes along with the project – I believe this is a ghc bug.  You can work around it by setting this convenient flag to ‘true’:
    flag systemlib
    description: Use the system-wide sqlite library
    default: True
    Then, you’ll want to add your altered persistent-sqlite to the sandbox for your yesod project, with “cabal sandbox add-source <path to your checkout of persisent>/persistent/persistent-sqlite”
  • Newer versions of persistent-sqlite have an additional C file to compile, unfortunately.  I was able to successfully compile version 2.1.3 because it doesn’t have that file.  I’m not sure exactly when the other file came in to the project, but anyway there you go.
  • Compiling my little yesod project takes at least 6 hours.  The first time.  You may end up needing to change library versions and recompile everything multiple times.  Sometimes the compiler got stuck – one library in particular I had to cancel after it compiled for over 8 hours.
  • If your ram is only 1g, you must compile with the -j1 (or -j2 if you’re feeling lucky) option.  This limits your build to 1 or 2 threads, respectively.  Running out of memory is a thing, especially on the raspberry pi 2 with its quad cores.  So that’s:  “cabal -j1 install” for instance.
  • A lot of times the compile will fail, with some crash or other problem.  Often you can make the offending library compile by installing it by itself, then you can restart your project build and make it a little further.
  • I actually got my yesod project to build on bananapi with ghc 7.8.2!  I just kept rebuilding and etc until it worked.  I haven’t done a cabal update in over 150 days on that machine and I’m afraid if I touch anything the build will stop working.
  • I followed the same procedures to install ghc 7.8.2 and etc on the raspberry pi 2, also with arch.  There, compiler crashes made it impossible to complete installation.  It eventually failed on the link step, having compiled all the many libraries successfully.  Close but no cigar.
  • Ok yeah Yesod is far from an ideal framework for a little computer like the pi 2.  Its the opposite of lightweight, at least for compiling.  So I also tried scotty but that had similar compile difficulties.

So for myself, I’ve decided to check out rust as an alternative for this project, although I will be keeping an eye on the state of play for haskell on arm (seeing as I already wrote a perfectly good server in haskell).  Rust is not mainstream for web, but my needs are minimal – implementing some sliders in the browser UI to tweak parameters in the instrument, and maybe a few other things, we’ll see.  Arm binaries are here.  I made a little hello world project with dependencies on various libraries I want to use – json, sqlite, websockets, ‘iron’ web server, html, osc – and it downloaded and compiled everything in about 20 mins, with four threads of compilation using a constant 160mb of memory.  Not bad, rust!

As for ghc, well, my feeling is that arm support is a minor consideration at best, and that extensive testing just doesn’t happen for arm, either on libraries or for the compiler itself.  Its too bad, as performance is pretty good if you can ever get your program to compile.  But the reality is that ghc is sketchy and unreliable on arm, and arm problems, although they are being worked on, are not high priority in the haskell community as a whole.


4 thoughts on “GHC web dev considered harmful on ARM

  1. I run arch linux arm. I won’t claim there aren’t issues (GHC on ARM is tier 2 after all), but from your description I seem to have got more working than you have. A couple of pointers that may help:

    * GHCi will work if you put “:set -fobject-code” in your .ghci file.
    * GHC 7.10.2 will compile and it seems to work fine for me. There’s a little bit of a dance to do to get there, but briefly, I got it to work by:
    1. Creating a separate ghc-llvm package with just the opt and llc binaries, installed as /usr/bin/ghc-opt and /usr/bin/ghc-llc respectively.
    2. Downgrading the system llvm to a version which ghc from the repos works with.
    3. Creating and building a ghc PKGBUILD which builds ghc 7.10.2, specifying ghc-opt and ghc-llc explicitely at the configure step.*
    4. Restoring llvm to the current version (for the sake of anything else that depends on llvm; ghc-7.10.2 now depends on its own ghc-llvm package instead, which means that llvm can be upgraded as normal without breaking ghc.)

    I’ve been meaning to publish the PKGBUILDs, but haven’t got round to it yet. Might even be able to provide some armv7h packages if that’s useful to you. I haven’t worked with Yesod or TH much, so maybe there are more dragons there, but I’ve managed to install a lot of other packages using cabal/stack without issue.

    *I actually went via 7.10.1, so I can’t be 100% sure bootstrapping ghc-7.10.2 with ghc-7.8.2 works, but I expect it will.

    Liked by 1 person

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s