Haskell - Packaging cabal package with custom preprocessors - haskell

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?

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

Related

stack build fails with "Failed to load interface for `Main' no unit id matching `main' was found"

I've been trying to change a project to also provide a library (previous it was just an executable).
The only change has been (to the hpack package.yaml):
+library:
+ source-dirs: src
+ exposed-modules:
+ - CYAva
However now when running stack build I see output of:
2018-12-31 16:32:06.406901: [warn] Failed to load interface for `Main'
2018-12-31 16:32:06.407023: [warn] no unit id matching `main' was found
hpack file:
library:
source-dirs: src
exposed-modules:
- CYAva
executable:
source-dirs: src
main: Main.hs
license-file: LICENSE
build-type: Simple
maintainer: Chris Stryczynski
dependencies:
- base >=4.10 && <4.12
- colour
- data-default-class
# common
- Chart-cairo
- Chart
- lens
- aeson
- bytestring
- stm
- split
- text
- time
- thyme
- binary
- binary-orphans
- old-locale
- directory
- pretty-simple
- string-conversions
- optparse-applicative
name: ceriumyankeeavocado
version: '0.1.0.0'
extra-source-files: ChangeLog.md
author: Chris Stryczynski
license: BSD3
cabal file:
cabal-version: 1.12
-- This file has been generated from package.yaml by hpack version 0.31.1.
--
-- see: https://github.com/sol/hpack
--
-- hash: d90f1b53fc8bb74ddff9cf98937222e0c38a20affcd2506880039312e549541f
name: ceriumyankeeavocado
version: 0.1.0.0
author: Chris Stryczynski
maintainer: Chris Stryczynski
license: BSD3
license-file: LICENSE
build-type: Simple
extra-source-files:
ChangeLog.md
library
exposed-modules:
CYAva
other-modules:
Main
Paths_ceriumyankeeavocado
hs-source-dirs:
src
build-depends:
Chart
, Chart-cairo
, aeson
, base >=4.10 && <4.12
, binary
, binary-orphans
, bytestring
, colour
, data-default-class
, directory
, lens
, old-locale
, optparse-applicative
, pretty-simple
, split
, stm
, string-conversions
, text
, thyme
, time
default-language: Haskell2010
executable ceriumyankeeavocado
main-is: Main.hs
other-modules:
CYAva
Paths_ceriumyankeeavocado
hs-source-dirs:
src
build-depends:
Chart
, Chart-cairo
, aeson
, base >=4.10 && <4.12
, binary
, binary-orphans
, bytestring
, colour
, data-default-class
, directory
, lens
, old-locale
, optparse-applicative
, pretty-simple
, split
, stm
, string-conversions
, text
, thyme
, time
default-language: Haskell2010
stack build
thyme-0.3.5.5: configure
thyme-0.3.5.5: build
Chart-1.9: configure
Chart-1.9: build
Chart-1.9: copy/register
Chart-cairo-1.9: configure
Chart-cairo-1.9: build
Chart-cairo-1.9: copy/register
thyme-0.3.5.5: copy/register
Building all executables for `ceriumyankeeavocado' once. After a successful build of all of them, only specified executables will be rebuilt.
ceriumyankeeavocado-0.1.0.0: configure (lib + exe)
Configuring ceriumyankeeavocado-0.1.0.0...
ceriumyankeeavocado-0.1.0.0: build (lib + exe)
Preprocessing executable 'ceriumyankeeavocado' for ceriumyankeeavocado-0.1.0.0..
Building executable 'ceriumyankeeavocado' for ceriumyankeeavocado-0.1.0.0..
[1 of 3] Compiling CYAva ( src/CYAva.hs, .stack-work/dist/x86_64-linux-nix/Cabal-2.2.0.1/build/ceriumyankeeavocado/ceriumyankeeavocado-tmp/CYAva.o )
[2 of 3] Compiling Main ( src/Main.hs, .stack-work/dist/x86_64-linux-nix/Cabal-2.2.0.1/build/ceriumyankeeavocado/ceriumyankeeavocado-tmp/Main.o )
[3 of 3] Compiling Paths_ceriumyankeeavocado ( .stack-work/dist/x86_64-linux-nix/Cabal-2.2.0.1/build/ceriumyankeeavocado/autogen/Paths_ceriumyankeeavocado.hs, .stack-work/dist/x86_64-linux-nix/Cabal-2.2.0.1/build/ceriumyankeeavocado/ceriumyankeeavocado-tmp/Paths_ceriumyankeeavocado.o )
Linking .stack-work/dist/x86_64-linux-nix/Cabal-2.2.0.1/build/ceriumyankeeavocado/ceriumyankeeavocado ...
Preprocessing library for ceriumyankeeavocado-0.1.0.0..
Building library for ceriumyankeeavocado-0.1.0.0..
[1 of 3] Compiling CYAva ( src/CYAva.hs, .stack-work/dist/x86_64-linux-nix/Cabal-2.2.0.1/build/CYAva.o )
[2 of 3] Compiling Main ( src/Main.hs, .stack-work/dist/x86_64-linux-nix/Cabal-2.2.0.1/build/Main.o )
Failed to load interface for `Main'
no unit id matching `main' was found
Completed 4 action(s).
-- While building package ceriumyankeeavocado-0.1.0.0 using:
/home/chris/.stack/setup-exe-cache/x86_64-linux-nix/Cabal-simple_mPHDZzAJ_2.2.0.1_ghc-8.4.3 --builddir=.stack-work/dist/x86_64-linux-nix/Cabal-2.2.0.1 build lib:ceriumyankeeavocado exe:ceriumyankeeavocado --ghc-options " -ddump-hi -ddump-to-file -fdiagnostics-color=always"
I did not have the following in my Main.hs file:
module Main where
The above changed fixed it..

Why is Dynamic Loader package unable to resolve functions?

I have been trying to use the dynamic loader package which I found from this question. I am very new to Haskell so excuse me if I am making some incredibly rookie mistakes. My problem is that when I attempt to use the resolveFunctions function I get the following error:
DyanmicLoad-exe: /home/ubuntu/DynamicLoadTest/Plugin.o: unknown symbol `ghczmprim_GHCziCString_unpackCStringzh_closure'
DyanmicLoad-exe: user error (Unable to resolve functions!)
I would love it if someone could tell me possibly where I am going wrong here.
Here is my code (I am using the basic stack new structure):
app/Main.hs
Just the main function.
module Main where
import Lib
main :: IO ()
main = libMain
src/Lib.hs
The module is loaded in here.
module Lib
( libMain
) where
import System.Plugins.DynamicLoader
import System.Directory
import Interface
libMain :: IO ()
libMain = do currentDir <- System.Directory.getCurrentDirectory
loadModuleFromPath (currentDir ++ "/Interface.o") Nothing
putStrLn "Loaded Interface"
loadedModule <- loadModuleFromPath (currentDir ++ "/Plugin.o") (Just currentDir)
putStrLn "Loaded Plugin Module!"
resolveFunctions
putStrLn "Resolved Functions"
plugin <- (loadFunction loadedModule "getPlugin") :: IO (JobInterface)
putStrLn "Loaded Plugin"
putStrLn (jobName plugin)
src/Interface.hs
This file is the "plugin interface"
module Interface (
JobInterface (..)
) where
data JobInterface =
JobInterface { jobName :: String
, runJob :: Int -> Int
}
src/Plugin.hs
An example plugin.
module Plugin (
getPlugin
) where
import Interface
getPlugin :: JobInterface
getPlugin = JobInterface "Hello" $ \x -> 1 * x
I am building with stack build followed by stack ghc src/Plugin.hs src/Interface.hs. I am running with stack exec DyanmicLoad-exe.
GHC version is 8.0.1
Full output:
$ stack exec DyanmicLoad-exe
Loaded Interface
Loaded Plugin Module!
DyanmicLoad-exe: /home/ubuntu/DynamicLoadTest/Plugin.o: unknown symbol `ghczmprim_GHCziCString_unpackCStringzh_closure'
DyanmicLoad-exe: user error (Unable to resolve functions!)
Edit 1:
Error with the -dynamic flag on build.
$ stack exec DyanmicLoad-exe
Loaded Interface
Loaded Plugin Module!
DyanmicLoad-exe: /home/ubuntu/DynamicLoadTest/Plugin.o: unhandled ELF relocation(RelA) type 42
DyanmicLoad-exe: user error (Unable to resolve functions!)
Edit 2 .cabal file
name: DyanmicLoad
version: 0.1.0.0
synopsis: Initial project template from stack
description: Please see README.md
homepage: https://github.com/githubuser/DyanmicLoad#readme
license: BSD3
license-file: LICENSE
author: Author name here
maintainer: example#example.com
copyright: 2017 Author name here
category: Web
build-type: Simple
extra-source-files: README.md
cabal-version: >=1.10
library
hs-source-dirs: src
exposed-modules: Lib
, Interface
build-depends: base >= 4.7 && < 5
, dynamic-loader
, directory
default-language: Haskell2010
executable DyanmicLoad-exe
hs-source-dirs: app
main-is: Main.hs
ghc-options: -dynamic -threaded -rtsopts -with-rtsopts=-N
build-depends: base
, DyanmicLoad
default-language: Haskell2010
test-suite DyanmicLoad-test
type: exitcode-stdio-1.0
hs-source-dirs: test
main-is: Spec.hs
build-depends: base
, DyanmicLoad
ghc-options: -threaded -rtsopts -with-rtsopts=-N
default-language: Haskell2010
source-repository head
type: git
location: https://github.com/githubuser/DyanmicLoad

Can't compile haskell encoding lib. Couldn't find HaXml modules

I need a library to encode data in cp1251 to work with an api which use it.
I found only 2 libs for this purpose. The encoding lib and text-icu lib. The first one looks better just because it can be statically linked to my program.
But I can't even compile it! I am using stack so I add encoding to build-deps in my .cabal file, and then stack solver update my stack yaml file with encoding-0.8 in extra-deps.
but after running stack build I a got an error
Data/Encoding/Preprocessor/XMLMapping.hs:11:8:
Could not find module ‘Text.XML.HaXml.Types’
Use -v to see a list of the files searched for.
Data/Encoding/Preprocessor/XMLMappingBuilder.hs:15:8:
Could not find module ‘Text.XML.HaXml.OneOfN’
Use -v to see a list of the files searched for.
Data/Encoding/Preprocessor/XMLMappingBuilder.hs:16:8:
Could not find module ‘Text.XML.HaXml.XmlContent’
Use -v to see a list of the files searched for.
I tried to use older version of HaXml and encoding but got the same error.
For example I tried to use encoding-0.6.7 with HaXml-1.22.3, after reading changelog https://hackage.haskell.org/package/encoding-0.7.0.2/changelog but got the same error.
In hackage documentation all this modules which encoding can't import exists.
How can I compile this lib? I am using stack 1.0.4, lts-5.6 and ghc-7.10.3 on linux mint x64
stack.yaml
flags: {}
extra-package-dbs: []
packages:
- '.'
extra-deps:
- encoding-0.8
- text-1.2.2.0
resolver: lts-5.6
cabal:
name: hapidry
version: 0.1.1.0
synopsis: Initial project template from stack
description: Please see README.md
homepage: -
license: GPL-2
license-file: LICENSE
author: -
maintainer: -
copyright: GPL
category: network
build-type: Simple
-- extra-source-files:
cabal-version: >=1.10
library
hs-source-dirs: src
exposed-modules: Lib
build-depends: base >= 4.7 && < 5
default-language: Haskell2010
executable hapidry-exe
hs-source-dirs: app
main-is: Main.hs
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends: base
, hapidry
, wreq
, ConfigFile
, aeson
, lens
, cryptohash
, binary
, mtl
, base16-bytestring
, bytestring
, containers
, text
, lens-aeson
, data-default
, optparse-applicative
, encoding
default-language: Haskell2010
test-suite hapidry-test
type: exitcode-stdio-1.0
hs-source-dirs: test
main-is: Spec.hs
build-depends: base
, hapidry
ghc-options: -threaded -rtsopts -with-rtsopts=-N
default-language: Haskell2010
source-repository head
type: git
location: -
Finally I wrote my own funtion for encoding. It looks like acceptable workaround. And functions for another one-byte encodings can be implemented in the same way.
toCP1251 :: Text -> B.ByteString
toCP1251 = B.pack . T.unpack . T.map replace where
replace l = case (Map.lookup l table) of
(Just x) -> x
(Nothing) -> l
table = Map.fromList $ zip rus cpCodes
cpCodes = map toEnum (168:184:[192 .. 255]) :: [Char]
rus = ['Ё', 'ё', 'А', 'Б', 'В', 'Г', 'Д', 'Е', 'Ж', 'З', 'И', 'Й', 'К', 'Л', 'М',
'Н', 'О', 'П', 'Р', 'С', 'Т', 'У', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ', 'Ъ', 'Ы',
'Ь', 'Э', 'Ю', 'Я', 'а', 'б', 'в', 'г', 'д', 'е', 'ж', 'з', 'и', 'й', 'к',
'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т', 'у', 'ф', 'х', 'ц', 'ч', 'ш', 'щ',
'ъ', 'ы', 'ь', 'э', 'ю', 'я'] :: [Char]

Why isn't haddock generating documentation?

My Haskell file (pretty sure this is not the problem) is basically:
import System.IO
...
-- | Every Word is a String
type Word = String
...
-- | Some documentation for Haddock to see
main :: IO ()
main = do
...
My Setup.hs:
import Distribution.Simple
main = defaultMain
My grade.cabal:
name: grade
version: 0.1.0.0
...
build-type: Simple
cabal-version: >=1.8
executable grade
main-is: grade.hs
-- other-modules:
build-depends: base ==4.6.*, split ==0.2.*
hs-source-dirs: src
When I run cabal haddock --executables I get
...
Haddock coverage:
Warning: Not found in environment: Main.main
50% ( 1 / 2) in 'Main'
Warning: Main: could not find link destinations for:
Main.main
Documentation created: dist/doc/html/grade/grade/index.html
and the HTML contains main but no documentation for it. It does not even contain functions I defined other than main. Why is that?
You need to add a module declaration to generate documents for it.
module Main (main, Word) where

cabal test not finding module

I'm trying to get cabal test to run my HUnit test, without much luck. The problem is that it can't find one of my test modules — how do I fix this?
cabal configure --enable-tests && cabal build && cabal test fails with
tests/HUnit/Test.hs:4:18:
Could not find module `AmazonTest'
/tests/HUnit
AmazonTest.hs
module AmazonTest where
import Test.HUnit
import Lib.Amazon
tests = TestList [ "test sayHello" ~: "Hell!" ~=? sayHello ]
Test.hs
module Main where
import Test.HUnit
import qualified AmazonTest as Amazon
main = runTestTT Amazon.tests
\Lib\Amazon.hs
module Lib.Amazon where
sayHello :: String
sayHello = "Hello!"
test part of my .cabal file
test-suite test
type: exitcode-stdio-1.0
main-is: tests/HUnit/Test.hs
hs-source-dirs: .
ghc-options: -Wall
build-depends: base
, myapp
, yesod-test >= 0.3 && < 0.4
, yesod-default
, yesod-core
, persistent
, persistent-postgresql
, resourcet
, monad-logger
, HUnit
, text
Add tests/HUnit to hs-source-dirs. hs-source-dirs are not searched recursively.

Resources