Developing cabal2wix - building Windows installers automatically

Hi, I decided to try to build a cabal -> wix converter, cabal2wix, to make it easier to generate Windows installers for cabal-packages. My main target is ghc-compiled libraries. There are few issues I've ran into and I'd appreciate any comments on them. I'll try to publish the darcs repo somewhere if there's interest. Some of the issues are gray, as I don't understand all the details myself, and reading Cabal's code isn't very enlightening. Issue 1: Cabal puts (at least) docs under Program Files\Common Files - this separates docs from other parts of the program by logical placing, which is pretty annoying if you need to offer way to relocate installation (say to user's home directory). I am considering moving docs next to library files in installers cabal2wix generates. Issue 2: setup copy --destdir=foo is confusing in Windows. If my prefix is c:\Program Files (like it is if I run configure without options), the directory structure after copy is foo\Program Files - ie. unsuable locally because drive letter is missing, and unusable at remote locations, because Program Files is not localized. I'd like not to use all possible directory flags at configure time, because it is impossible to know how different packages react to them. (currently cabal2wix assumes no directories were changed.) Suggestion: Make copy-hook unable to copy random files on their own, this way there could be setup copy --list-links, which would be nicer, IMHO. As the list could also differentiate between different types of files. Profiling lib, shared libs (dev and end-user installer in one.) Issue 3: Currently cabal2wix reads dist\setup-config to find out package and compiler information. This is pretty stupid, as LocalBuildInfo structure might not be that stable, and cabal2wix can only guarantee working with the same Cabal it was built with. cabal2wix could read installed-pkg-config (and maybe .cabal) to get package name and version. But I can't see how to get compiler information from any other place than setup-config. It'd also make sense to read solved build-depends info, but I currently don't have plans to do that. Issue 4: There is no proper registry keys for finding compiler installation. Neil's installer adds HKCU\Software\Haskell\GHC\InstallDir. I'd much prefer if the registry key path contained ghc version in it, and HKLM might be preferable on some multi-user machines. It'd be great if we could find recommended location for this info. (And use it for ghc 6.8 releases) My tentative proposal: Use HKLM if "all users" install, HKCU otherwise. Use \Software\Haskell\COMPILER\VERSION\InstallDir for storing path to base location of installed compiler. (i.e. it shouldn't point to bin-directory.) Small issues: * License file is not installed. * Docs need relinking at install location, that's a bit annoying. Big thank you for Duncan and Ian for useful comments at irc. Issue list is shorter now ;-) Thanks, Esa

Hi
I decided to try to build a cabal -> wix converter, cabal2wix, to make it easier to generate Windows installers for cabal-packages. My main target is ghc-compiled libraries. There are few issues I've ran into and I'd appreciate any comments on them.
I found wix annoying, and chose to use InnoSetup instead, following on from Duncan's use of it in Gtk2hs. Inno can't do .msi's.
I'll try to publish the darcs repo somewhere if there's interest.
If there was some way to get Hugs and GHC installers out of it, possibly with a fake cabal file or something, that would be lovely! Perhaps a System.Installer.Wix library that all could use?
Cabal puts (at least) docs under Program Files\Common Files - this separates docs from other parts of the program by logical placing, which is pretty annoying if you need to offer way to relocate installation (say to user's home directory). I am considering moving docs next to library files in installers cabal2wix generates.
I would very much like it if runhaskell Setup install, and running your installer generator did the same thing.
I'd like not to use all possible directory flags at configure time, because it is impossible to know how different packages react to them. (currently cabal2wix assumes no directories were changed.)
I think you can currently assume no Windows user has ever successfully used them!
Issue 4: There is no proper registry keys for finding compiler installation. Neil's installer adds HKCU\Software\Haskell\GHC\InstallDir. I'd much prefer if the registry key path contained ghc version in it, and HKLM might be preferable on some multi-user machines.
I copied what the previous installer had, and we only no what the previous installer had because Duncan was relying on it for Gtk2hs (the previous installer is closed source). Make a concrete suggestion, file it as a GHC bug and I'm sure it can be done/
My tentative proposal: Use HKLM if "all users" install, HKCU otherwise. Use \Software\Haskell\COMPILER\VERSION\InstallDir for storing path to base location of installed compiler. (i.e. it shouldn't point to bin-directory.)
Agreed.
Small issues: * License file is not installed.
On Windows, I doubt anyone cares :-) Thanks for doing this, it has been something I've been meaning to get to for ages. Thanks Neil

Hi,
On 8/6/07, Neil Mitchell
I found wix annoying, and chose to use InnoSetup instead, following on from Duncan's use of it in Gtk2hs. Inno can't do .msi's.
I chose Wix because I wanted to understand Wix and MSI's structure better.
I'll try to publish the darcs repo somewhere if there's interest.
If there was some way to get Hugs and GHC installers out of it, possibly with a fake cabal file or something, that would be lovely! Perhaps a System.Installer.Wix library that all could use?
I doubt compiler installers can be generated so easily. Btw, cabal2wix doesn't really need .cabal file for anything - it just reads what setup copy --destdir=dist\cabal2wix generates, and build configs. Library isn't my target for now, at least. On that scale, it might also be nicer to generate msi's directly, rather than generating xml.
My tentative proposal: Use HKLM if "all users" install, HKCU otherwise. Use \Software\Haskell\COMPILER\VERSION\InstallDir for storing path to base location of installed compiler. (i.e. it shouldn't point to bin-directory.)
Agreed.
Oops. I think it's already doing almost that, I just read my registry extract wrong.
Small issues: * License file is not installed.
On Windows, I doubt anyone cares :-)
I do. And I need the file for license agreement dialog :-) Best regards, --Esa

