
Hi List, First off, I want to say hi, as this is my first post. I'm trying to get some badly needed updates to cabal-rpm, so we can get more Haskell packages into Fedora. All of the following is with Cabal 1.2.3.0 and GHC 6.8.2 as packaged in Fedora 8. In the module Distribution.PackageDescription, there are four functions, hasExes, and hasLibs, as well as libModules and exeModules. These functions claim to do the obvious for a PackageDescription. The only problem I'm having is with packages like xmonad, which have both Executables and Libraries. In the case of xmobar, hasLibs returns False, and an empty list for libModules, but True and a list for hasExes and exeModules respectively. In the case of xmonad-contrib, the opposite is true, that is there are no Executables at all, but a bucket load of Libraries. In the case of xmonad, hasLibs returns True. but returns a nonempty list. hasExes returns True, and with the same nonempty list. I would expect the lists to be the same, as all the Modules listed therein are needed to compile the executable, and also to be linked with the user supplied config file. The only problem I see is with hasLibs itself. I heard something a while back that xmonad needs to be compiled twice, because this setup is considered an edge case in Cabal. Because xmonad is the reason why I'm working on getting Haskell packages into Fedora, I'm not sure I want to think of it that way. Is this a bug, or just a 'feature' I need to watch out for? Cheers, Yaakov Nemoy

On Tue, 2008-04-29 at 17:59 -0400, Yaakov Nemoy wrote:
Hi List,
First off, I want to say hi, as this is my first post. I'm trying to get some badly needed updates to cabal-rpm, so we can get more Haskell packages into Fedora.
Great! :-)
All of the following is with Cabal 1.2.3.0 and GHC 6.8.2 as packaged in Fedora 8.
In the module Distribution.PackageDescription, there are four functions, hasExes, and hasLibs, as well as libModules and exeModules. These functions claim to do the obvious for a PackageDescription. The only problem I'm having is with packages like xmonad, which have both Executables and Libraries.
In the case of xmobar, hasLibs returns False, and an empty list for libModules, but True and a list for hasExes and exeModules respectively.
This is as you expect right? The xmobar package contains one exe.
In the case of xmonad-contrib, the opposite is true, that is there are no Executables at all, but a bucket load of Libraries.
Yes.
In the case of xmonad, hasLibs returns True. but returns a nonempty list. hasExes returns True, and with the same nonempty list. I would expect the lists to be the same, as all the Modules listed therein are needed to compile the executable, and also to be linked with the user supplied config file. The only problem I see is with hasLibs itself.
http://hackage.haskell.org/packages/archive/xmonad/0.7/xmonad.cabal Looking at the xmonad.cabal file we see that xmonad does contain both a library and an executable, so we would expect hasLibs and hasExes to return True. The reason the modules returned for both are the same is because the list of exposed-modules and other-modules in the xmonad.cabal are exactly the same for the lib and for the exe.
I heard something a while back that xmonad needs to be compiled twice, because this setup is considered an edge case in Cabal. Because xmonad is the reason why I'm working on getting Haskell packages into Fedora, I'm not sure I want to think of it that way. Is this a bug, or just a 'feature' I need to watch out for?
What they meant is that it is not currently possible to make a package with a library and an executable where the executable links against the library, instead it must compile the same modules that are in the library itself. So that's what people mean by having to compile things twice. If/when it becomes possible we'd write something like: library exposed-modules: XMonad XMonad.Main [...etc...] executable xmonad main-is: Main.hs build-depends: xmonad [...etc...] That is, we'd specify that the xmonad depends on the xmonad library. Then it would not be necessary to list all the modules twice and have them compiled twice. So in summary: there is no bug. xmonad really does contain a library and an executable. The only limitation is that a few modules get compiled twice rather than once. Duncan

On Wed, Apr 30, 2008 at 4:04 AM, Duncan Coutts
On Tue, 2008-04-29 at 17:59 -0400, Yaakov Nemoy wrote:
Hi List,
First off, I want to say hi, as this is my first post. I'm trying to get some badly needed updates to cabal-rpm, so we can get more Haskell packages into Fedora.
Great! :-)
<snip>
In the case of xmonad, hasLibs returns True. but returns a nonempty list. hasExes returns True, and with the same nonempty list. I would expect the lists to be the same, as all the Modules listed therein are needed to compile the executable, and also to be linked with the user supplied config file. The only problem I see is with hasLibs itself.
http://hackage.haskell.org/packages/archive/xmonad/0.7/xmonad.cabal
Looking at the xmonad.cabal file we see that xmonad does contain both a library and an executable, so we would expect hasLibs and hasExes to return True. The reason the modules returned for both are the same is because the list of exposed-modules and other-modules in the xmonad.cabal are exactly the same for the lib and for the exe.
Ack, what I meant to say is that hasLibs returns False. I am actually expecting those two lists to be the same. I've written an alternate function for hasLibs and withLibs that works on that expectation, but it's specific to cabal-rpm. I haven't tested it because of another bug I've come across, that I need to talk to Brian O'Sullivan about. I may bug you guys on this list again though, but it's a separate issue.
I heard something a while back that xmonad needs to be compiled twice, because this setup is considered an edge case in Cabal. Because xmonad is the reason why I'm working on getting Haskell packages into Fedora, I'm not sure I want to think of it that way. Is this a bug, or just a 'feature' I need to watch out for?
What they meant is that it is not currently possible to make a package with a library and an executable where the executable links against the library, instead it must compile the same modules that are in the library itself. So that's what people mean by having to compile things twice.
If/when it becomes possible we'd write something like:
<snip>
So in summary: there is no bug. xmonad really does contain a library and an executable. The only limitation is that a few modules get compiled twice rather than once.
So in all likelihood this issue has little to do with the bug I'm reporting here. Glad that at least is not in the way.

