Three questions about patch to cabal
jeremy.shaw at linspireinc.com
Mon Jul 17 20:45:13 EDT 2006
At Thu, 13 Jul 2006 12:26:22 +0100,
Simon Marlow wrote:
> Jeremy Shaw wrote:
> > (1) Flag sanity checking
> > Not all combinations of flags are sensible. For example, we can
> > already specify:
> There's another restriction I know of: if the code uses Template Haskell, then
> --enable-library-vanilla will always be required. Since the extensions used are
> all listed in the .cabal file, checking this will be easy.
Hrm, that puts me back in the same situation I am in now -- not having
a good way to split the profiling libraries into a separate package.
I have written up some of my thoughts below. I would love to hear
opinions from any interested parties, such as compiler writers,
package maintainers, end users, etc.
My overall goal is to add some flags to Cabal that will make it
easier for package maintainers to provide several variations of the
same library in separate packages. For example, separate packages for
the library compiled: vanilla, profiling, smp, bytecode, etc. If a
package (such as the profiling) needs files that are already in
another package (such as vanilla), it will simply depend on the other
package. (i.e. it will *not* contain a second copy of the files)
Currently, in order to split the profiling and vanilla libraries into
separate .debs, I have to do some fancy hacking in the Debian
specific dh_haskell script. If someone wants to build .rpms, they
will probably come up with their own hacks to achieve the same goal.
Clearly, this should be fixed at the Cabal level, instead of having
each package maintainer come up with a duplicate set of hacks.
Proper Level Of Abstraction
Cabal is nice because it hides all the nasty compiler and platform
specific build issues from the user. The user puts *what* they want
in the .cabal file, and they let Cabal take care of the *how*.
I think it is very desirable to retain this abstraction in the
configure flags as much as possible. To me, this means that the
Should have a specified behavior that is compiler and platform
independent. It is the job of the compiler specific Cabal code to
meet the spec. (e.g. Distribution.Simple.GHC, etc)
Appropriate Level of Error Reporting
Some options never make sense, for example:
We can check for that nonsense all the time.
But the are other combinations of flags that only make sense from a
maintainers point of view. The typical end user would just end up
with a broken library install.
So I propose we enable strict flag checking by default, but provide a
flag, such as --maintainer-mode, that loosen the restrictions.
It is difficult to make a specification that all compilers can
meet. For example, most compilers do not support profiling, so they
can not support the --enable-*-profiling flag at the moment. In this
case, we could just extend the spec to say that it is an error to
enable profiling for a compiler that does not support profiling.
On the other hand, someone might make a compiler that does not allow
you to install the vanilla and profiling libraries at the same
time. Now you have the problem that you do want to have a -prof .deb,
but it is going to work different from the 'standard'.
Of course, the specifications are supposedly reasonable
specifications that are dictated by the actual needs of the users and
the package maintainers. So, I think in most cases, having a
specification to meet will make it easier for compiler writers, since
they will not have to learn the hard way that certain features are
There will be exceptions. That is why, for example, the .cabal file
has compiler specific fields like ghc-options even though it has the
Extensions field. I am not quite sure how that translates to
How to Handle GHC + Profiling + TemplateHaskell
Profiling + TemplateHaskell Question
I currently only have 6.4.1 installed -- as far as I can tell,
profiling + TH does not work at all in 6.4.1. In ghc head, if I do,
ghc --make -prof Test.hs -o test
Does the compiler automatically build the vanilla objects and then
build the profiling objects? Or do I need to first build without
-prof, and then build with -prof?
I think I can implement a solution in three incremental steps:
(1) Add finer granularity configure flags
(2) Add sanity checking to the argument processing
(3) Add some 'speed' hacks
How It Would Work In Cabal
The spec for the flags:
--maintainer --disable-library-vanilla --enable-library-profiling
is something like,
+ build the libraries with profiling enabled
+ copy out just the files needed add profiling support to a system
that already has the vanilla libraries available
+ this assumes that the profiling and vanilla libraries can co-exist
(i.e. do not have conflicting files, etc)
Here is how the Cabal code for GHC would meet that spec:
(1) In the 'build' phase:
(i) if ghc requires you to explicitly build the vanilla libraries
before building the profiling libraries, then do that.
(ii) build the profiling libraries
(2) In the 'install/copy' phase, *only* copy the profiling libraries
(NOTE: This is actually quite easy -- I have already implemented it
Downside Of This Solution
The downside of the above implementation is that the vanilla
libraries will be built twice. Once for installation in the -vanilla
package, and a second time when trying to create the -prof package.
Unsafe Speed Hacks:
In most cases, the above solution will be fine. But, if you are
dealing with a package where building the vanilla libraries twice is a
huge overhead, then it might be worthwhile to try to use one the hacks
presented below. The downside is they require you to understand the
situations in which they can be safely used. These hacks are a perhaps
a bit like unsafePerformIO, unsafeCoerce, etc ;)
change copy/install to allow selective copy
Add the flags --copy-only-profiling --copy-only-vanilla. This
solution works for vanilla and profiling, because they contain
uniquely named output files. But, if you want to build with and with
out the -O2 flag, then you really do have to run the build phase
If we did not delete the vanilla libraries before building the
profiling libraries, then we would only have to build them once. On
the other hand, if we look at our -O2 example, it *would* require a
'clean' between builds.
Your Comments Here
If you have any suggestions, see any pitfalls, or have a completely
different idea about how to solve this problem, please let me know. I
think the approach is pretty conservative -- so if it does not work
out, we should still be in a good position to try a different
approach. But, anything we can learn now will certainly help :)
More information about the Libraries