On Mon, 2007-08-06 at 00:04 +0100, Neil Mitchell wrote:
Cabal puts (at least) docs under Program Files\Common Files - this separates docs from other parts of the program by logical placing, which is pretty annoying if you need to offer way to relocate installation (say to user's home directory). I am considering moving docs next to library files in installers cabal2wix generates.
I would very much like it if runhaskell Setup install, and running your installer generator did the same thing.
Yes they should be the same, but what is the rationale for using Program Files\Common Files for docs? Don't most Windows apps install into a single relocatable directory rather than putting files in many places? A similar issue arises for that common Haskell tool bin directory we're using on windows. Duncan

Hi
I would very much like it if runhaskell Setup install, and running your installer generator did the same thing.
Yes they should be the same, but what is the rationale for using Program Files\Common Files for docs? Don't most Windows apps install into a single relocatable directory rather than putting files in many places?
A similar issue arises for that common Haskell tool bin directory we're using on windows.
Otherwise you need to add a lot of things to the path, once per installer. Windows wasn't really designed for lots of console apps, Haskell isn't really designed for lots of GUI apps - here the difference shows through. Thanks Neil

On Mon, 2007-08-06 at 01:05 +0300, Esa Ilari Vuokko wrote:
Hi,
I decided to try to build a cabal -> wix converter, cabal2wix, to make it easier to generate Windows installers for cabal-packages. My main target is ghc-compiled libraries. There are few issues I've ran into and I'd appreciate any comments on them.
I'll try to publish the darcs repo somewhere if there's interest.
Some of the issues are gray, as I don't understand all the details myself, and reading Cabal's code isn't very enlightening.
Issue 1: Cabal puts (at least) docs under Program Files\Common Files - this separates docs from other parts of the program by logical placing, which is pretty annoying if you need to offer way to relocate installation (say to user's home directory). I am considering moving docs next to library files in installers cabal2wix generates.
Issue 2: setup copy --destdir=foo is confusing in Windows. If my prefix is c:\Program Files (like it is if I run configure without options), the directory structure after copy is foo\Program Files - ie. unsuable locally because drive letter is missing,
It's not clear that's true, if you copy the files in foo\Program Files\ to C:\Program Files\ and register the package with ghc-pkg then it should work fine.
and unusable at remote locations, because Program Files is not localized. I'd like not to use all possible directory flags at configure time, because it is impossible to know how different packages react to them.
I'm not sure why you say that; what they mean does not vary between packages. I think setting the prefix and other directory flags should be fine. Since you want a relocatable package you do want to set prefix as ".". As you said, some of the other bits are not relative to prefix on windows, like the docs. So that's a problem.
(currently cabal2wix assumes no directories were changed.)
Suggestion: Make copy-hook unable to copy random files on their own, this way there could be setup copy --list-links, which would be nicer, IMHO. As the list could also differentiate between different types of files. Profiling lib, shared libs (dev and end-user installer in one.)
I don't think it's a problem that cabal doesn't support this since it's easy to generate an install image by copying into a temp dir. This is the way most other build systems work (both unix and windows ones). All you'd be saving is one bunch of file copies which is really pretty cheap.
Issue 3: Currently cabal2wix reads dist\setup-config to find out package and compiler information. This is pretty stupid, as LocalBuildInfo structure might not be that stable, and cabal2wix can only guarantee working with the same Cabal it was built with. cabal2wix could read installed-pkg-config (and maybe .cabal) to get package name and version. But I can't see how to get compiler information from any other place than setup-config.
You an do that by calling functions in the Simple build system.
It'd also make sense to read solved build-depends info, but I currently don't have plans to do that.
Similarly.
Big thank you for Duncan and Ian for useful comments at irc. Issue list is shorter now ;-)
Good :-) This is potentially a very useful project. We do have lots of windows users and we don't yet have things as easy for them as we should. In the long term we would want to tie this into the hackage build server to build binary packages and the cabal-install tool to download and install them. Duncan