On Wed, 2008-04-30 at 15:32 -0400, Yaakov Nemoy wrote:
http://hackage.haskell.org/packages/archive/xmonad/0.7/xmonad.cabal
Looking at the xmonad.cabal file we see that xmonad does contain both a library and an executable, so we would expect hasLibs and hasExes to return True. The reason the modules returned for both are the same is because the list of exposed-modules and other-modules in the xmonad.cabal are exactly the same for the lib and for the exe.
Ack, what I meant to say is that hasLibs returns False.
In that case I expect it is because you have used flattenPackageDescription to get a PackageDescription from a GenericPackageDescription. This function makes sense in some circumstances but not for what you want. If we look in xmonad.cabal we see: library exposed-modules: XMonad XMonad.Main [...snip...] if flag(testing) buildable: False So when the testing flag is True, the library will not be buildable. The hasLibs function actually only tells you about buildable libraries (the same goes for hasExes). If you use flattenPackageDescription on this description you will get a PackageDescription whith buildable: False because flattening ignores all conditions and includes *both* sides of conditionals. So what you want is finalizePackageDescription to get a PackageDescription that reflects how the package can actually be configured given the environment in which you expect to use it. I discussed this point with Brian O'Sullivan on irc the other day. One API improvement we should do is to make hasLibs and similar functions take a parameter to say if you want to include or exclude buildable components since the choice is important and we've had a couple bugs in cabal because of this issue (for example bugs like not including non-buildable components in the source tarball). Duncan

On 1 maj 2008, at 00.30, Duncan Coutts wrote:
If we look in xmonad.cabal we see:
library exposed-modules: XMonad XMonad.Main [...snip...] if flag(testing) buildable: False
So when the testing flag is True, the library will not be buildable. The hasLibs function actually only tells you about buildable libraries (the same goes for hasExes).
If you use flattenPackageDescription on this description you will get a PackageDescription whith buildable: False because flattening ignores all conditions and includes *both* sides of conditionals.
The key part here is that 'flattenPackageDescription' (more precisely 'unionBuildInfo' uses '&&' to join multiple occurences of buildable. If at any time a branch claims the package is not buildable, we, of course, want this property to be propagated. Using a '||' only for within flattenPackageDescription doesn't seem like a good idea to me.
So what you want is finalizePackageDescription to get a PackageDescription that reflects how the package can actually be configured given the environment in which you expect to use it.
I discussed this point with Brian O'Sullivan on irc the other day.
One API improvement we should do is to make hasLibs and similar functions take a parameter to say if you want to include or exclude buildable components since the choice is important and we've had a couple bugs in cabal because of this issue (for example bugs like not including non-buildable components in the source tarball).
Duncan
_______________________________________________ cabal-devel mailing list cabal-devel@haskell.org http://www.haskell.org/mailman/listinfo/cabal-devel

On Thu, 2008-05-01 at 01:24 +0200, Thomas Schilling wrote:
On 1 maj 2008, at 00.30, Duncan Coutts wrote:
If you use flattenPackageDescription on this description you will get a PackageDescription whith buildable: False because flattening ignores all conditions and includes *both* sides of conditionals.
The key part here is that 'flattenPackageDescription' (more precisely 'unionBuildInfo' uses '&&' to join multiple occurences of buildable. If at any time a branch claims the package is not buildable, we, of course, want this property to be propagated. Using a '||' only for within flattenPackageDescription doesn't seem like a good idea to me.
Yes. flattenPackageDescription is doing the right thing. It's just not appropriate to use in this particular context. Perhaps we need to document this function more loudly :-). I mean the current documentation is quite accurate but perhaps it needs more big flashing lights. Duncan
participants (3)
-
Duncan Coutts
-
Thomas Schilling
-
Yaakov Nemoy