Consider this simple .hs
file:
module MinHaddockFail where
yo :: String
yo = "yo"
And the .cabal
file:
Name: min-haddock-fail
Version: 0.1.0.0
Build-type: Simple
Cabal-version: >=1.8
Library
Exposed-modules: MinHaddockFail
Build-depends: base == 4.*
Extensions: CPP
The Extensions
directive in the .cabal
file will cause all .hs
files to be
pre-processed. The pre-processed output looks pretty much the same under gcc
(extra blank lines ellided):
{-# LINE 1 "MinHaddockFail.hs" #-}
# 1 "MinHaddockFail.hs"
# 1 "<built-in>"
# 1 "<command-line>"
# 13 "<command-line>"
# 1 "./dist/build/autogen/cabal_macros.h" 1
# 13 "<command-line>" 2
# 1 "MinHaddockFail.hs"
module MinHaddockFail where
yo :: String
yo = "yo"
or clang
:
{-# LINE 1 "MinHaddockFail.hs" #-}
# 1 "MinHaddockFail.hs"
# 1 "<built-in>" 1
# 19 "<built-in>"
# 1 "dist/build/autogen/cabal_macros.h" 1
# 20 "<built-in>" 2
# 1 "MinHaddockFail.hs" 2
module MinHaddockFail where
yo :: String
yo = "yo"
When generating haddock cabal does a bad thing: It pre-processes the .hs
file
with ghc
before handing it to haddock
, but then it adds --optghc=-XCPP
to
the haddock
command line as well. This causes the pre-processed output to be
pre-processed again. This is almost certainly wrong: pre-processing is not
defined to be idempotent.
The output, under either compiler is indeed a bit of a mess. gcc
's output is:
# 1 "dist/build/tmp-5926/MinHaddockFail.hs"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "dist/build/tmp-5926/MinHaddockFail.hs"
{-# LINE 1 "MinHaddockFail.hs" #-}
# 1 "MinHaddockFail.hs"
# 1 "<built-in>"
# 1 "<command-line>"
# 13 "<command-line>"
# 1 "./dist/build/autogen/cabal_macros.h" 1
# 13 "<command-line>" 2
# 1 "MinHaddockFail.hs"
module MinHaddockFail where
yo :: String
yo = "yo"
The line markers from the first pass have been passed through blind into the second. This is inoccuous for the purposes of haddock (though may be a source of incorrect line numbers).
clang
's output in this situation is slightly more rigorous:
# 1 "dist/build/tmp-88937/MinHaddockFail.hs"
# 1 "<built-in>" 1
# 1 "dist/build/tmp-88937/MinHaddockFail.hs" 2
{-# LINE 1 "MinHaddockFail.hs" #-}
# 1 "MinHaddockFail.hs"
# 1 "<built-in>" 1
# 19 "<built-in>"
# 1 "dist/build/autogen/cabal_macros.h" 1
# 79 "dist/build/tmp-88937/MinHaddockFail.hs"
# 20 "<built-in>" 2
# 1 "MinHaddockFail.hs" 2
module MinHaddockFail where
yo :: String
yo = "yo"
It attempts to shield the exsiting linemarkers from the new ones by adding a
space to them. ghc
correctly does not parse those lines as line-markers, and
then those lines cause parse errors.
If the Extensions
directive is removed from the .cabal
file, then it all
works fine because cabal
doesn't attempt to pre-process the file before
handing it off to haddock
. It even works if the file itself has the pragma:
{-# LANGUAGE CPP #-}
With that (and with the Extensions
directive) the file will correctly compile
and haddock
, being prep-rocessed exactly once.
The only work around is to add -optP-P
to ghc
during the first
pre-processing step. This can be done while invoking cabal haddock
:
cabal haddock --ghc-option=-optP-P
However, there is no way to configure cabal
to add this option all the time
when running haddock
: The new program-default-options
directive lets one
set the options for haddock
itself, but not the ghc
pre-processing step
before haddock
is called.
One could add -optP-P
to the ghc-options
directive. But then all
compilations would lose accurate line number tracking. This would apply to all
compilations even those that don't use CPP
because once the Extensions
directive includes CPP
, all files are pre-processed.