Listing package dependencies from GHC

If I'm doing development between ghci and vim, all the different dependencies I need get linked in when required without me asking. Similarly if I call "ghc --make" from the command line. But I have to write them in manually to my *.cabal file otherwise the compilation process will fail. Until now I've just loaded the program in to ghci and noted down all the dependencies it links in. Am I missing a trick? There must be an easier way, especially for multiple source files. cheers, D.

If I'm doing development between ghci and vim, all the different dependencies I need get linked in when required without me asking. Similarly if I call "ghc --make" from the command line. But I have to write them in manually to my *.cabal file otherwise the compilation process will fail.
Until now I've just loaded the program in to ghci and noted down all the dependencies it links in. Am I missing a trick? There must be an easier way, especially for multiple source files.
I once used this perl script to determine the files I was actually used (to have proper LOC stats). It uses ghc -M which usually outputs the dependencies as makefile targets, and then grep over this to get all the .hs files. If you have different file types you might want to modify this: #!/usr/bin/env perl # Prints the .hs files that are actually used to STDOUT $tmpfile = '/tmp/deps'; $mainfile = 'Foo.hs'; $ghc_deps = `ghc -M $mainfile -optdep-f -optdep$tmpfile`; die "ghc -M failed\n" if $? != 0; open(INF, "< $tmpfile") || die "Could not open $tempfile\n"; @files = (); while (<INF>) { m/(\w+\.hs)/; push(@files, $1); } close (INF); undef %saw; @nodups = grep(!$saw{$_}++, @files); # remove duplictes print join(' ',@nodups), "\n";

On 03/05/07, Thomas Schilling
I once used this perl script to determine the files I was actually used (to have proper LOC stats). It uses ghc -M which usually outputs the dependencies as makefile targets, and then grep over this to get all the .hs files. If you have different file types you might want to modify this:
Sorry, maybe I didn't express myself properly. By dependencies I meant, library packages that GHC knows about. For example, if I load something simple like
import System.Posix.Files main = touchFile "example"
into GHCi and execute ":main" it prints
Loading package unix-1.0 ... linking ... done.
But if I try the same by compiling with a ./Setup build (ie cabal) the build system complains that it "could not find X, it is a member of unix". My problem is that the only way I can get from a template cabal file to a fully working one is by iteration - add dependency to "Build-depends", recompile, fail, repeat. It's obvious GHC knows how to find all the right dependencies. It does it in GHCi. It can even be done from the command line with "--make". But can I get it to *tell* me the information that cabal needs? Cheers, Dougal.

By dependencies I meant, library packages that GHC knows about.
For example, if I load something simple like
import System.Posix.Files main = touchFile "example"
into GHCi and execute ":main" it prints
Loading package unix-1.0 ... linking ... done.
Oh, right. Well, then please file it as a bug report on Cabal. I'll be working on Cabal configs as my Summer of Code project; this is clearly related. With a bit of luck it'll be done before end of August. / Thomas

On 03/05/07, Thomas Schilling
Oh, right. Well, then please file it as a bug report on Cabal. I'll be working on Cabal configs as my Summer of Code project; this is clearly related. With a bit of luck it'll be done before end of August.
Okay. It seemed like a feature, but just one that made things more difficult than they could be. D.

On Thu, 2007-05-03 at 16:49 +0200, Thomas Schilling wrote:
By dependencies I meant, library packages that GHC knows about.
For example, if I load something simple like
import System.Posix.Files main = touchFile "example"
into GHCi and execute ":main" it prints
Loading package unix-1.0 ... linking ... done.
Oh, right. Well, then please file it as a bug report on Cabal. I'll be working on Cabal configs as my Summer of Code project; this is clearly related. With a bit of luck it'll be done before end of August.
This is not a Cabal bug. By design, Cabal does not just pick up any packages from the environment like --make does. One of the main points of Cabal is to be able to explicitly track dependencies of a package, so we do require that they all be listed explicitly. Cabal then tells ghc to *only* look in those listed packages and ignore all others even if they happen to be installed. Now certainly it would be nicer if ghc+cabal could be more helpful and tell you all the missing packages that you need to list in the "build-depends" field in the .cabal file, rather than currently where you have to do it one by one. This feature could be implemented in GHC, or it could actually be implemented in Cabal. To do it in cabal requires that cabal gain an infrastructure for doing dependency analysis of modules. We don't have that yet. We do need this infrastructure anyway though, since for example some pre-processors (notably c2hs) need to be called in dependency order. It would also allow other nice things like having cabal work out for you exactly which pre-processors and build tools are required, and make partial and parallel rebuilds possible. I'm not sure that's in scope for this SoC project but if anyone wants to volunteer to look at this project then that'd be a great service to the community. There's quite a bit of existing code to look at, in ghc, yhc, jhc and hmake which already do some kind of dependency chasing. We'd need that plus make it extensible to arbitrary pre-processors (eg using suffix rules, .y -> .hs, .hs.pp -> .hs) Duncan

On 3 maj 2007, at 17.53, Duncan Coutts wrote:
This is not a Cabal bug. By design, Cabal does not just pick up any packages from the environment like --make does. One of the main points of Cabal is to be able to explicitly track dependencies of a package, so we do require that they all be listed explicitly. Cabal then tells ghc to *only* look in those listed packages and ignore all others even if they happen to be installed.
Now certainly it would be nicer if ghc+cabal could be more helpful and tell you all the missing packages that you need to list in the "build-depends" field in the .cabal file, rather than currently where you have to do it one by one.
In fact I was thinking of something more than this. When I said "file a bug" I didn't intend to describe it as a bug but as a feature, which are also managed by the bug tracker. Also, I agree that dependencies should be listed explicitly; it might be very useful to let Cabal generate you a template with some sane suggestions, though. / Thomas

Duncan Coutts wrote:
On Thu, 2007-05-03 at 16:49 +0200, Thomas Schilling wrote:
By dependencies I meant, library packages that GHC knows about.
For example, if I load something simple like
import System.Posix.Files main = touchFile "example" into GHCi and execute ":main" it prints
Loading package unix-1.0 ... linking ... done. Oh, right. Well, then please file it as a bug report on Cabal. I'll be working on Cabal configs as my Summer of Code project; this is clearly related. With a bit of luck it'll be done before end of August.
This is not a Cabal bug. By design, Cabal does not just pick up any packages from the environment like --make does. One of the main points of Cabal is to be able to explicitly track dependencies of a package, so we do require that they all be listed explicitly. Cabal then tells ghc to *only* look in those listed packages and ignore all others even if they happen to be installed.
Now certainly it would be nicer if ghc+cabal could be more helpful and tell you all the missing packages that you need to list in the "build-depends" field in the .cabal file, rather than currently where you have to do it one by one.
This feature could be implemented in GHC, or it could actually be implemented in Cabal. To do it in cabal requires that cabal gain an infrastructure for doing dependency analysis of modules. We don't have that yet. We do need this infrastructure anyway though, since for example some pre-processors (notably c2hs) need to be called in dependency order. It would also allow other nice things like having cabal work out for you exactly which pre-processors and build tools are required, and make partial and parallel rebuilds possible.
ghc --show-iface Main.hi | grep 'package dependencies'
This doesn't do exactly what you want, but it's useful nonetheless: package dependencies: base haskell98 Cheers, Simon
participants (4)
-
Dougal Stanton
-
Duncan Coutts
-
Simon Marlow
-
Thomas Schilling