Applying flag normalisation to local packages. - #5287
Conversation
Move package flag normalisation code for the new-build hash into it's own `normaliseConfiguredPackage` function and reuse it to detect whether the configuration of a local package has changed and needs to be rebuild.
Strip empty arguments lists from the elabProgramArgs in ElaboratedConfiguredPackage to eliminate spurious configuration changes being found.
|
Apparently not so straight-forward, as this seems to cause ghci to ignore arguments when running |
|
Ping @dcoutts, @ezyang, @23Skidoo You all seem to be responsible for the majority of the code in Setting the StageThere's a whole bunch of GHC flags that don't affect the output, so we don't want to uselessly rebuild. For dependencies this was fixed and merged by normalising the flags going into the dependency hash. However, local/inplace packages are handled differently, they are covered by a Why is that a problem? I have a Obviously this gets annoying quickly if those local packages take a non-trivial time to compile. The Problem"I know!", I said optimistically, "I'll just change the package So, the Why? After a lot of sleuthing I figured out that Possible SolutionsSo here's where I need you guys to chime in. I've brainstormed a bunch of (partial) solutions, each with it's own trade-offs and I need some feedback.
Pros & ConsBoth 1 & 3 keep the indirection via serialised build info between cabal-install and repl by invoking 2 is fast and trivial to implement. We can skip the configure step for the repl, just pass in all the GHC arguments directly. Downside is, some of the arguments we're passing in may already be in the stored build info on disk, so we end up passing them twice to ghci. I'm not sure whether that could cause problems or not, which is why I'm a bit hesitant about this approach. ConclusionI think we should try to keep the normalisation for local packages, because it does safe me a considerable amount of compile time. We should probably add a flag for Ideally, we should avoid calling configure just to store repl flags it slows things down for no good reason. But this would mean we need an entirely different approach to how the |
|
Yes, (2) seems like the right approach. The mental model I have is that there are "slow" flags and there are "fast" flags; ostensibly you only want to reconfigure when a slow flag changes, but you want all invocations to be affected by changes to fast flags whenever. So those better be passed through and not scrubbed, as you noticed. Perhaps the reason (2) is not the obvious solution is that, based on your description, it sounds like flag normalization doesn't really classify flags as fast or slow, it just munges the flags until you have a new "flag set" that is "normalized". So to "properly" fix this we may need to add a new concept. It's been a while since I've read the code so I am not sure. |
|
Currently flag normalisation doesn't do any sort of classification, as I just did the simplest thing possible to reduce recompiles of dependencies. There's still a bunch of design space and trade-offs to talk about (for example, I currently let warning flags trigger rebuilds of dependencies if I actually did have an epiphany after writing this up that would push things in the right direction. One of the issue here is that
This gets rid of useless recompiles of local packages. Does not affect old repl behaviour at all. Code changes can be confined to the |
|
And finally we're getting somewhere! I still need to test and dogfood this a bit, but this'd be a good time for people to start looking over the code. |
ezyang
left a comment
There was a problem hiding this comment.
If this has dogfooded well, I don't have objections to merging it. There aren't any BC-breaking changes to the ./Setup CLI interface, are there?
| let clbi = targetCLBI target | ||
| comp = targetComponent target | ||
| lbi' = lbiForComponent comp lbi | ||
| replFlags = toNubListR $ replReplOptions flags |
There was a problem hiding this comment.
Is this going to be sane if, e.g., the repl options are -trust base -trust containers? Or is that somehow guaranteed not to happen and the only things in replReplOptions are safe to de-dupe?
There was a problem hiding this comment.
Good question, I'd have to test that a bit. Most of the obvious REPL flags are probably not affected and I'm not sure "-trust" even makes sense here? (Since that seems like it should affect the build outcome?). Sadly there's no real "safe" way of deduping stuff (I'm not even sure the current use of NubListR is completely sensible in the presence of space separated flags?)
A simple solution might be to simply break the NubListR invariant by manually wrapping the list with the newtype, that avoids any doubt about whether things could break (but is rather hacky)...
There was a problem hiding this comment.
Yeah, I can't say definitively if this is a problem either. It just looks suspicious to me in the context of #5369, which removed a load of nub operations on argument lists.
There was a problem hiding this comment.
Oh, actually, master no longer uses NubListR it seems. I only used that because I was forced by the types of the GHC config. So seems the problem is trivially solved by rebasing onto master and just eliminating NubListR entirely. I wasn't using it myself anyway.
|
@ezyang About backwards compatiblity: I'm not 100% sure, because honestly I still don't get the internals well enough to say. I added the --repl-options flag to "cabal repl" too (because all new-X commands end up getting re-parsed by the old ones) and extended the ReplFlags type. I don't think adding a flag should affect backwards compat, so the only issue might be the ReplFlags record type? But as long as people use the empty/default variable and initialise fields there, that shouldn't break compat either, right? |
|
Ok, so the only problematic bit (aside from the new flag for |
59bd528 to
fb67b25
Compare
|
Accidentally closed when fiddling with the branch... |
4a16d11 to
079580d
Compare
|
Adding a new optional flag is good; signing off! |
f3b52f1 to
00347f8
Compare
|
|
||
| 2.4.0.0 (current development version) | ||
| * Add '--repl-options' flag to 'cabal repl' and 'cabal new-repl' | ||
| commands. Passes it's arguments to the invoked repl, bypassing the |
|
Changelog notes look good. There's a |
|
Yeah, I've been testing it locally and a bunch of people told me they start using it and so far no one's complained, so if the latest CI finishes without any errors from rebasing I'm gonna merge it. |
|
Actually, maybe that's not useful to wait for. As far as I can tell a large amount of tests are just very broken in ways unrelated to my changes right now... |
| flags are now stripped from ``ghc-options``. As a result ``--ghc-options`` will | ||
| no longer (reliably) work to pass flags to ``ghci`` (or other repls). Instead, | ||
| you should use the new ``--repl-options`` flag to specify these options to the | ||
| invoked repl. (This flags also works on ``cabal repl`` and ``Setup repl`` on |
There was a problem hiding this comment.
s/This flags/This flag/
| no longer (reliably) work to pass flags to ``ghci`` (or other repls). Instead, | ||
| you should use the new ``--repl-options`` flag to specify these options to the | ||
| invoked repl. (This flags also works on ``cabal repl`` and ``Setup repl`` on | ||
| sufficiently new versions) |
There was a problem hiding this comment.
Missing full stop. Should specify that it's versions of Cabal.
| GHCi as interpreted bytecode. It takes the same flags as | ||
| ``cabal new-build``. | ||
| GHCi as interpreted bytecode. In addition to the ``cabal new-build``'s flags, | ||
| it takes an additional ``--repl-options`` flags. |
| it takes an additional ``--repl-options`` flags. | ||
|
|
||
| To avoid ``ghci`` specific flags from triggering unneeded global rebuilds these | ||
| flags are now stripped from ``ghc-options``. As a result ``--ghc-options`` will |
There was a problem hiding this comment.
I got momentarily confused here between ghc-options the Cabal file field, and --ghc-options the command-line argument, which is what are being talked about here, right? Worth clarifying.
There was a problem hiding this comment.
To be honest, it refers to both. --ghc-options the flag and ghc-options the field end up in the same data structure that gets filtered, so this applies in both cases.
|
Still seeing some failures on Travis, but I don't understand at all why those are failing. I see all sorts of doctest warnings, warnings about unrecognised ghc 8.7 versions (in the tests for 7.4), so all-in-all I'm a bit lost how to get everything passing again. |
|
#5389 is seeing similar weird failures, so it's probably not your code but something else somewhere that's broken. HEAD is currently green, so I guess that something is environmental. I do note that |
|
Actually looks like wherever the tests fetch GHC HEAD from has updated. 3 out of 4 failures fail with "unsupported GHC in /opt/ghc/head/bin", looking at the reported version of GHC it was updated yesterday, so presumably all green tests ran before the remote source updated and every test since late yesterday is failing. I don't know what to do about this, though. |
|
Oh, you're right. It looks like the proximal cause is that the error message has changed in GHC HEAD as well, in at least some of the tests. I think I can fix that. |
|
hvr was already looking at it too, after I asked on IRC. |
|
I just put up #5392, which hopefully fixes the residual problems; hvr got to the 'unsupported GHC versions' error message ahead of me. |
56eba60 to
a9ab437
Compare
|
Seems to be one weird error left: https://travis-ci.org/haskell/cabal/jobs/395597958#L1131-L1133 I pushed another commit to print the actual failing value, but it's not printing anything, so it'd seems to be failing in the cabal that's trying to build cabal for testing. So I dunno if that's breakage in the cabal that ships with 8.2.2 or that I broke something... |
|
Seems like we're using |
|
On the basis that I can't see how the PR could've caused an error before any code was even being built and how it wasn't failing in this way earlier, I'm tempted to blame intermittent Travis weridness for this latest error, and I've restarted the build to see if it comes back good. |
|
Nope, still happening. Quite baffling: this PR doesn't touch the package description at all, and other recent builds have succeeded so it's not some kind of global weirdness with the Hackage state. I can only assume it's something like some ordering-dependent bad case and this PR is unlucky enough that its component hashes are tickling it. |
2364701 to
a9ab437
Compare
|
Yeah, I'd restarted it a bunch of times already so far. Maybe rebasing it on master will churn it enough to get fixed again. |
a9ab437 to
cbcfc43
Compare
|
Ha! After @hvr cleared the build cache this is finally in the realm of happy green checkmarks. |
Continuing efforts from #4247, apply similar recompilation avoidance to local packages as well. Need to look into how this interacts with new-haddock.
Please include the following checklist in your PR:
[ci skip]is used to avoid triggering the build bots.Please also shortly describe how you tested your change. Bonus points for added tests!