I have written some simplistic code to call a function in a C library. The code compiles (and a similar piece works for a standard C library) but when I compile and link, ghc cannot find the C library. My cabal files is:
executable ttclient
main-is: MainFFI4TT.hs
build-depends: base
default-language: Haskell2010
hs-source-dirs: src
other-modules:
Include-dirs: treetaggerSourceC
Includes: tagger-api.h
extra-libraries: libtreetagger
extra-lib-dirs: /usr/lib
the file libtreetagger.so is in /usr/lib but cannot be found. what else would be reuqired? It does not make a difference whether I use stack build or cabal install (8.0.2 or 8.0.1). cabal is version 1.24.0.0 and the system is linux debian stretch.
I would prefer to keep the library in a user dir and not a system dir. Can this be achieved?
The haskell code is:
foreign import ccall "tagger-api.h init_treetagger"
c_initTreeTagger :: CString -> IO ()
-- void init_treetagger(char *param_file_name);
mainFFItest :: IO ()
mainFFItest = do
c_initTreeTagger "german-utf8.par"
I assume you're getting the error message:
* Missing C library: libtreetagger
If so, the likely problem is that extra-libraries should list libraries without the lib prefix:
extra-libraries: treetagger
Related
I'm using inline-c and I have two C files that I'd like to call in the Haskell code. In the Cabal file, there are:
include-dirs: cbits
, /usr/local/include
c-sources: cbits/genann.c
In the Cbits directory, there's also genann.h
I can build and run the project without problem but when I do cabal install, the compiler complain that it can't find the C header file.
I checked the Cabal manual and added the following options:
includes: cbits/genann.h
install-includes: cbits/genann.h
This time I got:
Configuring executable 'inline-gsl' for inline-gsl-0.1.0.0..
cabal-3.6.2.0: Missing dependency on a foreign library:
* Missing (or bad) header file: cbits/genann.h
This problem can usually be solved by installing the system package that
provides this library (you may need the "-dev" version). If the library is
Where is wrong here? Do I need to compile the C code into object code and put them in the system?
The complete Cabal file:
cabal-version: 2.4
name: inline-gsl
version: 0.1.0.0
-- A short (one-line) description of the package.
-- synopsis:
extra-source-files: CHANGELOG.md
executable inline-gsl
main-is: Main.hs
build-depends: base ^>=4.14.3.0
, inline-c
, vector
, massiv
, array
, bytestring >= 0.10
, template-haskell
hs-source-dirs: app
pkgconfig-depends: glib-2.0, gtk4, gsl
default-language: Haskell2010
extra-libraries: m, tensorflow
extra-lib-dirs: /usr/local/lib
cc-options: -Wall -m64 -O4
include-dirs: cbits
, /usr/local/include
includes: cbits/genann.h
install-includes: cbits/genann.h
c-sources: cbits/genann.c
I can build and run the project without problem but when I do cabal install, the compiler complain that it can't find the C header file.
I believe this indicates that the problem is that your header files are not included in your package source tarballs (sdist). You need to list all non-Haskell source files under the extra-source-files field in your cabal file:
extra-source-files: CHANGELOG.md, cbits/genann.h, cbits/genann.c
First off, I'm new to using cabal and external packages with Haskell.
I'm trying to use the Graphics.Gloss package inside of MyLib. I can make it work if I include gloss in both the build-depends of library and executable.
Here is the relevant portion of the cabal file:
library
exposed-modules: MyLib
build-depends: base ^>=4.13.0.0,
gloss ^>=1.13.1.1
default-language: Haskell2010
executable ray-tracer
main-is: Main.hs
other-modules: MyLib
build-depends: base ^>=4.13.0.0, ray-tracer,
haskell-say ^>=1.0.0.0,
gloss ^>=1.13.1.1
MyLib.hs
module MyLib (someFunc) where
import Graphics.Gloss
someFunc :: IO ()
someFunc = display (InWindow "My Window" (200,200) (10,10)) white (Circle 80)
Main.hs
module Main where
import qualified MyLib (someFunc)
import HaskellSay (haskellSay)
main :: IO ()
main = do
MyLib.someFunc
Why doesn't this work when gloss is only included in the library dependencies?
You can make it work. There is a problem in your current set up, which is that the files for the library and the executable are in the same directory. See also this question How to avoid recompiling in this cabal file? which is a symptom of the same underlying problem: when you build the executable, it rebuilds MyLib from scratch (which requires the gloss dependency) instead of reusing your library that was already built.
MyLib/
ray-tracer.cabal
MyLib.hs
Main.hs # Bad
Move the .hs files in separate directories (technically you only need to move one of them, but I think it's better to keep the root directory as uniform as possible):
MyLib/
MyLib.cabal
src/
MyLib.hs
exe/
Main.hs
And in the cabal file, add hs-source-dirs: src and hs-source-dirs: exe to the corresponding sections:
library
hs-source-dirs: src
...
executable ray-tracer
hs-source-dirs: exe
...
I'm currently not using stack at all on this project (just Cabal), and all was going well when everything was in Main.hs. I decided to split up code, moving my dhall dep and related code from my executable deps to my library deps, and now seem to have this strange error when running cabal new-build:
Building executable 'FarmDataServer.exe' for FarmDataServer-0.1.0.0..
<no location info>: warning: [-Wmissing-home-modules]
These modules are needed for compilation but not listed in your .cabal file's other-modules: FDS
FDS.Config.Core
FDS.Config.DhallConf
[2 of 4] Compiling FDS.Config.DhallConf ( src/FDS/Config/DhallConf.hs, /home/brandon/workspace/CIDA/FarmDataServer/dist-newstyle/buil
d/x86_64-linux/ghc-8.4.4/FarmDataServer-0.1.0.0/x/FarmDataServer.exe/build/FarmDataServer.exe/FarmDataServer.exe-tmp/FDS/Config/Dhall
Conf.o )
src/FDS/Config/DhallConf.hs:7:1: error:
Could not find module `Dhall'
Use -v to see a list of the files searched for.
|
7 | import Dhall
| ^^^^^^^^^^^^^^^^^^^^^^
Certainly I'm also a bit confused by the Wmissing-home-modules message since I seem to have added those in my cabal file.
Relevant bits of my .cabal file:
cabal-version: 2.4
name: FarmDataServer
version: 0.1.0.0
library
exposed-modules:
FDS
other-modules:
FDS.Config.Core
, FDS.Config.DhallConf
build-depends: base ^>=4.11.1.0
, conduit ^>=1.3.1
, csv-conduit ^>=0.7.0.0
, dhall ^>=1.20.0
, text ^>=1.2.3.1
hs-source-dirs: src
executable FarmDataServer.exe
main-is: Main.hs
build-depends: base ^>=4.11.1.0
, conduit ^>=1.3.1
, csv-conduit ^>=0.7.0.0
, scotty ^>=0.11.3
, text ^>=1.2.3.1
, FarmDataServer ^>=0.1.0.0
My src folder:
$ pwd
/home/brandon/workspace/CIDA/FarmDataServer/src
$ du -a
4 ./FDS/Config/DhallConf.hs
4 ./FDS/Config/Core.hs
12 ./FDS/Config
16 ./FDS
4 ./FDS.hs
4 ./Main.hs
28 .
For the missing modules, sink your program executable into a directory such that the module hierarchy for yoru library isn't visible:
mkdir program ; mv src/Main.hs program/
and in cabal for the executable
hs-source-dirs: program
For your missing module Dhall, add the dhall build dependency to your executable stanza in the cabal file.
I'm messing around with the plugins package however I bumped into a problem.
Here's the code:
Util/Header.hs
module Util.Header(PT(..)) where
data PT a = PT a deriving Show
Plug.hs
module Plug(helloPlugin) where
import Util.Header
helloPlugin :: PT Int
helloPlugin = PT 1
Main.hs
module Main where
import Util.Header
import System.Plugins
main :: IO ()
main = do
mv <- load "Plug.o" ["."] [] "helloPlugin"
case mv of
LoadFailure msg -> print msg
LoadSuccess _ v -> print $ show (v :: PT Int)
This all works fine then compiling with ghc. Building with Cabal works fine as well, but when I run the executable I get this error:
plugintest: /home/kevin/.cabal/lib/plugins-1.5.4.0/ghc-7.6.3/HSplugins-1.5.4.0.o: unknown symbol `ghczm7zi6zi3_ErrUtils_zdsinsertzuzdsgo5_info'
plugintest: user error (resolvedObjs failed.)
My very minimalistic cabal file:
name: plugintest
version: 0.1.0.0
license-file: LICENSE
build-type: Simple
cabal-version: >=1.8
library
hs-source-dirs: src
exposed-modules: Util.Header
build-depends: base ==4.6.*, plugins ==1.5.*
executable plugintest
main-is: Main.hs
build-depends: base ==4.6.*, plugins ==1.5.*, plugintest == 0.1.0.0
hs-source-dirs: src
Now I assume the problem is that it can't find the "ErrUtils" module which is part of the ghc package installed in /usr/lib/ghc-7.x.x.
Since it's using cabal it'll use the $HOME/.cabal/lib/ instead.
Now I obviously wouldn't want to use /usr/lib if I wanted to make it distributable. Sadly I'm not very familiar with how packages are managed nor am I familiar with the plugins package.
I have a feeling this is extremly nooby but I wasn't able to find a solution myself.
So a few questions:
How can I get my dependencies to work in a way to make this distributable?
It seems I'll need to know beforehand what my Plugin.o files will depend on before actually being able to use them (If I understand correctly).
Is there a way to package a .o files that I wouldn't have to worry about this problem? (Sorry if this question is too vague, feel free to ignore)
Thanks in advance!
Ok, so I had the exact same problem.
Here is a workaround I found
Change the load call to
load "Plug.o" [".","dist/build/plugintest/plugintest-tmp"] [] "testplugin"
Make sure you compile the thing with -c or by using the "make" library from plugins.
Quite annoyed by this... The error suggests it is having issues linking against the standard libs, so why does showing it these .o files fix it?
Anyways, this worked for me, and didn't require a ton of mucking around with .cabal files.
You must declare your exported- and other- modules in order for Cabal to package them all together. For instance (from https://github.com/tel/happstack-heroku-test)
name: hktest -- note the name here names
-- the *library* which is a package name
-- in scope when building the executable
...
library
exposed-modules:
HKTest
other-modules:
-- there aren't any, but there could be some
build-depends: base >= 4.6 && <4.7
...
, mtl >= 2.1.2
hs-source-dirs: src
executable server
main-is: Server.hs
other-modules:
-- there might be some use to having these here,
-- but they'll be harder to get into GHCi, so I wouldn't
-- recommend it---just put them in the library part
build-depends: base >=4.6 && <4.7
, hktest -- note that I grab all the hktest
-- modules here
hs-source-dirs: exe
If I leave out one of those modules I'll likely get a build error as Cabal compiles files which expect to be able to find symbols that haven't been packaged.
In your case, since you're building an executable, the common pattern exemplified above is to put all of your code into a library and then have the executable side depend upon that library. For instance, in this example the complete text of exe/Server.hs is
module Main where
import qualified HKTest as HK
main :: IO ()
main = HK.main
I am making a small Haskell game in Windows, where I would like to respond each time the user presses a key. Because getChar behaves strangely on Windows, I use FFI to get access to getch in conio.h, as described here. The relevant code is:
foreign import ccall unsafe "conio.h getch" c_getch :: IO CInt
This works fine, when I run it in ghci, or compile it with ghc. I also want to try making a cabal package out of it, so extending from this question, I include the following in my cabal file:
...
executable noughts
Includes: conio.h
Extra-libraries conio
...
But when I run cabal configure, it tells me:
cabal: Missing dependency on a foreign library:
* Missing C library: conio
It makes sense, because in my haskell platform directory, under ...\Haskell Platform\2012.4.0.0\mingw there is a conio.h file under the include directory, but no other conio file to provide the object code.
Am I doing this the right way, and if so, how can I find out which library to include in my cabal file?
First off, there is not always a one-to-one mapping between C header files and libraries. In this case, the functions declared in conio.h can be found in various runtime libraries, such as crtdll (deprecated) or msvcrt (preferred, I guess).
With the Haskell Platform on Windows, Cabal will look for these libraries in .\mingw\lib (under your Haskell Platform directory): if you ask for msvcrt, it will look for .\mingw\lib\libmsvcrt.a. This specific library should already be shipped with your Haskell Platform. (If you want to point to other directories with lib*.a files, you can use Cabal's --extra-lib-dirs option.)
A tiny example of this would be as follows; this is Main.hs:
{-# LANGUAGE ForeignFunctionInterface #-}
import Foreign.C.Types
foreign import ccall unsafe "conio.h _putch" c_putch :: CInt -> IO ()
main :: IO ()
main = do
c_putch . toEnum . fromEnum $ '!'
c_putch . toEnum . fromEnum $ '\n'
And this would be something-awesome.cabal:
name: something-awesome
version: 0.1.0.0
build-type: Simple
cabal-version: >=1.8
executable yay
main-is: Main.hs
build-depends: base ==4.5.*
includes: conio.h
extra-libraries: msvcrt
This should work fine:
c:\tmp\something-awesome> dir /B
Main.hs
something-awesome.cabal
c:\tmp\something-awesome> cabal configure
Resolving dependencies...
Configuring something-awesome-0.1.0.0...
c:\tmp\something-awesome> cabal build
Building something-awesome-0.1.0.0...
Preprocessing executable 'yay' for something-awesome-0.1.0.0...
[1 of 1] Compiling Main ( Main.hs, dist\build\yay\yay-tmp\Main.o )
Linking dist\build\yay\yay.exe ...
c:\tmp\something-awesome> dist\build\yay\yay.exe
!