Hi,
Sorry for slow reply, I tried to get cabalw2wix to state where it
somehow works, so that I can distill the issues further. Unfortunately,
that didn't help ;-)
On 8/6/07, Duncan Coutts
On Mon, 2007-08-06 at 01:05 +0300, Esa Ilari Vuokko wrote:
Issue 2: setup copy --destdir=foo is confusing in Windows. If my prefix is c:\Program Files (like it is if I run configure without options), the directory structure after copy is foo\Program Files - ie. unsuable locally because drive letter is missing,
It's not clear that's true, if you copy the files in foo\Program Files\ to C:\Program Files\ and register the package with ghc-pkg then it should work fine.
Yeah, but unlike unix, information is lost, and some of it is system dependent. Hence setup copy dist feel so very wrong in Windows.
and unusable at remote locations, because Program Files is not localized. I'd like not to use all possible directory flags at configure time, because it is impossible to know how different packages react to them.
I'm not sure why you say that; what they mean does not vary between packages. I think setting the prefix and other directory flags should be fine.
If that's a rule for packages, I'll go with it. There is no such guarantee in Setup script. It also forces me to duplicate Cabal's logic on directory structure.
Since you want a relocatable package you do want to set prefix as ".". As you said, some of the other bits are not relative to prefix on windows, like the docs. So that's a problem.
Yeah. Annoyance really.
Suggestion: Make copy-hook unable to copy random files on their own, this way there could be setup copy --list-links, which would be nicer, IMHO. As the list could also differentiate between different types of files. Profiling lib, shared libs (dev and end-user installer in one.)
I don't think it's a problem that cabal doesn't support this since it's easy to generate an install image by copying into a temp dir. This is the way most other build systems work (both unix and windows ones). All you'd be saving is one bunch of file copies which is really pretty cheap.
Space is not my concern at all in this. It's the akwardness. setup copy clearly works because that's how unix files are typically organised. It typically seems clunky from Windows perspective. I'd also really like to know what each files does. Are they executables, libraries (and what kind!), interface file, etc.
Issue 3: Currently cabal2wix reads dist\setup-config to find out package and compiler information. This is pretty stupid, as LocalBuildInfo structure might not be that stable, and cabal2wix can only guarantee
You an do that by calling functions in the Simple build system.
Yes. I use read instance provided for LocalBuildInfo. It still will break if setup is built against cabal that has changed LocalBuildInfo structure AFAICT. Best regards, Esa

On Tue, 2007-08-07 at 16:22 +0300, Esa Ilari Vuokko wrote:
On 8/6/07, Duncan Coutts
wrote: On Mon, 2007-08-06 at 01:05 +0300, Esa Ilari Vuokko wrote:
Issue 2: setup copy --destdir=foo is confusing in Windows. If my prefix is c:\Program Files (like it is if I run configure without options), the directory structure after copy is foo\Program Files - ie. unsuable locally because drive letter is missing,
It's not clear that's true, if you copy the files in foo\Program Files\ to C:\Program Files\ and register the package with ghc-pkg then it should work fine.
Yeah, but unlike unix, information is lost, and some of it is system dependent. Hence setup copy dist feel so very wrong in Windows.
I don't really understand this. Sure having a Program File prefix in your image directory is useless, so you want --prefix=. to get no extra prefix. But the concept of an install image is not at all useless. That's what all build systems give you, on windows or other systems. I've worked with windows installers before and the modus operandi is to start from an install image generated by the build system. That's what setup copy is for - for generating an install image.
and unusable at remote locations, because Program Files is not localized. I'd like not to use all possible directory flags at configure time, because it is impossible to know how different packages react to them.
I'm not sure why you say that; what they mean does not vary between packages. I think setting the prefix and other directory flags should be fine.
If that's a rule for packages, I'll go with it. There is no such guarantee in Setup script.
If they're using the Simple build system (and almost all packages do) then you know that the directory flags to the same thing.
It also forces me to duplicate Cabal's logic on directory structure.
I don't understand this.
Suggestion: Make copy-hook unable to copy random files on their own, this way there could be setup copy --list-links, which would be nicer, IMHO. As the list could also differentiate between different types of files. Profiling lib, shared libs (dev and end-user installer in one.)
I don't think it's a problem that cabal doesn't support this since it's easy to generate an install image by copying into a temp dir. This is the way most other build systems work (both unix and windows ones). All you'd be saving is one bunch of file copies which is really pretty cheap.
Space is not my concern at all in this. It's the akwardness. setup copy clearly works because that's how unix files are typically organised. It typically seems clunky from Windows perspective.
If the install image is not laid out to your liking then it can be modified by overriding the various directory flags in the configure step. It may well be that these defaults are not yet right for windows or that there is insufficient flexibility in being able to modify the directories for particular kinds of files. Those are things we can fix.
I'd also really like to know what each files does. Are they executables, libraries (and what kind!), interface file, etc.
The way cabal (and other build systems) deal with this is that instead of identifying what each file is, they allow you to specify where various kinds of files should go. At the moment that's not sufficiently fine grained even for unix systems (eg we'd like to set docs independently from data files). You may also need more fine grained distinctions for Windows. Tell us what distinctions you need to make that you can't make at the moment, or better, tell us what you expect the install image to look like.
You an do that by calling functions in the Simple build system.
Yes. I use read instance provided for LocalBuildInfo.
It still will break if setup is built against cabal that has changed LocalBuildInfo structure AFAICT.
Yes. This will happen frequently. Hmm, for packages that don't need hooks you could do the whole build using the cabal api and you'd have no problems, but for ones that use Setup.hs it's harder. Duncan

