Search code examples
haskellcabalcabal-install

Haskell - Packaging cabal package with custom preprocessors


I've implemented a custom preprocessor which creates *.hs files form *.tpl files. It is specified in Setup.hs by using a Build-Type: Custom. Everything works fine, but I can't create tar.gz package from it (using cabal sdist).

Cabal complains, that it can not find the exposed modules which are generated by the preprocessor. The error message is

cabal: Error: Could not find module with any
suffix: ["gc","chs","hsc","x","y","ly","cpphs","hs","lhs"]

How can I make Cabal aware of the fact that the module is not missing, or maybe add tpl to the known file extensions, or something?


Solution

  • This is a known issue with cabal sdist. Use ./dist/setup/setup sdist instead.

    Here's an example:

    $ cat preprocessor-test.cabal 
    name:                preprocessor-test
    version:             0.1.0.0
    build-type:          Custom
    cabal-version:       >=1.10
    extra-source-files:  PreprocessorTest/*.prepro
    
    library
      exposed-modules:     PreprocessorTest.PreprocessorTest
      build-depends:       base ==4.5.*
      -- hs-source-dirs:
      default-language:    Haskell2010
    
    $ cat Setup.hs 
    #!/usr/bin/env runhaskell
    
    import Distribution.Simple
    import Distribution.Simple.PreProcess
    import Distribution.Simple.Utils
    import Distribution.PackageDescription
    import Distribution.Simple.LocalBuildInfo
    import System.Cmd (rawSystem)
    import System.FilePath ((</>))
    
    main = let hooks = simpleUserHooks
               dummy = ("prepro", dummyPreprocessor)
           in defaultMainWithHooks hooks
              { hookedPreProcessors = dummy:knownSuffixHandlers  }
    
    dummyPreprocessor :: BuildInfo -> LocalBuildInfo -> PreProcessor
    dummyPreprocessor build local = PreProcessor {
      platformIndependent = True,
      runPreProcessor =
        mkSimplePreProcessor $ \inFile outFile verbosity -> do
          notice verbosity (inFile ++ " is being preprocessed to " ++ outFile)
          rawSystem "cp" [inFile, outFile]
          return ()
      }
    $ cat PreprocessorTest/PreprocessorTest.prepro 
    module PreprocessorTest.PreprocessorTest
           where
    
    preprocessorTest :: Int
    preprocessorTest = 1
    
    $ cabal configure
    Resolving dependencies...
    [1 of 1] Compiling Main             ( Setup.hs, dist/setup/Main.o )
    Linking ./dist/setup/setup ...
    Configuring preprocessor-test-0.1.0.0...
    
    $ cabal build    
    Building preprocessor-test-0.1.0.0...
    Preprocessing library preprocessor-test-0.1.0.0...
    PreprocessorTest/PreprocessorTest.prepro is being preprocessed to
    dist/build/PreprocessorTest/PreprocessorTest.hs
    [1 of 1] Compiling PreprocessorTest.PreprocessorTest ( dist/build/PreprocessorTest/PreprocessorTest.hs, dist/build/PreprocessorTest/PreprocessorTest.o )
    Registering preprocessor-test-0.1.0.0...
    
    $ ./dist/setup/setup sdist
    Distribution quality errors:
    No 'synopsis' or 'description' field.
    The 'license' field is missing or specified as AllRightsReserved.
    Distribution quality warnings:
    No 'category' field.
    No 'maintainer' field.
    Note: the public hackage server would reject this package.
    Building source dist for preprocessor-test-0.1.0.0...
    Preprocessing library preprocessor-test-0.1.0.0...
    PreprocessorTest/PreprocessorTest.prepro is being preprocessed to
    dist/src/sdist.-6767/preprocessor-test-0.1.0.0/dist/build/PreprocessorTest/PreprocessorTest.hs
    Source tarball created: dist/preprocessor-test-0.1.0.0.tar.gz
    
    $ tar tzf dist/preprocessor-test-0.1.0.0.tar.gz
    preprocessor-test-0.1.0.0/
    preprocessor-test-0.1.0.0/dist/
    preprocessor-test-0.1.0.0/dist/build/
    preprocessor-test-0.1.0.0/dist/build/PreprocessorTest/
    preprocessor-test-0.1.0.0/dist/build/PreprocessorTest/PreprocessorTest.hs
    preprocessor-test-0.1.0.0/Setup.hs
    preprocessor-test-0.1.0.0/PreprocessorTest/
    preprocessor-test-0.1.0.0/PreprocessorTest/PreprocessorTest.prepro
    preprocessor-test-0.1.0.0/preprocessor-test.cabal