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