How do I install dependencies when cross compiling haskell code?

I've successfully created a ghc cross compiler, that allows me to compile haskell code for armv6h (raspberry pi in my case) from my x64 linux machine. I've successfully run a hello world program on the raspberry.

No I want to build my real app, which has a lot of dependencies on other haskell modules. When I compile for x64 I simply do

cabal install dependenciy1 depenency2 ...

I know I could make my own programm a cabal-project an automate this step. But that's not the point here.

When I try to use the cross-compiler

arm-unknown-linux-gnueabi-ghc --make myapp.hs

It tells me about modules it could not find. Of course, they are not installed!

I read https://ghc.haskell.org/trac/ghc/wiki/Building/CrossCompiling and according to that I tried

cabal --with-ghc=arm-unknown-linux-gnueabi-ghc --with-ghc-pkg=arm-unknown-linux-gnueabi-ghc-pkg --with-ld=arm-unknown-linux-gnueabi-ld install random

random is the depenency I'm trying to install here. I get the following error:

Resolving dependencies...
Configuring random-1.0.1.3...
Failed to install random-1.0.1.3
Last 10 lines of the build log ( /home/daniel/.cabal/logs/random-1.0.1.3.log ):
/home/daniel/.cabal/setup-exe-cache/setup-Cabal-1.18.1.3-arm-linux-ghc-7.8.3.20140804: /home/daniel/.cabal/setup-exe-cache/setup-Cabal-1.18.1.3-arm-linux-ghc-7.8.3.20140804:      cannot execute binary file
cabal: Error: some packages failed to install:
random-1.0.1.3 failed during the configure step. The exception was:
ExitFailure 126

When I do

file /home/daniel/.cabal/setup-exe-cache/setup-Cabal-1.18.1.3-arm-linux-ghc-7.8.3.20140804

I get

/home/daniel/.cabal/setup-exe-cache/setup-Cabal-1.18.1.3-arm-linux-ghc-7.8.3.20140804: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 3.10.2, not stripped

No wonder it can't execute it. It's compiled for arm.

Am I missing something here? My goal is to pull in all dependencies, then create a statically linked app that I can deploy on my raspberry.


To understand this error, you need to know how cabal install works internally. In essence, it will perform the following steps:

  • Download and unpack the source code
  • Compile Setup.hs (this file is used for customization of the build system, for example, you can implement some hooks to run additional haskell code in the configure phase).
  • Run setup configure <configure flags> && setup build && setup install
  • The problem is now that cabal install uses the GHC given by --with-ghc also for step 2, but the executable produced by that step must run on the host system!

    A workaround is to do the steps manually, which means you have full control. First, get the source:

    $ cabal get random
    Downloading random-1.0.1.3...
    Unpacking to random-1.0.1.3/
    $ cd random-1.0.1.3
    

    Then, compile Setup.hs , using the host ghc:

    $ ghc ./Setup.hs -o setup
    

    And finally, configure, build and install. As suggested by @Yuras in a comment, we also add the -x option for running hsc2hs :

    $ ./setup configure ----with-ghc=arm-unknown-linux-gnueabi-ghc --with-ghc-pkg=arm-unknown-linux-gnueabi-ghc-pkg --with-ld=arm-unknown-linux-gnueabi-ld --hsc2hs-options=-x
    $ ./setup build && ./setup install
    

    There is already a cabal issue about this: https://github.com/haskell/cabal/issues/2085

    链接地址: http://www.djcxy.com/p/64060.html

    上一篇: 使用amd64内核(Debian)在i386 root上编译amd64二进制文件

    下一篇: 如何在交叉编译haskell代码时安装依赖关系?