Is it possible to package c code with Haskell using cabal? - haskell

I have a c library that I'd like to provide an FFI interface for. This is easy enough, but I can't figure out how to get the packaging right. It would be nice to just be able to
cabal install librarybindings
and have cabal automatically build it with gcc, generate the .o file, and include that with the distribution. Right now, I can the package to compile fine, but when you go to build an executable using the bindings you have to explicitly pass ghc the .o file on the command line. Yuck.

Yes, you can ship C code with Haskell. See e.g.
bytestring
zlib
download
By convention the C bits are put in a cbits/ directory.

Related

Two cabal packages in a cabal.project and nix-building both (a lib and its example prgs)

I have a haskell lib X having the following file-structure:
X/src/libxfiles.hs
X/default.nix
X/shell.nix
X/libx.nix
X/libx.cabal
X/cabal.project
and
X/example/lib/exampleCommon.hs
X/example/ex1/main.hs
X/example/ex2/main.hs
X/example/example.cabal
cabal.project points to libx.cabal and to example/example.cabal and cabal new-build all works inside nix-shell. The required haskell packages for libx library and example-programs are introduced in the libx.nix -file.
Why this structure? Since the example programs have 99% common code and only a couple of lines that are ui-dependend (webkit2gtk and such). Earlier version had flags and CPP inside the main of example and nix-build produced the lib and example prg in result-directory. On this new setup, the cabal new-build works ok when the compiler is ghc and my aim is to produce programs with ghc.
Earlier nix-build build the lib and one of its example programs with ghcjs.
At the moment, nix-build makes only the lib. Is it somehow possible to tell in the libx.nix or in the default.nix to also build one of the example-programs, say ex1? That is, to tell for the build process to cabal new-build ex1 and then install the result just like it installs the lib.
To use ghcjs, to build the ex1 that is targeted to ghcjs, it is possible to nix-shell --argstr "compiler" "ghcjs" and then cabal new-configure --ghcjs etc. (So, outside nix-shell, the nix-build -command is not doing all I'd like it do.)
Is it required to make a nix-files into the example-directory? Somehow this does not sound that appealing as the required modules are already given in libx.nix. That is, should I do something like in the answer to how to get cabal and nix work together?
Or is there a haskell package in github having similar structure that could work as an example?
Ideal solution would be that nix-build would build the lib and all its example programs. That would require the use of different building tools (ghc and ghcjs). Thus, maybe the question is, how to make a nix-setup for a multipackage cabal-project where individual packages need different environments including the compilation tools. On ideal world, the default nix-build would build all, and user could parameterize the nix-build to build the chosen example or examples etc.
It appears that the discussions in
cabal issue 4646 and in cabal2nix issue 286 are possibly related.

Including other *.o files with Cabal

I'm building a simple library that wraps some parts of Qt. I want to be able to use Qt's qmake configuration system to find the Qt libraries on the given system, etc, to build the c wrapper code. I can get this to work and produce a *.o file, no problem.
But how can I get cabal to include this *.o file in the *.a it generates? I assume I'll have to write a custom Setup.hs to make it work, but reading over the Cabal library documentation I don't see an obvious way to do it.
On #haskell someone suggested that I could use postBuild to add files to the *.a after it is generated, but even then how do I get the path to the generated *.a from inside postBuild?

Installing GLUT fails due to missing foreign library - ghc7.8

I tried cabal install GLUT which gave the following:
Setup: Missing dependency on a foreign library:
* Missing C library: glut32
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
already installed but in a non-standard location then you can use the flags
--extra-include-dirs= and --extra-lib-dirs= to specify where it is.
So I thought, ok, lets get the sources and point cabal to the directories. I first tried freeglut and then the following
cabal install GLUT --extra-include-dirs="<path to freeglut>\include"
--extra-lib-dirs="<path to freeglut>\src"
Same thing, so I thought maybe it doesn't work with freeglut, and got glut:
cabal install GLUT --extra-include-dirs="<path to glut>\include"
--extra-lib-dirs="<path to glut>\lib"
When this doesn't work, I try to download the source and cabal install inside the directory, then runghc Setup configure. Then thinking that there is some parse error of the paths, I try every possible way of writing a file path known to man; quotes, no quotes, backslashes, double backslashes, forward slashes, and every combination of the above. I even placed all the files on my PATH in hopes it would find them. All other options exhausted, I proceeded to sacrifice a goat to satan, but still no dice.
The question is, what do I have to do to convince ghc to find this library? (this is windows 7)
You need to make the libglut32.a import library accessible to the compiler (see this answer for information about what import libraries are). Just copy it under $GHCDIR/mingw/lib. Alternatively, try the Haskell Platform installer, which ships with a pre-compiled version of the GLUT bindings.

Haskell Bad Interface File

I am trying to take my Haskell project and split it apart into a library and a set of executables that depend on the library. When I try to compile now I get the following error:
src/Main.hs:23:0:
Bad interface file: /Users/<MyHomeDir>/.cabal/lib/Core-0.0.1/ghc-6.12.1/<MyModule>.hi
mismatched interface file ways (wanted "", got "p")
I believe that the p might be the p flag related to packages for ghc. Is this correct? Do I need to add more configuration options somewhere to my cabal file to support this?
I encountered a similar problem when compiling executables with dynamic linking.
I compiled a library and executable by invoking cabal install --ghc-option=-dynamic pkg.
The executable was built with dynamic linking but the library part was unusable.
I assume that using the --ghc-option=-dynamic option caused the static version of the library was built with dynamic linking also.
Since Cabal-1.14 I can use the --enable-executable-dynamic option which works correctly.
That's saying it found a profiling build, but you're building Main.hs without profiling enabled. Quick fixes:
enable profiling in the build for Main.hs
build and install <MyModule> with profiling enabled
Either way, that will begin with a command that resembles
$ runghc Setup.hs configure --enable-library-profiling

Haskell cabal+hsc2hs

Can cabal use hsc2hs to create hs files? How?
I didn't find an answer in the manuals, googling, nor in other projects (had my hopes up for gtk2hs but it turns out that it doesn't use cabal)
Yes, cabal understands that when you list module Foo in your .cabal file, and it finds Foo.hsc on disk, that it must run hsc2hs on the module first.
Cabal transparently handles the existence of .hsc files.

Resources