Skip to content
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

Use response files for ghc invocations #9367

Merged

Conversation

Gabriella439
Copy link
Contributor

@Gabriella439 Gabriella439 commented Oct 24, 2023

Before this change, cabal could fail with the following error message when building very large Haskell packages:

ghc: createProcess: posix_spawnp: resource exhausted (Argument list too long)

This is because when the number of modules or dependencies grows large enough, then the ghc command line can potentially exceed the ARG_MAX command line length limit.

However, ghc supports response files in order to work around these sorts of command line length limitations, so this change enables the use of those response files.

Note that this requires taking a special precaution to not pass RTS options to the response file because there's no way that ghc can support RTS options via the response file. The reason why is because the Haskell runtime processes these options (not ghc), so if you store the RTS options in the response file then ghc's command line parser won't know what to do with them.

This means that ghc commands can still potentially fail if the RTS options get long enough, but this is less likely to occur in practice since RTS options tend to be significantly smaller than non-RTS options.

This also requires skipping the response file if the first argument is --interactive. See the corresponding code comment which explains why in more detail.

Please read Github PR Conventions and then fill in one of these two templates.


Template Α: This PR modifies cabal behaviour

Include the following checklist in your PR:

Bonus points for added automated tests!

Depends-on: #10292

@Gabriella439
Copy link
Contributor Author

Note that this has been tested internally at Mercury not just for cabal commands but also downstream tools (like ghcid and haskell-language-server), which is how we stumbled upon the hie-bios issue.

We ran into this issue when building our internal Haskell monolith (which has ~7000 Haskell modules), and we verified that this change fixes the problem without breaking anything else.

Copy link
Collaborator

@geekosaur geekosaur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you run fourmolu on this (make style)? That check is failing.

Cabal/src/Distribution/Simple/Program/GHC.hs Outdated Show resolved Hide resolved
@Gabriella439 Gabriella439 force-pushed the gabriella/response_files_2 branch 2 times, most recently from bbe0bd2 to b689455 Compare October 24, 2023 23:10
Cabal/src/Distribution/Simple/Program/GHC.hs Outdated Show resolved Hide resolved
Cabal/src/Distribution/Simple/Program/GHC.hs Outdated Show resolved Hide resolved
Copy link
Member

@Kleidukos Kleidukos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot @Gabriella439 for this contribution. 🙇

@Kleidukos
Copy link
Member

@Gabriella439
Copy link
Contributor Author

Gabriella439 commented Oct 27, 2023

I'm trying to reproduce the problem locally, but when I run ./validate.sh -s build && ./validate.sh -s lib-suite I get a whole bunch of tests being skipped with "SKIP no cabal-install" and I'm not sure how to fix that

Copy link
Collaborator

@mpickering mpickering left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a good direction of travel to me.

I want to block this being merged until there is a way to keep the response file around.

A very common workflow for me is to copy the command line which cabal invokes GHC with so that I can debug GHC issues without going through cabal, it seems this patch would regress that workflow.

@9999years 9999years force-pushed the gabriella/response_files_2 branch from 9e4dad2 to b0ef42d Compare August 29, 2024 21:21
9999years added a commit to MercuryTechnologies/cabal that referenced this pull request Aug 29, 2024
Currently, `cabal repl` has a `--keep-temp-files` option, and
`cabal.project` has a `keep-temp-files` option but it only effects
Haddock builds.

This patch adds `--keep-temp-files` to `CommonSetupFlags`, making it
available to all commands. The expanded `--keep-temp-files` flag is used
for the `cabal repl` command and Haddock builds (retaining compatibility
with the previous behavior). The flag will also be used for response
files; see haskell#9367.
@9999years 9999years force-pushed the gabriella/response_files_2 branch 6 times, most recently from eff868d to 6d2f9f3 Compare September 3, 2024 19:09
@9999years
Copy link
Collaborator

The requested support for preserving the temp files ended up being much more complicated to implement than I thought it would be, and I just wanted to check with the maintainers to make sure I'm on the right track.

I've put the flag in SetupCommonOptions because those are already passed to the build functions that need them, and I've attempted to thread it through the conversion functions in D.C.ProjectConfig.Legacy, but I keep getting test failures from the value getting dropped somewhere in the round-trip conversion; this is with cabal test cabal-install:unit-tests --test-options="-p ProjectConfig":

