问题描述
位于 https://github.com/ysangkok/cabal-profiling-issue 的完整项目
该项目包含由 cabal init
生成的脚手架。我现在将粘贴最有趣的源代码片段。
在 Main.hs
我有:
newtype Wrapper = Wrapper Int
deriveConvertible ''Wrapper ''Int
在 TH.hs
我有:
import Data.Convertible
deriveConvertible :: TH.Name -> TH.Name -> TH.Q [TH.Dec]
deriveConvertible newType otherType = do
Just newCon <- TH.lookupValueName (TH.nameBase newType)
v <- TH.newName "v"
[d|
instance Convertible $(TH.conT newType) $(TH.conT otherType) where
safeConvert $(TH.conP newCon [TH.varP v]) = Right $(TH.varE v)
instance Convertible $(TH.conT otherType) $(TH.conT newType) where
safeConvert source = Right ($(TH.conE newCon) source)
|]
但如果我将 profiling: true
放入 cabal.project
并使用 GHC 8.6.5 和 Cabal 3.4.0.0(使用 ghcup 安装)运行 cabal build
,我得到:
Failed to load interface for 'Data.Convertible.Base'
Perhaps you haven't installed the profiling libraries for package 'convertible-1.1.1.0'?
代码有什么问题,为什么它在没有分析的情况下编译,但在启用时失败?
解决方法
编译包含用于分析的 TH 代码的多模块程序是一个已知问题,请参阅文档中的相关部分:
如果您的多模块程序包含 模板 Haskell 代码,您需要编译它以进行分析, 因为 GHC 无法加载分析的目标代码并在以下情况下使用它 执行拼接。
作为一种解决方法,只需将 TemplateHaskell
放入 test.cabal 中的 other-modules
,
other-extensions: TemplateHaskell
然后使用分析(即使用 cabal build --enable-library-profiling
)构建,一切都会好起来的。
有关为什么我们需要 TemplateHaskell
部分中的 other-modules
的更多详细信息,请参阅 https://github.com/haskell/cabal/issues/5961。