Thursday, August 26, 2010
Speeding up your cabal builds
Every waited too long for your cabal builds to finish? If that’s because you have multiple executable sections in your .cabal file, then there might be a solution.
By default, cabal rebuilds all relevant object files for each executable in separation. In other words, object files are not shared between executables. So if you have n executables and m source files, then cabal needs n * m compilation steps plus n link steps to rebuild the executables, no matter whethe any source file contributes to multiple executables.
Starting with cabal 1.8, there is a better solution, provided your executables have some source files in common. In this case, you might build a library from these common source files and then link the executables against the library. In the example above, if all n executables use the same set of m source files, then you end up with m compilation steps plus n + 1 link steps. Sounds good, doesn’t it?!
Here is a simple .cabal file that demonstrates how linking against an internal library works:
Name: test Version: 0.1 Synopsis: test package for linking against internal libraries Author: Stefan Wehr Build-type: Simple Cabal-version: >=1.8 -- IMPORTANT Library Hs-source-dirs: lib -- IMPORTANT Exposed-modules: A Build-Depends: base >= 4 Executable test-exe Build-depends: base >= 4, test, -- link against the internal library Main-is: Main.hs -- imports A Hs-source-dirs: prog -- IMPORTANT
There are some things to consider:
- The Cabal-Version must be greater or equal 1.8.
- The library and the executable must not use common source directories, otherwise the compiler does not pick the library but recompiles the source files.
- The library must be mentioned in the Build-depends of the executable
Running cabal build now gives the following output:
Building test-0.1... [1 of 1] Compiling A ( lib/A.hs, dist/build/A.o ) Registering test-0.1... [1 of 1] Compiling Main ( prog/Main.hs, dist/build/test-exe/test-exe-tmp/Main.o ) Linking dist/build/test-exe/test-exe ...
No rebuilding of A when compiling Main!!!
This feature of cabal isn’t mentioned in the manual, at least I didn’t find it. Further, there seems to be no changelog for cabal. I found out about this feature by browsing the bug tracker for cabal. Is there a better way to get informed of new features of cabal?
Note: I successfully tested this with cabal-install version 0.8.2 (cabal library 22.214.171.124). I couldn’t get it to work with cabal-install version 0.8.0.
Author: Stefan Wehr