projectConfigKeepTempFiles = -NoFlag +Flag False,

Am I missing something? Is there a simpler way of doing this?

@9999years 9999years force-pushed the gabriella/response_files_2 branch 7 times, most recently from e170a59 to 7d04b62 Compare September 5, 2024 16:36
@9999years 9999years force-pushed the gabriella/response_files_2 branch 2 times, most recently from 07570f9 to 25d97f8 Compare September 6, 2024 19:57
@9999years
Copy link
Collaborator

Ready for review, but we should probably merge #10292 first for the --keep-temp-files changes.

@geekosaur
Copy link
Collaborator

Added a dependency so Mergify will hold off until it's merged.

@9999years 9999years force-pushed the gabriella/response_files_2 branch from 25d97f8 to b021b34 Compare November 7, 2024 22:42
@9999years 9999years force-pushed the gabriella/response_files_2 branch 2 times, most recently from 44b913b to 2f72704 Compare November 19, 2024 22:54
@9999years
Copy link
Collaborator

Ready for review! #10292 is merged and I've added a release note.

@Mikolaj
Copy link
Member

Mikolaj commented Nov 20, 2024

@mpickering: I'm guessing your comment is addressed? Would you like have a second look?

@9999years 9999years requested a review from mpickering November 22, 2024 23:30
@mpickering mpickering added the merge me Tell Mergify Bot to merge label Dec 5, 2024
@mergify mergify bot added ready and waiting Mergify is waiting out the cooldown period merge delay passed Applied (usually by Mergify) when PR approved and received no updates for 2 days labels Dec 5, 2024
Copy link
Contributor

mergify bot commented Dec 7, 2024

This pull request has been removed from the queue for the following reason: pull request branch update failed.

The pull request can't be updated.

You should look at the reason for the failure and decide if the pull request needs to be fixed or if you want to requeue it.

If you want to requeue this pull request, you need to post a comment with the text: @mergifyio requeue

@geekosaur
Copy link
Collaborator

@Gabriella439, since you made this PR from your work account, you must rebase it manually and use the merge+no rebase label because neither Mergify nor we are allowed to update it (no access to your employer's GitHub organization).

@geekosaur geekosaur removed the merge me Tell Mergify Bot to merge label Dec 7, 2024
Before this change, `cabal` could fail with the following error message
when building very large Haskell packages:

```
ghc: createProcess: posix_spawnp: resource exhausted (Argument list too long)
```

This is because when the number of modules or dependencies grows large
enough, then the `ghc` command line can potentially exceed the
`ARG_MAX` command line length limit.

However, `ghc` supports response files in order to work around these
sorts of command line length limitations, so this change enables the
use of those response files.

Note that this requires taking a special precaution to not pass RTS
options to the response file because there's no way that `ghc` can
support RTS options via the response file.  The reason why is because
the Haskell runtime processes these options (not `ghc`), so if you
store the RTS options in the response file then `ghc`'s command line
parser won't know what to do with them.

This means that `ghc` commands can still potentially fail if the RTS
options get long enough, but this is less likely to occur in practice
since RTS options tend to be significantly smaller than non-RTS
options.

This also requires skipping the response file if the first argument
is `--interactive`.  See the corresponding code comment which explains
why in more detail.

Co-Authored-By: Gabriella Gonzales <[email protected]>
@9999years 9999years force-pushed the gabriella/response_files_2 branch from 2f72704 to 6549f2d Compare December 9, 2024 17:16
@9999years 9999years added merge me Tell Mergify Bot to merge merge+no rebase labels Dec 9, 2024
@mergify mergify bot merged commit 949464d into haskell:master Dec 9, 2024
42 checks passed
Copy link
Contributor

mergify bot commented Dec 9, 2024

This pull request has been removed from the queue for the following reason: pull request dequeued.

Pull request #9367 has been dequeued. Pull request automatically merged by a merge action.

You should look at the reason for the failure and decide if the pull request needs to be fixed or if you want to requeue it.

If you want to requeue this pull request, you need to post a comment with the text: @mergifyio requeue

@9999years 9999years deleted the gabriella/response_files_2 branch December 9, 2024 17:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merge delay passed Applied (usually by Mergify) when PR approved and received no updates for 2 days merge me Tell Mergify Bot to merge merge+no rebase ready and waiting Mergify is waiting out the cooldown period
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants