
On Tue, Feb 28, 2012 at 1:53 AM, Simon Marlow
I don't see how we could avoid including -D, since it might really affect the source of the module that GHC eventually sees. We've never taken -D into account before, and that was incorrect. I can't explain the behaviour you say you saw with older GHC's. unless your CPP flags only affected the imports of the module.
In fact, that's what I do. I put system specific stuff or expensive stuff into a module and then do #ifdef EXPENSIVE_FEATURE import qualified ExpensiveFeature #else import qualified StubbedOutFeature as ExpensiveFeature #endif I think this is a pretty common strategy. I know it's common for os-specific stuff, e.g. filepath does this. Although obviously for OS stuff we're not interested in saving recompilation :)
Well, one solution would be to take the hash of the source file after preprocessing. That would be accurate and would automatically take into account -D and -I in a robust way. It could also cause too much recompilation, if for example a preprocessor injected some funny comments or strings containing the date/time or detailed version numbers of components (like the gcc version).
By "take the hash of the source file" do you mean the hash of the textual contents, or the usual hash of the interface etc? I assumed it was the latter, i.e. that the normal hash was taken after preprocessing. But suppose it's the former, I still think it's better than unconditional recompilation (which is what always including -D in the hash does, right?). Unconditionally including -D in the hash either makes it *always* compile too much--and likely drastically too much, if you have one module out of 300 that switches out depending on a compile time flag, you'll still recompile all 300 when you change the flag. And there's nothing you can really do about it if you're using --make. If you try to get around that by using a build system that knows which files it has to recompile, then you get in a situation where the files have been compiled with different flags, and now ghci can't cope since it can't switch flags while loading. If your preprocessor does something like put the date in... well, firstly I think that's much less common than switching out module imports, since for the latter as far as I know CPP is the only way to do it, while for dates or version numbers you'd be better off with a config file anyway. And it's still correct, right? You changed your gcc version or date or whatever, if you want a module to have the build date then of course you have to rebuild the module every time---you got exactly what you asked for. Even if for some reason you have a preprocessor that nondeterministically alters comments, taking the interface hash after preprocessing would handle that. And come to think of it, these are CPP flags not some arbitrary pgmF... can CPP even do something like insert the current date without also changing its -D flags?