Added RPM generation capability to Cabal

I spent a few hours over the past couple of days hacking on Cabal to add the ability to build RPM packages. You can fetch my darcs repository from here: darcs get --partial http://darcs.serpentine.com/cabal-rpm This new capability is easy to use. It adds a single new Cabal command, called rpm. runhaskell Setup.*hs rpm This generates a spec file, and builds source and binary RPMs. Here’s a quick example, of trying to build the Haskell XML-RPC library: ~/src/darcs/haxr $ runghc Setup.*hs rpm Source tarball created: dist/SOURCES/haxr-3000.0.0.tar.gz error: Failed build dependencies: HaXml-ghc66 >= 1.13 is needed by haxr-3000.0.0-1.i386 HaXml-ghc66 < 1.14 is needed by haxr-3000.0.0-1.i386 Setup.lhs: rpmbuild failed with status 1 The rpm command has converted the dependencies in the haxr.cabal file into build-time and runtime dependencies in the haxr.spec file that it generated, but rpmbuild can’t find the HaXml package. Having earlier built a HaXml package using the rpm command, I can install it with the system’s rpm command. # rpm -i haxml-ghc66-1.13.2-1.i386.rpm Reading package info from stdin ... done. Saving old package config file... done. Writing new package config file... done. The RPM’s post-install scriptlet informs GHC’s package manager about the package’s availability: # ghc-pkg list --simple | tr ' ' '\n' | grep -i haxml HaXml-1.13.2 Now if I try to build haxr again, it will succeed. By default, the rpm command builds both normal and profiling-enabled libraries. It also uses Haddock to generate library documentation. It’s possible to control these behaviours from the command line. The command also provides a --gen-spec option, which only generates a spec file. You can use this >spec file as a basis for crafting one of your own. I’ve used the rpm command to build about a third of the packages listed in the Hackage package database, with no problems.

Great stuff Bryan, I look forward to seeing the patches. Do darcs send them to this list for review. Duncan On Tue, 2007-02-20 at 15:39 -0800, Bryan O'Sullivan wrote:
I spent a few hours over the past couple of days hacking on Cabal to add the ability to build RPM packages. You can fetch my darcs repository from here:
darcs get --partial http://darcs.serpentine.com/cabal-rpm
This new capability is easy to use. It adds a single new Cabal command, called rpm.
runhaskell Setup.*hs rpm
This generates a spec file, and builds source and binary RPMs.
Here’s a quick example, of trying to build the Haskell XML-RPC library:
~/src/darcs/haxr $ runghc Setup.*hs rpm Source tarball created: dist/SOURCES/haxr-3000.0.0.tar.gz error: Failed build dependencies: HaXml-ghc66 >= 1.13 is needed by haxr-3000.0.0-1.i386 HaXml-ghc66 < 1.14 is needed by haxr-3000.0.0-1.i386 Setup.lhs: rpmbuild failed with status 1
The rpm command has converted the dependencies in the haxr.cabal file into build-time and runtime dependencies in the haxr.spec file that it generated, but rpmbuild can’t find the HaXml package.
Having earlier built a HaXml package using the rpm command, I can install it with the system’s rpm command.
# rpm -i haxml-ghc66-1.13.2-1.i386.rpm Reading package info from stdin ... done. Saving old package config file... done. Writing new package config file... done.
The RPM’s post-install scriptlet informs GHC’s package manager about the package’s availability:
# ghc-pkg list --simple | tr ' ' '\n' | grep -i haxml HaXml-1.13.2
Now if I try to build haxr again, it will succeed.
By default, the rpm command builds both normal and profiling-enabled libraries. It also uses Haddock to generate library documentation. It’s possible to control these behaviours from the command line.
The command also provides a --gen-spec option, which only generates a spec file. You can use this >spec file as a basis for crafting one of your own.
I’ve used the rpm command to build about a third of the packages listed in the Hackage package database, with no problems. _______________________________________________ cabal-devel mailing list cabal-devel@haskell.org http://www.haskell.org/mailman/listinfo/cabal-devel

Duncan Coutts wrote:
Great stuff Bryan, I look forward to seeing the patches. Do darcs send them to this list for review.
I'd be happy to, but my darcs repo contains about 50 patches that resulted from many incremental checkpoints as I went. I'm guessing that you'd prefer to see something closer to three or four? My darcs fu is not strong enough to know whether there's an easy way to do this, so I may end up having to diff my branch with the main repository and repatch.

On Tue, Feb 20, 2007 at 04:36:38PM -0800, Bryan O'Sullivan wrote:
Duncan Coutts wrote:
Great stuff Bryan, I look forward to seeing the patches. Do darcs send them to this list for review.
I'd be happy to, but my darcs repo contains about 50 patches that resulted from many incremental checkpoints as I went. I'm guessing that you'd prefer to see something closer to three or four?
My darcs fu is not strong enough to know whether there's an easy way to do this, so I may end up having to diff my branch with the main repository and repatch.
As I recall, it is considered a major feature of darcs that patches retain their identity on merging - if something breaks, you can unrecord only a small piece, even after the merge. Besides, remember that 50 patches is 50x the documentation :)

