Plugins package неизвестный символ при использовании cabal

Я возился с пакетом плагинов, но я столкнулся с проблемой.

Здесь код:

Util/Header.hs

module Util.Header(PT(..)) where

data PT a = PT a deriving Show

Plug.hs

module Plug(helloPlugin) where
import Util.Header
helloPlugin :: PT Int
helloPlugin = PT 1

Main.hs

module Main where

import Util.Header
import System.Plugins

main :: IO ()
main = do
    mv <- load "Plug.o" ["."] [] "helloPlugin"
    case mv of
        LoadFailure msg -> print msg
        LoadSuccess _ v -> print $ show (v :: PT Int)

Все работает отлично, а затем компилируется с помощью ghc. Строительство с помощью Cabal отлично работает, но когда я запускаю исполняемый файл, я получаю эту ошибку:

plugintest: /home/kevin/.cabal/lib/plugins-1.5.4.0/ghc-7.6.3/HSplugins-1.5.4.0.o: unknown symbol `ghczm7zi6zi3_ErrUtils_zdsinsertzuzdsgo5_info'
plugintest: user error (resolvedObjs failed.)

Мой очень минималистический файл кабалы:

name:                plugintest
version:             0.1.0.0
license-file:        LICENSE
build-type:          Simple
cabal-version:       >=1.8

library
  hs-source-dirs: src
  exposed-modules: Util.Header
  build-depends:  base ==4.6.*, plugins ==1.5.*

executable plugintest
  main-is: Main.hs
  build-depends:  base ==4.6.*, plugins ==1.5.*, plugintest == 0.1.0.0
  hs-source-dirs: src

Теперь я предполагаю, что проблема заключается в том, что он не может найти модуль "ErrUtils", который является частью пакета ghc, установленного в /usr/lib/ghc -7.x.x. Поскольку он использует cabal, вместо этого он будет использовать $HOME/.cabal/lib/.

Теперь я, очевидно, не хотел бы использовать /usr/lib, если бы захотел сделать его дистрибутируемым. К сожалению, я не очень хорошо разбираюсь в том, как управляются пакеты, и я не знаком с пакетом плагинов.

У меня такое чувство, что это экстремально nooby, но я не смог найти решение самостоятельно.

Итак, несколько вопросов:

  • Как я могу заставить свои зависимости работать таким образом, чтобы это распространялось?
  • Кажется, мне нужно будет заранее знать, за что будут зависеть мои файлы Plugin.o, прежде чем они смогут их использовать (если я правильно понимаю). Есть ли способ упаковать файлы .o, которые мне не придется беспокоиться об этой проблеме? (Извините, если этот вопрос слишком расплывчатый, не стесняйтесь игнорировать)

Спасибо заранее!

Ответ 1

Хорошо, поэтому у меня была такая же проблема. Вот обходной путь, который я нашел

Измените вызов загрузки на

load "Plug.o" [".","dist/build/plugintest/plugintest-tmp"] [] "testplugin"

Убедитесь, что вы скомпилируете вещь с помощью -c или с помощью библиотеки "make" из плагинов.

Довольно раздражает это... Ошибка говорит о том, что у него возникают проблемы со стандартными libs, так почему же это показывает, что эти .o файлы исправляют его? В любом случае, это сработало для меня, и не требовало тонны сбрасывания файлов с .cabal.

Ответ 2

Вы должны объявить свои модули exported- и other-, чтобы Cabal упаковывала их все вместе. Например (от https://github.com/tel/happstack-heroku-test)

name:                hktest         -- note the name here names
                                    -- the *library* which is a package name
                                    -- in scope when building the executable

...

library
  exposed-modules:     
    HKTest
  other-modules:
    -- there aren't any, but there could be some
  build-depends:       base                >= 4.6    && <4.7

                       ...

                     , mtl                 >= 2.1.2
  hs-source-dirs:      src

executable server
  main-is:             Server.hs
  other-modules:
    -- there might be some use to having these here,
    -- but they'll be harder to get into GHCi, so I wouldn't
    -- recommend it---just put them in the library part
  build-depends:       base >=4.6 && <4.7
                     , hktest                  -- note that I grab all the hktest
                                               -- modules here  
  hs-source-dirs:      exe

Если я оставлю один из этих модулей, я, скорее всего, получу ошибку сборки, поскольку Cabal компилирует файлы, которые ожидают, что смогут найти символы, которые не были упакованы.

В вашем случае, поскольку вы создаете исполняемый файл, общая модель, приведенная в качестве примера выше, состоит в том, чтобы поместить весь ваш код в библиотеку, а затем зависеть от исполняемой стороны от этой библиотеки. Например, в этом примере полный текст exe/Server.hs равен

module Main where

import qualified HKTest as HK

main :: IO ()
main = HK.main