-
Notifications
You must be signed in to change notification settings - Fork 696
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
Add support for loading multiple components into one repl session #8726
Conversation
Tests and documentation are coming, here to test against CI. |
bd9c69d
to
3b02302
Compare
CI seems broken currently:
|
37e25d8
to
5c0f4a7
Compare
Yes, thank you, CI was broken. Please kindly rebase. I hope we have hacked around that. |
d58a1f6
to
6b95a4a
Compare
Actually, this time, the third CI fix will really fix your PR's run. Let me rebase myself... |
@mergify rebase |
To get the future behavior now, you can configure Or you can create a dedicated github account for squash and rebase operations, and use it in different |
✅ Branch has been successfully rebased |
6b95a4a
to
bcf661f
Compare
6b95a4a
to
743dcb3
Compare
743dcb3
to
0eed781
Compare
This should be passing CI and ready for review now @Mikolaj I am writing a blog post to describe this feature which might be helpful to read as well. I will post a link once it is finished. |
0eed781
to
27fe0fe
Compare
Can anyone explain why this is failing? https://github.com/haskell/cabal/actions/runs/4262053788/jobs/7417094108 |
Very unfortunate :-( The linker warning looks like what was reported on ghc-devs recently. But I'm not sure if this is the reason for the failure. |
The only error I can find in this log is
|
This may or may not fix it: haskellari/lukko#33 If that's it, for now I'd not worry and review and even merge with this failure. |
But, the other failures are not about GHC 9.6, so I'd worry about those. |
But there is no long. It just says "This job failed". Doh. |
Which probably means this is a GHA outage. Restarting the job may help. |
All done. I ended up implementing the "good" fix. Now we need a maintainer to go over my fixup commits, then I can squash them and finally merge this |
The fix indeed looks very civilized, though I got lost reading the code due to how long the |
When there are multiple home units we need to be able to distinguish between different executables. The way to do this is to pass the `-this-unit-id` flag when compiling the executable. Unfortunately this was broken before ghc-9.2 so there is a guard to check that the compiler version is old enough. It's only critical we do this from GHC-9.4 (when multiple home units was first supported) but there's no harm in always passing this option.
The ./Setup repl command is modified to allow a user to defer starting the repl and instead instruct the command to write the necessary build flags to a file. The option is called --repl-multi-file <FILEPATH>.
It is necessary to modify `./Setup configure` to allow users to configure a package *without* having previously built the dependency. Instead, we promise to the configure phase that we will have built it by the time we build the package. This allows us to configure all the packages we intend to load into the repl without building any dependenices which we will load in the same session, because the promise is satisifed due to loading the package and it's dependency into one multi-session which ensures the dependency is built before it is needed. A user of ./Setup configure specifies a promised dependency by using the "--promised-dependency" flag with a normal dependency specification. For example: ``` '--promised-dependency=cabal-install-solver=cabal-install-solver-3.9.0.0-inplace' ```
There are several parts to this patch which are logically distinct but work together to support the overal goal of starting a GHCi session with multiple packages loaded at once. 1. When a user writes "cabal repl <target>" then if the user is using a compiler > ghc-9.4.* then we will attempt to start a multi-session which loads the selected targets into one multi-package session of GHC. 1a. The closure property states that in order to load components `p` and `q` into the same session that if `p` depends on `z` and `z` depends on `q` then `z` must also be loaded into the session. 1b. Only inplace packages are able to be loaded into a multi session (if a component `z` exists then it is already made into an inplace package by cabal). Therefore cabal has already engineered that there is source code locally available for all packages which we will want to load into a session. 2. The solver is unmodified, the solver is given the repl targets and creates a build plan as before. After the solver is completed then in `setRootTargets` and `pruneInstallPlan` we modify the install plan to enforce the closure property and mark which dependencies need to be promised. * Mark the current components as `BuildInPlaceOnly InMemory`, which indicates to the compiler that it is to be built in a GHC multi-session. * Augment the component repl targets to indicate that components required by the closure property (in addition to normal targets) will be loaded into the repl. * Modify the dependency edges in `compLibDependencies` to indicate which dependencies are the promised ones (which is precisely components which are `BuildInPlaceOnly InMemory` build styles). This is the field which is eventually used to populate the `--dependency` argument to `./Setup configure`. Fixes haskell#8491
🎉 Great work everyone, this is gonna be mega! |
Top notch PR and top notch teamwork. Thank you everyone. |
This adds a multi-repl-enabled (see haskell/cabal#8726) cabal (using a recent commit from `master`) to the shell. When using GHC >=9.4, one can then run e.g. ```console cabal-multi-repl repl ouroboros-consensus ouroboros-consensus-diffusion ``` to get a REPL with all components in `ouroboros-consensus` and `ouroboros-consensus-diffusion` 🎉 `ghcid` also works, e.g. ```console ghcid -c 'cabal-multi-repl repl ...' ``` Beware that this feature is still somewhat experimental, e.g. `cabal-multi-repl repl ouroboros-consensus-cardano` (or also `-protocol`) are stalling for me, and selecting individual components involving sublibraries fails with this message: ```console $ cabal-multi-repl repl ouroboros-consensus:consensus-testlib ouroboros-consensus:consensus-test Error: Dependency on unbuildable library 'consensus-testlib' from ouroboros-consensus ``` Still, this might already be useful, and should not have any risks/maintenance burden.
This change pulls cabal HEAD for haskell/cabal#8726 through `pkgs.cabal-multi-repl` instead of `pkgs.cabal-install`.
This change uses haskell/cabal#8726 .
This change uses haskell/cabal#8726 .
There are several parts to this patch which are logically distinct but work together to support the overal goal of starting a GHCi session with multiple packages loaded at once.
When a user writes "cabal repl " then if the user is using a compiler > ghc-9.4.* then we will attempt to start a multi-session which loads the selected targets into one multi-package session of GHC. 1a. The closure property states that in order to load components
p
andq
intothe same session that if
p
depends onz
andz
depends onq
then
z
must also be loaded into the session.1b. Only inplace packages are able to be loaded into a multi session (if a component
z
exists then it is already made into an inplace package bycabal). Therefore cabal has already engineered that there is source
code locally available for all packages which we will want to load
into a session.
It is necessary to modify
./Setup configure
to allow users to configure a package without having previously built the dependency. Instead, we promise to the configure phase that we will have built it by the time we build the package. This allows us to configure all the packages we intend to load into the repl without building any dependenices which we will load in the same session, because the promise is satisifed due to loading the package and it's dependency into one multi-session which ensures the dependency is built before it is needed.A user of ./Setup configure specifies a promised dependency by prepending a "+" to a normal dependency specification. For example:
2a. The
./Setup repl
command is modified to allow a user to deferstarting the repl and instead instruct the command to write the
necessary build flags to a file. The option is called
--repl-multi-file <FILEPATH>
.The solver is unmodified, the solver is given the repl targets and creates a build plan as before. After the solver is completed then in
setRootTargets
andpruneInstallPlan
we modify the install plan to enforce the closure property and mark which dependencies need to be promised.BuildInPlaceOnly InMemory
, which indicates to the compiler that it is to be built in a GHC multi-session.compLibDependencies
to indicate which dependencies are the promised ones (which is precisely components which areBuildInPlaceOnly InMemory
build styles). This is the field which is eventually used to populate the--dependency
argument to./Setup configure
.Please include the following checklist in your PR:
Please also shortly describe how you tested your change. Bonus points for added tests!