Как установить зависимости при кросс-компиляции кода haskell?

Я успешно создал кросс-компилятор ghc, который позволяет мне компилировать код haskell для armv6h (в моем случае raspberry pi) с моей машины x64 linux. Я успешно запустил программу hello world на малине.

Нет, я хочу создать свое настоящее приложение, которое во многом зависит от других модулей Haskell. Когда я компилирую для x64, я просто делаю

cabal install dependenciy1 depenency2 ...

Я знаю, что могу сделать свою собственную программу кликой-проектом и автоматизировать этот шаг. Но дело не в этом.

Когда я пытаюсь использовать кросс-компилятор

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

Он говорит мне о модулях, которые он не смог найти. Конечно, они не установлены!

Я прочитал https://ghc.haskell.org/trac/ghc/wiki/Building/CrossCompiling и в соответствии с этим я пробовал

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 - это зависимость, которую я пытаюсь установить здесь. Я получаю следующую ошибку:

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

Когда я делаю

file /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: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 3.10.2, not stripped

Неудивительно, что он не может его выполнить. Он скомпилирован для руки.

Я что-то упустил здесь? Моя цель — подключить все зависимости, а затем создать статически связанное приложение, которое я могу развернуть на своей малине.


person Daniel Schmitz    schedule 10.09.2014    source источник
comment
Вы можете попробовать cabal get random, затем перейти в каталог random-???, а затем runhaskell ./Setup.hs install --with-ghc=... ...?   -  person bennofs    schedule 10.09.2014
comment
Когда я это делаю, я получаю unrecognized 'install' option `--with-ghc=arm-unknown-linux-gnueabi-ghc' unrecognized 'install' option `--with-ghc-pkg=arm-unknown-linux-gnueabi-ghc-pkg' unrecognized 'install' option `--with-ld=arm-unknown-linux-gnueabi-ld'   -  person Daniel Schmitz    schedule 10.09.2014
comment
О, кажется, вам нужно сделать runhaskell ./Setup.hs configure --with..., затем runhaskell ./Setup.hs build и, наконец, runhaskell ./Setup.hs install.   -  person bennofs    schedule 10.09.2014
comment
Хорошо, кажется, это работает. Но теперь, когда я пытаюсь связать свое приложение с ним, компоновщик говорит: /home/daniel/x-tools/arm-unknown-linux-gnueabi/lib/gcc/arm-unknown-linux-gnueabi/4.8.2/../../../../arm-unknown-linux-gnueabi/bin/ld: skipping incompatible /home/daniel/.cabal/lib/arm-linux-ghc-7.8.3.20140804/random-1.0.1.3/libHSrandom-1.0.1.3.a when searching for -lHSrandom-1.0.1.3   -  person Daniel Schmitz    schedule 10.09.2014
comment
@DanielSchmitz Попробуйте отключить зачистку при настройке, --disable-library-stripping и --disable-executable-stripping   -  person Yuras    schedule 10.09.2014
comment
@bennofs, вам, вероятно, следует дать реальный ответ, чтобы мы проголосовали за него.   -  person Yuras    schedule 10.09.2014
comment
Кроме того, если пакет использует hsc2hs, убедитесь, что он получает флаг -x, иначе он создаст экземпляры Storable для хост-архитектуры вместо цели. IIRC Мне это было нужно для network, иначе он разбился во время выполнения.   -  person Yuras    schedule 10.09.2014
comment
@Yuras: отключение зачистки помогло. Теперь я могу скомпилировать и связать статический двоичный файл и выполнить его на пи :-)   -  person Daniel Schmitz    schedule 10.09.2014


Ответы (1)


Чтобы понять эту ошибку, вам нужно знать, как cabal install работает внутри. По сути, он будет выполнять следующие шаги:

  1. Скачайте и распакуйте исходный код
  2. Скомпилируйте Setup.hs (этот файл используется для настройки системы сборки, например, вы можете реализовать некоторые хуки для запуска дополнительного кода haskell в фазе configure).
  3. Беги setup configure <configure flags> && setup build && setup install

Проблема теперь в том, что cabal install использует GHC, предоставленный --with-ghc, также для шага 2, но исполняемый файл, созданный на этом шаге, должен работать в хост-системе!

Обходной путь — выполнить шаги вручную, что означает, что у вас есть полный контроль. Во-первых, получите источник:

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

Затем скомпилируйте Setup.hs, используя хост ghc:

$ ghc ./Setup.hs -o setup

И, наконец, настроить, собрать и установить. Как предложил @Yuras в комментарии, мы также добавляем опцию -x для запуска 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

Об этом уже есть проблема клики: https://github.com/haskell/cabal/issues/ 2085

person bennofs    schedule 10.09.2014
comment
Должно ли ghc ./Setup.hs -osetup быть ghc ./Setup.hs -o setup с пробелом между -o и setup? Я получил unrecognised flags: -osetup без пробела. - person HeatfanJohn; 19.09.2014
comment
@HeatfanJohn О, это удивительно, тебе действительно нужно место. Интересно, почему тогда -packagelens работает без пробела... - person bennofs; 19.09.2014
comment
Есть ли на самом деле способ смоделировать то, что клика делает в сценарии? Было бы полезно указать опцию builddir и иметь поддержку песочниц... - person Alexey Raga; 04.04.2015