-
Notifications
You must be signed in to change notification settings - Fork 714
Applying flag normalisation to local packages. #5287
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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?
Cabal/Distribution/Simple/Build.hs
Outdated
@@ -171,8 +172,9 @@ repl pkg_descr lbi flags suffixes args = do | |||
let clbi = targetCLBI target | |||
comp = targetComponent target | |||
lbi' = lbiForComponent comp lbi | |||
replFlags = toNubListR $ replReplOptions flags |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
cabal-install/changelog
Outdated
@@ -1,6 +1,10 @@ | |||
-*-change-log-*- | |||
|
|||
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/it's/its/
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... |
Cabal/doc/nix-local-build.rst
Outdated
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/This flags/This flag/
Cabal/doc/nix-local-build.rst
Outdated
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing full stop. Should specify that it's versions of Cabal.
Cabal/doc/nix-local-build.rst
Outdated
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/flag/flags/
Cabal/doc/nix-local-build.rst
Outdated
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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!