Remove Setup.hs, use Setup.lhs only

[forwarding this manually as the BTS doesn't send to a mailing list; the bug is at http://hackage.haskell.org/trac/hackage/ticket/100 ] I'm not sure if this should be a bug(enhancement) report or on the mailing list, but I've gone with putting it here so that it won't be accidentally forgotten about. Allowing both Setup.hs and Setup.lhs causes minor annoyances all over the place when working with cabal packages, and moreso when writing tools to work with cabal packages. There are also a couple of larger problems I've had. For example, when writing a Makefile that builds all cabal packages in subdirectories (i.e. (re)make setup if necessary, configure and build) it is hard (for me at least!) to tell make "setup depends on whichever of Setup.hs and Setup.lhs exists". The benefits of allowing Setup.hs are small. For the common case you only save a couple of copies of > , while for larger Setup.lhs files \begin{code} and \end{code} at the start and end is not significant overhead. The reason for choosing to keep Setup.lhs over Setup.hs is so that we can use #! scripts etc without having to worry about the Haskell impl trying to parse it. Thus I would like to propose dropping support for Setup.hs and supporting Setup.lhs only. It would probably be necessary for cabal to complain if it finds a Setup.hs file, as otherwise people wouldn't notice they hadn't updated their packages. Thanks Ian

On Tue, 2006-11-21 at 18:43 +0000, Ian Lynagh wrote:
There are also a couple of larger problems I've had. For example, when writing a Makefile that builds all cabal packages in subdirectories (i.e. (re)make setup if necessary, configure and build) it is hard (for me at least!) to tell make "setup depends on whichever of Setup.hs and Setup.lhs exists".
Note that in future we intend to allow there being no Setup.(l)hs at all when using cabal-setup. No Setup.(l)hs file would be equivalent to the basic one that uses defaultMain. So how would that affect your makefile? Duncan

On Wed, Nov 22, 2006 at 01:36:13AM +0000, Duncan Coutts wrote:
Note that in future we intend to allow there being no Setup.(l)hs at all when using cabal-setup. No Setup.(l)hs file would be equivalent to the basic one that uses defaultMain.
Could we have an optional field in the package description to tell cabal-setup which setup to use? There could be tokens representing main = Distribution.Simple.defaultMain main = Distribution.Simple.defaultMainWithHooks defaultUserHooks main = Distribution.Make.defaultMain user-supplied Setup.[l]hs

Ross Paterson
On Wed, Nov 22, 2006 at 01:36:13AM +0000, Duncan Coutts wrote:
Note that in future we intend to allow there being no Setup.(l)hs at all when using cabal-setup. No Setup.(l)hs file would be equivalent to the basic one that uses defaultMain.
Could we have an optional field in the package description to tell cabal-setup which setup to use? There could be tokens representing
main = Distribution.Simple.defaultMain main = Distribution.Simple.defaultMainWithHooks defaultUserHooks main = Distribution.Make.defaultMain
Since we've decided to go with making Setup.[l]hs optional, I agree that this is the way to go, except:
user-supplied Setup.[l]hs
Hmm. This one is a little funny, since it's the Setup program (or cabal-setup) that's reading the .cabal file, but it kinda makes sense :) I also like Ian's suggestion, and it would be good to do it all at the same time, while providing warnings for Setup.hs users. So a summary of the new rules would be something like: * Setup.lhs will be found automatically, as it is now. * Setup.hs will be found and complained about with an error. Maybe in the interum, we can have a warning. In the common case, the error can be fixed by deleting Setup.hs and using cabal-setup :) * Setup will become optional, and cabal-setup will do the job of defaultMain (or whatever is in the new field). * A new field will be introduced to indicate what kind of build system cabal-setup should use, in the absense of a Setup.lhs file. I anticipate some objections, because some people _hate_ .lhs, but we can see how it goes; in that case, they could always use the user-supplied field to tell cabal layered tools to use the Setup.Foo.Hs or whatever the user wants. Ross, how do you see the fields panning out? Want to implement it? :) peace, isaac