Stefan O'Rear wrote:
Besides, remember that 50 patches is 50x the documentation :)
Yes, but it's 50x the blundering about when trying to review the code :-) Here's a seemingly reasonable compromise. I've attached a single unified diff that contains all of my changes in a single lump. If the code looks sane, you can then "darcs pull" the real changes and see if the history "smells right". There shouldn't be any review surprises. The only "unrelated" change it makes is to check the return code from tar in SrcDist, something that must have been overlooked. The actual darcs history is pretty clean, too. Small, self-contained changes, etc, etc.

Have you seen cabal2rpm? It's an external tool with a similar goal: http://community.moertel.com/ss/space/Cabal2rpm/cabal2rpm.html Similarly, there's dh_haskell for Debian packages: http://man.cx/dh_haskell(1) Can you outline any other differences between this command and cabal2rpm? This seems like really cool work, but what do folks think about adding OS-specific items like this to Cabal. My stance has been that we should keep such tools external to Cabal, layered on top of Cabal so as to not clutter Cabal too much, and to make Cabal's interface to the outside world as good as possible. peace, isaac

Le Wednesday 21 February 2007, Isaac Jones a écrit :
Have you seen cabal2rpm? It's an external tool with a similar goal:
I did also mine, but according my haskell knowledge, I'd better to have a look to already existing project. I am myself a Mandriva contributor, and I started to package some haskell module, and plan to increase the count. But if all thoses project want to have a sex appeal, they should be configurable per distribution to apply their policy. For example, at mandriva our rpm are in svn, the spec is generated once, and then update, like in many distribution, the official "Group" list differ, and finally we all use macros. Hit me if you want to know how to improve them to make them really usefull. Such project are a good idea anyway.

Have you seen cabal2rpm? It's an external tool with a similar goal:
http://community.moertel.com/ss/space/Cabal2rpm/cabal2rpm.html
I hadn't seen it, no.
Can you outline any other differences between this command and cabal2rpm?
Cabal2rpm is much less sophisticated. The rpm command I wrote correctly calculates dependencies on other Haskell packages, and on system packages too. Also, cabal2rpm has clearly bitrotted from looking at the source, and would be unlikely to work now.
This seems like really cool work, but what do folks think about adding OS-specific items like this to Cabal.
I realise I get a bit less of a vote since I wrote this, but I think that cabal2rpm illustrates one aspect of the problem with keeping tools like this outside of Cabal: they break. Another aspect is that you have to be able to *find* the external tools. A Google search like "cabal rpm spec" does not yield cabal2rpm anywhere in the results.
My stance has been that we should keep such tools external to Cabal, layered on top of Cabal so as to not clutter Cabal too much, and to make Cabal's interface to the outside world as good as possible.
I certainly wouldn't mind there being a single command entry point for building binary packages, e.g. bdist, with flags to control which kind of binary package to build (RPM, deb, DMG, Innosetup, etc.). But I really think it's a good thing for the language as a whole to make it as easy as possible for people to provide binaries to their respective OS/distro communities. This is a step towards that. I've written Mac and Windows installers, too, so if the RPM stuff gets in, they're natural targets. You can see that the code I added has negligible effect on the core of Cabal, so it doesn't add clutter.

Isaac Jones wrote:
Have you seen cabal2rpm? It's an external tool with a similar goal:
http://community.moertel.com/ss/space/Cabal2rpm/cabal2rpm.html
Similarly, there's dh_haskell for Debian packages: http://man.cx/dh_haskell(1)
Can you outline any other differences between this command and cabal2rpm?
This seems like really cool work, but what do folks think about adding OS-specific items like this to Cabal. My stance has been that we should keep such tools external to Cabal, layered on top of Cabal so as to not clutter Cabal too much, and to make Cabal's interface to the outside world as good as possible.
The problem with layered tools is that they don't work well with the Setup.lhs scheme that we currently have. Setup.lhs can modify PackageDescription via hooks, so the layered tool won't see these modifications. I suspect that in practice there are hardly any clashes of this kind, though. To properly support this we would have to provide a way to output the modified PackageDescription so the tool can read it in. On the other hand, every time we add a new command (like 'Setup rpm') we need a new hook, which breaks the Cabal API again: existing packages which use hooks probably wanted to also hook the new command. The current design for hooks doesn't extend well, we should think about that. FWIW, I'd let the RPM patch in for now. Cheers, Simon

On Tue, Feb 20, 2007 at 03:52:30PM -0800, Isaac Jones wrote:
This seems like really cool work, but what do folks think about adding OS-specific items like this to Cabal. My stance has been that we should keep such tools external to Cabal, layered on top of Cabal so as to not clutter Cabal too much, and to make Cabal's interface to the outside world as good as possible.
FWIW, I agree. Also, having the rpm code built with cabal will only ensure it keeps compiling. I won't necessarily keep it correct, and in my experience it is also common to see "temporary" (error "unhandled case")s appear in such situations, where many contributors are not interested in the rpm code, and are unable to easily test it. Thanks Ian
participants (7)
-
Bryan O'Sullivan
-
Duncan Coutts
-
Ian Lynagh
-
Isaac Jones
-
Olivier Thauvin
-
Simon Marlow
-
Stefan O'Rear