Esa Ilari Vuokko wrote:
Hi,
I decided to try to build a cabal -> wix converter, cabal2wix, to make it easier to generate Windows installers for cabal-packages. My main target is ghc-compiled libraries. There are few issues I've ran into and I'd appreciate any comments on them.
I'll try to publish the darcs repo somewhere if there's interest.
Some of the issues are gray, as I don't understand all the details myself, and reading Cabal's code isn't very enlightening.
Issue 1: Cabal puts (at least) docs under Program Files\Common Files - this separates docs from other parts of the program by logical placing,
Not quite true: for an executable, on Windows, docs currently go by default into $prefix\Haskell\$pkgid. See: http://www.haskell.org/ghc/docs/latest/html/Cabal/builders.html#setup-config... For a library, data files go in C:\Program Files\Common Files\$pkgid. There's a very good reason for this: a library cannot discover its installation location like an executable can, because it could be linked in to an executable anywhere on the system. Hence if a library needs access to auxiliary data files, they better be in a fixed place in the filesystem. A library with data files cannot be fully relocatable at install-time. However, we do need to change where docs go (they don't have to go in $datadir, and they can be relocated at install-time). Cheers, Simon

Simon Marlow wrote:
Esa Ilari Vuokko wrote:
Issue 1: Cabal puts (at least) docs under Program Files\Common Files - this separates docs from other parts of the program by logical placing,
Not quite true: for an executable, on Windows, docs currently go by default into $prefix\Haskell\$pkgid. See:
http://www.haskell.org/ghc/docs/latest/html/Cabal/builders.html#setup-config...
Yes. I should have said library docs.
For a library, data files go in C:\Program Files\Common Files\$pkgid. There's a very good reason for this: a library cannot discover its installation location like an executable can, because it could be linked in to an executable anywhere on the system. Hence if a library needs access to auxiliary data files, they better be in a fixed place in the filesystem. A library with data files cannot be fully relocatable at install-time.
This might be some unix trick, but in Windows you can at least * Use resource strings * Use registry And indeed, if that's the purpose, Common Files is pretty much the right directory. But, this is mainly for *widespread* libraries. In general it is much better that the application does the installing of library's data files and then tells library where they are. I don't really care, I think. Libraries that are not prepared for relocation are not ready for publishing in Windows, IMHO.
However, we do need to change where docs go (they don't have to go in $datadir, and they can be relocated at install-time).
Assuming docs are haddock generated, aren't they actually pretty much fixed because of links? Best regards, Esa

On Wed, Aug 08, 2007 at 09:19:04AM +0100, Simon Marlow wrote:
For a library, data files go in C:\Program Files\Common Files\$pkgid. There's a very good reason for this: a library cannot discover its installation location like an executable can, because it could be linked in to an executable anywhere on the system. Hence if a library needs access to auxiliary data files, they better be in a fixed place in the filesystem.
If a library needs auxiliary data files, how are they meant to get installed when someone makes a binary release of a program available? Thanks Ian
participants (5)
-
Duncan Coutts
-
Esa Ilari Vuokko
-
Ian Lynagh
-
Neil Mitchell
-
Simon Marlow