<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>therning.org/ magnus &#187; cabal</title>
	<atom:link href="http://therning.org/magnus/archives/tag/cabal/feed" rel="self" type="application/rss+xml" />
	<link>http://therning.org/magnus</link>
	<description>Incoherent mumblings</description>
	<lastBuildDate>Thu, 12 Jan 2012 13:40:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Maintaining Haskell packages for a Linux distribution&#8212;cblrepo</title>
		<link>http://therning.org/magnus/archives/914</link>
		<comments>http://therning.org/magnus/archives/914#comments</comments>
		<pubDate>Wed, 27 Apr 2011 22:51:01 +0000</pubDate>
		<dc:creator>Magnus</dc:creator>
				<category><![CDATA[Posts]]></category>
		<category><![CDATA[arch]]></category>
		<category><![CDATA[cabal]]></category>
		<category><![CDATA[hackage]]></category>
		<category><![CDATA[haskell]]></category>

		<guid isPermaLink="false">http://therning.org/magnus/?p=914</guid>
		<description><![CDATA[Maintaining a large set of Haskell packages for a Linux distribution is quite a chore. Especially if one wants to track Hackage as far as possible. Several distributions have tools to automatically convert Cabal-based packages into distribution packages, e.g. cabal2arch for ArchLinux and cabal-rpm. They are just conversion tools though, and the most time-consuming activity [...]]]></description>
			<content:encoded><![CDATA[<p>Maintaining a large set of Haskell packages for a Linux distribution is quite
a chore.  Especially if one wants to track <a href="http://hackage.haskell.org/">Hackage</a> as far as possible.
Several distributions have tools to automatically convert Cabal-based packages
into distribution packages, e.g. <a href="http://hackage.haskell.org/package/cabal2arch">cabal2arch</a> for <a href="http://www.archlinux.org/">ArchLinux</a> and
<a href="http://hackage.haskell.org/package/cabal-rpm">cabal-rpm</a>.  They are just conversion tools though, and the most
time-consuming activity in maintaining Haskell packages is resolving
and verifying dependencies.</p>

<p>At least that was my experience when I was actively involved in
<a href="http://archhaskell.wordpress.com/">ArchHaskell</a>.  I only saw two options when adding or upgrading a package,
either I worked out dependencies manually, or I simply tried it out.  Neither
of them was very appealing, and both were very time-consuming.  It seemed
obvious that I needed some tool to help out.</p>

<p>Enter <code>cblrepo</code>!</p>

<p>It allows me to maintain a database of specific versions of packages, and when
I want to upgrade a package, or add a new one, it&#8217;ll verify that all
dependencies can be satisfied.  In other words, it helps me maintain a
buildable set of packages at all times.</p>

<p>The tool also has some functionality that helps in tracking Hackage as
packages are updated there.</p>

<h3>Something about how it works</h3>

<p>At the moment I maintain a small repository of Arch packages, mostly just to
try out <code>cblrepo</code> and convince myself that it works.  The work environment
contains a database and a directory of patches:</p>

<pre><code>% ls
cblrepo.db  patches/
%
</code></pre>

<p>The database is a cleartext file containing the information on the packages.
It&#8217;s basically just a dump of the related Haskell datatype, encoded in JSON.
The <code>patches</code> directory holds patches for Cabal files and PKGBUILD files.
They must be named <code>patch.cabal.&lt;hackage name&gt;</code> or <code>patch.pkgbuild.&lt;hackage
name&gt;</code> in order to be picked up by <code>cblrepo</code>.</p>

<p>There&#8217;s also an application directory (<code>~/.cblrepo</code>) for caching info about
the packages available on Hackage:</p>

<pre><code>% ls ~/.cblrepo
00-index.tar.gz
%
</code></pre>

<h3>How to use it</h3>

<p>A session with <code>cblrepo</code> looks something like this.  First we update the
information about what packages are available on Hackage:</p>

<pre><code>% cblrepo idxsync
%
</code></pre>

<p>After that it&#8217;s possible to see what packages are out-of-date:</p>

<pre><code>% cblrepo updates
cmdargs: 0.6.8 (0.6.9)
test-framework-th: 0.1.3 (0.2.0)
xml: 1.3.7 (1.3.8)
language-haskell-extract: 0.1.2 (0.2.0)
blaze-builder: 0.2.1.4 (0.3.0.0)
%
</code></pre>

<p>Let&#8217;s check whether <code>cmdargs</code> can be updated:</p>

<p>% cblrepo add -n cmdargs,0.6.9
   %</p>

<p>It generates no output, so that means it&#8217;s possible to update.  When
attempting to add all the packages we run into a problem:</p>

<pre><code>% cblrepo add -n cmdargs,0.6.9 \
&gt; test-framework-th,0.2.0 \
&gt; xml,1.3.7 \
&gt; language-haskell-extract,0.2.0 \
&gt; blaze-builder,0.3.0.0
Adding blaze-builder 0.3.0.0 would break:
  haxr : blaze-builder ==0.2.*
</code></pre>

<p>We&#8217;ll leave <code>blaze-builder</code> at the current version for now:</p>

<pre><code>% cblrepo add cmdargs,0.6.9 \
&gt; test-framework-th,0.2.0 \
&gt; xml,1.3.7 \
&gt; language-haskell-extract,0.2.0
%
</code></pre>

<p>After these updates we also need to make sure that all packages that depend on
these ones are re-built, that is we need to bump their release version:</p>

<pre><code>% cblrepo bump -n cmdargs \
&gt; test-framework-th \
&gt; xml \
&gt; language-haskell-extract
Would bump:
test-framework
test-framework-hunit
test-framework-quickcheck2
%
</code></pre>

<p>Just re-run that without the <code>-n</code> to actually perform the bump.  Now that all
this is done we need to generate the files necessary to build the Arch
packages.  We can easily check what packages need re-building, and get a good
order for building them:</p>

<pre><code>% cblrepo build cmdargs \
&gt; test-framework-th \
&gt; xml \
&gt; language-haskell-extract
cmdargs
xml
test-framework
test-framework-quickcheck2
test-framework-hunit
language-haskell-extract
test-framework-th
%
</code></pre>

<p>And generating the required files is also easy:</p>

<pre><code>% cblrepo pkgbuild $(!!)
% tree
.
|-- cblrepo.db
|-- haskell-cmdargs
|   |-- haskell-cmdargs.install
|   `-- PKGBUILD
|-- haskell-language-haskell-extract
|   |-- haskell-language-haskell-extract.install
|   `-- PKGBUILD
|-- haskell-test-framework
|   |-- haskell-test-framework.install
|   `-- PKGBUILD
|-- haskell-test-framework-hunit
|   |-- haskell-test-framework-hunit.install
|   `-- PKGBUILD
|-- haskell-test-framework-quickcheck2
|   |-- haskell-test-framework-quickcheck2.install
|   `-- PKGBUILD
|-- haskell-test-framework-th
|   |-- haskell-test-framework-th.install
|   `-- PKGBUILD
|-- haskell-xml
|   |-- haskell-xml.install
|   `-- PKGBUILD
`-- patches

8 directories, 15 files
%
</code></pre>

<p>Now all that&#8217;s left is running <code>makepkg</code> in each of the directories, in the
order indicated by <code>cblrepo build</code> above.</p>

<p>Unfortunately they won&#8217;t all build&#8212;generating the Haddock docs for
<code>test-framework-th</code> fails.  That&#8217;s however fairly easy to remedy by patching
the <code>PKGBUILD</code> to disable the generation of docs.</p>

<p>I&#8217;ll get back to that in a later post though.</p>

<h3>Your comments, please</h3>

<p>Please leave comments and suggestions.  I&#8217;m planning on uploading the source
to <a href="http://github.com">github</a> shortly.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Ftherning.org%2Fmagnus%2Farchives%2F914&amp;title=Maintaining%20Haskell%20packages%20for%20a%20Linux%20distribution%26%238212%3Bcblrepo" id="wpa2a_2">Share/Bookmark</a></p>]]></content:encoded>
			<wfw:commentRss>http://therning.org/magnus/archives/914/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>On maintaining Haskell packages for a Linux distro</title>
		<link>http://therning.org/magnus/archives/897</link>
		<comments>http://therning.org/magnus/archives/897#comments</comments>
		<pubDate>Mon, 24 Jan 2011 22:30:37 +0000</pubDate>
		<dc:creator>Magnus</dc:creator>
				<category><![CDATA[Posts]]></category>
		<category><![CDATA[arch]]></category>
		<category><![CDATA[cabal]]></category>
		<category><![CDATA[haskell]]></category>

		<guid isPermaLink="false">http://therning.org/magnus/?p=897</guid>
		<description><![CDATA[When trying to maintain set of binary packages of Haskell libraries for a Linux distribution there are a few issues that come up: The set of packages must be compilable at all times, and Updating one package requires all packages that depend on it, in one or more steps, to be re-compiled. The first requires [...]]]></description>
			<content:encoded><![CDATA[<p>When trying to maintain set of binary packages of Haskell libraries for a
Linux distribution there are a few issues that come up:</p>

<ol>
<li>The set of packages must be compilable at all times, and</li>
<li>Updating one package requires all packages that depend on it, in one or
more steps, to be re-compiled.</li>
</ol>

<p>The first requires keeping track of all dependencies of the packages in the
set and making sure that they are satisfiable at all times.  For a while I was
doing this by simple attempting to compile all updated packages and check for
breakages.  Which was both time-consuming and a painful when build-failures
had to be resolved.</p>

<p>The second requires bumping the package release number for all packages that
are reachable when following the dependencies in the reverse direction.  Doing
this manually is tedious and very error prone in my experience.</p>

<p>Of course it ought to be possible to make this a lot easier with the help of a
tool.  The last few days I&#8217;ve been writing such a tool.  This is how I&#8217;ve been
using it so far.</p>

<h3>Building the initial database</h3>

<p>GHC in ArchLinux ships with a few Haskell libraries and ArchLinux also has a
few Haskell packages in its base repositories.  Since I don&#8217;t need to maintain
any of those packages I decided to treat these as a sort of base.  Adding
those is as simple as this:</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">%</span> <span style="color: #c20cb9; font-weight: bold;">head</span> base-pkgs
base,4.2.0.2
array,0.3.0.1
bytestring,0.9.1.7
Cabal,1.8.0.6
containers,0.3.0.0
directory,1.0.1.1
extensible-exceptions,0.1.1.1
filepath,1.1.0.4
haskell98,1.0.1.1
hpc,0.5.0.5
<span style="color: #000000; font-weight: bold;">%</span> cblrepo addbasepkg $<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">cat</span> base-pkgs<span style="color: #7a0874; font-weight: bold;">&#41;</span>
Success</pre></div></div>


<p>Then I need to add the packages of the binary repo provided by ArchHaskell.  I
wrote a little script that extracts the package name and version from the
ArchHaskell HABS tree (<code>get-ah-cabals</code>):</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#! /bin/bash</span>
&nbsp;
<span style="color: #007800;">habsdir</span>=<span style="color: #007800;">$1</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">for</span> d <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #800000;">${habsdir}</span><span style="color: #000000; font-weight: bold;">/</span>habs<span style="color: #000000; font-weight: bold;">/*</span>; <span style="color: #000000; font-weight: bold;">do</span>
    . <span style="color: #800000;">${d}</span><span style="color: #000000; font-weight: bold;">/</span>PKGBUILD
    <span style="color: #000000; font-weight: bold;">case</span> <span style="color: #007800;">$_hkgname</span> <span style="color: #000000; font-weight: bold;">in</span>
        <span style="color: #7a0874; font-weight: bold;">&#40;</span>datetime<span style="color: #000000; font-weight: bold;">|</span>haskell-platform<span style="color: #7a0874; font-weight: bold;">&#41;</span>
            <span style="color: #000000; font-weight: bold;">;;</span>
        <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
            <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #800000;">${_hkgname}</span>,<span style="color: #800000;">${pkgver}</span>
            <span style="color: #000000; font-weight: bold;">;;</span>
    <span style="color: #000000; font-weight: bold;">esac</span>
<span style="color: #000000; font-weight: bold;">done</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">echo</span> http:<span style="color: #000000; font-weight: bold;">//</span>hackage.haskell.org<span style="color: #000000; font-weight: bold;">/</span>platform<span style="color: #000000; font-weight: bold;">/</span>2010.2.0.0<span style="color: #000000; font-weight: bold;">/</span>haskell-platform.cabal</pre></div></div>


<p>Since <code>haskell-platform</code> isn&#8217;t on Hackage it requires special handling.  The
reason why <code>datetime</code> is excluded is slightly different.  It&#8217;s the only package
that requires old <code>base</code> (version <code>&lt;4</code>).  <code>GHC</code> in Arch does whip with both
old and new <code>base</code> so <code>datetime</code> can be built, but <code>cblrepo</code> can&#8217;t deal with
two versions of the same package.  This is a limitation, but I&#8217;m not sure it&#8217;s
worth fixing it since <code>base</code> is the only library that comes in two versions,
and <code>datetime</code> is the only package that hasn&#8217;t been updated to use new <code>base</code>.</p>

<p>Knowing this it&#8217;s easy to add all the ArchHaskell packages to the database:</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">%</span> cblrepo idxupdate
<span style="color: #000000; font-weight: bold;">%</span> cblrepo add $<span style="color: #7a0874; font-weight: bold;">&#40;</span>get-ah-cabals path<span style="color: #000000; font-weight: bold;">/</span>to<span style="color: #000000; font-weight: bold;">/</span>habs<span style="color: #7a0874; font-weight: bold;">&#41;</span>
Success</pre></div></div>


<h3>Attempting an update</h3>

<p>Now it&#8217;s possible to attempt to attempt an update:</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">%</span> cblrepo add neither,0.2.0
Failed to satisfy the following dependencies <span style="color: #000000; font-weight: bold;">for</span> neither:
  monad-peel <span style="color: #000000; font-weight: bold;">&gt;</span>=<span style="color: #000000;">0.1</span> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #000000; font-weight: bold;">&lt;</span><span style="color: #000000;">0.2</span>
Adding neither 0.2.0 would <span style="color: #7a0874; font-weight: bold;">break</span>:
  yesod : neither <span style="color: #000000; font-weight: bold;">&gt;</span>=0.1.0 <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #000000; font-weight: bold;">&lt;</span><span style="color: #000000;">0.2</span>
  persistent : neither <span style="color: #000000; font-weight: bold;">&gt;</span>=<span style="color: #000000;">0.1</span> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #000000; font-weight: bold;">&lt;</span><span style="color: #000000;">0.2</span></pre></div></div>


<p>The way to read this is that there first of all is a missing dependency to
satisfy for <code>neither</code> itself, and second there are two packages, <code>yesod</code> and
<code>persistent</code>, that wouldn&#8217;t be buildable if <code>neither</code> were updated.</p>

<p>Now if it were possible to update <code>neither</code>, what packages would require a
bump?</p>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">%</span> cblrepo bump neither     
persistent
yesod</pre></div></div>

<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Ftherning.org%2Fmagnus%2Farchives%2F897&amp;title=On%20maintaining%20Haskell%20packages%20for%20a%20Linux%20distro" id="wpa2a_4">Share/Bookmark</a></p>]]></content:encoded>
			<wfw:commentRss>http://therning.org/magnus/archives/897/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Even more Cabal fun, visualising in 3d</title>
		<link>http://therning.org/magnus/archives/543</link>
		<comments>http://therning.org/magnus/archives/543#comments</comments>
		<pubDate>Fri, 27 Feb 2009 22:43:10 +0000</pubDate>
		<dc:creator>Magnus</dc:creator>
				<category><![CDATA[Posts]]></category>
		<category><![CDATA[cabal]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[ubigraph]]></category>

		<guid isPermaLink="false">http://therning.org/magnus/?p=543</guid>
		<description><![CDATA[avsm pointed me to ubigraph. So after a bit of XML-RPC hacking (haxr really rocks, it is just so amazingly easy to use) I now have code that sends the graph data over to a ubigraph server. Of course I had to create a video of it. The video shows the dependencies of just two [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://twitter.com/avsm">avsm</a> pointed me to <a href="http://ubietylab.net/ubigraph/">ubigraph</a>.  So after a bit of XML-RPC hacking (<a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/haxr">haxr</a> <em>really</em> rocks, it is just so amazingly easy to use) I now have code that sends the graph data over to a ubigraph server.</p>

<p>Of course I had to create a video of it.  The <a href="http://therning.org/magnus_files/cabal-deps-ubigraph-01.mpeg">video</a> shows the dependencies of just two packages (<a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/dataenc">dataenc</a> and <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/datetime">datetime</a>).  I tried creating a second video of the dependencies of more packages, but xvidcap isn&#8217;t very reliable it seems.  One irritating thing is that I run out of filehandles fairly soon, so I couldn&#8217;t create a 3d graph of more than about 75 packages (all packages starting with &#8216;a&#8217; and &#8216;b&#8217; on Hackage).</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Ftherning.org%2Fmagnus%2Farchives%2F543&amp;title=Even%20more%20Cabal%20fun%2C%20visualising%20in%203d" id="wpa2a_6">Share/Bookmark</a></p>]]></content:encoded>
			<wfw:commentRss>http://therning.org/magnus/archives/543/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
<enclosure url="http://therning.org/magnus_files/cabal-deps-ubigraph-01.mpeg" length="2423630" type="video/mpeg" />
		</item>
		<item>
		<title>More fun with Cabal, visualising dependencies</title>
		<link>http://therning.org/magnus/archives/534</link>
		<comments>http://therning.org/magnus/archives/534#comments</comments>
		<pubDate>Fri, 27 Feb 2009 14:54:34 +0000</pubDate>
		<dc:creator>Magnus</dc:creator>
				<category><![CDATA[Posts]]></category>
		<category><![CDATA[cabal]]></category>
		<category><![CDATA[haskell]]></category>

		<guid isPermaLink="false">http://therning.org/magnus/?p=534</guid>
		<description><![CDATA[It wasn&#8217;t why I started playing with Cabal, but after extracting dependencies from a single package I thought struck me that I could extract dependencies from many packages, e.g. hackage, and draw a dependency graph of the result. The basic idea is to use the code from my earlier post, accumulate dependency information by mapping [...]]]></description>
			<content:encoded><![CDATA[<p>It wasn&#8217;t why I started playing with Cabal, but after <a href="http://therning.org/magnus/archives/514">extracting dependencies from a single package</a> I thought struck me that I could extract dependencies from many packages, e.g. <a href="http://hackage.haskell.org/packages/hackage.html">hackage</a>, and draw a dependency graph of the result.</p>

<p>The basic idea is to use the code from my earlier post, accumulate dependency information by mapping it over several cabal files.  Then convert that information into nodes and edges suitable for building a graph (<code>Data.Graph</code>).  That graph is then &#8220;graphviz&#8217;ed&#8221; using <code>Data.Graph.Inductive.Graphviz</code>.  Not that since this is performed on Debian Sid I&#8217;m using some rather old versions of packages<sup><a href="http://therning.org/magnus/archives/534#footnote_0_534" id="identifier_0_534" class="footnote-link footnote-identifier-link" title="Yes, I&amp;#8217;d be really happy if the transition to GHC 6.10 would finish soon.">i</a></sup>.</p>

<p>First off a shortcut for reading cabal files:</p>


<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;">readCabalFile <span style="color: #339933; font-weight: bold;">=</span> readPackageDescription silent</pre></div></div>


<p>Once I have a <code>GenericPackageDescription</code> I want to collapse it into a regular <code>PackageDescription</code> (see the comments in my previous post for some details regarding this).  Then I extract the package name and its dependencies and package them into a tuple.  by mapping this function over a list of <code>GenericPackageDescription</code> I end up with an association list where the key is the package and the value is a list of all its dependencies.</p>


<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;">processFile gpd <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">let</span>
        finPkgDesc <span style="color: #339933; font-weight: bold;">=</span> finalizePackageDescription <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span> Nothing
            <span style="background-color: #3cb371;">&quot;Linux&quot;</span> <span style="background-color: #3cb371;">&quot;X86_64&quot;</span> <span style="color: green;">&#40;</span><span style="background-color: #3cb371;">&quot;GHC&quot;</span><span style="color: #339933; font-weight: bold;">,</span> Version <span style="color: green;">&#91;</span><span style="color: red;">6</span><span style="color: #339933; font-weight: bold;">,</span> <span style="color: red;">8</span><span style="color: #339933; font-weight: bold;">,</span> <span style="color: red;">2</span><span style="color: green;">&#93;</span> <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span><span style="color: green;">&#41;</span>
        <span style="color: green;">&#40;</span>Right <span style="color: green;">&#40;</span>pd<span style="color: #339933; font-weight: bold;">,</span> <span style="color: #339933; font-weight: bold;">_</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=</span> finPkgDesc gpd
        getPackageName <span style="color: green;">&#40;</span>Dependency name <span style="color: #339933; font-weight: bold;">_</span><span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=</span> name
        nameNDeps <span style="color: #339933; font-weight: bold;">=</span> <span style="color: green;">&#40;</span>pkgName <span style="color: #339933; font-weight: bold;">.</span> package<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">&amp;&amp;</span>&amp; <span style="color: green;">&#40;</span>nub <span style="color: #339933; font-weight: bold;">.</span> <span style="font-weight: bold;">map</span> getPackageName <span style="color: #339933; font-weight: bold;">.</span> buildDepends<span style="color: green;">&#41;</span>
    <span style="color: #06c; font-weight: bold;">in</span>
        nameNDeps pd</pre></div></div>


<p>In order to create the graph later on I need a complete list of all nodes.  To do this I take all the keys and all the values in the association list, collapse them into a single list, and remove duplicates.  To turn this resulting list of packages into a list of <code>LNode</code> I then <code>zip</code> it with a list of integers.</p>


<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;">getNodes <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">let</span>
        assocKeys <span style="color: #339933; font-weight: bold;">=</span> <span style="font-weight: bold;">map</span> <span style="font-weight: bold;">fst</span>
        assocVals <span style="color: #339933; font-weight: bold;">=</span> <span style="font-weight: bold;">concat</span> <span style="color: #339933; font-weight: bold;">.</span> <span style="font-weight: bold;">map</span> <span style="font-weight: bold;">snd</span>
    <span style="color: #06c; font-weight: bold;">in</span> <span style="font-weight: bold;">zip</span> <span style="color: green;">&#91;</span><span style="color: red;">1</span><span style="color: #339933; font-weight: bold;">..</span><span style="color: green;">&#93;</span> <span style="color: #339933; font-weight: bold;">.</span> nub <span style="color: #339933; font-weight: bold;">.</span> <span style="font-weight: bold;">uncurry</span> <span style="color: green;">&#40;</span><span style="color: #339933; font-weight: bold;">++</span><span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#40;</span>assocKeys <span style="color: #339933; font-weight: bold;">&amp;&amp;</span>&amp; assocVals<span style="color: green;">&#41;</span></pre></div></div>


<p>Building the edges is straight forward, but a bit more involved.  An edge is a tuple of two integers and something else, I don&#8217;t need to label the edges so in my case it is <code>(Int, Int, ())</code>.  The list of nodes is basically an association list (an integer for key and a string for value), but I need to flip keys and values since I know the package name and need its node number.</p>


<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;">getEdges deps <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">let</span>
        nodes <span style="color: #339933; font-weight: bold;">=</span> getNodes deps
        nodesAssoc <span style="color: #339933; font-weight: bold;">=</span> <span style="font-weight: bold;">map</span> <span style="color: green;">&#40;</span>\ <span style="color: green;">&#40;</span>a<span style="color: #339933; font-weight: bold;">,</span> b<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: green;">&#40;</span>b<span style="color: #339933; font-weight: bold;">,</span> a<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> nodes
        buildEdges <span style="color: green;">&#40;</span>name<span style="color: #339933; font-weight: bold;">,</span> dep<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">let</span>
                getNode n <span style="color: #339933; font-weight: bold;">=</span> fromJust <span style="color: #339933; font-weight: bold;">$</span> <span style="font-weight: bold;">lookup</span> n nodesAssoc
                fromNode <span style="color: #339933; font-weight: bold;">=</span> getNode name
            <span style="color: #06c; font-weight: bold;">in</span> <span style="font-weight: bold;">map</span> <span style="color: green;">&#40;</span>\ t <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: green;">&#40;</span>fromNode<span style="color: #339933; font-weight: bold;">,</span> getNode t<span style="color: #339933; font-weight: bold;">,</span> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> dep
    <span style="color: #06c; font-weight: bold;">in</span> <span style="font-weight: bold;">concat</span> <span style="color: #339933; font-weight: bold;">$</span> <span style="font-weight: bold;">map</span> buildEdges deps</pre></div></div>


<p>Now that that&#8217;s done I can put it all together in a <code>main</code> function.  The trickiest bit of that was to find the size of A4 in incehs <img src='http://therning.org/magnus/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>


<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;">main <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span>
    files <span style="color: #339933; font-weight: bold;">&lt;-</span> getArgs
    gpds <span style="color: #339933; font-weight: bold;">&lt;-</span> <span style="font-weight: bold;">mapM</span> readCabalFile files
    <span style="color: #06c; font-weight: bold;">let</span> deps <span style="color: #339933; font-weight: bold;">=</span> <span style="font-weight: bold;">map</span> processFile gpds
    <span style="color: #06c; font-weight: bold;">let</span> <span style="color: green;">&#40;</span>nodes<span style="color: #339933; font-weight: bold;">,</span> edges<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=</span> <span style="color: green;">&#40;</span>getNodes <span style="color: #339933; font-weight: bold;">&amp;&amp;</span>&amp; getEdges<span style="color: green;">&#41;</span> deps
    <span style="color: #06c; font-weight: bold;">let</span> depGraph <span style="color: #339933; font-weight: bold;">=</span> mkGraph nodes edges <span style="color: #339933; font-weight: bold;">::</span> Gr <span style="color: #cccc00; font-weight: bold;">String</span> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span>
    <span style="font-weight: bold;">putStrLn</span> <span style="color: #339933; font-weight: bold;">$</span> graphviz depGraph <span style="background-color: #3cb371;">&quot;Dependency_Graph&quot;</span> <span style="color: green;">&#40;</span><span style="color: red;">11.7</span><span style="color: #339933; font-weight: bold;">,</span> <span style="color: red;">16.5</span><span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span><span style="color: red;">1</span><span style="color: #339933; font-weight: bold;">,</span><span style="color: red;">1</span><span style="color: green;">&#41;</span> Landscape</pre></div></div>


<p>I downloaded all cabal files from Hackage and ran this code over them.  I bumped into a few that use Cabal features not supported in the ancient version I&#8217;m using.  I was a bit disappointed that Cabal wouldn&#8217;t let me handle that kind of errors myself (as I already expressed in an <a href="http://therning.org/magnus/archives/523">earlier post</a>) so I was forced to delete them manually.</p>

<p><a href="http://therning.org/magnus_files/hackage_deps.ps">Here&#8217;s the output</a>, completely unreadable, I know, but still sort of cool.</p>
<ol class="footnotes"><li id="footnote_0_534" class="footnote">Yes, I&#8217;d be really happy if the transition to GHC 6.10 would finish soon.</li></ol><p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Ftherning.org%2Fmagnus%2Farchives%2F534&amp;title=More%20fun%20with%20Cabal%2C%20visualising%20dependencies" id="wpa2a_8">Share/Bookmark</a></p>]]></content:encoded>
			<wfw:commentRss>http://therning.org/magnus/archives/534/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A no-no in my book (found in Cabal)</title>
		<link>http://therning.org/magnus/archives/523</link>
		<comments>http://therning.org/magnus/archives/523#comments</comments>
		<pubDate>Fri, 27 Feb 2009 09:52:38 +0000</pubDate>
		<dc:creator>Magnus</dc:creator>
				<category><![CDATA[Posts]]></category>
		<category><![CDATA[cabal]]></category>
		<category><![CDATA[haskell]]></category>

		<guid isPermaLink="false">http://therning.org/magnus/?p=523</guid>
		<description><![CDATA[A recent &#8220;find&#8221; in Cabal made me think of this: In my opinion the final decision of what to do in case of an error belongs in the appliation, not in libraries. I&#8217;m sure there are exceptions to this, but I believe it&#8217;s good as a guiding principle when defining APIs. Here&#8217;s the code in [...]]]></description>
			<content:encoded><![CDATA[<p>A recent &#8220;find&#8221; in Cabal made me think of this:</p>

<blockquote>
  <p>In my opinion the final decision of what to do in case of an error belongs in the appliation, not in libraries.</p>
</blockquote>

<p>I&#8217;m sure there are exceptions to this, but I believe it&#8217;s good as a guiding principle when defining APIs.</p>

<p>Here&#8217;s the <a href="http://hackage.haskell.org/packages/archive/Cabal/1.6.0.2/doc/html/src/Distribution-PackageDescription-Parse.html#readAndParseFile">code in Cabal</a> that breaks this rule.  Basically, if you write an application and call <code>readPackageDescription</code> on a cabal file with errors then your application is terminated (the call to <a href="http://hackage.haskell.org/packages/archive/Cabal/1.6.0.2/doc/html/src/Distribution-Simple-Utils.html#dieWithLocation"><code>dieWithLocation</code></a> ends up calling <code>exitWith</code>).  I would much rather it returned an error (e.g. based on <code>Either</code>) so I can decide what to do with bad cabal files myself.</p>

<p>I&#8217;ve raised a <a href="http://hackage.haskell.org/trac/hackage/ticket/510">ticket</a> for it of course <img src='http://therning.org/magnus/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Ftherning.org%2Fmagnus%2Farchives%2F523&amp;title=A%20no-no%20in%20my%20book%20%28found%20in%20Cabal%29" id="wpa2a_10">Share/Bookmark</a></p>]]></content:encoded>
			<wfw:commentRss>http://therning.org/magnus/archives/523/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Simple Cabal parsing</title>
		<link>http://therning.org/magnus/archives/514</link>
		<comments>http://therning.org/magnus/archives/514#comments</comments>
		<pubDate>Tue, 24 Feb 2009 22:19:49 +0000</pubDate>
		<dc:creator>Magnus</dc:creator>
				<category><![CDATA[Posts]]></category>
		<category><![CDATA[cabal]]></category>
		<category><![CDATA[haskell]]></category>

		<guid isPermaLink="false">http://therning.org/magnus/?p=514</guid>
		<description><![CDATA[This is going to be a silly post, simply because it is so amazingly simple to do some basic parsing of Cabal files. It turns out to be true even for old versions of Cabal, the code below is for 1.2.3.0 since that&#8217;s the version still found in Debian Unstablei First import the required modules: [...]]]></description>
			<content:encoded><![CDATA[<p>This is going to be a silly post, simply because it is so amazingly simple to do some basic parsing of Cabal files.  It turns out to be true even for old versions of Cabal, the code below is for 1.2.3.0 since that&#8217;s the version still found in Debian Unstable<sup><a href="http://therning.org/magnus/archives/514#footnote_0_514" id="identifier_0_514" class="footnote-link footnote-identifier-link" title="That&amp;#8217;ll change when GHC 6.10 makes it onto my system.  It&amp;#8217;s already in Debian, just not on my system since some Xmonad-related packages haven&amp;#8217;t been rebuilt yet.">i</a></sup></p>

<p>First import the required modules:</p>


<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">import</span> Distribution<span style="color: #339933; font-weight: bold;">.</span>PackageDescription
<span style="color: #06c; font-weight: bold;">import</span> Data<span style="color: #339933; font-weight: bold;">.</span>Version
<span style="color: #06c; font-weight: bold;">import</span> Distribution<span style="color: #339933; font-weight: bold;">.</span>Verbosity
<span style="color: #06c; font-weight: bold;">import</span> Distribution<span style="color: #339933; font-weight: bold;">.</span>Version</pre></div></div>


<p>The a simplistic shortcut, I don&#8217;t care about setting flags or pretty much anything else</p>


<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;">finPkgDesc <span style="color: #339933; font-weight: bold;">=</span> finalizePackageDescription <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span> Nothing <span style="background-color: #3cb371;">&quot;Linux&quot;</span> <span style="background-color: #3cb371;">&quot;X86_64&quot;</span> <span style="color: green;">&#40;</span><span style="background-color: #3cb371;">&quot;GHC&quot;</span><span style="color: #339933; font-weight: bold;">,</span> Version <span style="color: green;">&#91;</span><span style="color: red;">6</span><span style="color: #339933; font-weight: bold;">,</span> <span style="color: red;">8</span><span style="color: #339933; font-weight: bold;">,</span> <span style="color: red;">2</span><span style="color: green;">&#93;</span> <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span><span style="color: green;">&#41;</span></pre></div></div>


<p>and I&#8217;m only interested in listing the package names of dependencies</p>


<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;">getPackageName <span style="color: green;">&#40;</span>Dependency name <span style="color: #339933; font-weight: bold;">_</span><span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=</span> name</pre></div></div>


<p>After this it&#8217;s possible to do the following in <code>ghci</code> (<code>ex01.cabal</code> is a copy of the Cabal file for <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/dataenc">dataenc</a>):</p>


<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"><span style="color: #339933; font-weight: bold;">&gt;</span> gpd <span style="color: #339933; font-weight: bold;">&lt;-</span> readPackageDescription silent <span style="background-color: #3cb371;">&quot;ex01.cabal&quot;</span>
<span style="color: #339933; font-weight: bold;">...</span>
<span style="color: #339933; font-weight: bold;">&gt;</span> <span style="color: #06c; font-weight: bold;">let</span> pd <span style="color: #339933; font-weight: bold;">=</span> finPkgDesc gpd
<span style="color: #339933; font-weight: bold;">&gt;</span> <span style="color: #06c; font-weight: bold;">let</span> deps <span style="color: #339933; font-weight: bold;">=</span> <span style="font-weight: bold;">either</span> <span style="color: green;">&#40;</span>\<span style="color: #339933; font-weight: bold;">_</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span><span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>\ <span style="color: green;">&#40;</span>p<span style="color: #339933; font-weight: bold;">,</span> <span style="color: #339933; font-weight: bold;">_</span><span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> buildDepends p<span style="color: green;">&#41;</span> pd
<span style="color: #339933; font-weight: bold;">&gt;</span> <span style="font-weight: bold;">map</span> getPackageName deps
<span style="color: green;">&#91;</span><span style="background-color: #3cb371;">&quot;array&quot;</span><span style="color: #339933; font-weight: bold;">,</span><span style="background-color: #3cb371;">&quot;base&quot;</span><span style="color: #339933; font-weight: bold;">,</span><span style="background-color: #3cb371;">&quot;containers&quot;</span><span style="color: green;">&#93;</span></pre></div></div>

<ol class="footnotes"><li id="footnote_0_514" class="footnote">That&#8217;ll change when GHC 6.10 makes it onto my system.  It&#8217;s already in Debian, just not on my system since some Xmonad-related packages haven&#8217;t been rebuilt yet.</li></ol><p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Ftherning.org%2Fmagnus%2Farchives%2F514&amp;title=Simple%20Cabal%20parsing" id="wpa2a_12">Share/Bookmark</a></p>]]></content:encoded>
			<wfw:commentRss>http://therning.org/magnus/archives/514/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Experience with cabal-debian</title>
		<link>http://therning.org/magnus/archives/476</link>
		<comments>http://therning.org/magnus/archives/476#comments</comments>
		<pubDate>Wed, 21 Jan 2009 23:54:10 +0000</pubDate>
		<dc:creator>Magnus</dc:creator>
				<category><![CDATA[Posts]]></category>
		<category><![CDATA[cabal]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[haskell]]></category>

		<guid isPermaLink="false">http://therning.org/magnus/?p=476</guid>
		<description><![CDATA[So, after receiving several pointers to seereason&#8217;s cabal-debian tool I thought I&#8217;d take it for a spin.i After about 30 minutes of browsing through HackageDB and seereason&#8217;s source repos, building and installing, I had finally satisfied all dependencies and the build of cabal-debian succeeded. (Oh, BTW, seereason people, it&#8217;s really confusing that you have a [...]]]></description>
			<content:encoded><![CDATA[<p>So, after receiving several pointers to seereason&#8217;s <a href="http://src.seereason.com/cabal-debian/">cabal-debian tool</a> I thought I&#8217;d take it for a spin.<sup><a href="http://therning.org/magnus/archives/476#footnote_0_476" id="identifier_0_476" class="footnote-link footnote-identifier-link" title="I did pull down autobuilder as well, but didn&amp;#8217;t feel I had enough time to explore it tonight.">i</a></sup></p>

<p>After about 30 minutes of browsing through HackageDB and seereason&#8217;s source repos, building and installing, I had finally satisfied all dependencies and the build of <code>cabal-debian</code> succeeded.  (Oh, BTW, seereason people, it&#8217;s really confusing that you have a package called <em>debian</em> among your source repos, when there already is a different <em>debian</em> package on HackageDB.  Please consider renaming it!)  I decided to take the tool for a spin on my own package, <em>dataenc</em>.</p>

<p>The result was fairly good.  It seems the generated files depend on some packages that either aren&#8217;t in Debian or that the people at seereason have modified.  With the following changes to the generated files I was happy with the contents of <code>./debian</code> and I successfully built an (almost) autogenerated Debian package:</p>

<ol>
<li>Download <a href="http://people.debian.org/~kaol/repos/hlibrary/hlibrary.mk">hlibrary.mk</a> into <code>./debian</code>.</li>
<li>Modify <code>./debian/rules</code> so that <code>hlibrary.mk</code> is loaded from <code>$(CURDIR)/debian/hlibrary.mk</code>.</li>
<li>Delete <code>./debian/libghc6-dataenc-doc.post*</code>.</li>
<li>Remove <code>cabal-debian</code> and <code>haskell-devscripts-cdbs</code> from the build dependencies in <code>./debian/control</code>.</li>
</ol>

<p>I&#8217;ll try to find the time to put those changes into <code>cabal-debian</code> itself.  Then I&#8217;d have a rather nice tool for building Debian packages automatically.</p>
<ol class="footnotes"><li id="footnote_0_476" class="footnote">I did pull down <a href="http://src.seereason.com/autobuilder/">autobuilder</a> as well, but didn&#8217;t feel I had enough time to explore it tonight.</li></ol><p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Ftherning.org%2Fmagnus%2Farchives%2F476&amp;title=Experience%20with%20cabal-debian" id="wpa2a_14">Share/Bookmark</a></p>]]></content:encoded>
			<wfw:commentRss>http://therning.org/magnus/archives/476/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>C and Haskell sitting in a tree&#8230;</title>
		<link>http://therning.org/magnus/archives/238</link>
		<comments>http://therning.org/magnus/archives/238#comments</comments>
		<pubDate>Fri, 08 Dec 2006 08:48:30 +0000</pubDate>
		<dc:creator>Magnus</dc:creator>
				<category><![CDATA[Posts]]></category>
		<category><![CDATA[c2hs]]></category>
		<category><![CDATA[cabal]]></category>
		<category><![CDATA[haskell]]></category>

		<guid isPermaLink="false">http://therning.org/magnus/archives/238</guid>
		<description><![CDATA[A few days ago I thougth I&#8217;d take a look at calling C functions from haskell. I wrote up the following set of files: foo.h: int foo(int i); foo.c: int foo(int i) { return i * i; } Foo.hs: module Main where import Foreign.C.Types main = do r &#60;- foo 2 putStrLn $ show r [...]]]></description>
			<content:encoded><![CDATA[<p>A few days ago I thougth I&#8217;d take a look at calling C functions from haskell. I wrote up the following set of files:</p>

<p><em>foo.h</em>:</p>

<pre><code>int foo(int i);
</code></pre>

<p><em>foo.c</em>:</p>

<pre><code>int
foo(int i)
{
    return i * i;
}
</code></pre>

<p><em>Foo.hs</em>:</p>

<pre><code>module Main where

import Foreign.C.Types

main = do
    r &lt;- foo 2
    putStrLn $ show r

foreign import ccall safe "foo.h foo" foo :: CInt -&gt; IO CInt
</code></pre>

<p>Compiling the C file was of course no problem:</p>

<pre><code>% gcc -c foo.c
</code></pre>

<p>The haskell file offered some resistance:</p>

<pre><code>% ghc -c Foo.hs
Foo.hs:9:8: parse error on input `import'
</code></pre>

<p>It took me a round on <em>haskell-cafe</em> before I found out that <em>ghc</em> needs to be told to use the <em>foreign function interface</em>, <code>-ffi</code> or <code>-fffi</code>:</p>

<pre><code>% ghc -c -fffi Foo.hs
</code></pre>

<p>Linking is a snap after that:</p>

<pre><code>% ghc -o foo foo.o Foo.o
% ./foo
4
</code></pre>

<p>It&#8217;s also possible to build and link it all in one go:</p>

<pre><code>% ghc --make -fffi -o foo foo.c Foo.hs
</code></pre>

<p>Now, that&#8217;s pretty nice, however it&#8217;d be even nicer to use <a href="http://www.haskell.org/ghc/docs/latest/html/Cabal/">cabal</a> to do the building. At the same time I decided to put <a href="http://www.cse.unsw.edu.au/~chak/haskell/c2hs/">c2hs</a> to use. It seemed to be a lot easier than having to create the <em>import</em> statements manually. I ended up with the following:</p>

<p><em>csrc/foo.h</em>:</p>

<pre><code>#ifndef _FOO_H_

int foo(int);

#endif
</code></pre>

<p><em>csrc/foo.c</em>:</p>

<pre><code>#include "foo.h"

int
foo(int i)
{
    return i * i;
}
</code></pre>

<p>I couldn&#8217;t get cabal to accept <em>Foo.chs</em> as the file containing the <em>Main</em> module in my project. So I ended up putting all the relevant code in <em>Foo</em> and then have a dummy <em>Main</em>.</p>

<p><em>src/Foo.chs</em>:</p>

<pre><code>module Foo where

#include "foo.h"

import Foreign.C.Types

main = do
    r &lt;- {# call foo #} 2
    putStrLn $ show r
</code></pre>

<p>Here&#8217;s the dummy <em>Main</em>.</p>

<p><em>src/Main.hs</em>:</p>

<pre><code>module Main where

import qualified Foo

main = Foo.main
</code></pre>

<p>The cabal file is rather straight forward. It took me a round on <em>haskell-cafe</em> to find out how to let the compiler know that I need the foreign function interface without putting compiler directives in the source file.</p>

<p><em>cnh.cabal</em>:</p>

<pre><code>name: cnh
version: 0.1
build-depends: base

executable: cnh
main-is: Main.hs
hs-source-dirs: src
include-dirs: csrc
c-sources: csrc/foo.c
extensions: ForeignFunctionInterface
other-modules: Foo
</code></pre>

<p>Nothing special is needed in the <em>Setup.hs</em>:</p>

<pre><code>#! /usr/bin/env runhaskell

import Distribution.Simple
main = defaultMain
</code></pre>

<p>Make it executable and you can build in two easy steps:</p>

<pre><code>% ./Setup.hs configure &amp;&amp; ./Setup.hs build
</code></pre>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Ftherning.org%2Fmagnus%2Farchives%2F238&amp;title=C%20and%20Haskell%20sitting%20in%20a%20tree%26%238230%3B" id="wpa2a_16">Share/Bookmark</a></p>]]></content:encoded>
			<wfw:commentRss>http://therning.org/magnus/archives/238/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

