
On 7/29/05, Isaac Jones
Brian Smith
writes: (one of which I am working on).
Can you tell me more about the tool you're working on?
Well, right now it is just a couple of really simple tools. One simply continuously builds a project. That is, if you execute: cabal-listen path/to/Package.cabal then, it automatically runs "runghc Setup.hs configure" when the Cabal file changes, it automatically does "runghc Setup.hs build" when any other file is modified, and it does "runghc Setup.hs clean && runghc Setup.hs build" when files are renamed or moved. If any errors are found (currently by grepping through the output) then it it automatically opens my editor to the location of the first error. Pressing "n" and "p" cycle through the errors. The program is efficient about listening for file changes because it uses the Windows File Change Notification API, but on large packages it is too slow to build. My hope is that I will be able to use the GHC API to improve the efficiency of the building process, by keeping GHC's internal data structures for the package cached in memory between builds, and only updating them on a module-by-module basis. Next week I want to convert it to wxHaskell. The other tool takes a Cabal file, and lists all the modules that are defined in that package, where you can e.g. double click on the module to open it in an editor or browse its structure (top-level bindings). It uses wxHaskell. I also used the GHC API to build a very crude Haddock-like tool that allowed me to browse the GHC API when I was learning it. Haddock doesn't handle GHC's recursive modules well. Using the GHC API also allowed me to do type inference automatically. But, Haddock is really a lot more polished (for example, my tool does automatic hyperlinking, but it just displays the comments in their raw form, and it doesn't reorganize things into sections and subsections)
For example, an IDE might use the GHC API to implement an "incremental build" feature, which would rebuild projects upon detecting changes to the source files (like Eclipse does). Futhermore, it might want to provide context-sensitive features like autocomplete that Cabal doesn't provide, and that requires knowledge of all source code dependencies in the source code.
I don't understand what you mean; how does this involve the simple build system if you're using the GHC API?
I think what VHS.NET does--and what I am/was planning to do--is use Cabal files as projects, but reimplement Distribution.Simple.Build et. al. to work in an better in an "interactive" GUI environment than the current system, which is batch-compile oriented. In particular, VHS.NET and maybe my tool will use the GHC API extensively. For example, using the GHC API I can do dependency analysis that will allow me to say "build just this one source file because that other source file changed." But, Cabal always restarts dependency analysis over at the root modules, which make it too slow for interactive use. I am not sure exactly how the eclipsefp tool builds files but it pauses for too long during saving (Eclipse rebuilds after every save). As another example, I want to be able to typecheck a module inside an editor when the file hasn't been saved yet (like Java tools do). I don't see how I can reliably reuse the Cabal library to do that. I also want to know which names are in scope at a particular location in a source file. In order to do that, I need to know all of the current modules dependencies (and the current module might not even have been saved even once yet.)
I don't see how my suggestion is limiting users,
It limits users by blocking out those who use their own build infrastructure.
Well, if you took out the "hooks" part of my suggestion, then I expect Cabal's API would be the same. The only limitations would come in tools that use Cabal package descriptions but don't use Cabal's API's. Or alternatively, I want to build tools that have optimizations for Cabal packages that don't require arbitrary code to execute during the build process.
I thought you were suggesting that a stand-alone executable read and interpret the .cabal file, then execute functions from only a pre-determined set of build infrastructures. Perhaps you're saying that the stand-alone executable should run pre-determined build infrastructures if it knows about them and otherwise the user has to provide a Setup.lhs file which gets executed with the "system" call?
Exactly. We could even change it to "Setup-Module:" Then, adding a "cabal-setup" tool would be minor change. Imagine such a cabal-setup tool with logic like this: If the "Build-Infrastructure" is Simple Then If there are not hooks Then -- Does not require any arbitrary code to build Distribution.Simple.defaultMain Else Dstribution.Simple.defaultMainWithHooks .... End If Else -- The setup module can do whatever it wants. Use runghc/runhugs/whatever. to execute the module identified, and return whatever exit code it returns. End If
if ppl do use the simple build infrastructure. Right now the cabal interface is conservative so we can get a better idea of how people use it. If 90% of people end up using the same Setup.lhs file, then we'll probably stop requiring it and add a caveat that says "if there's no Setup script, then use the 'standard' one."
I think that makes a lot of sense. Peace, Brian