Search code examples
haskellghcheap-profilingcabal-new

How to profile TemplateHaskell built with Cabal?


Full project at https://github.com/ysangkok/cabal-profiling-issue

The project contains scaffolding generated by cabal init. I'll paste the most interesting source snippets now.

In Main.hs I have:

newtype Wrapper = Wrapper Int

deriveConvertible ''Wrapper ''Int

in TH.hs I have:

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)

    |]

But if I put profiling: true in cabal.project and run cabal build with GHC 8.6.5 and Cabal 3.4.0.0 (installed using ghcup), I get:

    Failed to load interface for 'Data.Convertible.Base'
    Perhaps you haven't installed the profiling libraries for package 'convertible-1.1.1.0'?

What is wrong with the code, and why does it compile without profiling, but fails when enabled?


Solution

  • It is a known problem about compile multi-module program that contains TH code for profiling, see related sections in the documentation:

    This causes difficulties if you have a multi-module program containing Template Haskell code and you need to compile it for profiling, because GHC cannot load the profiled object code and use it when executing the splices.

    As a workaround, just put TemplateHaskell into the other-modules in your test.cabal,

         other-extensions: TemplateHaskell
    

    Then building with profiling (i.e., with the cabal build --enable-library-profiling) every thing would be ok.

    For more details about why we need TemplateHaskell in other-modules section, see https://github.com/haskell/cabal/issues/5961.