On Sat, Nov 25, 2006 at 09:57:50AM -0800, Isaac Jones wrote:
Ross Paterson
writes: On Wed, Nov 22, 2006 at 01:36:13AM +0000, Duncan Coutts wrote:
Note that in future we intend to allow there being no Setup.(l)hs at all when using cabal-setup. No Setup.(l)hs file would be equivalent to the basic one that uses defaultMain.
Could we have an optional field in the package description to tell cabal-setup which setup to use? There could be tokens representing
main = Distribution.Simple.defaultMain main = Distribution.Simple.defaultMainWithHooks defaultUserHooks main = Distribution.Make.defaultMain
Since we've decided to go with making Setup.[l]hs optional, I agree
What's the advantage of making it optional, especially now we have mkcabal to make the defaultMain Setup.lhs for us? It would be much simpler, IMO, if it was the case that all cabal packages have a Setup.lhs file. As we need to support the presence of a Setup.lhs, no tool can be made simpler by allowing it to be absent (and many will need a little extra complexity to cope), and the only saving is a tiny amount of compilation for one (admittedly common) case. Thanks Ian

Ian Lynagh
On Sat, Nov 25, 2006 at 09:57:50AM -0800, Isaac Jones wrote:
Ross Paterson
writes: On Wed, Nov 22, 2006 at 01:36:13AM +0000, Duncan Coutts wrote:
Note that in future we intend to allow there being no Setup.(l)hs at all when using cabal-setup. No Setup.(l)hs file would be equivalent to the basic one that uses defaultMain.
Could we have an optional field in the package description to tell cabal-setup which setup to use? There could be tokens representing
main = Distribution.Simple.defaultMain main = Distribution.Simple.defaultMainWithHooks defaultUserHooks main = Distribution.Make.defaultMain
Since we've decided to go with making Setup.[l]hs optional, I agree
What's the advantage of making it optional, especially now we have mkcabal to make the defaultMain Setup.lhs for us? It would be much simpler, IMO, if it was the case that all cabal packages have a Setup.lhs file.
As we need to support the presence of a Setup.lhs, no tool can be made simpler by allowing it to be absent (and many will need a little extra complexity to cope), and the only saving is a tiny amount of compilation for one (admittedly common) case.
I see your point about layered tools needing to do a somewhat more complex check for Setup.lhs. Really, layered tools should try to use cabal-setup and let that tool handle finding the Setup file (or not) but cabal-setup isn't in common use yet. But if we're talking about tools in Debian and Gentoo, it would probably be best to require that cabal-setup is there and just use that. The thing about requiring Setup.lhs is that it makes running setup just a little more complex than it needs to be; runhaskell isn't really in common use yet and compiling Setup files still can cause problems. I still think that if Haskell were as easy to envoke as something like perl or php (via runhaskell), we'd have more adoption. I know it doesn't help that Cabal's API isn't particularly stable. peace, isaac

On Sun, Nov 26, 2006 at 03:27:31PM -0800, Isaac Jones wrote:
I see your point about layered tools needing to do a somewhat more complex check for Setup.lhs. Really, layered tools should try to use cabal-setup and let that tool handle finding the Setup file (or not) but cabal-setup isn't in common use yet.
OK, if cabal-setup will become the recommended interface rather than Setup.[l]hs then I don't mind Setup.hs continuing to be accepted (but I also wouldn't object to it being disallowed). Thanks Ian

Ian Lynagh wrote:
On Sat, Nov 25, 2006 at 09:57:50AM -0800, Isaac Jones wrote:
Ross Paterson
writes: On Wed, Nov 22, 2006 at 01:36:13AM +0000, Duncan Coutts wrote:
Note that in future we intend to allow there being no Setup.(l)hs at all when using cabal-setup. No Setup.(l)hs file would be equivalent to the basic one that uses defaultMain.
Could we have an optional field in the package description to tell cabal-setup which setup to use? There could be tokens representing
main = Distribution.Simple.defaultMain main = Distribution.Simple.defaultMainWithHooks defaultUserHooks main = Distribution.Make.defaultMain
Since we've decided to go with making Setup.[l]hs optional, I agree
What's the advantage of making it optional, especially now we have mkcabal to make the defaultMain Setup.lhs for us? It would be much simpler, IMO, if it was the case that all cabal packages have a Setup.lhs file.
As we need to support the presence of a Setup.lhs, no tool can be made simpler by allowing it to be absent (and many will need a little extra complexity to cope), and the only saving is a tiny amount of compilation for one (admittedly common) case.
Lets we forget, the main reason for wanting cabal-setup was so that it can read the .cabal file and select the right version of the Cabal package to use when reading Setup.l?hs, so we can handle Setup.lhs scripts that depend on particular versions of the Cabal API. It has been quite common to encounter compile errors in Setup.lhs scripts recently, and this is very confusing for users. Cheers, Simon

On Sat, Nov 25, 2006 at 09:57:50AM -0800, Isaac Jones wrote:
So a summary of the new rules would be something like:
* Setup.lhs will be found automatically, as it is now.
* Setup.hs will be found and complained about with an error. Maybe in the interim, we can have a warning. In the common case, the error can be fixed by deleting Setup.hs and using cabal-setup :)
* Setup will become optional, and cabal-setup will do the job of defaultMain (or whatever is in the new field).
* A new field will be introduced to indicate what kind of build system cabal-setup should use, in the absense of a Setup.lhs file.
I'd suggest putting the last two slightly differently. As I understood it, the idea of cabal-setup is that you have it pre-compiled on your system, and you always run it, because it's smart enough to find a compiler and suitable Cabal version to execute Setup.lhs. If this field is set to something other than Custom, cabal-setup can ignore Setup.lhs, and just do the appropriate thing itself (making Setup.lhs optional). For backward compatibility, you'd probably want the default value of the new field to be Custom, though this would mean you couldn't omit Setup.lhs unless this field was set.
Ross, how do you see the fields panning out? Want to implement it? :)
Something like Build-Type: (Simple|Configure|Make|Custom) I'd be happy to implement it, if/when we get agreement.

Ross Paterson
On Sat, Nov 25, 2006 at 09:57:50AM -0800, Isaac Jones wrote:
So a summary of the new rules would be something like:
* Setup.lhs will be found automatically, as it is now.
* Setup.hs will be found and complained about with an error. Maybe in the interim, we can have a warning. In the common case, the error can be fixed by deleting Setup.hs and using cabal-setup :)
* Setup will become optional, and cabal-setup will do the job of defaultMain (or whatever is in the new field).
* A new field will be introduced to indicate what kind of build system cabal-setup should use, in the absense of a Setup.lhs file.
I'd suggest putting the last two slightly differently. As I understood it, the idea of cabal-setup is that you have it pre-compiled on your system, and you always run it, because it's smart enough to find a compiler and suitable Cabal version to execute Setup.lhs.
Right!
If this field is set to something other than Custom, cabal-setup can ignore Setup.lhs, and just do the appropriate thing itself (making Setup.lhs optional).
That's a good idea. People can include Setup.lhs to be backward compatible, but if the Build-Type field is Custom (for instance) we can ignore it. I guess if they say "Custom" then we look for Setup.lhs only, (and maybe Setup.hs to give a helpful hint). I think I mentioned the idea of letting them give an arbitrary path, but that just seems like a bad idea.
For backward compatibility, you'd probably want the default value of the new field to be Custom, though this would mean you couldn't omit Setup.lhs unless this field was set.
Right.
Ross, how do you see the fields panning out? Want to implement it? :)
Something like
Build-Type: (Simple|Configure|Make|Custom)
I'd be happy to implement it, if/when we get agreement.
Cool. What do others think of all this? peace, isaac

On Mon, 2006-11-27 at 15:06 -0800, Isaac Jones wrote:
Ross, how do you see the fields panning out? Want to implement it? :)
Something like
Build-Type: (Simple|Configure|Make|Custom)
I'd be happy to implement it, if/when we get agreement.
Cool. What do others think of all this?
It's not clear to me that we need to have an extra field. I had originally envisaged that cabal-setup would just find the right compiler to build Setup.(l)hs and if there was none that it'd use defaultMain (possibly without needing to compile any setup binary). So do we really need a 'build-type:' field? Arn't there just two values for it, 'Simple' and 'Custom' (since all others are just different implementations of 'Custom')? Can't the Simple/Custom distinction be simply if the Setup.(l)hs is present or not? As people have said, backwards compat is easy, just include a Setup.(l)hs that calls defaultMain. If you ommit it, then new cabal-setup can build it anyway. Duncan

On Tue, Nov 28, 2006 at 12:28:56AM +0000, Duncan Coutts wrote:
It's not clear to me that we need to have an extra field. I had originally envisaged that cabal-setup would just find the right compiler to build Setup.(l)hs and if there was none that it'd use defaultMain (possibly without needing to compile any setup binary).
If there was a Setup.[l]hs, it wouldn't be correct to use defaultMain, would it?
So do we really need a 'build-type:' field? Arn't there just two values for it, 'Simple' and 'Custom' (since all others are just different implementations of 'Custom')?
In that sense, there's only one value (Custom), but defaultMain is common, and a reasonable number of packages use main = defaultMainWithHooks defaultUserHooks I had a value for Distribution.Make.defaultMain too (but I don't know if anyone uses that).
Can't the Simple/Custom distinction be simply if the Setup.(l)hs is present or not?
If you have a field, cabal-setup can avoid compiling Setup.[l]hs in the common cases.

Hi
In that sense, there's only one value (Custom), but defaultMain is common, and a reasonable number of packages use
main = defaultMainWithHooks defaultUserHooks
I had a value for Distribution.Make.defaultMain too (but I don't know if anyone uses that).
Can't the Simple/Custom distinction be simply if the Setup.(l)hs is present or not?
If you have a field, cabal-setup can avoid compiling Setup.[l]hs in the common cases.
Another advantage of not having a Setup.hs file is that you can't get your machine taken over just by installing a package. The library author would have to be much more creative. Thanks Neil

On Tue, Nov 28, 2006 at 06:41:16PM +0000, Neil Mitchell wrote:
Another advantage of not having a Setup.hs file is that you can't get your machine taken over just by installing a package. The library author would have to be much more creative.
Only if cabal-setup uses defaultMain rather than the hooks which run configure or make, and if TH isn't enabled anywhere. There may be other thing to watch out for too. Thanks Ian

On Tue, Nov 28, 2006 at 06:28:35PM +0000, Ross Paterson wrote:
Can't the Simple/Custom distinction be simply if the Setup.(l)hs is present or not?
If you have a field, cabal-setup can avoid compiling Setup.[l]hs in the common cases.
It would be nice to avoid allowing the possibility of having a Setup.[l]hs that doesn't match what cabal-setup does. Thanks Ian

On Tue, 2006-11-28 at 18:28 +0000, Ross Paterson wrote:
On Tue, Nov 28, 2006 at 12:28:56AM +0000, Duncan Coutts wrote:
It's not clear to me that we need to have an extra field. I had originally envisaged that cabal-setup would just find the right compiler to build Setup.(l)hs and if there was none that it'd use defaultMain (possibly without needing to compile any setup binary).
If there was a Setup.[l]hs, it wouldn't be correct to use defaultMain, would it?
Indeed, it would not. If there's a Setup.[l]hs then we use that. If there isn't then we use Distribution.Simple.defaultMain (either directly or indirectly via a simple Setup.hs).
So do we really need a 'build-type:' field? Arn't there just two values for it, 'Simple' and 'Custom' (since all others are just different implementations of 'Custom')?
In that sense, there's only one value (Custom), but defaultMain is common, and a reasonable number of packages use
main = defaultMainWithHooks defaultUserHooks
which (bizarrely) is not the same as defaultMainWithHooks defaultUserHooks, though it really should be.
I had a value for Distribution.Make.defaultMain too (but I don't know if anyone uses that).
Can't the Simple/Custom distinction be simply if the Setup.(l)hs is present or not?
If you have a field, cabal-setup can avoid compiling Setup.[l]hs in the common cases.
Oh you mean that since people would want to be backwards compatible that they would include a simple Setup.hs and then we loose the advantage of not having to compile Setup.hs and thus having an extra field to say to use simple even if there is a Setup.hs present is a benefit? Yes, it is a benefit but it seems rather marginal to me. Remember that we can't always avoid building a trivial Setup.hs anyway, since in the case that cabal-setup was built with Cabal-x.y and the .cabal requests cabal version x.y+1 then cabal-setup needs to build Setup.hs with the later version of the Cabal lib and use that. Duncan

On Wed, Nov 29, 2006 at 03:32:52AM +0000, Duncan Coutts wrote:
On Tue, 2006-11-28 at 18:28 +0000, Ross Paterson wrote:
In that sense, there's only one value (Custom), but defaultMain is common, and a reasonable number of packages use
main = defaultMainWithHooks defaultUserHooks
which (bizarrely) is not the same as defaultMainWithHooks defaultUserHooks, though it really should be.
Fair enough, but for this discussion the point is that whatever they're called, there are two of them (three if you count Make).
Oh you mean that since people would want to be backwards compatible that they would include a simple Setup.hs and then we loose the advantage of not having to compile Setup.hs and thus having an extra field to say to use simple even if there is a Setup.hs present is a benefit?
Yes, it is a benefit but it seems rather marginal to me. Remember that we can't always avoid building a trivial Setup.hs anyway, since in the case that cabal-setup was built with Cabal-x.y and the .cabal requests cabal version x.y+1 then cabal-setup needs to build Setup.hs with the later version of the Cabal lib and use that.
Yes we do, and even if Setup.hs wasn't present. But this will be rare, especially if one keeps cabal-setup up to date. The idea is to get the benefit most of the time, though not all.

On Sat, 25 Nov 2006, Isaac Jones wrote:
I anticipate some objections, because some people _hate_ .lhs, but we can see how it goes; in that case, they could always use the user-supplied field to tell cabal layered tools to use the Setup.Foo.Hs or whatever the user wants.
What about a separate binary, say 'cabal-setup', that calls runhaskell Setup.hs ?

On 11/27/06, Henning Thielemann
On Sat, 25 Nov 2006, Isaac Jones wrote:
I anticipate some objections, because some people _hate_ .lhs, but we can see how it goes; in that case, they could always use the user-supplied field to tell cabal layered tools to use the Setup.Foo.Hs or whatever the user wants.
What about a separate binary, say 'cabal-setup', that calls runhaskell Setup.hs ?
Isn't that essentially what 'cabal-setup' is doing now? -- Cheers, Lemmih

Lemmih
On 11/27/06, Henning Thielemann
wrote: On Sat, 25 Nov 2006, Isaac Jones wrote:
I anticipate some objections, because some people _hate_ .lhs, but we can see how it goes; in that case, they could always use the user-supplied field to tell cabal layered tools to use the Setup.Foo.Hs or whatever the user wants.
What about a separate binary, say 'cabal-setup', that calls runhaskell Setup.hs ?
Isn't that essentially what 'cabal-setup' is doing now?
cabal-setup is doing that and more, yes. peace, isaac
participants (8)
-
Duncan Coutts
-
Henning Thielemann
-
Ian Lynagh
-
Isaac Jones
-
Lemmih
-
Neil Mitchell
-
Ross Paterson
-
Simon Marlow