Difference between revisions of "Cabal/FAQ"

From HaskellWiki
Jump to navigation Jump to search
m
(Archaic content removed)
 
(6 intermediate revisions by 5 users not shown)
Line 1: Line 1:
 
[[Category:FAQ]]
 
[[Category:FAQ]]
  +
[[Category:Cabal]]
   
Before you continue: Don't miss the other FAQ at http://www.haskell.org/cabal/FAQ.html
+
See http://www.haskell.org/cabal/FAQ.html
 
== What is this hidden package? ==
 
 
You build a package and get a message like:
 
 
<pre>
 
Could not find module `Data.Map': it is a member of package
 
containers-0.1.0.0, which is hidden.
 
</pre>
 
 
or
 
 
<pre>
 
Failed to load interface for `GHC.Prim':
 
it is a member of the hidden package `ghc-prim'
 
Use -v to see a list of the files searched for.
 
</pre>
 
 
This is because the package has not been updated for ghc-6.8 which has split the base package into lots of smaller packages. The package needs to be updated to say that it depends on these new split base packages, like containers, process and several others.
 
 
If you just want to get the package to build, add the missing package names to the build-depends: line in the .cabal file. For example given the above error message we would add the 'containers' package to the build-depends. (Alternatively, you can add the switch --ghc-options="-package hidden-package-name" to cabal.)
 
 
Developers of packages who want to know how to update their package properly so that it will continue to work with old and new compilers should see [[Upgrading_packages]].
 
 
== How do I handle Haskell language extensions? ==
 
If your code uses some of the advanced Haskell extensions, you have a number of options.
 
 
Each language extension has a standard name. You can find the list in [http://haskell.org/ghc/docs/latest/html/libraries/Cabal/Language-Haskell-Extension.html Language.Haskell.Extension].
 
 
# The simplest way, if you're distributing via Cabal, is to add <code>extensions: </code> and the list of extensions names to your .cabal file. For example <code>extensions: CPP, ForeignFunctionInterface</code>. This allows every module in the package to use the listed extensions. Cabal will pass the appropriate flags to the compiler and it even checks that the compiler supports those extensions.
 
# The best way to do it, if you know your users are using GHC 6.8.x is the new LANGUAGE pragma. This allows you to enable just those extensions that you are using in a particular module. For example stick <haskell>{-# LANGUAGE CPP, ForeignFunctionInterface #-}</haskell> at the top of the file.
 
# An equivalent of the LANGUAGE pragma for older versions of GHC is the <code>OPTIONS_GHC</code> pragma (or for GHC 6.4 and older the <code>OPTIONS</code> pragma). The downside is that you have to know the GHC command line flag for the extensions you want. For example stick <haskell>{-# OPTIONS_GHC -fffi -cpp #-}</haskell> at the top of the file. Many other language extensions are enabled by <code>-fglasgow-exts</code>.
 
 
== [Windows] I tried to install a Haskell binding to (some external C library), but I get build errors ==
 
 
Packages consisting of 100% Haskell code almost always build perfectly on Windows. However, packages which implement bindings to external C libraries (e.g., OpenSSH, libSDL, etc.) sometimes won't build on Windows without prodding.
 
 
# Check that the external C library is actually installed on your system. (Cabal does ''not'' do this for you.)
 
# Check the package contents, package home page, etc., to see if the author has ''told'' you how to get this package to work on Windows.
 
 
If those two fail to get you any further, proceed as follows:
 
 
* Cabal probably needs to be able to find header files in order to compile the package. In future there will be some switches for the 'configure' step to allow you to specify the path to these. For now, you'll have to manually ''hack'' the Cabal information file to tell Cabal where to look. Try adding a line in the 'library' section saying something like <code>include-dirs: "C:\\Program Files\\My External Library\\include"</code> (Note carefully the quotes and double backslashes!) Obviously the actual path varies depending on where you installed the thing.
 
* Cabal may also need to find object files that need to be statically linked. Again, a future Cabal release will allow you to specify these during the configure state with switches, but for now try adding <code>extra-lib-dirs: "C:\\Program Files\\My External Library\\lib"</code> or similar.
 
* Assuming you get your library to compile, you may still need to add DLLs or other resources to your PATH variable to get any programs ''using'' the package to actually run. (But the installer for the external library might have done this for you already.)
 
 
== Conditional compilation ==
 
 
=== Executables with additional dependencies ===
 
 
Example Question: I want to build an executable for automated tests that depend on QuickCheck. However, building of tests is not necessary for installing the library and thus the dependency on QuickCheck is not always necessary. How can I explain that to Cabal?
 
 
Answer:
 
Write something like the following into your Cabal file:
 
 
<code>
 
Flag buildTests
 
description: Build test suite
 
default: False
 
 
Library
 
...
 
 
Executable test
 
If flag(buildTests)
 
Build-Depends: QuickCheck
 
Else
 
Buildable: False
 
GHC-Options: -Wall
 
Hs-Source-Dirs: src
 
Main-Is: Test.hs
 
</code>
 
 
=== Enabling additional features via Cabal flags ===
 
 
Question: I like to let the user enable extended functionality using a Cabal flag. Is this the right way?
 
 
Answer:
 
Certainly not.
 
Since other packages can distinguish packages only according to their name and their version,
 
it is not a good idea to allow different APIs for the same package version.
 
Cumbersome as it is you have to move extra features to a separate package.
 
 
=== Adapt to different systems without CPP ===
 
 
Question: The Cabal documentation suggests to use the C preprocessor on Haskell code in order to adapt to system specific behaviour. I find this ugly. Is there another way?
 
 
Answer:
 
You can put modules with the same name and API in different directories and choose the right module using a Cabal test.
 
 
<code>
 
-- necessary packaging all module variants when doing 'sdist'
 
Extra-Source-Files:
 
src-i386/CPU/Dependent/Module.hs
 
src-gen/CPU/Dependent/Module.hs
 
 
Exposed-Modules:
 
CPU.Dependent.Module
 
...
 
 
If arch(i386)
 
Hs-Source-Dirs: src-i386
 
Else
 
Hs-Source-Dirs: src-gen
 
</code>
 
On the one hand it is a bit cumbersome to maintain the separate directory trees,
 
on the other hand the modules can be read as they are and the reader does not need to untangle nested <code>#if</code> directives.
 
Separation of OS dependent code into individual modules is certainly a good idea anyway,
 
however if you want to adapt to many combinations of compilers and their versions, operating systems and processors
 
then the above approach will make things worse.
 

Latest revision as of 01:27, 20 April 2021