diff --git a/.github/workflows/haskell.yml b/.github/workflows/haskell.yml
--- a/.github/workflows/haskell.yml
+++ b/.github/workflows/haskell.yml
@@ -22,6 +22,7 @@
           , "9.4"
           , "9.6"
           , "9.8"
+          , "9.10"
           ]
 
     steps:
diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,14 @@
+## v0.9.0.0 (2024-12-02)
+
+Release v0.9.0.0
+
+- Migrate to cabal-3.10 branch. This introduces a dependency on
+  `directory >=1.3.7.0`. This effectively means that, moving forward,
+  >=dev-lang/ghc-9.4 is required for newer versions of hackport on
+  Gentoo.
+
+- Hackport now builds with ghc-9.10
+
 ## v0.8.5.2 (2024-12-01)
 
 Release v0.8.5.2
diff --git a/cabal/.git-blame-ignore-revs b/cabal/.git-blame-ignore-revs
--- a/cabal/.git-blame-ignore-revs
+++ b/cabal/.git-blame-ignore-revs
@@ -4,6 +4,9 @@
 # Make Cabal-syntax package
 a64b9aea0839cd7183dfae1e94455b870a3d5812
 
+# Fix whitespace violations
+b1f59dde5b2f456d9698584598d7f571abe433a8
+
 # 2020 Summer
 ########################################
 
diff --git a/cabal/.github/dependabot.yml b/cabal/.github/dependabot.yml
new file mode 100644
--- /dev/null
+++ b/cabal/.github/dependabot.yml
@@ -0,0 +1,15 @@
+# From:
+# - https://github.com/haskell/hackage-server
+# - https://github.com/rhysd/actionlint/issues/228#issuecomment-1272493095
+# - https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot
+
+# Set update schedule for GitHub Actions
+
+version: 2
+updates:
+
+  - package-ecosystem: "github-actions"
+    directory: "/"
+    schedule:
+      # Check for updates to GitHub Actions every week
+      interval: "weekly"
diff --git a/cabal/.github/mergify.yml b/cabal/.github/mergify.yml
--- a/cabal/.github/mergify.yml
+++ b/cabal/.github/mergify.yml
@@ -1,4 +1,19 @@
 pull_request_rules:
+
+  # implementing PR delay logic: apply a label after 2 days of inactivity
+  # the label will allow Mergify to merge (see #8442, #8448)
+  - actions:
+      label:
+        add:
+          - merge delay passed
+    name: Wait for 2 days before validating merge
+    conditions:
+      - updated-at<2 days ago
+      - or:
+        - label=merge me
+        - label=squash+merge me
+      - '#approved-reviews-by>=2'
+
   # rebase+merge strategy
   - actions:
       queue:
@@ -9,8 +24,11 @@
         update_method: rebase
     name: Put pull requests in the rebase+merge queue
     conditions:
+      - base=master
       - label=merge me
+      - label=merge delay passed
       - '#approved-reviews-by>=2'
+
   # merge+squash strategy
   - actions:
       queue:
@@ -21,8 +39,51 @@
         update_method: merge
     name: Put pull requests in the squash+merge queue
     conditions:
+      - base=master
       - label=squash+merge me
+      - label=merge delay passed
       - '#approved-reviews-by>=2'
+
+  # rebase+merge strategy for backports: require 1 approver instead of 2
+  - actions:
+      queue:
+        name: default
+        # Merge with a merge commit
+        method: merge
+        # Update the pr branch with rebase, so the history is clean
+        update_method: rebase
+    name: Put backports in the rebase+merge queue
+    conditions:
+      - label=merge me
+      - base!=master
+      - body~=backport
+      - label=merge delay passed
+      - '#approved-reviews-by>=1'
+
+  # merge+squash strategy for backports: require 1 approver instead of 2
+  - actions:
+      queue:
+        name: default
+        method: squash
+        # both update methods get absorbed by the squash, so we use the most
+        # reliable
+        update_method: merge
+    name: Put pull requests in the squash+merge queue
+    conditions:
+      - label=merge me
+      - base!=master
+      - body~=backport
+      - label=merge delay passed
+      - '#approved-reviews-by>=1'
+
+  # backports should be labeled as such
+  - actions:
+      label:
+        add:
+          - backport
+    name: Label backports as such
+    conditions:
+      - body~=automatic backport
 
 queue_rules:
   - name: default
diff --git a/cabal/.github/workflows/bootstrap.yml b/cabal/.github/workflows/bootstrap.yml
--- a/cabal/.github/workflows/bootstrap.yml
+++ b/cabal/.github/workflows/bootstrap.yml
@@ -19,27 +19,50 @@
     strategy:
       matrix:
         os: [ubuntu-latest]
-        ghc: ["8.6.5", "8.8.4", "8.10.7", "9.0.2", "9.2.3"]
+        ghc: ["8.10.7", "9.0.2", "9.2.8", "9.4.8"]
         include:
           - os: macos-latest
-            ghc: "9.2.3"
+            ghc: "9.2.8"
     name: Bootstrap ${{ matrix.os }} ghc-${{ matrix.ghc }}
     runs-on: ${{ matrix.os }}
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/cache@v3
+        name: Cache the downloads
+        id: bootstrap-cache
+        with:
+          path: "/home/runner/work/cabal/cabal/_build"
+          key: bootstrap-${{ runner.os }}-${{ matrix.ghc }}-20221115-${{ github.sha }}
+          restore-keys: bootstrap-${{ runner.os }}-${{ matrix.ghc }}-20221115-
+
+      - uses: actions/checkout@v3
+      # See https://github.com/haskell/cabal/pull/8739
+      - name: Sudo chmod to permit ghcup to update its cache
+        run: |
+          if [[ "${{ runner.os }}" == "Linux" ]]; then
+            sudo ls -lah /usr/local/.ghcup/cache
+            sudo mkdir -p /usr/local/.ghcup/cache
+            sudo ls -lah /usr/local/.ghcup/cache
+            sudo chown -R $USER /usr/local/.ghcup
+            sudo chmod -R 777 /usr/local/.ghcup
+          fi
       - name: bootstrap.py
         run: |
           GHC_VERSION=${{ matrix.ghc }}
+          ghcup --version
           ghcup config set cache true
           ghcup install ghc $GHC_VERSION
-          # We use linux dependencies also on macos
-          python3 bootstrap/bootstrap.py -w $(ghcup whereis ghc $GHC_VERSION) -d bootstrap/linux-$GHC_VERSION.json
 
+          # Fetch the bootstrap sources (we use linux dependencies also on macos)
+          python3 bootstrap/bootstrap.py -w $(ghcup whereis ghc $GHC_VERSION) -d bootstrap/linux-$GHC_VERSION.json fetch
+
+          # Bootstrap using the bootstrap sources
+          python3 bootstrap/bootstrap.py -w $(ghcup whereis ghc $GHC_VERSION) --bootstrap-sources bootstrap-sources.tar.gz
+
       - name: Smoke test
         run: |
           _build/bin/cabal --version
 
-      - uses: actions/upload-artifact@v2
+      - uses: actions/upload-artifact@v3
         with:
           name: cabal-${{ matrix.os }}-${{ matrix.ghc }}-bootstrapped
           path: _build/artifacts/*
diff --git a/cabal/.github/workflows/changelogs.yml b/cabal/.github/workflows/changelogs.yml
--- a/cabal/.github/workflows/changelogs.yml
+++ b/cabal/.github/workflows/changelogs.yml
@@ -29,23 +29,30 @@
         # https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#adding-a-system-path
         run: |
           echo "$HOME/.cabal/bin" >> $GITHUB_PATH
-      - uses: actions/cache@v1
+      - uses: actions/cache@v3
         with:
           path: ~/.cabal/store
           key: linux-store-changelogs
+      # See https://github.com/haskell/cabal/pull/8739
+      - name: Sudo chmod to permit ghcup to update its cache
+        run: |
+          if [[ "${{ runner.os }}" == "Linux" ]]; then
+            sudo mkdir -p /usr/local/.ghcup/cache
+            sudo chown -R $USER /usr/local/.ghcup
+            sudo chmod -R 777 /usr/local/.ghcup
+          fi
       - name: ghcup
         run: |
           ghcup config set cache true
-          ghcup install ghc 8.10.7
-          ghcup set ghc 8.10.7
-      # GHC 8.10.7 needed due to https://github.com/phadej/changelog-d/pull/2
+          ghcup install ghc recommended
+          ghcup set ghc recommended
       - name: Update Hackage index
         run: cabal v2-update
       # Cannot install it from tarball due to
       # https://github.com/haskell/cabal/issues/7360
       - uses: actions/checkout@v3
         with:
-          repository: "phadej/changelog-d"
+          repository: "fgaz/changelog-d"
           path: "changelog-d"
       - name: Install changelog-d
         run: |
diff --git a/cabal/.github/workflows/quick-jobs.yml b/cabal/.github/workflows/quick-jobs.yml
--- a/cabal/.github/workflows/quick-jobs.yml
+++ b/cabal/.github/workflows/quick-jobs.yml
@@ -24,20 +24,31 @@
         # https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#adding-a-system-path
         run: |
           echo "$HOME/.cabal/bin" >> $GITHUB_PATH
-      - uses: actions/cache@v1
+      - uses: actions/cache@v3
         with:
           path: ~/.cabal/store
           key: linux-store-meta
+      # See https://github.com/haskell/cabal/pull/8739
+      - name: Sudo chmod to permit ghcup to update its cache
+        run: |
+          if [[ "${{ runner.os }}" == "Linux" ]]; then
+            sudo ls -lah /usr/local/.ghcup/cache
+            sudo mkdir -p /usr/local/.ghcup/cache
+            sudo ls -lah /usr/local/.ghcup/cache
+            sudo chown -R $USER /usr/local/.ghcup
+            sudo chmod -R 777 /usr/local/.ghcup
+          fi
       - name: ghcup
         run: |
+          ghcup --version
           ghcup config set cache true
           ghcup install ghc recommended
           ghcup set ghc recommended
       - name: Update Hackage index
         run: cabal v2-update
       - name: Install alex
-        run: cabal v2-install alex --constraint='alex ==3.2.6'
-      - uses: actions/checkout@v2
+        run: cabal v2-install alex --constraint='alex ==3.2.7.3'
+      - uses: actions/checkout@v3
       - name: Regenerate files
         run: |
           make -B lexer
@@ -54,32 +65,30 @@
       - name: Set PATH
         run: |
           echo "$HOME/.cabal/bin" >> $GITHUB_PATH
-      - name: Install cabal-env
-        run: |
-          mkdir -p $HOME/.cabal/bin
-          curl -sL https://github.com/phadej/cabal-extras/releases/download/preview-20191225/cabal-env-snapshot-20191225-x86_64-linux.xz > cabal-env.xz
-          echo "1b567d529c5f627fd8c956e57ae8f0d9f11ee66d6db34b7fb0cb1c370b4edf01  cabal-env.xz" | sha256sum -c -
-          xz -d < cabal-env.xz > $HOME/.cabal/bin/cabal-env
-          rm -f cabal-env.xz
-          chmod a+x $HOME/.cabal/bin/cabal-env
-      - uses: actions/cache@v1
+      - uses: actions/cache@v3
         with:
           path: ~/.cabal/store
           key: linux-store-doctest
+      # See https://github.com/haskell/cabal/pull/8739
+      - name: Sudo chmod to permit ghcup to update its cache
+        run: |
+          if [[ "${{ runner.os }}" == "Linux" ]]; then
+            sudo ls -lah /usr/local/.ghcup/cache
+            sudo mkdir -p /usr/local/.ghcup/cache
+            sudo ls -lah /usr/local/.ghcup/cache
+            sudo chown -R $USER /usr/local/.ghcup
+            sudo chmod -R 777 /usr/local/.ghcup
+          fi
       - name: ghcup
         run: |
+          ghcup --version
           ghcup config set cache true
-          ghcup install ghc 8.10.7
-          ghcup set ghc 8.10.7
+          ghcup install ghc --set recommended
+          ghcup install cabal --set latest
       - name: Update Hackage index
         run: cabal v2-update
+      - uses: actions/checkout@v3
       - name: Install doctest
-        run: cabal v2-install doctest
-      - name: Install libraries
-        run: |
-          cabal-env --transitive QuickCheck
-          cabal-env array bytestring containers deepseq directory filepath pretty process time binary unix text parsec mtl
-          cat $HOME/.ghc/*/environments/default
-      - uses: actions/checkout@v2
+        run: make doctest-install
       - name: Doctest
         run: make doctest
diff --git a/cabal/.github/workflows/users-guide.yml b/cabal/.github/workflows/users-guide.yml
--- a/cabal/.github/workflows/users-guide.yml
+++ b/cabal/.github/workflows/users-guide.yml
@@ -46,15 +46,15 @@
     runs-on: ubuntu-latest
     strategy:
       matrix:
-        python-version: [3.7]
+        python-version: ['3.10']
 
     steps:
-    - uses: actions/checkout@v2
+    - uses: actions/checkout@v3
       with:
         submodules: recursive
 
     - name: Set up Python ${{ matrix.python-version }}
-      uses: actions/setup-python@v2
+      uses: actions/setup-python@v4
       with:
         python-version: ${{ matrix.python-version }}
 
@@ -67,7 +67,7 @@
       run: |
         make SPHINX_HTML_OUTDIR=html users-guide
 
-    - uses: actions/upload-artifact@v2
+    - uses: actions/upload-artifact@v3
       with:
         name: users-guide-html
         path: html/
diff --git a/cabal/.github/workflows/validate.yml b/cabal/.github/workflows/validate.yml
--- a/cabal/.github/workflows/validate.yml
+++ b/cabal/.github/workflows/validate.yml
@@ -23,10 +23,10 @@
 env:
   # We choose a stable ghc version across all os's
   # which will be used to do the next release
-  GHC_FOR_RELEASE: '9.2.3'
+  GHC_FOR_RELEASE: '9.2.8'
   # Ideally we should use the version about to be released for hackage tests and benchmarks
-  GHC_FOR_SOLVER_BENCHMARKS: '9.2.3'
-  GHC_FOR_COMPLETE_HACKAGE_TESTS: '9.2.3'
+  GHC_FOR_SOLVER_BENCHMARKS: '9.2.8'
+  GHC_FOR_COMPLETE_HACKAGE_TESTS: '9.2.8'
   COMMON_FLAGS: '-j 2 -v'
 
 jobs:
@@ -37,31 +37,51 @@
       GHC_FOR_RELEASE: ${{ format('["{0}"]', env.GHC_FOR_RELEASE) }}
     strategy:
       matrix:
-        os: ["ubuntu-latest", "macos-latest", "windows-latest"]
-        ghc: ["9.2.3", "9.0.2", "8.10.7", "8.8.4", "8.6.5", "8.4.4"]
+        os: ["ubuntu-20.04", "macos-latest", "windows-latest"]
+        ghc: ["9.4.8", "9.2.8", "9.0.2", "8.10.7", "8.8.4", "8.6.5", "8.4.4"]
         exclude:
+          # Run takes 4+ hours
+          - os: "windows-latest"
+            ghc: "9.0.2"
           # corrupts GHA cache or the fabric of reality itself, see https://github.com/haskell/cabal/issues/8356
           - os: "windows-latest"
             ghc: "8.10.7"
           # lot of segfaults caused by ghc bugs
           - os: "windows-latest"
             ghc: "8.8.4"
+          # it also throws segfaults randomly
           - os: "windows-latest"
             ghc: "8.4.4"
+          # it often randomly does "C:\Users\RUNNER~1\AppData\Local\Temp\ghcFEDE.c: DeleteFile "\\\\?\\C:\\Users\\RUNNER~1\\AppData\\Local\\Temp\\ghcFEDE.c": permission denied (Access is denied.)"
+          - os: "windows-latest"
+            ghc: "8.6.5"
 
     steps:
 
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
 
-      - uses: haskell/actions/setup@v1
+      # See https://github.com/haskell/cabal/pull/8739
+      - name: Sudo chmod to permit ghcup to update its cache
+        run: |
+          if [[ "${{ runner.os }}" == "Linux" ]]; then
+            sudo ls -lah /usr/local/.ghcup/cache
+            sudo mkdir -p /usr/local/.ghcup/cache
+            sudo ls -lah /usr/local/.ghcup/cache
+            sudo chown -R $USER /usr/local/.ghcup
+            sudo chmod -R 777 /usr/local/.ghcup
+          fi
+      - uses: haskell-actions/setup@v2
         id: setup-haskell
         with:
           ghc-version: ${{ matrix.ghc }}
-          cabal-version: latest # default, keeping for visibility
+          cabal-version: '3.10.1.0'
 
       #  See the following link for a breakdown of the following step
       #  https://github.com/haskell/actions/issues/7#issuecomment-745697160
-      - uses: actions/cache@v2
+      #
+      # See https://github.com/haskell/cabal/pull/8739 for why Windows is excluded
+      - if: ${{ runner.os != 'Windows' }}
+        uses: actions/cache@v3
         with:
           # validate.sh uses a special build dir
           path: |
@@ -147,7 +167,7 @@
       # - Make it available in the workflow to make easier testing it locally
       - name: Upload cabal-install executable to workflow artifacts
         if: matrix.cli != 'false' && matrix.ghc == env.GHC_FOR_RELEASE
-        uses: actions/upload-artifact@v2
+        uses: actions/upload-artifact@v3
         with:
           name: cabal-${{ runner.os }}-${{ matrix.ghc }}
           path: ${{ env.CABAL_EXEC_TAR }}
@@ -170,9 +190,140 @@
         if: matrix.cli != 'false'
         run: sh validate.sh $FLAGS -s cli-suite
 
+  # The job below is a copy-paste of validate with the necessary tweaks
+  # to make all work with an upcoming GHC. Those tweaks include:
+  # - ghcup needs the prerelease channel activated
+  # - allow-newer for base libraries and Cabal* libraries
+  # - (sometimes) disabling some parts on Windows because it's hard to figure
+  #   out why they fail
+  validate-prerelease:
+    # TODO: reenable when the next GHC prerelease appears
+    if: false
+
+    name: Validate ${{ matrix.os }} ghc-prerelease
+    runs-on: ${{ matrix.os }}
+    outputs:
+      GHC_FOR_RELEASE: ${{ format('["{0}"]', env.GHC_FOR_RELEASE) }}
+    strategy:
+      matrix:
+        os: ["ubuntu-20.04", "macos-latest", "windows-latest"]
+
+    steps:
+
+      - uses: actions/checkout@v3
+
+      # See https://github.com/haskell/cabal/pull/8739
+      - name: Sudo chmod to permit ghcup to update its cache
+        run: |
+          if [[ "${{ runner.os }}" == "Linux" ]]; then
+            sudo ls -lah /usr/local/.ghcup/cache
+            sudo mkdir -p /usr/local/.ghcup/cache
+            sudo ls -lah /usr/local/.ghcup/cache
+            sudo chown -R $USER /usr/local/.ghcup
+            sudo chmod -R 777 /usr/local/.ghcup
+          fi
+
+      - name: ghcup
+        run: |
+          ghcup --version
+          ghcup config set cache true
+          ghcup config add-release-channel https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-prereleases-0.0.7.yaml
+          ghcup install ghc --set 9.6.0.20230210
+          ghcup install cabal --set latest
+          ghc --version
+          cabal update
+
+      #  See the following link for a breakdown of the following step
+      #  https://github.com/haskell/actions/issues/7#issuecomment-745697160
+      #
+      # See https://github.com/haskell/cabal/pull/8739 for why Windows is excluded
+      - if: ${{ runner.os != 'Windows' }}
+        uses: actions/cache@v3
+        with:
+          # validate.sh uses a special build dir
+          path: |
+            ${{ steps.setup-haskell.outputs.cabal-store }}
+            dist-*
+          key: ${{ runner.os }}-${{ matrix.ghc }}-20220419-${{ github.sha }}
+          restore-keys: ${{ runner.os }}-${{ matrix.ghc }}-20220419-
+
+      - name: Work around git problem https://bugs.launchpad.net/ubuntu/+source/git/+bug/1993586 (cabal PR #8546)
+        run: |
+          git config --global protocol.file.allow always
+
+      # The '+exe' constraint below is important, otherwise cabal-install
+      # might decide to build the library but not the executable which is
+      # what we need.
+      - name: Install cabal-plan
+        run: |
+          cd $(mktemp -d)
+          cabal install cabal-plan --constraint='cabal-plan +exe' --allow-newer
+          echo "$HOME/.cabal/bin" >> $GITHUB_PATH
+
+      # The tool is not essential to the rest of the test suite. If
+      # hackage-repo-tool is not present, any test that requires it will
+      # be skipped.
+      # We want to keep this in the loop but we don't want to fail if
+      # hackage-repo-tool breaks or fails to support a newer GHC version.
+      - name: Install hackage-repo-tool
+        continue-on-error: true
+        run: |
+          cd $(mktemp -d)
+          cabal install hackage-repo-tool
+
+      # Needed by cabal-testsuite/PackageTests/Configure/setup.test.hs
+      - name: Install Autotools
+        if: runner.os == 'macOS'
+        run: |
+          brew install automake
+
+      - name: Allow newer boot libraries
+        run: |
+          echo "allow-newer: base, template-haskell, ghc-prim, Cabal-syntax, Cabal-described, Cabal, cabal-install-solver, cabal-install" >> cabal.project.validate
+
+      - name: Set validate inputs
+        run: |
+          FLAGS="${{ env.COMMON_FLAGS }}"
+          if [[ "${{ matrix.cli }}" == "false" ]]; then
+            FLAGS="$FLAGS --lib-only"
+          fi
+          echo "FLAGS=$FLAGS" >> $GITHUB_ENV
+
+      - name: Validate print-config
+        run: sh validate.sh $FLAGS -s print-config
+
+      - name: Validate print-tool-versions
+        run: sh validate.sh $FLAGS -s print-tool-versions
+
+      - name: Validate build
+        run: sh validate.sh $FLAGS -s build
+
+      - name: Validate lib-tests
+        env:
+          # `rawSystemStdInOut reports text decoding errors`
+          # test does not find ghc without the full path in windows
+          GHCPATH: ${{ steps.setup-haskell.outputs.ghc-exe }}
+        run: sh validate.sh $FLAGS -s lib-tests
+
+      - name: Validate lib-suite
+        # see https://github.com/haskell/cabal/pull/8754#issuecomment-1435025848
+        # for discussion about the trouble on Windows
+        if: ${{ runner.os != 'Windows' }}
+        run: sh validate.sh $FLAGS -s lib-suite
+
+      - name: Validate cli-tests
+        if: matrix.cli != 'false'
+        run: sh validate.sh $FLAGS -s cli-tests
+
+      - name: Validate cli-suite
+        # see https://github.com/haskell/cabal/pull/8754#issuecomment-1435025848
+        # for discussion about the trouble on Windows
+        if: ( runner.os != 'Windows' ) && ( matrix.cli != 'false' )
+        run: sh validate.sh $FLAGS -s cli-suite
+
   validate-old-ghcs:
     name: Validate old ghcs ${{ matrix.extra-ghc }}
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-20.04
     needs: validate
     # This job needs an older ubuntu (16.04) cause
     # the required old ghcs using the `-dyn` flavour
@@ -195,7 +346,7 @@
       # cause it does not work with the git version included in it, see:
       # https://github.com/actions/checkout/issues/170
       # https://github.com/actions/checkout/issues/295
-      # - uses: actions/checkout@v2
+      # - uses: actions/checkout@v3
       - name: Checkout
         run: |
           echo $GITHUB_REF $GITHUB_SHA
@@ -208,15 +359,17 @@
           apt-get update
           apt-get install -y ghc-${{ matrix.extra-ghc }}-dyn
 
-      - uses: haskell/actions/setup@v1
+      - uses: haskell-actions/setup@v2
         id: setup-haskell
         with:
           ghc-version: ${{ matrix.ghc }}
+          # Make sure this bindist works in this old environment
+          cabal-version: 3.10.1.0
 
       # As we are reusing the cached build dir from the previous step
       # the generated artifacts are available here,
       # including the cabal executable and the test suite
-      - uses: actions/cache@v2
+      - uses: actions/cache@v3
         with:
           path: |
             ${{ steps.setup-haskell.outputs.cabal-store }}
@@ -247,23 +400,39 @@
     needs: validate
     strategy:
       matrix:
-        os: ["ubuntu-latest", "macos-latest", "windows-latest"]
+        os: ["ubuntu-20.04", "macos-latest", "windows-latest"]
         # We only use one ghc version the used one for the next release (defined at top of the workflow)
         # We need to build an array dynamically to inject the appropiate env var in a previous job,
         # see https://docs.github.com/en/actions/learn-github-actions/expressions#fromjson
         ghc: ${{ fromJSON (needs.validate.outputs.GHC_FOR_RELEASE) }}
 
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
 
-      - uses: haskell/actions/setup@v1
+      # See https://github.com/haskell/cabal/pull/8739
+      - name: Sudo chmod to permit ghcup to update its cache
+        run: |
+          if [[ "${{ runner.os }}" == "Linux" ]]; then
+            sudo ls -lah /usr/local/.ghcup/cache
+            sudo mkdir -p /usr/local/.ghcup/cache
+            sudo ls -lah /usr/local/.ghcup/cache
+            sudo chown -R $USER /usr/local/.ghcup
+            sudo chmod -R 777 /usr/local/.ghcup
+          fi
+      - uses: haskell-actions/setup@v2
         id: setup-haskell
         with:
           ghc-version: ${{ matrix.ghc }}
           cabal-version: latest # default, we are not using it in this job
 
+      - name: Install cabal-plan
+        run: |
+          cd $(mktemp -d)
+          cabal install cabal-plan --constraint='cabal-plan +exe'
+          echo "$HOME/.cabal/bin" >> $GITHUB_PATH
+
       - name: Download cabal executable from workflow artifacts
-        uses: actions/download-artifact@v2
+        uses: actions/download-artifact@v3
         with:
           name: cabal-${{ runner.os }}-${{ matrix.ghc }}
           path: cabal-head
@@ -286,7 +455,7 @@
   validate-post-job:
     if: always()
     name: Validate post job
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-20.04
     # IMPORTANT! Any job added to the workflow should be added here too
     needs: [validate, validate-old-ghcs, dogfooding]
 
diff --git a/cabal/.github/workflows/whitespace.yml b/cabal/.github/workflows/whitespace.yml
new file mode 100644
--- /dev/null
+++ b/cabal/.github/workflows/whitespace.yml
@@ -0,0 +1,57 @@
+name: Assorted
+
+on:
+  push:
+    branches:
+      - master
+  pull_request:
+  release:
+    types:
+      - created
+jobs:
+  check:
+    name: Whitespace
+    runs-on: ubuntu-latest
+
+    env:
+     fix-whitespace-ver: '0.0.10'
+
+    steps:
+    - uses: actions/checkout@v3
+      name: Checkout sources
+
+    - name: Create directory for binary
+      run: |
+        mkdir -p $HOME/.local/bin
+
+    - uses: actions/cache@v3
+      name: Cache the binary
+      id: cache
+      with:
+        path: "~/.local/bin"
+        key: fix-whitespace-${{ env.fix-whitespace-ver }}
+
+    # See https://github.com/haskell/cabal/pull/8739
+    - name: Sudo chmod to permit ghcup to update its cache
+      run: |
+        if [[ "${{ runner.os }}" == "Linux" ]]; then
+          sudo mkdir -p /usr/local/.ghcup/cache
+          sudo chown -R $USER /usr/local/.ghcup
+          sudo chmod -R 777 /usr/local/.ghcup
+        fi
+
+    - uses: haskell/actions/setup@v2
+      if: ${{ !steps.cache.outputs.cache-hit }}
+      with:
+        ghc-version: '9.2'
+        cabal-version: latest
+
+    - name: Install fix-whitespace
+      if: ${{ !steps.cache.outputs.cache-hit }}
+      run: |
+        cabal install --constraint=aeson==2.1.2.1 --ignore-project --install-method=copy --installdir=$HOME/.local/bin fix-whitespace-${{ env.fix-whitespace-ver }}
+        strip $HOME/.local/bin/fix-whitespace
+
+    - name: Check the whitespace issue
+      run: |
+        $HOME/.local/bin/fix-whitespace --check
diff --git a/cabal/.gitignore b/cabal/.gitignore
--- a/cabal/.gitignore
+++ b/cabal/.gitignore
@@ -68,6 +68,7 @@
 # windows test artifacts
 cabal-testsuite/**/*.exe
 cabal-testsuite/**/*.bat
+cabal-testsuite/**/haddocks
 
 # python artifacts from documentation builds
 *.pyc
@@ -82,3 +83,13 @@
 
 # Emacs
 .projectile
+
+# I'm unsure how to ignore these generated golden files
+cabal-testsuite/PackageTests/NewUpdate/RejectFutureIndexStates/cabal.out
+
+## Release Scripts
+
+# ignore the downloaded binary files
+scripts/release/binary-downloads/
+scripts/release/fetch-gitlab/
+scripts/release/*.json
diff --git a/cabal/.gitlab-ci.yml b/cabal/.gitlab-ci.yml
--- a/cabal/.gitlab-ci.yml
+++ b/cabal/.gitlab-ci.yml
@@ -1,11 +1,9 @@
 stages:
   - build
 
-# Used for ci setup in the gitlab mirror of the project:
-# https://gitlab.haskell.org/haskell/haskell-language-server/-/pipelines
 variables:
   # Commit of ghc/ci-images repository from which to pull Docker images
-  DOCKER_REV: "4ed1a4f27828ba96a34662dc954335e29b470cd2"
+  DOCKER_REV: "572353e0644044fe3a5465bba4342a9a0b0eb60e"
 
   GHC_VERSION: 9.2.3
   CABAL_INSTALL_VERSION: 3.6.2.0
@@ -28,86 +26,60 @@
     paths:
       - out/*
 
-build-aarch64-linux-deb10:
-  extends: .build
-  tags:
-    - aarch64-linux
-  image: "registry.gitlab.haskell.org/ghc/ci-images/aarch64-linux-deb10:$DOCKER_REV"
-  variables:
-    TARBALL_ARCHIVE_SUFFIX: aarch64-linux-deb10
-    TARBALL_EXT: tar.xz
-    ADD_CABAL_ARGS: ""
-    # this permits building pre-releases that are not on Hackage
-    CABAL_INSTALL_VERSION: 3.4.0.0
-
-build-armv7-linux-deb10:
-  extends: .build
-  tags:
-    - armv7-linux
-  image: "registry.gitlab.haskell.org/ghc/ci-images/armv7-linux-deb10:$DOCKER_REV"
-  variables:
-    TARBALL_ARCHIVE_SUFFIX: armv7-linux-deb1
-    TARBALL_EXT: tar.xz
-    ADD_CABAL_ARGS: ""
-    # this permits building pre-releases that are not on Hackage
-    CABAL_INSTALL_VERSION: 3.4.0.0
-  retry: 2
-
-build-x86_64-linux:
+build-linux:
   extends: .build
+  parallel:
+    matrix:
+      - ARCH: i386
+        TAG: x86_64-linux
+        OS:
+          - deb9
+      - ARCH: x86_64
+        TAG: x86_64-linux
+        OS:
+          - centos7
+          - deb9
+          - fedora33
+          - rocky8
+          - ubuntu18_04
+          - ubuntu20_04
+          - deb10
+          - deb11
+      - ARCH: aarch64
+        TAG: aarch64-linux
+        OS:
+          - deb10
+          - deb11
   tags:
-    - x86_64-linux
-  image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV"
+    - $TAG
+  image: "registry.gitlab.haskell.org/ghc/ci-images/$PLATFORM:$DOCKER_REV"
   variables:
-    TARBALL_ARCHIVE_SUFFIX: x86_64-linux-deb10
+    PLATFORM: "${ARCH}-linux-${OS}"
+    TARBALL_ARCHIVE_SUFFIX: $PLATFORM
     TARBALL_EXT: tar.xz
     ADD_CABAL_ARGS: "--enable-split-sections"
-    # this permits building pre-releases that are not on Hackage
-    CABAL_INSTALL_VERSION: 3.4.0.0
 
-build-x86_64-linux-alpine:
+build-linux-alpine:
   extends: .build
+  parallel:
+    matrix:
+      - ARCH: i386
+        OS: [alpine3_12]
+        GHC_VERSION: 9.0.2
+      - ARCH: x86_64
+        OS: [alpine3_12]
   tags:
     - x86_64-linux
   before_script:
     # for cabal build
     - sudo apk add --no-cache zlib zlib-dev zlib-static
-  image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-alpine3_12:$DOCKER_REV"
+  image: "registry.gitlab.haskell.org/ghc/ci-images/$PLATFORM:$DOCKER_REV"
   variables:
-    TARBALL_ARCHIVE_SUFFIX: x86_64-linux-alpine
+    PLATFORM: "${ARCH}-linux-${OS}"
+    TARBALL_ARCHIVE_SUFFIX: $PLATFORM
     TARBALL_EXT: tar.xz
     ADD_CABAL_ARGS: "--enable-split-sections --enable-executable-static"
-    # this permits building pre-releases that are not on Hackage
-    CABAL_INSTALL_VERSION: 3.4.0.0
 
-build-i386-linux-alpine:
-  extends: .build
-  tags:
-    - x86_64-linux
-  image: "i386/alpine:3.12"
-  before_script:
-    # for GHC
-    - apk add --no-cache bash curl gcc g++ binutils binutils-gold bsd-compat-headers gmp-dev ncurses-dev libffi-dev make xz tar perl
-    # for cabal build
-    - apk add --no-cache zlib zlib-dev zlib-static
-  variables:
-    TARBALL_ARCHIVE_SUFFIX: i386-linux-alpine
-    TARBALL_EXT: tar.xz
-    ADD_CABAL_ARGS: "--enable-split-sections --enable-executable-static"
-    # this permits building pre-releases that are not on Hackage
-    CABAL_INSTALL_VERSION: 3.4.0.0
-
-build-x86_64-freebsd12:
-  extends: .build
-  tags:
-    - x86_64-freebsd12
-  variables:
-    TARBALL_ARCHIVE_SUFFIX: x86_64-freebsd12
-    TARBALL_EXT: tar.xz
-    ADD_CABAL_ARGS: "--enable-split-sections"
-    # this permits building pre-releases that are not on Hackage
-    CABAL_INSTALL_VERSION: 3.4.0.0
-
 build-x86_64-darwin:
   extends: .build
   tags:
@@ -116,8 +88,6 @@
     TARBALL_ARCHIVE_SUFFIX: x86_64-darwin
     TARBALL_EXT: tar.xz
     ADD_CABAL_ARGS: ""
-    # this permits building pre-releases that are not on Hackage
-    CABAL_INSTALL_VERSION: 3.4.0.0
 
 build-aarch64-darwin:
   stage: build
@@ -143,12 +113,15 @@
     TARBALL_ARCHIVE_SUFFIX: aarch64-darwin
     TARBALL_EXT: tar.xz
     ADD_CABAL_ARGS: ""
-    # this permits building pre-releases that are not on Hackage
-    CABAL_INSTALL_VERSION: 3.4.0.0
+    # Update periodically.
+    BREW_VERSION: 4.0.5
   artifacts:
     expire_in: 2 week
     paths:
       - out/*
+  cache:
+    paths:
+      - .brew
 
 build-x86_64-windows:
   extends: .build
@@ -161,6 +134,4 @@
     TARBALL_ARCHIVE_SUFFIX: x86_64-windows
     TARBALL_EXT: zip
     ADD_CABAL_ARGS: ""
-    # this permits building pre-releases that are not on Hackage
-    CABAL_INSTALL_VERSION: 3.4.0.0
   retry: 2
diff --git a/cabal/.gitlab/brew.sh b/cabal/.gitlab/brew.sh
--- a/cabal/.gitlab/brew.sh
+++ b/cabal/.gitlab/brew.sh
@@ -1,10 +1,18 @@
 #!/usr/bin/env bash
 
-set -Eeuxo pipefail
+set -Eeuo pipefail
 
 # Install brew locally in the project dir. Packages will also be installed here.
-[ -e "$CI_PROJECT_DIR/.brew" ] || git clone --depth=1 https://github.com/Homebrew/brew $CI_PROJECT_DIR/.brew
-export PATH="$CI_PROJECT_DIR/.brew/bin:$CI_PROJECT_DIR/.brew/sbin:$PATH"
+# FIXME: Use brew in supported way. See
+# https://docs.brew.sh/Installation#untar-anywhere-unsupported
+brew_dir="${CI_PROJECT_DIR}/.brew"
+
+if [ ! -e "${brew_dir}" ]; then
+    mkdir -p "${brew_dir}"
+    curl -L "https://github.com/Homebrew/brew/archive/refs/tags/${BREW_VERSION}.tar.gz" | tar xz --strip 1 -C "${brew_dir}"
+fi
+
+export PATH="${brew_dir}/bin:${brew_dir}/sbin:$PATH"
 
 # make sure to not pollute the machine with temp files etc
 mkdir -p $CI_PROJECT_DIR/.brew_cache
diff --git a/cabal/.gitlab/ci.sh b/cabal/.gitlab/ci.sh
--- a/cabal/.gitlab/ci.sh
+++ b/cabal/.gitlab/ci.sh
@@ -1,6 +1,6 @@
 #!/usr/bin/env bash
 
-set -Eeuxo pipefail
+set -Eeuo pipefail
 
 source "$CI_PROJECT_DIR/.gitlab/common.sh"
 
@@ -8,15 +8,15 @@
 export CABAL_DIR="$CI_PROJECT_DIR/cabal"
 
 case "$(uname)" in
-	MSYS_*|MINGW*)
-		export CABAL_DIR="$(cygpath -w "$CABAL_DIR")"
-		GHCUP_BINDIR="${GHCUP_INSTALL_BASE_PREFIX}/ghcup/bin"
-		EXE_EXT=".exe"
-		;;
-	*)
-		GHCUP_BINDIR="${GHCUP_INSTALL_BASE_PREFIX}/.ghcup/bin"
-		EXE_EXT=""
-		;;
+    MSYS_*|MINGW*)
+        export CABAL_DIR="$(cygpath -w "$CABAL_DIR")"
+        GHCUP_BINDIR="${GHCUP_INSTALL_BASE_PREFIX}/ghcup/bin"
+        EXE_EXT=".exe"
+        ;;
+    *)
+        GHCUP_BINDIR="${GHCUP_INSTALL_BASE_PREFIX}/.ghcup/bin"
+        EXE_EXT=""
+        ;;
 esac
 
 mkdir -p "$CABAL_DIR"
@@ -26,29 +26,34 @@
 export BOOTSTRAP_HASKELL_NONINTERACTIVE=1
 export BOOTSTRAP_HASKELL_GHC_VERSION=$GHC_VERSION
 export BOOTSTRAP_HASKELL_CABAL_VERSION=$CABAL_INSTALL_VERSION
-export BOOTSTRAP_HASKELL_VERBOSE=1
 export BOOTSTRAP_HASKELL_ADJUST_CABAL_CONFIG=yes
+# We don't use stack, and it isn't available on i386-deb9
+export BOOTSTRAP_HASKELL_INSTALL_NO_STACK=yes
 
 # for some reason the subshell doesn't pick up the arm64 environment on darwin
 # and starts installing x86_64 GHC
 case "$(uname -s)" in
-	"Darwin"|"darwin")
-		case "$(/usr/bin/arch)" in
-			aarch64|arm64|armv8l)
-				curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | arch -arm64 /bin/bash
-				;;
-			*)
-				curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh
-				;;
-		esac
-		;;
-	*)
-		curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh
-		;;
+    "Darwin"|"darwin")
+        case "$(/usr/bin/arch)" in
+            aarch64|arm64|armv8l)
+                curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | arch -arm64 /bin/bash
+                ;;
+            *)
+                curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh
+                ;;
+        esac
+        ;;
+    *)
+        curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh
+        ;;
 esac
 
 # https://github.com/haskell/cabal/issues/7313#issuecomment-811851884
-if [ "$(getconf LONG_BIT)" == "32" ] ; then
+# and
+# https://github.com/haskellari/lukko/issues/17
+#
+# $PLATFORM comes from CI.
+if [ "$(getconf LONG_BIT)" = "32" -o "${PLATFORM:=xxx}" = "x86_64-linux-centos7" ] ; then
     echo 'constraints: lukko -ofd-locking' >> cabal.project.release.local
 fi
 
@@ -60,6 +65,7 @@
     ${ADD_CABAL_ARGS}
 )
 
+run cabal update hackage.haskell.org,HEAD
 run cabal v2-build ${args[@]} cabal-install
 
 mkdir "$CI_PROJECT_DIR/out"
diff --git a/cabal/.readthedocs.yml b/cabal/.readthedocs.yml
--- a/cabal/.readthedocs.yml
+++ b/cabal/.readthedocs.yml
@@ -3,7 +3,11 @@
 sphinx:
   configuration: doc/conf.py
 
+build:
+  os: "ubuntu-22.04"
+  tools:
+    python: "3.8"
+
 python:
-  version: 3.7
   install:
     - requirements: doc/requirements.txt
diff --git a/cabal/CONTRIBUTING.md b/cabal/CONTRIBUTING.md
--- a/cabal/CONTRIBUTING.md
+++ b/cabal/CONTRIBUTING.md
@@ -4,16 +4,19 @@
 --------------------------
 
 The current recommended way of developing Cabal is to use the
-`v2-build` feature which [shipped in cabal-install-1.24](http://blog.ezyang.com/2016/05/announcing-cabal-new-build-nix-style-local-builds/).  Assuming
-that you have a sufficiently recent cabal-install (see above),
-it is sufficient to run:
+`v2-build` feature which [shipped in cabal-install-1.24](http://blog.ezyang.com/2016/05/announcing-cabal-new-build-nix-style-local-builds/).  If you use the latest version of cabal published on Hackage, it is sufficient to run:
 
 ```
 cabal v2-build cabal
 ```
 
-To build a local, development copy of cabal-install.  The location
-of your build products will vary depending on which version of
+If not, you aren't able to build the testsuite, so you need to disable the default `cabal.project` that implies configuring the testsuite, e.g., with:
+
+```
+cabal v2-build --project-file=cabal.project.release cabal
+```
+
+The location of your build products will vary depending on which version of
 cabal-install you use to build; see the documentation section
 [Where are my build products?](http://cabal.readthedocs.io/en/latest/nix-local-build.html#where-are-my-build-products)
 to find the binary (or just run `find -type f -executable -name cabal`).
@@ -113,11 +116,35 @@
 `cabal run <test-target>` in order to test locally.
 
 
-Conventions
------------
+Whitespace Conventions
+----------------------
 
-* Spaces, not tabs.
+* No tab characters allowed.
+* No trailing whitespace allowed.
+* File needs to be terminated by a newline character.
 
+These conventions are enforced by the
+[fix-whitespace](https://hackage.haskell.org/package/fix-whitespace)
+tool.  Install it from hackage as usual (`cabal install fix-whitespace`)
+and run it in the project root to fix whitespace violations.
+
+The files included in the automatic whitespace check are specified in
+`fix-whitespace.yaml`.  Please add to this file if you add textfiles
+to this repository that are not included by the rules given there.
+Note that files that make essential use of tab characters (like `Makefile`)
+should _not_ be included in the automatic check.
+
+Whitespace conventions are enforced by
+[CI](https://github.com/haskell/cabal/actions/workflows/whitespace.yml).
+If you push a fix of a whitespace violation, please do so in a
+_separate commit_.
+
+
+
+
+Other Conventions
+-----------------
+
 * Try to follow style conventions of a file you are modifying, and
   avoid gratuitous reformatting (it makes merges harder!)
 
@@ -183,6 +210,40 @@
 
 [guide]: https://github.com/tibbe/haskell-style-guide/blob/master/haskell-style.md
 
+GitHub Ticket Conventions
+-------------------
+
+Each major `Cabal`/`cabal-install` release (e.g. 3.4, 3.6, etc.) has a
+corresponding GitHub Project and milestone. A ticket is included in a release's
+project if the release managers are tenatively planning on including a fix for
+the ticket in the release, i.e. if they are actively seeking someone to work on
+the ticket.
+
+By contrast, a ticket is milestoned to a given release if we are open to
+accepting a fix in that release, i.e. we would very much appreciate someone
+working on it, but are not committing to actively sourcing someone to work on
+it.
+
+GitHub Pull Request Conventions
+-------------------
+
+Every (non-backport) pull request has to go through a review and get 2
+approvals. After this is done, the author of the pull request is expected to add
+any final touches they deem important and put the `merge me` label on the pull
+request. If the author lacks permissions to apply labels, they are welcome to
+explicitly signal the merge intent on the discussion thread of the pull request,
+at which point others (e.g., reviewers) apply the label. Merge buttons are
+reserved for exceptional situations, e.g., CI fixes being iterated on or
+backports/patches that need to be expedited for a release.
+
+Currently there is a 2 day buffer for potential extra feedback between the last
+update of a pull request (e.g. a commit, a rebase, an addition of the `merge me`
+label) and the moment the Mergify bot picks up the pull request for a merge.
+
+If your pull request consists of several commits, consider using `squash+merge
+me` instead of `merge me`: the Mergify bot will squash all the commits into one
+and concatenate the commit messages of the commits before merging.
+
 Changelog
 ---------
 
@@ -224,7 +285,7 @@
 [here](https://github.com/haskell/cabal/tree/bc83de27569fda22dbe1e10be1a921bebf4d3430/changelog.d).
 
 At release time, the entries will be merged with
-[this tool](https://github.com/phadej/changelog-d).
+[this tool](https://github.com/fgaz/changelog-d).
 
 In addition, if you're changing the .cabal file format specification you should
 add an entry in `doc/file-format-changelog.rst`.
diff --git a/cabal/Cabal-QuickCheck/Cabal-QuickCheck.cabal b/cabal/Cabal-QuickCheck/Cabal-QuickCheck.cabal
--- a/cabal/Cabal-QuickCheck/Cabal-QuickCheck.cabal
+++ b/cabal/Cabal-QuickCheck/Cabal-QuickCheck.cabal
@@ -1,6 +1,6 @@
 cabal-version: 2.2
 name:          Cabal-QuickCheck
-version:       3.8.1.0
+version:       3.10.1.0
 synopsis:      QuickCheck instances for types in Cabal
 category:      Testing
 description:
@@ -13,8 +13,8 @@
   build-depends:
     , base
     , bytestring
-    , Cabal         ^>=3.8.0.0
-    , Cabal-syntax  ^>=3.8.0.0
+    , Cabal         ^>=3.10.0.0
+    , Cabal-syntax  ^>=3.10.0.0
     , QuickCheck    ^>=2.13.2 || ^>=2.14
 
   exposed-modules:
diff --git a/cabal/Cabal-described/Cabal-described.cabal b/cabal/Cabal-described/Cabal-described.cabal
--- a/cabal/Cabal-described/Cabal-described.cabal
+++ b/cabal/Cabal-described/Cabal-described.cabal
@@ -1,6 +1,6 @@
 cabal-version: 2.2
 name:          Cabal-described
-version:       3.8.1.0
+version:       3.10.1.0
 synopsis:      Described functionality for types in Cabal
 category:      Testing, Parsec
 description:   Provides rere bindings
@@ -11,8 +11,8 @@
   ghc-options:      -Wall
   build-depends:
     , base
-    , Cabal             ^>=3.8.0.0
-    , Cabal-syntax      ^>=3.8.0.0
+    , Cabal             ^>=3.10.0.0
+    , Cabal-syntax      ^>=3.10.0.0
     , containers
     , pretty
     , QuickCheck
diff --git a/cabal/Cabal-syntax/Cabal-syntax.cabal b/cabal/Cabal-syntax/Cabal-syntax.cabal
--- a/cabal/Cabal-syntax/Cabal-syntax.cabal
+++ b/cabal/Cabal-syntax/Cabal-syntax.cabal
@@ -1,9 +1,8 @@
-cabal-version: 1.22
+cabal-version: 2.2
 name:          Cabal-syntax
-version:       3.8.1.0
-x-revision:    2
-copyright:     2003-2022, Cabal Development Team (see AUTHORS file)
-license:       BSD3
+version:       3.10.3.0
+copyright:     2003-2023, Cabal Development Team (see AUTHORS file)
+license:       BSD-3-Clause
 license-file:  LICENSE
 author:        Cabal Development Team <cabal-devel@haskell.org>
 maintainer:    cabal-devel@haskell.org
@@ -16,7 +15,7 @@
 category:       Distribution
 build-type:     Simple
 
-extra-source-files:
+extra-doc-files:
   README.md ChangeLog.md
 
 source-repository head
@@ -32,15 +31,15 @@
     array      >= 0.4.0.1  && < 0.6,
     base       >= 4.9      && < 5,
     binary     >= 0.7      && < 0.9,
-    bytestring >= 0.10.0.0 && < 0.12,
-    containers >= 0.5.0.0  && < 0.7,
-    deepseq    >= 1.3.0.1  && < 1.5,
+    bytestring >= 0.10.0.0 && < 0.13,
+    containers >= 0.5.0.0  && < 0.8,
+    deepseq    >= 1.3.0.1  && < 1.6,
     directory  >= 1.2      && < 1.4,
-    filepath   >= 1.3.0.1  && < 1.5,
+    filepath   >= 1.3.0.1  && < 1.6,
     mtl        >= 2.1      && < 2.4,
     parsec     >= 3.1.13.0 && < 3.2,
     pretty     >= 1.1.1    && < 1.2,
-    text       (>= 1.2.3.0 && < 1.3) || (>= 2.0 && < 2.1),
+    text       (>= 1.2.3.0 && < 1.3) || (>= 2.0 && < 2.2),
     time       >= 1.4.0.1  && < 1.13,
     -- transformers-0.4.0.0 doesn't have record syntax e.g. for Identity
     -- See also https://github.com/ekmett/transformers-compat/issues/35
@@ -49,12 +48,14 @@
   if os(windows)
     build-depends: Win32 >= 2.3.0.0 && < 2.14
   else
-    build-depends: unix  >= 2.6.0.0 && < 2.8
+    build-depends: unix  >= 2.6.0.0 && < 2.9
 
   ghc-options: -Wall -fno-ignore-asserts -fwarn-tabs -fwarn-incomplete-uni-patterns -fwarn-incomplete-record-updates
-  ghc-options: -Wcompat -Wnoncanonical-monad-instances
 
-  if impl(ghc < 8.8)
+  if impl(ghc >= 8.0)
+    ghc-options: -Wcompat -Wnoncanonical-monad-instances
+
+  if impl(ghc >= 8.0) && impl(ghc < 8.8)
     ghc-options: -Wnoncanonical-monadfail-instances
 
   exposed-modules:
diff --git a/cabal/Cabal-syntax/ChangeLog.md b/cabal/Cabal-syntax/ChangeLog.md
--- a/cabal/Cabal-syntax/ChangeLog.md
+++ b/cabal/Cabal-syntax/ChangeLog.md
@@ -1,1 +1,1 @@
-Please see https://hackage.haskell.org/package/Cabal/changelog
+Please see See https://github.com/haskell/cabal/blob/master/release-notes/Cabal-3.10.3.0.md
diff --git a/cabal/Cabal-syntax/LICENSE b/cabal/Cabal-syntax/LICENSE
--- a/cabal/Cabal-syntax/LICENSE
+++ b/cabal/Cabal-syntax/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2003-2022, Cabal Development Team.
+Copyright (c) 2003-2023, Cabal Development Team.
 See the AUTHORS file for the full list of copyright holders.
 
 See */LICENSE for the copyright holders of the subcomponents.
diff --git a/cabal/Cabal-syntax/src/Distribution/Backpack.hs b/cabal/Cabal-syntax/src/Distribution/Backpack.hs
--- a/cabal/Cabal-syntax/src/Distribution/Backpack.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Backpack.hs
@@ -98,7 +98,7 @@
 -- TODO: cache holes?
 
 instance Binary OpenUnitId
-instance Structured OpenUnitId 
+instance Structured OpenUnitId
 instance NFData OpenUnitId where
     rnf (IndefFullUnitId cid subst) = rnf cid `seq` rnf subst
     rnf (DefiniteUnitId uid) = rnf uid
diff --git a/cabal/Cabal-syntax/src/Distribution/CabalSpecVersion.hs b/cabal/Cabal-syntax/src/Distribution/CabalSpecVersion.hs
--- a/cabal/Cabal-syntax/src/Distribution/CabalSpecVersion.hs
+++ b/cabal/Cabal-syntax/src/Distribution/CabalSpecVersion.hs
@@ -30,6 +30,7 @@
     | CabalSpecV3_4
     | CabalSpecV3_6
     | CabalSpecV3_8
+    -- 3.10: no changes
   deriving (Eq, Ord, Show, Read, Enum, Bounded, Typeable, Data, Generic)
 
 instance Binary CabalSpecVersion
diff --git a/cabal/Cabal-syntax/src/Distribution/Compat/Prelude.hs b/cabal/Cabal-syntax/src/Distribution/Compat/Prelude.hs
--- a/cabal/Cabal-syntax/src/Distribution/Compat/Prelude.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Compat/Prelude.hs
@@ -130,10 +130,9 @@
 
 -- We also could hide few partial function
 import Prelude                       as BasePrelude hiding
-    ( mapM, mapM_, sequence, null, length, foldr, any, all, head, tail, last, init
+    ( mapM, mapM_, sequence, any, all, head, tail, last, init
     -- partial functions
     , read
-    , foldr1, foldl1
 #if MINVER_base_411
     -- As of base 4.11.0.0 Prelude exports part of Semigroup(..).
     -- Hide this so we instead rely on Distribution.Compat.Semigroup.
@@ -142,8 +141,9 @@
     , Word
     -- We hide them, as we import only some members
     , Traversable, traverse, sequenceA
-    , Foldable, foldMap
+    , Foldable(..)
     )
+import Data.Foldable as BasePrelude (foldl, elem, sum, product, maximum, minimum)
 
 -- AMP
 import Data.Foldable
@@ -186,7 +186,7 @@
 import Distribution.Compat.Binary    (Binary (..))
 import Distribution.Compat.Semigroup (Semigroup (..), gmappend, gmempty)
 import Distribution.Compat.Typeable  (TypeRep, Typeable, typeRep)
-import GHC.Generics                  ((:*:) ((:*:)), (:+:) (L1, R1), Generic, K1 (unK1), M1 (unM1), Rep (..), U1 (U1), V1)
+import GHC.Generics                  (Generic (..), K1 (unK1), M1 (unM1), U1 (U1), V1, (:*:) ((:*:)), (:+:) (L1, R1))
 import System.Exit                   (ExitCode (..), exitFailure, exitSuccess, exitWith)
 import Text.Read                     (readMaybe)
 
diff --git a/cabal/Cabal-syntax/src/Distribution/Compiler.hs b/cabal/Cabal-syntax/src/Distribution/Compiler.hs
--- a/cabal/Cabal-syntax/src/Distribution/Compiler.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Compiler.hs
@@ -125,7 +125,7 @@
 -- Cabal parses only @ghc-options@ and @ghcjs-options@, others are omitted.
 --
 data PerCompilerFlavor v = PerCompilerFlavor v v
-  deriving (Generic, Show, Read, Eq, Typeable, Data, Functor, Foldable
+  deriving (Generic, Show, Read, Eq, Ord, Typeable, Data, Functor, Foldable
            , Traversable)
 
 instance Binary a => Binary (PerCompilerFlavor a)
diff --git a/cabal/Cabal-syntax/src/Distribution/Fields/Lexer.hs b/cabal/Cabal-syntax/src/Distribution/Fields/Lexer.hs
--- a/cabal/Cabal-syntax/src/Distribution/Fields/Lexer.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Fields/Lexer.hs
@@ -1,7 +1,7 @@
 {-# OPTIONS_GHC -fno-warn-unused-binds -fno-warn-missing-signatures #-}
-{-# LANGUAGE CPP,MagicHash #-}
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE MagicHash #-}
 {-# LINE 1 "templates/Lexer.x" #-}
-
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Distribution.Fields.Lexer
@@ -52,7 +52,6 @@
 import qualified Data.Text.Encoding as T
 import qualified Data.Text.Encoding.Error as T
 #endif
-
 #if __GLASGOW_HASKELL__ >= 603
 #include "ghcconfig.h"
 #elif defined(__GLASGOW_HASKELL__)
@@ -73,106 +72,107 @@
 alex_tab_size = 8
 alex_base :: AlexAddr
 alex_base = AlexA#
-  "\x12\xff\xff\xff\xf9\xff\xff\xff\xfb\xff\xff\xff\x01\x00\x00\x00\x2f\x00\x00\x00\x50\x00\x00\x00\xd0\x00\x00\x00\x48\xff\xff\xff\xdc\xff\xff\xff\x51\xff\xff\xff\x6d\xff\xff\xff\x6f\xff\xff\xff\x50\x01\x00\x00\x74\x01\x00\x00\x70\xff\xff\xff\x68\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\xa3\x01\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6a\x00\x00\x00\xd1\x01\x00\x00\xfb\x01\x00\x00\x7b\x02\x00\x00\xfb\x02\x00\x00\x00\x00\x00\x00\x7b\x03\x00\x00\x7d\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x00\x00\x6d\x00\x00\x00\x6b\x00\x00\x00\xfc\x03\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x6f\x00\x00\x00\x1c\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00\x00"#
+  "\x12\xff\xff\xff\xf9\xff\xff\xff\xfb\xff\xff\xff\x01\x00\x00\x00\x2f\x00\x00\x00\x50\x00\x00\x00\xd0\x00\x00\x00\x50\x01\x00\x00\xd0\x01\x00\x00\x50\x02\x00\x00\x81\x00\x00\x00\xfe\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x69\xff\xff\xff\x03\x00\x00\x00\x09\x00\x00\x00\xf8\x00\x00\x00\xe2\xff\xff\xff\xd0\x02\x00\x00\x71\xff\xff\xff\x0b\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x5f\xff\xff\xff\x5d\xff\xff\xff\x00\x00\x00\x00\xf0\x02\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\x03\x00\x00\x6a\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x00\x66\x03\x00\x00\x98\x00\x00\x00\x80\xff\xff\xff\x00\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x03\x00\x00\x00\x00\x00\x00\xef\x03\x00\x00\x13\x04\x00\x00"#
 
 alex_table :: AlexAddr
 alex_table = AlexA#
-  "\x00\x00\x09\x00\x0f\x00\x11\x00\x02\x00\x11\x00\x12\x00\x00\x00\x12\x00\x13\x00\x03\x00\x11\x00\x07\x00\x10\x00\x12\x00\x25\x00\x14\x00\x11\x00\x10\x00\x11\x00\x14\x00\x11\x00\x12\x00\x23\x00\x12\x00\x0f\x00\x28\x00\x02\x00\x2e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x08\x00\x10\x00\x00\x00\x14\x00\x00\x00\x00\x00\x08\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2a\x00\x2e\x00\xff\xff\xff\xff\x2f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x26\x00\x28\x00\xff\xff\xff\xff\x29\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x26\x00\x0f\x00\x11\x00\x17\x00\x26\x00\x12\x00\x25\x00\x11\x00\x2a\x00\x00\x00\x12\x00\x00\x00\x15\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x17\x00\x26\x00\x00\x00\x25\x00\x00\x00\x2a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2c\x00\x00\x00\x2d\x00\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x0e\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x17\x00\x23\x00\xff\xff\xff\xff\x24\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x17\x00\x1e\x00\x0d\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x00\x00\x1f\x00\x1f\x00\x1e\x00\x1e\x00\x1e\x00\x19\x00\x1a\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x1f\x00\x1e\x00\x1f\x00\x1e\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x21\x00\x1e\x00\x22\x00\x1e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x1d\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x0c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1e\x00\xff\xff\x1e\x00\x1e\x00\x1e\x00\x1e\x00\xff\xff\xff\xff\xff\xff\x1e\x00\x1e\x00\x1e\x00\x18\x00\x1a\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x1e\x00\xff\xff\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x1e\x00\xff\xff\x1e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1e\x00\xff\xff\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x00\x00\xff\xff\xff\xff\x1e\x00\x1e\x00\x1e\x00\x1a\x00\x1a\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x1e\x00\xff\xff\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x1e\x00\xff\xff\x1e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x1c\x00\x1e\x00\x00\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x1e\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\x00\xff\xff\x1e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\xff\xff\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#
+  "\x00\x00\x18\x00\x11\x00\x17\x00\x02\x00\x17\x00\x16\x00\x0b\x00\x16\x00\x0f\x00\x03\x00\x17\x00\x0f\x00\x17\x00\x16\x00\x13\x00\x16\x00\x15\x00\x10\x00\x17\x00\x15\x00\x17\x00\x16\x00\x17\x00\x16\x00\x11\x00\x19\x00\x02\x00\x1a\x00\x1c\x00\x0b\x00\x22\x00\x10\x00\x03\x00\x27\x00\x0f\x00\x00\x00\x00\x00\x12\x00\x00\x00\x12\x00\x10\x00\x00\x00\x15\x00\x00\x00\x00\x00\x12\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x21\x00\x1c\x00\xff\xff\xff\xff\x1d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x21\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x25\x00\x22\x00\xff\xff\xff\xff\x23\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x25\x00\x00\x00\x00\x00\x21\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x00\x00\x0c\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x21\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x25\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x1e\x00\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x25\x00\x00\x00\x00\x00\x14\x00\x00\x00\x26\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x26\x00\x00\x00\x14\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0b\x00\x27\x00\xff\xff\xff\xff\x28\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0b\x00\x2d\x00\x1b\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x00\x00\x2c\x00\x2c\x00\x2d\x00\x2d\x00\x2d\x00\x08\x00\x09\x00\x2d\x00\xff\xff\x11\x00\x17\x00\x00\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2b\x00\x00\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2c\x00\x2d\x00\x2c\x00\x2d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2a\x00\x2d\x00\x29\x00\x2d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2d\x00\xff\xff\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x00\x00\xff\xff\xff\xff\x2d\x00\x2d\x00\x2d\x00\x0a\x00\x09\x00\x2d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x2d\x00\xff\xff\x2d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x2d\x00\xff\xff\x2d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2d\x00\xff\xff\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x00\x00\xff\xff\xff\xff\x2d\x00\x2d\x00\x2d\x00\x09\x00\x09\x00\x2d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x2d\x00\xff\xff\x2d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x2d\x00\xff\xff\x2d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x2e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x30\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\xff\xff\x2d\x00\xff\xff\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x00\x00\x00\x00\x00\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x2d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2d\x00\x00\x00\x2d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2d\x00\x00\x00\x2d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x2e\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x2f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#
 
 alex_check :: AlexAddr
 alex_check = AlexA#
-  "\xff\xff\xef\x00\x09\x00\x0a\x00\x09\x00\x0a\x00\x0d\x00\xbf\x00\x0d\x00\x2d\x00\x09\x00\x0a\x00\xbb\x00\xa0\x00\x0d\x00\xa0\x00\xa0\x00\x0a\x00\x09\x00\x0a\x00\x09\x00\x0a\x00\x0d\x00\x0a\x00\x0d\x00\x20\x00\x0a\x00\x20\x00\x0a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x20\x00\xff\xff\xff\xff\xff\xff\xff\xff\x2d\x00\xff\xff\x2d\x00\x20\x00\xff\xff\x20\x00\xff\xff\xff\xff\x2d\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x09\x00\x0a\x00\x09\x00\x09\x00\x0d\x00\x09\x00\x0a\x00\x09\x00\xff\xff\x0d\x00\xff\xff\x7b\x00\xff\xff\x7d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x20\x00\xff\xff\x20\x00\x20\x00\xff\xff\x20\x00\xff\xff\x20\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7b\x00\xff\xff\x7d\x00\xff\xff\x7f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc2\x00\xff\xff\xc2\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc2\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc2\x00\xff\xff\xc2\x00\xff\xff\x7f\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x3a\x00\xff\xff\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc2\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\xc2\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x7f\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\xff\xff\xff\xff\x22\x00\xff\xff\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\xff\xff\xff\xff\x22\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x5c\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f\x00\x5c\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\xff\xff\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\xff\xff\xff\xff\x7f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x7f\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x3a\x00\xff\xff\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5b\x00\x5c\x00\x5d\x00\x5e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x7f\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x3a\x00\xff\xff\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5b\x00\x5c\x00\x5d\x00\x5e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x7f\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\xff\xff\xff\xff\x2f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x3a\x00\xff\xff\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5b\x00\x5c\x00\x5d\x00\x5e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x7f\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\xff\xff\xff\xff\x22\x00\x21\x00\xff\xff\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\xff\xff\x5c\x00\xff\xff\x5e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7c\x00\x7f\x00\x7e\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\xff\xff\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\xff\xff\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7b\x00\xff\xff\x7d\x00\xff\xff\x7f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#
+  "\xff\xff\xef\x00\x09\x00\x0a\x00\x09\x00\x0a\x00\x0d\x00\x09\x00\x0d\x00\xa0\x00\x09\x00\x0a\x00\x09\x00\x0a\x00\x0d\x00\x2d\x00\x0d\x00\xa0\x00\x09\x00\x0a\x00\x09\x00\x0a\x00\x0d\x00\x0a\x00\x0d\x00\x20\x00\xbb\x00\x20\x00\xbf\x00\x0a\x00\x20\x00\x0a\x00\xa0\x00\x20\x00\x0a\x00\x20\x00\xff\xff\xff\xff\x2d\x00\xff\xff\x2d\x00\x20\x00\xff\xff\x20\x00\xff\xff\xff\xff\x2d\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\xff\xff\xff\xff\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7b\x00\xff\xff\x7d\x00\xff\xff\xff\xff\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x20\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7b\x00\xff\xff\x7d\x00\xff\xff\x7f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x20\x00\xff\xff\xff\xff\xc2\x00\xff\xff\xc2\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc2\x00\xff\xff\xc2\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc2\x00\xff\xff\xc2\x00\xff\xff\x7f\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x7f\x00\x09\x00\x0a\x00\xff\xff\xff\xff\x0d\x00\xff\xff\xff\xff\xff\xff\xff\xff\x3a\x00\xff\xff\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x20\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5b\x00\x5c\x00\x5d\x00\x5e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x7f\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\xff\xff\xff\xff\x2f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x3a\x00\xff\xff\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5b\x00\x5c\x00\x5d\x00\x5e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc2\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x7f\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x3a\x00\xff\xff\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5b\x00\x5c\x00\x5d\x00\x5e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x7f\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x3a\x00\xff\xff\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5b\x00\x5c\x00\x5d\x00\x5e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x7f\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\xff\xff\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\xff\xff\xff\xff\x22\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\xff\xff\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\xff\xff\xff\xff\x7f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x7f\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7b\x00\xff\xff\x7d\x00\x21\x00\x7f\x00\x23\x00\x24\x00\x25\x00\x26\x00\xff\xff\xff\xff\xff\xff\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\xff\xff\x5e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7c\x00\xff\xff\x7e\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\xff\xff\xff\xff\x22\x00\xff\xff\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\xff\xff\xff\xff\x22\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f\x00\x5c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#
 
 alex_deflt :: AlexAddr
 alex_deflt = AlexA#
-  "\xff\xff\xff\xff\xff\xff\xff\xff\x2b\x00\x27\x00\x1b\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0d\x00\x0d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x13\x00\xff\xff\xff\xff\xff\xff\xff\xff\x18\x00\x1b\x00\x1b\x00\x1b\x00\xff\xff\x0d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x27\x00\xff\xff\xff\xff\xff\xff\x2b\x00\xff\xff\xff\xff\xff\xff\xff\xff"#
+  "\xff\xff\xff\xff\xff\xff\xff\xff\x20\x00\x24\x00\x07\x00\x07\x00\x07\x00\x07\x00\x0a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x13\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1b\x00\xff\xff\xff\xff\xff\xff\xff\xff\x20\x00\xff\xff\xff\xff\xff\xff\x24\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1b\x00\x1b\x00"#
 
-alex_accept = listArray (0 :: Int, 47)
-  [ AlexAcc 29
+alex_accept = listArray (0 :: Int, 48)
+  [ AlexAcc 30
+  , AlexAcc 29
   , AlexAcc 28
   , AlexAcc 27
-  , AlexAcc 26
   , AlexAccNone
   , AlexAccNone
   , AlexAccNone
-  , AlexAccNone
-  , AlexAccNone
-  , AlexAccNone
-  , AlexAccNone
-  , AlexAccNone
-  , AlexAccNone
-  , AlexAccNone
-  , AlexAccNone
-  , AlexAccNone
-  , AlexAccNone
+  , AlexAcc 26
   , AlexAcc 25
   , AlexAcc 24
   , AlexAccSkip
+  , AlexAccSkip
   , AlexAcc 23
   , AlexAcc 22
+  , AlexAccNone
   , AlexAcc 21
-  , AlexAccSkip
-  , AlexAccSkip
   , AlexAcc 20
+  , AlexAccNone
+  , AlexAccNone
+  , AlexAccSkip
+  , AlexAccNone
+  , AlexAccNone
   , AlexAcc 19
   , AlexAcc 18
+  , AlexAccNone
+  , AlexAccNone
   , AlexAcc 17
+  , AlexAccNone
   , AlexAcc 16
   , AlexAcc 15
   , AlexAcc 14
   , AlexAcc 13
   , AlexAcc 12
+  , AlexAccSkip
   , AlexAcc 11
   , AlexAcc 10
   , AlexAcc 9
-  , AlexAcc 8
   , AlexAccSkip
+  , AlexAccNone
+  , AlexAcc 8
   , AlexAcc 7
   , AlexAcc 6
   , AlexAcc 5
-  , AlexAccSkip
   , AlexAcc 4
   , AlexAcc 3
   , AlexAcc 2
   , AlexAcc 1
   , AlexAcc 0
+  , AlexAccNone
   ]
 
-alex_actions = array (0 :: Int, 30)
-  [ (29,alex_action_0)
-  , (28,alex_action_20)
-  , (27,alex_action_16)
-  , (26,alex_action_3)
-  , (25,alex_action_1)
-  , (24,alex_action_1)
-  , (23,alex_action_3)
+alex_actions = array (0 :: Int, 31)
+  [ (30,alex_action_0)
+  , (29,alex_action_20)
+  , (28,alex_action_16)
+  , (27,alex_action_3)
+  , (26,alex_action_8)
+  , (25,alex_action_8)
+  , (24,alex_action_8)
+  , (23,alex_action_5)
   , (22,alex_action_4)
-  , (21,alex_action_5)
-  , (20,alex_action_8)
-  , (19,alex_action_8)
-  , (18,alex_action_8)
-  , (17,alex_action_9)
-  , (16,alex_action_9)
-  , (15,alex_action_10)
-  , (14,alex_action_11)
-  , (13,alex_action_12)
-  , (12,alex_action_13)
-  , (11,alex_action_14)
-  , (10,alex_action_15)
-  , (9,alex_action_15)
-  , (8,alex_action_16)
-  , (7,alex_action_18)
-  , (6,alex_action_19)
-  , (5,alex_action_19)
-  , (4,alex_action_22)
-  , (3,alex_action_23)
-  , (2,alex_action_24)
-  , (1,alex_action_25)
-  , (0,alex_action_25)
+  , (21,alex_action_3)
+  , (20,alex_action_16)
+  , (19,alex_action_1)
+  , (18,alex_action_1)
+  , (17,alex_action_0)
+  , (16,alex_action_25)
+  , (15,alex_action_25)
+  , (14,alex_action_24)
+  , (13,alex_action_23)
+  , (12,alex_action_22)
+  , (11,alex_action_19)
+  , (10,alex_action_19)
+  , (9,alex_action_18)
+  , (8,alex_action_15)
+  , (7,alex_action_15)
+  , (6,alex_action_14)
+  , (5,alex_action_13)
+  , (4,alex_action_12)
+  , (3,alex_action_11)
+  , (2,alex_action_10)
+  , (1,alex_action_9)
+  , (0,alex_action_9)
   ]
 
 {-# LINE 151 "templates/Lexer.x" #-}
-
 -- | Tokens of outer cabal file structure. Field values are treated opaquely.
 data Token = TokSym   !ByteString       -- ^ Haskell-like identifier, number or operator
            | TokStr   !ByteString       -- ^ String in quotes
@@ -195,17 +195,17 @@
 tok :: Token -> Position -> Int -> ByteString -> Lex LToken
 tok  t pos _len _input = return $! L pos t
 
-checkLeadingWhitespace :: Int -> ByteString -> Lex Int
-checkLeadingWhitespace len bs
+checkLeadingWhitespace :: Position -> Int -> ByteString -> Lex Int
+checkLeadingWhitespace pos len bs
     | B.any (== 9) (B.take len bs) = do
-        addWarning LexWarningTab
-        checkWhitespace len bs
-    | otherwise = checkWhitespace len bs
+        addWarningAt pos LexWarningTab
+        checkWhitespace pos len bs
+    | otherwise = checkWhitespace pos len bs
 
-checkWhitespace :: Int -> ByteString -> Lex Int
-checkWhitespace len bs
+checkWhitespace :: Position -> Int -> ByteString -> Lex Int
+checkWhitespace pos len bs
     | B.any (== 194) (B.take len bs) = do
-        addWarning LexWarningNBSP
+        addWarningAt pos LexWarningNBSP
         return $ len - B.count 194 (B.take len bs)
     | otherwise = return len
 
@@ -313,40 +313,42 @@
 in_field_braces = 4
 in_field_layout = 5
 in_section = 6
-alex_action_0 =  \_ len _ -> do
-              when (len /= 0) $ addWarning LexWarningBOM
+alex_action_0 = \pos len _ -> do
+              when (len /= 0) $ addWarningAt pos LexWarningBOM
               setStartCode bol_section
               lexToken
-         
-alex_action_1 =  \_pos len inp -> checkWhitespace len inp >> adjustPos retPos >> lexToken 
-alex_action_3 =  \pos len inp -> checkLeadingWhitespace len inp >>
+alex_action_1 = \pos len inp -> checkWhitespace pos len inp >> adjustPos retPos >> lexToken
+alex_action_3 = \pos len inp -> checkLeadingWhitespace pos len inp >>
                                      if B.length inp == len
                                        then return (L pos EOF)
                                        else setStartCode in_section
-                                         >> return (L pos (Indent len)) 
-alex_action_4 =  tok  OpenBrace 
-alex_action_5 =  tok  CloseBrace 
-alex_action_8 =  toki TokSym 
-alex_action_9 =  \pos len inp -> return $! L pos (TokStr (B.take (len - 2) (B.tail inp))) 
-alex_action_10 =  toki TokOther 
-alex_action_11 =  toki TokOther 
-alex_action_12 =  tok  Colon 
-alex_action_13 =  tok  OpenBrace 
-alex_action_14 =  tok  CloseBrace 
-alex_action_15 =  \_ _ _ -> adjustPos retPos >> setStartCode bol_section >> lexToken 
-alex_action_16 =  \pos len inp -> checkLeadingWhitespace len inp >>= \len' ->
+                                         >> return (L pos (Indent len))
+alex_action_4 = tok  OpenBrace
+alex_action_5 = tok  CloseBrace
+alex_action_8 = toki TokSym
+alex_action_9 = \pos len inp -> return $! L pos (TokStr (B.take (len - 2) (B.tail inp)))
+alex_action_10 = toki TokOther
+alex_action_11 = toki TokOther
+alex_action_12 = tok  Colon
+alex_action_13 = tok  OpenBrace
+alex_action_14 = tok  CloseBrace
+alex_action_15 = \_ _ _ -> adjustPos retPos >> setStartCode bol_section >> lexToken
+alex_action_16 = \pos len inp -> checkLeadingWhitespace pos len inp >>= \len' ->
                                   if B.length inp == len
                                     then return (L pos EOF)
                                     else setStartCode in_field_layout
-                                      >> return (L pos (Indent len')) 
-alex_action_18 =  toki TokFieldLine 
-alex_action_19 =  \_ _ _ -> adjustPos retPos >> setStartCode bol_field_layout >> lexToken 
-alex_action_20 =  \_ _ _ -> setStartCode in_field_braces >> lexToken 
-alex_action_22 =  toki TokFieldLine 
-alex_action_23 =  tok  OpenBrace  
-alex_action_24 =  tok  CloseBrace 
-alex_action_25 =  \_ _ _ -> adjustPos retPos >> setStartCode bol_field_braces >> lexToken 
-{-# LINE 1 "templates/GenericTemplate.hs" #-}
+                                      >> return (L pos (Indent len'))
+alex_action_18 = toki TokFieldLine
+alex_action_19 = \_ _ _ -> adjustPos retPos >> setStartCode bol_field_layout >> lexToken
+alex_action_20 = \_ _ _ -> setStartCode in_field_braces >> lexToken
+alex_action_22 = toki TokFieldLine
+alex_action_23 = tok  OpenBrace
+alex_action_24 = tok  CloseBrace
+alex_action_25 = \_ _ _ -> adjustPos retPos >> setStartCode bol_field_braces >> lexToken
+
+#define ALEX_GHC 1
+#define ALEX_LATIN1 1
+#define ALEX_NOPRED 1
 -- -----------------------------------------------------------------------------
 -- ALEX TEMPLATE
 --
@@ -356,15 +358,37 @@
 -- -----------------------------------------------------------------------------
 -- INTERNALS and main scanner engine
 
+#ifdef ALEX_GHC
+#  define ILIT(n) n#
+#  define IBOX(n) (I# (n))
+#  define FAST_INT Int#
 -- Do not remove this comment. Required to fix CPP parsing when using GCC and a clang-compiled alex.
-#if __GLASGOW_HASKELL__ > 706
-#define GTE(n,m) (tagToEnum# (n >=# m))
-#define EQ(n,m) (tagToEnum# (n ==# m))
+#  if __GLASGOW_HASKELL__ > 706
+#    define GTE(n,m) (tagToEnum# (n >=# m))
+#    define EQ(n,m) (tagToEnum# (n ==# m))
+#  else
+#    define GTE(n,m) (n >=# m)
+#    define EQ(n,m) (n ==# m)
+#  endif
+#  define PLUS(n,m) (n +# m)
+#  define MINUS(n,m) (n -# m)
+#  define TIMES(n,m) (n *# m)
+#  define NEGATE(n) (negateInt# (n))
+#  define IF_GHC(x) (x)
 #else
-#define GTE(n,m) (n >=# m)
-#define EQ(n,m) (n ==# m)
+#  define ILIT(n) (n)
+#  define IBOX(n) (n)
+#  define FAST_INT Int
+#  define GTE(n,m) (n >= m)
+#  define EQ(n,m) (n == m)
+#  define PLUS(n,m) (n + m)
+#  define MINUS(n,m) (n - m)
+#  define TIMES(n,m) (n * m)
+#  define NEGATE(n) (negate (n))
+#  define IF_GHC(x)
 #endif
 
+#ifdef ALEX_GHC
 data AlexAddr = AlexA# Addr#
 -- Do not remove this comment. Required to fix CPP parsing when using GCC and a clang-compiled alex.
 #if __GLASGOW_HASKELL__ < 503
@@ -387,7 +411,11 @@
 #endif
     (indexInt16OffAddr# arr off)
 #endif
+#else
+alexIndexInt16OffAddr arr off = arr ! off
+#endif
 
+#ifdef ALEX_GHC
 {-# INLINE alexIndexInt32OffAddr #-}
 alexIndexInt32OffAddr :: AlexAddr -> Int# -> Int#
 alexIndexInt32OffAddr (AlexA# arr) off =
@@ -408,13 +436,21 @@
 #endif
     (indexInt32OffAddr# arr off)
 #endif
+#else
+alexIndexInt32OffAddr arr off = arr ! off
+#endif
 
+#ifdef ALEX_GHC
+
 #if __GLASGOW_HASKELL__ < 503
 quickIndex arr i = arr ! i
 #else
 -- GHC >= 503, unsafeAt is available from Data.Array.Base.
 quickIndex = unsafeAt
 #endif
+#else
+quickIndex arr i = arr ! i
+#endif
 
 -- -----------------------------------------------------------------------------
 -- Main lexing routines
@@ -426,26 +462,34 @@
   | AlexToken  !AlexInput !Int a
 
 -- alexScan :: AlexInput -> StartCode -> AlexReturn a
-alexScan input__ (I# (sc))
-  = alexScanUser undefined input__ (I# (sc))
+alexScan input__ IBOX(sc)
+  = alexScanUser undefined input__ IBOX(sc)
 
-alexScanUser user__ input__ (I# (sc))
-  = case alex_scan_tkn user__ input__ 0# input__ sc AlexNone of
+alexScanUser user__ input__ IBOX(sc)
+  = case alex_scan_tkn user__ input__ ILIT(0) input__ sc AlexNone of
   (AlexNone, input__') ->
     case alexGetByte input__ of
       Nothing ->
-
+#ifdef ALEX_DEBUG
+                                   trace ("End of input.") $
+#endif
                                    AlexEOF
       Just _ ->
-
+#ifdef ALEX_DEBUG
+                                   trace ("Error.") $
+#endif
                                    AlexError input__'
 
   (AlexLastSkip input__'' len, _) ->
-
+#ifdef ALEX_DEBUG
+    trace ("Skipping.") $
+#endif
     AlexSkip input__'' len
 
   (AlexLastAcc k input__''' len, _) ->
-
+#ifdef ALEX_DEBUG
+    trace ("Accept.") $
+#endif
     AlexToken input__''' len (alex_actions ! k)
 
 -- Push the input through the DFA, remembering the most recent accepting
@@ -454,35 +498,56 @@
 alex_scan_tkn user__ orig_input len input__ s last_acc =
   input__ `seq` -- strict in the input
   let
-  new_acc = (check_accs (alex_accept `quickIndex` (I# (s))))
+  new_acc = (check_accs (alex_accept `quickIndex` IBOX(s)))
   in
   new_acc `seq`
   case alexGetByte input__ of
      Nothing -> (new_acc, input__)
      Just (c, new_input) ->
-
-      case fromIntegral c of { (I# (ord_c)) ->
+#ifdef ALEX_DEBUG
+      trace ("State: " ++ show IBOX(s) ++ ", char: " ++ show c) $
+#endif
+      case fromIntegral c of { IBOX(ord_c) ->
         let
                 base   = alexIndexInt32OffAddr alex_base s
-                offset = (base +# ord_c)
-                check  = alexIndexInt16OffAddr alex_check offset
+                offset = PLUS(base,ord_c)
 
-                new_s = if GTE(offset,0#) && EQ(check,ord_c)
+                new_s = if GTE(offset,ILIT(0))
+                          && let check  = alexIndexInt16OffAddr alex_check offset
+                             in  EQ(check,ord_c)
                           then alexIndexInt16OffAddr alex_table offset
                           else alexIndexInt16OffAddr alex_deflt s
         in
         case new_s of
-            -1# -> (new_acc, input__)
+            ILIT(-1) -> (new_acc, input__)
                 -- on an error, we want to keep the input *before* the
                 -- character that failed, not after.
-            _ -> alex_scan_tkn user__ orig_input (if c < 0x80 || c >= 0xC0 then (len +# 1#) else len)
-                                                -- note that the length is increased ONLY if this is the 1st byte in a char encoding)
-                        new_input new_s new_acc
+            _ -> alex_scan_tkn user__ orig_input
+#ifdef ALEX_LATIN1
+                   PLUS(len,ILIT(1))
+                   -- issue 119: in the latin1 encoding, *each* byte is one character
+#else
+                   (if c < 0x80 || c >= 0xC0 then PLUS(len,ILIT(1)) else len)
+                   -- note that the length is increased ONLY if this is the 1st byte in a char encoding)
+#endif
+                   new_input new_s new_acc
       }
   where
         check_accs (AlexAccNone) = last_acc
-        check_accs (AlexAcc a  ) = AlexLastAcc a input__ (I# (len))
-        check_accs (AlexAccSkip) = AlexLastSkip  input__ (I# (len))
+        check_accs (AlexAcc a  ) = AlexLastAcc a input__ IBOX(len)
+        check_accs (AlexAccSkip) = AlexLastSkip  input__ IBOX(len)
+#ifndef ALEX_NOPRED
+        check_accs (AlexAccPred a predx rest)
+           | predx user__ orig_input IBOX(len) input__
+           = AlexLastAcc a input__ IBOX(len)
+           | otherwise
+           = check_accs rest
+        check_accs (AlexAccSkipPred predx rest)
+           | predx user__ orig_input IBOX(len) input__
+           = AlexLastSkip input__ IBOX(len)
+           | otherwise
+           = check_accs rest
+#endif
 
 data AlexLastAcc
   = AlexNone
@@ -493,4 +558,32 @@
   = AlexAccNone
   | AlexAcc Int
   | AlexAccSkip
+#ifndef ALEX_NOPRED
+  | AlexAccPred Int (AlexAccPred user) (AlexAcc user)
+  | AlexAccSkipPred (AlexAccPred user) (AlexAcc user)
 
+type AlexAccPred user = user -> AlexInput -> Int -> AlexInput -> Bool
+
+-- -----------------------------------------------------------------------------
+-- Predicates on a rule
+
+alexAndPred p1 p2 user__ in1 len in2
+  = p1 user__ in1 len in2 && p2 user__ in1 len in2
+
+--alexPrevCharIsPred :: Char -> AlexAccPred _
+alexPrevCharIs c _ input__ _ _ = c == alexInputPrevChar input__
+
+alexPrevCharMatches f _ input__ _ _ = f (alexInputPrevChar input__)
+
+--alexPrevCharIsOneOfPred :: Array Char Bool -> AlexAccPred _
+alexPrevCharIsOneOf arr _ input__ _ _ = arr ! alexInputPrevChar input__
+
+--alexRightContext :: Int -> AlexAccPred _
+alexRightContext IBOX(sc) user__ _ _ input__ =
+     case alex_scan_tkn user__ input__ ILIT(0) input__ sc AlexNone of
+          (AlexNone, _) -> False
+          _ -> True
+        -- TODO: there's no need to find the longest
+        -- match when checking the right context, just
+        -- the first match will do.
+#endif
diff --git a/cabal/Cabal-syntax/src/Distribution/Fields/LexerMonad.hs b/cabal/Cabal-syntax/src/Distribution/Fields/LexerMonad.hs
--- a/cabal/Cabal-syntax/src/Distribution/Fields/LexerMonad.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Fields/LexerMonad.hs
@@ -27,6 +27,7 @@
     LexWarning(..),
     LexWarningType(..),
     addWarning,
+    addWarningAt,
     toPWarnings,
 
   ) where
@@ -152,4 +153,9 @@
 -- | Add warning at the current position
 addWarning :: LexWarningType -> Lex ()
 addWarning wt = Lex $ \s@LexState{ curPos = pos, warnings = ws  } ->
+    LexResult s{ warnings = LexWarning wt pos : ws } ()
+
+-- | Add warning at specific position
+addWarningAt :: Position -> LexWarningType -> Lex ()
+addWarningAt pos wt = Lex $ \s@LexState{ warnings = ws  } ->
     LexResult s{ warnings = LexWarning wt pos : ws } ()
diff --git a/cabal/Cabal-syntax/src/Distribution/Fields/Parser.hs b/cabal/Cabal-syntax/src/Distribution/Fields/Parser.hs
--- a/cabal/Cabal-syntax/src/Distribution/Fields/Parser.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Fields/Parser.hs
@@ -47,6 +47,9 @@
 import qualified Data.Text.Encoding.Error as T
 #endif
 
+-- $setup
+-- >>> import Data.Either (isLeft)
+
 -- | The 'LexState'' (with a prime) is an instance of parsec's 'Stream'
 -- wrapped around lexer's 'LexState' (without a prime)
 data LexState' = LexState' !LexState (LToken, LexState')
diff --git a/cabal/Cabal-syntax/src/Distribution/Fields/Pretty.hs b/cabal/Cabal-syntax/src/Distribution/Fields/Pretty.hs
--- a/cabal/Cabal-syntax/src/Distribution/Fields/Pretty.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Fields/Pretty.hs
@@ -34,7 +34,7 @@
 import qualified Data.ByteString  as BS
 import qualified Text.PrettyPrint as PP
 
--- | This type is used to discern when a comment block should go 
+-- | This type is used to discern when a comment block should go
 --   before or after a cabal-like file field, otherwise it would
 --   be hardcoded to a single position. It is often used in
 --   conjunction with @PrettyField@.
@@ -153,7 +153,7 @@
     narrowStyle = PP.style { PP.lineLength = PP.lineLength PP.style - fw }
 
 renderField opts@(Opts rann indent post) _ (PrettySection ann name args fields) = Block Margin Margin $
-    
+
     attachComments
       (post ann [ PP.render $ PP.hsep $ PP.text (fromUTF8BS name) : args ])
     ++
diff --git a/cabal/Cabal-syntax/src/Distribution/InstalledPackageInfo.hs b/cabal/Cabal-syntax/src/Distribution/InstalledPackageInfo.hs
--- a/cabal/Cabal-syntax/src/Distribution/InstalledPackageInfo.hs
+++ b/cabal/Cabal-syntax/src/Distribution/InstalledPackageInfo.hs
@@ -62,9 +62,6 @@
 import Distribution.Types.InstalledPackageInfo
 import Distribution.Types.InstalledPackageInfo.FieldGrammar
 
--- $setup
--- >>> :set -XOverloadedStrings
-
 installedComponentId :: InstalledPackageInfo -> ComponentId
 installedComponentId ipi =
     case unComponentId (installedComponentId_ ipi) of
@@ -127,7 +124,7 @@
 
 -- |
 --
--- >>> let ipi = emptyInstalledPackageInfo { maintainer = "Tester" }
+-- >>> let ipi = emptyInstalledPackageInfo { maintainer = fromString "Tester" }
 -- >>> fmap ($ ipi) $ showInstalledPackageInfoField "maintainer"
 -- Just "maintainer: Tester"
 showInstalledPackageInfoField :: String -> Maybe (InstalledPackageInfo -> String)
diff --git a/cabal/Cabal-syntax/src/Distribution/License.hs b/cabal/Cabal-syntax/src/Distribution/License.hs
--- a/cabal/Cabal-syntax/src/Distribution/License.hs
+++ b/cabal/Cabal-syntax/src/Distribution/License.hs
@@ -125,7 +125,7 @@
 
     -- | Indicates an erroneous license name.
   | UnknownLicense String
-  deriving (Generic, Read, Show, Eq, Typeable, Data)
+  deriving (Generic, Read, Show, Eq, Ord, Typeable, Data)
 
 instance Binary License
 instance Structured License
diff --git a/cabal/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs b/cabal/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs
--- a/cabal/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs
+++ b/cabal/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs
@@ -6,6 +6,8 @@
 module Distribution.PackageDescription.FieldGrammar (
     -- * Package description
     packageDescriptionFieldGrammar,
+    CompatFilePath(..),
+    CompatLicenseFile(..),
     -- * Library
     libraryFieldGrammar,
     -- * Foreign library
diff --git a/cabal/Cabal-syntax/src/Distribution/PackageDescription/Quirks.hs b/cabal/Cabal-syntax/src/Distribution/PackageDescription/Quirks.hs
--- a/cabal/Cabal-syntax/src/Distribution/PackageDescription/Quirks.hs
+++ b/cabal/Cabal-syntax/src/Distribution/PackageDescription/Quirks.hs
@@ -37,7 +37,7 @@
     [ mk "-- This file has been generated from package.yaml by hpack version 0.17.0.\n--\n-- see: https://github.com/sol/hpack\n\nname:                unicode-transforms\nversion:             0.3.3\nsynopsis:            Unicode normalization\ndescription:         Fast Unic"
          (Fingerprint 15958160436627155571 10318709190730872881)
          (Fingerprint 11008465475756725834 13815629925116264363)
-         (bsRemove "  other-modules:\n      .\n") -- TODO: remove traling \n to test structural-diff
+         (bsRemove "  other-modules:\n      .\n") -- TODO: remove trailing \n to test structural-diff
     -- http://hackage.haskell.org/package/DSTM-0.1.2
     -- http://hackage.haskell.org/package/DSTM-0.1.1
     -- http://hackage.haskell.org/package/DSTM-0.1
diff --git a/cabal/Cabal-syntax/src/Distribution/Parsec/Warning.hs b/cabal/Cabal-syntax/src/Distribution/Parsec/Warning.hs
--- a/cabal/Cabal-syntax/src/Distribution/Parsec/Warning.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Parsec/Warning.hs
@@ -51,7 +51,7 @@
 
 -- | Parser warning.
 data PWarning = PWarning !PWarnType !Position String
-    deriving (Show, Generic)
+    deriving (Eq, Ord, Show, Generic)
 
 instance Binary PWarning
 instance NFData PWarning where rnf = genericRnf
diff --git a/cabal/Cabal-syntax/src/Distribution/SPDX/LicenseExceptionId.hs b/cabal/Cabal-syntax/src/Distribution/SPDX/LicenseExceptionId.hs
--- a/cabal/Cabal-syntax/src/Distribution/SPDX/LicenseExceptionId.hs
+++ b/cabal/Cabal-syntax/src/Distribution/SPDX/LicenseExceptionId.hs
@@ -29,7 +29,7 @@
 -- LicenseExceptionId
 -------------------------------------------------------------------------------
 
--- | SPDX License Exceptions identifiers list v3.16 
+-- | SPDX License Exceptions identifiers list v3.16
 data LicenseExceptionId
     = DS389_exception -- ^ @389-exception@, 389 Directory Server Exception
     | Autoconf_exception_2_0 -- ^ @Autoconf-exception-2.0@, Autoconf exception 2.0
diff --git a/cabal/Cabal-syntax/src/Distribution/SPDX/LicenseId.hs b/cabal/Cabal-syntax/src/Distribution/SPDX/LicenseId.hs
--- a/cabal/Cabal-syntax/src/Distribution/SPDX/LicenseId.hs
+++ b/cabal/Cabal-syntax/src/Distribution/SPDX/LicenseId.hs
@@ -32,7 +32,7 @@
 -- LicenseId
 -------------------------------------------------------------------------------
 
--- | SPDX License identifiers list v3.16 
+-- | SPDX License identifiers list v3.16
 data LicenseId
     = NullBSD -- ^ @0BSD@, BSD Zero Clause License
     | AAL -- ^ @AAL@, Attribution Assurance License
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/AbiHash.hs b/cabal/Cabal-syntax/src/Distribution/Types/AbiHash.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/AbiHash.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/AbiHash.hs
@@ -27,18 +27,18 @@
 newtype AbiHash = AbiHash ShortText
     deriving (Eq, Show, Read, Generic, Typeable)
 
+-- | Convert 'AbiHash' to 'String'
+--
+-- @since 2.0.0.2
+unAbiHash :: AbiHash -> String
+unAbiHash (AbiHash h) = fromShortText h
+
 -- | Construct a 'AbiHash' from a 'String'
 --
 -- 'mkAbiHash' is the inverse to 'unAbiHash'
 --
 -- Note: No validations are performed to ensure that the resulting
 -- 'AbiHash' is valid
---
--- @since 2.0.0.2
-unAbiHash :: AbiHash -> String
-unAbiHash (AbiHash h) = fromShortText h
-
--- | Convert 'AbiHash' to 'String'
 --
 -- @since 2.0.0.2
 mkAbiHash :: String -> AbiHash
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/Benchmark.hs b/cabal/Cabal-syntax/src/Distribution/Types/Benchmark.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/Benchmark.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/Benchmark.hs
@@ -29,7 +29,7 @@
         benchmarkInterface :: BenchmarkInterface,
         benchmarkBuildInfo :: BuildInfo
     }
-    deriving (Generic, Show, Read, Eq, Typeable, Data)
+    deriving (Generic, Show, Read, Eq, Ord, Typeable, Data)
 
 instance Binary Benchmark
 instance Structured Benchmark
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/BenchmarkInterface.hs b/cabal/Cabal-syntax/src/Distribution/Types/BenchmarkInterface.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/BenchmarkInterface.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/BenchmarkInterface.hs
@@ -21,8 +21,8 @@
      -- | Benchmark interface \"exitcode-stdio-1.0\". The benchmark
      -- takes the form of an executable. It returns a zero exit code
      -- for success, non-zero for failure. The stdout and stderr
-     -- channels may be logged. It takes no command line parameters
-     -- and nothing on stdin.
+     -- channels may be logged. Test tooling may pass command line
+     -- arguments and/or connect the stdin channel to the test.
      --
      BenchmarkExeV10 Version FilePath
 
@@ -30,7 +30,7 @@
      -- interfaces for the given reason (e.g. unknown benchmark type).
      --
    | BenchmarkUnsupported BenchmarkType
-   deriving (Eq, Generic, Read, Show, Typeable, Data)
+   deriving (Eq, Ord, Generic, Read, Show, Typeable, Data)
 
 instance Binary BenchmarkInterface
 instance Structured BenchmarkInterface
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/BenchmarkType.hs b/cabal/Cabal-syntax/src/Distribution/Types/BenchmarkType.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/BenchmarkType.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/BenchmarkType.hs
@@ -22,7 +22,7 @@
                      -- ^ \"type: exitcode-stdio-x.y\"
                    | BenchmarkTypeUnknown String Version
                      -- ^ Some unknown benchmark type e.g. \"type: foo\"
-    deriving (Generic, Show, Read, Eq, Typeable, Data)
+    deriving (Generic, Show, Read, Eq, Ord, Typeable, Data)
 
 instance Binary BenchmarkType
 instance Structured BenchmarkType
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/BuildInfo.hs b/cabal/Cabal-syntax/src/Distribution/Types/BuildInfo.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/BuildInfo.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/BuildInfo.hs
@@ -111,7 +111,7 @@
         targetBuildDepends :: [Dependency], -- ^ Dependencies specific to a library or executable target
         mixins :: [Mixin]
     }
-    deriving (Generic, Show, Read, Eq, Typeable, Data)
+    deriving (Generic, Show, Read, Eq, Ord, Typeable, Data)
 
 instance Binary BuildInfo
 instance Structured BuildInfo
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/BuildType.hs b/cabal/Cabal-syntax/src/Distribution/Types/BuildType.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/BuildType.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/BuildType.hs
@@ -25,7 +25,7 @@
                 -- information used by later phases.
   | Make        -- ^ calls @Distribution.Make.defaultMain@
   | Custom      -- ^ uses user-supplied @Setup.hs@ or @Setup.lhs@ (default)
-                deriving (Generic, Show, Read, Eq, Typeable, Data)
+                deriving (Generic, Show, Read, Eq, Ord, Typeable, Data)
 
 instance Binary BuildType
 instance Structured BuildType
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/ComponentName.hs b/cabal/Cabal-syntax/src/Distribution/Types/ComponentName.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/ComponentName.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/ComponentName.hs
@@ -1,9 +1,11 @@
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE PatternSynonyms #-}
 
 module Distribution.Types.ComponentName (
-  ComponentName(..),
+  ComponentName(.., CFLibName, CExeName, CTestName, CBenchName),
   showComponentName,
+  componentNameRaw,
   componentNameStanza,
   componentNameString,
   ) where
@@ -21,12 +23,32 @@
 
 -- Libraries live in a separate namespace, so must distinguish
 data ComponentName = CLibName   LibraryName
-                   | CFLibName  UnqualComponentName
-                   | CExeName   UnqualComponentName
-                   | CTestName  UnqualComponentName
-                   | CBenchName UnqualComponentName
+                   | CNotLibName NotLibComponentName
                    deriving (Eq, Generic, Ord, Read, Show, Typeable)
 
+data NotLibComponentName
+                   = CNLFLibName  { toCompName :: UnqualComponentName }
+                   | CNLExeName   { toCompName :: UnqualComponentName }
+                   | CNLTestName  { toCompName :: UnqualComponentName }
+                   | CNLBenchName { toCompName :: UnqualComponentName }
+                   deriving (Eq, Generic, Ord, Read, Show, Typeable)
+
+pattern CFLibName :: UnqualComponentName -> ComponentName
+pattern CFLibName  n = CNotLibName (CNLFLibName  n)
+
+pattern CExeName :: UnqualComponentName -> ComponentName
+pattern CExeName   n = CNotLibName (CNLExeName   n)
+
+pattern CTestName :: UnqualComponentName -> ComponentName
+pattern CTestName  n = CNotLibName (CNLTestName  n)
+
+pattern CBenchName :: UnqualComponentName -> ComponentName
+pattern CBenchName n = CNotLibName (CNLBenchName n)
+{-# COMPLETE CLibName, CFLibName, CExeName, CTestName, CBenchName #-}
+
+instance Binary NotLibComponentName
+instance Structured NotLibComponentName
+
 instance Binary ComponentName
 instance Structured ComponentName
 
@@ -59,6 +81,10 @@
 showComponentName (CTestName  name) = "test suite '" ++ prettyShow name ++ "'"
 showComponentName (CBenchName name) = "benchmark '" ++ prettyShow name ++ "'"
 
+componentNameRaw :: ComponentName -> String
+componentNameRaw l@(CLibName  _) = showComponentName l
+componentNameRaw (CNotLibName x) = prettyShow $ toCompName x
+
 componentNameStanza :: ComponentName -> String
 componentNameStanza (CLibName lib)    = libraryNameStanza lib
 componentNameStanza (CFLibName  name) = "foreign-library " ++ prettyShow name
@@ -71,8 +97,5 @@
 -- @Nothing@ if the 'ComponentName' was for the public
 -- library.
 componentNameString :: ComponentName -> Maybe UnqualComponentName
-componentNameString (CLibName lib) = libraryNameString lib
-componentNameString (CFLibName  n) = Just n
-componentNameString (CExeName   n) = Just n
-componentNameString (CTestName  n) = Just n
-componentNameString (CBenchName n) = Just n
+componentNameString (CLibName  lib) = libraryNameString lib
+componentNameString (CNotLibName x) = Just $ toCompName x
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/CondTree.hs b/cabal/Cabal-syntax/src/Distribution/Types/CondTree.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/CondTree.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/CondTree.hs
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/Condition.hs b/cabal/Cabal-syntax/src/Distribution/Types/Condition.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/Condition.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/Condition.hs
@@ -26,7 +26,7 @@
 cNot (CNot c) = c
 cNot c        = CNot c
 
--- | Boolean AND of two 'Condtion' values.
+-- | Boolean AND of two 'Condition' values.
 cAnd :: Condition a -> Condition a -> Condition a
 cAnd (Lit False) _           = Lit False
 cAnd _           (Lit False) = Lit False
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/Dependency.hs b/cabal/Cabal-syntax/src/Distribution/Types/Dependency.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/Dependency.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/Dependency.hs
@@ -44,7 +44,7 @@
                     -- ^ The set of libraries required from the package.
                     -- Only the selected libraries will be built.
                     -- It does not affect the cabal-install solver yet.
-                  deriving (Generic, Read, Show, Eq, Typeable, Data)
+                  deriving (Generic, Read, Show, Eq, Ord, Typeable, Data)
 
 depPkgName :: Dependency -> PackageName
 depPkgName (Dependency pn _ _) = pn
@@ -77,16 +77,16 @@
 
 -- |
 --
--- >>> prettyShow $ Dependency "pkg" anyVersion mainLibSet
+-- >>> prettyShow $ Dependency (mkPackageName "pkg") anyVersion mainLibSet
 -- "pkg"
 --
--- >>> prettyShow $ Dependency "pkg" anyVersion $ NES.insert (LSubLibName "sublib") mainLibSet
+-- >>> prettyShow $ Dependency (mkPackageName "pkg") anyVersion $ NES.insert (LSubLibName $ mkUnqualComponentName "sublib") mainLibSet
 -- "pkg:{pkg, sublib}"
 --
--- >>> prettyShow $ Dependency "pkg" anyVersion $ NES.singleton (LSubLibName "sublib")
+-- >>> prettyShow $ Dependency (mkPackageName "pkg") anyVersion $ NES.singleton (LSubLibName $ mkUnqualComponentName "sublib")
 -- "pkg:sublib"
 --
--- >>> prettyShow $ Dependency "pkg" anyVersion $ NES.insert (LSubLibName "sublib-b") $ NES.singleton (LSubLibName "sublib-a")
+-- >>> prettyShow $ Dependency (mkPackageName "pkg") anyVersion $ NES.insert (LSubLibName $ mkUnqualComponentName "sublib-b") $ NES.singleton (LSubLibName $ mkUnqualComponentName "sublib-a")
 -- "pkg:{sublib-a, sublib-b}"
 --
 instance Pretty Dependency where
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/ExeDependency.hs b/cabal/Cabal-syntax/src/Distribution/Types/ExeDependency.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/ExeDependency.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/ExeDependency.hs
@@ -24,7 +24,7 @@
                      PackageName
                      UnqualComponentName -- name of executable component of package
                      VersionRange
-                     deriving (Generic, Read, Show, Eq, Typeable, Data)
+                     deriving (Generic, Read, Show, Eq, Ord, Typeable, Data)
 
 instance Binary ExeDependency
 instance Structured ExeDependency
@@ -37,7 +37,7 @@
       pver | isAnyVersion ver = PP.empty
            | otherwise        = pretty ver
 
--- | 
+-- |
 --
 -- Examples
 --
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/Executable.hs b/cabal/Cabal-syntax/src/Distribution/Types/Executable.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/Executable.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/Executable.hs
@@ -25,7 +25,7 @@
         exeScope   :: ExecutableScope,
         buildInfo  :: BuildInfo
     }
-    deriving (Generic, Show, Read, Eq, Typeable, Data)
+    deriving (Generic, Show, Read, Eq, Ord, Typeable, Data)
 
 instance L.HasBuildInfo Executable where
     buildInfo f l = (\x -> l { buildInfo = x }) <$> f (buildInfo l)
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/ExecutableScope.hs b/cabal/Cabal-syntax/src/Distribution/Types/ExecutableScope.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/ExecutableScope.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/ExecutableScope.hs
@@ -17,7 +17,7 @@
 
 data ExecutableScope = ExecutablePublic
                      | ExecutablePrivate
-    deriving (Generic, Show, Read, Eq, Typeable, Data)
+    deriving (Generic, Show, Read, Eq, Ord, Typeable, Data)
 
 instance Pretty ExecutableScope where
     pretty ExecutablePublic       = Disp.text "public"
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/Flag.hs b/cabal/Cabal-syntax/src/Distribution/Types/Flag.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/Flag.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/Flag.hs
@@ -193,7 +193,7 @@
 
 -- | Insert or update the boolean value of a flag.
 --
--- If the flag is already present in the 'FlagAssigment', the
+-- If the flag is already present in the 'FlagAssignment', the
 -- value will be updated and the fact that multiple values have
 -- been provided for that flag will be recorded so that a
 -- warning can be generated later on.
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/ForeignLib.hs b/cabal/Cabal-syntax/src/Distribution/Types/ForeignLib.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/ForeignLib.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/ForeignLib.hs
@@ -61,7 +61,7 @@
       -- the condition trees (for instance, when creating an sdist)
     , foreignLibModDefFile :: [FilePath]
     }
-    deriving (Generic, Show, Read, Eq, Typeable, Data)
+    deriving (Generic, Show, Read, Eq, Ord, Typeable, Data)
 
 data LibVersionInfo = LibVersionInfo Int Int Int deriving (Data, Eq, Generic, Typeable)
 
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/ForeignLibOption.hs b/cabal/Cabal-syntax/src/Distribution/Types/ForeignLibOption.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/ForeignLibOption.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/ForeignLibOption.hs
@@ -22,7 +22,7 @@
      -- This option is compulsory on Windows and unsupported
      -- on other platforms.
      ForeignLibStandalone
-    deriving (Generic, Show, Read, Eq, Typeable, Data)
+    deriving (Generic, Show, Read, Eq, Ord, Typeable, Data)
 
 instance Pretty ForeignLibOption where
   pretty ForeignLibStandalone = Disp.text "standalone"
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/ForeignLibType.hs b/cabal/Cabal-syntax/src/Distribution/Types/ForeignLibType.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/ForeignLibType.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/ForeignLibType.hs
@@ -27,7 +27,7 @@
     | ForeignLibNativeStatic
       -- TODO: Maybe this should record a string?
     | ForeignLibTypeUnknown
-    deriving (Generic, Show, Read, Eq, Typeable, Data)
+    deriving (Generic, Show, Read, Eq, Ord, Typeable, Data)
 
 instance Pretty ForeignLibType where
   pretty ForeignLibNativeShared = Disp.text "native-shared"
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/GenericPackageDescription.hs b/cabal/Cabal-syntax/src/Distribution/Types/GenericPackageDescription.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/GenericPackageDescription.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/GenericPackageDescription.hs
@@ -1,7 +1,6 @@
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE DeriveGeneric #-}
 {-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
 module Distribution.Types.GenericPackageDescription (
@@ -86,7 +85,6 @@
             <*> (traverse . L._2 . traverseCondTreeBuildInfo) f x4
             <*> (traverse . L._2 . traverseCondTreeBuildInfo) f x5
             <*> (traverse . L._2 . traverseCondTreeBuildInfo) f x6
-      where
 
 -- We use this traversal to keep [Dependency] field in CondTree up to date.
 traverseCondTreeBuildInfo
@@ -94,7 +92,7 @@
     => LensLike' f (CondTree v [Dependency] comp) L.BuildInfo
 traverseCondTreeBuildInfo g = node where
     mkCondNode :: comp -> [CondBranch v [Dependency] comp] -> CondTree v [Dependency] comp
-    mkCondNode comp branches = CondNode comp (view L.targetBuildDepends comp) branches
+    mkCondNode comp = CondNode comp (view L.targetBuildDepends comp)
 
     node (CondNode comp _ branches) = mkCondNode
         <$> L.buildInfo g comp
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/LegacyExeDependency.hs b/cabal/Cabal-syntax/src/Distribution/Types/LegacyExeDependency.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/LegacyExeDependency.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/LegacyExeDependency.hs
@@ -24,7 +24,7 @@
 data LegacyExeDependency = LegacyExeDependency
                            String
                            VersionRange
-                         deriving (Generic, Read, Show, Eq, Typeable, Data)
+                         deriving (Generic, Read, Show, Eq, Ord, Typeable, Data)
 
 instance Binary LegacyExeDependency
 instance Structured LegacyExeDependency
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/Library.hs b/cabal/Cabal-syntax/src/Distribution/Types/Library.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/Library.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/Library.hs
@@ -26,10 +26,10 @@
     , reexportedModules :: [ModuleReexport]
     , signatures        :: [ModuleName]       -- ^ What sigs need implementations?
     , libExposed        :: Bool               -- ^ Is the lib to be exposed by default? (i.e. whether its modules available in GHCi for example)
-    , libVisibility     :: LibraryVisibility  -- ^ Whether this multilib can be dependent from outside.
+    , libVisibility     :: LibraryVisibility  -- ^ Whether this multilib can be used as a dependency for other packages.
     , libBuildInfo      :: BuildInfo
     }
-    deriving (Generic, Show, Eq, Read, Typeable, Data)
+    deriving (Generic, Show, Eq, Ord, Read, Typeable, Data)
 
 instance L.HasBuildInfo Library where
     buildInfo f l = (\x -> l { libBuildInfo = x }) <$> f (libBuildInfo l)
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/LibraryName.hs b/cabal/Cabal-syntax/src/Distribution/Types/LibraryName.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/LibraryName.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/LibraryName.hs
@@ -35,7 +35,7 @@
 --
 -- /Note:/ there are no 'Pretty' or 'Parsec' instances,
 -- as there's other way to represent 'LibraryName', namely as bare
--- 'UnqualComponentName'. 
+-- 'UnqualComponentName'.
 prettyLibraryNameComponent :: LibraryName -> Disp.Doc
 prettyLibraryNameComponent LMainLibName      = Disp.text "lib"
 prettyLibraryNameComponent (LSubLibName str) = Disp.text "lib:" <<>> pretty str
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/LibraryVisibility.hs b/cabal/Cabal-syntax/src/Distribution/Types/LibraryVisibility.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/LibraryVisibility.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/LibraryVisibility.hs
@@ -20,11 +20,11 @@
 -- @since 3.0.0.0
 --
 data LibraryVisibility
-      -- | Can be depenendent from other packages
+      -- | Can be used as a dependency for other packages
     = LibraryVisibilityPublic
       -- | Internal library, default
     | LibraryVisibilityPrivate
-    deriving (Generic, Show, Read, Eq, Typeable, Data)
+    deriving (Generic, Show, Read, Eq, Ord, Typeable, Data)
 
 instance Pretty LibraryVisibility where
     pretty LibraryVisibilityPublic  = Disp.text "public"
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/Mixin.hs b/cabal/Cabal-syntax/src/Distribution/Types/Mixin.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/Mixin.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/Mixin.hs
@@ -78,7 +78,7 @@
     ]
 
 -- | Smart constructor of 'Mixin', enforces invariant.
--- 
+--
 -- @since 3.4.0.0
 mkMixin :: PackageName -> LibraryName -> IncludeRenaming -> Mixin
 mkMixin pn (LSubLibName uqn) incl
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/ModuleReexport.hs b/cabal/Cabal-syntax/src/Distribution/Types/ModuleReexport.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/ModuleReexport.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/ModuleReexport.hs
@@ -24,7 +24,7 @@
        moduleReexportOriginalName    :: ModuleName,
        moduleReexportName            :: ModuleName
     }
-    deriving (Eq, Generic, Read, Show, Typeable, Data)
+    deriving (Eq, Ord, Generic, Read, Show, Typeable, Data)
 
 instance Binary ModuleReexport
 instance Structured ModuleReexport
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/PackageDescription.hs b/cabal/Cabal-syntax/src/Distribution/Types/PackageDescription.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/PackageDescription.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/PackageDescription.hs
@@ -146,7 +146,7 @@
         extraTmpFiles  :: [FilePath],
         extraDocFiles  :: [FilePath]
     }
-    deriving (Generic, Show, Read, Eq, Typeable, Data)
+    deriving (Generic, Show, Read, Eq, Ord, Typeable, Data)
 
 instance Binary PackageDescription
 instance Structured PackageDescription
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/PkgconfigDependency.hs b/cabal/Cabal-syntax/src/Distribution/Types/PkgconfigDependency.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/PkgconfigDependency.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/PkgconfigDependency.hs
@@ -21,7 +21,7 @@
 data PkgconfigDependency = PkgconfigDependency
                            PkgconfigName
                            PkgconfigVersionRange
-                         deriving (Generic, Read, Show, Eq, Typeable, Data)
+                         deriving (Generic, Read, Show, Eq, Ord, Typeable, Data)
 
 instance Binary PkgconfigDependency
 instance Structured PkgconfigDependency
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/PkgconfigVersion.hs b/cabal/Cabal-syntax/src/Distribution/Types/PkgconfigVersion.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/PkgconfigVersion.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/PkgconfigVersion.hs
@@ -53,7 +53,7 @@
         predicate c = isAsciiAlphaNum c || c == '.' || c == '-'
 
 -------------------------------------------------------------------------------
--- rmpvercmp - pure Haskell implementation
+-- rpmvercmp - pure Haskell implementation
 -------------------------------------------------------------------------------
 
 -- | Compare two version strings as @pkg-config@ would compare them.
@@ -115,5 +115,4 @@
 
 isAlpha8 :: Word8 -> Bool
 isAlpha8 w = (0x41 <= w && w <= 0x5A) || (0x61 <= w && w <= 0x7A)
-
 
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/PkgconfigVersionRange.hs b/cabal/Cabal-syntax/src/Distribution/Types/PkgconfigVersionRange.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/PkgconfigVersionRange.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/PkgconfigVersionRange.hs
@@ -35,7 +35,7 @@
   | PcOrEarlierVersion       PkgconfigVersion -- =< version
   | PcUnionVersionRanges     PkgconfigVersionRange PkgconfigVersionRange
   | PcIntersectVersionRanges PkgconfigVersionRange PkgconfigVersionRange
-  deriving (Generic, Read, Show, Eq, Typeable, Data)
+  deriving (Generic, Read, Show, Eq, Ord, Typeable, Data)
 
 instance Binary PkgconfigVersionRange
 instance Structured PkgconfigVersionRange
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/SetupBuildInfo.hs b/cabal/Cabal-syntax/src/Distribution/Types/SetupBuildInfo.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/SetupBuildInfo.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/SetupBuildInfo.hs
@@ -25,7 +25,7 @@
         -- internally, and doesn't correspond to anything in the .cabal
         -- file. See #3199.
     }
-    deriving (Generic, Show, Eq, Read, Typeable, Data)
+    deriving (Generic, Show, Eq, Ord, Read, Typeable, Data)
 
 instance Binary SetupBuildInfo
 instance Structured SetupBuildInfo
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/TestSuite.hs b/cabal/Cabal-syntax/src/Distribution/Types/TestSuite.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/TestSuite.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/TestSuite.hs
@@ -30,7 +30,7 @@
         testBuildInfo :: BuildInfo,
         testCodeGenerators :: [String]
     }
-    deriving (Generic, Show, Read, Eq, Typeable, Data)
+    deriving (Generic, Show, Read, Eq, Ord, Typeable, Data)
 
 instance L.HasBuildInfo TestSuite where
     buildInfo f l = (\x -> l { testBuildInfo = x }) <$> f (testBuildInfo l)
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/TestSuiteInterface.hs b/cabal/Cabal-syntax/src/Distribution/Types/TestSuiteInterface.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/TestSuiteInterface.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/TestSuiteInterface.hs
@@ -21,8 +21,8 @@
 
      -- | Test interface \"exitcode-stdio-1.0\". The test-suite takes the form
      -- of an executable. It returns a zero exit code for success, non-zero for
-     -- failure. The stdout and stderr channels may be logged. It takes no
-     -- command line parameters and nothing on stdin.
+     -- failure. The stdout and stderr channels may be logged. Test tooling may
+     -- pass command line arguments and/or connect the stdin channel to the test.
      --
      TestSuiteExeV10 Version FilePath
 
@@ -35,7 +35,7 @@
      -- the given reason (e.g. unknown test type).
      --
    | TestSuiteUnsupported TestType
-   deriving (Eq, Generic, Read, Show, Typeable, Data)
+   deriving (Eq, Ord, Generic, Read, Show, Typeable, Data)
 
 instance Binary TestSuiteInterface
 instance Structured TestSuiteInterface
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/TestType.hs b/cabal/Cabal-syntax/src/Distribution/Types/TestType.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/TestType.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/TestType.hs
@@ -22,7 +22,7 @@
 data TestType = TestTypeExe Version     -- ^ \"type: exitcode-stdio-x.y\"
               | TestTypeLib Version     -- ^ \"type: detailed-x.y\"
               | TestTypeUnknown String Version -- ^ Some unknown test type e.g. \"type: foo\"
-    deriving (Generic, Show, Read, Eq, Typeable, Data)
+    deriving (Generic, Show, Read, Eq, Ord, Typeable, Data)
 
 instance Binary TestType
 instance Structured TestType
diff --git a/cabal/Cabal-syntax/src/Distribution/Types/VersionRange/Internal.hs b/cabal/Cabal-syntax/src/Distribution/Types/VersionRange/Internal.hs
--- a/cabal/Cabal-syntax/src/Distribution/Types/VersionRange/Internal.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Types/VersionRange/Internal.hs
@@ -56,7 +56,7 @@
   | MajorBoundVersion      Version -- @^>= ver@ (same as >= ver && < MAJ(ver)+1)
   | UnionVersionRanges     VersionRange VersionRange
   | IntersectVersionRanges VersionRange VersionRange
-  deriving ( Data, Eq, Generic, Read, Show, Typeable )
+  deriving ( Data, Eq, Ord, Generic, Read, Show, Typeable )
 
 instance Binary VersionRange
 instance Structured VersionRange
diff --git a/cabal/Cabal-syntax/src/Distribution/Utils/Generic.hs b/cabal/Cabal-syntax/src/Distribution/Utils/Generic.hs
--- a/cabal/Cabal-syntax/src/Distribution/Utils/Generic.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Utils/Generic.hs
@@ -237,7 +237,7 @@
         Just (cn, bs') | cn .&. 0xC0 == 0x80 ->
             moreBytes (off + 1) (byteCount-1) overlong bs' ((acc `shiftL` 6) .|. fromIntegral cn .&. 0x3F)
         _ -> Just off
-        
+
 
 -- | Ignore a Unicode byte order mark (BOM) at the beginning of the input
 --
diff --git a/cabal/Cabal-syntax/src/Distribution/Utils/ShortText.hs b/cabal/Cabal-syntax/src/Distribution/Utils/ShortText.hs
--- a/cabal/Cabal-syntax/src/Distribution/Utils/ShortText.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Utils/ShortText.hs
@@ -4,7 +4,7 @@
 
 -- | Compact representation of short 'Strings'
 --
--- This module is designed to be import qualifeid
+-- This module is designed to be import qualified
 --
 -- @
 -- import Distribution.Utils.ShortText (ShortText)
diff --git a/cabal/Cabal-syntax/src/Distribution/Utils/Structured.hs b/cabal/Cabal-syntax/src/Distribution/Utils/Structured.hs
--- a/cabal/Cabal-syntax/src/Distribution/Utils/Structured.hs
+++ b/cabal/Cabal-syntax/src/Distribution/Utils/Structured.hs
@@ -7,7 +7,6 @@
 {-# LANGUAGE TypeFamilies        #-}
 {-# LANGUAGE TypeOperators       #-}
 {-# LANGUAGE PatternSynonyms     #-}
-{-# LANGUAGE TypeInType          #-}
 -- |
 --
 -- Copyright: (c) 2019 Oleg Grenrus
@@ -321,7 +320,7 @@
 -- Generic
 -------------------------------------------------------------------------------
 
--- | Derive 'structure' genrically.
+-- | Derive 'structure' generically.
 genericStructure :: forall a. (Typeable a, Generic a, GStructured (Rep a)) => Proxy a -> Structure
 genericStructure _ = gstructured (typeRep (Proxy :: Proxy a)) (Proxy :: Proxy (Rep a)) 0
 
diff --git a/cabal/Cabal-syntax/src/Language/Haskell/Extension.hs b/cabal/Cabal-syntax/src/Language/Haskell/Extension.hs
--- a/cabal/Cabal-syntax/src/Language/Haskell/Extension.hs
+++ b/cabal/Cabal-syntax/src/Language/Haskell/Extension.hs
@@ -25,7 +25,6 @@
         knownExtensions
   ) where
 
-import qualified Prelude (head)
 import Distribution.Compat.Prelude
 
 import Data.Array (Array, accumArray, bounds, Ix(inRange), (!))
@@ -61,7 +60,7 @@
 
   -- | An unknown language, identified by its name.
   | UnknownLanguage String
-  deriving (Generic, Show, Read, Eq, Typeable, Data)
+  deriving (Generic, Show, Read, Eq, Ord, Typeable, Data)
 
 instance Binary Language
 instance Structured Language
@@ -121,28 +120,27 @@
 
 instance NFData Extension where rnf = genericRnf
 
+-- | Known Haskell language extensions, including deprecated and undocumented
+-- ones.
+--
+-- Check <https://downloads.haskell.org/~ghc/9.2.3/docs/html/users_guide/exts/table.html “Overview of all language extensions” in GHC User’s Guide>
+-- for more information.
 data KnownExtension =
 
   -- | Allow overlapping class instances, provided there is a unique
   -- most specific instance for each use.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XOverlappingInstances>
     OverlappingInstances
 
   -- | Ignore structural rules guaranteeing the termination of class
   -- instance resolution.  Termination is guaranteed by a fixed-depth
   -- recursion stack, and compilation may fail if this depth is
   -- exceeded.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XUndecidableInstances>
   | UndecidableInstances
 
   -- | Implies 'OverlappingInstances'.  Allow the implementation to
   -- choose an instance even when it is possible that further
   -- instantiation of types will lead to a more specific instance
   -- being applicable.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XIncoherentInstances>
   | IncoherentInstances
 
   -- | /(deprecated)/ Deprecated in favour of 'RecursiveDo'.
@@ -153,34 +151,29 @@
 
   -- | Allow recursive bindings in @do@ blocks, using the @rec@
   -- keyword, or @mdo@, a variant of @do@.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XRecursiveDo>
   | RecursiveDo
 
   -- | Provide syntax for writing list comprehensions which iterate
   -- over several lists together, like the 'zipWith' family of
   -- functions.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XParallelListComp>
   | ParallelListComp
 
   -- | Allow multiple parameters in a type class.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XMultiParamTypeClasses>
   | MultiParamTypeClasses
 
   -- | Enable the dreaded monomorphism restriction.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XNoMonomorphismRestriction>
   | MonomorphismRestriction
 
+  -- | Enable deep subsumption, relaxing the simple subsumption rules,
+  -- implicitly inserting eta-expansions when matching up function types
+  -- with different quantification structures.
+  | DeepSubsumption
+
   -- | Allow a specification attached to a multi-parameter type class
   -- which indicates that some parameters are entirely determined by
   -- others. The implementation will check that this property holds
   -- for the declared instances, and will use this property to reduce
   -- ambiguity in instance resolution.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XFunctionalDependencies>
   | FunctionalDependencies
 
   -- | /(deprecated)/ A synonym for 'RankNTypes'.
@@ -188,14 +181,10 @@
   -- Old description: Like 'RankNTypes' but does not allow a
   -- higher-rank type to itself appear on the left of a function
   -- arrow.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XRank2Types>
   | Rank2Types
 
   -- | Allow a universally-quantified type to occur on the left of a
   -- function arrow.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XRankNTypes>
   | RankNTypes
 
   -- | /(deprecated)/ A synonym for 'RankNTypes'.
@@ -203,197 +192,134 @@
   -- Old description: Allow data constructors to have polymorphic
   -- arguments.  Unlike 'RankNTypes', does not allow this for ordinary
   -- functions.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#arbitrary-rank-polymorphism>
   | PolymorphicComponents
 
   -- | Allow existentially-quantified data constructors.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XExistentialQuantification>
   | ExistentialQuantification
 
   -- | Cause a type variable in a signature, which has an explicit
   -- @forall@ quantifier, to scope over the definition of the
   -- accompanying value declaration.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XScopedTypeVariables>
   | ScopedTypeVariables
 
   -- | Deprecated, use 'ScopedTypeVariables' instead.
   | PatternSignatures
 
   -- | Enable implicit function parameters with dynamic scope.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XImplicitParams>
   | ImplicitParams
 
   -- | Relax some restrictions on the form of the context of a type
   -- signature.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XFlexibleContexts>
   | FlexibleContexts
 
   -- | Relax some restrictions on the form of the context of an
   -- instance declaration.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XFlexibleInstances>
   | FlexibleInstances
 
   -- | Allow data type declarations with no constructors.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XEmptyDataDecls>
   | EmptyDataDecls
 
   -- | Run the C preprocessor on Haskell source code.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#language-pragma>
   | CPP
 
   -- | Allow an explicit kind signature giving the kind of types over
   -- which a type variable ranges.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XKindSignatures>
   | KindSignatures
 
   -- | Enable a form of pattern which forces evaluation before an
   -- attempted match, and a form of strict @let@/@where@ binding.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XBangPatterns>
   | BangPatterns
 
   -- | Allow type synonyms in instance heads.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XTypeSynonymInstances>
   | TypeSynonymInstances
 
   -- | Enable Template Haskell, a system for compile-time
   -- metaprogramming.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XTemplateHaskell>
   | TemplateHaskell
 
   -- | Enable the Foreign Function Interface.  In GHC, implements the
   -- standard Haskell 98 Foreign Function Interface Addendum, plus
   -- some GHC-specific extensions.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#language-pragma>
   | ForeignFunctionInterface
 
   -- | Enable arrow notation.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XArrows>
   | Arrows
 
   -- | /(deprecated)/ Enable generic type classes, with default instances defined in
   -- terms of the algebraic structure of a type.
-  --
-  -- * <https://haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#generic-classes>
   | Generics
 
   -- | Enable the implicit importing of the module "Prelude".  When
   -- disabled, when desugaring certain built-in syntax into ordinary
   -- identifiers, use whatever is in scope rather than the "Prelude"
   -- -- version.
-  --
-  -- * <https://haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#rebindable-syntax-and-the-implicit-prelude-import>
   | ImplicitPrelude
 
   -- | Enable syntax for implicitly binding local names corresponding
   -- to the field names of a record.  Puns bind specific names, unlike
   -- 'RecordWildCards'.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XNamedFieldPuns>
   | NamedFieldPuns
 
   -- | Enable a form of guard which matches a pattern and binds
   -- variables.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XPatternGuards>
   | PatternGuards
 
   -- | Allow a type declared with @newtype@ to use @deriving@ for any
   -- class with an instance for the underlying type.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XGeneralizedNewtypeDeriving>
   | GeneralizedNewtypeDeriving
 
   -- Synonym for GeneralizedNewtypeDeriving added in GHC 8.6.1.
   | GeneralisedNewtypeDeriving
 
   -- | Enable the \"Trex\" extensible records system.
-  --
-  -- * <http://haskell.org/hugs/pages/users_guide/hugs-only.html#TREX>
   | ExtensibleRecords
 
   -- | Enable type synonyms which are transparent in some definitions
   -- and opaque elsewhere, as a way of implementing abstract
   -- datatypes.
-  --
-  -- * <http://haskell.org/hugs/pages/users_guide/restricted-synonyms.html>
   | RestrictedTypeSynonyms
 
   -- | Enable an alternate syntax for string literals,
   -- with string templating.
-  --
-  -- * <http://haskell.org/hugs/pages/users_guide/here-documents.html>
   | HereDocuments
 
   -- | Allow the character @#@ as a postfix modifier on identifiers.
   -- Also enables literal syntax for unboxed values.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XMagicHash>
   | MagicHash
 
   -- | Allow data types and type synonyms which are indexed by types,
   -- i.e. ad-hoc polymorphism for types.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XTypeFamilies>
   | TypeFamilies
 
   -- | Allow a standalone declaration which invokes the type class
   -- @deriving@ mechanism.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XStandaloneDeriving>
   | StandaloneDeriving
 
   -- | Allow certain Unicode characters to stand for certain ASCII
   -- character sequences, e.g. keywords and punctuation.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XUnicodeSyntax>
   | UnicodeSyntax
 
   -- | Allow the use of unboxed types as foreign types, e.g. in
   -- @foreign import@ and @foreign export@.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#language-options>
   | UnliftedFFITypes
 
   -- | Enable interruptible FFI.
-  --
-  -- * <https://haskell.org/ghc/docs/latest/html/users_guide/ffi-chap.html#interruptible-foreign-calls>
   | InterruptibleFFI
 
   -- | Allow use of CAPI FFI calling convention (@foreign import capi@).
-  --
-  -- * <https://haskell.org/ghc/docs/latest/html/users_guide/ffi-chap.html#the-capi-calling-convention>
   | CApiFFI
 
   -- | Defer validity checking of types until after expanding type
   -- synonyms, relaxing the constraints on how synonyms may be used.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XLiberalTypeSynonyms>
   | LiberalTypeSynonyms
 
   -- | Allow the name of a type constructor, type class, or type
   -- variable to be an infix operator.
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XTypeOperators>
   | TypeOperators
 
   -- | Enable syntax for implicitly binding local names corresponding
   -- to the field names of a record.  A wildcard binds all unmentioned
   -- names, unlike 'NamedFieldPuns'.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XRecordWildCards>
   | RecordWildCards
 
   -- | Deprecated, use 'NamedFieldPuns' instead.
@@ -401,131 +327,87 @@
 
   -- | Allow a record field name to be disambiguated by the type of
   -- the record it's in.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XDisambiguateRecordFields>
   | DisambiguateRecordFields
 
   -- | Enable traditional record syntax (as supported by Haskell 98)
-  --
-  -- * <https://haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#traditional-record-syntax>
   | TraditionalRecordSyntax
 
   -- | Enable overloading of string literals using a type class, much
   -- like integer literals.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XOverloadedStrings>
   | OverloadedStrings
 
   -- | Enable generalized algebraic data types, in which type
   -- variables may be instantiated on a per-constructor basis. Implies
   -- 'GADTSyntax'.
-  --
-  -- * <https://haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#generalised-algebraic-data-types-gadts>
   | GADTs
 
   -- | Enable GADT syntax for declaring ordinary algebraic datatypes.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XGADTSyntax>
   | GADTSyntax
 
   -- | /(deprecated)/ Has no effect.
   --
   -- Old description: Make pattern bindings monomorphic.
-  --
-  -- * <https://downloads.haskell.org/~ghc/7.6.3/docs/html/users_guide/monomorphism.html>
   | MonoPatBinds
 
   -- | Relax the requirements on mutually-recursive polymorphic
   -- functions.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XRelaxedPolyRec>
   | RelaxedPolyRec
 
   -- | Allow default instantiation of polymorphic types in more
   -- situations.
-  --
-  -- * <http://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ghci.html#type-defaulting-in-ghci>
   | ExtendedDefaultRules
 
   -- | Enable unboxed tuples.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XUnboxedTuples>
   | UnboxedTuples
 
   -- | Enable @deriving@ for classes 'Data.Typeable.Typeable' and
   -- 'Data.Generics.Data'.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XDeriveDataTypeable>
   | DeriveDataTypeable
 
   -- | Enable @deriving@ for 'GHC.Generics.Generic' and 'GHC.Generics.Generic1'.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XDeriveGeneric>
   | DeriveGeneric
 
   -- | Enable support for default signatures.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XDefaultSignatures>
   | DefaultSignatures
 
   -- | Allow type signatures to be specified in instance declarations.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XInstanceSigs>
   | InstanceSigs
 
   -- | Allow a class method's type to place additional constraints on
   -- a class type variable.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XConstrainedClassMethods>
   | ConstrainedClassMethods
 
   -- | Allow imports to be qualified by the package name the module is
   -- intended to be imported from, e.g.
   --
   -- > import "network" Network.Socket
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XPackageImports>
   | PackageImports
 
   -- | /(deprecated)/ Allow a type variable to be instantiated at a
   -- polymorphic type.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XImpredicativeTypes>
   | ImpredicativeTypes
 
   -- | /(deprecated)/ Change the syntax for qualified infix operators.
-  --
-  -- * <http://www.haskell.org/ghc/docs/6.12.3/html/users_guide/syntax-extns.html#new-qualified-operators>
   | NewQualifiedOperators
 
   -- | Relax the interpretation of left operator sections to allow
   -- unary postfix operators.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XPostfixOperators>
   | PostfixOperators
 
   -- | Enable quasi-quotation, a mechanism for defining new concrete
   -- syntax for expressions and patterns.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XQuasiQuotes>
   | QuasiQuotes
 
   -- | Enable generalized list comprehensions, supporting operations
   -- such as sorting and grouping.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XTransformListComp>
   | TransformListComp
 
   -- | Enable monad comprehensions, which generalise the list
   -- comprehension syntax to work for any monad.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XMonadComprehensions>
   | MonadComprehensions
 
   -- | Enable view patterns, which match a value by applying a
   -- function and matching on the result.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XViewPatterns>
   | ViewPatterns
 
   -- | Allow concrete XML syntax to be used in expressions and patterns,
@@ -542,8 +424,6 @@
 
   -- | Enable the use of tuple sections, e.g. @(, True)@ desugars into
   -- @\x -> (x, True)@.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XTupleSections>
   | TupleSections
 
   -- | Allow GHC primops, written in C--, to be imported into a Haskell
@@ -552,8 +432,6 @@
 
   -- | Support for patterns of the form @n + k@, where @k@ is an
   -- integer literal.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XNPlusKPatterns>
   | NPlusKPatterns
 
   -- | Improve the layout rule when @if@ expressions are used in a @do@
@@ -561,56 +439,36 @@
   | DoAndIfThenElse
 
   -- | Enable support for multi-way @if@-expressions.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XMultiWayIf>
   | MultiWayIf
 
   -- | Enable support lambda-@case@ expressions.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XLambdaCase>
   | LambdaCase
 
   -- | Makes much of the Haskell sugar be desugared into calls to the
   -- function with a particular name that is in scope.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XRebindableSyntax>
   | RebindableSyntax
 
   -- | Make @forall@ a keyword in types, which can be used to give the
   -- generalisation explicitly.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XExplicitForAll>
   | ExplicitForAll
 
   -- | Allow contexts to be put on datatypes, e.g. the @Eq a@ in
   -- @data Eq a => Set a = NilSet | ConsSet a (Set a)@.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XDatatypeContexts>
   | DatatypeContexts
 
   -- | Local (@let@ and @where@) bindings are monomorphic.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XMonoLocalBinds>
   | MonoLocalBinds
 
   -- | Enable @deriving@ for the 'Data.Functor.Functor' class.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XDeriveFunctor>
   | DeriveFunctor
 
   -- | Enable @deriving@ for the 'Data.Traversable.Traversable' class.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XDeriveTraversable>
   | DeriveTraversable
 
   -- | Enable @deriving@ for the 'Data.Foldable.Foldable' class.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XDeriveFoldable>
   | DeriveFoldable
 
   -- | Enable non-decreasing indentation for @do@ blocks.
-  --
-  -- * <https://haskell.org/ghc/docs/latest/html/users_guide/bugs.html#context-free-syntax>
   | NondecreasingIndentation
 
   -- | Allow imports to be qualified with a safe keyword that requires
@@ -618,156 +476,107 @@
   -- definition of trust.
   --
   -- > import safe Network.Socket
-  --
-  -- * <https://haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#safe-imports>
   | SafeImports
 
   -- | Compile a module in the Safe, Safe Haskell mode -- a restricted
   -- form of the Haskell language to ensure type safety.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/safe_haskell.html#ghc-flag--XSafe>
   | Safe
 
   -- | Compile a module in the Trustworthy, Safe Haskell mode -- no
   -- restrictions apply but the module is marked as trusted as long as
   -- the package the module resides in is trusted.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/safe_haskell.html#ghc-flag--XTrustworthy>
   | Trustworthy
 
   -- | Compile a module in the Unsafe, Safe Haskell mode so that
   -- modules compiled using Safe, Safe Haskell mode can't import it.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/safe_haskell.html#ghc-flag--XUnsafe>
   | Unsafe
 
   -- | Allow type class/implicit parameter/equality constraints to be
   -- used as types with the special kind constraint.  Also generalise
   -- the @(ctxt => ty)@ syntax so that any type of kind constraint can
   -- occur before the arrow.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XConstraintKinds>
   | ConstraintKinds
 
   -- | Enable kind polymorphism.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XPolyKinds>
   | PolyKinds
 
   -- | Enable datatype promotion.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XDataKinds>
   | DataKinds
 
+  -- | Enable @type data@ declarations, defining constructors at the type level.
+  | TypeData
+
   -- | Enable parallel arrays syntax (@[:@, @:]@) for /Data Parallel Haskell/.
-  --
-  -- * <http://www.haskell.org/haskellwiki/GHC/Data_Parallel_Haskell>
   | ParallelArrays
 
   -- | Enable explicit role annotations, like in (@type role Foo representational representational@).
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XRoleAnnotations>
   | RoleAnnotations
 
   -- | Enable overloading of list literals, arithmetic sequences and
   -- list patterns using the 'IsList' type class.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XOverloadedLists>
   | OverloadedLists
 
   -- | Enable case expressions that have no alternatives. Also applies to lambda-case expressions if they are enabled.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XEmptyCase>
   | EmptyCase
 
   -- | /(deprecated)/ Deprecated in favour of 'DeriveDataTypeable'.
   --
   -- Old description: Triggers the generation of derived 'Typeable'
   -- instances for every datatype and type class declaration.
-  --
-  -- * <https://haskell.org/ghc/docs/7.8.4/html/users_guide/deriving.html#auto-derive-typeable>
   | AutoDeriveTypeable
 
   -- | Desugars negative literals directly (without using negate).
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XNegativeLiterals>
   | NegativeLiterals
 
   -- | Allow the use of binary integer literal syntax (e.g. @0b11001001@ to denote @201@).
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XBinaryLiterals>
   | BinaryLiterals
 
   -- | Allow the use of floating literal syntax for all instances of 'Num', including 'Int' and 'Integer'.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XNumDecimals>
   | NumDecimals
 
   -- | Enable support for type classes with no type parameter.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XNullaryTypeClasses>
   | NullaryTypeClasses
 
   -- | Enable explicit namespaces in module import/export lists.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XExplicitNamespaces>
   | ExplicitNamespaces
 
   -- | Allow the user to write ambiguous types, and the type inference engine to infer them.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XAllowAmbiguousTypes>
   | AllowAmbiguousTypes
 
   -- | Enable @foreign import javascript@.
   | JavaScriptFFI
 
   -- | Allow giving names to and abstracting over patterns.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XPatternSynonyms>
   | PatternSynonyms
 
   -- | Allow anonymous placeholders (underscore) inside type signatures.  The
   -- type inference engine will generate a message describing the type inferred
   -- at the hole's location.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XPartialTypeSignatures>
   | PartialTypeSignatures
 
   -- | Allow named placeholders written with a leading underscore inside type
   -- signatures.  Wildcards with the same name unify to the same type.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XNamedWildCards>
   | NamedWildCards
 
   -- | Enable @deriving@ for any class.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XDeriveAnyClass>
   | DeriveAnyClass
 
   -- | Enable @deriving@ for the 'Language.Haskell.TH.Syntax.Lift' class.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XDeriveLift>
   | DeriveLift
 
   -- | Enable support for 'static pointers' (and the @static@
   -- keyword) to refer to globally stable names, even across
   -- different programs.
-  --
-  -- * <https://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#ghc-flag--XStaticPointers>
   | StaticPointers
 
   -- | Switches data type declarations to be strict by default (as if
   -- they had a bang using @BangPatterns@), and allow opt-in field
   -- laziness using @~@.
-  --
-  -- * <https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#ghc-flag--XStrictData>
   | StrictData
 
   -- | Switches all pattern bindings to be strict by default (as if
   -- they had a bang using @BangPatterns@), ordinary patterns are
   -- recovered using @~@. Implies @StrictData@.
-  --
-  -- * <https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#ghc-flag--XStrict>
   | Strict
 
   -- | Allows @do@-notation for types that are @'Applicative'@ as well
@@ -830,8 +639,6 @@
   | StarIsType
 
   -- | Liberalises deriving to provide instances for empty data types.
-  --
-  -- * <https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#deriving-instances-for-empty-data-types>
   | EmptyDataDeriving
 
   -- | Enable detection of complete user-supplied kind signatures.
@@ -855,6 +662,9 @@
   -- | Enable linear types.
   | LinearTypes
 
+  -- | Allow the use of visible forall in types of terms.
+  | RequiredTypeArguments
+
   -- | Enable the generation of selector functions corresponding to record fields.
   | FieldSelectors
 
@@ -862,8 +672,6 @@
   | OverloadedRecordDot
 
   -- | Provides record @.@ syntax in record updates, e.g. @x {foo.bar = 1}@.
-  --
-  -- * <https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/exts/overloaded_record_update.html#extension-OverloadedRecordUpdate>
   | OverloadedRecordUpdate
 
   -- | Enable data types for which an unlifted or levity-polymorphic result kind is inferred.
@@ -943,9 +751,9 @@
 knownExtensionTable :: Array Char [(String, KnownExtension)]
 knownExtensionTable =
   accumArray (flip (:)) [] ('A', 'Z')
-    [ (Prelude.head str, (str, extension)) -- assume KnownExtension's Show returns a non-empty string
-    | extension <- [toEnum 0 ..]
-    , let str = show extension ]
+    [ (hd, (str, extension)) -- assume KnownExtension's Show returns a non-empty string
+    | (extension, str@(hd : _)) <- map (\e -> (e, show e)) [toEnum 0 ..]
+    ]
 
 knownExtensions :: [KnownExtension]
 knownExtensions = [minBound .. maxBound]
diff --git a/cabal/Cabal-tests/Cabal-tests.cabal b/cabal/Cabal-tests/Cabal-tests.cabal
--- a/cabal/Cabal-tests/Cabal-tests.cabal
+++ b/cabal/Cabal-tests/Cabal-tests.cabal
@@ -1,7 +1,7 @@
 cabal-version: 2.2
 name:          Cabal-tests
 version:       3
-copyright:     2003-2022, Cabal Development Team (see AUTHORS file)
+copyright:     2003-2023, Cabal Development Team (see AUTHORS file)
 license:       BSD-3-Clause
 license-file:  LICENSE
 author:        Cabal Development Team <cabal-devel@haskell.org>
@@ -51,7 +51,7 @@
   build-depends:
       array
     , async               >=2.2.2 && <2.3
-    , base                >=0     && <5
+    , base                >=4.9     && <5
     , binary
     , bytestring
     , Cabal
@@ -60,7 +60,7 @@
     , Cabal-QuickCheck
     , containers
     , deepseq
-    , Diff                >=0.4   && <0.5
+    , Diff                >=0.4   && <0.6
     , directory
     , filepath
     , integer-logarithms  >=1.0.2 && <1.1
@@ -68,7 +68,7 @@
     , QuickCheck          >=2.14  && <2.15
     , rere                >=0.1   && <0.3
     , tagged
-    , tasty               >=1.2.3 && <1.5
+    , tasty               >=1.2.3 && <1.6
     , tasty-hunit
     , tasty-quickcheck
     , temporary
@@ -84,18 +84,18 @@
   main-is:          ParserTests.hs
   build-depends:
       base
-    , base-compat       >=0.11.0  && <0.13
+    , base-compat       >=0.11.0  && <0.14
     , bytestring
     , Cabal-syntax
     , Cabal-tree-diff
-    , Diff              >=0.4     && <0.5
+    , Diff              >=0.4     && <0.6
     , directory
     , filepath
-    , tasty             >=1.2.3   && <1.5
+    , tasty             >=1.2.3   && <1.6
     , tasty-golden      >=2.3.1.1 && <2.4
     , tasty-hunit
     , tasty-quickcheck
-    , tree-diff         >=0.1     && <0.3
+    , tree-diff         >=0.1     && <0.4
 
   ghc-options:      -Wall
   default-language: Haskell2010
@@ -109,10 +109,10 @@
     , bytestring
     , Cabal
     , Cabal-syntax
-    , Diff          >=0.4     && <0.5
+    , Diff          >=0.4     && <0.6
     , directory
     , filepath
-    , tasty         >=1.2.3   && <1.5
+    , tasty         >=1.2.3   && <1.6
     , tasty-expected-failure
     , tasty-golden  >=2.3.1.1 && <2.4
 
@@ -155,13 +155,13 @@
     , filepath
 
   build-depends:
-      base-compat           >=0.11.0   && <0.13
-    , base-orphans          >=0.6      && <0.9
+      base-compat           >=0.11.0   && <0.14
+    , base-orphans          >=0.6      && <0.10
     , clock                 >=0.8      && <0.9
-    , optparse-applicative  >=0.13.2.0 && <0.17
+    , optparse-applicative  >=0.13.2.0 && <0.19
     , stm                   >=2.4.5.0  && <2.6
     , tar                   >=0.5.0.3  && <0.7
-    , tree-diff             >=0.1      && <0.3
+    , tree-diff             >=0.1      && <0.4
 
   ghc-options:        -Wall -rtsopts -threaded
   default-extensions: CPP
@@ -178,7 +178,7 @@
 
   build-depends:
       QuickCheck
-    , tasty             >=1.2.3 && <1.5
+    , tasty             >=1.2.3 && <1.6
     , tasty-hunit
     , tasty-quickcheck
 
@@ -197,10 +197,10 @@
       base
     , bytestring
     , Cabal-syntax
-    , tasty        >=1.2.3 && <1.5
+    , tasty        >=1.2.3 && <1.6
     , tasty-hunit
 
   -- this is test is buildable on old GHCs
   -- but it doesn't do anything.
   if impl(ghc >=8.6)
-    build-depends: nothunks >=0.1.1.0 && <0.2
+    build-depends: nothunks >=0.1.1.0 && <0.3
diff --git a/cabal/Cabal-tests/LICENSE b/cabal/Cabal-tests/LICENSE
--- a/cabal/Cabal-tests/LICENSE
+++ b/cabal/Cabal-tests/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2003-2022, Cabal Development Team.
+Copyright (c) 2003-2023, Cabal Development Team.
 See the AUTHORS file for the full list of copyright holders.
 
 See */LICENSE for the copyright holders of the subcomponents.
diff --git a/cabal/Cabal-tests/tests/CheckTests.hs b/cabal/Cabal-tests/tests/CheckTests.hs
--- a/cabal/Cabal-tests/tests/CheckTests.hs
+++ b/cabal/Cabal-tests/tests/CheckTests.hs
@@ -45,6 +45,7 @@
     , checkTest "assoc-cpp-options.cabal"
     , checkTest "public-multilib-1.cabal"
     , checkTest "public-multilib-2.cabal"
+    , checkTest "all-upper-bound.cabal"
     , checkTest "issue-6288-a.cabal"
     , checkTest "issue-6288-b.cabal"
     , checkTest "issue-6288-c.cabal"
@@ -55,6 +56,7 @@
     , checkTest "issue-7776-a.cabal"
     , checkTest "issue-7776-b.cabal"
     , checkTest "issue-7776-c.cabal"
+    , checkTest "issue-8646.cabal"
     ]
 
 checkTest :: FilePath -> TestTree
diff --git a/cabal/Cabal-tests/tests/HackageTests.hs b/cabal/Cabal-tests/tests/HackageTests.hs
--- a/cabal/Cabal-tests/tests/HackageTests.hs
+++ b/cabal/Cabal-tests/tests/HackageTests.hs
@@ -25,7 +25,7 @@
 import Distribution.PackageDescription.Quirks      (patchQuirks)
 import Distribution.Simple.Utils                   (fromUTF8BS, toUTF8BS)
 import Numeric                                     (showFFloat)
-import System.Directory                            (getAppUserDataDirectory)
+import System.Directory                            (getXdgDirectory, XdgDirectory(XdgCache, XdgConfig), getAppUserDataDirectory, doesDirectoryExist)
 import System.Environment                          (lookupEnv)
 import System.Exit                                 (exitFailure)
 import System.FilePath                             ((</>))
@@ -63,27 +63,38 @@
 parseIndex :: (Monoid a, NFData a) => (FilePath -> Bool)
            -> (FilePath -> B.ByteString -> IO a) -> IO a
 parseIndex predicate action = do
-    cabalDir   <- getCabalDir
-    configPath <- getCabalConfigPath cabalDir
+    configPath <- getCabalConfigPath
     cfg        <- B.readFile configPath
     cfgFields  <- either (fail . show) pure $ Parsec.readFields cfg
+    repoCache  <- case lookupInConfig "remote-repo-cache" cfgFields of
+                    []        -> getCacheDirPath   -- Default
+                    (rrc : _) -> return rrc        -- User-specified
     let repos        = reposFromConfig cfgFields
-        repoCache    = case lookupInConfig "remote-repo-cache" cfgFields of
-            []        -> cabalDir </> "packages"  -- Default
-            (rrc : _) -> rrc                      -- User-specified
         tarName repo = repoCache </> repo </> "01-index.tar"
     mconcat <$> traverse (parseIndex' predicate action . tarName) repos
   where
-    getCabalDir = do
-        mx <- lookupEnv "CABAL_DIR"
-        case mx of
-            Just x  -> return x
-            Nothing -> getAppUserDataDirectory "cabal"
-    getCabalConfigPath cabalDir = do
+    getCacheDirPath =
+        getXdgDirectory XdgCache $ "cabal" </> "packages"
+    getCabalConfigPath = do
         mx <- lookupEnv "CABAL_CONFIG"
         case mx of
             Just x  -> return x
-            Nothing -> return (cabalDir </> "config")
+            Nothing -> do
+              mDir <- maybeGetCabalDir
+              case mDir of
+                Nothing -> getXdgDirectory XdgConfig $ "cabal" </> "config"
+                Just dir -> return $ dir </> "config"
+    maybeGetCabalDir :: IO (Maybe FilePath)
+    maybeGetCabalDir = do
+      mDir <- lookupEnv "CABAL_DIR"
+      case mDir of
+        Just dir -> return $ Just dir
+        Nothing -> do
+          defaultDir <- getAppUserDataDirectory "cabal"
+          dotCabalExists <- doesDirectoryExist defaultDir
+          return $ if dotCabalExists
+                   then Just defaultDir
+                   else Nothing
 
 
 parseIndex'
diff --git a/cabal/Cabal-tests/tests/ParserTests/errors/leading-comma-2c.cabal b/cabal/Cabal-tests/tests/ParserTests/errors/leading-comma-2c.cabal
--- a/cabal/Cabal-tests/tests/ParserTests/errors/leading-comma-2c.cabal
+++ b/cabal/Cabal-tests/tests/ParserTests/errors/leading-comma-2c.cabal
@@ -8,7 +8,7 @@
   default-language: Haskell2010
   exposed-modules:
     LeadingComma, MixedComma NoComma
-   
+
 
   build-depends: base, containers
 
diff --git a/cabal/Cabal-tests/tests/ParserTests/regressions/Octree-0.5.format b/cabal/Cabal-tests/tests/ParserTests/regressions/Octree-0.5.format
--- a/cabal/Cabal-tests/tests/ParserTests/regressions/Octree-0.5.format
+++ b/cabal/Cabal-tests/tests/ParserTests/regressions/Octree-0.5.format
@@ -1,4 +1,4 @@
-Octree-0.5.cabal:39:3: Non breaking spaces at 39:3, 41:3, 43:3
+Octree-0.5.cabal:39:1: Non breaking spaces at 39:1, 41:1, 43:1
 cabal-version: >=1.8
 name:          Octree
 version:       0.5
diff --git a/cabal/Cabal-tests/tests/ParserTests/regressions/all-upper-bound.cabal b/cabal/Cabal-tests/tests/ParserTests/regressions/all-upper-bound.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/Cabal-tests/tests/ParserTests/regressions/all-upper-bound.cabal
@@ -0,0 +1,19 @@
+cabal-version: 3.0
+name:          all-upper-bound
+version:       0
+synopsis:      all-upper-bound
+category:      Tests
+license:       MIT
+maintainer:    someone@example.com
+description:   all-upper-bound test package.
+
+library
+  default-language: Haskell2010
+  build-depends:
+    , base     ^>=4.14
+    , somelib
+    , alphalib
+    , betalib
+    , deltalib
+
+  exposed-modules:  Foo
diff --git a/cabal/Cabal-tests/tests/ParserTests/regressions/all-upper-bound.check b/cabal/Cabal-tests/tests/ParserTests/regressions/all-upper-bound.check
new file mode 100644
--- /dev/null
+++ b/cabal/Cabal-tests/tests/ParserTests/regressions/all-upper-bound.check
@@ -0,0 +1,6 @@
+These packages miss upper bounds:
+  - alphalib
+  - betalib
+  - deltalib
+  - somelib
+Please add them, using `cabal gen-bounds` for suggestions. For more information see:  https://pvp.haskell.org/
diff --git a/cabal/Cabal-tests/tests/ParserTests/regressions/cc-options-with-optimization.cabal b/cabal/Cabal-tests/tests/ParserTests/regressions/cc-options-with-optimization.cabal
--- a/cabal/Cabal-tests/tests/ParserTests/regressions/cc-options-with-optimization.cabal
+++ b/cabal/Cabal-tests/tests/ParserTests/regressions/cc-options-with-optimization.cabal
@@ -6,7 +6,7 @@
 name:          cxx-options-with-optimization
 synopsis:      test a build check
 version:       1
-         
+
 library
     build-depends: base >= 4.9 && <4.10
     cc-options: -O2
diff --git a/cabal/Cabal-tests/tests/ParserTests/regressions/cxx-options-with-optimization.cabal b/cabal/Cabal-tests/tests/ParserTests/regressions/cxx-options-with-optimization.cabal
--- a/cabal/Cabal-tests/tests/ParserTests/regressions/cxx-options-with-optimization.cabal
+++ b/cabal/Cabal-tests/tests/ParserTests/regressions/cxx-options-with-optimization.cabal
@@ -6,7 +6,7 @@
 name:          cxx-options-with-optimization
 synopsis:      test a build check
 version:       1
-         
+
 library
     build-depends: base >= 4.9 && <4.10
     cxx-options: -O2
diff --git a/cabal/Cabal-tests/tests/ParserTests/regressions/hasktorch.cabal b/cabal/Cabal-tests/tests/ParserTests/regressions/hasktorch.cabal
--- a/cabal/Cabal-tests/tests/ParserTests/regressions/hasktorch.cabal
+++ b/cabal/Cabal-tests/tests/ParserTests/regressions/hasktorch.cabal
@@ -216,7 +216,7 @@
         hasktorch-indef-signed -any
     mixins: hasktorch-indef-signed (Torch.Indef.Storage as Torch.Indef.Long.Storage, Torch.Indef.Storage.Copy as Torch.Indef.Long.Storage.Copy, Torch.Indef.Static.Tensor as Torch.Indef.Long.Tensor, Torch.Indef.Static.Tensor.Copy as Torch.Indef.Long.Tensor.Copy, Torch.Indef.Static.Tensor.Index as Torch.Indef.Long.Tensor.Index, Torch.Indef.Static.Tensor.Masked as Torch.Indef.Long.Tensor.Masked, Torch.Indef.Static.Tensor.Math as Torch.Indef.Long.Tensor.Math, Torch.Indef.Static.Tensor.Math.Compare as Torch.Indef.Long.Tensor.Math.Compare, Torch.Indef.Static.Tensor.Math.CompareT as Torch.Indef.Long.Tensor.Math.CompareT, Torch.Indef.Static.Tensor.Math.Pairwise as Torch.Indef.Long.Tensor.Math.Pairwise, Torch.Indef.Static.Tensor.Math.Pointwise as Torch.Indef.Long.Tensor.Math.Pointwise, Torch.Indef.Static.Tensor.Math.Reduce as Torch.Indef.Long.Tensor.Math.Reduce, Torch.Indef.Static.Tensor.Math.Scan as Torch.Indef.Long.Tensor.Math.Scan, Torch.Indef.Static.Tensor.Mode as Torch.Indef.Long.Tensor.Mode, Torch.Indef.Static.Tensor.ScatterGather as Torch.Indef.Long.Tensor.ScatterGather, Torch.Indef.Static.Tensor.Sort as Torch.Indef.Long.Tensor.Sort, Torch.Indef.Static.Tensor.TopK as Torch.Indef.Long.Tensor.TopK, Torch.Indef.Dynamic.Tensor as Torch.Indef.Long.Dynamic.Tensor, Torch.Indef.Dynamic.Tensor.Copy as Torch.Indef.Long.Dynamic.Tensor.Copy, Torch.Indef.Dynamic.Tensor.Index as Torch.Indef.Long.Dynamic.Tensor.Index, Torch.Indef.Dynamic.Tensor.Masked as Torch.Indef.Long.Dynamic.Tensor.Masked, Torch.Indef.Dynamic.Tensor.Math as Torch.Indef.Long.Dynamic.Tensor.Math, Torch.Indef.Dynamic.Tensor.Math.Compare as Torch.Indef.Long.Dynamic.Tensor.Math.Compare, Torch.Indef.Dynamic.Tensor.Math.CompareT as Torch.Indef.Long.Dynamic.Tensor.Math.CompareT, Torch.Indef.Dynamic.Tensor.Math.Pairwise as Torch.Indef.Long.Dynamic.Tensor.Math.Pairwise, Torch.Indef.Dynamic.Tensor.Math.Pointwise as Torch.Indef.Long.Dynamic.Tensor.Math.Pointwise, Torch.Indef.Dynamic.Tensor.Math.Reduce as Torch.Indef.Long.Dynamic.Tensor.Math.Reduce, Torch.Indef.Dynamic.Tensor.Math.Scan as Torch.Indef.Long.Dynamic.Tensor.Math.Scan, Torch.Indef.Dynamic.Tensor.Mode as Torch.Indef.Long.Dynamic.Tensor.Mode, Torch.Indef.Dynamic.Tensor.ScatterGather as Torch.Indef.Long.Dynamic.Tensor.ScatterGather, Torch.Indef.Dynamic.Tensor.Sort as Torch.Indef.Long.Dynamic.Tensor.Sort, Torch.Indef.Dynamic.Tensor.TopK as Torch.Indef.Long.Dynamic.Tensor.TopK, Torch.Indef.Types as Torch.Long.Types, Torch.Indef.Index as Torch.Long.Index, Torch.Indef.Mask as Torch.Long.Mask, Torch.Indef.Static.Tensor.Math.Pointwise.Signed as Torch.Indef.Long.Tensor.Math.Pointwise.Signed, Torch.Indef.Dynamic.Tensor.Math.Pointwise.Signed as Torch.Indef.Long.Dynamic.Tensor.Math.Pointwise.Signed) requires (Torch.Sig.Index.Tensor as Torch.FFI.TH.Long.Tensor, Torch.Sig.Index.TensorFree as Torch.FFI.TH.Long.FreeTensor, Torch.Sig.Mask.Tensor as Torch.FFI.TH.Byte.Tensor, Torch.Sig.Mask.TensorFree as Torch.FFI.TH.Byte.FreeTensor, Torch.Sig.Mask.MathReduce as Torch.FFI.TH.Byte.TensorMath, Torch.Sig.State as Torch.Types.TH, Torch.Sig.Types.Global as Torch.Types.TH, Torch.Sig.Types as Torch.Types.TH.Long, Torch.Sig.Storage as Torch.FFI.TH.Long.Storage, Torch.Sig.Storage.Copy as Torch.FFI.TH.Long.StorageCopy, Torch.Sig.Storage.Memory as Torch.FFI.TH.Long.FreeStorage, Torch.Sig.Tensor as Torch.FFI.TH.Long.Tensor, Torch.Sig.Tensor.Copy as Torch.FFI.TH.Long.TensorCopy, Torch.Sig.Tensor.Memory as Torch.FFI.TH.Long.FreeTensor, Torch.Sig.Tensor.Index as Torch.FFI.TH.Long.TensorMath, Torch.Sig.Tensor.Masked as Torch.FFI.TH.Long.TensorMath, Torch.Sig.Tensor.Math as Torch.FFI.TH.Long.TensorMath, Torch.Sig.Tensor.Math.Compare as Torch.FFI.TH.Long.TensorMath, Torch.Sig.Tensor.Math.CompareT as Torch.FFI.TH.Long.TensorMath, Torch.Sig.Tensor.Math.Pairwise as Torch.FFI.TH.Long.TensorMath, Torch.Sig.Tensor.Math.Pointwise as Torch.FFI.TH.Long.TensorMath, Torch.Sig.Tensor.Math.Reduce as Torch.FFI.TH.Long.TensorMath, Torch.Sig.Tensor.Math.Scan as Torch.FFI.TH.Long.TensorMath, Torch.Sig.Tensor.Mode as Torch.FFI.TH.Long.TensorMath, Torch.Sig.Tensor.ScatterGather as Torch.FFI.TH.Long.TensorMath, Torch.Sig.Tensor.Sort as Torch.FFI.TH.Long.TensorMath, Torch.Sig.Tensor.TopK as Torch.FFI.TH.Long.TensorMath, Torch.Sig.Tensor.Math.Pointwise.Signed as Torch.FFI.TH.Long.TensorMath),
             hasktorch-indef-floating (Torch.Indef.Storage as Torch.Indef.Double.Storage, Torch.Indef.Storage.Copy as Torch.Indef.Double.Storage.Copy, Torch.Indef.Static.Tensor as Torch.Indef.Double.Tensor, Torch.Indef.Static.Tensor.Copy as Torch.Indef.Double.Tensor.Copy, Torch.Indef.Static.Tensor.Index as Torch.Indef.Double.Tensor.Index, Torch.Indef.Static.Tensor.Masked as Torch.Indef.Double.Tensor.Masked, Torch.Indef.Static.Tensor.Math as Torch.Indef.Double.Tensor.Math, Torch.Indef.Static.Tensor.Math.Compare as Torch.Indef.Double.Tensor.Math.Compare, Torch.Indef.Static.Tensor.Math.CompareT as Torch.Indef.Double.Tensor.Math.CompareT, Torch.Indef.Static.Tensor.Math.Pairwise as Torch.Indef.Double.Tensor.Math.Pairwise, Torch.Indef.Static.Tensor.Math.Pointwise as Torch.Indef.Double.Tensor.Math.Pointwise, Torch.Indef.Static.Tensor.Math.Reduce as Torch.Indef.Double.Tensor.Math.Reduce, Torch.Indef.Static.Tensor.Math.Scan as Torch.Indef.Double.Tensor.Math.Scan, Torch.Indef.Static.Tensor.Mode as Torch.Indef.Double.Tensor.Mode, Torch.Indef.Static.Tensor.ScatterGather as Torch.Indef.Double.Tensor.ScatterGather, Torch.Indef.Static.Tensor.Sort as Torch.Indef.Double.Tensor.Sort, Torch.Indef.Static.Tensor.TopK as Torch.Indef.Double.Tensor.TopK, Torch.Indef.Dynamic.Tensor as Torch.Indef.Double.Dynamic.Tensor, Torch.Indef.Dynamic.Tensor.Copy as Torch.Indef.Double.Dynamic.Tensor.Copy, Torch.Indef.Dynamic.Tensor.Index as Torch.Indef.Double.Dynamic.Tensor.Index, Torch.Indef.Dynamic.Tensor.Masked as Torch.Indef.Double.Dynamic.Tensor.Masked, Torch.Indef.Dynamic.Tensor.Math as Torch.Indef.Double.Dynamic.Tensor.Math, Torch.Indef.Dynamic.Tensor.Math.Compare as Torch.Indef.Double.Dynamic.Tensor.Math.Compare, Torch.Indef.Dynamic.Tensor.Math.CompareT as Torch.Indef.Double.Dynamic.Tensor.Math.CompareT, Torch.Indef.Dynamic.Tensor.Math.Pairwise as Torch.Indef.Double.Dynamic.Tensor.Math.Pairwise, Torch.Indef.Dynamic.Tensor.Math.Pointwise as Torch.Indef.Double.Dynamic.Tensor.Math.Pointwise, Torch.Indef.Dynamic.Tensor.Math.Reduce as Torch.Indef.Double.Dynamic.Tensor.Math.Reduce, Torch.Indef.Dynamic.Tensor.Math.Scan as Torch.Indef.Double.Dynamic.Tensor.Math.Scan, Torch.Indef.Dynamic.Tensor.Mode as Torch.Indef.Double.Dynamic.Tensor.Mode, Torch.Indef.Dynamic.Tensor.ScatterGather as Torch.Indef.Double.Dynamic.Tensor.ScatterGather, Torch.Indef.Dynamic.Tensor.Sort as Torch.Indef.Double.Dynamic.Tensor.Sort, Torch.Indef.Dynamic.Tensor.TopK as Torch.Indef.Double.Dynamic.Tensor.TopK, Torch.Indef.Types as Torch.Double.Types, Torch.Indef.Index as Torch.Double.Index, Torch.Indef.Mask as Torch.Double.Mask, Torch.Indef.Static.Tensor.Math.Pointwise.Signed as Torch.Indef.Double.Tensor.Math.Pointwise.Signed, Torch.Indef.Dynamic.Tensor.Math.Pointwise.Signed as Torch.Indef.Double.Dynamic.Tensor.Math.Pointwise.Signed, Torch.Indef.Dynamic.Tensor.Math.Blas as Torch.Indef.Double.Dynamic.Tensor.Math.Blas, Torch.Indef.Dynamic.Tensor.Math.Lapack as Torch.Indef.Double.Dynamic.Tensor.Math.Lapack, Torch.Indef.Dynamic.Tensor.Math.Pointwise.Floating as Torch.Indef.Double.Dynamic.Tensor.Math.Pointwise.Floating, Torch.Indef.Dynamic.Tensor.Math.Reduce.Floating as Torch.Indef.Double.Dynamic.Tensor.Math.Reduce.Floating, Torch.Indef.Dynamic.Tensor.Math.Floating as Torch.Indef.Double.Dynamic.Tensor.Math.Floating, Torch.Indef.Static.Tensor.Math.Blas as Torch.Indef.Double.Tensor.Math.Blas, Torch.Indef.Static.Tensor.Math.Lapack as Torch.Indef.Double.Tensor.Math.Lapack, Torch.Indef.Static.Tensor.Math.Pointwise.Floating as Torch.Indef.Double.Tensor.Math.Pointwise.Floating, Torch.Indef.Static.Tensor.Math.Reduce.Floating as Torch.Indef.Double.Tensor.Math.Reduce.Floating, Torch.Indef.Static.Tensor.Math.Floating as Torch.Indef.Double.Tensor.Math.Floating, Torch.Indef.Static.Tensor.Random.TH as Torch.Indef.Double.Tensor.Random.TH, Torch.Indef.Static.Tensor.Math.Random.TH as Torch.Indef.Double.Tensor.Math.Random.TH, Torch.Indef.Dynamic.Tensor.Random.TH as Torch.Indef.Double.Dynamic.Tensor.Random.TH, Torch.Indef.Dynamic.Tensor.Math.Random.TH as Torch.Indef.Double.Dynamic.Tensor.Math.Random.TH, Torch.Undefined.Tensor.Random.THC as Torch.Undefined.Double.Tensor.Random.THC, Torch.Indef.Storage as Torch.Indef.Double.Storage, Torch.Indef.Storage.Copy as Torch.Indef.Double.Storage.Copy, Torch.Indef.Static.Tensor as Torch.Indef.Double.Tensor, Torch.Indef.Static.Tensor.Copy as Torch.Indef.Double.Tensor.Copy, Torch.Indef.Static.Tensor.Index as Torch.Indef.Double.Tensor.Index, Torch.Indef.Static.Tensor.Masked as Torch.Indef.Double.Tensor.Masked, Torch.Indef.Static.Tensor.Math as Torch.Indef.Double.Tensor.Math, Torch.Indef.Static.Tensor.Math.Compare as Torch.Indef.Double.Tensor.Math.Compare, Torch.Indef.Static.Tensor.Math.CompareT as Torch.Indef.Double.Tensor.Math.CompareT, Torch.Indef.Static.Tensor.Math.Pairwise as Torch.Indef.Double.Tensor.Math.Pairwise, Torch.Indef.Static.Tensor.Math.Pointwise as Torch.Indef.Double.Tensor.Math.Pointwise, Torch.Indef.Static.Tensor.Math.Reduce as Torch.Indef.Double.Tensor.Math.Reduce, Torch.Indef.Static.Tensor.Math.Scan as Torch.Indef.Double.Tensor.Math.Scan, Torch.Indef.Static.Tensor.Mode as Torch.Indef.Double.Tensor.Mode, Torch.Indef.Static.Tensor.ScatterGather as Torch.Indef.Double.Tensor.ScatterGather, Torch.Indef.Static.Tensor.Sort as Torch.Indef.Double.Tensor.Sort, Torch.Indef.Static.Tensor.TopK as Torch.Indef.Double.Tensor.TopK, Torch.Indef.Dynamic.Tensor as Torch.Indef.Double.Dynamic.Tensor, Torch.Indef.Dynamic.Tensor.Copy as Torch.Indef.Double.Dynamic.Tensor.Copy, Torch.Indef.Dynamic.Tensor.Index as Torch.Indef.Double.Dynamic.Tensor.Index, Torch.Indef.Dynamic.Tensor.Masked as Torch.Indef.Double.Dynamic.Tensor.Masked, Torch.Indef.Dynamic.Tensor.Math as Torch.Indef.Double.Dynamic.Tensor.Math, Torch.Indef.Dynamic.Tensor.Math.Compare as Torch.Indef.Double.Dynamic.Tensor.Math.Compare, Torch.Indef.Dynamic.Tensor.Math.CompareT as Torch.Indef.Double.Dynamic.Tensor.Math.CompareT, Torch.Indef.Dynamic.Tensor.Math.Pairwise as Torch.Indef.Double.Dynamic.Tensor.Math.Pairwise, Torch.Indef.Dynamic.Tensor.Math.Pointwise as Torch.Indef.Double.Dynamic.Tensor.Math.Pointwise, Torch.Indef.Dynamic.Tensor.Math.Reduce as Torch.Indef.Double.Dynamic.Tensor.Math.Reduce, Torch.Indef.Dynamic.Tensor.Math.Scan as Torch.Indef.Double.Dynamic.Tensor.Math.Scan, Torch.Indef.Dynamic.Tensor.Mode as Torch.Indef.Double.Dynamic.Tensor.Mode, Torch.Indef.Dynamic.Tensor.ScatterGather as Torch.Indef.Double.Dynamic.Tensor.ScatterGather, Torch.Indef.Dynamic.Tensor.Sort as Torch.Indef.Double.Dynamic.Tensor.Sort, Torch.Indef.Dynamic.Tensor.TopK as Torch.Indef.Double.Dynamic.Tensor.TopK, Torch.Indef.Types as Torch.Double.Types, Torch.Indef.Index as Torch.Double.Index, Torch.Indef.Mask as Torch.Double.Mask, Torch.Indef.Static.Tensor.Math.Pointwise.Signed as Torch.Indef.Double.Tensor.Math.Pointwise.Signed, Torch.Indef.Dynamic.Tensor.Math.Pointwise.Signed as Torch.Indef.Double.Dynamic.Tensor.Math.Pointwise.Signed, Torch.Indef.Dynamic.NN as Torch.Double.Dynamic.NN, Torch.Indef.Dynamic.NN.Activation as Torch.Double.Dynamic.NN.Activation, Torch.Indef.Dynamic.NN.Pooling as Torch.Double.Dynamic.NN.Pooling, Torch.Indef.Dynamic.NN.Criterion as Torch.Double.Dynamic.NN.Criterion, Torch.Indef.Static.NN as Torch.Double.NN, Torch.Indef.Static.NN as Torch.Double.NN, Torch.Indef.Static.NN.Activation as Torch.Double.NN.Activation, Torch.Indef.Static.NN.Backprop as Torch.Double.NN.Backprop, Torch.Indef.Static.NN.Conv1d as Torch.Double.NN.Conv1d, Torch.Indef.Static.NN.Conv2d as Torch.Double.NN.Conv2d, Torch.Indef.Static.NN.Criterion as Torch.Double.NN.Criterion, Torch.Indef.Static.NN.Layers as Torch.Double.NN.Layers, Torch.Indef.Static.NN.Linear as Torch.Double.NN.Linear, Torch.Indef.Static.NN.Math as Torch.Double.NN.Math, Torch.Indef.Static.NN.Padding as Torch.Double.NN.Padding, Torch.Indef.Static.NN.Pooling as Torch.Double.NN.Pooling, Torch.Indef.Static.NN.Sampling as Torch.Double.NN.Sampling) requires (Torch.Sig.Index.Tensor as Torch.FFI.TH.Long.Tensor, Torch.Sig.Index.TensorFree as Torch.FFI.TH.Long.FreeTensor, Torch.Sig.Mask.Tensor as Torch.FFI.TH.Byte.Tensor, Torch.Sig.Mask.TensorFree as Torch.FFI.TH.Byte.FreeTensor, Torch.Sig.Mask.MathReduce as Torch.FFI.TH.Byte.TensorMath, Torch.Sig.State as Torch.Types.TH, Torch.Sig.Types.Global as Torch.Types.TH, Torch.Sig.Types as Torch.Types.TH.Double, Torch.Sig.Storage as Torch.FFI.TH.Double.Storage, Torch.Sig.Storage.Copy as Torch.FFI.TH.Double.StorageCopy, Torch.Sig.Storage.Memory as Torch.FFI.TH.Double.FreeStorage, Torch.Sig.Tensor as Torch.FFI.TH.Double.Tensor, Torch.Sig.Tensor.Copy as Torch.FFI.TH.Double.TensorCopy, Torch.Sig.Tensor.Memory as Torch.FFI.TH.Double.FreeTensor, Torch.Sig.Tensor.Index as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Masked as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Math as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Math.Compare as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Math.CompareT as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Math.Pairwise as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Math.Pointwise as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Math.Reduce as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Math.Scan as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Mode as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.ScatterGather as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Sort as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.TopK as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Math.Pointwise.Signed as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Math.Pointwise.Floating as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Math.Reduce.Floating as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Math.Floating as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Math.Blas as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Math.Lapack as Torch.FFI.TH.Double.TensorLapack, Torch.Sig.NN as Torch.FFI.TH.NN.Double, Torch.Sig.Types.NN as Torch.Types.TH, Torch.Sig.Tensor.Math.Random.TH as Torch.FFI.TH.Double.TensorMath, Torch.Sig.Tensor.Random.TH as Torch.FFI.TH.Double.TensorRandom, Torch.Sig.Tensor.Random.THC as Torch.Undefined.Double.Tensor.Random.THC)
-    
+
     if flag(lite)
     else
         exposed-modules:
@@ -297,7 +297,7 @@
         hasktorch-types-thc (==0.0.1 || >0.0.1) && <0.0.2
     mixins: hasktorch-indef-signed (Torch.Indef.Storage as Torch.Indef.Cuda.Long.Storage, Torch.Indef.Storage.Copy as Torch.Indef.Cuda.Long.Storage.Copy, Torch.Indef.Static.Tensor as Torch.Indef.Cuda.Long.Tensor, Torch.Indef.Static.Tensor.Copy as Torch.Indef.Cuda.Long.Tensor.Copy, Torch.Indef.Static.Tensor.Index as Torch.Indef.Cuda.Long.Tensor.Index, Torch.Indef.Static.Tensor.Masked as Torch.Indef.Cuda.Long.Tensor.Masked, Torch.Indef.Static.Tensor.Math as Torch.Indef.Cuda.Long.Tensor.Math, Torch.Indef.Static.Tensor.Math.Compare as Torch.Indef.Cuda.Long.Tensor.Math.Compare, Torch.Indef.Static.Tensor.Math.CompareT as Torch.Indef.Cuda.Long.Tensor.Math.CompareT, Torch.Indef.Static.Tensor.Math.Pairwise as Torch.Indef.Cuda.Long.Tensor.Math.Pairwise, Torch.Indef.Static.Tensor.Math.Pointwise as Torch.Indef.Cuda.Long.Tensor.Math.Pointwise, Torch.Indef.Static.Tensor.Math.Reduce as Torch.Indef.Cuda.Long.Tensor.Math.Reduce, Torch.Indef.Static.Tensor.Math.Scan as Torch.Indef.Cuda.Long.Tensor.Math.Scan, Torch.Indef.Static.Tensor.Mode as Torch.Indef.Cuda.Long.Tensor.Mode, Torch.Indef.Static.Tensor.ScatterGather as Torch.Indef.Cuda.Long.Tensor.ScatterGather, Torch.Indef.Static.Tensor.Sort as Torch.Indef.Cuda.Long.Tensor.Sort, Torch.Indef.Static.Tensor.TopK as Torch.Indef.Cuda.Long.Tensor.TopK, Torch.Indef.Dynamic.Tensor as Torch.Indef.Cuda.Long.Dynamic.Tensor, Torch.Indef.Dynamic.Tensor.Copy as Torch.Indef.Cuda.Long.Dynamic.Tensor.Copy, Torch.Indef.Dynamic.Tensor.Index as Torch.Indef.Cuda.Long.Dynamic.Tensor.Index, Torch.Indef.Dynamic.Tensor.Masked as Torch.Indef.Cuda.Long.Dynamic.Tensor.Masked, Torch.Indef.Dynamic.Tensor.Math as Torch.Indef.Cuda.Long.Dynamic.Tensor.Math, Torch.Indef.Dynamic.Tensor.Math.Compare as Torch.Indef.Cuda.Long.Dynamic.Tensor.Math.Compare, Torch.Indef.Dynamic.Tensor.Math.CompareT as Torch.Indef.Cuda.Long.Dynamic.Tensor.Math.CompareT, Torch.Indef.Dynamic.Tensor.Math.Pairwise as Torch.Indef.Cuda.Long.Dynamic.Tensor.Math.Pairwise, Torch.Indef.Dynamic.Tensor.Math.Pointwise as Torch.Indef.Cuda.Long.Dynamic.Tensor.Math.Pointwise, Torch.Indef.Dynamic.Tensor.Math.Reduce as Torch.Indef.Cuda.Long.Dynamic.Tensor.Math.Reduce, Torch.Indef.Dynamic.Tensor.Math.Scan as Torch.Indef.Cuda.Long.Dynamic.Tensor.Math.Scan, Torch.Indef.Dynamic.Tensor.Mode as Torch.Indef.Cuda.Long.Dynamic.Tensor.Mode, Torch.Indef.Dynamic.Tensor.ScatterGather as Torch.Indef.Cuda.Long.Dynamic.Tensor.ScatterGather, Torch.Indef.Dynamic.Tensor.Sort as Torch.Indef.Cuda.Long.Dynamic.Tensor.Sort, Torch.Indef.Dynamic.Tensor.TopK as Torch.Indef.Cuda.Long.Dynamic.Tensor.TopK, Torch.Indef.Types as Torch.Cuda.Long.Types, Torch.Indef.Index as Torch.Cuda.Long.Index, Torch.Indef.Mask as Torch.Cuda.Long.Mask, Torch.Indef.Static.Tensor.Math.Pointwise.Signed as Torch.Indef.Cuda.Long.Tensor.Math.Pointwise.Signed, Torch.Indef.Dynamic.Tensor.Math.Pointwise.Signed as Torch.Indef.Cuda.Long.Dynamic.Tensor.Math.Pointwise.Signed) requires (Torch.Sig.Index.Tensor as Torch.FFI.THC.Long.Tensor, Torch.Sig.Index.TensorFree as Torch.FFI.THC.Long.Tensor, Torch.Sig.Mask.Tensor as Torch.FFI.THC.Byte.Tensor, Torch.Sig.Mask.TensorFree as Torch.FFI.THC.Byte.Tensor, Torch.Sig.Mask.MathReduce as Torch.FFI.THC.Byte.TensorMathReduce, Torch.Sig.State as Torch.FFI.THC.State, Torch.Sig.Types.Global as Torch.Types.THC, Torch.Sig.Types as Torch.Types.THC.Long, Torch.Sig.Storage as Torch.FFI.THC.Long.Storage, Torch.Sig.Storage.Copy as Torch.FFI.THC.Long.StorageCopy, Torch.Sig.Storage.Memory as Torch.FFI.THC.Long.Storage, Torch.Sig.Tensor as Torch.FFI.THC.Long.Tensor, Torch.Sig.Tensor.Copy as Torch.FFI.THC.Long.TensorCopy, Torch.Sig.Tensor.Memory as Torch.FFI.THC.Long.Tensor, Torch.Sig.Tensor.Index as Torch.FFI.THC.Long.TensorIndex, Torch.Sig.Tensor.Masked as Torch.FFI.THC.Long.TensorMasked, Torch.Sig.Tensor.Math as Torch.FFI.THC.Long.TensorMath, Torch.Sig.Tensor.Math.Compare as Torch.FFI.THC.Long.TensorMathCompare, Torch.Sig.Tensor.Math.CompareT as Torch.FFI.THC.Long.TensorMathCompareT, Torch.Sig.Tensor.Math.Pairwise as Torch.FFI.THC.Long.TensorMathPairwise, Torch.Sig.Tensor.Math.Pointwise as Torch.FFI.THC.Long.TensorMathPointwise, Torch.Sig.Tensor.Math.Reduce as Torch.FFI.THC.Long.TensorMathReduce, Torch.Sig.Tensor.Math.Scan as Torch.FFI.THC.Long.TensorMathScan, Torch.Sig.Tensor.Mode as Torch.FFI.THC.Long.TensorMode, Torch.Sig.Tensor.ScatterGather as Torch.FFI.THC.Long.TensorScatterGather, Torch.Sig.Tensor.Sort as Torch.FFI.THC.Long.TensorSort, Torch.Sig.Tensor.TopK as Torch.FFI.THC.Long.TensorTopK, Torch.Sig.Tensor.Math.Pointwise.Signed as Torch.FFI.THC.Long.TensorMathPointwise),
             hasktorch-indef-floating (Torch.Indef.Storage as Torch.Indef.Cuda.Double.Storage, Torch.Indef.Storage.Copy as Torch.Indef.Cuda.Double.Storage.Copy, Torch.Indef.Static.Tensor as Torch.Indef.Cuda.Double.Tensor, Torch.Indef.Static.Tensor.Copy as Torch.Indef.Cuda.Double.Tensor.Copy, Torch.Indef.Static.Tensor.Index as Torch.Indef.Cuda.Double.Tensor.Index, Torch.Indef.Static.Tensor.Masked as Torch.Indef.Cuda.Double.Tensor.Masked, Torch.Indef.Static.Tensor.Math as Torch.Indef.Cuda.Double.Tensor.Math, Torch.Indef.Static.Tensor.Math.Compare as Torch.Indef.Cuda.Double.Tensor.Math.Compare, Torch.Indef.Static.Tensor.Math.CompareT as Torch.Indef.Cuda.Double.Tensor.Math.CompareT, Torch.Indef.Static.Tensor.Math.Pairwise as Torch.Indef.Cuda.Double.Tensor.Math.Pairwise, Torch.Indef.Static.Tensor.Math.Pointwise as Torch.Indef.Cuda.Double.Tensor.Math.Pointwise, Torch.Indef.Static.Tensor.Math.Reduce as Torch.Indef.Cuda.Double.Tensor.Math.Reduce, Torch.Indef.Static.Tensor.Math.Scan as Torch.Indef.Cuda.Double.Tensor.Math.Scan, Torch.Indef.Static.Tensor.Mode as Torch.Indef.Cuda.Double.Tensor.Mode, Torch.Indef.Static.Tensor.ScatterGather as Torch.Indef.Cuda.Double.Tensor.ScatterGather, Torch.Indef.Static.Tensor.Sort as Torch.Indef.Cuda.Double.Tensor.Sort, Torch.Indef.Static.Tensor.TopK as Torch.Indef.Cuda.Double.Tensor.TopK, Torch.Indef.Dynamic.Tensor as Torch.Indef.Cuda.Double.Dynamic.Tensor, Torch.Indef.Dynamic.Tensor.Copy as Torch.Indef.Cuda.Double.Dynamic.Tensor.Copy, Torch.Indef.Dynamic.Tensor.Index as Torch.Indef.Cuda.Double.Dynamic.Tensor.Index, Torch.Indef.Dynamic.Tensor.Masked as Torch.Indef.Cuda.Double.Dynamic.Tensor.Masked, Torch.Indef.Dynamic.Tensor.Math as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math, Torch.Indef.Dynamic.Tensor.Math.Compare as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Compare, Torch.Indef.Dynamic.Tensor.Math.CompareT as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.CompareT, Torch.Indef.Dynamic.Tensor.Math.Pairwise as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Pairwise, Torch.Indef.Dynamic.Tensor.Math.Pointwise as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Pointwise, Torch.Indef.Dynamic.Tensor.Math.Reduce as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Reduce, Torch.Indef.Dynamic.Tensor.Math.Scan as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Scan, Torch.Indef.Dynamic.Tensor.Mode as Torch.Indef.Cuda.Double.Dynamic.Tensor.Mode, Torch.Indef.Dynamic.Tensor.ScatterGather as Torch.Indef.Cuda.Double.Dynamic.Tensor.ScatterGather, Torch.Indef.Dynamic.Tensor.Sort as Torch.Indef.Cuda.Double.Dynamic.Tensor.Sort, Torch.Indef.Dynamic.Tensor.TopK as Torch.Indef.Cuda.Double.Dynamic.Tensor.TopK, Torch.Indef.Types as Torch.Cuda.Double.Types, Torch.Indef.Index as Torch.Cuda.Double.Index, Torch.Indef.Mask as Torch.Cuda.Double.Mask, Torch.Indef.Static.Tensor.Math.Pointwise.Signed as Torch.Indef.Cuda.Double.Tensor.Math.Pointwise.Signed, Torch.Indef.Dynamic.Tensor.Math.Pointwise.Signed as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Pointwise.Signed, Torch.Indef.Dynamic.Tensor.Math.Blas as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Blas, Torch.Indef.Dynamic.Tensor.Math.Lapack as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Lapack, Torch.Indef.Dynamic.Tensor.Math.Pointwise.Floating as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Pointwise.Floating, Torch.Indef.Dynamic.Tensor.Math.Reduce.Floating as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Reduce.Floating, Torch.Indef.Dynamic.Tensor.Math.Floating as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Floating, Torch.Indef.Static.Tensor.Math.Blas as Torch.Indef.Cuda.Double.Tensor.Math.Blas, Torch.Indef.Static.Tensor.Math.Lapack as Torch.Indef.Cuda.Double.Tensor.Math.Lapack, Torch.Indef.Static.Tensor.Math.Pointwise.Floating as Torch.Indef.Cuda.Double.Tensor.Math.Pointwise.Floating, Torch.Indef.Static.Tensor.Math.Reduce.Floating as Torch.Indef.Cuda.Double.Tensor.Math.Reduce.Floating, Torch.Indef.Static.Tensor.Math.Floating as Torch.Indef.Cuda.Double.Tensor.Math.Floating, Torch.Undefined.Tensor.Random.TH as Torch.Undefined.Cuda.Double.Tensor.Random.TH, Torch.Undefined.Tensor.Math.Random.TH as Torch.Undefined.Cuda.Double.Tensor.Math.Random.TH, Torch.Indef.Static.Tensor.Random.THC as Torch.Indef.Cuda.Double.Tensor.Random.THC, Torch.Indef.Dynamic.Tensor.Random.THC as Torch.Indef.Cuda.Double.Dynamic.Tensor.Random.THC, Torch.Indef.Storage as Torch.Indef.Cuda.Double.Storage, Torch.Indef.Storage.Copy as Torch.Indef.Cuda.Double.Storage.Copy, Torch.Indef.Static.Tensor as Torch.Indef.Cuda.Double.Tensor, Torch.Indef.Static.Tensor.Copy as Torch.Indef.Cuda.Double.Tensor.Copy, Torch.Indef.Static.Tensor.Index as Torch.Indef.Cuda.Double.Tensor.Index, Torch.Indef.Static.Tensor.Masked as Torch.Indef.Cuda.Double.Tensor.Masked, Torch.Indef.Static.Tensor.Math as Torch.Indef.Cuda.Double.Tensor.Math, Torch.Indef.Static.Tensor.Math.Compare as Torch.Indef.Cuda.Double.Tensor.Math.Compare, Torch.Indef.Static.Tensor.Math.CompareT as Torch.Indef.Cuda.Double.Tensor.Math.CompareT, Torch.Indef.Static.Tensor.Math.Pairwise as Torch.Indef.Cuda.Double.Tensor.Math.Pairwise, Torch.Indef.Static.Tensor.Math.Pointwise as Torch.Indef.Cuda.Double.Tensor.Math.Pointwise, Torch.Indef.Static.Tensor.Math.Reduce as Torch.Indef.Cuda.Double.Tensor.Math.Reduce, Torch.Indef.Static.Tensor.Math.Scan as Torch.Indef.Cuda.Double.Tensor.Math.Scan, Torch.Indef.Static.Tensor.Mode as Torch.Indef.Cuda.Double.Tensor.Mode, Torch.Indef.Static.Tensor.ScatterGather as Torch.Indef.Cuda.Double.Tensor.ScatterGather, Torch.Indef.Static.Tensor.Sort as Torch.Indef.Cuda.Double.Tensor.Sort, Torch.Indef.Static.Tensor.TopK as Torch.Indef.Cuda.Double.Tensor.TopK, Torch.Indef.Dynamic.Tensor as Torch.Indef.Cuda.Double.Dynamic.Tensor, Torch.Indef.Dynamic.Tensor.Copy as Torch.Indef.Cuda.Double.Dynamic.Tensor.Copy, Torch.Indef.Dynamic.Tensor.Index as Torch.Indef.Cuda.Double.Dynamic.Tensor.Index, Torch.Indef.Dynamic.Tensor.Masked as Torch.Indef.Cuda.Double.Dynamic.Tensor.Masked, Torch.Indef.Dynamic.Tensor.Math as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math, Torch.Indef.Dynamic.Tensor.Math.Compare as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Compare, Torch.Indef.Dynamic.Tensor.Math.CompareT as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.CompareT, Torch.Indef.Dynamic.Tensor.Math.Pairwise as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Pairwise, Torch.Indef.Dynamic.Tensor.Math.Pointwise as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Pointwise, Torch.Indef.Dynamic.Tensor.Math.Reduce as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Reduce, Torch.Indef.Dynamic.Tensor.Math.Scan as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Scan, Torch.Indef.Dynamic.Tensor.Mode as Torch.Indef.Cuda.Double.Dynamic.Tensor.Mode, Torch.Indef.Dynamic.Tensor.ScatterGather as Torch.Indef.Cuda.Double.Dynamic.Tensor.ScatterGather, Torch.Indef.Dynamic.Tensor.Sort as Torch.Indef.Cuda.Double.Dynamic.Tensor.Sort, Torch.Indef.Dynamic.Tensor.TopK as Torch.Indef.Cuda.Double.Dynamic.Tensor.TopK, Torch.Indef.Types as Torch.Cuda.Double.Types, Torch.Indef.Index as Torch.Cuda.Double.Index, Torch.Indef.Mask as Torch.Cuda.Double.Mask, Torch.Indef.Static.Tensor.Math.Pointwise.Signed as Torch.Indef.Cuda.Double.Tensor.Math.Pointwise.Signed, Torch.Indef.Dynamic.Tensor.Math.Pointwise.Signed as Torch.Indef.Cuda.Double.Dynamic.Tensor.Math.Pointwise.Signed, Torch.Indef.Dynamic.NN as Torch.Cuda.Double.Dynamic.NN, Torch.Indef.Dynamic.NN.Activation as Torch.Cuda.Double.Dynamic.NN.Activation, Torch.Indef.Dynamic.NN.Pooling as Torch.Cuda.Double.Dynamic.NN.Pooling, Torch.Indef.Dynamic.NN.Criterion as Torch.Cuda.Double.Dynamic.NN.Criterion, Torch.Indef.Static.NN as Torch.Cuda.Double.NN, Torch.Indef.Static.NN as Torch.Cuda.Double.NN, Torch.Indef.Static.NN.Activation as Torch.Cuda.Double.NN.Activation, Torch.Indef.Static.NN.Backprop as Torch.Cuda.Double.NN.Backprop, Torch.Indef.Static.NN.Conv1d as Torch.Cuda.Double.NN.Conv1d, Torch.Indef.Static.NN.Conv2d as Torch.Cuda.Double.NN.Conv2d, Torch.Indef.Static.NN.Criterion as Torch.Cuda.Double.NN.Criterion, Torch.Indef.Static.NN.Layers as Torch.Cuda.Double.NN.Layers, Torch.Indef.Static.NN.Linear as Torch.Cuda.Double.NN.Linear, Torch.Indef.Static.NN.Math as Torch.Cuda.Double.NN.Math, Torch.Indef.Static.NN.Padding as Torch.Cuda.Double.NN.Padding, Torch.Indef.Static.NN.Pooling as Torch.Cuda.Double.NN.Pooling, Torch.Indef.Static.NN.Sampling as Torch.Cuda.Double.NN.Sampling) requires (Torch.Sig.Index.Tensor as Torch.FFI.THC.Long.Tensor, Torch.Sig.Index.TensorFree as Torch.FFI.THC.Long.Tensor, Torch.Sig.Mask.Tensor as Torch.FFI.THC.Byte.Tensor, Torch.Sig.Mask.TensorFree as Torch.FFI.THC.Byte.Tensor, Torch.Sig.Mask.MathReduce as Torch.FFI.THC.Byte.TensorMathReduce, Torch.Sig.State as Torch.FFI.THC.State, Torch.Sig.Types.Global as Torch.Types.THC, Torch.Sig.Types as Torch.Types.THC.Double, Torch.Sig.Storage as Torch.FFI.THC.Double.Storage, Torch.Sig.Storage.Copy as Torch.FFI.THC.Double.StorageCopy, Torch.Sig.Storage.Memory as Torch.FFI.THC.Double.Storage, Torch.Sig.Tensor as Torch.FFI.THC.Double.Tensor, Torch.Sig.Tensor.Copy as Torch.FFI.THC.Double.TensorCopy, Torch.Sig.Tensor.Memory as Torch.FFI.THC.Double.Tensor, Torch.Sig.Tensor.Index as Torch.FFI.THC.Double.TensorIndex, Torch.Sig.Tensor.Masked as Torch.FFI.THC.Double.TensorMasked, Torch.Sig.Tensor.Math as Torch.FFI.THC.Double.TensorMath, Torch.Sig.Tensor.Math.Compare as Torch.FFI.THC.Double.TensorMathCompare, Torch.Sig.Tensor.Math.CompareT as Torch.FFI.THC.Double.TensorMathCompareT, Torch.Sig.Tensor.Math.Pairwise as Torch.FFI.THC.Double.TensorMathPairwise, Torch.Sig.Tensor.Math.Pointwise as Torch.FFI.THC.Double.TensorMathPointwise, Torch.Sig.Tensor.Math.Reduce as Torch.FFI.THC.Double.TensorMathReduce, Torch.Sig.Tensor.Math.Scan as Torch.FFI.THC.Double.TensorMathScan, Torch.Sig.Tensor.Mode as Torch.FFI.THC.Double.TensorMode, Torch.Sig.Tensor.ScatterGather as Torch.FFI.THC.Double.TensorScatterGather, Torch.Sig.Tensor.Sort as Torch.FFI.THC.Double.TensorSort, Torch.Sig.Tensor.TopK as Torch.FFI.THC.Double.TensorTopK, Torch.Sig.Tensor.Math.Pointwise.Signed as Torch.FFI.THC.Double.TensorMathPointwise, Torch.Sig.Tensor.Math.Pointwise.Floating as Torch.FFI.THC.Double.TensorMathPointwise, Torch.Sig.Tensor.Math.Reduce.Floating as Torch.FFI.THC.Double.TensorMathReduce, Torch.Sig.Tensor.Math.Floating as Torch.FFI.THC.Double.TensorMath, Torch.Sig.Tensor.Math.Blas as Torch.FFI.THC.Double.TensorMathBlas, Torch.Sig.Tensor.Math.Lapack as Torch.FFI.THC.Double.TensorMathMagma, Torch.Sig.NN as Torch.FFI.THC.NN.Double, Torch.Sig.Types.NN as Torch.Types.THC, Torch.Sig.Tensor.Math.Random.TH as Torch.Undefined.Cuda.Double.Tensor.Math.Random.TH, Torch.Sig.Tensor.Random.TH as Torch.Undefined.Cuda.Double.Tensor.Random.TH, Torch.Sig.Tensor.Random.THC as Torch.FFI.THC.Double.TensorRandom)
-    
+
     if flag(lite)
     else
         exposed-modules:
diff --git a/cabal/Cabal-tests/tests/ParserTests/regressions/issue-774.check b/cabal/Cabal-tests/tests/ParserTests/regressions/issue-774.check
--- a/cabal/Cabal-tests/tests/ParserTests/regressions/issue-774.check
+++ b/cabal/Cabal-tests/tests/ParserTests/regressions/issue-774.check
@@ -2,6 +2,5 @@
 No 'category' field.
 No 'maintainer' field.
 The 'license' field is missing or is NONE.
-'ghc-options: -threaded' has no effect for libraries. It should only be used for executables.
 'ghc-options: -rtsopts' has no effect for libraries. It should only be used for executables.
 'ghc-options: -with-rtsopts' has no effect for libraries. It should only be used for executables.
diff --git a/cabal/Cabal-tests/tests/ParserTests/regressions/issue-7776-a.cabal b/cabal/Cabal-tests/tests/ParserTests/regressions/issue-7776-a.cabal
--- a/cabal/Cabal-tests/tests/ParserTests/regressions/issue-7776-a.cabal
+++ b/cabal/Cabal-tests/tests/ParserTests/regressions/issue-7776-a.cabal
diff --git a/cabal/Cabal-tests/tests/ParserTests/regressions/issue-8646.cabal b/cabal/Cabal-tests/tests/ParserTests/regressions/issue-8646.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/Cabal-tests/tests/ParserTests/regressions/issue-8646.cabal
@@ -0,0 +1,16 @@
+cabal-version: 3.0
+
+name: issue
+version: 8646
+build-type: Simple
+category: Test
+maintainer: Joe
+synopsis: Input to 'cabal check'
+description: Input to 'cabal check'.
+license: BSD-3-Clause
+
+executable test
+  main-is: ExeMain.hs
+  build-depends: base > 4 && < 5
+  default-language: Haskell2010
+  ghc-options: -main-is ExeMain
diff --git a/cabal/Cabal-tests/tests/ParserTests/regressions/issue-8646.check b/cabal/Cabal-tests/tests/ParserTests/regressions/issue-8646.check
new file mode 100644
--- /dev/null
+++ b/cabal/Cabal-tests/tests/ParserTests/regressions/issue-8646.check
diff --git a/cabal/Cabal-tests/tests/ParserTests/regressions/monad-param.format b/cabal/Cabal-tests/tests/ParserTests/regressions/monad-param.format
--- a/cabal/Cabal-tests/tests/ParserTests/regressions/monad-param.format
+++ b/cabal/Cabal-tests/tests/ParserTests/regressions/monad-param.format
@@ -1,4 +1,4 @@
-monad-param.cabal:19:3: Tabs used as indentation at 19:3, 20:3
+monad-param.cabal:19:1: Tabs used as indentation at 19:1, 20:1
 name:         monad-param
 version:      0.0.1
 license:      BSD3
diff --git a/cabal/Cabal-tests/tests/ParserTests/regressions/public-multilib-2.cabal b/cabal/Cabal-tests/tests/ParserTests/regressions/public-multilib-2.cabal
--- a/cabal/Cabal-tests/tests/ParserTests/regressions/public-multilib-2.cabal
+++ b/cabal/Cabal-tests/tests/ParserTests/regressions/public-multilib-2.cabal
@@ -9,6 +9,6 @@
   default-language: Haskell2010
   build-depends:
     , base     ^>=4.14
-    , somelib:internal
+    , somelib:internal ^>=1.0
 
   exposed-modules:  Foo
diff --git a/cabal/Cabal-tests/tests/ParserTests/regressions/th-lift-instances.format b/cabal/Cabal-tests/tests/ParserTests/regressions/th-lift-instances.format
--- a/cabal/Cabal-tests/tests/ParserTests/regressions/th-lift-instances.format
+++ b/cabal/Cabal-tests/tests/ParserTests/regressions/th-lift-instances.format
@@ -1,4 +1,4 @@
-th-lift-instances.cabal:15:9: Tabs used as indentation at 15:9
+th-lift-instances.cabal:15:1: Tabs used as indentation at 15:1
 cabal-version:      >=1.10
 name:               th-lift-instances
 version:            0.1.4
diff --git a/cabal/Cabal-tests/tests/UnitTests/Distribution/Simple/Command.hs b/cabal/Cabal-tests/tests/UnitTests/Distribution/Simple/Command.hs
--- a/cabal/Cabal-tests/tests/UnitTests/Distribution/Simple/Command.hs
+++ b/cabal/Cabal-tests/tests/UnitTests/Distribution/Simple/Command.hs
@@ -37,7 +37,7 @@
       , commandOptions = const [ optField ]
       }
     optField = optionVerbosity id const
-        
+
 tests :: [TestTree]
 tests =
   [ testGroup "option argument tests" argumentTests
diff --git a/cabal/Cabal-tests/tests/UnitTests/Distribution/Simple/Program/GHC.hs b/cabal/Cabal-tests/tests/UnitTests/Distribution/Simple/Program/GHC.hs
--- a/cabal/Cabal-tests/tests/UnitTests/Distribution/Simple/Program/GHC.hs
+++ b/cabal/Cabal-tests/tests/UnitTests/Distribution/Simple/Program/GHC.hs
@@ -170,3 +170,34 @@
 options_9_0_affects =
     [ "-fcmm-static-pred"
     ]
+
+-------------------------------------------------------------------------------
+-- GHC-9.2
+-------------------------------------------------------------------------------
+
+options_9_2_all :: [String]
+options_9_2_all =
+    [ "-dynohi"
+    , "-ddump-c-backend"
+    , "-ddump-stg-from-core"
+    , "-ddump-stg"
+    , "-ddump-faststrings"
+    , "--run"
+    , "-ffamily-application-cache"
+    , "-fno-family-application-cache"
+    ] ++ options_9_2_affects
+
+options_9_2_affects :: [String]
+options_9_2_affects =
+    [ "-fprof-callers"
+    , "-funfolding-case-threshold"
+    , "-funfolding-case-scaling"
+    , "-fdistinct-constructor-tables"
+    , "-finfo-table-map"
+    , "-fexpose-internal-symbols"
+    , "-finline-generics"
+    , "-finline-generics-aggressively"
+    , "-fno-expose-internal-symbols"
+    , "-fno-inline-generics"
+    , "-fno-inline-generics-aggressively"
+    ]
diff --git a/cabal/Cabal-tests/tests/UnitTests/Distribution/Utils/CharSet.hs b/cabal/Cabal-tests/tests/UnitTests/Distribution/Utils/CharSet.hs
--- a/cabal/Cabal-tests/tests/UnitTests/Distribution/Utils/CharSet.hs
+++ b/cabal/Cabal-tests/tests/UnitTests/Distribution/Utils/CharSet.hs
@@ -5,8 +5,9 @@
 #endif
 module UnitTests.Distribution.Utils.CharSet where
 
+import Prelude hiding (Foldable(..))
 import Data.Char        (isAlpha, isAlphaNum)
-import Data.List        (foldl')
+import Data.Foldable    (foldl')
 import Test.Tasty       (TestTree, testGroup)
 import Test.Tasty.HUnit (testCase, (@?=))
 
diff --git a/cabal/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs b/cabal/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs
--- a/cabal/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs
+++ b/cabal/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs
@@ -27,9 +27,9 @@
     -- The difference is in encoding of newtypes
 #if MIN_VERSION_base(4,7,0)
     , testCase "GenericPackageDescription" $
-      md5Check (Proxy :: Proxy GenericPackageDescription) 0xaf3d4c667a8f019c98a45451419ad71c
+      md5Check (Proxy :: Proxy GenericPackageDescription) 0xa3e9433662ecf0c7a3c26f6d75a53ba1
     , testCase "LocalBuildInfo" $
-      md5Check (Proxy :: Proxy LocalBuildInfo) 0x6d132d3f99c869b678468256f24b6241
+      md5Check (Proxy :: Proxy LocalBuildInfo) 0x91ffcd61bbd83525e8edba877435a031
 #endif
     ]
 
diff --git a/cabal/Cabal-tests/tests/cbits/rpmvercmp.c b/cabal/Cabal-tests/tests/cbits/rpmvercmp.c
--- a/cabal/Cabal-tests/tests/cbits/rpmvercmp.c
+++ b/cabal/Cabal-tests/tests/cbits/rpmvercmp.c
@@ -21,10 +21,10 @@
 #include <stdlib.h>
 
 /* macros to help code look more like upstream */
-#define rstreq(a, b)	(strcmp(a, b) == 0)
-#define risalnum(c)	isalnum((char)(c))
-#define risdigit(c)	isdigit((char)(c))
-#define risalpha(c)	isalpha((char)(c))
+#define rstreq(a, b)    (strcmp(a, b) == 0)
+#define risalnum(c)     isalnum((char)(c))
+#define risdigit(c)     isdigit((char)(c))
+#define risalpha(c)     isalpha((char)(c))
 
 int rmpvercmp_impl(const char *a, const char *b, char *buf1, char *buf2);
 
@@ -39,7 +39,7 @@
 
     char *buf1 = malloc(strlen(a) + 1);
     char *buf2 = malloc(strlen(b) + 1);
-    
+
     if (!buf1 || !buf2) return 0; // arbitrary
 
     int r = rmpvercmp_impl(a, b, buf1, buf2);
@@ -64,71 +64,71 @@
 
     /* loop through each version segment of str1 and str2 and compare them */
     while (*one && *two) {
-	while (*one && !risalnum(*one)) one++;
-	while (*two && !risalnum(*two)) two++;
+        while (*one && !risalnum(*one)) one++;
+        while (*two && !risalnum(*two)) two++;
 
-	/* If we ran to the end of either, we are finished with the loop */
-	if (!(*one && *two)) break;
+        /* If we ran to the end of either, we are finished with the loop */
+        if (!(*one && *two)) break;
 
-	str1 = one;
-	str2 = two;
+        str1 = one;
+        str2 = two;
 
-	/* grab first completely alpha or completely numeric segment */
-	/* leave one and two pointing to the start of the alpha or numeric */
-	/* segment and walk str1 and str2 to end of segment */
-	if (risdigit(*str1)) {
-	    while (*str1 && risdigit(*str1)) str1++;
-	    while (*str2 && risdigit(*str2)) str2++;
-	    isnum = 1;
-	} else {
-	    while (*str1 && risalpha(*str1)) str1++;
-	    while (*str2 && risalpha(*str2)) str2++;
-	    isnum = 0;
-	}
+        /* grab first completely alpha or completely numeric segment */
+        /* leave one and two pointing to the start of the alpha or numeric */
+        /* segment and walk str1 and str2 to end of segment */
+        if (risdigit(*str1)) {
+            while (*str1 && risdigit(*str1)) str1++;
+            while (*str2 && risdigit(*str2)) str2++;
+            isnum = 1;
+        } else {
+            while (*str1 && risalpha(*str1)) str1++;
+            while (*str2 && risalpha(*str2)) str2++;
+            isnum = 0;
+        }
 
-	/* save character at the end of the alpha or numeric segment */
-	/* so that they can be restored after the comparison */
-	oldch1 = *str1;
-	*str1 = '\0';
-	oldch2 = *str2;
-	*str2 = '\0';
+        /* save character at the end of the alpha or numeric segment */
+        /* so that they can be restored after the comparison */
+        oldch1 = *str1;
+        *str1 = '\0';
+        oldch2 = *str2;
+        *str2 = '\0';
 
-	/* this cannot happen, as we previously tested to make sure that */
-	/* the first string has a non-null segment */
-	if (one == str1) return -1;	/* arbitrary */
+        /* this cannot happen, as we previously tested to make sure that */
+        /* the first string has a non-null segment */
+        if (one == str1) return -1;     /* arbitrary */
 
-	/* take care of the case where the two version segments are */
-	/* different types: one numeric, the other alpha (i.e. empty) */
-	/* numeric segments are always newer than alpha segments */
-	/* XXX See patch #60884 (and details) from bugzilla #50977. */
-	if (two == str2) return (isnum ? 1 : -1);
+        /* take care of the case where the two version segments are */
+        /* different types: one numeric, the other alpha (i.e. empty) */
+        /* numeric segments are always newer than alpha segments */
+        /* XXX See patch #60884 (and details) from bugzilla #50977. */
+        if (two == str2) return (isnum ? 1 : -1);
 
-	if (isnum) {
-	    /* this used to be done by converting the digit segments */
-	    /* to ints using atoi() - it's changed because long  */
-	    /* digit segments can overflow an int - this should fix that. */
+        if (isnum) {
+            /* this used to be done by converting the digit segments */
+            /* to ints using atoi() - it's changed because long  */
+            /* digit segments can overflow an int - this should fix that. */
 
-	    /* throw away any leading zeros - it's a number, right? */
-	    while (*one == '0') one++;
-	    while (*two == '0') two++;
+            /* throw away any leading zeros - it's a number, right? */
+            while (*one == '0') one++;
+            while (*two == '0') two++;
 
-	    /* whichever number has more digits wins */
-	    if (strlen(one) > strlen(two)) return 1;
-	    if (strlen(two) > strlen(one)) return -1;
-	}
+            /* whichever number has more digits wins */
+            if (strlen(one) > strlen(two)) return 1;
+            if (strlen(two) > strlen(one)) return -1;
+        }
 
-	/* strcmp will return which one is greater - even if the two */
-	/* segments are alpha or if they are numeric.  don't return  */
-	/* if they are equal because there might be more segments to */
-	/* compare */
-	rc = strcmp(one, two);
-	if (rc) return (rc < 1 ? -1 : 1);
+        /* strcmp will return which one is greater - even if the two */
+        /* segments are alpha or if they are numeric.  don't return  */
+        /* if they are equal because there might be more segments to */
+        /* compare */
+        rc = strcmp(one, two);
+        if (rc) return (rc < 1 ? -1 : 1);
 
-	/* restore character that was replaced by null above */
-	*str1 = oldch1;
-	one = str1;
-	*str2 = oldch2;
-	two = str2;
+        /* restore character that was replaced by null above */
+        *str1 = oldch1;
+        one = str1;
+        *str2 = oldch2;
+        two = str2;
     }
 
     /* this catches the case where all numeric and alpha segments have */
diff --git a/cabal/Cabal-tests/tests/hackage/check.sh b/cabal/Cabal-tests/tests/hackage/check.sh
--- a/cabal/Cabal-tests/tests/hackage/check.sh
+++ b/cabal/Cabal-tests/tests/hackage/check.sh
@@ -6,17 +6,17 @@
 for setup in archive/*/*/Setup.hs archive/*/*/Setup.lhs; do
 
   pkgname=$(basename ${setup})
-  
+
   if test $(wc -w < ${setup}) -gt 21; then
     if ghc -package Cabal-${base_version} -S ${setup} -o /dev/null 2> /dev/null; then
 
       if ghc -package Cabal-${test_version} -S ${setup} -o /dev/null 2> /dev/null; then
         echo "OK ${setup}"
       else
-        echo "FAIL ${setup} does not compile with Cabal-${test_version}"     
+        echo "FAIL ${setup} does not compile with Cabal-${test_version}"
       fi
     else
-      echo "OK ${setup} (does not compile with Cabal-${base_version})" 
+      echo "OK ${setup} (does not compile with Cabal-${base_version})"
     fi
   else
     echo "trivial ${setup}"
diff --git a/cabal/Cabal-tests/tests/hackage/download.sh b/cabal/Cabal-tests/tests/hackage/download.sh
--- a/cabal/Cabal-tests/tests/hackage/download.sh
+++ b/cabal/Cabal-tests/tests/hackage/download.sh
@@ -5,7 +5,7 @@
   wget http://hackage.haskell.org/cgi-bin/hackage-scripts/archive.tar
   mkdir -p archive
   mv archive.tar archive/
-  tar -C archive -xf archive/archive.tar    
+  tar -C archive -xf archive/archive.tar
 
 fi
 
diff --git a/cabal/Cabal-tests/tests/misc/ghc-supported-languages.hs b/cabal/Cabal-tests/tests/misc/ghc-supported-languages.hs
--- a/cabal/Cabal-tests/tests/misc/ghc-supported-languages.hs
+++ b/cabal/Cabal-tests/tests/misc/ghc-supported-languages.hs
@@ -23,7 +23,7 @@
 checkProblems implemented =
 
   let unregistered  =
-        [ ext | ext <- implemented          -- extensions that ghc knows about 
+        [ ext | ext <- implemented          -- extensions that ghc knows about
               , not (registered ext)        -- but that are not registered
               , ext `notElem` exceptions ]  -- except for the exceptions
 
@@ -31,10 +31,10 @@
 
       -- exceptions that are not implemented
       badExceptions  = exceptions \\ implemented
-      
+
       -- exceptions that are now registered
       badExceptions' = filter registered exceptions
-      
+
    in catMaybes
       [ check unregistered $ unlines
           [ "The following extensions are known to GHC but are not in the "
@@ -66,7 +66,7 @@
    registered (UnknownExtension _) = False
    registered _                    = True
 
-   check [] _ = Nothing  
+   check [] _ = Nothing
    check _  i = Just i
 
 
diff --git a/cabal/Cabal-tree-diff/Cabal-tree-diff.cabal b/cabal/Cabal-tree-diff/Cabal-tree-diff.cabal
--- a/cabal/Cabal-tree-diff/Cabal-tree-diff.cabal
+++ b/cabal/Cabal-tree-diff/Cabal-tree-diff.cabal
@@ -1,6 +1,6 @@
 cabal-version: 2.2
 name:          Cabal-tree-diff
-version:       3.8.1.0
+version:       3.10.1.0
 synopsis:      QuickCheck instances for types in Cabal
 category:      Testing
 description:   Provides tree-diff ToExpr instances for some types in Cabal
@@ -11,9 +11,9 @@
   ghc-options:      -Wall
   build-depends:
     , base
-    , Cabal-syntax  ^>=3.8.0.0
-    , Cabal         ^>=3.8.0.0
-    , tree-diff     ^>=0.1 || ^>=0.2
+    , Cabal-syntax  ^>=3.10.0.0
+    , Cabal         ^>=3.10.0.0
+    , tree-diff     ^>=0.1 || ^>=0.2 || ^>=0.3
 
   exposed-modules:  Data.TreeDiff.Instances.Cabal
   other-modules:
diff --git a/cabal/Cabal-tree-diff/src/Data/TreeDiff/Instances/Cabal.hs b/cabal/Cabal-tree-diff/src/Data/TreeDiff/Instances/Cabal.hs
--- a/cabal/Cabal-tree-diff/src/Data/TreeDiff/Instances/Cabal.hs
+++ b/cabal/Cabal-tree-diff/src/Data/TreeDiff/Instances/Cabal.hs
@@ -57,6 +57,8 @@
 
 instance ToExpr (SymbolicPath from to)
 
+instance ToExpr a => ToExpr (InstallDirs a)
+
 instance ToExpr AbiDependency
 instance ToExpr AbiHash
 instance ToExpr Arch
diff --git a/cabal/Cabal/Cabal.cabal b/cabal/Cabal/Cabal.cabal
--- a/cabal/Cabal/Cabal.cabal
+++ b/cabal/Cabal/Cabal.cabal
@@ -1,8 +1,8 @@
-cabal-version: 1.22
+cabal-version: 2.2
 name:          Cabal
-version:       3.8.1.0
-copyright:     2003-2022, Cabal Development Team (see AUTHORS file)
-license:       BSD3
+version:       3.10.3.0
+copyright:     2003-2023, Cabal Development Team (see AUTHORS file)
+license:       BSD-3-Clause
 license-file:  LICENSE
 author:        Cabal Development Team <cabal-devel@haskell.org>
 maintainer:    cabal-devel@haskell.org
@@ -21,7 +21,7 @@
 -- If we use a new Cabal feature, this needs to be changed to Custom so
 -- we can bootstrap.
 
-extra-source-files:
+extra-doc-files:
   README.md ChangeLog.md
 
 source-repository head
@@ -34,22 +34,22 @@
   hs-source-dirs: src
 
   build-depends:
-    Cabal-syntax >= 3.8    && < 3.9,
+    Cabal-syntax ^>= 3.10,
     array      >= 0.4.0.1  && < 0.6,
-    base       >= 4.6      && < 5,
-    bytestring >= 0.10.0.0 && < 0.12,
-    containers >= 0.5.0.0  && < 0.7,
-    deepseq    >= 1.3.0.1  && < 1.5,
+    base       >= 4.9      && < 5,
+    bytestring >= 0.10.0.0 && < 0.13,
+    containers >= 0.5.0.0  && < 0.8,
+    deepseq    >= 1.3.0.1  && < 1.6,
     directory  >= 1.2      && < 1.4,
-    filepath   >= 1.3.0.1  && < 1.5,
+    filepath   >= 1.3.0.1  && < 1.6,
     pretty     >= 1.1.1    && < 1.2,
     process    >= 1.2.1.0  && < 1.7,
     time       >= 1.4.0.1  && < 1.13
 
   if os(windows)
-    build-depends: Win32 >= 2.3.0.0 && < 2.14
+    build-depends: Win32 >= 2.3.0.0 && < 2.15
   else
-    build-depends: unix  >= 2.6.0.0 && < 2.8
+    build-depends: unix  >= 2.6.0.0 && < 2.9
 
   ghc-options: -Wall -fno-ignore-asserts -fwarn-tabs -fwarn-incomplete-uni-patterns -fwarn-incomplete-record-updates
 
@@ -89,6 +89,7 @@
     Distribution.Simple.Bench
     Distribution.Simple.Build
     Distribution.Simple.Build.Macros
+    Distribution.Simple.Build.PackageInfoModule
     Distribution.Simple.Build.PathsModule
     Distribution.Simple.BuildPaths
     Distribution.Simple.BuildTarget
@@ -299,9 +300,9 @@
   build-depends:
     -- transformers-0.4.0.0 doesn't have record syntax e.g. for Identity
     -- See also https://github.com/ekmett/transformers-compat/issues/35
-    transformers (>= 0.3      && < 0.4) || (>= 0.4.1.0 && < 0.7),
+    transformers (>= 0.3      && < 0.4) || (>=0.4.1.0 && <0.7),
     mtl           >= 2.1      && < 2.4,
-    text         (>= 1.2.3.0  && < 1.3) || (>= 2.0 && < 2.1),
+    text         (>= 1.2.3.0  && < 1.3) || (>= 2.0 && < 2.2),
     parsec        >= 3.1.13.0 && < 3.2
 
   other-modules:
@@ -319,11 +320,16 @@
     Distribution.GetOpt
     Distribution.Lex
     Distribution.Simple.Build.Macros.Z
+    Distribution.Simple.Build.PackageInfoModule.Z
     Distribution.Simple.Build.PathsModule.Z
     Distribution.Simple.GHC.EnvironmentParser
     Distribution.Simple.GHC.Internal
     Distribution.Simple.GHC.ImplInfo
+    Distribution.Simple.ConfigureScript
     Distribution.ZinzaPrelude
+    Paths_Cabal
+
+  autogen-modules:
     Paths_Cabal
 
   other-extensions:
diff --git a/cabal/Cabal/ChangeLog.md b/cabal/Cabal/ChangeLog.md
--- a/cabal/Cabal/ChangeLog.md
+++ b/cabal/Cabal/ChangeLog.md
@@ -1,3 +1,15 @@
+# 3.10.3.0 [Hécate](mailto:hecate+github@glitchbra.in) January 2024
+* See https://github.com/haskell/cabal/blob/master/release-notes/Cabal-3.10.3.0.md
+
+# 3.10.2.1 [Hécate](mailto:hecate+github@glitchbra.in) October 2023
+* See https://github.com/haskell/cabal/blob/master/release-notes/Cabal-3.10.2.1.md
+
+# 3.10.2.0 [Hécate](mailto:hecate+github@glitchbra.in) August 2023
+* See https://github.com/haskell/cabal/blob/master/release-notes/Cabal-3.10.2.0.md
+
+# 3.10.1.0 [Mikolaj Konarski](mailto:mikolaj@well-typed.com) March 2023
+* See https://github.com/haskell/cabal/blob/master/release-notes/Cabal-3.10.1.0.md
+
 # 3.8.1.0 [Mikolaj Konarski](mailto:mikolaj@well-typed.com) August 2022
   * See https://github.com/haskell/cabal/blob/master/release-notes/Cabal-3.8.1.0.md
 
diff --git a/cabal/Cabal/LICENSE b/cabal/Cabal/LICENSE
--- a/cabal/Cabal/LICENSE
+++ b/cabal/Cabal/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2003-2022, Cabal Development Team.
+Copyright (c) 2003-2023, Cabal Development Team.
 See the AUTHORS file for the full list of copyright holders.
 
 See */LICENSE for the copyright holders of the subcomponents.
diff --git a/cabal/Cabal/Makefile b/cabal/Cabal/Makefile
--- a/cabal/Cabal/Makefile
+++ b/cabal/Cabal/Makefile
@@ -1,4 +1,4 @@
-VERSION=3.8.1.0
+VERSION=3.10.3.0
 
 #KIND=devel
 KIND=rc
diff --git a/cabal/Cabal/src/Distribution/Backpack/LinkedComponent.hs b/cabal/Cabal/src/Distribution/Backpack/LinkedComponent.hs
--- a/cabal/Cabal/src/Distribution/Backpack/LinkedComponent.hs
+++ b/cabal/Cabal/src/Distribution/Backpack/LinkedComponent.hs
@@ -210,12 +210,14 @@
         -- Read out all the final results by converting back
         -- into a pure representation.
         let convertIncludeU (ComponentInclude dep_aid rns i) = do
-                uid <- convertUnitIdU (ann_id dep_aid)
+                let component_name = pretty $ ann_cname dep_aid
+                uid <- convertUnitIdU (ann_id dep_aid) component_name
                 return (ComponentInclude {
-                            ci_ann_id = dep_aid { ann_id = uid },
-                            ci_renaming = rns,
-                            ci_implicit = i
-                        })
+                        ci_ann_id = dep_aid { ann_id = uid },
+                        ci_renaming = rns,
+                        ci_implicit = i
+                    })
+
         shape <- convertModuleScopeU shape_u
         let (includes_u, sig_includes_u) = partitionEithers all_includes_u
         incls <- traverse convertIncludeU includes_u
diff --git a/cabal/Cabal/src/Distribution/Backpack/UnifyM.hs b/cabal/Cabal/src/Distribution/Backpack/UnifyM.hs
--- a/cabal/Cabal/src/Distribution/Backpack/UnifyM.hs
+++ b/cabal/Cabal/src/Distribution/Backpack/UnifyM.hs
@@ -386,19 +386,21 @@
 
 -- The workhorse functions
 
-convertUnitIdU' :: MooEnv -> UnitIdU s -> UnifyM s OpenUnitId
-convertUnitIdU' stk uid_u = do
+-- | Returns `OpenUnitId` if there is no a mutually recursive unit.
+-- | Otherwise returns a list of signatures instantiated by given `UnitIdU`.
+convertUnitIdU' :: MooEnv -> UnitIdU s -> Doc -> UnifyM s OpenUnitId
+convertUnitIdU' stk uid_u required_mod_name = do
     x <- liftST $ UnionFind.find uid_u
     case x of
-        UnitIdThunkU uid -> return (DefiniteUnitId uid)
+        UnitIdThunkU uid -> return $ DefiniteUnitId uid
         UnitIdU u cid insts_u ->
             case lookupMooEnv stk u of
-                Just _i ->
-                    failWith (text "Unsupported mutually recursive unit identifier")
-                    -- return (UnitIdVar i)
+                Just _ ->
+                    let mod_names = Map.keys insts_u
+                    in failWithMutuallyRecursiveUnitsError required_mod_name mod_names
                 Nothing -> do
                     insts <- for insts_u $ convertModuleU' (extendMooEnv stk u)
-                    return (IndefFullUnitId cid insts)
+                    return $ IndefFullUnitId cid insts
 
 convertModuleU' :: MooEnv -> ModuleU s -> UnifyM s OpenModule
 convertModuleU' stk mod_u = do
@@ -406,12 +408,20 @@
     case mod of
         ModuleVarU mod_name -> return (OpenModuleVar mod_name)
         ModuleU uid_u mod_name -> do
-            uid <- convertUnitIdU' stk uid_u
+            uid <- convertUnitIdU' stk uid_u (pretty mod_name)
             return (OpenModule uid mod_name)
 
+failWithMutuallyRecursiveUnitsError :: Doc -> [ModuleName] -> UnifyM s a
+failWithMutuallyRecursiveUnitsError required_mod_name mod_names =
+    let sigsList = hcat $ punctuate (text ", ") $ map (quotes . pretty) mod_names in
+    failWith $
+        text "Cannot instantiate requirement" <+> quotes required_mod_name $$
+        text "Ensure \"build-depends:\" doesn't include any library with signatures:" <+> sigsList $$
+        text "as this creates a cyclic dependency, which GHC does not support."
+
 -- Helper functions
 
-convertUnitIdU :: UnitIdU s -> UnifyM s OpenUnitId
+convertUnitIdU :: UnitIdU s -> Doc -> UnifyM s OpenUnitId
 convertUnitIdU = convertUnitIdU' emptyMooEnv
 
 convertModuleU :: ModuleU s -> UnifyM s OpenModule
diff --git a/cabal/Cabal/src/Distribution/Compat/Process.hs b/cabal/Cabal/src/Distribution/Compat/Process.hs
--- a/cabal/Cabal/src/Distribution/Compat/Process.hs
+++ b/cabal/Cabal/src/Distribution/Compat/Process.hs
@@ -1,17 +1,12 @@
 {-# LANGUAGE CPP #-}
 module Distribution.Compat.Process (
     -- * Redefined functions
-    createProcess,
-    runInteractiveProcess,
-    rawSystem,
+    proc,
     -- * Additions
     enableProcessJobs,
     ) where
 
-import System.Exit (ExitCode (..))
-import System.IO   (Handle)
-
-import           System.Process (CreateProcess, ProcessHandle, waitForProcess)
+import           System.Process (CreateProcess)
 import qualified System.Process as Process
 
 #if defined(mingw32_HOST_OS) && MIN_VERSION_process(1,6,9)
@@ -60,35 +55,7 @@
 -- process redefinitions
 -------------------------------------------------------------------------------
 
--- | 'System.Process.createProcess' with process jobs enabled when appropriate.
--- See 'enableProcessJobs'.
-createProcess :: CreateProcess
-              -> IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
-createProcess = Process.createProcess . enableProcessJobs
-
--- | 'System.Process.rawSystem' with process jobs enabled when appropriate.
--- See 'enableProcessJobs'.
-rawSystem :: String -> [String] -> IO ExitCode
-rawSystem cmd args = do
-  (_,_,_,p) <- createProcess (Process.proc cmd args) { Process.delegate_ctlc = True }
-  waitForProcess p
-
--- | 'System.Process.runInteractiveProcess' with process jobs enabled when
--- appropriate. See 'enableProcessJobs'.
-runInteractiveProcess
-  :: FilePath                   -- ^ Filename of the executable (see 'RawCommand' for details)
-  -> [String]                   -- ^ Arguments to pass to the executable
-  -> Maybe FilePath             -- ^ Optional path to the working directory
-  -> Maybe [(String,String)]    -- ^ Optional environment (otherwise inherit)
-  -> IO (Handle,Handle,Handle,ProcessHandle)
-runInteractiveProcess cmd args mb_cwd mb_env = do
-  (mb_in, mb_out, mb_err, p) <-
-      createProcess (Process.proc cmd args)
-              { Process.std_in  = Process.CreatePipe,
-                Process.std_out = Process.CreatePipe,
-                Process.std_err = Process.CreatePipe,
-                Process.env     = mb_env,
-                Process.cwd     = mb_cwd }
-  return (fromJust mb_in, fromJust mb_out, fromJust mb_err, p)
-  where
-    fromJust = maybe (error "runInteractiveProcess: fromJust") id
+-- | 'System.Process.proc' with process jobs enabled when appropriate,
+-- and defaulting 'delegate_ctlc' to 'True'.
+proc :: FilePath -> [String] -> CreateProcess
+proc path args = enableProcessJobs (Process.proc path args) { Process.delegate_ctlc = True }
diff --git a/cabal/Cabal/src/Distribution/PackageDescription/Check.hs b/cabal/Cabal/src/Distribution/PackageDescription/Check.hs
--- a/cabal/Cabal/src/Distribution/PackageDescription/Check.hs
+++ b/cabal/Cabal/src/Distribution/PackageDescription/Check.hs
@@ -23,2395 +23,2918 @@
 
 module Distribution.PackageDescription.Check (
         -- * Package Checking
-        PackageCheck(..),
-        checkPackage,
-        checkConfiguredPackage,
-
-        -- ** Checking package contents
-        checkPackageFiles,
-        checkPackageContent,
-        CheckPackageContentOps(..),
-        checkPackageFileNames,
-  ) where
-
-import Distribution.Compat.Prelude
-import Prelude ()
-
-import Data.List                                     (group)
-import Distribution.CabalSpecVersion
-import Distribution.Compat.Lens
-import Distribution.Compiler
-import Distribution.License
-import Distribution.Package
-import Distribution.PackageDescription
-import Distribution.PackageDescription.Configuration
-import Distribution.Pretty                           (prettyShow)
-import Distribution.Simple.BuildPaths                (autogenPathsModuleName)
-import Distribution.Simple.BuildToolDepends
-import Distribution.Simple.CCompiler
-import Distribution.Simple.Glob
-import Distribution.Simple.Utils                     hiding (findPackageDesc, notice)
-import Distribution.System
-import Distribution.Types.ComponentRequestedSpec
-import Distribution.Types.PackageName.Magic
-import Distribution.Utils.Generic                    (isAscii)
-import Distribution.Verbosity
-import Distribution.Version
-import Distribution.Utils.Path
-import Language.Haskell.Extension
-import System.FilePath
-       (splitDirectories, splitExtension, splitPath, takeExtension, takeFileName, (<.>), (</>))
-
-import qualified Data.ByteString.Lazy      as BS
-import qualified Data.Map                  as Map
-import qualified Distribution.Compat.DList as DList
-import qualified Distribution.SPDX         as SPDX
-import qualified System.Directory          as System
-
-import qualified System.Directory        (getDirectoryContents)
-import qualified System.FilePath.Windows as FilePath.Windows (isValid)
-
-import qualified Data.Set as Set
-import qualified Distribution.Utils.ShortText as ShortText
-
-import qualified Distribution.Types.BuildInfo.Lens                 as L
-import qualified Distribution.Types.GenericPackageDescription.Lens as L
-import qualified Distribution.Types.PackageDescription.Lens        as L
-
--- $setup
--- >>> import Control.Arrow ((&&&))
-
--- | Results of some kind of failed package check.
---
--- There are a range of severities, from merely dubious to totally insane.
--- All of them come with a human readable explanation. In future we may augment
--- them with more machine readable explanations, for example to help an IDE
--- suggest automatic corrections.
---
-data PackageCheck =
-
-       -- | This package description is no good. There's no way it's going to
-       -- build sensibly. This should give an error at configure time.
-       PackageBuildImpossible { explanation :: String }
-
-       -- | A problem that is likely to affect building the package, or an
-       -- issue that we'd like every package author to be aware of, even if
-       -- the package is never distributed.
-     | PackageBuildWarning { explanation :: String }
-
-       -- | An issue that might not be a problem for the package author but
-       -- might be annoying or detrimental when the package is distributed to
-       -- users. We should encourage distributed packages to be free from these
-       -- issues, but occasionally there are justifiable reasons so we cannot
-       -- ban them entirely.
-     | PackageDistSuspicious { explanation :: String }
-
-       -- | Like PackageDistSuspicious but will only display warnings
-       -- rather than causing abnormal exit when you run 'cabal check'.
-     | PackageDistSuspiciousWarn { explanation :: String }
-
-       -- | An issue that is OK in the author's environment but is almost
-       -- certain to be a portability problem for other environments. We can
-       -- quite legitimately refuse to publicly distribute packages with these
-       -- problems.
-     | PackageDistInexcusable { explanation :: String }
-  deriving (Eq, Ord)
-
-instance Show PackageCheck where
-    show notice = explanation notice
-
-check :: Bool -> PackageCheck -> Maybe PackageCheck
-check False _  = Nothing
-check True  pc = Just pc
-
-checkSpecVersion :: PackageDescription -> CabalSpecVersion -> Bool -> PackageCheck
-                 -> Maybe PackageCheck
-checkSpecVersion pkg specver cond pc
-  | specVersion pkg >= specver  = Nothing
-  | otherwise                   = check cond pc
-
--- ------------------------------------------------------------
--- * Standard checks
--- ------------------------------------------------------------
-
--- | Check for common mistakes and problems in package descriptions.
---
--- This is the standard collection of checks covering all aspects except
--- for checks that require looking at files within the package. For those
--- see 'checkPackageFiles'.
---
--- It requires the 'GenericPackageDescription' and optionally a particular
--- configuration of that package. If you pass 'Nothing' then we just check
--- a version of the generic description using 'flattenPackageDescription'.
---
-checkPackage :: GenericPackageDescription
-             -> Maybe PackageDescription
-             -> [PackageCheck]
-checkPackage gpkg mpkg =
-     checkConfiguredPackage pkg
-  ++ checkConditionals gpkg
-  ++ checkPackageVersions gpkg
-  ++ checkDevelopmentOnlyFlags gpkg
-  ++ checkFlagNames gpkg
-  ++ checkUnusedFlags gpkg
-  ++ checkUnicodeXFields gpkg
-  ++ checkPathsModuleExtensions pkg
-  ++ checkSetupVersions gpkg
-  ++ checkDuplicateModules gpkg
-  where
-    pkg = fromMaybe (flattenPackageDescription gpkg) mpkg
-
---TODO: make this variant go away
---      we should always know the GenericPackageDescription
-checkConfiguredPackage :: PackageDescription -> [PackageCheck]
-checkConfiguredPackage pkg =
-    checkSanity pkg
- ++ checkFields pkg
- ++ checkLicense pkg
- ++ checkSourceRepos pkg
- ++ checkAllGhcOptions pkg
- ++ checkCCOptions pkg
- ++ checkCxxOptions pkg
- ++ checkCPPOptions pkg
- ++ checkPaths pkg
- ++ checkCabalVersion pkg
-
-
--- ------------------------------------------------------------
--- * Basic sanity checks
--- ------------------------------------------------------------
-
--- | Check that this package description is sane.
---
-checkSanity :: PackageDescription -> [PackageCheck]
-checkSanity pkg =
-  catMaybes [
-
-    check (null . unPackageName . packageName $ pkg) $
-      PackageBuildImpossible "No 'name' field."
-
-  , check (nullVersion == packageVersion pkg) $
-      PackageBuildImpossible "No 'version' field."
-
-  , check (all ($ pkg) [ null . executables
-                       , null . testSuites
-                       , null . benchmarks
-                       , null . allLibraries
-                       , null . foreignLibs ]) $
-      PackageBuildImpossible
-        "No executables, libraries, tests, or benchmarks found. Nothing to do."
-
-  , check (any (== LMainLibName) (map libName $ subLibraries pkg)) $
-      PackageBuildImpossible $ "Found one or more unnamed internal libraries. "
-        ++ "Only the non-internal library can have the same name as the package."
-
-  , check (not (null duplicateNames)) $
-      PackageBuildImpossible $ "Duplicate sections: "
-        ++ commaSep (map unUnqualComponentName duplicateNames)
-        ++ ". The name of every library, executable, test suite,"
-        ++ " and benchmark section in"
-        ++ " the package must be unique."
-
-  -- NB: but it's OK for executables to have the same name!
-  -- TODO shouldn't need to compare on the string level
-  , check (any (== prettyShow (packageName pkg)) (prettyShow <$> subLibNames)) $
-      PackageBuildImpossible $ "Illegal internal library name "
-        ++ prettyShow (packageName pkg)
-        ++ ". Internal libraries cannot have the same name as the package."
-        ++ " Maybe you wanted a non-internal library?"
-        ++ " If so, rewrite the section stanza"
-        ++ " from 'library: '" ++ prettyShow (packageName pkg) ++ "' to 'library'."
-  ]
-  --TODO: check for name clashes case insensitively: windows file systems cannot
-  --cope.
-
-  ++ concatMap (checkLibrary    pkg) (allLibraries pkg)
-  ++ concatMap (checkExecutable pkg) (executables pkg)
-  ++ concatMap (checkTestSuite  pkg) (testSuites pkg)
-  ++ concatMap (checkBenchmark  pkg) (benchmarks pkg)
-
-  where
-    -- The public 'library' gets special dispensation, because it
-    -- is common practice to export a library and name the executable
-    -- the same as the package.
-    subLibNames = mapMaybe (libraryNameString . libName) $ subLibraries pkg
-    exeNames = map exeName $ executables pkg
-    testNames = map testName $ testSuites pkg
-    bmNames = map benchmarkName $ benchmarks pkg
-    duplicateNames = dups $ subLibNames ++ exeNames ++ testNames ++ bmNames
-
-checkLibrary :: PackageDescription -> Library -> [PackageCheck]
-checkLibrary pkg lib =
-  catMaybes [
-
-  -- TODO: This check is bogus if a required-signature was passed through
-    check (null (explicitLibModules lib) && null (reexportedModules lib)) $
-      PackageDistSuspiciousWarn $
-           showLibraryName (libName lib) ++ " does not expose any modules"
-
-    -- check use of signatures sections
-  , checkVersion CabalSpecV2_0 (not (null (signatures lib))) $
-      PackageDistInexcusable $
-           "To use the 'signatures' field the package needs to specify "
-        ++ "at least 'cabal-version: 2.0'."
-
-    -- check that all autogen-modules appear on other-modules or exposed-modules
-  , check
-      (not $ and $ map (flip elem (explicitLibModules lib)) (libModulesAutogen lib)) $
-      PackageBuildImpossible $
-           "An 'autogen-module' is neither on 'exposed-modules' or "
-        ++ "'other-modules'."
-
-    -- check that all autogen-includes appear on includes or install-includes
-  , check
-      (not $ and $ map (flip elem (allExplicitIncludes lib)) (view L.autogenIncludes lib)) $
-      PackageBuildImpossible $
-           "An include in 'autogen-includes' is neither in 'includes' or "
-        ++ "'install-includes'."
-  ]
-
-  where
-    checkVersion :: CabalSpecVersion -> Bool -> PackageCheck -> Maybe PackageCheck
-    checkVersion ver cond pc
-      | specVersion pkg >= ver = Nothing
-      | otherwise              = check cond pc
-
-allExplicitIncludes :: L.HasBuildInfo a => a -> [FilePath]
-allExplicitIncludes x = view L.includes x ++ view L.installIncludes x
-
-checkExecutable :: PackageDescription -> Executable -> [PackageCheck]
-checkExecutable pkg exe =
-  catMaybes [
-
-    check (null (modulePath exe)) $
-      PackageBuildImpossible $
-        "No 'main-is' field found for executable " ++ prettyShow (exeName exe)
-  -- This check does not apply to scripts.
-  , check (package pkg /= fakePackageId
-       && not (null (modulePath exe))
-       && (not $ fileExtensionSupportedLanguage $ modulePath exe)) $
-      PackageBuildImpossible $
-           "The 'main-is' field must specify a '.hs' or '.lhs' file "
-        ++ "(even if it is generated by a preprocessor), "
-        ++ "or it may specify a C/C++/obj-C source file."
-
-  , checkSpecVersion pkg CabalSpecV1_18
-          (fileExtensionSupportedLanguage (modulePath exe)
-        && takeExtension (modulePath exe) `notElem` [".hs", ".lhs"]) $
-      PackageDistInexcusable $
-           "The package uses a C/C++/obj-C source file for the 'main-is' field. "
-        ++ "To use this feature you need to specify 'cabal-version: 1.18' or higher."
-
-    -- check that all autogen-modules appear on other-modules
-  , check
-      (not $ and $ map (flip elem (exeModules exe)) (exeModulesAutogen exe)) $
-      PackageBuildImpossible $
-           "On executable '" ++ prettyShow (exeName exe) ++ "' an 'autogen-module' is not "
-        ++ "on 'other-modules'"
-
-    -- check that all autogen-includes appear on includes
-  , check
-      (not $ and $ map (flip elem (view L.includes exe)) (view L.autogenIncludes exe)) $
-      PackageBuildImpossible "An include in 'autogen-includes' is not in 'includes'."
-  ]
-
-checkTestSuite :: PackageDescription -> TestSuite -> [PackageCheck]
-checkTestSuite pkg test =
-  catMaybes [
-
-    case testInterface test of
-      TestSuiteUnsupported tt@(TestTypeUnknown _ _) -> Just $
-        PackageBuildWarning $
-             quote (prettyShow tt) ++ " is not a known type of test suite. "
-          ++ "Either remove the 'type' field or use a known type. "
-          ++ "The known test suite types are: "
-          ++ commaSep (map prettyShow knownTestTypes)
-
-      TestSuiteUnsupported tt -> Just $
-        PackageBuildWarning $
-             quote (prettyShow tt) ++ " is not a supported test suite version. "
-          ++ "Either remove the 'type' field or use a known type. "
-          ++ "The known test suite types are: "
-          ++ commaSep (map prettyShow knownTestTypes)
-      _ -> Nothing
-
-  , check mainIsWrongExt $
-      PackageBuildImpossible $
-           "The 'main-is' field must specify a '.hs' or '.lhs' file "
-        ++ "(even if it is generated by a preprocessor), "
-        ++ "or it may specify a C/C++/obj-C source file."
-
-  , checkSpecVersion pkg CabalSpecV1_18 (mainIsNotHsExt && not mainIsWrongExt) $
-      PackageDistInexcusable $
-           "The package uses a C/C++/obj-C source file for the 'main-is' field. "
-        ++ "To use this feature you need to specify 'cabal-version: 1.18' or higher."
-
-    -- check that all autogen-modules appear on other-modules
-  , check
-      (not $ and $ map (flip elem (testModules test)) (testModulesAutogen test)) $
-      PackageBuildImpossible $
-           "On test suite '" ++ prettyShow (testName test) ++ "' an 'autogen-module' is not "
-        ++ "on 'other-modules'"
-
-    -- check that all autogen-includes appear on includes
-  , check
-      (not $ and $ map (flip elem (view L.includes test)) (view L.autogenIncludes test)) $
-      PackageBuildImpossible "An include in 'autogen-includes' is not in 'includes'."
-  ]
-  where
-    mainIsWrongExt = case testInterface test of
-      TestSuiteExeV10 _ f -> not $ fileExtensionSupportedLanguage f
-      _                   -> False
-
-    mainIsNotHsExt = case testInterface test of
-      TestSuiteExeV10 _ f -> takeExtension f `notElem` [".hs", ".lhs"]
-      _                   -> False
-
-checkBenchmark :: PackageDescription -> Benchmark -> [PackageCheck]
-checkBenchmark _pkg bm =
-  catMaybes [
-
-    case benchmarkInterface bm of
-      BenchmarkUnsupported tt@(BenchmarkTypeUnknown _ _) -> Just $
-        PackageBuildWarning $
-             quote (prettyShow tt) ++ " is not a known type of benchmark. "
-          ++ "Either remove the 'type' field or use a known type. "
-          ++ "The known benchmark types are: "
-          ++ commaSep (map prettyShow knownBenchmarkTypes)
-
-      BenchmarkUnsupported tt -> Just $
-        PackageBuildWarning $
-             quote (prettyShow tt) ++ " is not a supported benchmark version. "
-          ++ "Either remove the 'type' field or use a known type. "
-          ++ "The known benchmark types are: "
-          ++ commaSep (map prettyShow knownBenchmarkTypes)
-      _ -> Nothing
-
-  , check mainIsWrongExt $
-      PackageBuildImpossible $
-           "The 'main-is' field must specify a '.hs' or '.lhs' file "
-        ++ "(even if it is generated by a preprocessor)."
-
-    -- check that all autogen-modules appear on other-modules
-  , check
-      (not $ and $ map (flip elem (benchmarkModules bm)) (benchmarkModulesAutogen bm)) $
-      PackageBuildImpossible $
-             "On benchmark '" ++ prettyShow (benchmarkName bm) ++ "' an 'autogen-module' is "
-          ++ "not on 'other-modules'"
-
-    -- check that all autogen-includes appear on includes
-  , check
-      (not $ and $ map (flip elem (view L.includes bm)) (view L.autogenIncludes bm)) $
-      PackageBuildImpossible "An include in 'autogen-includes' is not in 'includes'."
-  ]
-  where
-    mainIsWrongExt = case benchmarkInterface bm of
-      BenchmarkExeV10 _ f -> takeExtension f `notElem` [".hs", ".lhs"]
-      _                   -> False
-
--- ------------------------------------------------------------
--- * Additional pure checks
--- ------------------------------------------------------------
-
-checkFields :: PackageDescription -> [PackageCheck]
-checkFields pkg =
-  catMaybes [
-
-    check (not . FilePath.Windows.isValid . prettyShow . packageName $ pkg) $
-      PackageDistInexcusable $
-           "The package name '" ++ prettyShow (packageName pkg) ++ "' is "
-        ++ "invalid on Windows. Many tools need to convert package names to "
-        ++ "file names so using this name would cause problems."
-
-  , check ((isPrefixOf "z-") . prettyShow . packageName $ pkg) $
-      PackageDistInexcusable $
-           "Package names with the prefix 'z-' are reserved by Cabal and "
-        ++ "cannot be used."
-
-  , check (isNothing (buildTypeRaw pkg) && specVersion pkg < CabalSpecV2_2) $
-      PackageBuildWarning $
-           "No 'build-type' specified. If you do not need a custom Setup.hs or "
-        ++ "./configure script then use 'build-type: Simple'."
-
-  , check (isJust (setupBuildInfo pkg) && buildType pkg /= Custom) $
-      PackageBuildWarning $
-           "Ignoring the 'custom-setup' section because the 'build-type' is "
-        ++ "not 'Custom'. Use 'build-type: Custom' if you need to use a "
-        ++ "custom Setup.hs script."
-
-  , check (not (null unknownCompilers)) $
-      PackageBuildWarning $
-        "Unknown compiler " ++ commaSep (map quote unknownCompilers)
-                            ++ " in 'tested-with' field."
-
-  , check (not (null unknownLanguages)) $
-      PackageBuildWarning $
-        "Unknown languages: " ++ commaSep unknownLanguages
-
-  , check (not (null unknownExtensions)) $
-      PackageBuildWarning $
-        "Unknown extensions: " ++ commaSep unknownExtensions
-
-  , check (not (null languagesUsedAsExtensions)) $
-      PackageBuildWarning $
-           "Languages listed as extensions: "
-        ++ commaSep languagesUsedAsExtensions
-        ++ ". Languages must be specified in either the 'default-language' "
-        ++ " or the 'other-languages' field."
-
-  , check (not (null ourDeprecatedExtensions)) $
-      PackageDistSuspicious $
-           "Deprecated extensions: "
-        ++ commaSep (map (quote . prettyShow . fst) ourDeprecatedExtensions)
-        ++ ". " ++ unwords
-             [ "Instead of '" ++ prettyShow ext
-            ++ "' use '" ++ prettyShow replacement ++ "'."
-             | (ext, Just replacement) <- ourDeprecatedExtensions ]
-
-  , check (ShortText.null (category pkg)) $
-      PackageDistSuspicious "No 'category' field."
-
-  , check (ShortText.null (maintainer pkg)) $
-      PackageDistSuspicious "No 'maintainer' field."
-
-  , check (ShortText.null (synopsis pkg) && ShortText.null (description pkg)) $
-      PackageDistInexcusable "No 'synopsis' or 'description' field."
-
-  , check (ShortText.null (description pkg) && not (ShortText.null (synopsis pkg))) $
-      PackageDistSuspicious "No 'description' field."
-
-  , check (ShortText.null (synopsis pkg) && not (ShortText.null (description pkg))) $
-      PackageDistSuspicious "No 'synopsis' field."
-
-    --TODO: recommend the bug reports URL, author and homepage fields
-    --TODO: recommend not using the stability field
-    --TODO: recommend specifying a source repo
-
-  , check (ShortText.length (synopsis pkg) > 80) $
-      PackageDistSuspicious
-        "The 'synopsis' field is rather long (max 80 chars is recommended)."
-
-    -- See also https://github.com/haskell/cabal/pull/3479
-  , check (not (ShortText.null (description pkg))
-           && ShortText.length (description pkg) <= ShortText.length (synopsis pkg)) $
-      PackageDistSuspicious $
-           "The 'description' field should be longer than the 'synopsis' "
-        ++ "field. "
-        ++ "It's useful to provide an informative 'description' to allow "
-        ++ "Haskell programmers who have never heard about your package to "
-        ++ "understand the purpose of your package. "
-        ++ "The 'description' field content is typically shown by tooling "
-        ++ "(e.g. 'cabal info', Haddock, Hackage) below the 'synopsis' which "
-        ++ "serves as a headline. "
-        ++ "Please refer to <https://cabal.readthedocs.io/en/stable/"
-        ++ "cabal-package.html#package-properties> for more details."
-
-    -- check use of impossible constraints "tested-with: GHC== 6.10 && ==6.12"
-  , check (not (null testedWithImpossibleRanges)) $
-      PackageDistInexcusable $
-           "Invalid 'tested-with' version range: "
-        ++ commaSep (map prettyShow testedWithImpossibleRanges)
-        ++ ". To indicate that you have tested a package with multiple "
-        ++ "different versions of the same compiler use multiple entries, "
-        ++ "for example 'tested-with: GHC==6.10.4, GHC==6.12.3' and not "
-        ++ "'tested-with: GHC==6.10.4 && ==6.12.3'."
-
-  -- for more details on why the following was commented out,
-  -- check https://github.com/haskell/cabal/pull/7470#issuecomment-875878507
-  -- , check (not (null depInternalLibraryWithExtraVersion)) $
-  --     PackageBuildWarning $
-  --          "The package has an extraneous version range for a dependency on an "
-  --       ++ "internal library: "
-  --       ++ commaSep (map prettyShow depInternalLibraryWithExtraVersion)
-  --       ++ ". This version range includes the current package but isn't needed "
-  --       ++ "as the current package's library will always be used."
-
-  , check (not (null depInternalLibraryWithImpossibleVersion)) $
-      PackageBuildImpossible $
-           "The package has an impossible version range for a dependency on an "
-        ++ "internal library: "
-        ++ commaSep (map prettyShow depInternalLibraryWithImpossibleVersion)
-        ++ ". This version range does not include the current package, and must "
-        ++ "be removed as the current package's library will always be used."
-
-  -- , check (not (null depInternalExecutableWithExtraVersion)) $
-  --     PackageBuildWarning $
-  --          "The package has an extraneous version range for a dependency on an "
-  --       ++ "internal executable: "
-  --       ++ commaSep (map prettyShow depInternalExecutableWithExtraVersion)
-  --       ++ ". This version range includes the current package but isn't needed "
-  --       ++ "as the current package's executable will always be used."
-
-  , check (not (null depInternalExecutableWithImpossibleVersion)) $
-      PackageBuildImpossible $
-           "The package has an impossible version range for a dependency on an "
-        ++ "internal executable: "
-        ++ commaSep (map prettyShow depInternalExecutableWithImpossibleVersion)
-        ++ ". This version range does not include the current package, and must "
-        ++ "be removed as the current package's executable will always be used."
-
-  , check (not (null depMissingInternalExecutable)) $
-      PackageBuildImpossible $
-           "The package depends on a missing internal executable: "
-        ++ commaSep (map prettyShow depInternalExecutableWithImpossibleVersion)
-  ]
-  where
-    unknownCompilers  = [ name | (OtherCompiler name, _) <- testedWith pkg ]
-    unknownLanguages  = [ name | bi <- allBuildInfo pkg
-                               , UnknownLanguage name <- allLanguages bi ]
-    unknownExtensions = [ name | bi <- allBuildInfo pkg
-                               , UnknownExtension name <- allExtensions bi
-                               , name `notElem` map prettyShow knownLanguages ]
-    ourDeprecatedExtensions = nub $ catMaybes
-      [ find ((==ext) . fst) deprecatedExtensions
-      | bi <- allBuildInfo pkg
-      , ext <- allExtensions bi ]
-    languagesUsedAsExtensions =
-      [ name | bi <- allBuildInfo pkg
-             , UnknownExtension name <- allExtensions bi
-             , name `elem` map prettyShow knownLanguages ]
-
-    testedWithImpossibleRanges =
-      [ Dependency (mkPackageName (prettyShow compiler)) vr mainLibSet
-      | (compiler, vr) <- testedWith pkg
-      , isNoVersion vr ]
-
-    internalLibraries =
-        map (maybe (packageName pkg) (unqualComponentNameToPackageName) . libraryNameString . libName)
-            (allLibraries pkg)
-
-    internalExecutables = map exeName $ executables pkg
-
-    internalLibDeps =
-      [ dep
-      | bi <- allBuildInfo pkg
-      , dep@(Dependency name _ _) <- targetBuildDepends bi
-      , name `elem` internalLibraries
-      ]
-
-    internalExeDeps =
-      [ dep
-      | bi <- allBuildInfo pkg
-      , dep <- getAllToolDependencies pkg bi
-      , isInternal pkg dep
-      ]
-
-    -- depInternalLibraryWithExtraVersion =
-    --   [ dep
-    --   | dep@(Dependency _ versionRange _) <- internalLibDeps
-    --   , not $ isAnyVersion versionRange
-    --   , packageVersion pkg `withinRange` versionRange
-    --   ]
-
-    depInternalLibraryWithImpossibleVersion =
-      [ dep
-      | dep@(Dependency _ versionRange _) <- internalLibDeps
-      , not $ packageVersion pkg `withinRange` versionRange
-      ]
-
-    -- depInternalExecutableWithExtraVersion =
-    --   [ dep
-    --   | dep@(ExeDependency _ _ versionRange) <- internalExeDeps
-    --   , not $ isAnyVersion versionRange
-    --   , packageVersion pkg `withinRange` versionRange
-    --   ]
-
-    depInternalExecutableWithImpossibleVersion =
-      [ dep
-      | dep@(ExeDependency _ _ versionRange) <- internalExeDeps
-      , not $ packageVersion pkg `withinRange` versionRange
-      ]
-
-    depMissingInternalExecutable =
-      [ dep
-      | dep@(ExeDependency _ eName _) <- internalExeDeps
-      , not $ eName `elem` internalExecutables
-      ]
-
-
-checkLicense :: PackageDescription -> [PackageCheck]
-checkLicense pkg = case licenseRaw pkg of
-    Right l -> checkOldLicense pkg l
-    Left  l -> checkNewLicense pkg l
-
-checkNewLicense :: PackageDescription -> SPDX.License -> [PackageCheck]
-checkNewLicense _pkg lic = catMaybes
-    [ check (lic == SPDX.NONE) $
-        PackageDistInexcusable
-            "The 'license' field is missing or is NONE."
-    ]
-
-checkOldLicense :: PackageDescription -> License -> [PackageCheck]
-checkOldLicense pkg lic = catMaybes
-  [ check (lic == UnspecifiedLicense) $
-      PackageDistInexcusable
-        "The 'license' field is missing."
-
-  , check (lic == AllRightsReserved) $
-      PackageDistSuspicious
-        "The 'license' is AllRightsReserved. Is that really what you want?"
-
-  , checkVersion CabalSpecV1_4 (lic `notElem` compatLicenses) $
-      PackageDistInexcusable $
-           "Unfortunately the license " ++ quote (prettyShow (license pkg))
-        ++ " messes up the parser in earlier Cabal versions so you need to "
-        ++ "specify 'cabal-version: >= 1.4'. Alternatively if you require "
-        ++ "compatibility with earlier Cabal versions then use 'OtherLicense'."
-
-  , case lic of
-      UnknownLicense l -> Just $
-        PackageBuildWarning $
-             quote ("license: " ++ l) ++ " is not a recognised license. The "
-          ++ "known licenses are: "
-          ++ commaSep (map prettyShow knownLicenses)
-      _ -> Nothing
-
-  , check (lic == BSD4) $
-      PackageDistSuspicious $
-           "Using 'license: BSD4' is almost always a misunderstanding. 'BSD4' "
-        ++ "refers to the old 4-clause BSD license with the advertising "
-        ++ "clause. 'BSD3' refers the new 3-clause BSD license."
-
-  , case unknownLicenseVersion (lic) of
-      Just knownVersions -> Just $
-        PackageDistSuspicious $
-             "'license: " ++ prettyShow (lic) ++ "' is not a known "
-          ++ "version of that license. The known versions are "
-          ++ commaSep (map prettyShow knownVersions)
-          ++ ". If this is not a mistake and you think it should be a known "
-          ++ "version then please file a ticket."
-      _ -> Nothing
-
-  , check (lic `notElem` [ AllRightsReserved
-                                 , UnspecifiedLicense, PublicDomain]
-           -- AllRightsReserved and PublicDomain are not strictly
-           -- licenses so don't need license files.
-        && null (licenseFiles pkg)) $
-      PackageDistSuspicious "A 'license-file' is not specified."
-  ]
-  where
-    unknownLicenseVersion (GPL  (Just v))
-      | v `notElem` knownVersions = Just knownVersions
-      where knownVersions = [ v' | GPL  (Just v') <- knownLicenses ]
-    unknownLicenseVersion (LGPL (Just v))
-      | v `notElem` knownVersions = Just knownVersions
-      where knownVersions = [ v' | LGPL (Just v') <- knownLicenses ]
-    unknownLicenseVersion (AGPL (Just v))
-      | v `notElem` knownVersions = Just knownVersions
-      where knownVersions = [ v' | AGPL (Just v') <- knownLicenses ]
-    unknownLicenseVersion (Apache  (Just v))
-      | v `notElem` knownVersions = Just knownVersions
-      where knownVersions = [ v' | Apache  (Just v') <- knownLicenses ]
-    unknownLicenseVersion _ = Nothing
-
-    checkVersion :: CabalSpecVersion -> Bool -> PackageCheck -> Maybe PackageCheck
-    checkVersion ver cond pc
-      | specVersion pkg >= ver  = Nothing
-      | otherwise               = check cond pc
-
-    compatLicenses = [ GPL Nothing, LGPL Nothing, AGPL Nothing, BSD3, BSD4
-                     , PublicDomain, AllRightsReserved
-                     , UnspecifiedLicense, OtherLicense ]
-
-checkSourceRepos :: PackageDescription -> [PackageCheck]
-checkSourceRepos pkg =
-  catMaybes $ concat [[
-
-    case repoKind repo of
-      RepoKindUnknown kind -> Just $ PackageDistInexcusable $
-        quote kind ++ " is not a recognised kind of source-repository. "
-                   ++ "The repo kind is usually 'head' or 'this'"
-      _ -> Nothing
-
-  , check (isNothing (repoType repo)) $
-      PackageDistInexcusable
-        "The source-repository 'type' is a required field."
-
-  , check (isNothing (repoLocation repo)) $
-      PackageDistInexcusable
-        "The source-repository 'location' is a required field."
-
-  , check (repoType repo == Just (KnownRepoType CVS) && isNothing (repoModule repo)) $
-      PackageDistInexcusable
-        "For a CVS source-repository, the 'module' is a required field."
-
-  , check (repoKind repo == RepoThis && isNothing (repoTag repo)) $
-      PackageDistInexcusable $
-           "For the 'this' kind of source-repository, the 'tag' is a required "
-        ++ "field. It should specify the tag corresponding to this version "
-        ++ "or release of the package."
-
-  , check (maybe False isAbsoluteOnAnyPlatform (repoSubdir repo)) $
-      PackageDistInexcusable
-        "The 'subdir' field of a source-repository must be a relative path."
-
-  , do
-      subdir <- repoSubdir repo
-      err    <- isGoodRelativeDirectoryPath subdir
-      return $ PackageDistInexcusable $
-        "The 'subdir' field of a source-repository is not a good relative path: " ++ show err
-  ]
-  | repo <- sourceRepos pkg ]
-
---TODO: check location looks like a URL for some repo types.
-
--- | Checks GHC options from all ghc-*-options fields in the given
--- PackageDescription and reports commonly misused or non-portable flags
-checkAllGhcOptions :: PackageDescription -> [PackageCheck]
-checkAllGhcOptions pkg =
-    checkGhcOptions "ghc-options" (hcOptions GHC) pkg
- ++ checkGhcOptions "ghc-prof-options" (hcProfOptions GHC) pkg
- ++ checkGhcOptions "ghc-shared-options" (hcSharedOptions GHC) pkg
-
--- | Extracts GHC options belonging to the given field from the given
--- PackageDescription using given function and checks them for commonly misused
--- or non-portable flags
-checkGhcOptions :: String -> (BuildInfo -> [String]) -> PackageDescription -> [PackageCheck]
-checkGhcOptions fieldName getOptions pkg =
-  catMaybes [
-
-    checkFlags ["-fasm"] $
-      PackageDistInexcusable $
-           "'" ++ fieldName ++ ": -fasm' is unnecessary and will not work on CPU "
-        ++ "architectures other than x86, x86-64, ppc or sparc."
-
-  , checkFlags ["-fvia-C"] $
-      PackageDistSuspicious $
-           "'" ++ fieldName ++": -fvia-C' is usually unnecessary. If your package "
-        ++ "needs -via-C for correctness rather than performance then it "
-        ++ "is using the FFI incorrectly and will probably not work with GHC "
-        ++ "6.10 or later."
-
-  , checkFlags ["-fhpc"] $
-      PackageDistInexcusable $
-           "'" ++ fieldName ++ ": -fhpc' is not necessary. Use the configure flag "
-        ++ " --enable-coverage instead."
-
-  , checkFlags ["-prof"] $
-      PackageBuildWarning $
-           "'" ++ fieldName ++ ": -prof' is not necessary and will lead to problems "
-        ++ "when used on a library. Use the configure flag "
-        ++ "--enable-library-profiling and/or --enable-profiling."
-
-  , checkFlags ["-o"] $
-      PackageBuildWarning $
-           "'" ++ fieldName ++ ": -o' is not needed. "
-        ++ "The output files are named automatically."
-
-  , checkFlags ["-hide-package"] $
-      PackageBuildWarning $
-      "'" ++ fieldName ++ ": -hide-package' is never needed. "
-      ++ "Cabal hides all packages."
-
-  , checkFlags ["--make"] $
-      PackageBuildWarning $
-      "'" ++ fieldName ++ ": --make' is never needed. Cabal uses this automatically."
-
-  , checkFlags ["-main-is"] $
-      PackageDistSuspicious $
-      "'" ++ fieldName ++ ": -main-is' is not portable."
-
-  , checkNonTestAndBenchmarkFlags ["-O0", "-Onot"] $
-      PackageDistSuspicious $
-      "'" ++ fieldName ++ ": -O0' is not needed. "
-      ++ "Use the --disable-optimization configure flag."
-
-  , checkTestAndBenchmarkFlags ["-O0", "-Onot"] $
-      PackageDistSuspiciousWarn $
-      "'" ++ fieldName ++ ": -O0' is not needed. "
-      ++ "Use the --disable-optimization configure flag."
-
-  , checkFlags [ "-O", "-O1"] $
-      PackageDistInexcusable $
-      "'" ++ fieldName ++ ": -O' is not needed. "
-      ++ "Cabal automatically adds the '-O' flag. "
-      ++ "Setting it yourself interferes with the --disable-optimization flag."
-
-  , checkFlags ["-O2"] $
-      PackageDistSuspiciousWarn $
-      "'" ++ fieldName ++ ": -O2' is rarely needed. "
-      ++ "Check that it is giving a real benefit "
-      ++ "and not just imposing longer compile times on your users."
-
-  , checkFlags ["-split-sections"] $
-      PackageBuildWarning $
-        "'" ++ fieldName ++ ": -split-sections' is not needed. "
-        ++ "Use the --enable-split-sections configure flag."
-
-  , checkFlags ["-split-objs"] $
-      PackageBuildWarning $
-        "'" ++ fieldName ++ ": -split-objs' is not needed. "
-        ++ "Use the --enable-split-objs configure flag."
-
-  , checkFlags ["-optl-Wl,-s", "-optl-s"] $
-      PackageDistInexcusable $
-           "'" ++ fieldName ++ ": -optl-Wl,-s' is not needed and is not portable to all"
-        ++ " operating systems. Cabal 1.4 and later automatically strip"
-        ++ " executables. Cabal also has a flag --disable-executable-stripping"
-        ++ " which is necessary when building packages for some Linux"
-        ++ " distributions and using '-optl-Wl,-s' prevents that from working."
-
-  , checkFlags ["-fglasgow-exts"] $
-      PackageDistSuspicious $
-        "Instead of '" ++ fieldName ++ ": -fglasgow-exts' it is preferable to use "
-        ++ "the 'extensions' field."
-
-  , check ("-threaded" `elem` lib_ghc_options) $
-      PackageBuildWarning $
-           "'" ++ fieldName ++ ": -threaded' has no effect for libraries. It should "
-        ++ "only be used for executables."
-
-  , check ("-rtsopts" `elem` lib_ghc_options) $
-      PackageBuildWarning $
-           "'" ++ fieldName ++ ": -rtsopts' has no effect for libraries. It should "
-        ++ "only be used for executables."
-
-  , check (any (\opt -> "-with-rtsopts" `isPrefixOf` opt) lib_ghc_options) $
-      PackageBuildWarning $
-           "'" ++ fieldName ++ ": -with-rtsopts' has no effect for libraries. It "
-        ++ "should only be used for executables."
-
-  , checkAlternatives fieldName "extensions"
-      [ (flag, prettyShow extension) | flag <- all_ghc_options
-                                  , Just extension <- [ghcExtension flag] ]
-
-  , checkAlternatives fieldName "extensions"
-      [ (flag, extension) | flag@('-':'X':extension) <- all_ghc_options ]
-
-  , checkAlternatives fieldName "cpp-options" $
-         [ (flag, flag) | flag@('-':'D':_) <- all_ghc_options ]
-      ++ [ (flag, flag) | flag@('-':'U':_) <- all_ghc_options ]
-
-  , checkAlternatives fieldName "include-dirs"
-      [ (flag, dir) | flag@('-':'I':dir) <- all_ghc_options ]
-
-  , checkAlternatives fieldName "extra-libraries"
-      [ (flag, lib) | flag@('-':'l':lib) <- all_ghc_options ]
-
-  , checkAlternatives fieldName "extra-libraries-static"
-      [ (flag, lib) | flag@('-':'l':lib) <- all_ghc_options ]
-
-  , checkAlternatives fieldName "extra-lib-dirs"
-      [ (flag, dir) | flag@('-':'L':dir) <- all_ghc_options ]
-
-  , checkAlternatives fieldName "extra-lib-dirs-static"
-      [ (flag, dir) | flag@('-':'L':dir) <- all_ghc_options ]
-
-  , checkAlternatives fieldName "frameworks"
-      [ (flag, fmwk) | (flag@"-framework", fmwk) <-
-           zip all_ghc_options (safeTail all_ghc_options) ]
-
-  , checkAlternatives fieldName "extra-framework-dirs"
-      [ (flag, dir) | (flag@"-framework-path", dir) <-
-           zip all_ghc_options (safeTail all_ghc_options) ]
-  ]
-
-  where
-    all_ghc_options    = concatMap getOptions (allBuildInfo pkg)
-    lib_ghc_options    = concatMap (getOptions . libBuildInfo)
-                         (allLibraries pkg)
-    test_ghc_options      = concatMap (getOptions . testBuildInfo)
-                            (testSuites pkg)
-    benchmark_ghc_options = concatMap (getOptions . benchmarkBuildInfo)
-                            (benchmarks pkg)
-    test_and_benchmark_ghc_options     = test_ghc_options ++
-                                         benchmark_ghc_options
-    non_test_and_benchmark_ghc_options = concatMap getOptions
-                                         (allBuildInfo (pkg { testSuites = []
-                                                            , benchmarks = []
-                                                            }))
-
-    checkFlags :: [String] -> PackageCheck -> Maybe PackageCheck
-    checkFlags flags = check (any (`elem` flags) all_ghc_options)
-
-    checkTestAndBenchmarkFlags :: [String] -> PackageCheck -> Maybe PackageCheck
-    checkTestAndBenchmarkFlags flags = check (any (`elem` flags) test_and_benchmark_ghc_options)
-
-    checkNonTestAndBenchmarkFlags :: [String] -> PackageCheck -> Maybe PackageCheck
-    checkNonTestAndBenchmarkFlags flags = check (any (`elem` flags) non_test_and_benchmark_ghc_options)
-
-    ghcExtension ('-':'f':name) = case name of
-      "allow-overlapping-instances"    -> enable  OverlappingInstances
-      "no-allow-overlapping-instances" -> disable OverlappingInstances
-      "th"                             -> enable  TemplateHaskell
-      "no-th"                          -> disable TemplateHaskell
-      "ffi"                            -> enable  ForeignFunctionInterface
-      "no-ffi"                         -> disable ForeignFunctionInterface
-      "fi"                             -> enable  ForeignFunctionInterface
-      "no-fi"                          -> disable ForeignFunctionInterface
-      "monomorphism-restriction"       -> enable  MonomorphismRestriction
-      "no-monomorphism-restriction"    -> disable MonomorphismRestriction
-      "mono-pat-binds"                 -> enable  MonoPatBinds
-      "no-mono-pat-binds"              -> disable MonoPatBinds
-      "allow-undecidable-instances"    -> enable  UndecidableInstances
-      "no-allow-undecidable-instances" -> disable UndecidableInstances
-      "allow-incoherent-instances"     -> enable  IncoherentInstances
-      "no-allow-incoherent-instances"  -> disable IncoherentInstances
-      "arrows"                         -> enable  Arrows
-      "no-arrows"                      -> disable Arrows
-      "generics"                       -> enable  Generics
-      "no-generics"                    -> disable Generics
-      "implicit-prelude"               -> enable  ImplicitPrelude
-      "no-implicit-prelude"            -> disable ImplicitPrelude
-      "implicit-params"                -> enable  ImplicitParams
-      "no-implicit-params"             -> disable ImplicitParams
-      "bang-patterns"                  -> enable  BangPatterns
-      "no-bang-patterns"               -> disable BangPatterns
-      "scoped-type-variables"          -> enable  ScopedTypeVariables
-      "no-scoped-type-variables"       -> disable ScopedTypeVariables
-      "extended-default-rules"         -> enable  ExtendedDefaultRules
-      "no-extended-default-rules"      -> disable ExtendedDefaultRules
-      _                                -> Nothing
-    ghcExtension "-cpp"             = enable CPP
-    ghcExtension _                  = Nothing
-
-    enable  e = Just (EnableExtension e)
-    disable e = Just (DisableExtension e)
-
-checkCCOptions :: PackageDescription -> [PackageCheck]
-checkCCOptions = checkCLikeOptions "C" "cc-options" ccOptions
-
-checkCxxOptions :: PackageDescription -> [PackageCheck]
-checkCxxOptions = checkCLikeOptions "C++" "cxx-options" cxxOptions
-
-checkCLikeOptions :: String -> String -> (BuildInfo -> [String]) -> PackageDescription -> [PackageCheck]
-checkCLikeOptions label prefix accessor pkg =
-  catMaybes [
-
-    checkAlternatives prefix "include-dirs"
-      [ (flag, dir) | flag@('-':'I':dir) <- all_cLikeOptions ]
-
-  , checkAlternatives prefix "extra-libraries"
-      [ (flag, lib) | flag@('-':'l':lib) <- all_cLikeOptions ]
-
-  , checkAlternatives prefix "extra-lib-dirs"
-      [ (flag, dir) | flag@('-':'L':dir) <- all_cLikeOptions ]
-
-  , checkAlternatives "ld-options" "extra-libraries"
-      [ (flag, lib) | flag@('-':'l':lib) <- all_ldOptions ]
-
-  , checkAlternatives "ld-options" "extra-lib-dirs"
-      [ (flag, dir) | flag@('-':'L':dir) <- all_ldOptions ]
-
-  , checkCCFlags [ "-O", "-Os", "-O0", "-O1", "-O2", "-O3" ] $
-      PackageDistSuspicious $
-           "'"++prefix++": -O[n]' is generally not needed. When building with "
-        ++ " optimisations Cabal automatically adds '-O2' for "++label++" code. "
-        ++ "Setting it yourself interferes with the --disable-optimization flag."
-  ]
-
-  where all_cLikeOptions = [ opts | bi <- allBuildInfo pkg
-                                  , opts <- accessor bi ]
-        all_ldOptions = [ opts | bi <- allBuildInfo pkg
-                               , opts <- ldOptions bi ]
-
-        checkCCFlags :: [String] -> PackageCheck -> Maybe PackageCheck
-        checkCCFlags flags = check (any (`elem` flags) all_cLikeOptions)
-
-checkCPPOptions :: PackageDescription -> [PackageCheck]
-checkCPPOptions pkg = catMaybes
-    [ checkAlternatives "cpp-options" "include-dirs"
-      [ (flag, dir) | flag@('-':'I':dir) <- all_cppOptions ]
-    ]
-    ++
-    [ PackageBuildWarning $ "'cpp-options: " ++ opt ++ "' is not a portable C-preprocessor flag."
-    | opt <- all_cppOptions
-    -- "-I" is handled above, we allow only -DNEWSTUFF and -UOLDSTUFF
-    , not $ any (`isPrefixOf` opt) ["-D", "-U", "-I" ]
-    ]
-  where
-    all_cppOptions = [ opts | bi <- allBuildInfo pkg, opts <- cppOptions bi ]
-
-checkAlternatives :: String -> String -> [(String, String)]
-                  -> Maybe PackageCheck
-checkAlternatives badField goodField flags =
-  check (not (null badFlags)) $
-    PackageBuildWarning $
-         "Instead of " ++ quote (badField ++ ": " ++ unwords badFlags)
-      ++ " use " ++ quote (goodField ++ ": " ++ unwords goodFlags)
-
-  where (badFlags, goodFlags) = unzip flags
-
-data PathKind
-    = PathKindFile
-    | PathKindDirectory
-    | PathKindGlob
-  deriving (Eq)
-
-checkPaths :: PackageDescription -> [PackageCheck]
-checkPaths pkg =
-  checkPackageFileNamesWithGlob
-  [ (kind == PathKindGlob, path)
-  | (path, _, kind) <- relPaths ++ absPaths
-  ]
-  ++
-  [ PackageBuildWarning $
-         quote (field ++ ": " ++ path)
-      ++ " is a relative path outside of the source tree. "
-      ++ "This will not work when generating a tarball with 'sdist'."
-  | (path, field, _) <- relPaths ++ absPaths
-  , isOutsideTree path ]
-  ++
-  [ PackageDistInexcusable $
-         quote (field ++ ": " ++ path) ++ " specifies an absolute path, but the "
-      ++ quote field ++ " field must use relative paths."
-  | (path, field, _) <- relPaths
-  , isAbsoluteOnAnyPlatform path ]
-  ++
-  [ PackageDistInexcusable $
-      quote (field ++ ": " ++ path) ++ " is not a good relative path: " ++ show err
-  | (path, field, kind) <- relPaths
-  -- these are not paths, but globs...
-  , err <- maybeToList $ case kind of
-      PathKindFile      -> isGoodRelativeFilePath path
-      PathKindGlob      -> isGoodRelativeGlob path
-      PathKindDirectory -> isGoodRelativeDirectoryPath path
-  ]
-  ++
-  [ PackageDistInexcusable $
-         quote (field ++ ": " ++ path) ++ " points inside the 'dist' "
-      ++ "directory. This is not reliable because the location of this "
-      ++ "directory is configurable by the user (or package manager). In "
-      ++ "addition the layout of the 'dist' directory is subject to change "
-      ++ "in future versions of Cabal."
-  | (path, field, _) <- relPaths ++ absPaths
-  , isInsideDist path ]
-  ++
-  [ PackageDistInexcusable $
-         "The 'ghc-options' contain the path '" ++ path ++ "' which points "
-      ++ "inside the 'dist' directory. This is not reliable because the "
-      ++ "location of this directory is configurable by the user (or package "
-      ++ "manager). In addition the layout of the 'dist' directory is subject "
-      ++ "to change in future versions of Cabal."
-  | bi <- allBuildInfo pkg
-  , (GHC, flags) <- perCompilerFlavorToList $ options bi
-  , path <- flags
-  , isInsideDist path ]
-  ++
-  [ PackageDistInexcusable $
-        "In the 'data-files' field: " ++ explainGlobSyntaxError pat err
-  | pat <- dataFiles pkg
-  , Left err <- [parseFileGlob (specVersion pkg) pat]
-  ]
-  ++
-  [ PackageDistInexcusable $
-        "In the 'extra-source-files' field: " ++ explainGlobSyntaxError pat err
-  | pat <- extraSrcFiles pkg
-  , Left err <- [parseFileGlob (specVersion pkg) pat]
-  ]
-  ++
-  [ PackageDistInexcusable $
-        "In the 'extra-doc-files' field: " ++ explainGlobSyntaxError pat err
-  | pat <- extraDocFiles pkg
-  , Left err <- [parseFileGlob (specVersion pkg) pat]
-  ]
-  where
-    isOutsideTree path = case splitDirectories path of
-      "..":_     -> True
-      ".":"..":_ -> True
-      _          -> False
-    isInsideDist path = case map lowercase (splitDirectories path) of
-      "dist"    :_ -> True
-      ".":"dist":_ -> True
-      _            -> False
-
-    -- paths that must be relative
-    relPaths :: [(FilePath, String, PathKind)]
-    relPaths =
-      [ (path, "extra-source-files", PathKindGlob)      | path <- extraSrcFiles pkg ] ++
-      [ (path, "extra-tmp-files",    PathKindFile)      | path <- extraTmpFiles pkg ] ++
-      [ (path, "extra-doc-files",    PathKindGlob)      | path <- extraDocFiles pkg ] ++
-      [ (path, "data-files",         PathKindGlob)      | path <- dataFiles     pkg ] ++
-      [ (path, "data-dir",           PathKindDirectory) | path <- [dataDir      pkg]] ++
-      [ (path, "license-file",       PathKindFile)      | path <- map getSymbolicPath $ licenseFiles  pkg ] ++
-      concat
-        [ [ (path, "asm-sources",      PathKindFile)      | path <- asmSources      bi ] ++
-          [ (path, "cmm-sources",      PathKindFile)      | path <- cmmSources      bi ] ++
-          [ (path, "c-sources",        PathKindFile)      | path <- cSources        bi ] ++
-          [ (path, "cxx-sources",      PathKindFile)      | path <- cxxSources      bi ] ++
-          [ (path, "js-sources",       PathKindFile)      | path <- jsSources       bi ] ++
-          [ (path, "install-includes", PathKindFile)      | path <- installIncludes bi ] ++
-          [ (path, "hs-source-dirs",   PathKindDirectory) | path <- map getSymbolicPath $ hsSourceDirs bi ]
-        | bi <- allBuildInfo pkg
-        ]
-
-    -- paths that are allowed to be absolute
-    absPaths :: [(FilePath, String, PathKind)]
-    absPaths = concat
-      [ [ (path, "includes",       PathKindFile)      | path <- includes     bi ] ++
-        [ (path, "include-dirs",   PathKindDirectory) | path <- includeDirs  bi ] ++
-        [ (path, "extra-lib-dirs", PathKindDirectory) | path <- extraLibDirs bi ] ++
-        [ (path, "extra-lib-dirs-static", PathKindDirectory) | path <- extraLibDirsStatic bi ]
-      | bi <- allBuildInfo pkg
-      ]
-
---TODO: check sets of paths that would be interpreted differently between Unix
--- and windows, ie case-sensitive or insensitive. Things that might clash, or
--- conversely be distinguished.
-
---TODO: use the tar path checks on all the above paths
-
--- | Check that the package declares the version in the @\"cabal-version\"@
--- field correctly.
---
-checkCabalVersion :: PackageDescription -> [PackageCheck]
-checkCabalVersion pkg =
-  catMaybes [
-
-    -- check use of test suite sections
-    checkVersion CabalSpecV1_8 (not (null $ testSuites pkg)) $
-      PackageDistInexcusable $
-           "The 'test-suite' section is new in Cabal 1.10. "
-        ++ "Unfortunately it messes up the parser in older Cabal versions "
-        ++ "so you must specify at least 'cabal-version: >= 1.8', but note "
-        ++ "that only Cabal 1.10 and later can actually run such test suites."
-
-    -- check use of default-language field
-    -- note that we do not need to do an equivalent check for the
-    -- other-language field since that one does not change behaviour
-  , checkVersion CabalSpecV1_10 (any isJust (buildInfoField defaultLanguage)) $
-      PackageBuildWarning $
-           "To use the 'default-language' field the package needs to specify "
-        ++ "at least 'cabal-version: >= 1.10'."
-
-  , check (specVersion pkg >= CabalSpecV1_10 && specVersion pkg < CabalSpecV3_4
-           && (any isNothing (buildInfoField defaultLanguage))) $
-      PackageBuildWarning $
-           "Packages using 'cabal-version: >= 1.10' and before 'cabal-version: 3.4' must specify the "
-        ++ "'default-language' field for each component (e.g. Haskell98 or "
-        ++ "Haskell2010). If a component uses different languages in "
-        ++ "different modules then list the other ones in the "
-        ++ "'other-languages' field."
-
-  , checkVersion CabalSpecV1_18
-    (not . null $ extraDocFiles pkg) $
-      PackageDistInexcusable $
-           "To use the 'extra-doc-files' field the package needs to specify "
-        ++ "'cabal-version: 1.18' or higher."
-
-  , checkVersion CabalSpecV2_0
-    (not (null (subLibraries pkg))) $
-      PackageDistInexcusable $
-           "To use multiple 'library' sections or a named library section "
-        ++ "the package needs to specify at least 'cabal-version: 2.0'."
-
-    -- check use of reexported-modules sections
-  , checkVersion CabalSpecV1_22
-    (any (not.null.reexportedModules) (allLibraries pkg)) $
-      PackageDistInexcusable $
-           "To use the 'reexported-module' field the package needs to specify "
-        ++ "'cabal-version: 1.22' or higher."
-
-    -- check use of thinning and renaming
-  , checkVersion CabalSpecV2_0 usesBackpackIncludes $
-      PackageDistInexcusable $
-           "To use the 'mixins' field the package needs to specify "
-        ++ "at least 'cabal-version: 2.0'."
-
-    -- check use of 'extra-framework-dirs' field
-  , checkVersion CabalSpecV1_24 (any (not . null) (buildInfoField extraFrameworkDirs)) $
-      -- Just a warning, because this won't break on old Cabal versions.
-      PackageDistSuspiciousWarn $
-           "To use the 'extra-framework-dirs' field the package needs to specify"
-        ++ " 'cabal-version: 1.24' or higher."
-
-    -- check use of default-extensions field
-    -- don't need to do the equivalent check for other-extensions
-  , checkVersion CabalSpecV1_10 (any (not . null) (buildInfoField defaultExtensions)) $
-      PackageBuildWarning $
-           "To use the 'default-extensions' field the package needs to specify "
-        ++ "at least 'cabal-version: >= 1.10'."
-
-    -- check use of extensions field
-  , check (specVersion pkg >= CabalSpecV1_10
-           && (any (not . null) (buildInfoField oldExtensions))) $
-      PackageBuildWarning $
-           "For packages using 'cabal-version: >= 1.10' the 'extensions' "
-        ++ "field is deprecated. The new 'default-extensions' field lists "
-        ++ "extensions that are used in all modules in the component, while "
-        ++ "the 'other-extensions' field lists extensions that are used in "
-        ++ "some modules, e.g. via the {-# LANGUAGE #-} pragma."
-
-  , checkVersion CabalSpecV3_0 (any (not . null)
-                        (concatMap buildInfoField
-                         [ asmSources
-                         , cmmSources
-                         , extraBundledLibs
-                         , extraLibFlavours ])) $
-      PackageDistInexcusable $
-           "The use of 'asm-sources', 'cmm-sources', 'extra-bundled-libraries' "
-        ++ " and 'extra-library-flavours' requires the package "
-        ++ " to specify at least 'cabal-version: 3.0'."
-
-  , checkVersion CabalSpecV3_0 (any (not . null) $ buildInfoField extraDynLibFlavours) $
-      PackageDistInexcusable $
-           "The use of 'extra-dynamic-library-flavours' requires the package "
-        ++ " to specify at least 'cabal-version: 3.0'. The flavours are: "
-        ++ commaSep [ flav
-                    | flavs <- buildInfoField extraDynLibFlavours
-                    , flav <- flavs ]
-
-  , checkVersion CabalSpecV2_2 (any (not . null)
-                        (buildInfoField virtualModules)) $
-      PackageDistInexcusable $
-           "The use of 'virtual-modules' requires the package "
-        ++ " to specify at least 'cabal-version: 2.2'."
-
-    -- check use of "source-repository" section
-  , checkVersion CabalSpecV1_6 (not (null (sourceRepos pkg))) $
-      PackageDistInexcusable $
-           "The 'source-repository' section is new in Cabal 1.6. "
-        ++ "Unfortunately it messes up the parser in earlier Cabal versions "
-        ++ "so you need to specify 'cabal-version: >= 1.6'."
-
-    -- check for new language extensions
-  , checkVersion CabalSpecV1_2 (not (null mentionedExtensionsThatNeedCabal12)) $
-      PackageDistInexcusable $
-           "Unfortunately the language extensions "
-        ++ commaSep (map (quote . prettyShow) mentionedExtensionsThatNeedCabal12)
-        ++ " break the parser in earlier Cabal versions so you need to "
-        ++ "specify 'cabal-version: >= 1.2'. Alternatively if you require "
-        ++ "compatibility with earlier Cabal versions then you may be able to "
-        ++ "use an equivalent compiler-specific flag."
-
-  , checkVersion CabalSpecV1_4 (not (null mentionedExtensionsThatNeedCabal14)) $
-      PackageDistInexcusable $
-           "Unfortunately the language extensions "
-        ++ commaSep (map (quote . prettyShow) mentionedExtensionsThatNeedCabal14)
-        ++ " break the parser in earlier Cabal versions so you need to "
-        ++ "specify 'cabal-version: >= 1.4'. Alternatively if you require "
-        ++ "compatibility with earlier Cabal versions then you may be able to "
-        ++ "use an equivalent compiler-specific flag."
-
-  , check (specVersion pkg >= CabalSpecV1_24
-           && isNothing (setupBuildInfo pkg)
-           && buildType pkg == Custom) $
-      PackageBuildWarning $
-           "Packages using 'cabal-version: 1.24' or higher with 'build-type: Custom' "
-        ++ "must use a 'custom-setup' section with a 'setup-depends' field "
-        ++ "that specifies the dependencies of the Setup.hs script itself. "
-        ++ "The 'setup-depends' field uses the same syntax as 'build-depends', "
-        ++ "so a simple example would be 'setup-depends: base, Cabal'."
-
-  , check (specVersion pkg < CabalSpecV1_24
-           && isNothing (setupBuildInfo pkg)
-           && buildType pkg == Custom) $
-      PackageDistSuspiciousWarn $
-           "From version 1.24 cabal supports specifying explicit dependencies "
-        ++ "for Custom setup scripts. Consider using 'cabal-version: 1.24' or higher "
-        ++ "and adding a 'custom-setup' section with a 'setup-depends' field "
-        ++ "that specifies the dependencies of the Setup.hs script itself. "
-        ++ "The 'setup-depends' field uses the same syntax as 'build-depends', "
-        ++ "so a simple example would be 'setup-depends: base, Cabal'."
-
-  , check (specVersion pkg >= CabalSpecV2_0
-           && elem (autogenPathsModuleName pkg) allModuleNames
-           && not (elem (autogenPathsModuleName pkg) allModuleNamesAutogen) ) $
-      PackageDistInexcusable $
-           "Packages using 'cabal-version: 2.0' and the autogenerated "
-        ++ "module Paths_* must include it also on the 'autogen-modules' field "
-        ++ "besides 'exposed-modules' and 'other-modules'. This specifies that "
-        ++ "the module does not come with the package and is generated on "
-        ++ "setup. Modules built with a custom Setup.hs script also go here "
-        ++ "to ensure that commands like sdist don't fail."
-
-  ]
-  where
-    -- Perform a check on packages that use a version of the spec less than
-    -- the version given. This is for cases where a new Cabal version adds
-    -- a new feature and we want to check that it is not used prior to that
-    -- version.
-    checkVersion :: CabalSpecVersion -> Bool -> PackageCheck -> Maybe PackageCheck
-    checkVersion ver cond pc
-      | specVersion pkg >= ver = Nothing
-      | otherwise              = check cond pc
-
-    buildInfoField field         = map field (allBuildInfo pkg)
-
-    usesBackpackIncludes = any (not . null . mixins) (allBuildInfo pkg)
-
-    mentionedExtensions = [ ext | bi <- allBuildInfo pkg
-                                , ext <- allExtensions bi ]
-    mentionedExtensionsThatNeedCabal12 =
-      nub (filter (`elem` compatExtensionsExtra) mentionedExtensions)
-
-    -- As of Cabal-1.4 we can add new extensions without worrying about
-    -- breaking old versions of cabal.
-    mentionedExtensionsThatNeedCabal14 =
-      nub (filter (`notElem` compatExtensions) mentionedExtensions)
-
-    -- The known extensions in Cabal-1.2.3
-    compatExtensions =
-      map EnableExtension
-      [ OverlappingInstances, UndecidableInstances, IncoherentInstances
-      , RecursiveDo, ParallelListComp, MultiParamTypeClasses
-      , FunctionalDependencies, Rank2Types
-      , RankNTypes, PolymorphicComponents, ExistentialQuantification
-      , ScopedTypeVariables, ImplicitParams, FlexibleContexts
-      , FlexibleInstances, EmptyDataDecls, CPP, BangPatterns
-      , TypeSynonymInstances, TemplateHaskell, ForeignFunctionInterface
-      , Arrows, Generics, NamedFieldPuns, PatternGuards
-      , GeneralizedNewtypeDeriving, ExtensibleRecords, RestrictedTypeSynonyms
-      , HereDocuments] ++
-      map DisableExtension
-      [MonomorphismRestriction, ImplicitPrelude] ++
-      compatExtensionsExtra
-
-    -- The extra known extensions in Cabal-1.2.3 vs Cabal-1.1.6
-    -- (Cabal-1.1.6 came with ghc-6.6. Cabal-1.2 came with ghc-6.8)
-    compatExtensionsExtra =
-      map EnableExtension
-      [ KindSignatures, MagicHash, TypeFamilies, StandaloneDeriving
-      , UnicodeSyntax, PatternSignatures, UnliftedFFITypes, LiberalTypeSynonyms
-      , TypeOperators, RecordWildCards, RecordPuns, DisambiguateRecordFields
-      , OverloadedStrings, GADTs, RelaxedPolyRec
-      , ExtendedDefaultRules, UnboxedTuples, DeriveDataTypeable
-      , ConstrainedClassMethods
-      ] ++
-      map DisableExtension
-      [MonoPatBinds]
-
-    allModuleNames =
-         (case library pkg of
-           Nothing -> []
-           (Just lib) -> explicitLibModules lib
-         )
-      ++ concatMap otherModules (allBuildInfo pkg)
-
-    allModuleNamesAutogen = concatMap autogenModules (allBuildInfo pkg)
-
--- ------------------------------------------------------------
--- * Checks on the GenericPackageDescription
--- ------------------------------------------------------------
-
--- | Check the build-depends fields for any weirdness or bad practice.
---
-checkPackageVersions :: GenericPackageDescription -> [PackageCheck]
-checkPackageVersions pkg =
-  catMaybes [
-
-    -- Check that the version of base is bounded above.
-    -- For example this bans "build-depends: base >= 3".
-    -- It should probably be "build-depends: base >= 3 && < 4"
-    -- which is the same as  "build-depends: base == 3.*"
-    check (not (hasUpperBound baseDependency)) $
-      PackageDistInexcusable $
-           "The dependency 'build-depends: base' does not specify an upper "
-        ++ "bound on the version number. Each major release of the 'base' "
-        ++ "package changes the API in various ways and most packages will "
-        ++ "need some changes to compile with it. The recommended practice "
-        ++ "is to specify an upper bound on the version of the 'base' "
-        ++ "package. This ensures your package will continue to build when a "
-        ++ "new major version of the 'base' package is released. If you are "
-        ++ "not sure what upper bound to use then use the next  major "
-        ++ "version. For example if you have tested your package with 'base' "
-        ++ "version 4.5 and 4.6 then use 'build-depends: base >= 4.5 && < 4.7'."
-
-  ]
-  where
-    baseDependency = case typicalPkg pkg of
-      Right (pkg', _) | not (null baseDeps) ->
-          foldr intersectVersionRanges anyVersion baseDeps
-        where
-          baseDeps =
-            [ vr | Dependency pname vr _ <- allBuildDepends pkg'
-                 , pname == mkPackageName "base" ]
-
-      -- Just in case finalizePD fails for any reason,
-      -- or if the package doesn't depend on the base package at all,
-      -- then we will just skip the check, since hasUpperBound noVersion = True
-      _          -> noVersion
-
-checkConditionals :: GenericPackageDescription -> [PackageCheck]
-checkConditionals pkg =
-  catMaybes [
-
-    check (not $ null unknownOSs) $
-      PackageDistInexcusable $
-           "Unknown operating system name "
-        ++ commaSep (map quote unknownOSs)
-
-  , check (not $ null unknownArches) $
-      PackageDistInexcusable $
-           "Unknown architecture name "
-        ++ commaSep (map quote unknownArches)
-
-  , check (not $ null unknownImpls) $
-      PackageDistInexcusable $
-           "Unknown compiler name "
-        ++ commaSep (map quote unknownImpls)
-  ]
-  where
-    unknownOSs    = [ os   | OS   (OtherOS os)           <- conditions ]
-    unknownArches = [ arch | Arch (OtherArch arch)       <- conditions ]
-    unknownImpls  = [ impl | Impl (OtherCompiler impl) _ <- conditions ]
-    conditions = concatMap fvs (maybeToList (condLibrary pkg))
-              ++ concatMap (fvs . snd) (condSubLibraries pkg)
-              ++ concatMap (fvs . snd) (condForeignLibs pkg)
-              ++ concatMap (fvs . snd) (condExecutables pkg)
-              ++ concatMap (fvs . snd) (condTestSuites pkg)
-              ++ concatMap (fvs . snd) (condBenchmarks pkg)
-    fvs (CondNode _ _ ifs) = concatMap compfv ifs -- free variables
-    compfv (CondBranch c ct mct) = condfv c ++ fvs ct ++ maybe [] fvs mct
-    condfv c = case c of
-      Var v      -> [v]
-      Lit _      -> []
-      CNot c1    -> condfv c1
-      COr  c1 c2 -> condfv c1 ++ condfv c2
-      CAnd c1 c2 -> condfv c1 ++ condfv c2
-
-checkFlagNames :: GenericPackageDescription -> [PackageCheck]
-checkFlagNames gpd
-    | null invalidFlagNames = []
-    | otherwise             = [ PackageDistInexcusable
-        $ "Suspicious flag names: " ++ unwords invalidFlagNames ++ ". "
-        ++ "To avoid ambiguity in command line interfaces, flag shouldn't "
-        ++ "start with a dash. Also for better compatibility, flag names "
-        ++ "shouldn't contain non-ascii characters."
-        ]
-  where
-    invalidFlagNames =
-        [ fn
-        | flag <- genPackageFlags gpd
-        , let fn = unFlagName (flagName flag)
-        , invalidFlagName fn
-        ]
-    -- starts with dash
-    invalidFlagName ('-':_) = True
-    -- mon ascii letter
-    invalidFlagName cs = any (not . isAscii) cs
-
-checkUnusedFlags :: GenericPackageDescription -> [PackageCheck]
-checkUnusedFlags gpd
-    | declared == used = []
-    | otherwise        = [ PackageDistSuspicious
-        $ "Declared and used flag sets differ: "
-        ++ s declared ++ " /= " ++ s used ++ ". "
-        ]
-  where
-    s :: Set.Set FlagName -> String
-    s = commaSep . map unFlagName . Set.toList
-
-    declared :: Set.Set FlagName
-    declared = toSetOf (L.genPackageFlags . traverse . L.flagName) gpd
-
-    used :: Set.Set FlagName
-    used = mconcat
-        [ toSetOf (L.condLibrary      . traverse      . traverseCondTreeV . L._PackageFlag) gpd
-        , toSetOf (L.condSubLibraries . traverse . _2 . traverseCondTreeV . L._PackageFlag) gpd
-        , toSetOf (L.condForeignLibs  . traverse . _2 . traverseCondTreeV . L._PackageFlag) gpd
-        , toSetOf (L.condExecutables  . traverse . _2 . traverseCondTreeV . L._PackageFlag) gpd
-        , toSetOf (L.condTestSuites   . traverse . _2 . traverseCondTreeV . L._PackageFlag) gpd
-        , toSetOf (L.condBenchmarks   . traverse . _2 . traverseCondTreeV . L._PackageFlag) gpd
-        ]
-
-checkUnicodeXFields :: GenericPackageDescription -> [PackageCheck]
-checkUnicodeXFields gpd
-    | null nonAsciiXFields = []
-    | otherwise            = [ PackageDistInexcusable
-        $ "Non ascii custom fields: " ++ unwords nonAsciiXFields ++ ". "
-        ++ "For better compatibility, custom field names "
-        ++ "shouldn't contain non-ascii characters."
-        ]
-  where
-    nonAsciiXFields :: [String]
-    nonAsciiXFields = [ n | (n, _) <- xfields, any (not . isAscii) n ]
-
-    xfields :: [(String,String)]
-    xfields = DList.runDList $ mconcat
-        [ toDListOf (L.packageDescription . L.customFieldsPD . traverse) gpd
-        , toDListOf (L.traverseBuildInfos . L.customFieldsBI . traverse) gpd
-        ]
-
--- | cabal-version <2.2 + Paths_module + default-extensions: doesn't build.
-checkPathsModuleExtensions :: PackageDescription -> [PackageCheck]
-checkPathsModuleExtensions pd
-    | specVersion pd >= CabalSpecV2_2 = []
-    | any checkBI (allBuildInfo pd) || any checkLib (allLibraries pd)
-        = return $ PackageBuildImpossible $ unwords
-            [ "Packages using RebindableSyntax with OverloadedStrings or"
-            , "OverloadedLists in default-extensions, in conjunction with the"
-            , "autogenerated module Paths_*, are known to cause compile failures"
-            , "with Cabal < 2.2. To use these default-extensions with a Paths_*"
-            , "autogen module, specify at least 'cabal-version: 2.2'."
-            ]
-    | otherwise = []
-  where
-    mn = autogenPathsModuleName pd
-
-    checkLib :: Library -> Bool
-    checkLib l = mn `elem` exposedModules l && checkExts (l ^. L.defaultExtensions)
-
-    checkBI :: BuildInfo -> Bool
-    checkBI bi =
-        (mn `elem` otherModules bi || mn `elem` autogenModules bi) &&
-        checkExts (bi ^. L.defaultExtensions)
-
-    checkExts exts = rebind `elem` exts && (strings `elem` exts || lists `elem` exts)
-      where
-        rebind  = EnableExtension RebindableSyntax
-        strings = EnableExtension OverloadedStrings
-        lists   = EnableExtension OverloadedLists
-
--- | Checks GHC options from all ghc-*-options fields from the given BuildInfo
--- and reports flags that are OK during development process, but are
--- unacceptable in a distributed package
-checkDevelopmentOnlyFlagsBuildInfo :: BuildInfo -> [PackageCheck]
-checkDevelopmentOnlyFlagsBuildInfo bi =
-    checkDevelopmentOnlyFlagsOptions "ghc-options" (hcOptions GHC bi)
- ++ checkDevelopmentOnlyFlagsOptions "ghc-prof-options" (hcProfOptions GHC bi)
- ++ checkDevelopmentOnlyFlagsOptions "ghc-shared-options" (hcSharedOptions GHC bi)
-
--- | Checks the given list of flags belonging to the given field and reports
--- flags that are OK during development process, but are unacceptable in a
--- distributed package
-checkDevelopmentOnlyFlagsOptions :: String -> [String] -> [PackageCheck]
-checkDevelopmentOnlyFlagsOptions fieldName ghcOptions =
-  catMaybes [
-
-    check has_WerrorWall $
-      PackageDistInexcusable $
-           "'" ++ fieldName ++ ": -Wall -Werror' makes the package very easy to "
-        ++ "break with future GHC versions because new GHC versions often "
-        ++ "add new warnings. Use just '" ++ fieldName ++ ": -Wall' instead."
-        ++ extraExplanation
-
-  , check (not has_WerrorWall && has_Werror) $
-      PackageDistInexcusable $
-           "'" ++ fieldName ++ ": -Werror' makes the package easy to "
-        ++ "break with future GHC versions because new GHC versions often "
-        ++ "add new warnings."
-        ++ extraExplanation
-
-  , check (has_J) $
-      PackageDistInexcusable $
-           "'" ++ fieldName ++ ": -j[N]' can make sense for specific user's setup,"
-        ++ " but it is not appropriate for a distributed package."
-        ++ extraExplanation
-
-  , checkFlags ["-fdefer-type-errors"] $
-      PackageDistInexcusable $
-           "'" ++ fieldName ++ ": -fdefer-type-errors' is fine during development but "
-        ++ "is not appropriate for a distributed package."
-        ++ extraExplanation
-
-    -- -dynamic is not a debug flag
-  , check (any (\opt -> "-d" `isPrefixOf` opt && opt /= "-dynamic")
-           ghcOptions) $
-      PackageDistInexcusable $
-           "'" ++ fieldName ++ ": -d*' debug flags are not appropriate "
-        ++ "for a distributed package."
-        ++ extraExplanation
-
-  , checkFlags ["-fprof-auto", "-fprof-auto-top", "-fprof-auto-calls",
-               "-fprof-cafs", "-fno-prof-count-entries",
-               "-auto-all", "-auto", "-caf-all"] $
-      PackageDistSuspicious $
-           "'" ++ fieldName ++ ": -fprof*' profiling flags are typically not "
-        ++ "appropriate for a distributed library package. These flags are "
-        ++ "useful to profile this package, but when profiling other packages "
-        ++ "that use this one these flags clutter the profile output with "
-        ++ "excessive detail. If you think other packages really want to see "
-        ++ "cost centres from this package then use '-fprof-auto-exported' "
-        ++ "which puts cost centres only on exported functions."
-        ++ extraExplanation
-  ]
-  where
-    extraExplanation =
-         " Alternatively, if you want to use this, make it conditional based "
-      ++ "on a Cabal configuration flag (with 'manual: True' and 'default: "
-      ++ "False') and enable that flag during development."
-
-    has_WerrorWall   = has_Werror && ( has_Wall || has_W )
-    has_Werror       = "-Werror" `elem` ghcOptions
-    has_Wall         = "-Wall"   `elem` ghcOptions
-    has_W            = "-W"      `elem` ghcOptions
-    has_J            = any
-                         (\o -> case o of
-                           "-j"                -> True
-                           ('-' : 'j' : d : _) -> isDigit d
-                           _                   -> False
-                         )
-                         ghcOptions
-    checkFlags :: [String] -> PackageCheck -> Maybe PackageCheck
-    checkFlags flags = check (any (`elem` flags) ghcOptions)
-
-checkDevelopmentOnlyFlags :: GenericPackageDescription -> [PackageCheck]
-checkDevelopmentOnlyFlags pkg =
-    concatMap checkDevelopmentOnlyFlagsBuildInfo
-              [ bi
-              | (conditions, bi) <- allConditionalBuildInfo
-              , not (any guardedByManualFlag conditions) ]
-  where
-    guardedByManualFlag = definitelyFalse
-
-    -- We've basically got three-values logic here: True, False or unknown
-    -- hence this pattern to propagate the unknown cases properly.
-    definitelyFalse (Var (PackageFlag n)) = maybe False not (Map.lookup n manualFlags)
-    definitelyFalse (Var _)        = False
-    definitelyFalse (Lit  b)       = not b
-    definitelyFalse (CNot c)       = definitelyTrue c
-    definitelyFalse (COr  c1 c2)   = definitelyFalse c1 && definitelyFalse c2
-    definitelyFalse (CAnd c1 c2)   = definitelyFalse c1 || definitelyFalse c2
-
-    definitelyTrue (Var (PackageFlag n)) = fromMaybe False (Map.lookup n manualFlags)
-    definitelyTrue (Var _)        = False
-    definitelyTrue (Lit  b)       = b
-    definitelyTrue (CNot c)       = definitelyFalse c
-    definitelyTrue (COr  c1 c2)   = definitelyTrue c1 || definitelyTrue c2
-    definitelyTrue (CAnd c1 c2)   = definitelyTrue c1 && definitelyTrue c2
-
-    manualFlags = Map.fromList
-                    [ (flagName flag, flagDefault flag)
-                    | flag <- genPackageFlags pkg
-                    , flagManual flag ]
-
-    allConditionalBuildInfo :: [([Condition ConfVar], BuildInfo)]
-    allConditionalBuildInfo =
-        concatMap (collectCondTreePaths libBuildInfo)
-                  (maybeToList (condLibrary pkg))
-
-     ++ concatMap (collectCondTreePaths libBuildInfo . snd)
-                  (condSubLibraries pkg)
-
-     ++ concatMap (collectCondTreePaths buildInfo . snd)
-                  (condExecutables pkg)
-
-     ++ concatMap (collectCondTreePaths testBuildInfo . snd)
-                  (condTestSuites pkg)
-
-     ++ concatMap (collectCondTreePaths benchmarkBuildInfo . snd)
-                  (condBenchmarks pkg)
-
-    -- get all the leaf BuildInfo, paired up with the path (in the tree sense)
-    -- of if-conditions that guard it
-    collectCondTreePaths :: (a -> b)
-                         -> CondTree v c a
-                         -> [([Condition v], b)]
-    collectCondTreePaths mapData = go []
-      where
-        go conditions condNode =
-            -- the data at this level in the tree:
-            (reverse conditions, mapData (condTreeData condNode))
-
-          : concat
-            [ go (condition:conditions) ifThen
-            | (CondBranch condition ifThen _) <- condTreeComponents condNode ]
-
-         ++ concat
-            [ go (condition:conditions) elseThen
-            | (CondBranch condition _ (Just elseThen)) <- condTreeComponents condNode ]
-
-
--- ------------------------------------------------------------
--- * Checks involving files in the package
--- ------------------------------------------------------------
-
--- | Sanity check things that requires IO. It looks at the files in the
--- package and expects to find the package unpacked in at the given file path.
---
-checkPackageFiles :: Verbosity -> PackageDescription -> FilePath -> IO [PackageCheck]
-checkPackageFiles verbosity pkg root = do
-  contentChecks <- checkPackageContent checkFilesIO pkg
-  preDistributionChecks <- checkPackageFilesPreDistribution verbosity pkg root
-  -- Sort because different platforms will provide files from
-  -- `getDirectoryContents` in different orders, and we'd like to be
-  -- stable for test output.
-  return (sort contentChecks ++ sort preDistributionChecks)
-  where
-    checkFilesIO = CheckPackageContentOps {
-      doesFileExist        = System.doesFileExist                  . relative,
-      doesDirectoryExist   = System.doesDirectoryExist             . relative,
-      getDirectoryContents = System.Directory.getDirectoryContents . relative,
-      getFileContents      = BS.readFile                           . relative
-    }
-    relative path = root </> path
-
--- | A record of operations needed to check the contents of packages.
--- Used by 'checkPackageContent'.
---
-data CheckPackageContentOps m = CheckPackageContentOps {
-    doesFileExist        :: FilePath -> m Bool,
-    doesDirectoryExist   :: FilePath -> m Bool,
-    getDirectoryContents :: FilePath -> m [FilePath],
-    getFileContents      :: FilePath -> m BS.ByteString
-  }
-
--- | Sanity check things that requires looking at files in the package.
--- This is a generalised version of 'checkPackageFiles' that can work in any
--- monad for which you can provide 'CheckPackageContentOps' operations.
---
--- The point of this extra generality is to allow doing checks in some virtual
--- file system, for example a tarball in memory.
---
-checkPackageContent :: (Monad m, Applicative m)
-                    => CheckPackageContentOps m
-                    -> PackageDescription
-                    -> m [PackageCheck]
-checkPackageContent ops pkg = do
-  cabalBomError   <- checkCabalFileBOM    ops
-  cabalNameError  <- checkCabalFileName   ops pkg
-  licenseErrors   <- checkLicensesExist   ops pkg
-  setupError      <- checkSetupExists     ops pkg
-  configureError  <- checkConfigureExists ops pkg
-  localPathErrors <- checkLocalPathsExist ops pkg
-  vcsLocation     <- checkMissingVcsInfo  ops pkg
-
-  return $ licenseErrors
-        ++ catMaybes [cabalBomError, cabalNameError, setupError, configureError]
-        ++ localPathErrors
-        ++ vcsLocation
-
-checkCabalFileBOM :: Monad m => CheckPackageContentOps m
-                  -> m (Maybe PackageCheck)
-checkCabalFileBOM ops = do
-  epdfile <- findPackageDesc ops
-  case epdfile of
-    -- MASSIVE HACK.  If the Cabal file doesn't exist, that is
-    -- a very strange situation to be in, because the driver code
-    -- in 'Distribution.Setup' ought to have noticed already!
-    -- But this can be an issue, see #3552 and also when
-    -- --cabal-file is specified.  So if you can't find the file,
-    -- just don't bother with this check.
-    Left _       -> return $ Nothing
-    Right pdfile -> (flip check pc . BS.isPrefixOf bomUtf8)
-                    `liftM` (getFileContents ops pdfile)
-      where pc = PackageDistInexcusable $
-                 pdfile ++ " starts with an Unicode byte order mark (BOM)."
-                 ++ " This may cause problems with older cabal versions."
-
-  where
-    bomUtf8 :: BS.ByteString
-    bomUtf8 = BS.pack [0xef,0xbb,0xbf] -- U+FEFF encoded as UTF8
-
-checkCabalFileName :: Monad m => CheckPackageContentOps m
-                 -> PackageDescription
-                 -> m (Maybe PackageCheck)
-checkCabalFileName ops pkg = do
-  -- findPackageDesc already takes care to detect missing/multiple
-  -- .cabal files; we don't include this check in 'findPackageDesc' in
-  -- order not to short-cut other checks which call 'findPackageDesc'
-  epdfile <- findPackageDesc ops
-  case epdfile of
-    -- see "MASSIVE HACK" note in 'checkCabalFileBOM'
-    Left _       -> return Nothing
-    Right pdfile
-      | takeFileName pdfile == expectedCabalname -> return Nothing
-      | otherwise -> return $ Just $ PackageDistInexcusable $
-                 "The filename " ++ quote pdfile ++ " does not match package name " ++
-                 "(expected: " ++ quote expectedCabalname ++ ")"
-  where
-    pkgname = unPackageName . packageName $ pkg
-    expectedCabalname = pkgname <.> "cabal"
-
-
--- |Find a package description file in the given directory.  Looks for
--- @.cabal@ files.  Like 'Distribution.Simple.Utils.findPackageDesc',
--- but generalized over monads.
-findPackageDesc :: Monad m => CheckPackageContentOps m
-                 -> m (Either PackageCheck FilePath) -- ^<pkgname>.cabal
-findPackageDesc ops
- = do let dir = "."
-      files <- getDirectoryContents ops dir
-      -- to make sure we do not mistake a ~/.cabal/ dir for a <pkgname>.cabal
-      -- file we filter to exclude dirs and null base file names:
-      cabalFiles <- filterM (doesFileExist ops)
-                       [ dir </> file
-                       | file <- files
-                       , let (name, ext) = splitExtension file
-                       , not (null name) && ext == ".cabal" ]
-      case cabalFiles of
-        []          -> return (Left $ PackageBuildImpossible noDesc)
-        [cabalFile] -> return (Right cabalFile)
-        multiple    -> return (Left $ PackageBuildImpossible
-                               $ multiDesc multiple)
-
-  where
-    noDesc :: String
-    noDesc = "No cabal file found.\n"
-             ++ "Please create a package description file <pkgname>.cabal"
-
-    multiDesc :: [String] -> String
-    multiDesc l = "Multiple cabal files found while checking.\n"
-                  ++ "Please use only one of: "
-                  ++ intercalate ", " l
-
-checkLicensesExist :: (Monad m, Applicative m)
-                   => CheckPackageContentOps m
-                   -> PackageDescription
-                   -> m [PackageCheck]
-checkLicensesExist ops pkg = do
-    exists <- traverse (doesFileExist ops . getSymbolicPath) (licenseFiles pkg)
-    return
-      [ PackageBuildWarning $
-           "The '" ++ fieldname ++ "' field refers to the file "
-        ++ quote (getSymbolicPath file) ++ " which does not exist."
-      | (file, False) <- zip (licenseFiles pkg) exists ]
-  where
-    fieldname | length (licenseFiles pkg) == 1 = "license-file"
-              | otherwise                      = "license-files"
-
-checkSetupExists :: Monad m => CheckPackageContentOps m
-                 -> PackageDescription
-                 -> m (Maybe PackageCheck)
-checkSetupExists ops pkg = do
-  let simpleBuild = buildType pkg == Simple
-  hsexists  <- doesFileExist ops "Setup.hs"
-  lhsexists <- doesFileExist ops "Setup.lhs"
-  return $ check (not simpleBuild && not hsexists && not lhsexists) $
-    PackageDistInexcusable $
-      "The package is missing a Setup.hs or Setup.lhs script."
-
-checkConfigureExists :: Monad m => CheckPackageContentOps m
-                     -> PackageDescription
-                     -> m (Maybe PackageCheck)
-checkConfigureExists ops pd
-  | buildType pd == Configure = do
-      exists <- doesFileExist ops "configure"
-      return $ check (not exists) $
-        PackageBuildWarning $
-          "The 'build-type' is 'Configure' but there is no 'configure' script. "
-          ++ "You probably need to run 'autoreconf -i' to generate it."
-  | otherwise = return Nothing
-
-checkLocalPathsExist :: Monad m => CheckPackageContentOps m
-                     -> PackageDescription
-                     -> m [PackageCheck]
-checkLocalPathsExist ops pkg = do
-  let dirs = [ (dir, kind)
-             | bi <- allBuildInfo pkg
-             , (dir, kind) <-
-                  [ (dir, "extra-lib-dirs") | dir <- extraLibDirs bi ]
-               ++ [ (dir, "extra-lib-dirs-static") | dir <- extraLibDirsStatic bi ]
-               ++ [ (dir, "extra-framework-dirs")
-                  | dir <- extraFrameworkDirs  bi ]
-               ++ [ (dir, "include-dirs")   | dir <- includeDirs  bi ]
-               ++ [ (getSymbolicPath dir, "hs-source-dirs") | dir <- hsSourceDirs bi ]
-             , isRelativeOnAnyPlatform dir ]
-  missing <- filterM (liftM not . doesDirectoryExist ops . fst) dirs
-  return [ PackageBuildWarning {
-             explanation = quote (kind ++ ": " ++ dir)
-                        ++ " specifies a directory which does not exist."
-           }
-         | (dir, kind) <- missing ]
-
-checkMissingVcsInfo :: (Monad m, Applicative m)
-                    => CheckPackageContentOps m
-                    -> PackageDescription
-                    -> m [PackageCheck]
-checkMissingVcsInfo ops pkg | null (sourceRepos pkg) = do
-    vcsInUse <- liftM or $ traverse (doesDirectoryExist ops) repoDirnames
-    if vcsInUse
-      then return [ PackageDistSuspicious message ]
-      else return []
-  where
-    repoDirnames = [ dirname | repo    <- knownRepoTypes
-                             , dirname <- repoTypeDirname repo]
-    message  = "When distributing packages it is encouraged to specify source "
-            ++ "control information in the .cabal file using one or more "
-            ++ "'source-repository' sections. See the Cabal user guide for "
-            ++ "details."
-
-checkMissingVcsInfo _ _ = return []
-
-repoTypeDirname :: KnownRepoType -> [FilePath]
-repoTypeDirname Darcs     = ["_darcs"]
-repoTypeDirname Git       = [".git"]
-repoTypeDirname SVN       = [".svn"]
-repoTypeDirname CVS       = ["CVS"]
-repoTypeDirname Mercurial = [".hg"]
-repoTypeDirname GnuArch   = [".arch-params"]
-repoTypeDirname Bazaar    = [".bzr"]
-repoTypeDirname Monotone  = ["_MTN"]
-repoTypeDirname Pijul     = [".pijul"]
-
--- ------------------------------------------------------------
--- * Checks involving files in the package
--- ------------------------------------------------------------
-
--- | Check the names of all files in a package for portability problems. This
--- should be done for example when creating or validating a package tarball.
---
-checkPackageFileNames :: [FilePath] -> [PackageCheck]
-checkPackageFileNames = checkPackageFileNamesWithGlob . zip (repeat True)
-
-checkPackageFileNamesWithGlob :: [(Bool, FilePath)] -> [PackageCheck]
-checkPackageFileNamesWithGlob files =
-  catMaybes $
-    checkWindowsPaths files
-    :
-    [ checkTarPath file
-    | (_, file) <- files
-    ]
-
-checkWindowsPaths :: [(Bool, FilePath)] -> Maybe PackageCheck
-checkWindowsPaths paths =
-    case filter (not . FilePath.Windows.isValid . escape) paths of
-      [] -> Nothing
-      ps -> Just $
-        PackageDistInexcusable $
-             "The " ++ quotes (map snd ps) ++ " invalid on Windows, which "
-          ++ "would cause portability problems for this package. Windows file "
-          ++ "names cannot contain any of the characters \":*?<>|\" and there "
-          ++ "a few reserved names including \"aux\", \"nul\", \"con\", "
-          ++ "\"prn\", \"com1-9\", \"lpt1-9\" and \"clock$\"."
-  where
-    -- force a relative name to catch invalid file names like "f:oo" which
-    -- otherwise parse as file "oo" in the current directory on the 'f' drive.
-    escape (isGlob, path) = (".\\" ++)
-        -- glob paths will be expanded before being dereferenced, so asterisks
-        -- shouldn't count against them.
-      $ map (\c -> if c == '*' && isGlob then 'x' else c) path
-    quotes [failed] =
-        "path " ++ quote failed ++ " is"
-    quotes failed =
-        "paths " ++ intercalate ", " (map quote failed) ++ " are"
-
--- | Check a file name is valid for the portable POSIX tar format.
---
--- The POSIX tar format has a restriction on the length of file names. It is
--- unfortunately not a simple restriction like a maximum length. The exact
--- restriction is that either the whole path be 100 characters or less, or it
--- be possible to split the path on a directory separator such that the first
--- part is 155 characters or less and the second part 100 characters or less.
---
-checkTarPath :: FilePath -> Maybe PackageCheck
-checkTarPath path
-  | length path > 255   = Just longPath
-  | otherwise = case pack nameMax (reverse (splitPath path)) of
-    Left err           -> Just err
-    Right []           -> Nothing
-    Right (h:rest) -> case pack prefixMax remainder of
-      Left err         -> Just err
-      Right []         -> Nothing
-      Right (_:_)      -> Just noSplit
-     where
-        -- drop the '/' between the name and prefix:
-        remainder = safeInit h : rest
-
-  where
-    nameMax, prefixMax :: Int
-    nameMax   = 100
-    prefixMax = 155
-
-    pack _   []     = Left emptyName
-    pack maxLen (c:cs)
-      | n > maxLen  = Left longName
-      | otherwise   = Right (pack' maxLen n cs)
-      where n = length c
-
-    pack' maxLen n (c:cs)
-      | n' <= maxLen = pack' maxLen n' cs
-      where n' = n + length c
-    pack' _     _ cs = cs
-
-    longPath = PackageDistInexcusable $
-         "The following file name is too long to store in a portable POSIX "
-      ++ "format tar archive. The maximum length is 255 ASCII characters.\n"
-      ++ "The file in question is:\n  " ++ path
-    longName = PackageDistInexcusable $
-         "The following file name is too long to store in a portable POSIX "
-      ++ "format tar archive. The maximum length for the name part (including "
-      ++ "extension) is 100 ASCII characters. The maximum length for any "
-      ++ "individual directory component is 155.\n"
-      ++ "The file in question is:\n  " ++ path
-    noSplit = PackageDistInexcusable $
-         "The following file name is too long to store in a portable POSIX "
-      ++ "format tar archive. While the total length is less than 255 ASCII "
-      ++ "characters, there are unfortunately further restrictions. It has to "
-      ++ "be possible to split the file path on a directory separator into "
-      ++ "two parts such that the first part fits in 155 characters or less "
-      ++ "and the second part fits in 100 characters or less. Basically you "
-      ++ "have to make the file name or directory names shorter, or you could "
-      ++ "split a long directory name into nested subdirectories with shorter "
-      ++ "names.\nThe file in question is:\n  " ++ path
-    emptyName = PackageDistInexcusable $
-         "Encountered a file with an empty name, something is very wrong! "
-      ++ "Files with an empty name cannot be stored in a tar archive or in "
-      ++ "standard file systems."
-
--- --------------------------------------------------------------
--- * Checks for missing content and other pre-distribution checks
--- --------------------------------------------------------------
-
--- | Similar to 'checkPackageContent', 'checkPackageFilesPreDistribution'
--- inspects the files included in the package, but is primarily looking for
--- files in the working tree that may have been missed or other similar
--- problems that can only be detected pre-distribution.
---
--- Because Hackage necessarily checks the uploaded tarball, it is too late to
--- check these on the server; these checks only make sense in the development
--- and package-creation environment. Hence we can use IO, rather than needing
--- to pass a 'CheckPackageContentOps' dictionary around.
-checkPackageFilesPreDistribution :: Verbosity -> PackageDescription -> FilePath -> IO [PackageCheck]
--- Note: this really shouldn't return any 'Inexcusable' warnings,
--- because that will make us say that Hackage would reject the package.
--- But, because Hackage doesn't run these tests, that will be a lie!
-checkPackageFilesPreDistribution = checkGlobFiles
-
--- | Discover problems with the package's wildcards.
-checkGlobFiles :: Verbosity
-               -> PackageDescription
-               -> FilePath
-               -> IO [PackageCheck]
-checkGlobFiles verbosity pkg root =
-  fmap concat $ for allGlobs $ \(field, dir, glob) ->
-    -- Note: we just skip over parse errors here; they're reported elsewhere.
-    case parseFileGlob (specVersion pkg) glob of
-      Left _ -> return []
-      Right parsedGlob -> do
-        results <- runDirFileGlob verbosity (root </> dir) parsedGlob
-        let individualWarnings = results >>= getWarning field glob
-            noMatchesWarning =
-              [ PackageDistSuspiciousWarn $
-                     "In '" ++ field ++ "': the pattern '" ++ glob ++ "' does not"
-                  ++ " match any files."
-              | all (not . suppressesNoMatchesWarning) results
-              ]
-        return (noMatchesWarning ++ individualWarnings)
-  where
-    adjustedDataDir = if null (dataDir pkg) then "." else dataDir pkg
-    allGlobs = concat
-      [ (,,) "extra-source-files" "." <$> extraSrcFiles pkg
-      , (,,) "extra-doc-files" "." <$> extraDocFiles pkg
-      , (,,) "data-files" adjustedDataDir <$> dataFiles pkg
-      ]
-
-    -- If there's a missing directory in play, since our globs don't
-    -- (currently) support disjunction, that will always mean there are no
-    -- matches. The no matches error in this case is strictly less informative
-    -- than the missing directory error, so sit on it.
-    suppressesNoMatchesWarning (GlobMatch _) = True
-    suppressesNoMatchesWarning (GlobWarnMultiDot _) = False
-    suppressesNoMatchesWarning (GlobMissingDirectory _) = True
-
-    getWarning :: String -> FilePath -> GlobResult FilePath -> [PackageCheck]
-    getWarning _ _ (GlobMatch _) =
-      []
-    -- Before Cabal 2.4, the extensions of globs had to match the file
-    -- exactly. This has been relaxed in 2.4 to allow matching only the
-    -- suffix. This warning detects when pre-2.4 package descriptions are
-    -- omitting files purely because of the stricter check.
-    getWarning field glob (GlobWarnMultiDot file) =
-      [ PackageDistSuspiciousWarn $
-             "In '" ++ field ++ "': the pattern '" ++ glob ++ "' does not"
-          ++ " match the file '" ++ file ++ "' because the extensions do not"
-          ++ " exactly match (e.g., foo.en.html does not exactly match *.html)."
-          ++ " To enable looser suffix-only matching, set 'cabal-version: 2.4' or higher."
-      ]
-    getWarning field glob (GlobMissingDirectory dir) =
-      [ PackageDistSuspiciousWarn $
-             "In '" ++ field ++ "': the pattern '" ++ glob ++ "' attempts to"
-          ++ " match files in the directory '" ++ dir ++ "', but there is no"
-          ++ " directory by that name."
-      ]
-
--- | Check that setup dependencies, have proper bounds.
--- In particular, @base@ and @Cabal@ upper bounds are mandatory.
-checkSetupVersions :: GenericPackageDescription -> [PackageCheck]
-checkSetupVersions pkg =
-    [ emitError nameStr
-    | (name, vr) <- Map.toList deps
-    , not (hasUpperBound vr)
-    , let nameStr = unPackageName name
-    , nameStr `elem` criticalPkgs
-    ]
-  where
-    criticalPkgs = ["Cabal", "base"]
-    deps = case typicalPkg pkg of
-      Right (pkgs', _) ->
-        Map.fromListWith intersectVersionRanges
-          [ (pname, vr)
-          | sbi <- maybeToList $ setupBuildInfo pkgs'
-          , Dependency pname vr _ <- setupDepends sbi
-          ]
-      _ -> Map.empty
-    emitError nm =
-      PackageDistInexcusable $
-           "The dependency 'setup-depends: '"++nm++"' does not specify an "
-        ++ "upper bound on the version number. Each major release of the "
-        ++ "'"++nm++"' package changes the API in various ways and most "
-        ++ "packages will need some changes to compile with it. If you are "
-        ++ "not sure what upper bound to use then use the next major "
-        ++ "version."
-
-checkDuplicateModules :: GenericPackageDescription -> [PackageCheck]
-checkDuplicateModules pkg =
-       concatMap checkLib   (maybe id (:) (condLibrary pkg) . map snd $ condSubLibraries pkg)
-    ++ concatMap checkExe   (map snd $ condExecutables pkg)
-    ++ concatMap checkTest  (map snd $ condTestSuites  pkg)
-    ++ concatMap checkBench (map snd $ condBenchmarks  pkg)
-  where
-    -- the duplicate modules check is has not been thoroughly vetted for backpack
-    checkLib   = checkDups "library" (\l -> explicitLibModules l ++ map moduleReexportName (reexportedModules l))
-    checkExe   = checkDups "executable" exeModules
-    checkTest  = checkDups "test suite" testModules
-    checkBench = checkDups "benchmark"  benchmarkModules
-    checkDups s getModules t =
-               let sumPair (x,x') (y,y') = (x + x' :: Int, y + y' :: Int)
-                   mergePair (x, x') (y, y') = (x + x', max y y')
-                   maxPair (x, x') (y, y') = (max x x', max y y')
-                   libMap = foldCondTree Map.empty
-                                         (\(_,v) -> Map.fromListWith sumPair . map (\x -> (x,(1, 1))) $ getModules v )
-                                         (Map.unionWith mergePair) -- if a module may occur in nonexclusive branches count it twice strictly and once loosely.
-                                         (Map.unionWith maxPair) -- a module occurs the max of times it might appear in exclusive branches
-                                         t
-                   dupLibsStrict = Map.keys $ Map.filter ((>1) . fst) libMap
-                   dupLibsLax = Map.keys $ Map.filter ((>1) . snd) libMap
-               in if not (null dupLibsLax)
-                      then [PackageBuildImpossible $ "Duplicate modules in " ++ s ++ ": " ++ commaSep (map prettyShow dupLibsLax)]
-                      else if not (null dupLibsStrict)
-                           then [PackageDistSuspicious $ "Potential duplicate modules (subject to conditionals) in " ++ s ++ ": " ++ commaSep (map prettyShow dupLibsStrict)]
-                           else []
-
--- ------------------------------------------------------------
--- * Utils
--- ------------------------------------------------------------
-
-quote :: String -> String
-quote s = "'" ++ s ++ "'"
-
-commaSep :: [String] -> String
-commaSep = intercalate ", "
-
-dups :: Ord a => [a] -> [a]
-dups xs = [ x | (x:_:_) <- group (sort xs) ]
-
-fileExtensionSupportedLanguage :: FilePath -> Bool
-fileExtensionSupportedLanguage path =
-    isHaskell || isC
-  where
-    extension = takeExtension path
-    isHaskell = extension `elem` [".hs", ".lhs"]
-    isC       = isJust (filenameCDialect extension)
-
--- | Whether a path is a good relative path.  We aren't worried about perfect
--- cross-platform compatibility here; this function just checks the paths in
--- the (local) @.cabal@ file, while only Hackage needs the portability.
---
--- >>> let test fp = putStrLn $ show (isGoodRelativeDirectoryPath fp) ++ "; " ++ show (isGoodRelativeFilePath fp)
---
--- Note that "foo./bar.hs" would be invalid on Windows.
---
--- >>> traverse_ test ["foo/bar/quu", "a/b.hs", "foo./bar.hs"]
--- Nothing; Nothing
--- Nothing; Nothing
--- Nothing; Nothing
---
--- Trailing slash is not allowed for files, for directories it is ok.
---
--- >>> test "foo/"
--- Nothing; Just "trailing slash"
---
--- Leading @./@ is fine, but @.@ and @./@ are not valid files.
---
--- >>> traverse_ test [".", "./", "./foo/bar"]
--- Nothing; Just "trailing dot segment"
--- Nothing; Just "trailing slash"
--- Nothing; Nothing
---
--- Lastly, not good file nor directory cases:
---
--- >>> traverse_ test ["", "/tmp/src", "foo//bar", "foo/.", "foo/./bar", "foo/../bar"]
--- Just "empty path"; Just "empty path"
--- Just "posix absolute path"; Just "posix absolute path"
--- Just "empty path segment"; Just "empty path segment"
--- Just "trailing same directory segment: ."; Just "trailing same directory segment: ."
--- Just "same directory segment: ."; Just "same directory segment: ."
--- Just "parent directory segment: .."; Just "parent directory segment: .."
---
--- For the last case, 'isGoodRelativeGlob' doesn't warn:
---
--- >>> traverse_ (print . isGoodRelativeGlob) ["foo/../bar"]
--- Just "parent directory segment: .."
---
-isGoodRelativeFilePath :: FilePath -> Maybe String
-isGoodRelativeFilePath = state0
-  where
-    -- initial state
-    state0 []                    = Just "empty path"
-    state0 (c:cs) | c == '.'     = state1 cs
-                  | c == '/'     = Just "posix absolute path"
-                  | otherwise    = state5 cs
-
-    -- after initial .
-    state1 []                    = Just "trailing dot segment"
-    state1 (c:cs) | c == '.'     = state4 cs
-                  | c == '/'     = state2 cs
-                  | otherwise    = state5 cs
-
-    -- after ./ or after / between segments
-    state2 []                    = Just "trailing slash"
-    state2 (c:cs) | c == '.'     = state3 cs
-                  | c == '/'     = Just "empty path segment"
-                  | otherwise    = state5 cs
-
-    -- after non-first segment's .
-    state3 []                    = Just "trailing same directory segment: ."
-    state3 (c:cs) | c == '.'     = state4 cs
-                  | c == '/'     = Just "same directory segment: ."
-                  | otherwise    = state5 cs
-
-    -- after ..
-    state4 []                    = Just "trailing parent directory segment: .."
-    state4 (c:cs) | c == '.'     = state5 cs
-                  | c == '/'     = Just "parent directory segment: .."
-                  | otherwise    = state5 cs
-
-    -- in a segment which is ok.
-    state5 []                    = Nothing
-    state5 (c:cs) | c == '.'     = state5 cs
-                  | c == '/'     = state2 cs
-                  | otherwise    = state5 cs
-
--- | See 'isGoodRelativeFilePath'.
---
--- This is barebones function. We check whether the glob is a valid file
--- by replacing stars @*@ with @x@ses.
-isGoodRelativeGlob :: FilePath -> Maybe String
-isGoodRelativeGlob = isGoodRelativeFilePath . map f where
-    f '*' = 'x'
-    f c   = c
-
--- | See 'isGoodRelativeFilePath'.
-isGoodRelativeDirectoryPath :: FilePath -> Maybe String
-isGoodRelativeDirectoryPath = state0
-  where
-    -- initial state
-    state0 []                    = Just "empty path"
-    state0 (c:cs) | c == '.'     = state5 cs
-                  | c == '/'     = Just "posix absolute path"
-                  | otherwise    = state4 cs
-
-    -- after initial ./ or after / between segments
-    state1 []                    = Nothing
-    state1 (c:cs) | c == '.'     = state2 cs
-                  | c == '/'     = Just "empty path segment"
-                  | otherwise    = state4 cs
-
-    -- after non-first setgment's .
-    state2 []                    = Just "trailing same directory segment: ."
-    state2 (c:cs) | c == '.'     = state3 cs
-                  | c == '/'     = Just "same directory segment: ."
-                  | otherwise    = state4 cs
-
-    -- after ..
-    state3 []                    = Just "trailing parent directory segment: .."
-    state3 (c:cs) | c == '.'     = state4 cs
-                  | c == '/'     = Just "parent directory segment: .."
-                  | otherwise    = state4 cs
-
-    -- in a segment which is ok.
-    state4 []                    = Nothing
-    state4 (c:cs) | c == '.'     = state4 cs
-                  | c == '/'     = state1 cs
-                  | otherwise    = state4 cs
-
-    -- after initial .
-    state5 []                    = Nothing -- "."
-    state5 (c:cs) | c == '.'     = state3 cs
-                  | c == '/'     = state1 cs
-                  | otherwise    = state4 cs
-
--- [Note: Good relative paths]
---
--- Using @kleene@ we can define an extended regex:
---
--- @
--- import Algebra.Lattice
--- import Kleene
--- import Kleene.ERE (ERE (..), intersections)
---
--- data C = CDot | CSlash | CChar
---   deriving (Eq, Ord, Enum, Bounded, Show)
---
--- reservedR :: ERE C
--- reservedR = notChar CSlash
---
--- pathPieceR :: ERE C
--- pathPieceR = intersections
---     [ plus reservedR
---     , ERENot (string [CDot])
---     , ERENot (string [CDot,CDot])
---     ]
---
--- filePathR :: ERE C
--- filePathR = optional (string [CDot, CSlash]) <> pathPieceR <> star (char CSlash <> pathPieceR)
---
--- dirPathR :: ERE C
--- dirPathR = (char CDot \/ filePathR) <> optional (char CSlash)
---
--- plus :: ERE C -> ERE C
--- plus r = r <> star r
---
--- optional :: ERE C -> ERE C
--- optional r = mempty \/ r
--- @
---
--- Results in following state machine for @filePathR@
---
--- @
--- 0 -> \x -> if
---     | x <= CDot           -> 1
---     | otherwise           -> 5
--- 1 -> \x -> if
---     | x <= CDot           -> 4
---     | x <= CSlash         -> 2
---     | otherwise           -> 5
--- 2 -> \x -> if
---     | x <= CDot           -> 3
---     | otherwise           -> 5
--- 3 -> \x -> if
---     | x <= CDot           -> 4
---     | otherwise           -> 5
--- 4 -> \x -> if
---     | x <= CDot           -> 5
---     | otherwise           -> 5
--- 5+ -> \x -> if
---     | x <= CDot           -> 5
---     | x <= CSlash         -> 2
---     | otherwise           -> 5
--- @
---
--- and @dirPathR@:
---
--- @
--- 0 -> \x -> if
---     | x <= CDot           -> 5
---     | otherwise           -> 4
--- 1+ -> \x -> if
---     | x <= CDot           -> 2
---     | otherwise           -> 4
--- 2 -> \x -> if
---     | x <= CDot           -> 3
---     | otherwise           -> 4
--- 3 -> \x -> if
---     | x <= CDot           -> 4
---     | otherwise           -> 4
--- 4+ -> \x -> if
---     | x <= CDot           -> 4
---     | x <= CSlash         -> 1
---     | otherwise           -> 4
--- 5+ -> \x -> if
---     | x <= CDot           -> 3
---     | x <= CSlash         -> 1
---     | otherwise           -> 4
--- @
-
---
--- TODO: What we really want to do is test if there exists any
--- configuration in which the base version is unbounded above.
--- However that's a bit tricky because there are many possible
--- configurations. As a cheap easy and safe approximation we will
--- pick a single "typical" configuration and check if that has an
--- open upper bound. To get a typical configuration we finalise
--- using no package index and the current platform.
-typicalPkg :: GenericPackageDescription
-           -> Either [Dependency] (PackageDescription, FlagAssignment)
-typicalPkg = finalizePD
-  mempty defaultComponentRequestedSpec (const True)
-  buildPlatform
-  (unknownCompilerInfo
-    (CompilerId buildCompilerFlavor nullVersion)
-      NoAbiTag)
-  []
+        CheckExplanation(..),
+        PackageCheck(..),
+        checkPackage,
+        checkConfiguredPackage,
+        wrapParseWarning,
+        ppPackageCheck,
+
+        -- ** Checking package contents
+        checkPackageFiles,
+        checkPackageContent,
+        CheckPackageContentOps(..),
+        checkPackageFileNames,
+  ) where
+
+import Data.Foldable                                 (foldrM)
+import Distribution.Compat.Prelude
+import Prelude ()
+
+import Data.List                                     (delete, group)
+import Distribution.CabalSpecVersion
+import Distribution.Compat.Lens
+import Distribution.Compiler
+import Distribution.License
+import Distribution.ModuleName                       (ModuleName)
+import Distribution.Package
+import Distribution.PackageDescription
+import Distribution.PackageDescription.Configuration
+import Distribution.Parsec.Warning                   (PWarning, showPWarning)
+import Distribution.Pretty                           (prettyShow)
+import Distribution.Simple.BuildPaths                (autogenPackageInfoModuleName, autogenPathsModuleName)
+import Distribution.Simple.BuildToolDepends
+import Distribution.Simple.CCompiler
+import Distribution.Simple.Glob
+import Distribution.Simple.Utils                     hiding (findPackageDesc, notice)
+import Distribution.System
+import Distribution.Types.ComponentRequestedSpec
+import Distribution.Types.PackageName.Magic
+import Distribution.Utils.Generic                    (isAscii)
+import Distribution.Verbosity
+import Distribution.Version
+import Distribution.Utils.Path
+import Language.Haskell.Extension
+import System.FilePath
+       ( makeRelative, normalise, splitDirectories, splitExtension, splitPath
+       , takeExtension, takeFileName, (<.>), (</>))
+
+import qualified Data.ByteString.Lazy      as BS
+import qualified Data.Map                  as Map
+import qualified Control.Monad             as CM
+import qualified Distribution.Compat.DList as DList
+import qualified Distribution.SPDX         as SPDX
+import qualified System.Directory          as System
+
+import qualified System.Directory        (getDirectoryContents)
+import qualified System.FilePath.Windows as FilePath.Windows (isValid)
+
+import qualified Data.Set as Set
+import qualified Distribution.Utils.ShortText as ShortText
+
+import qualified Distribution.Types.BuildInfo.Lens                 as L
+import qualified Distribution.Types.GenericPackageDescription.Lens as L
+import qualified Distribution.Types.PackageDescription.Lens        as L
+
+-- $setup
+-- >>> import Control.Arrow ((&&&))
+
+-- ------------------------------------------------------------
+-- * Warning messages
+-- ------------------------------------------------------------
+
+-- | Which stanza does `CheckExplanation` refer to?
+--
+data CEType = CETLibrary | CETExecutable | CETTest | CETBenchmark
+    deriving (Eq, Ord, Show)
+
+-- | Pretty printing `CEType`.
+--
+ppCE :: CEType -> String
+ppCE CETLibrary = "library"
+ppCE CETExecutable = "executable"
+ppCE CETTest = "test suite"
+ppCE CETBenchmark = "benchmark"
+
+-- | Which field does `CheckExplanation` refer to?
+--
+data CEField = CEFCategory | CEFMaintainer | CEFSynopsis
+             | CEFDescription | CEFSynOrDesc
+    deriving (Eq, Ord, Show)
+
+-- | Pretty printing `CEField`.
+--
+ppCEField :: CEField -> String
+ppCEField CEFCategory = "category"
+ppCEField CEFMaintainer = "maintainer"
+ppCEField CEFSynopsis = "synopsis"
+ppCEField CEFDescription = "description"
+ppCEField CEFSynOrDesc = "synopsis' or 'description"
+
+-- | Explanations of 'PackageCheck`'s errors/warnings.
+--
+data CheckExplanation =
+          ParseWarning FilePath PWarning
+        | NoNameField
+        | NoVersionField
+        | NoTarget
+        | UnnamedInternal
+        | DuplicateSections [UnqualComponentName]
+        | IllegalLibraryName PackageDescription
+        | NoModulesExposed Library
+        | SignaturesCabal2
+        | AutogenNotExposed
+        | AutogenIncludesNotIncluded
+        | NoMainIs Executable
+        | NoHsLhsMain
+        | MainCCabal1_18
+        | AutogenNoOther CEType UnqualComponentName
+        | AutogenIncludesNotIncludedExe
+        | TestsuiteTypeNotKnown TestType
+        | TestsuiteNotSupported TestType
+        | BenchmarkTypeNotKnown BenchmarkType
+        | BenchmarkNotSupported BenchmarkType
+        | NoHsLhsMainBench
+        | InvalidNameWin PackageDescription
+        | ZPrefix
+        | NoBuildType
+        | NoCustomSetup
+        | UnknownCompilers [String]
+        | UnknownLanguages [String]
+        | UnknownExtensions [String]
+        | LanguagesAsExtension [String]
+        | DeprecatedExtensions [(Extension, Maybe Extension)]
+        | MissingField CEField
+        | SynopsisTooLong
+        | ShortDesc
+        | InvalidTestWith [Dependency]
+        | ImpossibleInternalDep [Dependency]
+        | ImpossibleInternalExe [ExeDependency]
+        | MissingInternalExe [ExeDependency]
+        | NONELicense
+        | NoLicense
+        | AllRightsReservedLicense
+        | LicenseMessParse PackageDescription
+        | UnrecognisedLicense String
+        | UncommonBSD4
+        | UnknownLicenseVersion License [Version]
+        | NoLicenseFile
+        | UnrecognisedSourceRepo String
+        | MissingType
+        | MissingLocation
+        | MissingModule
+        | MissingTag
+        | SubdirRelPath
+        | SubdirGoodRelPath String
+        | OptFasm String
+        | OptViaC String
+        | OptHpc String
+        | OptProf String
+        | OptO String
+        | OptHide String
+        | OptMake String
+        | OptONot String
+        | OptOOne String
+        | OptOTwo String
+        | OptSplitSections String
+        | OptSplitObjs String
+        | OptWls String
+        | OptExts String
+        | OptRts String
+        | OptWithRts String
+        | COptONumber String String
+        | COptCPP String
+        | OptAlternatives String String [(String, String)]
+        | RelativeOutside String FilePath
+        | AbsolutePath String FilePath
+        | BadRelativePAth String FilePath String
+        | DistPoint (Maybe String) FilePath
+        | GlobSyntaxError String String
+        | RecursiveGlobInRoot String FilePath
+        | InvalidOnWin [FilePath]
+        | FilePathTooLong FilePath
+        | FilePathNameTooLong FilePath
+        | FilePathSplitTooLong FilePath
+        | FilePathEmpty
+        | CVTestSuite
+        | CVDefaultLanguage
+        | CVDefaultLanguageComponent
+        | CVExtraDocFiles
+        | CVMultiLib
+        | CVReexported
+        | CVMixins
+        | CVExtraFrameworkDirs
+        | CVDefaultExtensions
+        | CVExtensionsDeprecated
+        | CVSources
+        | CVExtraDynamic [[String]]
+        | CVVirtualModules
+        | CVSourceRepository
+        | CVExtensions CabalSpecVersion [Extension]
+        | CVCustomSetup
+        | CVExpliticDepsCustomSetup
+        | CVAutogenPaths
+        | CVAutogenPackageInfo
+        | CVAutogenPackageInfoGuard
+        | GlobNoMatch String String
+        | GlobExactMatch String String FilePath
+        | GlobNoDir String String FilePath
+        | UnknownOS [String]
+        | UnknownArch [String]
+        | UnknownCompiler [String]
+        | BaseNoUpperBounds
+        | MissingUpperBounds [PackageName]
+        | SuspiciousFlagName [String]
+        | DeclaredUsedFlags (Set FlagName) (Set FlagName)
+        | NonASCIICustomField [String]
+        | RebindableClashPaths
+        | RebindableClashPackageInfo
+        | WErrorUnneeded String
+        | JUnneeded String
+        | FDeferTypeErrorsUnneeded String
+        | DynamicUnneeded String
+        | ProfilingUnneeded String
+        | UpperBoundSetup String
+        | DuplicateModule String [ModuleName]
+        | PotentialDupModule String [ModuleName]
+        | BOMStart FilePath
+        | NotPackageName FilePath String
+        | NoDesc
+        | MultiDesc [String]
+        | UnknownFile String (SymbolicPath PackageDir LicenseFile)
+        | MissingSetupFile
+        | MissingConfigureScript
+        | UnknownDirectory String FilePath
+        | MissingSourceControl
+        | MissingExpectedDocFiles Bool [FilePath]
+        | WrongFieldForExpectedDocFiles Bool String [FilePath]
+    deriving (Eq, Ord, Show)
+
+-- | Wraps `ParseWarning` into `PackageCheck`.
+--
+wrapParseWarning :: FilePath -> PWarning -> PackageCheck
+wrapParseWarning fp pw = PackageDistSuspicious (ParseWarning fp pw)
+    -- TODO: as Jul 2022 there is no severity indication attached PWarnType.
+    --       Once that is added, we can output something more appropriate
+    --       than PackageDistSuspicious for every parse warning.
+    --       (see: Cabal-syntax/src/Distribution/Parsec/Warning.hs)
+
+-- | Pretty printing `CheckExplanation`.
+--
+ppExplanation :: CheckExplanation -> String
+ppExplanation (ParseWarning fp pp) = showPWarning fp pp
+ppExplanation NoNameField = "No 'name' field."
+ppExplanation NoVersionField = "No 'version' field."
+ppExplanation NoTarget =
+    "No executables, libraries, tests, or benchmarks found. Nothing to do."
+ppExplanation UnnamedInternal =
+    "Found one or more unnamed internal libraries. Only the non-internal"
+      ++ " library can have the same name as the package."
+ppExplanation (DuplicateSections duplicateNames) =
+    "Duplicate sections: "
+      ++ commaSep (map unUnqualComponentName duplicateNames)
+      ++ ". The name of every library, executable, test suite,"
+      ++ " and benchmark section in the package must be unique."
+ppExplanation (IllegalLibraryName pkg) =
+    "Illegal internal library name "
+      ++ prettyShow (packageName pkg)
+      ++ ". Internal libraries cannot have the same name as the package."
+      ++ " Maybe you wanted a non-internal library?"
+      ++ " If so, rewrite the section stanza"
+      ++ " from 'library: '" ++ prettyShow (packageName pkg)
+      ++ "' to 'library'."
+ppExplanation (NoModulesExposed lib) =
+    showLibraryName (libName lib) ++ " does not expose any modules"
+ppExplanation SignaturesCabal2 =
+    "To use the 'signatures' field the package needs to specify "
+      ++ "at least 'cabal-version: 2.0'."
+ppExplanation AutogenNotExposed =
+    "An 'autogen-module' is neither on 'exposed-modules' or 'other-modules'."
+ppExplanation AutogenIncludesNotIncluded =
+    "An include in 'autogen-includes' is neither in 'includes' or "
+       ++ "'install-includes'."
+ppExplanation (NoMainIs exe) =
+    "No 'main-is' field found for executable " ++ prettyShow (exeName exe)
+ppExplanation NoHsLhsMain =
+    "The 'main-is' field must specify a '.hs' or '.lhs' file "
+      ++ "(even if it is generated by a preprocessor), "
+      ++ "or it may specify a C/C++/obj-C source file."
+ppExplanation MainCCabal1_18 =
+    "The package uses a C/C++/obj-C source file for the 'main-is' field. "
+      ++ "To use this feature you need to specify 'cabal-version: 1.18' or"
+      ++ " higher."
+ppExplanation (AutogenNoOther ct ucn) =
+    "On " ++ ppCE ct ++ " '" ++ prettyShow ucn ++ "' an 'autogen-module'"
+      ++ " is not on 'other-modules'"
+ppExplanation AutogenIncludesNotIncludedExe =
+    "An include in 'autogen-includes' is not in 'includes'."
+ppExplanation (TestsuiteTypeNotKnown tt) =
+    quote (prettyShow tt) ++ " is not a known type of test suite. "
+      ++ "Either remove the 'type' field or use a known type. "
+      ++ "The known test suite types are: "
+      ++ commaSep (map prettyShow knownTestTypes)
+ppExplanation (TestsuiteNotSupported tt) =
+    quote (prettyShow tt) ++ " is not a supported test suite version. "
+      ++ "Either remove the 'type' field or use a known type. "
+      ++ "The known test suite types are: "
+      ++ commaSep (map prettyShow knownTestTypes)
+ppExplanation (BenchmarkTypeNotKnown tt) =
+    quote (prettyShow tt) ++ " is not a known type of benchmark. "
+      ++ "Either remove the 'type' field or use a known type. "
+      ++ "The known benchmark types are: "
+      ++ commaSep (map prettyShow knownBenchmarkTypes)
+ppExplanation (BenchmarkNotSupported tt) =
+    quote (prettyShow tt) ++ " is not a supported benchmark version. "
+      ++ "Either remove the 'type' field or use a known type. "
+      ++ "The known benchmark types are: "
+      ++ commaSep (map prettyShow knownBenchmarkTypes)
+ppExplanation NoHsLhsMainBench =
+    "The 'main-is' field must specify a '.hs' or '.lhs' file "
+      ++ "(even if it is generated by a preprocessor)."
+ppExplanation (InvalidNameWin pkg) =
+    "The package name '" ++ prettyShow (packageName pkg) ++ "' is "
+      ++ "invalid on Windows. Many tools need to convert package names to "
+      ++ "file names so using this name would cause problems."
+ppExplanation ZPrefix =
+    "Package names with the prefix 'z-' are reserved by Cabal and "
+      ++ "cannot be used."
+ppExplanation NoBuildType =
+    "No 'build-type' specified. If you do not need a custom Setup.hs or "
+      ++ "./configure script then use 'build-type: Simple'."
+ppExplanation NoCustomSetup =
+    "Ignoring the 'custom-setup' section because the 'build-type' is "
+      ++ "not 'Custom'. Use 'build-type: Custom' if you need to use a "
+      ++ "custom Setup.hs script."
+ppExplanation (UnknownCompilers unknownCompilers) =
+    "Unknown compiler " ++ commaSep (map quote unknownCompilers)
+      ++ " in 'tested-with' field."
+ppExplanation (UnknownLanguages unknownLanguages) =
+    "Unknown languages: " ++ commaSep unknownLanguages
+ppExplanation (UnknownExtensions unknownExtensions) =
+    "Unknown extensions: " ++ commaSep unknownExtensions
+ppExplanation (LanguagesAsExtension languagesUsedAsExtensions) =
+    "Languages listed as extensions: "
+      ++ commaSep languagesUsedAsExtensions
+      ++ ". Languages must be specified in either the 'default-language' "
+      ++ " or the 'other-languages' field."
+ppExplanation (DeprecatedExtensions ourDeprecatedExtensions) =
+    "Deprecated extensions: "
+      ++ commaSep (map (quote . prettyShow . fst) ourDeprecatedExtensions)
+      ++ ". " ++ unwords
+           [ "Instead of '" ++ prettyShow ext
+          ++ "' use '" ++ prettyShow replacement ++ "'."
+           | (ext, Just replacement) <- ourDeprecatedExtensions ]
+ppExplanation (MissingField cef) =
+    "No '" ++ ppCEField cef ++ "' field."
+ppExplanation SynopsisTooLong =
+    "The 'synopsis' field is rather long (max 80 chars is recommended)."
+ppExplanation ShortDesc =
+    "The 'description' field should be longer than the 'synopsis' field. "
+      ++ "It's useful to provide an informative 'description' to allow "
+      ++ "Haskell programmers who have never heard about your package to "
+      ++ "understand the purpose of your package. "
+      ++ "The 'description' field content is typically shown by tooling "
+      ++ "(e.g. 'cabal info', Haddock, Hackage) below the 'synopsis' which "
+      ++ "serves as a headline. "
+      ++ "Please refer to <https://cabal.readthedocs.io/en/stable/"
+      ++ "cabal-package.html#package-properties> for more details."
+ppExplanation (InvalidTestWith testedWithImpossibleRanges) =
+    "Invalid 'tested-with' version range: "
+      ++ commaSep (map prettyShow testedWithImpossibleRanges)
+      ++ ". To indicate that you have tested a package with multiple "
+      ++ "different versions of the same compiler use multiple entries, "
+      ++ "for example 'tested-with: GHC==6.10.4, GHC==6.12.3' and not "
+      ++ "'tested-with: GHC==6.10.4 && ==6.12.3'."
+ppExplanation (ImpossibleInternalDep depInternalLibWithImpossibleVersion) =
+    "The package has an impossible version range for a dependency on an "
+      ++ "internal library: "
+      ++ commaSep (map prettyShow depInternalLibWithImpossibleVersion)
+      ++ ". This version range does not include the current package, and must "
+      ++ "be removed as the current package's library will always be used."
+ppExplanation (ImpossibleInternalExe depInternalExecWithImpossibleVersion) =
+    "The package has an impossible version range for a dependency on an "
+      ++ "internal executable: "
+      ++ commaSep (map prettyShow depInternalExecWithImpossibleVersion)
+      ++ ". This version range does not include the current package, and must "
+      ++ "be removed as the current package's executable will always be used."
+ppExplanation (MissingInternalExe depInternalExeWithImpossibleVersion) =
+    "The package depends on a missing internal executable: "
+      ++ commaSep (map prettyShow depInternalExeWithImpossibleVersion)
+ppExplanation NONELicense = "The 'license' field is missing or is NONE."
+ppExplanation NoLicense = "The 'license' field is missing."
+ppExplanation AllRightsReservedLicense =
+    "The 'license' is AllRightsReserved. Is that really what you want?"
+ppExplanation (LicenseMessParse pkg) =
+    "Unfortunately the license " ++ quote (prettyShow (license pkg))
+      ++ " messes up the parser in earlier Cabal versions so you need to "
+      ++ "specify 'cabal-version: >= 1.4'. Alternatively if you require "
+      ++ "compatibility with earlier Cabal versions then use 'OtherLicense'."
+ppExplanation (UnrecognisedLicense l) =
+    quote ("license: " ++ l) ++ " is not a recognised license. The "
+      ++ "known licenses are: " ++ commaSep (map prettyShow knownLicenses)
+ppExplanation UncommonBSD4 =
+    "Using 'license: BSD4' is almost always a misunderstanding. 'BSD4' "
+      ++ "refers to the old 4-clause BSD license with the advertising "
+      ++ "clause. 'BSD3' refers the new 3-clause BSD license."
+ppExplanation (UnknownLicenseVersion lic known) =
+    "'license: " ++ prettyShow lic ++ "' is not a known "
+      ++ "version of that license. The known versions are "
+      ++ commaSep (map prettyShow known)
+      ++ ". If this is not a mistake and you think it should be a known "
+      ++ "version then please file a ticket."
+ppExplanation NoLicenseFile = "A 'license-file' is not specified."
+ppExplanation (UnrecognisedSourceRepo kind) =
+    quote kind ++ " is not a recognised kind of source-repository. "
+      ++ "The repo kind is usually 'head' or 'this'"
+ppExplanation MissingType =
+    "The source-repository 'type' is a required field."
+ppExplanation MissingLocation =
+    "The source-repository 'location' is a required field."
+ppExplanation MissingModule =
+    "For a CVS source-repository, the 'module' is a required field."
+ppExplanation MissingTag =
+    "For the 'this' kind of source-repository, the 'tag' is a required "
+      ++ "field. It should specify the tag corresponding to this version "
+      ++ "or release of the package."
+ppExplanation SubdirRelPath =
+    "The 'subdir' field of a source-repository must be a relative path."
+ppExplanation (SubdirGoodRelPath err) =
+    "The 'subdir' field of a source-repository is not a good relative path: "
+      ++ show err
+ppExplanation (OptFasm fieldName) =
+    "'" ++ fieldName ++ ": -fasm' is unnecessary and will not work on CPU "
+      ++ "architectures other than x86, x86-64, ppc or sparc."
+ppExplanation (OptViaC fieldName) =
+    "'" ++ fieldName ++": -fvia-C' is usually unnecessary. If your package "
+      ++ "needs -via-C for correctness rather than performance then it "
+      ++ "is using the FFI incorrectly and will probably not work with GHC "
+      ++ "6.10 or later."
+ppExplanation (OptHpc fieldName) =
+    "'" ++ fieldName ++ ": -fhpc' is not necessary. Use the configure flag "
+      ++ " --enable-coverage instead."
+ppExplanation (OptProf fieldName) =
+    "'" ++ fieldName ++ ": -prof' is not necessary and will lead to problems "
+      ++ "when used on a library. Use the configure flag "
+      ++ "--enable-library-profiling and/or --enable-profiling."
+ppExplanation (OptO fieldName) =
+    "'" ++ fieldName ++ ": -o' is not needed. "
+      ++ "The output files are named automatically."
+ppExplanation (OptHide fieldName) =
+    "'" ++ fieldName ++ ": -hide-package' is never needed. "
+      ++ "Cabal hides all packages."
+ppExplanation (OptMake fieldName) =
+    "'" ++ fieldName
+      ++ ": --make' is never needed. Cabal uses this automatically."
+ppExplanation (OptONot fieldName) =
+      "'" ++ fieldName ++ ": -O0' is not needed. "
+      ++ "Use the --disable-optimization configure flag."
+ppExplanation (OptOOne fieldName) =
+    "'" ++ fieldName ++ ": -O' is not needed. "
+      ++ "Cabal automatically adds the '-O' flag. "
+      ++ "Setting it yourself interferes with the --disable-optimization flag."
+ppExplanation (OptOTwo fieldName) =
+    "'" ++ fieldName ++ ": -O2' is rarely needed. "
+      ++ "Check that it is giving a real benefit "
+      ++ "and not just imposing longer compile times on your users."
+ppExplanation (OptSplitSections fieldName) =
+    "'" ++ fieldName ++ ": -split-sections' is not needed. "
+      ++ "Use the --enable-split-sections configure flag."
+ppExplanation (OptSplitObjs fieldName) =
+    "'" ++ fieldName ++ ": -split-objs' is not needed. "
+      ++ "Use the --enable-split-objs configure flag."
+ppExplanation (OptWls fieldName) =
+    "'" ++ fieldName ++ ": -optl-Wl,-s' is not needed and is not portable to"
+      ++ " all operating systems. Cabal 1.4 and later automatically strip"
+      ++ " executables. Cabal also has a flag --disable-executable-stripping"
+      ++ " which is necessary when building packages for some Linux"
+      ++ " distributions and using '-optl-Wl,-s' prevents that from working."
+ppExplanation (OptExts fieldName) =
+    "Instead of '" ++ fieldName ++ ": -fglasgow-exts' it is preferable to use "
+      ++ "the 'extensions' field."
+ppExplanation (OptRts fieldName) =
+    "'" ++ fieldName ++ ": -rtsopts' has no effect for libraries. It should "
+      ++ "only be used for executables."
+ppExplanation (OptWithRts fieldName) =
+    "'" ++ fieldName ++ ": -with-rtsopts' has no effect for libraries. It "
+      ++ "should only be used for executables."
+ppExplanation (COptONumber prefix label) =
+    "'" ++ prefix ++": -O[n]' is generally not needed. When building with "
+      ++ " optimisations Cabal automatically adds '-O2' for " ++ label
+      ++ " code. Setting it yourself interferes with the"
+      ++ " --disable-optimization flag."
+ppExplanation (COptCPP opt) =
+    "'cpp-options: " ++ opt ++ "' is not a portable C-preprocessor flag."
+ppExplanation (OptAlternatives badField goodField flags) =
+    "Instead of " ++ quote (badField ++ ": " ++ unwords badFlags)
+      ++ " use " ++ quote (goodField ++ ": " ++ unwords goodFlags)
+  where (badFlags, goodFlags) = unzip flags
+ppExplanation (RelativeOutside field path) =
+    quote (field ++ ": " ++ path)
+      ++ " is a relative path outside of the source tree. "
+      ++ "This will not work when generating a tarball with 'sdist'."
+ppExplanation (AbsolutePath field path) =
+    quote (field ++ ": " ++ path) ++ " specifies an absolute path, but the "
+      ++ quote field ++ " field must use relative paths."
+ppExplanation (BadRelativePAth field path err) =
+    quote (field ++ ": " ++ path)
+      ++ " is not a good relative path: " ++ show err
+ppExplanation (DistPoint mfield path) =
+    incipit ++ " points inside the 'dist' "
+      ++ "directory. This is not reliable because the location of this "
+      ++ "directory is configurable by the user (or package manager). In "
+      ++ "addition the layout of the 'dist' directory is subject to change "
+      ++ "in future versions of Cabal."
+  where -- mfiled Nothing -> the path is inside `ghc-options`
+        incipit = maybe ("'ghc-options' path " ++ quote path)
+                        (\field -> quote (field ++ ": " ++ path))
+                        mfield
+ppExplanation (GlobSyntaxError field expl) =
+    "In the '" ++ field ++ "' field: " ++ expl
+ppExplanation (RecursiveGlobInRoot field glob) =
+    "In the '" ++ field ++ "': glob '" ++ glob
+    ++ "' starts at project root directory, this might "
+    ++ "include `.git/`, ``dist-newstyle/``, or other large directories!"
+ppExplanation (InvalidOnWin paths) =
+    "The " ++ quotes paths ++ " invalid on Windows, which "
+      ++ "would cause portability problems for this package. Windows file "
+      ++ "names cannot contain any of the characters \":*?<>|\" and there "
+      ++ "a few reserved names including \"aux\", \"nul\", \"con\", "
+      ++ "\"prn\", \"com1-9\", \"lpt1-9\" and \"clock$\"."
+  where quotes [failed] = "path " ++ quote failed ++ " is"
+        quotes failed = "paths " ++ intercalate ", " (map quote failed)
+                          ++ " are"
+ppExplanation (FilePathTooLong path) =
+         "The following file name is too long to store in a portable POSIX "
+      ++ "format tar archive. The maximum length is 255 ASCII characters.\n"
+      ++ "The file in question is:\n  " ++ path
+ppExplanation (FilePathNameTooLong path) =
+    "The following file name is too long to store in a portable POSIX "
+      ++ "format tar archive. The maximum length for the name part (including "
+      ++ "extension) is 100 ASCII characters. The maximum length for any "
+      ++ "individual directory component is 155.\n"
+      ++ "The file in question is:\n  " ++ path
+ppExplanation (FilePathSplitTooLong path) =
+    "The following file name is too long to store in a portable POSIX "
+      ++ "format tar archive. While the total length is less than 255 ASCII "
+      ++ "characters, there are unfortunately further restrictions. It has to "
+      ++ "be possible to split the file path on a directory separator into "
+      ++ "two parts such that the first part fits in 155 characters or less "
+      ++ "and the second part fits in 100 characters or less. Basically you "
+      ++ "have to make the file name or directory names shorter, or you could "
+      ++ "split a long directory name into nested subdirectories with shorter "
+      ++ "names.\nThe file in question is:\n  " ++ path
+ppExplanation FilePathEmpty =
+    "Encountered a file with an empty name, something is very wrong! "
+      ++ "Files with an empty name cannot be stored in a tar archive or in "
+      ++ "standard file systems."
+ppExplanation CVTestSuite =
+    "The 'test-suite' section is new in Cabal 1.10. "
+      ++ "Unfortunately it messes up the parser in older Cabal versions "
+      ++ "so you must specify at least 'cabal-version: >= 1.8', but note "
+      ++ "that only Cabal 1.10 and later can actually run such test suites."
+ppExplanation CVDefaultLanguage =
+    "To use the 'default-language' field the package needs to specify "
+      ++ "at least 'cabal-version: >= 1.10'."
+ppExplanation CVDefaultLanguageComponent =
+    "Packages using 'cabal-version: >= 1.10' and before 'cabal-version: 3.4' "
+      ++ "must specify the 'default-language' field for each component (e.g. "
+      ++ "Haskell98 or Haskell2010). If a component uses different languages "
+      ++ "in different modules then list the other ones in the "
+      ++ "'other-languages' field."
+ppExplanation CVExtraDocFiles =
+    "To use the 'extra-doc-files' field the package needs to specify "
+      ++ "'cabal-version: 1.18' or higher."
+ppExplanation CVMultiLib =
+    "To use multiple 'library' sections or a named library section "
+      ++ "the package needs to specify at least 'cabal-version: 2.0'."
+ppExplanation CVReexported =
+    "To use the 'reexported-module' field the package needs to specify "
+      ++ "'cabal-version: 1.22' or higher."
+ppExplanation CVMixins =
+    "To use the 'mixins' field the package needs to specify "
+      ++ "at least 'cabal-version: 2.0'."
+ppExplanation CVExtraFrameworkDirs =
+    "To use the 'extra-framework-dirs' field the package needs to specify"
+      ++ " 'cabal-version: 1.24' or higher."
+ppExplanation CVDefaultExtensions =
+    "To use the 'default-extensions' field the package needs to specify "
+      ++ "at least 'cabal-version: >= 1.10'."
+ppExplanation CVExtensionsDeprecated =
+    "For packages using 'cabal-version: >= 1.10' the 'extensions' "
+      ++ "field is deprecated. The new 'default-extensions' field lists "
+      ++ "extensions that are used in all modules in the component, while "
+      ++ "the 'other-extensions' field lists extensions that are used in "
+      ++ "some modules, e.g. via the {-# LANGUAGE #-} pragma."
+ppExplanation CVSources =
+    "The use of 'asm-sources', 'cmm-sources', 'extra-bundled-libraries' "
+      ++ " and 'extra-library-flavours' requires the package "
+      ++ " to specify at least 'cabal-version: 3.0'."
+ppExplanation (CVExtraDynamic flavs) =
+    "The use of 'extra-dynamic-library-flavours' requires the package "
+      ++ " to specify at least 'cabal-version: 3.0'. The flavours are: "
+      ++ commaSep (concat flavs)
+ppExplanation CVVirtualModules =
+    "The use of 'virtual-modules' requires the package "
+      ++ " to specify at least 'cabal-version: 2.2'."
+ppExplanation CVSourceRepository =
+    "The 'source-repository' section is new in Cabal 1.6. "
+      ++ "Unfortunately it messes up the parser in earlier Cabal versions "
+      ++ "so you need to specify 'cabal-version: >= 1.6'."
+ppExplanation (CVExtensions version extCab12) =
+    "Unfortunately the language extensions "
+      ++ commaSep (map (quote . prettyShow) extCab12)
+      ++ " break the parser in earlier Cabal versions so you need to "
+      ++ "specify 'cabal-version: >= " ++ showCabalSpecVersion version
+      ++ "'. Alternatively if you require compatibility with earlier "
+      ++ "Cabal versions then you may be able to use an equivalent "
+      ++ "compiler-specific flag."
+ppExplanation CVCustomSetup =
+    "Packages using 'cabal-version: 1.24' or higher with 'build-type: Custom' "
+      ++ "must use a 'custom-setup' section with a 'setup-depends' field "
+      ++ "that specifies the dependencies of the Setup.hs script itself. "
+      ++ "The 'setup-depends' field uses the same syntax as 'build-depends', "
+      ++ "so a simple example would be 'setup-depends: base, Cabal'."
+ppExplanation CVExpliticDepsCustomSetup =
+    "From version 1.24 cabal supports specifying explicit dependencies "
+      ++ "for Custom setup scripts. Consider using 'cabal-version: 1.24' or "
+      ++ "higher and adding a 'custom-setup' section with a 'setup-depends' "
+      ++ "field that specifies the dependencies of the Setup.hs script "
+      ++ "itself. The 'setup-depends' field uses the same syntax as "
+      ++ "'build-depends', so a simple example would be 'setup-depends: base, "
+      ++ "Cabal'."
+ppExplanation CVAutogenPaths =
+    "Packages using 'cabal-version: 2.0' and the autogenerated "
+      ++ "module Paths_* must include it also on the 'autogen-modules' field "
+      ++ "besides 'exposed-modules' and 'other-modules'. This specifies that "
+      ++ "the module does not come with the package and is generated on "
+      ++ "setup. Modules built with a custom Setup.hs script also go here "
+      ++ "to ensure that commands like sdist don't fail."
+ppExplanation CVAutogenPackageInfo =
+    "Packages using 'cabal-version: 2.0' and the autogenerated "
+      ++ "module PackageInfo_* must include it in 'autogen-modules' as well as"
+      ++ " 'exposed-modules' and 'other-modules'. This specifies that "
+      ++ "the module does not come with the package and is generated on "
+      ++ "setup. Modules built with a custom Setup.hs script also go here "
+      ++ "to ensure that commands like sdist don't fail."
+ppExplanation CVAutogenPackageInfoGuard =
+    "To use the autogenerated module PackageInfo_* you need to specify "
+      ++ "`cabal-version: 3.12` or higher. This is not possible in `cabal "
+      ++ "3.10`. To use this feature and be able to upload your package to "
+      ++ "Hackage, download `cabal 3.12`!"
+ppExplanation (GlobNoMatch field glob) =
+    "In '" ++ field ++ "': the pattern '" ++ glob ++ "' does not"
+      ++ " match any files."
+ppExplanation (GlobExactMatch field glob file) =
+    "In '" ++ field ++ "': the pattern '" ++ glob ++ "' does not"
+      ++ " match the file '" ++ file ++ "' because the extensions do not"
+      ++ " exactly match (e.g., foo.en.html does not exactly match *.html)."
+      ++ " To enable looser suffix-only matching, set 'cabal-version: 2.4' or"
+      ++ " higher."
+ppExplanation (GlobNoDir field glob dir) =
+    "In '" ++ field ++ "': the pattern '" ++ glob ++ "' attempts to"
+      ++ " match files in the directory '" ++ dir ++ "', but there is no"
+      ++ " directory by that name."
+ppExplanation (UnknownOS unknownOSs) =
+    "Unknown operating system name " ++ commaSep (map quote unknownOSs)
+ppExplanation (UnknownArch unknownArches) =
+    "Unknown architecture name " ++ commaSep (map quote unknownArches)
+ppExplanation (UnknownCompiler unknownImpls) =
+    "Unknown compiler name " ++ commaSep (map quote unknownImpls)
+ppExplanation (MissingUpperBounds names) =
+    let separator = "\n  - "
+    in
+    "These packages miss upper bounds:" ++ separator
+      ++ (intercalate separator (unPackageName <$> names)) ++ "\n"
+      ++  "Please add them, using `cabal gen-bounds` for suggestions."
+      ++ " For more information see: "
+      ++ " https://pvp.haskell.org/"
+ppExplanation BaseNoUpperBounds =
+    "The dependency 'build-depends: base' does not specify an upper "
+      ++ "bound on the version number. Each major release of the 'base' "
+      ++ "package changes the API in various ways and most packages will "
+      ++ "need some changes to compile with it. The recommended practice "
+      ++ "is to specify an upper bound on the version of the 'base' "
+      ++ "package. This ensures your package will continue to build when a "
+      ++ "new major version of the 'base' package is released. If you are "
+      ++ "not sure what upper bound to use then use the next  major "
+      ++ "version. For example if you have tested your package with 'base' "
+      ++ "version 4.5 and 4.6 then use 'build-depends: base >= 4.5 && < 4.7'."
+ppExplanation (SuspiciousFlagName invalidFlagNames) =
+    "Suspicious flag names: " ++ unwords invalidFlagNames ++ ". "
+      ++ "To avoid ambiguity in command line interfaces, flag shouldn't "
+      ++ "start with a dash. Also for better compatibility, flag names "
+      ++ "shouldn't contain non-ascii characters."
+ppExplanation (DeclaredUsedFlags declared used) =
+    "Declared and used flag sets differ: "
+      ++ s declared ++ " /= " ++ s used ++ ". "
+  where s :: Set.Set FlagName -> String
+        s = commaSep . map unFlagName . Set.toList
+ppExplanation (NonASCIICustomField nonAsciiXFields) =
+    "Non ascii custom fields: " ++ unwords nonAsciiXFields ++ ". "
+      ++ "For better compatibility, custom field names "
+      ++ "shouldn't contain non-ascii characters."
+ppExplanation RebindableClashPaths =
+    "Packages using RebindableSyntax with OverloadedStrings or"
+      ++ " OverloadedLists in default-extensions, in conjunction with the"
+      ++ " autogenerated module Paths_*, are known to cause compile failures"
+      ++ " with Cabal < 2.2. To use these default-extensions with a Paths_*"
+      ++ " autogen module, specify at least 'cabal-version: 2.2'."
+ppExplanation RebindableClashPackageInfo =
+    "Packages using RebindableSyntax with OverloadedStrings or"
+      ++ " OverloadedLists in default-extensions, in conjunction with the"
+      ++ " autogenerated module PackageInfo_*, are known to cause compile failures"
+      ++ " with Cabal < 2.2. To use these default-extensions with a PackageInfo_*"
+      ++ " autogen module, specify at least 'cabal-version: 2.2'."
+ppExplanation (WErrorUnneeded fieldName) = addConditionalExp $
+    "'" ++ fieldName ++ ": -Werror' makes the package easy to "
+      ++ "break with future GHC versions because new GHC versions often "
+      ++ "add new warnings."
+ppExplanation (JUnneeded fieldName) = addConditionalExp $
+    "'" ++ fieldName ++ ": -j[N]' can make sense for specific user's setup,"
+      ++ " but it is not appropriate for a distributed package."
+ppExplanation (FDeferTypeErrorsUnneeded fieldName) = addConditionalExp $
+    "'" ++ fieldName ++ ": -fdefer-type-errors' is fine during development "
+      ++ "but is not appropriate for a distributed package."
+ppExplanation (DynamicUnneeded fieldName) = addConditionalExp $
+    "'" ++ fieldName ++ ": -d*' debug flags are not appropriate "
+      ++ "for a distributed package."
+ppExplanation (ProfilingUnneeded fieldName) = addConditionalExp $
+    "'" ++ fieldName ++ ": -fprof*' profiling flags are typically not "
+      ++ "appropriate for a distributed library package. These flags are "
+      ++ "useful to profile this package, but when profiling other packages "
+      ++ "that use this one these flags clutter the profile output with "
+      ++ "excessive detail. If you think other packages really want to see "
+      ++ "cost centres from this package then use '-fprof-auto-exported' "
+      ++ "which puts cost centres only on exported functions."
+ppExplanation (UpperBoundSetup nm) =
+    "The dependency 'setup-depends: '"++nm++"' does not specify an "
+      ++ "upper bound on the version number. Each major release of the "
+      ++ "'"++nm++"' package changes the API in various ways and most "
+      ++ "packages will need some changes to compile with it. If you are "
+      ++ "not sure what upper bound to use then use the next major "
+      ++ "version."
+ppExplanation (DuplicateModule s dupLibsLax) =
+    "Duplicate modules in " ++ s ++ ": "
+      ++ commaSep (map prettyShow dupLibsLax)
+ppExplanation (PotentialDupModule s dupLibsStrict) =
+    "Potential duplicate modules (subject to conditionals) in " ++ s
+      ++ ": " ++ commaSep (map prettyShow dupLibsStrict)
+ppExplanation (BOMStart pdfile) =
+    pdfile ++ " starts with an Unicode byte order mark (BOM)."
+      ++ " This may cause problems with older cabal versions."
+ppExplanation (NotPackageName pdfile expectedCabalname) =
+    "The filename " ++ quote pdfile ++ " does not match package name "
+      ++ "(expected: " ++ quote expectedCabalname ++ ")"
+ppExplanation NoDesc =
+    "No cabal file found.\n"
+      ++ "Please create a package description file <pkgname>.cabal"
+ppExplanation (MultiDesc multiple) =
+    "Multiple cabal files found while checking.\n"
+      ++ "Please use only one of: "
+      ++ intercalate ", " multiple
+ppExplanation (UnknownFile fieldname file) =
+    "The '" ++ fieldname ++ "' field refers to the file "
+      ++ quote (getSymbolicPath file) ++ " which does not exist."
+ppExplanation MissingSetupFile =
+    "The package is missing a Setup.hs or Setup.lhs script."
+ppExplanation MissingConfigureScript =
+    "The 'build-type' is 'Configure' but there is no 'configure' script. "
+      ++ "You probably need to run 'autoreconf -i' to generate it."
+ppExplanation (UnknownDirectory kind dir) =
+    quote (kind ++ ": " ++ dir)
+      ++ " specifies a directory which does not exist."
+ppExplanation MissingSourceControl =
+    "When distributing packages it is encouraged to specify source "
+      ++ "control information in the .cabal file using one or more "
+      ++ "'source-repository' sections. See the Cabal user guide for "
+      ++ "details."
+ppExplanation (MissingExpectedDocFiles extraDocFileSupport paths) =
+    "Please consider including the " ++ quotes paths
+      ++ " in the '" ++ targetField ++ "' section of the .cabal file "
+      ++ "if it contains useful information for users of the package."
+  where quotes [p] = "file " ++ quote p
+        quotes ps = "files " ++ intercalate ", " (map quote ps)
+        targetField = if extraDocFileSupport
+                        then "extra-doc-files"
+                        else "extra-source-files"
+ppExplanation (WrongFieldForExpectedDocFiles extraDocFileSupport field paths) =
+    "Please consider moving the " ++ quotes paths
+      ++ " from the '" ++ field ++ "' section of the .cabal file "
+      ++ "to the section '" ++ targetField ++ "'."
+  where quotes [p] = "file " ++ quote p
+        quotes ps = "files " ++ intercalate ", " (map quote ps)
+        targetField = if extraDocFileSupport
+                        then "extra-doc-files"
+                        else "extra-source-files"
+
+
+-- | Results of some kind of failed package check.
+--
+-- There are a range of severities, from merely dubious to totally insane.
+-- All of them come with a human readable explanation. In future we may augment
+-- them with more machine readable explanations, for example to help an IDE
+-- suggest automatic corrections.
+--
+data PackageCheck =
+
+       -- | This package description is no good. There's no way it's going to
+       -- build sensibly. This should give an error at configure time.
+       PackageBuildImpossible { explanation :: CheckExplanation }
+
+       -- | A problem that is likely to affect building the package, or an
+       -- issue that we'd like every package author to be aware of, even if
+       -- the package is never distributed.
+     | PackageBuildWarning { explanation :: CheckExplanation }
+
+       -- | An issue that might not be a problem for the package author but
+       -- might be annoying or detrimental when the package is distributed to
+       -- users. We should encourage distributed packages to be free from these
+       -- issues, but occasionally there are justifiable reasons so we cannot
+       -- ban them entirely.
+     | PackageDistSuspicious { explanation :: CheckExplanation }
+
+       -- | Like PackageDistSuspicious but will only display warnings
+       -- rather than causing abnormal exit when you run 'cabal check'.
+     | PackageDistSuspiciousWarn { explanation :: CheckExplanation }
+
+       -- | An issue that is OK in the author's environment but is almost
+       -- certain to be a portability problem for other environments. We can
+       -- quite legitimately refuse to publicly distribute packages with these
+       -- problems.
+     | PackageDistInexcusable { explanation :: CheckExplanation }
+  deriving (Eq, Ord)
+
+-- | Pretty printing 'PackageCheck'.
+--
+ppPackageCheck :: PackageCheck -> String
+ppPackageCheck e = ppExplanation (explanation e)
+
+instance Show PackageCheck where
+    show notice = ppPackageCheck notice
+
+check :: Bool -> PackageCheck -> Maybe PackageCheck
+check False _  = Nothing
+check True  pc = Just pc
+
+checkSpecVersion :: PackageDescription -> CabalSpecVersion -> Bool -> PackageCheck
+                 -> Maybe PackageCheck
+checkSpecVersion pkg specver cond pc
+  | specVersion pkg >= specver  = Nothing
+  | otherwise                   = check cond pc
+
+-- ------------------------------------------------------------
+-- * Standard checks
+-- ------------------------------------------------------------
+
+-- | Check for common mistakes and problems in package descriptions.
+--
+-- This is the standard collection of checks covering all aspects except
+-- for checks that require looking at files within the package. For those
+-- see 'checkPackageFiles'.
+--
+-- It requires the 'GenericPackageDescription' and optionally a particular
+-- configuration of that package. If you pass 'Nothing' then we just check
+-- a version of the generic description using 'flattenPackageDescription'.
+--
+checkPackage :: GenericPackageDescription
+             -> Maybe PackageDescription
+             -> [PackageCheck]
+checkPackage gpkg mpkg =
+     checkConfiguredPackage pkg
+  ++ checkConditionals gpkg
+  ++ checkPackageVersions gpkg
+  ++ checkDevelopmentOnlyFlags gpkg
+  ++ checkFlagNames gpkg
+  ++ checkUnusedFlags gpkg
+  ++ checkUnicodeXFields gpkg
+  ++ checkPathsModuleExtensions pkg
+  ++ checkPackageInfoModuleExtensions pkg
+  ++ checkSetupVersions gpkg
+  ++ checkDuplicateModules gpkg
+  where
+    pkg = fromMaybe (flattenPackageDescription gpkg) mpkg
+
+--TODO: make this variant go away
+--      we should always know the GenericPackageDescription
+checkConfiguredPackage :: PackageDescription -> [PackageCheck]
+checkConfiguredPackage pkg =
+    checkSanity pkg
+ ++ checkFields pkg
+ ++ checkLicense pkg
+ ++ checkSourceRepos pkg
+ ++ checkAllGhcOptions pkg
+ ++ checkCCOptions pkg
+ ++ checkCxxOptions pkg
+ ++ checkCPPOptions pkg
+ ++ checkPaths pkg
+ ++ checkCabalVersion pkg
+
+
+-- ------------------------------------------------------------
+-- * Basic sanity checks
+-- ------------------------------------------------------------
+
+-- | Check that this package description is sane.
+--
+checkSanity :: PackageDescription -> [PackageCheck]
+checkSanity pkg =
+  catMaybes [
+
+    check (null . unPackageName . packageName $ pkg) $
+      PackageBuildImpossible NoNameField
+
+  , check (nullVersion == packageVersion pkg) $
+      PackageBuildImpossible NoVersionField
+
+  , check (all ($ pkg) [ null . executables
+                       , null . testSuites
+                       , null . benchmarks
+                       , null . allLibraries
+                       , null . foreignLibs ]) $
+      PackageBuildImpossible NoTarget
+
+  , check (any (== LMainLibName) (map libName $ subLibraries pkg)) $
+      PackageBuildImpossible UnnamedInternal
+
+  , check (not (null duplicateNames)) $
+      PackageBuildImpossible (DuplicateSections duplicateNames)
+
+  -- NB: but it's OK for executables to have the same name!
+  -- TODO shouldn't need to compare on the string level
+  , check (any (== prettyShow (packageName pkg))
+               (prettyShow <$> subLibNames)) $
+      PackageBuildImpossible (IllegalLibraryName pkg)
+  ]
+  --TODO: check for name clashes case insensitively: windows file systems cannot
+  --cope.
+
+  ++ concatMap (checkLibrary    pkg) (allLibraries pkg)
+  ++ concatMap (checkExecutable pkg) (executables pkg)
+  ++ concatMap (checkTestSuite  pkg) (testSuites pkg)
+  ++ concatMap (checkBenchmark  pkg) (benchmarks pkg)
+
+  where
+    -- The public 'library' gets special dispensation, because it
+    -- is common practice to export a library and name the executable
+    -- the same as the package.
+    subLibNames = mapMaybe (libraryNameString . libName) $ subLibraries pkg
+    exeNames = map exeName $ executables pkg
+    testNames = map testName $ testSuites pkg
+    bmNames = map benchmarkName $ benchmarks pkg
+    duplicateNames = dups $ subLibNames ++ exeNames ++ testNames ++ bmNames
+
+checkLibrary :: PackageDescription -> Library -> [PackageCheck]
+checkLibrary pkg lib =
+  catMaybes [
+
+  -- TODO: This check is bogus if a required-signature was passed through
+    check (null (explicitLibModules lib) && null (reexportedModules lib)) $
+      PackageDistSuspiciousWarn (NoModulesExposed lib)
+
+    -- check use of signatures sections
+  , checkVersion CabalSpecV2_0 (not (null (signatures lib))) $
+      PackageDistInexcusable SignaturesCabal2
+
+    -- check that all autogen-modules appear on other-modules or exposed-modules
+  , check
+      (not $ and $ map (flip elem (explicitLibModules lib)) (libModulesAutogen lib)) $
+      PackageBuildImpossible AutogenNotExposed
+
+    -- check that all autogen-includes appear on includes or install-includes
+  , check
+      (not $ and $ map (flip elem (allExplicitIncludes lib)) (view L.autogenIncludes lib)) $
+      PackageBuildImpossible AutogenIncludesNotIncluded
+  ]
+
+  where
+    checkVersion :: CabalSpecVersion -> Bool -> PackageCheck -> Maybe PackageCheck
+    checkVersion ver cond pc
+      | specVersion pkg >= ver = Nothing
+      | otherwise              = check cond pc
+
+allExplicitIncludes :: L.HasBuildInfo a => a -> [FilePath]
+allExplicitIncludes x = view L.includes x ++ view L.installIncludes x
+
+checkExecutable :: PackageDescription -> Executable -> [PackageCheck]
+checkExecutable pkg exe =
+  catMaybes [
+
+    check (null (modulePath exe)) $
+      PackageBuildImpossible (NoMainIs exe)
+
+  -- This check does not apply to scripts.
+  , check (package pkg /= fakePackageId
+       && not (null (modulePath exe))
+       && not (fileExtensionSupportedLanguage $ modulePath exe)) $
+      PackageBuildImpossible NoHsLhsMain
+
+  , checkSpecVersion pkg CabalSpecV1_18
+          (fileExtensionSupportedLanguage (modulePath exe)
+        && takeExtension (modulePath exe) `notElem` [".hs", ".lhs"]) $
+      PackageDistInexcusable MainCCabal1_18
+
+    -- check that all autogen-modules appear on other-modules
+  , check
+      (not $ and $ map (flip elem (exeModules exe)) (exeModulesAutogen exe)) $
+      PackageBuildImpossible (AutogenNoOther CETExecutable (exeName exe))
+
+    -- check that all autogen-includes appear on includes
+  , check
+      (not $ and $ map (flip elem (view L.includes exe)) (view L.autogenIncludes exe)) $
+      PackageBuildImpossible AutogenIncludesNotIncludedExe
+  ]
+
+checkTestSuite :: PackageDescription -> TestSuite -> [PackageCheck]
+checkTestSuite pkg test =
+  catMaybes [
+
+    case testInterface test of
+      TestSuiteUnsupported tt@(TestTypeUnknown _ _) -> Just $
+        PackageBuildWarning (TestsuiteTypeNotKnown tt)
+
+      TestSuiteUnsupported tt -> Just $
+        PackageBuildWarning (TestsuiteNotSupported tt)
+      _ -> Nothing
+
+  , check mainIsWrongExt $
+      PackageBuildImpossible NoHsLhsMain
+
+  , checkSpecVersion pkg CabalSpecV1_18 (mainIsNotHsExt && not mainIsWrongExt) $
+      PackageDistInexcusable MainCCabal1_18
+
+    -- check that all autogen-modules appear on other-modules
+  , check
+      (not $ and $ map (flip elem (testModules test)) (testModulesAutogen test)) $
+      PackageBuildImpossible (AutogenNoOther CETTest (testName test))
+
+    -- check that all autogen-includes appear on includes
+  , check
+      (not $ and $ map (flip elem (view L.includes test)) (view L.autogenIncludes test)) $
+      PackageBuildImpossible AutogenIncludesNotIncludedExe
+  ]
+  where
+    mainIsWrongExt = case testInterface test of
+      TestSuiteExeV10 _ f -> not $ fileExtensionSupportedLanguage f
+      _                   -> False
+
+    mainIsNotHsExt = case testInterface test of
+      TestSuiteExeV10 _ f -> takeExtension f `notElem` [".hs", ".lhs"]
+      _                   -> False
+
+checkBenchmark :: PackageDescription -> Benchmark -> [PackageCheck]
+checkBenchmark _pkg bm =
+  catMaybes [
+
+    case benchmarkInterface bm of
+      BenchmarkUnsupported tt@(BenchmarkTypeUnknown _ _) -> Just $
+        PackageBuildWarning (BenchmarkTypeNotKnown tt)
+
+      BenchmarkUnsupported tt -> Just $
+        PackageBuildWarning (BenchmarkNotSupported tt)
+      _ -> Nothing
+
+  , check mainIsWrongExt $
+      PackageBuildImpossible NoHsLhsMainBench
+
+    -- check that all autogen-modules appear on other-modules
+  , check
+      (not $ and $ map (flip elem (benchmarkModules bm)) (benchmarkModulesAutogen bm)) $
+      PackageBuildImpossible (AutogenNoOther CETBenchmark (benchmarkName bm))
+
+    -- check that all autogen-includes appear on includes
+  , check
+      (not $ and $ map (flip elem (view L.includes bm)) (view L.autogenIncludes bm)) $
+      PackageBuildImpossible AutogenIncludesNotIncludedExe
+  ]
+  where
+    mainIsWrongExt = case benchmarkInterface bm of
+      BenchmarkExeV10 _ f -> takeExtension f `notElem` [".hs", ".lhs"]
+      _                   -> False
+
+-- ------------------------------------------------------------
+-- * Additional pure checks
+-- ------------------------------------------------------------
+
+checkFields :: PackageDescription -> [PackageCheck]
+checkFields pkg =
+  catMaybes [
+
+    check (not . FilePath.Windows.isValid . prettyShow . packageName $ pkg) $
+      PackageDistInexcusable (InvalidNameWin pkg)
+
+  , check (isPrefixOf "z-" . prettyShow . packageName $ pkg) $
+      PackageDistInexcusable ZPrefix
+
+  , check (isNothing (buildTypeRaw pkg) && specVersion pkg < CabalSpecV2_2) $
+      PackageBuildWarning NoBuildType
+
+  , check (isJust (setupBuildInfo pkg) && buildType pkg /= Custom) $
+      PackageBuildWarning NoCustomSetup
+
+  , check (not (null unknownCompilers)) $
+      PackageBuildWarning (UnknownCompilers unknownCompilers)
+
+  , check (not (null unknownLanguages)) $
+      PackageBuildWarning (UnknownLanguages unknownLanguages)
+
+  , check (not (null unknownExtensions)) $
+      PackageBuildWarning (UnknownExtensions unknownExtensions)
+
+  , check (not (null languagesUsedAsExtensions)) $
+      PackageBuildWarning (LanguagesAsExtension languagesUsedAsExtensions)
+
+  , check (not (null ourDeprecatedExtensions)) $
+      PackageDistSuspicious (DeprecatedExtensions ourDeprecatedExtensions)
+
+  , check (ShortText.null (category pkg)) $
+      PackageDistSuspicious (MissingField CEFCategory)
+
+  , check (ShortText.null (maintainer pkg)) $
+      PackageDistSuspicious (MissingField CEFMaintainer)
+
+  , check (ShortText.null (synopsis pkg) && ShortText.null (description pkg)) $
+      PackageDistInexcusable (MissingField CEFSynOrDesc)
+
+  , check (ShortText.null (description pkg) && not (ShortText.null (synopsis pkg))) $
+      PackageDistSuspicious (MissingField CEFDescription)
+
+  , check (ShortText.null (synopsis pkg) && not (ShortText.null (description pkg))) $
+      PackageDistSuspicious (MissingField CEFSynopsis)
+
+    --TODO: recommend the bug reports URL, author and homepage fields
+    --TODO: recommend not using the stability field
+    --TODO: recommend specifying a source repo
+
+  , check (ShortText.length (synopsis pkg) > 80) $
+      PackageDistSuspicious SynopsisTooLong
+
+    -- See also https://github.com/haskell/cabal/pull/3479
+  , check (not (ShortText.null (description pkg))
+           && ShortText.length (description pkg) <= ShortText.length (synopsis pkg)) $
+      PackageDistSuspicious ShortDesc
+
+    -- check use of impossible constraints "tested-with: GHC== 6.10 && ==6.12"
+  , check (not (null testedWithImpossibleRanges)) $
+      PackageDistInexcusable (InvalidTestWith testedWithImpossibleRanges)
+
+  -- for more details on why the following was commented out,
+  -- check https://github.com/haskell/cabal/pull/7470#issuecomment-875878507
+  -- , check (not (null depInternalLibraryWithExtraVersion)) $
+  --     PackageBuildWarning $
+  --          "The package has an extraneous version range for a dependency on an "
+  --       ++ "internal library: "
+  --       ++ commaSep (map prettyShow depInternalLibraryWithExtraVersion)
+  --       ++ ". This version range includes the current package but isn't needed "
+  --       ++ "as the current package's library will always be used."
+
+  , check (not (null depInternalLibraryWithImpossibleVersion)) $
+      PackageBuildImpossible
+        (ImpossibleInternalDep depInternalLibraryWithImpossibleVersion)
+
+  -- , check (not (null depInternalExecutableWithExtraVersion)) $
+  --     PackageBuildWarning $
+  --          "The package has an extraneous version range for a dependency on an "
+  --       ++ "internal executable: "
+  --       ++ commaSep (map prettyShow depInternalExecutableWithExtraVersion)
+  --       ++ ". This version range includes the current package but isn't needed "
+  --       ++ "as the current package's executable will always be used."
+
+  , check (not (null depInternalExecutableWithImpossibleVersion)) $
+      PackageBuildImpossible
+        (ImpossibleInternalExe depInternalExecutableWithImpossibleVersion)
+
+  , check (not (null depMissingInternalExecutable)) $
+      PackageBuildImpossible (MissingInternalExe depMissingInternalExecutable)
+  ]
+  where
+    unknownCompilers  = [ name | (OtherCompiler name, _) <- testedWith pkg ]
+    unknownLanguages  = [ name | bi <- allBuildInfo pkg
+                               , UnknownLanguage name <- allLanguages bi ]
+    unknownExtensions = filter (/= "TypeAbstractions")
+                          [ name | bi <- allBuildInfo pkg
+                                 , UnknownExtension name <- allExtensions bi
+                                 , name `notElem` map prettyShow knownLanguages ]
+    ourDeprecatedExtensions = nub $ catMaybes
+      [ find ((==ext) . fst) deprecatedExtensions
+      | bi <- allBuildInfo pkg
+      , ext <- allExtensions bi ]
+    languagesUsedAsExtensions =
+      [ name | bi <- allBuildInfo pkg
+             , UnknownExtension name <- allExtensions bi
+             , name `elem` map prettyShow knownLanguages ]
+
+    testedWithImpossibleRanges =
+      [ Dependency (mkPackageName (prettyShow compiler)) vr mainLibSet
+      | (compiler, vr) <- testedWith pkg
+      , isNoVersion vr ]
+
+    internalExecutables = map exeName $ executables pkg
+
+    internalLibDeps =
+      [ dep
+      | bi <- allBuildInfo pkg
+      , dep@(Dependency name _ _) <- targetBuildDepends bi
+      , name == packageName pkg
+      ]
+
+    internalExeDeps =
+      [ dep
+      | bi <- allBuildInfo pkg
+      , dep <- getAllToolDependencies pkg bi
+      , isInternal pkg dep
+      ]
+
+    -- depInternalLibraryWithExtraVersion =
+    --   [ dep
+    --   | dep@(Dependency _ versionRange _) <- internalLibDeps
+    --   , not $ isAnyVersion versionRange
+    --   , packageVersion pkg `withinRange` versionRange
+    --   ]
+
+    depInternalLibraryWithImpossibleVersion =
+      [ dep
+      | dep@(Dependency _ versionRange _) <- internalLibDeps
+      , not $ packageVersion pkg `withinRange` versionRange
+      ]
+
+    -- depInternalExecutableWithExtraVersion =
+    --   [ dep
+    --   | dep@(ExeDependency _ _ versionRange) <- internalExeDeps
+    --   , not $ isAnyVersion versionRange
+    --   , packageVersion pkg `withinRange` versionRange
+    --   ]
+
+    depInternalExecutableWithImpossibleVersion =
+      [ dep
+      | dep@(ExeDependency _ _ versionRange) <- internalExeDeps
+      , not $ packageVersion pkg `withinRange` versionRange
+      ]
+
+    depMissingInternalExecutable =
+      [ dep
+      | dep@(ExeDependency _ eName _) <- internalExeDeps
+      , not $ eName `elem` internalExecutables
+      ]
+
+checkLicense :: PackageDescription -> [PackageCheck]
+checkLicense pkg = case licenseRaw pkg of
+    Right l -> checkOldLicense pkg l
+    Left  l -> checkNewLicense pkg l
+
+checkNewLicense :: PackageDescription -> SPDX.License -> [PackageCheck]
+checkNewLicense _pkg lic = catMaybes
+    [ check (lic == SPDX.NONE) $
+        PackageDistInexcusable NONELicense ]
+
+checkOldLicense :: PackageDescription -> License -> [PackageCheck]
+checkOldLicense pkg lic = catMaybes
+  [ check (lic == UnspecifiedLicense) $
+      PackageDistInexcusable NoLicense
+
+  , check (lic == AllRightsReserved) $
+      PackageDistSuspicious AllRightsReservedLicense
+
+  , checkVersion CabalSpecV1_4 (lic `notElem` compatLicenses) $
+      PackageDistInexcusable (LicenseMessParse pkg)
+
+  , case lic of
+      UnknownLicense l -> Just $ PackageBuildWarning (UnrecognisedLicense l)
+      _ -> Nothing
+
+  , check (lic == BSD4) $
+      PackageDistSuspicious UncommonBSD4
+
+  , case unknownLicenseVersion lic of
+      Just knownVersions -> Just $
+        PackageDistSuspicious (UnknownLicenseVersion lic knownVersions)
+      _ -> Nothing
+
+  , check (lic `notElem` [ AllRightsReserved
+                                 , UnspecifiedLicense, PublicDomain]
+           -- AllRightsReserved and PublicDomain are not strictly
+           -- licenses so don't need license files.
+        && null (licenseFiles pkg)) $
+      PackageDistSuspicious NoLicenseFile
+  ]
+  where
+    unknownLicenseVersion (GPL  (Just v))
+      | v `notElem` knownVersions = Just knownVersions
+      where knownVersions = [ v' | GPL  (Just v') <- knownLicenses ]
+    unknownLicenseVersion (LGPL (Just v))
+      | v `notElem` knownVersions = Just knownVersions
+      where knownVersions = [ v' | LGPL (Just v') <- knownLicenses ]
+    unknownLicenseVersion (AGPL (Just v))
+      | v `notElem` knownVersions = Just knownVersions
+      where knownVersions = [ v' | AGPL (Just v') <- knownLicenses ]
+    unknownLicenseVersion (Apache  (Just v))
+      | v `notElem` knownVersions = Just knownVersions
+      where knownVersions = [ v' | Apache  (Just v') <- knownLicenses ]
+    unknownLicenseVersion _ = Nothing
+
+    checkVersion :: CabalSpecVersion -> Bool -> PackageCheck -> Maybe PackageCheck
+    checkVersion ver cond pc
+      | specVersion pkg >= ver  = Nothing
+      | otherwise               = check cond pc
+
+    compatLicenses = [ GPL Nothing, LGPL Nothing, AGPL Nothing, BSD3, BSD4
+                     , PublicDomain, AllRightsReserved
+                     , UnspecifiedLicense, OtherLicense ]
+
+checkSourceRepos :: PackageDescription -> [PackageCheck]
+checkSourceRepos pkg =
+  catMaybes $ concat [[
+
+    case repoKind repo of
+      RepoKindUnknown kind -> Just $ PackageDistInexcusable $
+        UnrecognisedSourceRepo kind
+      _ -> Nothing
+
+  , check (isNothing (repoType repo)) $
+      PackageDistInexcusable MissingType
+
+  , check (isNothing (repoLocation repo)) $
+      PackageDistInexcusable MissingLocation
+
+  , check (repoType repo == Just (KnownRepoType CVS) && isNothing (repoModule repo)) $
+      PackageDistInexcusable MissingModule
+
+  , check (repoKind repo == RepoThis && isNothing (repoTag repo)) $
+      PackageDistInexcusable MissingTag
+
+  , check (maybe False isAbsoluteOnAnyPlatform (repoSubdir repo)) $
+      PackageDistInexcusable SubdirRelPath
+
+  , do
+      subdir <- repoSubdir repo
+      err    <- isGoodRelativeDirectoryPath subdir
+      return $ PackageDistInexcusable (SubdirGoodRelPath err)
+  ]
+  | repo <- sourceRepos pkg ]
+
+--TODO: check location looks like a URL for some repo types.
+
+-- | Checks GHC options from all ghc-*-options fields in the given
+-- PackageDescription and reports commonly misused or non-portable flags
+checkAllGhcOptions :: PackageDescription -> [PackageCheck]
+checkAllGhcOptions pkg =
+    checkGhcOptions "ghc-options" (hcOptions GHC) pkg
+ ++ checkGhcOptions "ghc-prof-options" (hcProfOptions GHC) pkg
+ ++ checkGhcOptions "ghc-shared-options" (hcSharedOptions GHC) pkg
+
+-- | Extracts GHC options belonging to the given field from the given
+-- PackageDescription using given function and checks them for commonly misused
+-- or non-portable flags
+checkGhcOptions :: String -> (BuildInfo -> [String]) -> PackageDescription -> [PackageCheck]
+checkGhcOptions fieldName getOptions pkg =
+  catMaybes [
+
+    checkFlags ["-fasm"] $
+      PackageDistInexcusable (OptFasm fieldName)
+
+  , checkFlags ["-fvia-C"] $
+      PackageDistSuspicious (OptViaC fieldName)
+
+  , checkFlags ["-fhpc"] $
+      PackageDistInexcusable (OptHpc fieldName)
+
+  , checkFlags ["-prof"] $
+      PackageBuildWarning (OptProf fieldName)
+
+  , unlessScript . checkFlags ["-o"] $
+      PackageBuildWarning (OptO fieldName)
+
+  , checkFlags ["-hide-package"] $
+      PackageBuildWarning (OptHide fieldName)
+
+  , checkFlags ["--make"] $
+      PackageBuildWarning (OptMake fieldName)
+
+  , checkNonTestAndBenchmarkFlags ["-O0", "-Onot"] $
+      PackageDistSuspicious (OptONot fieldName)
+
+  , checkTestAndBenchmarkFlags ["-O0", "-Onot"] $
+      PackageDistSuspiciousWarn (OptONot fieldName)
+
+  , checkFlags [ "-O", "-O1"] $
+      PackageDistInexcusable (OptOOne fieldName)
+
+  , checkFlags ["-O2"] $
+      PackageDistSuspiciousWarn (OptOTwo fieldName)
+
+  , checkFlags ["-split-sections"] $
+      PackageBuildWarning (OptSplitSections fieldName)
+
+  , checkFlags ["-split-objs"] $
+      PackageBuildWarning (OptSplitObjs fieldName)
+
+  , checkFlags ["-optl-Wl,-s", "-optl-s"] $
+      PackageDistInexcusable (OptWls fieldName)
+
+  , checkFlags ["-fglasgow-exts"] $
+      PackageDistSuspicious (OptExts fieldName)
+
+  , check ("-rtsopts" `elem` lib_ghc_options) $
+      PackageBuildWarning (OptRts fieldName)
+
+  , check (any (\opt -> "-with-rtsopts" `isPrefixOf` opt) lib_ghc_options) $
+      PackageBuildWarning (OptWithRts fieldName)
+
+  , checkAlternatives fieldName "extensions"
+      [ (flag, prettyShow extension) | flag <- ghc_options_no_rtsopts
+                                  , Just extension <- [ghcExtension flag] ]
+
+  , checkAlternatives fieldName "extensions"
+      [ (flag, extension) | flag@('-':'X':extension) <- ghc_options_no_rtsopts ]
+
+  , checkAlternatives fieldName "cpp-options" $
+         [ (flag, flag) | flag@('-':'D':_) <- ghc_options_no_rtsopts ]
+      ++ [ (flag, flag) | flag@('-':'U':_) <- ghc_options_no_rtsopts ]
+
+  , checkAlternatives fieldName "include-dirs"
+      [ (flag, dir) | flag@('-':'I':dir) <- ghc_options_no_rtsopts ]
+
+  , checkAlternatives fieldName "extra-libraries"
+      [ (flag, lib) | flag@('-':'l':lib) <- ghc_options_no_rtsopts ]
+
+  , checkAlternatives fieldName "extra-libraries-static"
+      [ (flag, lib) | flag@('-':'l':lib) <- ghc_options_no_rtsopts ]
+
+  , checkAlternatives fieldName "extra-lib-dirs"
+      [ (flag, dir) | flag@('-':'L':dir) <- ghc_options_no_rtsopts ]
+
+  , checkAlternatives fieldName "extra-lib-dirs-static"
+      [ (flag, dir) | flag@('-':'L':dir) <- ghc_options_no_rtsopts ]
+
+  , checkAlternatives fieldName "frameworks"
+      [ (flag, fmwk) | (flag@"-framework", fmwk) <-
+           zip ghc_options_no_rtsopts (safeTail ghc_options_no_rtsopts) ]
+
+  , checkAlternatives fieldName "extra-framework-dirs"
+      [ (flag, dir) | (flag@"-framework-path", dir) <-
+           zip ghc_options_no_rtsopts (safeTail ghc_options_no_rtsopts) ]
+  ]
+
+  where
+    all_ghc_options    = concatMap getOptions (allBuildInfo pkg)
+    ghc_options_no_rtsopts = rmRtsOpts all_ghc_options
+    lib_ghc_options    = concatMap (getOptions . libBuildInfo)
+                         (allLibraries pkg)
+    test_ghc_options      = concatMap (getOptions . testBuildInfo)
+                            (testSuites pkg)
+    benchmark_ghc_options = concatMap (getOptions . benchmarkBuildInfo)
+                            (benchmarks pkg)
+    test_and_benchmark_ghc_options     = test_ghc_options ++
+                                         benchmark_ghc_options
+    non_test_and_benchmark_ghc_options = concatMap getOptions
+                                         (allBuildInfo (pkg { testSuites = []
+                                                            , benchmarks = []
+                                                            }))
+
+    checkFlags :: [String] -> PackageCheck -> Maybe PackageCheck
+    checkFlags flags = check (any (`elem` flags) all_ghc_options)
+
+    unlessScript :: Maybe PackageCheck -> Maybe PackageCheck
+    unlessScript pc | packageId pkg == fakePackageId = Nothing
+                    | otherwise                      = pc
+
+    checkTestAndBenchmarkFlags :: [String] -> PackageCheck -> Maybe PackageCheck
+    checkTestAndBenchmarkFlags flags = check (any (`elem` flags) test_and_benchmark_ghc_options)
+
+    checkNonTestAndBenchmarkFlags :: [String] -> PackageCheck -> Maybe PackageCheck
+    checkNonTestAndBenchmarkFlags flags = check (any (`elem` flags) non_test_and_benchmark_ghc_options)
+
+    ghcExtension ('-':'f':name) = case name of
+      "allow-overlapping-instances"    -> enable  OverlappingInstances
+      "no-allow-overlapping-instances" -> disable OverlappingInstances
+      "th"                             -> enable  TemplateHaskell
+      "no-th"                          -> disable TemplateHaskell
+      "ffi"                            -> enable  ForeignFunctionInterface
+      "no-ffi"                         -> disable ForeignFunctionInterface
+      "fi"                             -> enable  ForeignFunctionInterface
+      "no-fi"                          -> disable ForeignFunctionInterface
+      "monomorphism-restriction"       -> enable  MonomorphismRestriction
+      "no-monomorphism-restriction"    -> disable MonomorphismRestriction
+      "mono-pat-binds"                 -> enable  MonoPatBinds
+      "no-mono-pat-binds"              -> disable MonoPatBinds
+      "allow-undecidable-instances"    -> enable  UndecidableInstances
+      "no-allow-undecidable-instances" -> disable UndecidableInstances
+      "allow-incoherent-instances"     -> enable  IncoherentInstances
+      "no-allow-incoherent-instances"  -> disable IncoherentInstances
+      "arrows"                         -> enable  Arrows
+      "no-arrows"                      -> disable Arrows
+      "generics"                       -> enable  Generics
+      "no-generics"                    -> disable Generics
+      "implicit-prelude"               -> enable  ImplicitPrelude
+      "no-implicit-prelude"            -> disable ImplicitPrelude
+      "implicit-params"                -> enable  ImplicitParams
+      "no-implicit-params"             -> disable ImplicitParams
+      "bang-patterns"                  -> enable  BangPatterns
+      "no-bang-patterns"               -> disable BangPatterns
+      "scoped-type-variables"          -> enable  ScopedTypeVariables
+      "no-scoped-type-variables"       -> disable ScopedTypeVariables
+      "extended-default-rules"         -> enable  ExtendedDefaultRules
+      "no-extended-default-rules"      -> disable ExtendedDefaultRules
+      _                                -> Nothing
+    ghcExtension "-cpp"             = enable CPP
+    ghcExtension _                  = Nothing
+
+    enable  e = Just (EnableExtension e)
+    disable e = Just (DisableExtension e)
+
+    rmRtsOpts :: [String] -> [String]
+    rmRtsOpts ("-with-rtsopts":_:xs) = rmRtsOpts xs
+    rmRtsOpts (x:xs) = x : rmRtsOpts xs
+    rmRtsOpts [] = []
+
+
+checkCCOptions :: PackageDescription -> [PackageCheck]
+checkCCOptions = checkCLikeOptions "C" "cc-options" ccOptions
+
+checkCxxOptions :: PackageDescription -> [PackageCheck]
+checkCxxOptions = checkCLikeOptions "C++" "cxx-options" cxxOptions
+
+checkCLikeOptions :: String -> String -> (BuildInfo -> [String]) -> PackageDescription -> [PackageCheck]
+checkCLikeOptions label prefix accessor pkg =
+  catMaybes [
+
+    checkAlternatives prefix "include-dirs"
+      [ (flag, dir) | flag@('-':'I':dir) <- all_cLikeOptions ]
+
+  , checkAlternatives prefix "extra-libraries"
+      [ (flag, lib) | flag@('-':'l':lib) <- all_cLikeOptions ]
+
+  , checkAlternatives prefix "extra-lib-dirs"
+      [ (flag, dir) | flag@('-':'L':dir) <- all_cLikeOptions ]
+
+  , checkAlternatives "ld-options" "extra-libraries"
+      [ (flag, lib) | flag@('-':'l':lib) <- all_ldOptions ]
+
+  , checkAlternatives "ld-options" "extra-lib-dirs"
+      [ (flag, dir) | flag@('-':'L':dir) <- all_ldOptions ]
+
+  , checkCCFlags [ "-O", "-Os", "-O0", "-O1", "-O2", "-O3" ] $
+      PackageDistSuspicious (COptONumber prefix label)
+  ]
+
+  where all_cLikeOptions = [ opts | bi <- allBuildInfo pkg
+                                  , opts <- accessor bi ]
+        all_ldOptions = [ opts | bi <- allBuildInfo pkg
+                               , opts <- ldOptions bi ]
+
+        checkCCFlags :: [String] -> PackageCheck -> Maybe PackageCheck
+        checkCCFlags flags = check (any (`elem` flags) all_cLikeOptions)
+
+checkCPPOptions :: PackageDescription -> [PackageCheck]
+checkCPPOptions pkg = catMaybes
+    [ checkAlternatives "cpp-options" "include-dirs"
+      [ (flag, dir) | flag@('-':'I':dir) <- all_cppOptions ]
+    ]
+    ++
+    [ PackageBuildWarning (COptCPP opt)
+    | opt <- all_cppOptions
+    -- "-I" is handled above, we allow only -DNEWSTUFF and -UOLDSTUFF
+    , not $ any (`isPrefixOf` opt) ["-D", "-U", "-I" ]
+    ]
+  where
+    all_cppOptions = [ opts | bi <- allBuildInfo pkg, opts <- cppOptions bi ]
+
+checkAlternatives :: String -> String -> [(String, String)]
+                  -> Maybe PackageCheck
+checkAlternatives badField goodField flags =
+  check (not (null badFlags)) $
+    PackageBuildWarning (OptAlternatives badField goodField flags)
+  where (badFlags, _) = unzip flags
+
+data PathKind
+    = PathKindFile
+    | PathKindDirectory
+    | PathKindGlob
+  deriving (Eq)
+
+checkPaths :: PackageDescription -> [PackageCheck]
+checkPaths pkg =
+  checkPackageFileNamesWithGlob
+  [ (kind == PathKindGlob, path)
+  | (path, _, kind) <- relPaths ++ absPaths
+  ]
+  ++
+  [ PackageBuildWarning (RelativeOutside field path)
+  | (path, field, _) <- relPaths ++ absPaths
+  , isOutsideTree path ]
+  ++
+  [ PackageDistInexcusable (AbsolutePath field path)
+  | (path, field, _) <- relPaths
+  , isAbsoluteOnAnyPlatform path ]
+  ++
+  [ PackageDistInexcusable (BadRelativePAth field path err)
+  | (path, field, kind) <- relPaths
+  -- these are not paths, but globs...
+  , err <- maybeToList $ case kind of
+      PathKindFile      -> isGoodRelativeFilePath path
+      PathKindGlob      -> isGoodRelativeGlob path
+      PathKindDirectory -> isGoodRelativeDirectoryPath path
+  ]
+  ++
+  [ PackageDistInexcusable $ DistPoint (Just field) path
+  | (path, field, _) <- relPaths ++ absPaths
+  , isInsideDist path ]
+  ++
+  [ PackageDistInexcusable (DistPoint Nothing path)
+  | bi <- allBuildInfo pkg
+  , (GHC, flags) <- perCompilerFlavorToList $ options bi
+  , path <- flags
+  , isInsideDist path ]
+  ++
+  [ PackageDistInexcusable $
+      GlobSyntaxError "data-files" (explainGlobSyntaxError pat err)
+  | (Left err, pat) <- zip globsDataFiles $ dataFiles pkg
+  ]
+  ++
+  [ PackageDistInexcusable
+      (GlobSyntaxError "extra-source-files" (explainGlobSyntaxError pat err))
+  | (Left err, pat) <- zip globsExtraSrcFiles $ extraSrcFiles pkg
+  ]
+  ++
+  [ PackageDistInexcusable $
+      GlobSyntaxError "extra-doc-files" (explainGlobSyntaxError pat err)
+  | (Left err, pat) <- zip globsExtraDocFiles $ extraDocFiles pkg
+  ]
+  ++
+  [ PackageDistSuspiciousWarn $
+      RecursiveGlobInRoot "data-files" pat
+  | (Right glob, pat) <- zip globsDataFiles $ dataFiles pkg
+  , isRecursiveInRoot glob
+  ]
+  ++
+  [ PackageDistSuspiciousWarn $
+      RecursiveGlobInRoot "extra-source-files" pat
+  | (Right glob, pat) <- zip globsExtraSrcFiles $ extraSrcFiles pkg
+  , isRecursiveInRoot glob
+  ]
+  ++
+  [ PackageDistSuspiciousWarn $
+      RecursiveGlobInRoot "extra-doc-files" pat
+  | (Right glob, pat) <- zip globsExtraDocFiles $ extraDocFiles pkg
+  , isRecursiveInRoot glob
+  ]
+  where
+    isOutsideTree path = case splitDirectories path of
+      "..":_     -> True
+      ".":"..":_ -> True
+      _          -> False
+    isInsideDist path = case map lowercase (splitDirectories path) of
+      "dist"    :_ -> True
+      ".":"dist":_ -> True
+      _            -> False
+
+    -- paths that must be relative
+    relPaths :: [(FilePath, String, PathKind)]
+    relPaths =
+      [ (path, "extra-source-files", PathKindGlob)      | path <- extraSrcFiles pkg ] ++
+      [ (path, "extra-tmp-files",    PathKindFile)      | path <- extraTmpFiles pkg ] ++
+      [ (path, "extra-doc-files",    PathKindGlob)      | path <- extraDocFiles pkg ] ++
+      [ (path, "data-files",         PathKindGlob)      | path <- dataFiles     pkg ] ++
+      [ (path, "data-dir",           PathKindDirectory) | path <- [dataDir      pkg]] ++
+      [ (path, "license-file",       PathKindFile)      | path <- map getSymbolicPath $ licenseFiles  pkg ] ++
+      concat
+        [ [ (path, "asm-sources",      PathKindFile)      | path <- asmSources      bi ] ++
+          [ (path, "cmm-sources",      PathKindFile)      | path <- cmmSources      bi ] ++
+          [ (path, "c-sources",        PathKindFile)      | path <- cSources        bi ] ++
+          [ (path, "cxx-sources",      PathKindFile)      | path <- cxxSources      bi ] ++
+          [ (path, "js-sources",       PathKindFile)      | path <- jsSources       bi ] ++
+          [ (path, "install-includes", PathKindFile)      | path <- installIncludes bi ] ++
+          [ (path, "hs-source-dirs",   PathKindDirectory) | path <- map getSymbolicPath $ hsSourceDirs bi ]
+        | bi <- allBuildInfo pkg
+        ]
+
+    -- paths that are allowed to be absolute
+    absPaths :: [(FilePath, String, PathKind)]
+    absPaths = concat
+      [ [ (path, "includes",       PathKindFile)      | path <- includes     bi ] ++
+        [ (path, "include-dirs",   PathKindDirectory) | path <- includeDirs  bi ] ++
+        [ (path, "extra-lib-dirs", PathKindDirectory) | path <- extraLibDirs bi ] ++
+        [ (path, "extra-lib-dirs-static", PathKindDirectory) | path <- extraLibDirsStatic bi ]
+      | bi <- allBuildInfo pkg
+      ]
+    globsDataFiles :: [Either GlobSyntaxError Glob]
+    globsDataFiles =  parseFileGlob (specVersion pkg) <$> dataFiles pkg
+    globsExtraSrcFiles :: [Either GlobSyntaxError Glob]
+    globsExtraSrcFiles =  parseFileGlob (specVersion pkg) <$> extraSrcFiles pkg
+    globsExtraDocFiles :: [Either GlobSyntaxError Glob]
+    globsExtraDocFiles =  parseFileGlob (specVersion pkg) <$> extraDocFiles pkg
+
+--TODO: check sets of paths that would be interpreted differently between Unix
+-- and windows, ie case-sensitive or insensitive. Things that might clash, or
+-- conversely be distinguished.
+
+--TODO: use the tar path checks on all the above paths
+
+-- | Check that the package declares the version in the @\"cabal-version\"@
+-- field correctly.
+--
+checkCabalVersion :: PackageDescription -> [PackageCheck]
+checkCabalVersion pkg =
+  catMaybes [
+
+    -- check use of test suite sections
+    checkVersion CabalSpecV1_8 (not (null $ testSuites pkg)) $
+      PackageDistInexcusable CVTestSuite
+
+    -- check use of default-language field
+    -- note that we do not need to do an equivalent check for the
+    -- other-language field since that one does not change behaviour
+  , checkVersion CabalSpecV1_10 (any isJust (buildInfoField defaultLanguage)) $
+      PackageBuildWarning CVDefaultLanguage
+
+  , check (specVersion pkg >= CabalSpecV1_10 && specVersion pkg < CabalSpecV3_4
+           && any isNothing (buildInfoField defaultLanguage)) $
+      PackageBuildWarning CVDefaultLanguageComponent
+
+  , checkVersion CabalSpecV1_18
+    (not . null $ extraDocFiles pkg) $
+      PackageDistInexcusable CVExtraDocFiles
+
+  , checkVersion CabalSpecV2_0
+    (not (null (subLibraries pkg))) $
+      PackageDistInexcusable CVMultiLib
+
+    -- check use of reexported-modules sections
+  , checkVersion CabalSpecV1_22
+    (any (not.null.reexportedModules) (allLibraries pkg)) $
+      PackageDistInexcusable CVReexported
+
+    -- check use of thinning and renaming
+  , checkVersion CabalSpecV2_0 usesBackpackIncludes $
+      PackageDistInexcusable CVMixins
+
+    -- check use of 'extra-framework-dirs' field
+  , checkVersion CabalSpecV1_24 (any (not . null) (buildInfoField extraFrameworkDirs)) $
+      -- Just a warning, because this won't break on old Cabal versions.
+      PackageDistSuspiciousWarn CVExtraFrameworkDirs
+
+    -- check use of default-extensions field
+    -- don't need to do the equivalent check for other-extensions
+  , checkVersion CabalSpecV1_10 (any (not . null) (buildInfoField defaultExtensions)) $
+      PackageBuildWarning CVDefaultExtensions
+
+    -- check use of extensions field
+  , check (specVersion pkg >= CabalSpecV1_10
+           && any (not . null) (buildInfoField oldExtensions)) $
+      PackageBuildWarning CVExtensionsDeprecated
+
+  , checkVersion CabalSpecV3_0 (any (not . null)
+                        (concatMap buildInfoField
+                         [ asmSources
+                         , cmmSources
+                         , extraBundledLibs
+                         , extraLibFlavours ])) $
+      PackageDistInexcusable CVSources
+
+  , checkVersion CabalSpecV3_0 (any (not . null) $ buildInfoField extraDynLibFlavours) $
+      PackageDistInexcusable
+        (CVExtraDynamic $ buildInfoField extraDynLibFlavours)
+
+  , checkVersion CabalSpecV2_2 (any (not . null)
+                        (buildInfoField virtualModules)) $
+      PackageDistInexcusable CVVirtualModules
+
+    -- check use of "source-repository" section
+  , checkVersion CabalSpecV1_6 (not (null (sourceRepos pkg))) $
+      PackageDistInexcusable CVSourceRepository
+
+    -- check for new language extensions
+  , checkVersion CabalSpecV1_2 (not (null mentionedExtensionsThatNeedCabal12)) $
+      PackageDistInexcusable
+        (CVExtensions CabalSpecV1_2 mentionedExtensionsThatNeedCabal12)
+
+  , checkVersion CabalSpecV1_4 (not (null mentionedExtensionsThatNeedCabal14)) $
+      PackageDistInexcusable
+        (CVExtensions CabalSpecV1_4 mentionedExtensionsThatNeedCabal14)
+
+  , check (specVersion pkg >= CabalSpecV1_24
+           && isNothing (setupBuildInfo pkg)
+           && buildType pkg == Custom) $
+      PackageBuildWarning CVCustomSetup
+
+  , check (specVersion pkg < CabalSpecV1_24
+           && isNothing (setupBuildInfo pkg)
+           && buildType pkg == Custom) $
+      PackageDistSuspiciousWarn CVExpliticDepsCustomSetup
+
+  , check (specVersion pkg >= CabalSpecV2_0
+           && elem (autogenPathsModuleName pkg) allModuleNames
+           && not (elem (autogenPathsModuleName pkg) allModuleNamesAutogen) ) $
+      PackageDistInexcusable CVAutogenPaths
+
+  , check (specVersion pkg >= CabalSpecV2_0
+           && elem (autogenPackageInfoModuleName pkg) allModuleNames
+           && not (elem (autogenPackageInfoModuleName pkg) allModuleNamesAutogen) ) $
+      PackageDistInexcusable CVAutogenPackageInfo
+
+  , check
+      (elem (autogenPackageInfoModuleName pkg) allModuleNames)
+      (PackageDistInexcusable CVAutogenPackageInfoGuard)
+  ]
+  where
+    -- Perform a check on packages that use a version of the spec less than
+    -- the version given. This is for cases where a new Cabal version adds
+    -- a new feature and we want to check that it is not used prior to that
+    -- version.
+    checkVersion :: CabalSpecVersion -> Bool -> PackageCheck -> Maybe PackageCheck
+    checkVersion ver cond pc
+      | specVersion pkg >= ver = Nothing
+      | otherwise              = check cond pc
+
+    buildInfoField field         = map field (allBuildInfo pkg)
+
+    usesBackpackIncludes = any (not . null . mixins) (allBuildInfo pkg)
+
+    mentionedExtensions = [ ext | bi <- allBuildInfo pkg
+                                , ext <- allExtensions bi ]
+    mentionedExtensionsThatNeedCabal12 =
+      nub (filter (`elem` compatExtensionsExtra) mentionedExtensions)
+
+    -- As of Cabal-1.4 we can add new extensions without worrying about
+    -- breaking old versions of cabal.
+    mentionedExtensionsThatNeedCabal14 =
+      nub (filter (`notElem` compatExtensions) mentionedExtensions)
+
+    -- The known extensions in Cabal-1.2.3
+    compatExtensions =
+      map EnableExtension
+      [ OverlappingInstances, UndecidableInstances, IncoherentInstances
+      , RecursiveDo, ParallelListComp, MultiParamTypeClasses
+      , FunctionalDependencies, Rank2Types
+      , RankNTypes, PolymorphicComponents, ExistentialQuantification
+      , ScopedTypeVariables, ImplicitParams, FlexibleContexts
+      , FlexibleInstances, EmptyDataDecls, CPP, BangPatterns
+      , TypeSynonymInstances, TemplateHaskell, ForeignFunctionInterface
+      , Arrows, Generics, NamedFieldPuns, PatternGuards
+      , GeneralizedNewtypeDeriving, ExtensibleRecords, RestrictedTypeSynonyms
+      , HereDocuments] ++
+      map DisableExtension
+      [MonomorphismRestriction, ImplicitPrelude] ++
+      compatExtensionsExtra
+
+    -- The extra known extensions in Cabal-1.2.3 vs Cabal-1.1.6
+    -- (Cabal-1.1.6 came with ghc-6.6. Cabal-1.2 came with ghc-6.8)
+    compatExtensionsExtra =
+      map EnableExtension
+      [ KindSignatures, MagicHash, TypeFamilies, StandaloneDeriving
+      , UnicodeSyntax, PatternSignatures, UnliftedFFITypes, LiberalTypeSynonyms
+      , TypeOperators, RecordWildCards, RecordPuns, DisambiguateRecordFields
+      , OverloadedStrings, GADTs, RelaxedPolyRec
+      , ExtendedDefaultRules, UnboxedTuples, DeriveDataTypeable
+      , ConstrainedClassMethods
+      ] ++
+      map DisableExtension
+      [MonoPatBinds]
+
+    allModuleNames =
+         (case library pkg of
+           Nothing -> []
+           (Just lib) -> explicitLibModules lib
+         )
+      ++ concatMap otherModules (allBuildInfo pkg)
+
+    allModuleNamesAutogen = concatMap autogenModules (allBuildInfo pkg)
+
+-- ------------------------------------------------------------
+-- * Checks on the GenericPackageDescription
+-- ------------------------------------------------------------
+
+-- | Check the build-depends fields for any weirdness or bad practice.
+--
+checkPackageVersions :: GenericPackageDescription -> [PackageCheck]
+checkPackageVersions pkg =
+  -- if others is empty,
+  -- the error will still fire but listing no dependencies.
+  -- so we have to check
+  if length others > 0
+  then
+    PackageDistSuspiciousWarn (MissingUpperBounds others) : baseErrors
+  else
+    baseErrors
+  where
+    baseErrors = PackageDistInexcusable BaseNoUpperBounds <$ bases
+    deps = toDependencyVersionsMap allNonInternalBuildDepends pkg
+    -- base gets special treatment (it's more critical)
+    (bases, others) = partition (("base" ==) . unPackageName) $
+      [ name
+      | (name, vr) <- Map.toList deps
+      , not (hasUpperBound vr)
+      ]
+
+    -- Get the combined build-depends entries of all components.
+    allNonInternalBuildDepends :: PackageDescription -> [Dependency]
+    allNonInternalBuildDepends = targetBuildDepends CM.<=< allNonInternalBuildInfo
+
+    allNonInternalBuildInfo :: PackageDescription -> [BuildInfo]
+    allNonInternalBuildInfo pkg_descr =
+      [bi | lib <- allLibraries pkg_descr, let bi = libBuildInfo lib]
+        ++ [bi | flib <- foreignLibs pkg_descr, let bi = foreignLibBuildInfo flib]
+        ++ [bi | exe <- executables pkg_descr, let bi = buildInfo exe]
+
+checkConditionals :: GenericPackageDescription -> [PackageCheck]
+checkConditionals pkg =
+  catMaybes [
+
+    check (not $ null unknownOSs) $
+      PackageDistInexcusable (UnknownOS unknownOSs)
+
+  , check (not $ null unknownArches) $
+      PackageDistInexcusable (UnknownArch unknownArches)
+
+  , check (not $ null unknownImpls) $
+      PackageDistInexcusable (UnknownCompiler unknownImpls)
+  ]
+  where
+    unknownOSs    = [ os   | OS   (OtherOS os)           <- conditions, os /= "haiku" ]
+    unknownArches = [ arch | Arch (OtherArch arch)       <- conditions ]
+    unknownImpls  = [ impl | Impl (OtherCompiler impl) _ <- conditions ]
+    conditions = concatMap fvs (maybeToList (condLibrary pkg))
+              ++ concatMap (fvs . snd) (condSubLibraries pkg)
+              ++ concatMap (fvs . snd) (condForeignLibs pkg)
+              ++ concatMap (fvs . snd) (condExecutables pkg)
+              ++ concatMap (fvs . snd) (condTestSuites pkg)
+              ++ concatMap (fvs . snd) (condBenchmarks pkg)
+    fvs (CondNode _ _ ifs) = concatMap compfv ifs -- free variables
+    compfv (CondBranch c ct mct) = condfv c ++ fvs ct ++ maybe [] fvs mct
+    condfv c = case c of
+      Var v      -> [v]
+      Lit _      -> []
+      CNot c1    -> condfv c1
+      COr  c1 c2 -> condfv c1 ++ condfv c2
+      CAnd c1 c2 -> condfv c1 ++ condfv c2
+
+checkFlagNames :: GenericPackageDescription -> [PackageCheck]
+checkFlagNames gpd
+    | null invalidFlagNames = []
+    | otherwise             =
+        [ PackageDistInexcusable (SuspiciousFlagName invalidFlagNames) ]
+  where
+    invalidFlagNames =
+        [ fn
+        | flag <- genPackageFlags gpd
+        , let fn = unFlagName (flagName flag)
+        , invalidFlagName fn
+        ]
+    -- starts with dash
+    invalidFlagName ('-':_) = True
+    -- mon ascii letter
+    invalidFlagName cs = any (not . isAscii) cs
+
+checkUnusedFlags :: GenericPackageDescription -> [PackageCheck]
+checkUnusedFlags gpd
+    | declared == used = []
+    | otherwise        =
+        [ PackageDistSuspicious (DeclaredUsedFlags declared used) ]
+  where
+    declared :: Set.Set FlagName
+    declared = toSetOf (L.genPackageFlags . traverse . L.flagName) gpd
+
+    used :: Set.Set FlagName
+    used = mconcat
+        [ toSetOf (L.condLibrary      . traverse      . traverseCondTreeV . L._PackageFlag) gpd
+        , toSetOf (L.condSubLibraries . traverse . _2 . traverseCondTreeV . L._PackageFlag) gpd
+        , toSetOf (L.condForeignLibs  . traverse . _2 . traverseCondTreeV . L._PackageFlag) gpd
+        , toSetOf (L.condExecutables  . traverse . _2 . traverseCondTreeV . L._PackageFlag) gpd
+        , toSetOf (L.condTestSuites   . traverse . _2 . traverseCondTreeV . L._PackageFlag) gpd
+        , toSetOf (L.condBenchmarks   . traverse . _2 . traverseCondTreeV . L._PackageFlag) gpd
+        ]
+
+checkUnicodeXFields :: GenericPackageDescription -> [PackageCheck]
+checkUnicodeXFields gpd
+    | null nonAsciiXFields = []
+    | otherwise            =
+        [ PackageDistInexcusable (NonASCIICustomField nonAsciiXFields) ]
+  where
+    nonAsciiXFields :: [String]
+    nonAsciiXFields = [ n | (n, _) <- xfields, any (not . isAscii) n ]
+
+    xfields :: [(String,String)]
+    xfields = DList.runDList $ mconcat
+        [ toDListOf (L.packageDescription . L.customFieldsPD . traverse) gpd
+        , toDListOf (L.traverseBuildInfos . L.customFieldsBI . traverse) gpd
+        ]
+
+-- | cabal-version <2.2 + Paths_module + default-extensions: doesn't build.
+checkPathsModuleExtensions :: PackageDescription -> [PackageCheck]
+checkPathsModuleExtensions = checkAutogenModuleExtensions autogenPathsModuleName RebindableClashPaths
+
+-- | cabal-version <2.2 + PackageInfo_module + default-extensions: doesn't build.
+checkPackageInfoModuleExtensions :: PackageDescription -> [PackageCheck]
+checkPackageInfoModuleExtensions = checkAutogenModuleExtensions autogenPackageInfoModuleName RebindableClashPackageInfo
+
+-- | cabal-version <2.2 + *_module + default-extensions: doesn't build.
+checkAutogenModuleExtensions ::
+  (PackageDescription -> ModuleName) ->
+  CheckExplanation ->
+  PackageDescription ->
+  [PackageCheck]
+checkAutogenModuleExtensions autogenModuleName rebindableClashExplanation pd
+    | specVersion pd >= CabalSpecV2_2 = []
+    | any checkBI (allBuildInfo pd) || any checkLib (allLibraries pd)
+        = return (PackageBuildImpossible rebindableClashExplanation)
+    | otherwise = []
+  where
+    mn = autogenModuleName pd
+
+    checkLib :: Library -> Bool
+    checkLib l = mn `elem` exposedModules l && checkExts (l ^. L.defaultExtensions)
+
+    checkBI :: BuildInfo -> Bool
+    checkBI bi =
+        (mn `elem` otherModules bi || mn `elem` autogenModules bi) &&
+        checkExts (bi ^. L.defaultExtensions)
+
+    checkExts exts = rebind `elem` exts && (strings `elem` exts || lists `elem` exts)
+      where
+        rebind  = EnableExtension RebindableSyntax
+        strings = EnableExtension OverloadedStrings
+        lists   = EnableExtension OverloadedLists
+
+-- | Checks GHC options from all ghc-*-options fields from the given BuildInfo
+-- and reports flags that are OK during development process, but are
+-- unacceptable in a distributed package
+checkDevelopmentOnlyFlagsBuildInfo :: BuildInfo -> [PackageCheck]
+checkDevelopmentOnlyFlagsBuildInfo bi =
+    checkDevelopmentOnlyFlagsOptions "ghc-options" (hcOptions GHC bi)
+ ++ checkDevelopmentOnlyFlagsOptions "ghc-prof-options" (hcProfOptions GHC bi)
+ ++ checkDevelopmentOnlyFlagsOptions "ghc-shared-options" (hcSharedOptions GHC bi)
+
+-- | Checks the given list of flags belonging to the given field and reports
+-- flags that are OK during development process, but are unacceptable in a
+-- distributed package
+checkDevelopmentOnlyFlagsOptions :: String -> [String] -> [PackageCheck]
+checkDevelopmentOnlyFlagsOptions fieldName ghcOptions =
+  catMaybes [
+
+    check has_Werror $
+      PackageDistInexcusable (WErrorUnneeded fieldName)
+
+  , check has_J $
+      PackageDistInexcusable (JUnneeded fieldName)
+
+  , checkFlags ["-fdefer-type-errors"] $
+      PackageDistInexcusable (FDeferTypeErrorsUnneeded fieldName)
+
+    -- -dynamic is not a debug flag
+  , check (any (\opt -> "-d" `isPrefixOf` opt && opt /= "-dynamic")
+           ghcOptions) $
+      PackageDistInexcusable (DynamicUnneeded fieldName)
+
+  , checkFlags ["-fprof-auto", "-fprof-auto-top", "-fprof-auto-calls",
+               "-fprof-cafs", "-fno-prof-count-entries",
+               "-auto-all", "-auto", "-caf-all"] $
+      PackageDistSuspicious (ProfilingUnneeded fieldName)
+  ]
+  where
+
+    has_Werror       = "-Werror" `elem` ghcOptions
+    has_J            = any
+                         (\o -> case o of
+                           "-j"                -> True
+                           ('-' : 'j' : d : _) -> isDigit d
+                           _                   -> False
+                         )
+                         ghcOptions
+    checkFlags :: [String] -> PackageCheck -> Maybe PackageCheck
+    checkFlags flags = check (any (`elem` flags) ghcOptions)
+
+checkDevelopmentOnlyFlags :: GenericPackageDescription -> [PackageCheck]
+checkDevelopmentOnlyFlags pkg =
+    concatMap checkDevelopmentOnlyFlagsBuildInfo
+              [ bi
+              | (conditions, bi) <- allConditionalBuildInfo
+              , not (any guardedByManualFlag conditions) ]
+  where
+    guardedByManualFlag = definitelyFalse
+
+    -- We've basically got three-values logic here: True, False or unknown
+    -- hence this pattern to propagate the unknown cases properly.
+    definitelyFalse (Var (PackageFlag n)) = maybe False not (Map.lookup n manualFlags)
+    definitelyFalse (Var _)        = False
+    definitelyFalse (Lit  b)       = not b
+    definitelyFalse (CNot c)       = definitelyTrue c
+    definitelyFalse (COr  c1 c2)   = definitelyFalse c1 && definitelyFalse c2
+    definitelyFalse (CAnd c1 c2)   = definitelyFalse c1 || definitelyFalse c2
+
+    definitelyTrue (Var (PackageFlag n)) = fromMaybe False (Map.lookup n manualFlags)
+    definitelyTrue (Var _)        = False
+    definitelyTrue (Lit  b)       = b
+    definitelyTrue (CNot c)       = definitelyFalse c
+    definitelyTrue (COr  c1 c2)   = definitelyTrue c1 || definitelyTrue c2
+    definitelyTrue (CAnd c1 c2)   = definitelyTrue c1 && definitelyTrue c2
+
+    manualFlags = Map.fromList
+                    [ (flagName flag, flagDefault flag)
+                    | flag <- genPackageFlags pkg
+                    , flagManual flag ]
+
+    allConditionalBuildInfo :: [([Condition ConfVar], BuildInfo)]
+    allConditionalBuildInfo =
+        concatMap (collectCondTreePaths libBuildInfo)
+                  (maybeToList (condLibrary pkg))
+
+     ++ concatMap (collectCondTreePaths libBuildInfo . snd)
+                  (condSubLibraries pkg)
+
+     ++ concatMap (collectCondTreePaths buildInfo . snd)
+                  (condExecutables pkg)
+
+     ++ concatMap (collectCondTreePaths testBuildInfo . snd)
+                  (condTestSuites pkg)
+
+     ++ concatMap (collectCondTreePaths benchmarkBuildInfo . snd)
+                  (condBenchmarks pkg)
+
+    -- get all the leaf BuildInfo, paired up with the path (in the tree sense)
+    -- of if-conditions that guard it
+    collectCondTreePaths :: (a -> b)
+                         -> CondTree v c a
+                         -> [([Condition v], b)]
+    collectCondTreePaths mapData = go []
+      where
+        go conditions condNode =
+            -- the data at this level in the tree:
+            (reverse conditions, mapData (condTreeData condNode))
+
+          : concat
+            [ go (condition:conditions) ifThen
+            | (CondBranch condition ifThen _) <- condTreeComponents condNode ]
+
+         ++ concat
+            [ go (condition:conditions) elseThen
+            | (CondBranch condition _ (Just elseThen)) <- condTreeComponents condNode ]
+
+
+-- ------------------------------------------------------------
+-- * Checks involving files in the package
+-- ------------------------------------------------------------
+
+-- | Sanity check things that requires IO. It looks at the files in the
+-- package and expects to find the package unpacked in at the given file path.
+--
+checkPackageFiles :: Verbosity -> PackageDescription -> FilePath -> IO [PackageCheck]
+checkPackageFiles verbosity pkg root = do
+  contentChecks <- checkPackageContent checkFilesIO pkg
+  preDistributionChecks <- checkPackageFilesPreDistribution verbosity pkg root
+  -- Sort because different platforms will provide files from
+  -- `getDirectoryContents` in different orders, and we'd like to be
+  -- stable for test output.
+  return (sort contentChecks ++ sort preDistributionChecks)
+  where
+    checkFilesIO = CheckPackageContentOps {
+      doesFileExist        = System.doesFileExist                  . relative,
+      doesDirectoryExist   = System.doesDirectoryExist             . relative,
+      getDirectoryContents = System.Directory.getDirectoryContents . relative,
+      getFileContents      = BS.readFile                           . relative
+    }
+    relative path = root </> path
+
+-- | A record of operations needed to check the contents of packages.
+-- Used by 'checkPackageContent'.
+--
+data CheckPackageContentOps m = CheckPackageContentOps {
+    doesFileExist        :: FilePath -> m Bool,
+    doesDirectoryExist   :: FilePath -> m Bool,
+    getDirectoryContents :: FilePath -> m [FilePath],
+    getFileContents      :: FilePath -> m BS.ByteString
+  }
+
+-- | Sanity check things that requires looking at files in the package.
+-- This is a generalised version of 'checkPackageFiles' that can work in any
+-- monad for which you can provide 'CheckPackageContentOps' operations.
+--
+-- The point of this extra generality is to allow doing checks in some virtual
+-- file system, for example a tarball in memory.
+--
+checkPackageContent :: (Monad m, Applicative m)
+                    => CheckPackageContentOps m
+                    -> PackageDescription
+                    -> m [PackageCheck]
+checkPackageContent ops pkg = do
+  cabalBomError   <- checkCabalFileBOM    ops
+  cabalNameError  <- checkCabalFileName   ops pkg
+  licenseErrors   <- checkLicensesExist   ops pkg
+  setupError      <- checkSetupExists     ops pkg
+  configureError  <- checkConfigureExists ops pkg
+  localPathErrors <- checkLocalPathsExist ops pkg
+  vcsLocation     <- checkMissingVcsInfo  ops pkg
+
+  return $ licenseErrors
+        ++ catMaybes [cabalBomError, cabalNameError, setupError, configureError]
+        ++ localPathErrors
+        ++ vcsLocation
+
+checkCabalFileBOM :: Monad m => CheckPackageContentOps m
+                  -> m (Maybe PackageCheck)
+checkCabalFileBOM ops = do
+  epdfile <- findPackageDesc ops
+  case epdfile of
+    -- MASSIVE HACK.  If the Cabal file doesn't exist, that is
+    -- a very strange situation to be in, because the driver code
+    -- in 'Distribution.Setup' ought to have noticed already!
+    -- But this can be an issue, see #3552 and also when
+    -- --cabal-file is specified.  So if you can't find the file,
+    -- just don't bother with this check.
+    Left _       -> return Nothing
+    Right pdfile -> (flip check pc . BS.isPrefixOf bomUtf8)
+                    `liftM` getFileContents ops pdfile
+      where pc = PackageDistInexcusable (BOMStart pdfile)
+
+  where
+    bomUtf8 :: BS.ByteString
+    bomUtf8 = BS.pack [0xef,0xbb,0xbf] -- U+FEFF encoded as UTF8
+
+checkCabalFileName :: Monad m => CheckPackageContentOps m
+                 -> PackageDescription
+                 -> m (Maybe PackageCheck)
+checkCabalFileName ops pkg = do
+  -- findPackageDesc already takes care to detect missing/multiple
+  -- .cabal files; we don't include this check in 'findPackageDesc' in
+  -- order not to short-cut other checks which call 'findPackageDesc'
+  epdfile <- findPackageDesc ops
+  case epdfile of
+    -- see "MASSIVE HACK" note in 'checkCabalFileBOM'
+    Left _       -> return Nothing
+    Right pdfile
+      | takeFileName pdfile == expectedCabalname -> return Nothing
+      | otherwise -> return $ Just $ PackageDistInexcusable
+                       (NotPackageName pdfile expectedCabalname)
+  where
+    pkgname = unPackageName . packageName $ pkg
+    expectedCabalname = pkgname <.> "cabal"
+
+
+-- |Find a package description file in the given directory.  Looks for
+-- @.cabal@ files.  Like 'Distribution.Simple.Utils.findPackageDesc',
+-- but generalized over monads.
+findPackageDesc :: Monad m => CheckPackageContentOps m
+                 -> m (Either PackageCheck FilePath) -- ^<pkgname>.cabal
+findPackageDesc ops
+ = do let dir = "."
+      files <- getDirectoryContents ops dir
+      -- to make sure we do not mistake a ~/.cabal/ dir for a <pkgname>.cabal
+      -- file we filter to exclude dirs and null base file names:
+      cabalFiles <- filterM (doesFileExist ops)
+                       [ dir </> file
+                       | file <- files
+                       , let (name, ext) = splitExtension file
+                       , not (null name) && ext == ".cabal" ]
+      case cabalFiles of
+        []          -> return (Left $ PackageBuildImpossible NoDesc)
+        [cabalFile] -> return (Right cabalFile)
+        multiple    -> return (Left $ PackageBuildImpossible
+                                (MultiDesc multiple))
+
+checkLicensesExist :: (Monad m, Applicative m)
+                   => CheckPackageContentOps m
+                   -> PackageDescription
+                   -> m [PackageCheck]
+checkLicensesExist ops pkg = do
+    exists <- traverse (doesFileExist ops . getSymbolicPath) (licenseFiles pkg)
+    return
+      [ PackageBuildWarning (UnknownFile fieldname file)
+      | (file, False) <- zip (licenseFiles pkg) exists ]
+  where
+    fieldname | length (licenseFiles pkg) == 1 = "license-file"
+              | otherwise                      = "license-files"
+
+checkSetupExists :: Monad m => CheckPackageContentOps m
+                 -> PackageDescription
+                 -> m (Maybe PackageCheck)
+checkSetupExists ops pkg = do
+  let simpleBuild = buildType pkg == Simple
+  hsexists  <- doesFileExist ops "Setup.hs"
+  lhsexists <- doesFileExist ops "Setup.lhs"
+  return $ check (not simpleBuild && not hsexists && not lhsexists) $
+    PackageDistInexcusable MissingSetupFile
+
+checkConfigureExists :: Monad m => CheckPackageContentOps m
+                     -> PackageDescription
+                     -> m (Maybe PackageCheck)
+checkConfigureExists ops pd
+  | buildType pd == Configure = do
+      exists <- doesFileExist ops "configure"
+      return $ check (not exists) $
+        PackageBuildWarning MissingConfigureScript
+  | otherwise = return Nothing
+
+checkLocalPathsExist :: Monad m => CheckPackageContentOps m
+                     -> PackageDescription
+                     -> m [PackageCheck]
+checkLocalPathsExist ops pkg = do
+  let dirs = [ (dir, kind)
+             | bi <- allBuildInfo pkg
+             , (dir, kind) <-
+                  [ (dir, "extra-lib-dirs") | dir <- extraLibDirs bi ]
+               ++ [ (dir, "extra-lib-dirs-static") | dir <- extraLibDirsStatic bi ]
+               ++ [ (dir, "extra-framework-dirs")
+                  | dir <- extraFrameworkDirs  bi ]
+               ++ [ (dir, "include-dirs")   | dir <- includeDirs  bi ]
+               ++ [ (getSymbolicPath dir, "hs-source-dirs") | dir <- hsSourceDirs bi ]
+             , isRelativeOnAnyPlatform dir ]
+  missing <- filterM (liftM not . doesDirectoryExist ops . fst) dirs
+  return [ PackageBuildWarning (UnknownDirectory kind dir)
+         | (dir, kind) <- missing ]
+
+checkMissingVcsInfo :: (Monad m, Applicative m)
+                    => CheckPackageContentOps m
+                    -> PackageDescription
+                    -> m [PackageCheck]
+checkMissingVcsInfo ops pkg | null (sourceRepos pkg) = do
+    vcsInUse <- liftM or $ traverse (doesDirectoryExist ops) repoDirnames
+    if vcsInUse
+      then return [ PackageDistSuspicious MissingSourceControl ]
+      else return []
+  where
+    repoDirnames = [ dirname | repo    <- knownRepoTypes
+                             , dirname <- repoTypeDirname repo]
+
+checkMissingVcsInfo _ _ = return []
+
+repoTypeDirname :: KnownRepoType -> [FilePath]
+repoTypeDirname Darcs     = ["_darcs"]
+repoTypeDirname Git       = [".git"]
+repoTypeDirname SVN       = [".svn"]
+repoTypeDirname CVS       = ["CVS"]
+repoTypeDirname Mercurial = [".hg"]
+repoTypeDirname GnuArch   = [".arch-params"]
+repoTypeDirname Bazaar    = [".bzr"]
+repoTypeDirname Monotone  = ["_MTN"]
+repoTypeDirname Pijul     = [".pijul"]
+
+-- ------------------------------------------------------------
+-- * Checks involving files in the package
+-- ------------------------------------------------------------
+
+-- | Check the names of all files in a package for portability problems. This
+-- should be done for example when creating or validating a package tarball.
+--
+checkPackageFileNames :: [FilePath] -> [PackageCheck]
+checkPackageFileNames = checkPackageFileNamesWithGlob . zip (repeat True)
+
+checkPackageFileNamesWithGlob :: [(Bool, FilePath)] -> [PackageCheck]
+checkPackageFileNamesWithGlob files =
+  catMaybes $
+    checkWindowsPaths files
+    :
+    [ checkTarPath file
+    | (_, file) <- files
+    ]
+
+checkWindowsPaths :: [(Bool, FilePath)] -> Maybe PackageCheck
+checkWindowsPaths paths =
+    case filter (not . FilePath.Windows.isValid . escape) paths of
+      [] -> Nothing
+      ps -> Just $
+        PackageDistInexcusable (InvalidOnWin $ map snd ps)
+  where
+    -- force a relative name to catch invalid file names like "f:oo" which
+    -- otherwise parse as file "oo" in the current directory on the 'f' drive.
+    escape (isGlob, path) = (".\\" ++)
+        -- glob paths will be expanded before being dereferenced, so asterisks
+        -- shouldn't count against them.
+      $ map (\c -> if c == '*' && isGlob then 'x' else c) path
+
+-- | Check a file name is valid for the portable POSIX tar format.
+--
+-- The POSIX tar format has a restriction on the length of file names. It is
+-- unfortunately not a simple restriction like a maximum length. The exact
+-- restriction is that either the whole path be 100 characters or less, or it
+-- be possible to split the path on a directory separator such that the first
+-- part is 155 characters or less and the second part 100 characters or less.
+--
+checkTarPath :: FilePath -> Maybe PackageCheck
+checkTarPath path
+  | length path > 255   = Just longPath
+  | otherwise = case pack nameMax (reverse (splitPath path)) of
+    Left err           -> Just err
+    Right []           -> Nothing
+    Right (h:rest) -> case pack prefixMax remainder of
+      Left err         -> Just err
+      Right []         -> Nothing
+      Right (_:_)      -> Just noSplit
+     where
+        -- drop the '/' between the name and prefix:
+        remainder = safeInit h : rest
+
+  where
+    nameMax, prefixMax :: Int
+    nameMax   = 100
+    prefixMax = 155
+
+    pack _   []     = Left emptyName
+    pack maxLen (c:cs)
+      | n > maxLen  = Left longName
+      | otherwise   = Right (pack' maxLen n cs)
+      where n = length c
+
+    pack' maxLen n (c:cs)
+      | n' <= maxLen = pack' maxLen n' cs
+      where n' = n + length c
+    pack' _     _ cs = cs
+
+    longPath = PackageDistInexcusable (FilePathTooLong path)
+    longName = PackageDistInexcusable (FilePathNameTooLong path)
+    noSplit = PackageDistInexcusable (FilePathSplitTooLong path)
+    emptyName = PackageDistInexcusable FilePathEmpty
+
+-- --------------------------------------------------------------
+-- * Checks for missing content and other pre-distribution checks
+-- --------------------------------------------------------------
+
+-- | Similar to 'checkPackageContent', 'checkPackageFilesPreDistribution'
+-- inspects the files included in the package, but is primarily looking for
+-- files in the working tree that may have been missed or other similar
+-- problems that can only be detected pre-distribution.
+--
+-- Because Hackage necessarily checks the uploaded tarball, it is too late to
+-- check these on the server; these checks only make sense in the development
+-- and package-creation environment. Hence we can use IO, rather than needing
+-- to pass a 'CheckPackageContentOps' dictionary around.
+checkPackageFilesPreDistribution :: Verbosity -> PackageDescription -> FilePath -> IO [PackageCheck]
+-- Note: this really shouldn't return any 'Inexcusable' warnings,
+-- because that will make us say that Hackage would reject the package.
+-- But, because Hackage doesn't run these tests, that will be a lie!
+checkPackageFilesPreDistribution = checkGlobFiles
+
+-- | Discover problems with the package's wildcards.
+checkGlobFiles :: Verbosity
+               -> PackageDescription
+               -> FilePath
+               -> IO [PackageCheck]
+checkGlobFiles verbosity pkg root = do
+  -- Get the desirable doc files from package’s directory
+  rootContents <- System.Directory.getDirectoryContents root
+  docFiles0 <- filterM System.doesFileExist
+                       [ file
+                       | file <- rootContents
+                       , isDesirableExtraDocFile desirableDocFiles file
+                       ]
+  -- Check the globs
+  (warnings, unlisted) <- foldrM checkGlob ([], docFiles0) allGlobs
+
+  return $ if null unlisted
+    -- No missing desirable file
+    then warnings
+    -- Some missing desirable files
+    else warnings ++
+         let unlisted' = (root </>) <$> unlisted
+         in [ PackageDistSuspiciousWarn
+                (MissingExpectedDocFiles extraDocFilesSupport unlisted')
+            ]
+  where
+    -- `extra-doc-files` is supported only from version 1.18
+    extraDocFilesSupport = specVersion pkg >= CabalSpecV1_18
+    adjustedDataDir = if null (dataDir pkg) then root else root </> dataDir pkg
+    -- Cabal fields with globs
+    allGlobs :: [(String, Bool, FilePath, FilePath)]
+    allGlobs = concat
+      [ (,,,) "extra-source-files" (not extraDocFilesSupport) root <$>
+        extraSrcFiles pkg
+      , (,,,) "extra-doc-files" True root <$> extraDocFiles pkg
+      , (,,,) "data-files" False adjustedDataDir <$> dataFiles pkg
+      ]
+
+    -- For each field with globs (see allGlobs), look for:
+    -- • errors (missing directory, no match)
+    -- • omitted documentation files (changelog)
+    checkGlob :: (String, Bool, FilePath, FilePath)
+              -> ([PackageCheck], [FilePath])
+              -> IO ([PackageCheck], [FilePath])
+    checkGlob (field, isDocField, dir, glob) acc@(warnings, docFiles1) =
+      -- Note: we just skip over parse errors here; they're reported elsewhere.
+      case parseFileGlob (specVersion pkg) glob of
+        Left _ -> return acc
+        Right parsedGlob -> do
+          results <- runDirFileGlob verbosity (root </> dir) parsedGlob
+          let acc0 = (warnings, True, docFiles1, [])
+          return $ case foldr checkGlobResult acc0 results of
+            (individualWarn, noMatchesWarn, docFiles1', wrongPaths) ->
+              let wrongFieldWarnings = [ PackageDistSuspiciousWarn
+                                          (WrongFieldForExpectedDocFiles
+                                            extraDocFilesSupport
+                                            field wrongPaths)
+                                       | not (null wrongPaths) ]
+              in
+                ( if noMatchesWarn
+                    then [PackageDistSuspiciousWarn (GlobNoMatch field glob)] ++
+                         individualWarn ++
+                         wrongFieldWarnings
+                    else individualWarn ++ wrongFieldWarnings
+                , docFiles1'
+                )
+          where
+            checkGlobResult :: GlobResult FilePath
+                            -> ([PackageCheck], Bool, [FilePath], [FilePath])
+                            -> ([PackageCheck], Bool, [FilePath], [FilePath])
+            checkGlobResult result (ws, noMatchesWarn, docFiles2, wrongPaths) =
+              let noMatchesWarn' = noMatchesWarn &&
+                                   not (suppressesNoMatchesWarning result)
+              in case getWarning field glob result of
+                -- No match: add warning and do no further check
+                Left w ->
+                  ( w : ws
+                  , noMatchesWarn'
+                  , docFiles2
+                  , wrongPaths
+                  )
+                -- Match: check doc files
+                Right path ->
+                  let path' = makeRelative root (normalise path)
+                      (docFiles2', wrongPaths') = checkDoc isDocField
+                                                           path'
+                                                           docFiles2
+                                                           wrongPaths
+                  in
+                    ( ws
+                    , noMatchesWarn'
+                    , docFiles2'
+                    , wrongPaths'
+                    )
+
+    -- Check whether a path is a desirable doc: if so, check if it is in the
+    -- field "extra-doc-files".
+    checkDoc :: Bool                     -- Is it "extra-doc-files" ?
+             -> FilePath                 -- Path to test
+             -> [FilePath]               -- Pending doc files to check
+             -> [FilePath]               -- Previous wrong paths
+             -> ([FilePath], [FilePath]) -- Updated paths
+    checkDoc isDocField path docFiles wrongFieldPaths =
+      if path `elem` docFiles
+        -- Found desirable doc file
+        then
+          ( delete path docFiles
+          , if isDocField then wrongFieldPaths else path : wrongFieldPaths
+          )
+        -- Not a desirable doc file
+        else
+          ( docFiles
+          , wrongFieldPaths
+          )
+
+    -- Predicate for desirable documentation file on Hackage server
+    isDesirableExtraDocFile :: ([FilePath], [FilePath]) -> FilePath -> Bool
+    isDesirableExtraDocFile (basenames, extensions) path =
+      basename `elem` basenames && ext `elem` extensions
+      where
+        (basename, ext) = splitExtension (map toLower path)
+
+    -- Changelog patterns (basenames & extensions)
+    -- Source: hackage-server/src/Distribution/Server/Packages/ChangeLog.hs
+    desirableChangeLog =
+      [ "news"
+      , "changelog"
+      , "change_log"
+      , "changes"
+      ]
+    desirableChangeLogExtensions = ["", ".txt", ".md", ".markdown", ".rst"]
+    -- [TODO] Check readme. Observations:
+    --        • Readme is not necessary if package description is good.
+    --        • Some readmes exists only for repository browsing.
+    --        • There is currently no reliable way to check what a good
+    --          description is; there will be complains if the criterion is
+    --          based on the length or number of words (can of worms).
+    -- -- Readme patterns
+    -- -- Source: hackage-server/src/Distribution/Server/Packages/Readme.hs
+    -- desirableReadme = ["readme"]
+    desirableDocFiles = (desirableChangeLog, desirableChangeLogExtensions)
+
+    -- If there's a missing directory in play, since our globs don't
+    -- (currently) support disjunction, that will always mean there are no
+    -- matches. The no matches error in this case is strictly less informative
+    -- than the missing directory error, so sit on it.
+    suppressesNoMatchesWarning (GlobMatch _) = True
+    suppressesNoMatchesWarning (GlobWarnMultiDot _) = False
+    suppressesNoMatchesWarning (GlobMissingDirectory _) = True
+
+    getWarning :: String
+               -> FilePath
+               -> GlobResult FilePath
+               -> Either PackageCheck FilePath
+    getWarning _ _ (GlobMatch path) =
+      Right path
+    -- Before Cabal 2.4, the extensions of globs had to match the file
+    -- exactly. This has been relaxed in 2.4 to allow matching only the
+    -- suffix. This warning detects when pre-2.4 package descriptions are
+    -- omitting files purely because of the stricter check.
+    getWarning field glob (GlobWarnMultiDot file) =
+      Left (PackageDistSuspiciousWarn (GlobExactMatch field glob file))
+    getWarning field glob (GlobMissingDirectory dir) =
+      Left (PackageDistSuspiciousWarn (GlobNoDir field glob dir))
+
+-- | Check that setup dependencies, have proper bounds.
+-- In particular, @base@ and @Cabal@ upper bounds are mandatory.
+checkSetupVersions :: GenericPackageDescription -> [PackageCheck]
+checkSetupVersions pkg =
+    [ emitError nameStr
+    | (name, vr) <- Map.toList deps
+    , not (hasUpperBound vr)
+    , let nameStr = unPackageName name
+    , nameStr `elem` criticalPkgs
+    ]
+  where
+    criticalPkgs = ["Cabal", "base"]
+    deps = toDependencyVersionsMap (foldMap setupDepends . setupBuildInfo) pkg
+    emitError nm =
+      PackageDistInexcusable (UpperBoundSetup nm)
+
+checkDuplicateModules :: GenericPackageDescription -> [PackageCheck]
+checkDuplicateModules pkg =
+       concatMap checkLib   (maybe id (:) (condLibrary pkg) . map snd $ condSubLibraries pkg)
+    ++ concatMap checkExe   (map snd $ condExecutables pkg)
+    ++ concatMap checkTest  (map snd $ condTestSuites  pkg)
+    ++ concatMap checkBench (map snd $ condBenchmarks  pkg)
+  where
+    -- the duplicate modules check is has not been thoroughly vetted for backpack
+    checkLib   = checkDups "library" (\l -> explicitLibModules l ++ map moduleReexportName (reexportedModules l))
+    checkExe   = checkDups "executable" exeModules
+    checkTest  = checkDups "test suite" testModules
+    checkBench = checkDups "benchmark"  benchmarkModules
+    checkDups s getModules t =
+               let sumPair (x,x') (y,y') = (x + x' :: Int, y + y' :: Int)
+                   mergePair (x, x') (y, y') = (x + x', max y y')
+                   maxPair (x, x') (y, y') = (max x x', max y y')
+                   libMap = foldCondTree Map.empty
+                                         (\(_,v) -> Map.fromListWith sumPair . map (\x -> (x,(1, 1))) $ getModules v )
+                                         (Map.unionWith mergePair) -- if a module may occur in nonexclusive branches count it twice strictly and once loosely.
+                                         (Map.unionWith maxPair) -- a module occurs the max of times it might appear in exclusive branches
+                                         t
+                   dupLibsStrict = Map.keys $ Map.filter ((>1) . fst) libMap
+                   dupLibsLax = Map.keys $ Map.filter ((>1) . snd) libMap
+               in if not (null dupLibsLax)
+                      then [PackageBuildImpossible
+                             (DuplicateModule s dupLibsLax)]
+                      else if not (null dupLibsStrict)
+                           then [PackageDistSuspicious
+                                   (PotentialDupModule s dupLibsStrict)]
+                           else []
+
+-- ------------------------------------------------------------
+-- * Utils
+-- ------------------------------------------------------------
+
+toDependencyVersionsMap :: (PackageDescription -> [Dependency]) -> GenericPackageDescription -> Map PackageName VersionRange
+toDependencyVersionsMap selectDependencies pkg = case typicalPkg pkg of
+      Right (pkgs', _) ->
+        let
+          self :: PackageName
+          self = pkgName $ package pkgs'
+        in
+        Map.fromListWith intersectVersionRanges $
+          [ (pname, vr)
+          | Dependency pname vr _ <- selectDependencies pkgs'
+          , pname /= self
+          ]
+      -- Just in case finalizePD fails for any reason,
+      -- or if the package doesn't depend on the base package at all,
+      -- no deps is no checks.
+      _ -> Map.empty
+
+
+quote :: String -> String
+quote s = "'" ++ s ++ "'"
+
+commaSep :: [String] -> String
+commaSep = intercalate ", "
+
+dups :: Ord a => [a] -> [a]
+dups xs = [ x | (x:_:_) <- group (sort xs) ]
+
+fileExtensionSupportedLanguage :: FilePath -> Bool
+fileExtensionSupportedLanguage path =
+    isHaskell || isC
+  where
+    extension = takeExtension path
+    isHaskell = extension `elem` [".hs", ".lhs"]
+    isC       = isJust (filenameCDialect extension)
+
+-- | Whether a path is a good relative path.  We aren't worried about perfect
+-- cross-platform compatibility here; this function just checks the paths in
+-- the (local) @.cabal@ file, while only Hackage needs the portability.
+--
+-- >>> let test fp = putStrLn $ show (isGoodRelativeDirectoryPath fp) ++ "; " ++ show (isGoodRelativeFilePath fp)
+--
+-- Note that "foo./bar.hs" would be invalid on Windows.
+--
+-- >>> traverse_ test ["foo/bar/quu", "a/b.hs", "foo./bar.hs"]
+-- Nothing; Nothing
+-- Nothing; Nothing
+-- Nothing; Nothing
+--
+-- Trailing slash is not allowed for files, for directories it is ok.
+--
+-- >>> test "foo/"
+-- Nothing; Just "trailing slash"
+--
+-- Leading @./@ is fine, but @.@ and @./@ are not valid files.
+--
+-- >>> traverse_ test [".", "./", "./foo/bar"]
+-- Nothing; Just "trailing dot segment"
+-- Nothing; Just "trailing slash"
+-- Nothing; Nothing
+--
+-- Lastly, not good file nor directory cases:
+--
+-- >>> traverse_ test ["", "/tmp/src", "foo//bar", "foo/.", "foo/./bar", "foo/../bar"]
+-- Just "empty path"; Just "empty path"
+-- Just "posix absolute path"; Just "posix absolute path"
+-- Just "empty path segment"; Just "empty path segment"
+-- Just "trailing same directory segment: ."; Just "trailing same directory segment: ."
+-- Just "same directory segment: ."; Just "same directory segment: ."
+-- Just "parent directory segment: .."; Just "parent directory segment: .."
+--
+-- For the last case, 'isGoodRelativeGlob' doesn't warn:
+--
+-- >>> traverse_ (print . isGoodRelativeGlob) ["foo/../bar"]
+-- Just "parent directory segment: .."
+--
+isGoodRelativeFilePath :: FilePath -> Maybe String
+isGoodRelativeFilePath = state0
+  where
+    -- initial state
+    state0 []                    = Just "empty path"
+    state0 (c:cs) | c == '.'     = state1 cs
+                  | c == '/'     = Just "posix absolute path"
+                  | otherwise    = state5 cs
+
+    -- after initial .
+    state1 []                    = Just "trailing dot segment"
+    state1 (c:cs) | c == '.'     = state4 cs
+                  | c == '/'     = state2 cs
+                  | otherwise    = state5 cs
+
+    -- after ./ or after / between segments
+    state2 []                    = Just "trailing slash"
+    state2 (c:cs) | c == '.'     = state3 cs
+                  | c == '/'     = Just "empty path segment"
+                  | otherwise    = state5 cs
+
+    -- after non-first segment's .
+    state3 []                    = Just "trailing same directory segment: ."
+    state3 (c:cs) | c == '.'     = state4 cs
+                  | c == '/'     = Just "same directory segment: ."
+                  | otherwise    = state5 cs
+
+    -- after ..
+    state4 []                    = Just "trailing parent directory segment: .."
+    state4 (c:cs) | c == '.'     = state5 cs
+                  | c == '/'     = Just "parent directory segment: .."
+                  | otherwise    = state5 cs
+
+    -- in a segment which is ok.
+    state5 []                    = Nothing
+    state5 (c:cs) | c == '.'     = state5 cs
+                  | c == '/'     = state2 cs
+                  | otherwise    = state5 cs
+
+-- | See 'isGoodRelativeFilePath'.
+--
+-- This is barebones function. We check whether the glob is a valid file
+-- by replacing stars @*@ with @x@ses.
+isGoodRelativeGlob :: FilePath -> Maybe String
+isGoodRelativeGlob = isGoodRelativeFilePath . map f where
+    f '*' = 'x'
+    f c   = c
+
+-- | See 'isGoodRelativeFilePath'.
+isGoodRelativeDirectoryPath :: FilePath -> Maybe String
+isGoodRelativeDirectoryPath = state0
+  where
+    -- initial state
+    state0 []                    = Just "empty path"
+    state0 (c:cs) | c == '.'     = state5 cs
+                  | c == '/'     = Just "posix absolute path"
+                  | otherwise    = state4 cs
+
+    -- after initial ./ or after / between segments
+    state1 []                    = Nothing
+    state1 (c:cs) | c == '.'     = state2 cs
+                  | c == '/'     = Just "empty path segment"
+                  | otherwise    = state4 cs
+
+    -- after non-first setgment's .
+    state2 []                    = Just "trailing same directory segment: ."
+    state2 (c:cs) | c == '.'     = state3 cs
+                  | c == '/'     = Just "same directory segment: ."
+                  | otherwise    = state4 cs
+
+    -- after ..
+    state3 []                    = Just "trailing parent directory segment: .."
+    state3 (c:cs) | c == '.'     = state4 cs
+                  | c == '/'     = Just "parent directory segment: .."
+                  | otherwise    = state4 cs
+
+    -- in a segment which is ok.
+    state4 []                    = Nothing
+    state4 (c:cs) | c == '.'     = state4 cs
+                  | c == '/'     = state1 cs
+                  | otherwise    = state4 cs
+
+    -- after initial .
+    state5 []                    = Nothing -- "."
+    state5 (c:cs) | c == '.'     = state3 cs
+                  | c == '/'     = state1 cs
+                  | otherwise    = state4 cs
+
+-- [Note: Good relative paths]
+--
+-- Using @kleene@ we can define an extended regex:
+--
+-- @
+-- import Algebra.Lattice
+-- import Kleene
+-- import Kleene.ERE (ERE (..), intersections)
+--
+-- data C = CDot | CSlash | CChar
+--   deriving (Eq, Ord, Enum, Bounded, Show)
+--
+-- reservedR :: ERE C
+-- reservedR = notChar CSlash
+--
+-- pathPieceR :: ERE C
+-- pathPieceR = intersections
+--     [ plus reservedR
+--     , ERENot (string [CDot])
+--     , ERENot (string [CDot,CDot])
+--     ]
+--
+-- filePathR :: ERE C
+-- filePathR = optional (string [CDot, CSlash]) <> pathPieceR <> star (char CSlash <> pathPieceR)
+--
+-- dirPathR :: ERE C
+-- dirPathR = (char CDot \/ filePathR) <> optional (char CSlash)
+--
+-- plus :: ERE C -> ERE C
+-- plus r = r <> star r
+--
+-- optional :: ERE C -> ERE C
+-- optional r = mempty \/ r
+-- @
+--
+-- Results in following state machine for @filePathR@
+--
+-- @
+-- 0 -> \x -> if
+--     | x <= CDot           -> 1
+--     | otherwise           -> 5
+-- 1 -> \x -> if
+--     | x <= CDot           -> 4
+--     | x <= CSlash         -> 2
+--     | otherwise           -> 5
+-- 2 -> \x -> if
+--     | x <= CDot           -> 3
+--     | otherwise           -> 5
+-- 3 -> \x -> if
+--     | x <= CDot           -> 4
+--     | otherwise           -> 5
+-- 4 -> \x -> if
+--     | x <= CDot           -> 5
+--     | otherwise           -> 5
+-- 5+ -> \x -> if
+--     | x <= CDot           -> 5
+--     | x <= CSlash         -> 2
+--     | otherwise           -> 5
+-- @
+--
+-- and @dirPathR@:
+--
+-- @
+-- 0 -> \x -> if
+--     | x <= CDot           -> 5
+--     | otherwise           -> 4
+-- 1+ -> \x -> if
+--     | x <= CDot           -> 2
+--     | otherwise           -> 4
+-- 2 -> \x -> if
+--     | x <= CDot           -> 3
+--     | otherwise           -> 4
+-- 3 -> \x -> if
+--     | x <= CDot           -> 4
+--     | otherwise           -> 4
+-- 4+ -> \x -> if
+--     | x <= CDot           -> 4
+--     | x <= CSlash         -> 1
+--     | otherwise           -> 4
+-- 5+ -> \x -> if
+--     | x <= CDot           -> 3
+--     | x <= CSlash         -> 1
+--     | otherwise           -> 4
+-- @
+
+--
+-- TODO: What we really want to do is test if there exists any
+-- configuration in which the base version is unbounded above.
+-- However that's a bit tricky because there are many possible
+-- configurations. As a cheap easy and safe approximation we will
+-- pick a single "typical" configuration and check if that has an
+-- open upper bound. To get a typical configuration we finalise
+-- using no package index and the current platform.
+typicalPkg :: GenericPackageDescription
+           -> Either [Dependency] (PackageDescription, FlagAssignment)
+typicalPkg = finalizePD
+  mempty defaultComponentRequestedSpec (const True)
+  buildPlatform
+  (unknownCompilerInfo
+    (CompilerId buildCompilerFlavor nullVersion)
+      NoAbiTag)
+  []
+
+addConditionalExp :: String -> String
+addConditionalExp expl = expl ++
+         " Alternatively, if you want to use this, make it conditional based "
+      ++ "on a Cabal configuration flag (with 'manual: True' and 'default: "
+      ++ "False') and enable that flag during development."
diff --git a/cabal/Cabal/src/Distribution/ReadE.hs b/cabal/Cabal/src/Distribution/ReadE.hs
--- a/cabal/Cabal/src/Distribution/ReadE.hs
+++ b/cabal/Cabal/src/Distribution/ReadE.hs
@@ -43,7 +43,7 @@
 failReadE = ReadE . const . Left
 
 runParsecFromString :: ParsecParser a -> String -> Either Parsec.ParseError a
-runParsecFromString p txt = 
+runParsecFromString p txt =
     runParsecParser p "<parsecToReadE>" (fieldLineStreamFromString txt)
 
 parsecToReadE :: (String -> ErrorMsg) -> ParsecParser a -> ReadE a
@@ -51,11 +51,11 @@
     (const $ err txt) `Bi.first` runParsecFromString p txt
 
 parsecToReadEErr :: (Parsec.ParseError -> ErrorMsg) -> ParsecParser a -> ReadE a
-parsecToReadEErr err p = ReadE $ 
+parsecToReadEErr err p = ReadE $
     Bi.first err . runParsecFromString p
 
 -- Show only unexpected error messages
-unexpectMsgString :: Parsec.ParseError -> String 
+unexpectMsgString :: Parsec.ParseError -> String
 unexpectMsgString = unlines
    . map Parsec.messageString
    . filter (\case { Parsec.UnExpect _ -> True; _ -> False })
diff --git a/cabal/Cabal/src/Distribution/Simple.hs b/cabal/Cabal/src/Distribution/Simple.hs
--- a/cabal/Cabal/src/Distribution/Simple.hs
+++ b/cabal/Cabal/src/Distribution/Simple.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE RankNTypes #-}
 {-# LANGUAGE LambdaCase #-}
-{-# LANGUAGE CPP #-}
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Distribution.Simple
@@ -69,7 +69,6 @@
 import Distribution.PackageDescription.Configuration
 import Distribution.Simple.PackageDescription
 import Distribution.Simple.Program
-import Distribution.Simple.Program.Db
 import Distribution.Simple.PreProcess
 import Distribution.Simple.Setup
 import Distribution.Simple.Command
@@ -80,6 +79,7 @@
 
 import Distribution.Simple.Configure
 
+import Distribution.Simple.ConfigureScript
 import Distribution.Simple.LocalBuildInfo
 import Distribution.Simple.Bench
 import Distribution.Simple.BuildPaths
@@ -87,31 +87,21 @@
 import Distribution.Simple.Install
 import Distribution.Simple.Haddock
 import Distribution.Simple.Utils
-import Distribution.Utils.NubList
 import Distribution.Verbosity
 import Language.Haskell.Extension
 import Distribution.Version
 import Distribution.License
 import Distribution.Pretty
-import Distribution.System (buildPlatform)
 
 -- Base
 import System.Environment (getArgs, getProgName)
 import System.Directory   (removeFile, doesFileExist
                           ,doesDirectoryExist, removeDirectoryRecursive)
-import System.FilePath    (searchPathSeparator, takeDirectory, (</>),
-                           splitDirectories, dropDrive)
-#ifdef mingw32_HOST_OS
-import System.FilePath    (normalise, splitDrive)
-#endif
+import System.FilePath    (takeDirectory, (</>))
 import Distribution.Compat.ResponseFile (expandResponse)
-import Distribution.Compat.Directory        (makeAbsolute)
-import Distribution.Compat.Environment      (getEnvironment)
-import Distribution.Compat.GetShortPathName (getShortPathName)
 
 import Data.List       (unionBy, (\\))
 
-
 -- | A simple implementation of @main@ for a Cabal setup script.
 -- It reads the package description file using IO, and performs the
 -- action specified on the command line.
@@ -586,8 +576,7 @@
 --
 -- * 'postConf' runs @.\/configure@, if present.
 --
--- * the pre-hooks 'preBuild', 'preClean', 'preCopy', 'preInst',
---   'preReg' and 'preUnreg' read additional build information from
+-- * the pre-hooks, except for pre-conf, read additional build information from
 --   /package/@.buildinfo@, if present.
 --
 -- Thus @configure@ can use local system information to generate
@@ -598,14 +587,17 @@
     = simpleUserHooks
       {
        postConf    = defaultPostConf,
-       preBuild    = readHookWithArgs buildVerbosity buildDistPref, -- buildCabalFilePath,
+       preBuild = readHookWithArgs buildVerbosity buildDistPref,
+       preRepl = readHookWithArgs replVerbosity replDistPref,
        preCopy     = readHookWithArgs copyVerbosity copyDistPref,
        preClean    = readHook cleanVerbosity cleanDistPref,
        preInst     = readHook installVerbosity installDistPref,
        preHscolour = readHook hscolourVerbosity hscolourDistPref,
        preHaddock  = readHookWithArgs haddockVerbosity haddockDistPref,
        preReg      = readHook regVerbosity regDistPref,
-       preUnreg    = readHook regVerbosity regDistPref
+       preUnreg    = readHook regVerbosity regDistPref,
+       preTest     = readHookWithArgs testVerbosity testDistPref,
+       preBench    = readHookWithArgs benchmarkVerbosity benchmarkDistPref
       }
     where defaultPostConf :: Args -> ConfigFlags -> PackageDescription
                           -> LocalBuildInfo -> IO ()
@@ -616,7 +608,7 @@
                    confExists <- doesFileExist $ (baseDir lbi) </> "configure"
                    if confExists
                      then runConfigureScript verbosity
-                            backwardsCompatHack flags lbi
+                            flags lbi
                      else die' verbosity "configure script not found."
 
                    pbi <- getHookedBuildInfo verbosity (buildDir lbi)
@@ -625,8 +617,6 @@
                        lbi' = lbi { localPkgDescr = pkg_descr' }
                    postConf simpleUserHooks args flags pkg_descr' lbi'
 
-          backwardsCompatHack = False
-
           readHookWithArgs :: (a -> Flag Verbosity)
                            -> (a -> Flag FilePath)
                            -> Args -> a
@@ -646,112 +636,6 @@
               getHookedBuildInfo verbosity (dist_dir </> "build")
             where
               verbosity = fromFlag (get_verbosity flags)
-
-runConfigureScript :: Verbosity -> Bool -> ConfigFlags -> LocalBuildInfo
-                   -> IO ()
-runConfigureScript verbosity backwardsCompatHack flags lbi = do
-  env <- getEnvironment
-  let programDb = withPrograms lbi
-  (ccProg, ccFlags) <- configureCCompiler verbosity programDb
-  ccProgShort <- getShortPathName ccProg
-  -- The C compiler's compilation and linker flags (e.g.
-  -- "C compiler flags" and "Gcc Linker flags" from GHC) have already
-  -- been merged into ccFlags, so we set both CFLAGS and LDFLAGS
-  -- to ccFlags
-  -- We don't try and tell configure which ld to use, as we don't have
-  -- a way to pass its flags too
-  configureFile <- makeAbsolute $
-    fromMaybe "." (takeDirectory <$> cabalFilePath lbi) </> "configure"
-  -- autoconf is fussy about filenames, and has a set of forbidden
-  -- characters that can't appear in the build directory, etc:
-  -- https://www.gnu.org/software/autoconf/manual/autoconf.html#File-System-Conventions
-  --
-  -- This has caused hard-to-debug failures in the past (#5368), so we
-  -- detect some cases early and warn with a clear message. Windows's
-  -- use of backslashes is problematic here, so we'll switch to
-  -- slashes, but we do still want to fail on backslashes in POSIX
-  -- paths.
-  --
-  -- TODO: We don't check for colons, tildes or leading dashes. We
-  -- also should check the builddir's path, destdir, and all other
-  -- paths as well.
-  let configureFile' = toUnix configureFile
-  for_ badAutoconfCharacters $ \(c, cname) ->
-    when (c `elem` dropDrive configureFile') $
-      warn verbosity $ concat
-        [ "The path to the './configure' script, '", configureFile'
-        , "', contains the character '", [c], "' (", cname, ")."
-        , " This may cause the script to fail with an obscure error, or for"
-        , " building the package to fail later."
-        ]
-
-  let extraPath = fromNubList $ configProgramPathExtra flags
-  let cflagsEnv = maybe (unwords ccFlags) (++ (" " ++ unwords ccFlags))
-                  $ lookup "CFLAGS" env
-      spSep = [searchPathSeparator]
-      pathEnv = maybe (intercalate spSep extraPath)
-                ((intercalate spSep extraPath ++ spSep)++) $ lookup "PATH" env
-      overEnv = ("CFLAGS", Just cflagsEnv) :
-                [("PATH", Just pathEnv) | not (null extraPath)]
-      hp = hostPlatform lbi
-      maybeHostFlag = if hp == buildPlatform then [] else ["--host=" ++ show (pretty hp)]
-      args' = configureFile':args ++ ["CC=" ++ ccProgShort] ++ maybeHostFlag
-      shProg = simpleProgram "sh"
-      progDb = modifyProgramSearchPath
-               (\p -> map ProgramSearchPathDir extraPath ++ p) emptyProgramDb
-  shConfiguredProg <- lookupProgram shProg
-                      `fmap` configureProgram  verbosity shProg progDb
-  case shConfiguredProg of
-      Just sh -> runProgramInvocation verbosity $
-                 (programInvocation (sh {programOverrideEnv = overEnv}) args')
-                 { progInvokeCwd = Just (buildDir lbi) }
-      Nothing -> die' verbosity notFoundMsg
-  where
-    args = configureArgs backwardsCompatHack flags
-
-    notFoundMsg = "The package has a './configure' script. "
-               ++ "If you are on Windows, This requires a "
-               ++ "Unix compatibility toolchain such as MinGW+MSYS or Cygwin. "
-               ++ "If you are not on Windows, ensure that an 'sh' command "
-               ++ "is discoverable in your path."
-
--- | Convert Windows path to Unix ones
-toUnix :: String -> String
-#ifdef mingw32_HOST_OS
-toUnix s = let tmp = normalise s
-               (l, rest) = case splitDrive tmp of
-                             ([],  x) -> ("/"      , x)
-                             (h:_, x) -> ('/':h:"/", x)
-               parts = splitDirectories rest
-           in  l ++ intercalate "/" parts
-#else
-toUnix s = intercalate "/" $ splitDirectories s
-#endif
-
-badAutoconfCharacters :: [(Char, String)]
-badAutoconfCharacters =
-  [ (' ', "space")
-  , ('\t', "tab")
-  , ('\n', "newline")
-  , ('\0', "null")
-  , ('"', "double quote")
-  , ('#', "hash")
-  , ('$', "dollar sign")
-  , ('&', "ampersand")
-  , ('\'', "single quote")
-  , ('(', "left bracket")
-  , (')', "right bracket")
-  , ('*', "star")
-  , (';', "semicolon")
-  , ('<', "less-than sign")
-  , ('=', "equals sign")
-  , ('>', "greater-than sign")
-  , ('?', "question mark")
-  , ('[', "left square bracket")
-  , ('\\', "backslash")
-  , ('`', "backtick")
-  , ('|', "pipe")
-  ]
 
 getHookedBuildInfo :: Verbosity -> FilePath -> IO HookedBuildInfo
 getHookedBuildInfo verbosity build_dir = do
diff --git a/cabal/Cabal/src/Distribution/Simple/Build.hs b/cabal/Cabal/src/Distribution/Simple/Build.hs
--- a/cabal/Cabal/src/Distribution/Simple/Build.hs
+++ b/cabal/Cabal/src/Distribution/Simple/Build.hs
@@ -55,6 +55,7 @@
 import qualified Distribution.Simple.PackageIndex as Index
 
 import Distribution.Simple.Build.Macros      (generateCabalMacrosHeader)
+import Distribution.Simple.Build.PackageInfoModule (generatePackageInfoModule)
 import Distribution.Simple.Build.PathsModule (generatePathsModule)
 import qualified Distribution.Simple.Program.HcPkg as HcPkg
 
@@ -89,7 +90,6 @@
 import Distribution.Compat.Graph (IsNode(..))
 
 import Control.Monad
-import qualified Data.Set as Set
 import qualified Data.ByteString.Lazy as LBS
 import System.FilePath ( (</>), (<.>), takeDirectory )
 import System.Directory ( getCurrentDirectory, removeFile, doesFileExist )
@@ -277,6 +277,7 @@
                                   $ flip addExtraCmmSources extras
                                   $ flip addExtraCxxSources extras
                                   $ flip addExtraCSources   extras
+                                  $ flip addExtraJsSources  extras
                                   $ libbi
                    }
 
@@ -434,52 +435,43 @@
 -- information.
 addExtraCSources :: BuildInfo -> [FilePath] -> BuildInfo
 addExtraCSources bi extras = bi { cSources = new }
-  where new = Set.toList $ old `Set.union` exs
-        old = Set.fromList $ cSources bi
-        exs = Set.fromList extras
-
+  where new = ordNub (extras ++ cSources bi)
 
 -- | Add extra C++ sources generated by preprocessing to build
 -- information.
 addExtraCxxSources :: BuildInfo -> [FilePath] -> BuildInfo
 addExtraCxxSources bi extras = bi { cxxSources = new }
-  where new = Set.toList $ old `Set.union` exs
-        old = Set.fromList $ cxxSources bi
-        exs = Set.fromList extras
-
+  where new = ordNub (extras ++ cxxSources bi)
 
 -- | Add extra C-- sources generated by preprocessing to build
 -- information.
 addExtraCmmSources :: BuildInfo -> [FilePath] -> BuildInfo
 addExtraCmmSources bi extras = bi { cmmSources = new }
-  where new = Set.toList $ old `Set.union` exs
-        old = Set.fromList $ cmmSources bi
-        exs = Set.fromList extras
-
+  where new = ordNub (extras ++ cmmSources bi)
 
 -- | Add extra ASM sources generated by preprocessing to build
 -- information.
 addExtraAsmSources :: BuildInfo -> [FilePath] -> BuildInfo
 addExtraAsmSources bi extras = bi { asmSources = new }
-  where new = Set.toList $ old `Set.union` exs
-        old = Set.fromList $ asmSources bi
-        exs = Set.fromList extras
+  where new = ordNub (extras ++ asmSources bi)
 
+-- | Add extra JS sources generated by preprocessing to build
+-- information.
+addExtraJsSources :: BuildInfo -> [FilePath] -> BuildInfo
+addExtraJsSources bi extras = bi { jsSources = new }
+  where new = ordNub (extras ++ jsSources bi)
+
+
 -- | Add extra HS modules generated by preprocessing to build
 -- information.
 addExtraOtherModules :: BuildInfo -> [ModuleName.ModuleName] -> BuildInfo
 addExtraOtherModules bi extras = bi { otherModules = new }
-  where new = Set.toList $ old `Set.union` exs
-        old = Set.fromList $ otherModules bi
-        exs = Set.fromList extras
+  where new = ordNub (extras ++ otherModules bi)
 
 -- | Add extra source dir for generated modules.
 addSrcDir :: BuildInfo -> FilePath -> BuildInfo
 addSrcDir bi extra = bi { hsSourceDirs = new }
-  where new = Set.toList $ old `Set.union` ex
-        old = Set.fromList $ hsSourceDirs bi
-        ex  = Set.fromList [unsafeMakeSymbolicPath extra] -- TODO
-
+  where new = ordNub (unsafeMakeSymbolicPath extra : hsSourceDirs bi)
 
 replComponent :: ReplOptions
               -> Verbosity
@@ -790,7 +782,7 @@
 
   writeAutogenFiles verbosity pkg_descr lbi clbi
 
--- | Generate and write out the Paths_<pkg>.hs and cabal_macros.h files
+-- | Generate and write out the Paths_<pkg>.hs, PackageInfo_<pkg>.hs, and cabal_macros.h files
 --
 writeAutogenFiles :: Verbosity
                   -> PackageDescription
@@ -806,6 +798,13 @@
   -- Ensure that the directory exists!
   createDirectoryIfMissingVerbose verbosity True pathsModuleDir
   rewriteFileEx verbosity pathsModulePath (generatePathsModule pkg lbi clbi)
+
+  let packageInfoModulePath = autogenComponentModulesDir lbi clbi
+                 </> ModuleName.toFilePath (autogenPackageInfoModuleName pkg) <.> "hs"
+      packageInfoModuleDir = takeDirectory packageInfoModulePath
+  -- Ensure that the directory exists!
+  createDirectoryIfMissingVerbose verbosity True packageInfoModuleDir
+  rewriteFileEx verbosity packageInfoModulePath (generatePackageInfoModule pkg lbi)
 
   --TODO: document what we're doing here, and move it to its own function
   case clbi of
diff --git a/cabal/Cabal/src/Distribution/Simple/Build/PackageInfoModule.hs b/cabal/Cabal/src/Distribution/Simple/Build/PackageInfoModule.hs
new file mode 100644
--- /dev/null
+++ b/cabal/Cabal/src/Distribution/Simple/Build/PackageInfoModule.hs
@@ -0,0 +1,56 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Distribution.Simple.Build.PackageInfoModule
+-- Copyright   :
+--
+-- Maintainer  :  cabal-devel@haskell.org
+-- Portability :  portable
+--
+-- Generating the PackageInfo_pkgname module.
+--
+-- This is a module that Cabal generates for the benefit of packages. It
+-- enables them to find their package informations.
+--
+module Distribution.Simple.Build.PackageInfoModule (
+    generatePackageInfoModule
+  ) where
+
+import Distribution.Compat.Prelude
+import Prelude ()
+
+import Distribution.Package
+import Distribution.PackageDescription
+import Distribution.Simple.Compiler
+import Distribution.Simple.LocalBuildInfo
+import Distribution.Utils.ShortText
+import Distribution.Version
+
+import qualified Distribution.Simple.Build.PackageInfoModule.Z as Z
+
+-- ------------------------------------------------------------
+-- * Building Paths_<pkg>.hs
+-- ------------------------------------------------------------
+
+generatePackageInfoModule :: PackageDescription -> LocalBuildInfo -> String
+generatePackageInfoModule pkg_descr lbi = Z.render Z.Z
+    { Z.zPackageName   = showPkgName $ packageName pkg_descr
+    , Z.zVersionDigits = show $ versionNumbers $ packageVersion pkg_descr
+    , Z.zSynopsis        = fromShortText $ synopsis pkg_descr
+    , Z.zCopyright       = fromShortText $ copyright pkg_descr
+    , Z.zHomepage        = fromShortText $ homepage pkg_descr
+    , Z.zSupportsNoRebindableSyntax = supports_rebindable_syntax
+    }
+  where
+    supports_rebindable_syntax   = ghc_newer_than (mkVersion [7,0,1])
+
+    ghc_newer_than minVersion =
+        case compilerCompatVersion GHC (compiler lbi) of
+            Nothing      -> False
+            Just version -> version `withinRange` orLaterVersion minVersion
+
+showPkgName :: PackageName -> String
+showPkgName = map fixchar . unPackageName
+
+fixchar :: Char -> Char
+fixchar '-' = '_'
+fixchar c   = c
diff --git a/cabal/Cabal/src/Distribution/Simple/Build/PackageInfoModule/Z.hs b/cabal/Cabal/src/Distribution/Simple/Build/PackageInfoModule/Z.hs
new file mode 100644
--- /dev/null
+++ b/cabal/Cabal/src/Distribution/Simple/Build/PackageInfoModule/Z.hs
@@ -0,0 +1,60 @@
+{-# LANGUAGE DeriveGeneric #-}
+
+module Distribution.Simple.Build.PackageInfoModule.Z (render, Z (..)) where
+
+import Distribution.ZinzaPrelude
+
+data Z = Z
+  { zPackageName :: String,
+    zVersionDigits :: String,
+    zSynopsis :: String,
+    zCopyright :: String,
+    zHomepage :: String,
+    zSupportsNoRebindableSyntax :: Bool
+  }
+  deriving (Generic)
+
+render :: Z -> String
+render z_root = execWriter $ do
+  if (zSupportsNoRebindableSyntax z_root)
+  then do
+    tell "{-# LANGUAGE NoRebindableSyntax #-}\n"
+    return ()
+  else do
+    return ()
+  tell "{-# OPTIONS_GHC -fno-warn-missing-import-lists #-}\n"
+  tell "{-# OPTIONS_GHC -w #-}\n"
+  tell "module PackageInfo_"
+  tell (zPackageName z_root)
+  tell " (\n"
+  tell "    name,\n"
+  tell "    version,\n"
+  tell "    synopsis,\n"
+  tell "    copyright,\n"
+  tell "    homepage,\n"
+  tell "  ) where\n"
+  tell "\n"
+  tell "import Data.Version (Version(..))\n"
+  tell "import Prelude\n"
+  tell "\n"
+  tell "name :: String\n"
+  tell "name = "
+  tell (show $ zPackageName z_root)
+  tell "\n"
+  tell "version :: Version\n"
+  tell "version = Version "
+  tell (zVersionDigits z_root)
+  tell " []\n"
+  tell "\n"
+  tell "synopsis :: String\n"
+  tell "synopsis = "
+  tell (show $ zSynopsis z_root)
+  tell "\n"
+  tell "copyright :: String\n"
+  tell "copyright = "
+  tell (show $ zCopyright z_root)
+  tell "\n"
+  tell "homepage :: String\n"
+  tell "homepage = "
+  tell (show $ zHomepage z_root)
+  tell "\n"
diff --git a/cabal/Cabal/src/Distribution/Simple/Build/PathsModule/Z.hs b/cabal/Cabal/src/Distribution/Simple/Build/PathsModule/Z.hs
--- a/cabal/Cabal/src/Distribution/Simple/Build/PathsModule/Z.hs
+++ b/cabal/Cabal/src/Distribution/Simple/Build/PathsModule/Z.hs
@@ -41,6 +41,14 @@
     return ()
   else do
     return ()
+  if (zSupportsCpp z_root)
+  then do
+    tell "#if __GLASGOW_HASKELL__ >= 810\n"
+    tell "{-# OPTIONS_GHC -Wno-prepositive-qualified-module #-}\n"
+    tell "#endif\n"
+    return ()
+  else do
+    return ()
   tell "{-# OPTIONS_GHC -fno-warn-missing-import-lists #-}\n"
   tell "{-# OPTIONS_GHC -w #-}\n"
   tell "module Paths_"
@@ -104,7 +112,30 @@
   tell "\n"
   tell "getBinDir, getLibDir, getDynLibDir, getDataDir, getLibexecDir, getSysconfDir :: IO FilePath\n"
   tell "\n"
+  let
+    z_var0_function_defs = do
+      tell "minusFileName :: FilePath -> String -> FilePath\n"
+      tell "minusFileName dir \"\"     = dir\n"
+      tell "minusFileName dir \".\"    = dir\n"
+      tell "minusFileName dir suffix =\n"
+      tell "  minusFileName (fst (splitFileName dir)) (fst (splitFileName suffix))\n"
+      tell "\n"
+      tell "splitFileName :: FilePath -> (String, String)\n"
+      tell "splitFileName p = (reverse (path2++drive), reverse fname)\n"
+      tell "  where\n"
+      tell "    (path,drive) = case p of\n"
+      tell "      (c:':':p') -> (reverse p',[':',c])\n"
+      tell "      _          -> (reverse p ,\"\")\n"
+      tell "    (fname,path1) = break isPathSeparator path\n"
+      tell "    path2 = case path1 of\n"
+      tell "      []                           -> \".\"\n"
+      tell "      [_]                          -> path1   -- don't remove the trailing slash if\n"
+      tell "                                              -- there is only one character\n"
+      tell "      (c:path') | isPathSeparator c -> path'\n"
+      tell "      _                             -> path1\n"
+      return ()
   tell "\n"
+  tell "\n"
   if (zRelocatable z_root)
   then do
     tell "\n"
@@ -147,6 +178,8 @@
     tell (zSysconfdir z_root)
     tell ")\n"
     tell "\n"
+    z_var0_function_defs
+    tell "\n"
     return ()
   else do
     if (zAbsolute z_root)
@@ -237,6 +270,8 @@
         tell ") `joinFileName` dirRel)\n"
         tell "            | otherwise  -> try_size (size * 2)\n"
         tell "\n"
+        z_var0_function_defs
+        tell "\n"
         if (zIsI386 z_root)
         then do
           tell "foreign import stdcall unsafe \"windows.h GetModuleFileNameW\"\n"
@@ -265,31 +300,6 @@
       return ()
     return ()
   tell "\n"
-  tell "\n"
-  if (zNot z_root (zAbsolute z_root))
-  then do
-    tell "minusFileName :: FilePath -> String -> FilePath\n"
-    tell "minusFileName dir \"\"     = dir\n"
-    tell "minusFileName dir \".\"    = dir\n"
-    tell "minusFileName dir suffix =\n"
-    tell "  minusFileName (fst (splitFileName dir)) (fst (splitFileName suffix))\n"
-    tell "\n"
-    tell "splitFileName :: FilePath -> (String, String)\n"
-    tell "splitFileName p = (reverse (path2++drive), reverse fname)\n"
-    tell "  where\n"
-    tell "    (path,drive) = case p of\n"
-    tell "       (c:':':p') -> (reverse p',[':',c])\n"
-    tell "       _          -> (reverse p ,\"\")\n"
-    tell "    (fname,path1) = break isPathSeparator path\n"
-    tell "    path2 = case path1 of\n"
-    tell "      []                           -> \".\"\n"
-    tell "      [_]                          -> path1   -- don't remove the trailing slash if\n"
-    tell "                                              -- there is only one character\n"
-    tell "      (c:path') | isPathSeparator c -> path'\n"
-    tell "      _                             -> path1\n"
-    return ()
-  else do
-    return ()
   tell "\n"
   tell "joinFileName :: String -> String -> FilePath\n"
   tell "joinFileName \"\"  fname = fname\n"
diff --git a/cabal/Cabal/src/Distribution/Simple/BuildPaths.hs b/cabal/Cabal/src/Distribution/Simple/BuildPaths.hs
--- a/cabal/Cabal/src/Distribution/Simple/BuildPaths.hs
+++ b/cabal/Cabal/src/Distribution/Simple/BuildPaths.hs
@@ -20,6 +20,7 @@
     autogenComponentModulesDir,
 
     autogenPathsModuleName,
+    autogenPackageInfoModuleName,
     cppHeaderName,
     haddockName,
 
@@ -105,6 +106,14 @@
   where fixchar '-' = '_'
         fixchar c   = c
 
+-- | The name of the auto-generated PackageInfo_* module associated with a package
+autogenPackageInfoModuleName :: PackageDescription -> ModuleName
+autogenPackageInfoModuleName pkg_descr =
+  ModuleName.fromString $
+    "PackageInfo_" ++ map fixchar (prettyShow (packageName pkg_descr))
+  where fixchar '-' = '_'
+        fixchar c   = c
+
 haddockName :: PackageDescription -> FilePath
 haddockName pkg_descr = prettyShow (packageName pkg_descr) <.> "haddock"
 
@@ -235,8 +244,9 @@
 -- | Default extension for executable files on the current platform.
 -- (typically @\"\"@ on Unix and @\"exe\"@ on Windows or OS\/2)
 exeExtension :: Platform -> String
-exeExtension (Platform _arch os) = case os of
-                   Windows -> "exe"
+exeExtension platform = case platform of
+                   Platform _ Windows -> "exe"
+                   Platform Wasm32 _  -> "wasm"
                    _       -> ""
 
 -- | Extension for object files. For GHC the extension is @\"o\"@.
diff --git a/cabal/Cabal/src/Distribution/Simple/Command.hs b/cabal/Cabal/src/Distribution/Simple/Command.hs
--- a/cabal/Cabal/src/Distribution/Simple/Command.hs
+++ b/cabal/Cabal/src/Distribution/Simple/Command.hs
@@ -134,6 +134,14 @@
 
 -- | Create an option taking a single OptDescr.
 --   No explicit Name is given for the Option, the name is the first LFlag given.
+--
+-- Example: @'option' sf lf d get set@
+-- * @sf@: Short option name, for example: @[\'d\']@. No hyphen permitted.
+-- * @lf@: Long option name, for example: @["debug"]@. No hyphens permitted.
+-- * @d@: Description of the option, shown to the user in help messages.
+-- * @get@: Get the current value of the flag.
+-- * @set@: Set the value of the flag. Gets the current value of the flag as a
+--          parameter.
 option :: SFlags -> LFlags -> Description -> get -> set -> MkOptDescr get set a
           -> OptionField a
 option sf lf@(n:_) d get set arg = OptionField n [arg sf lf d get set]
@@ -153,6 +161,15 @@
                             -> OptDescr a
 
 -- | Create a string-valued command line interface.
+-- Usually called in the context of 'option' or 'multiOption'.
+--
+-- Example: @'reqArg' ad mkflag showflag@
+--
+-- * @ad@: Placeholder shown to the user, e.g. @"FILES"@ if files are expected
+--         parameters.
+-- * @mkflag@: How to parse the argument into the option.
+-- * @showflag@: If parsing goes wrong, display a useful error message to
+--               the user.
 reqArg :: Monoid b => ArgPlaceHolder -> ReadE b -> (b -> [String])
                    -> MkOptDescr (a -> b) (b -> a -> a) a
 reqArg ad mkflag showflag sf lf d get set =
@@ -574,7 +591,7 @@
     commandNotes = Just $ \pname ->
        "Examples:\n"
     ++ "  " ++ pname ++ " help help\n"
-    ++ "    Oh, appararently you already know this.\n"
+    ++ "    Oh, apparently you already know this.\n"
   }
 
 -- | wraps a @CommandUI@ together with a function that turns it into a @Command@.
diff --git a/cabal/Cabal/src/Distribution/Simple/Compiler.hs b/cabal/Cabal/src/Distribution/Simple/Compiler.hs
--- a/cabal/Cabal/src/Distribution/Simple/Compiler.hs
+++ b/cabal/Cabal/src/Distribution/Simple/Compiler.hs
@@ -425,6 +425,7 @@
                      | ProfDetailExportedFunctions
                      | ProfDetailToplevelFunctions
                      | ProfDetailAllFunctions
+                     | ProfDetailTopLate
                      | ProfDetailOther String
     deriving (Eq, Generic, Read, Show, Typeable)
 
@@ -448,6 +449,7 @@
   , ("exported-functions", ["exported"],        ProfDetailExportedFunctions)
   , ("toplevel-functions", ["toplevel", "top"], ProfDetailToplevelFunctions)
   , ("all-functions",      ["all"],             ProfDetailAllFunctions)
+  , ("late-toplevel",      ["late"],            ProfDetailTopLate)
   ]
 
 showProfDetailLevel :: ProfDetailLevel -> String
@@ -457,4 +459,5 @@
     ProfDetailExportedFunctions -> "exported-functions"
     ProfDetailToplevelFunctions -> "toplevel-functions"
     ProfDetailAllFunctions      -> "all-functions"
+    ProfDetailTopLate           -> "late-toplevel"
     ProfDetailOther other       -> other
diff --git a/cabal/Cabal/src/Distribution/Simple/Configure.hs b/cabal/Cabal/src/Distribution/Simple/Configure.hs
--- a/cabal/Cabal/src/Distribution/Simple/Configure.hs
+++ b/cabal/Cabal/src/Distribution/Simple/Configure.hs
@@ -55,7 +55,7 @@
   , platformDefines,
   ) where
 
-import qualified Prelude as Unsafe (tail)
+import Prelude ()
 import Distribution.Compat.Prelude
 
 import Distribution.Compiler
@@ -77,12 +77,13 @@
 import Distribution.Simple.Setup as Setup
 import Distribution.Simple.BuildTarget
 import Distribution.Simple.LocalBuildInfo
+import Distribution.Simple.Program.Db (appendProgramSearchPath, modifyProgramSearchPath, lookupProgramByName)
+import Distribution.Simple.Utils
+import Distribution.System
 import Distribution.Types.PackageVersionConstraint
 import Distribution.Types.LocalBuildInfo
 import Distribution.Types.ComponentRequestedSpec
 import Distribution.Types.GivenComponent
-import Distribution.Simple.Utils
-import Distribution.System
 import Distribution.Version
 import Distribution.Verbosity
 import qualified Distribution.Compat.Graph as Graph
@@ -102,20 +103,20 @@
 import Control.Exception
     ( try )
 import Distribution.Utils.Structured ( structuredDecodeOrFailIO, structuredEncode )
-import Distribution.Compat.Directory ( listDirectory )
+import Distribution.Compat.Directory
+    ( listDirectory, doesPathExist )
 import Data.ByteString.Lazy          ( ByteString )
 import qualified Data.ByteString            as BS
 import qualified Data.ByteString.Lazy.Char8 as BLC8
 import Data.List
-    ( (\\), inits, stripPrefix, intersect)
+    ( (\\), stripPrefix, intersect)
+import qualified Data.List.NonEmpty as NEL
 import qualified Data.Map as Map
 import System.Directory
     ( canonicalizePath, createDirectoryIfMissing, doesFileExist
     , getTemporaryDirectory, removeFile)
 import System.FilePath
     ( (</>), isAbsolute, takeDirectory )
-import Distribution.Compat.Directory
-    ( doesPathExist )
 import qualified System.Info
     ( compilerName, compilerVersion )
 import System.IO
@@ -129,6 +130,7 @@
     , punctuate, quotes, render, renderStyle, sep, text )
 import Distribution.Compat.Environment ( lookupEnv )
 
+import qualified Data.Maybe as M
 import qualified Data.Set as Set
 import qualified Distribution.Compat.NonEmptySet as NES
 
@@ -366,18 +368,19 @@
             (fromFlag (configUserInstall cfg))
             (configPackageDBs cfg)
 
+    programDbPre <- mkProgramDb cfg (configPrograms cfg)
     -- comp:            the compiler we're building with
     -- compPlatform:    the platform we're building for
     -- programDb:  location and args of all programs we're
     --                  building with
-    (comp         :: Compiler,
+    (comp :: Compiler,
      compPlatform :: Platform,
-     programDb    :: ProgramDb)
+     programDb :: ProgramDb)
         <- configCompilerEx
             (flagToMaybe (configHcFlavor cfg))
             (flagToMaybe (configHcPath cfg))
             (flagToMaybe (configHcPkg cfg))
-            (mkProgramDb cfg (configPrograms cfg))
+            programDbPre
             (lessVerbose verbosity)
 
     -- The InstalledPackageIndex of all installed packages
@@ -636,21 +639,16 @@
                                       "--enable-split-objs; ignoring")
                                 return False
 
-    let compilerSupportsGhciLibs :: Bool
-        compilerSupportsGhciLibs =
-          case compilerId comp of
-            CompilerId GHC version
-              | version > mkVersion [9,3] && windows ->
-                False
-            CompilerId GHC _ ->
-                True
-            CompilerId GHCJS _ ->
-                True
-            _ -> False
-          where
-            windows = case compPlatform of
-              Platform _ Windows -> True
-              Platform _ _ -> False
+    -- Basically yes/no/unknown.
+    let linkerSupportsRelocations :: Maybe Bool
+        linkerSupportsRelocations =
+          case lookupProgramByName "ld" programDb'' of
+            Nothing -> Nothing
+            Just ld ->
+              case Map.lookup "Supports relocatable output" $ programProperties ld of
+                Just "YES" -> Just True
+                Just "NO" -> Just False
+                _other -> Nothing
 
     let ghciLibByDefault =
           case compilerId comp of
@@ -670,10 +668,12 @@
 
     withGHCiLib_ <-
       case fromFlagOrDefault ghciLibByDefault (configGHCiLib cfg) of
-        True | not compilerSupportsGhciLibs -> do
+        -- NOTE: If linkerSupportsRelocations is Nothing this may still fail if the
+        -- linker does not support -r.
+        True | not (fromMaybe True linkerSupportsRelocations) -> do
           warn verbosity $
-                "--enable-library-for-ghci is no longer supported on Windows with"
-              ++ " GHC 9.4 and later; ignoring..."
+            "--enable-library-for-ghci is not supported with the current"
+            ++ "  linker; ignoring..."
           return False
         v -> return v
 
@@ -842,17 +842,28 @@
     where
       verbosity = fromFlag (configVerbosity cfg)
 
-mkProgramDb :: ConfigFlags -> ProgramDb -> ProgramDb
-mkProgramDb cfg initialProgramDb = programDb
+-- | Adds the extra program paths from the flags provided to @configure@ as
+-- well as specified locations for certain known programs and their default
+-- arguments.
+mkProgramDb :: ConfigFlags -> ProgramDb -> IO ProgramDb
+mkProgramDb cfg initialProgramDb = do
+  programDb <-
+    modifyProgramSearchPath (getProgramSearchPath initialProgramDb ++)
+      <$> appendProgramSearchPath (fromFlagOrDefault normal (configVerbosity cfg)) searchpath initialProgramDb
+  pure
+    . userSpecifyArgss (configProgramArgs cfg)
+    . userSpecifyPaths (configProgramPaths cfg)
+    $ programDb
   where
-    programDb  = userSpecifyArgss (configProgramArgs cfg)
-                 . userSpecifyPaths (configProgramPaths cfg)
-                 . setProgramSearchPath searchpath
-                 $ initialProgramDb
-    searchpath = getProgramSearchPath initialProgramDb
-                 ++ map ProgramSearchPathDir
-                 (fromNubList $ configProgramPathExtra cfg)
+    searchpath = fromNubList $ configProgramPathExtra cfg
 
+-- Note. We try as much as possible to _prepend_ rather than postpend the extra-prog-path
+-- so that we can override the system path. However, in a v2-build, at this point, the "system" path
+-- has already been extended by both the built-tools-depends paths, as well as the program-path-extra
+-- so for v2 builds adding it again is entirely unnecessary. However, it needs to get added again _anyway_
+-- so as to take effect for v1 builds or standalone calls to Setup.hs
+-- In this instance, the lesser evil is to not allow it to override the system path.
+
 -- -----------------------------------------------------------------------------
 -- Helper functions for configure
 
@@ -937,11 +948,11 @@
         then internalDepSatisfiable
         else
           -- Backward compatibility for the old sublibrary syntax
-          (sublibs == mainLibSet
+          sublibs == mainLibSet
             && Map.member
                  (pn, CLibName $ LSubLibName $
                       packageNameToUnqualComponentName depName)
-                 requiredDepsMap)
+                 requiredDepsMap
 
           || all visible sublibs
 
@@ -968,7 +979,7 @@
     internalDepSatisfiable =
         Set.isSubsetOf (NES.toSet sublibs) packageLibraries
     internalDepSatisfiableExternally =
-        all (\ln -> not $ null $ PackageIndex.lookupInternalDependency installedPackageSet pn vr ln) sublibs
+        all (not . null . PackageIndex.lookupInternalDependency installedPackageSet pn vr) sublibs
 
     -- Check whether a library exists and is visible.
     -- We don't disambiguate between dependency on non-existent or private
@@ -1437,8 +1448,7 @@
 -- flag into a single package db stack.
 --
 interpretPackageDbFlags :: Bool -> [Maybe PackageDB] -> PackageDBStack
-interpretPackageDbFlags userInstall specificDBs =
-    extra initialStack specificDBs
+interpretPackageDbFlags userInstall = extra initialStack
   where
     initialStack | userInstall = [GlobalPackageDB, UserPackageDB]
                  | otherwise   = [GlobalPackageDB]
@@ -1684,8 +1694,8 @@
   let (includeDirs',  cflags')   = partition ("-I" `isPrefixOf`) cflags
       (extraLibs',    ldflags')  = partition ("-l" `isPrefixOf`) ldflags
       (extraLibDirs', ldflags'') = partition ("-L" `isPrefixOf`) ldflags'
-      (extraLibsStatic')         = filter ("-l" `isPrefixOf`) ldflags_static
-      (extraLibDirsStatic')      = filter ("-L" `isPrefixOf`) ldflags_static
+      extraLibsStatic'         = filter ("-l" `isPrefixOf`) ldflags_static
+      extraLibDirsStatic'      = filter ("-L" `isPrefixOf`) ldflags_static
   in mempty {
        includeDirs  = map (drop 2) includeDirs',
        extraLibs    = map (drop 2) extraLibs',
@@ -1701,13 +1711,13 @@
 
 configCompilerAuxEx :: ConfigFlags
                     -> IO (Compiler, Platform, ProgramDb)
-configCompilerAuxEx cfg = configCompilerEx (flagToMaybe $ configHcFlavor cfg)
+configCompilerAuxEx cfg = do
+  programDb <- mkProgramDb cfg defaultProgramDb
+  configCompilerEx (flagToMaybe $ configHcFlavor cfg)
                                            (flagToMaybe $ configHcPath cfg)
                                            (flagToMaybe $ configHcPkg cfg)
                                            programDb
                                            (fromFlag (configVerbosity cfg))
-  where
-    programDb = mkProgramDb cfg defaultProgramDb
 
 configCompilerEx :: Maybe CompilerFlavor -> Maybe FilePath -> Maybe FilePath
                  -> ProgramDb -> Verbosity
@@ -1784,7 +1794,7 @@
         findOffendingHdr =
             ifBuildsWith allHeaders ccArgs
                          (return Nothing)
-                         (go . Unsafe.tail . inits $ allHeaders) -- inits always contains at least []
+                         (go . tail . NEL.inits $ allHeaders)
             where
               go [] = return Nothing       -- cannot happen
               go (hdrs:hdrsInits) =
@@ -1962,11 +1972,19 @@
 checkPackageProblems verbosity dir gpkg pkg = do
   ioChecks      <- checkPackageFiles verbosity pkg dir
   let pureChecks = checkPackage gpkg (Just pkg)
-      errors   = [ e | PackageBuildImpossible e <- pureChecks ++ ioChecks ]
-      warnings = [ w | PackageBuildWarning    w <- pureChecks ++ ioChecks ]
+      (errors, warnings) =
+        partitionEithers (M.mapMaybe classEW $ pureChecks ++ ioChecks)
   if null errors
-    then traverse_ (warn verbosity) warnings
-    else die' verbosity (intercalate "\n\n" errors)
+    then traverse_ (warn verbosity) (map ppPackageCheck warnings)
+    else die' verbosity (intercalate "\n\n" $ map ppPackageCheck errors)
+  where
+    -- Classify error/warnings. Left: error, Right: warning.
+    classEW :: PackageCheck -> Maybe (Either PackageCheck PackageCheck)
+    classEW e@(PackageBuildImpossible _) = Just (Left e)
+    classEW w@(PackageBuildWarning _) = Just (Right w)
+    classEW (PackageDistSuspicious _) = Nothing
+    classEW (PackageDistSuspiciousWarn _) = Nothing
+    classEW (PackageDistInexcusable _) = Nothing
 
 -- | Preform checks if a relocatable build is allowed
 checkRelocatable :: Verbosity
@@ -2058,7 +2076,7 @@
     go :: CompilerFlavor -> Maybe String
     go GHC
       | compilerVersion comp < mkVersion [7,8] = unsupported [
-        "Building foreign libraires is only supported with GHC >= 7.8"
+        "Building foreign libraries is only supported with GHC >= 7.8"
       ]
       | otherwise = goGhcPlatform platform
     go _   = unsupported [
diff --git a/cabal/Cabal/src/Distribution/Simple/ConfigureScript.hs b/cabal/Cabal/src/Distribution/Simple/ConfigureScript.hs
new file mode 100644
--- /dev/null
+++ b/cabal/Cabal/src/Distribution/Simple/ConfigureScript.hs
@@ -0,0 +1,194 @@
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE CPP #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Distribution.Simple.ConfigureScript
+-- Copyright   :  Isaac Jones 2003-2005
+-- License     :  BSD3
+--
+-- Maintainer  :  cabal-devel@haskell.org
+-- Portability :  portable
+--
+{-# OPTIONS_GHC -fno-warn-deprecations #-}
+
+module Distribution.Simple.ConfigureScript (
+    runConfigureScript
+  ) where
+
+import Prelude ()
+import Distribution.Compat.Prelude
+
+-- local
+import Distribution.PackageDescription
+import Distribution.Simple.Program
+import Distribution.Simple.Program.Db
+import Distribution.Simple.Setup
+
+import Distribution.Simple.LocalBuildInfo
+import Distribution.Simple.Utils
+import Distribution.Utils.NubList
+import Distribution.Verbosity
+import Distribution.Pretty
+import Distribution.System (buildPlatform)
+
+-- Base
+import System.FilePath    (searchPathSeparator, takeDirectory, (</>),
+                           splitDirectories, dropDrive)
+#ifdef mingw32_HOST_OS
+import System.FilePath    (normalise, splitDrive)
+#endif
+import Distribution.Compat.Directory        (makeAbsolute)
+import Distribution.Compat.Environment      (getEnvironment)
+import Distribution.Compat.GetShortPathName (getShortPathName)
+
+import qualified Data.List.NonEmpty as NonEmpty
+import qualified Data.Map as Map
+
+runConfigureScript :: Verbosity -> ConfigFlags -> LocalBuildInfo
+                   -> IO ()
+runConfigureScript verbosity flags lbi = do
+  env <- getEnvironment
+  let programDb = withPrograms lbi
+  (ccProg, ccFlags) <- configureCCompiler verbosity programDb
+  ccProgShort <- getShortPathName ccProg
+  -- The C compiler's compilation and linker flags (e.g.
+  -- "C compiler flags" and "Gcc Linker flags" from GHC) have already
+  -- been merged into ccFlags, so we set both CFLAGS and LDFLAGS
+  -- to ccFlags
+  -- We don't try and tell configure which ld to use, as we don't have
+  -- a way to pass its flags too
+  configureFile <- makeAbsolute $
+    fromMaybe "." (takeDirectory <$> cabalFilePath lbi) </> "configure"
+  -- autoconf is fussy about filenames, and has a set of forbidden
+  -- characters that can't appear in the build directory, etc:
+  -- https://www.gnu.org/software/autoconf/manual/autoconf.html#File-System-Conventions
+  --
+  -- This has caused hard-to-debug failures in the past (#5368), so we
+  -- detect some cases early and warn with a clear message. Windows's
+  -- use of backslashes is problematic here, so we'll switch to
+  -- slashes, but we do still want to fail on backslashes in POSIX
+  -- paths.
+  --
+  -- TODO: We don't check for colons, tildes or leading dashes. We
+  -- also should check the builddir's path, destdir, and all other
+  -- paths as well.
+  let configureFile' = toUnix configureFile
+  for_ badAutoconfCharacters $ \(c, cname) ->
+    when (c `elem` dropDrive configureFile') $
+      warn verbosity $ concat
+        [ "The path to the './configure' script, '", configureFile'
+        , "', contains the character '", [c], "' (", cname, ")."
+        , " This may cause the script to fail with an obscure error, or for"
+        , " building the package to fail later."
+        ]
+
+  let -- Convert a flag name to name of environment variable to represent its
+      -- value for the configure script.
+      flagEnvVar :: FlagName -> String
+      flagEnvVar flag = "CABAL_FLAG_" ++ map f (unFlagName flag)
+        where f c
+                | isAlphaNum c = c
+                | otherwise    = '_'
+      -- A map from such env vars to every flag name and value where the name
+      -- name maps to that that env var.
+      cabalFlagMap :: Map String (NonEmpty (FlagName, Bool))
+      cabalFlagMap = Map.fromListWith (<>)
+                     [ (flagEnvVar flag, (flag, bool) :| [])
+                     | (flag, bool) <- unFlagAssignment $ flagAssignment lbi
+                     ]
+  -- A map from env vars to flag names to the single flag we will go with
+  cabalFlagMapDeconflicted :: Map String (FlagName, Bool) <-
+    flip Map.traverseWithKey cabalFlagMap $ \ envVar -> \case
+      -- No conflict: no problem
+      singleFlag :| [] -> pure singleFlag
+      -- Conflict: warn and discard all but first
+      collidingFlags@(firstFlag :| _ : _) -> do
+        let quote s = "'" ++ s ++ "'"
+            toName = quote . unFlagName . fst
+            renderedList = intercalate ", " $ NonEmpty.toList $ toName <$> collidingFlags
+        warn verbosity $ unwords
+          [ "Flags", renderedList, "all map to the same environment variable"
+          , quote envVar, "causing a collision."
+          , "The value first flag", toName firstFlag, "will be used."
+          ]
+        pure firstFlag
+
+  let cabalFlagEnv = [ (envVar, Just val)
+                     | (envVar, (_, bool)) <- Map.toList cabalFlagMapDeconflicted
+                     , let val = if bool then "1" else "0"
+                     ] ++
+                     [ ( "CABAL_FLAGS"
+                       , Just $ unwords [ showFlagValue fv | fv <- unFlagAssignment $ flagAssignment lbi ]
+                       )
+                     ]
+  let extraPath = fromNubList $ configProgramPathExtra flags
+  let cflagsEnv = maybe (unwords ccFlags) (++ (" " ++ unwords ccFlags))
+                  $ lookup "CFLAGS" env
+      spSep = [searchPathSeparator]
+      pathEnv = maybe (intercalate spSep extraPath)
+                ((intercalate spSep extraPath ++ spSep)++) $ lookup "PATH" env
+      overEnv = ("CFLAGS", Just cflagsEnv) :
+                [("PATH", Just pathEnv) | not (null extraPath)] ++
+                cabalFlagEnv
+      hp = hostPlatform lbi
+      maybeHostFlag = if hp == buildPlatform then [] else ["--host=" ++ show (pretty hp)]
+      args' = configureFile':args ++ ["CC=" ++ ccProgShort] ++ maybeHostFlag
+      shProg = simpleProgram "sh"
+  progDb <- appendProgramSearchPath verbosity extraPath emptyProgramDb
+  shConfiguredProg <- lookupProgram shProg
+                      `fmap` configureProgram verbosity shProg progDb
+  case shConfiguredProg of
+      Just sh -> runProgramInvocation verbosity $
+                 (programInvocation (sh {programOverrideEnv = overEnv}) args')
+                 { progInvokeCwd = Just (buildDir lbi) }
+      Nothing -> die' verbosity notFoundMsg
+  where
+    args = configureArgs backwardsCompatHack flags
+    backwardsCompatHack = False
+
+    notFoundMsg = "The package has a './configure' script. "
+               ++ "If you are on Windows, This requires a "
+               ++ "Unix compatibility toolchain such as MinGW+MSYS or Cygwin. "
+               ++ "If you are not on Windows, ensure that an 'sh' command "
+               ++ "is discoverable in your path."
+
+-- | Convert Windows path to Unix ones
+toUnix :: String -> String
+#ifdef mingw32_HOST_OS
+toUnix s = let tmp = normalise s
+               (l, rest) = case splitDrive tmp of
+                             ([],  x) -> ("/"      , x)
+                             (h:_, x) -> ('/':h:"/", x)
+               parts = splitDirectories rest
+           in  l ++ intercalate "/" parts
+#else
+toUnix s = intercalate "/" $ splitDirectories s
+#endif
+
+badAutoconfCharacters :: [(Char, String)]
+badAutoconfCharacters =
+  [ (' ', "space")
+  , ('\t', "tab")
+  , ('\n', "newline")
+  , ('\0', "null")
+  , ('"', "double quote")
+  , ('#', "hash")
+  , ('$', "dollar sign")
+  , ('&', "ampersand")
+  , ('\'', "single quote")
+  , ('(', "left bracket")
+  , (')', "right bracket")
+  , ('*', "star")
+  , (';', "semicolon")
+  , ('<', "less-than sign")
+  , ('=', "equals sign")
+  , ('>', "greater-than sign")
+  , ('?', "question mark")
+  , ('[', "left square bracket")
+  , ('\\', "backslash")
+  , ('`', "backtick")
+  , ('|', "pipe")
+  ]
diff --git a/cabal/Cabal/src/Distribution/Simple/GHC.hs b/cabal/Cabal/src/Distribution/Simple/GHC.hs
--- a/cabal/Cabal/src/Distribution/Simple/GHC.hs
+++ b/cabal/Cabal/src/Distribution/Simple/GHC.hs
@@ -114,7 +114,8 @@
 import Data.Char (isLower)
 import qualified Data.Map as Map
 import System.Directory
-         ( doesFileExist, getAppUserDataDirectory, createDirectoryIfMissing
+         ( doesFileExist, doesDirectoryExist
+         , getAppUserDataDirectory, createDirectoryIfMissing
          , canonicalizePath, removeFile, renameFile, getDirectoryContents
          , makeRelativeToCurrentDirectory )
 import System.FilePath          ( (</>), (<.>), takeExtension
@@ -139,12 +140,12 @@
       (userMaybeSpecifyPath "ghc" hcPath conf0)
   let implInfo = ghcVersionImplInfo ghcVersion
 
-  -- Cabal currently supports ghc >= 7.0.1 && < 9.6
+  -- Cabal currently supports ghc >= 7.0.1 && < 9.10
   -- ... and the following odd development version
-  unless (ghcVersion < mkVersion [9,6]) $
+  unless (ghcVersion < mkVersion [9,10]) $
     warn verbosity $
          "Unknown/unsupported 'ghc' version detected "
-      ++ "(Cabal " ++ prettyShow cabalVersion ++ " supports 'ghc' version < 9.6): "
+      ++ "(Cabal " ++ prettyShow cabalVersion ++ " supports 'ghc' version < 9.10): "
       ++ programPath ghcProg ++ " is version " ++ prettyShow ghcVersion
 
   -- This is slightly tricky, we have to configure ghc first, then we use the
@@ -184,10 +185,13 @@
 
   ghcInfo <- Internal.getGhcInfo verbosity implInfo ghcProg
   let ghcInfoMap = Map.fromList ghcInfo
-      extensions = -- workaround https://gitlab.haskell.org/ghc/ghc/-/issues/11214
-                   filterExt JavaScriptFFI $
-                   -- see 'filterExtTH' comment below
-                   filterExtTH $ extensions0
+      filterJS = if ghcVersion < mkVersion [9, 8] then filterExt JavaScriptFFI else id
+      extensions =
+        -- workaround https://gitlab.haskell.org/ghc/ghc/-/issues/11214
+        filterJS $
+          -- see 'filterExtTH' comment below
+          filterExtTH $
+            extensions0
 
       -- starting with GHC 8.0, `TemplateHaskell` will be omitted from
       -- `--supported-extensions` when it's not available.
@@ -522,7 +526,8 @@
       comp = compiler lbi
       ghcVersion = compilerVersion comp
       implInfo  = getImplInfo comp
-      platform@(Platform _hostArch hostOS) = hostPlatform lbi
+      platform@(Platform hostArch hostOS) = hostPlatform lbi
+      hasJsSupport = hostArch == JavaScript
       has_code = not (componentIsIndefinite clbi)
 
   relLibTargetDir <- makeRelativeToCurrentDirectory libTargetDir
@@ -532,6 +537,11 @@
 
   let libBi = libBuildInfo lib
 
+  -- ensure extra lib dirs exist before passing to ghc
+  cleanedExtraLibDirs <- filterM doesDirectoryExist (extraLibDirs libBi)
+  cleanedExtraLibDirsStatic <- filterM doesDirectoryExist (extraLibDirsStatic libBi)
+
+
   let isGhcDynamic        = isDynamic comp
       dynamicTooSupported = supportsDynamicToo comp
       doingTH = usesTemplateHaskellOrQQ libBi
@@ -561,6 +571,13 @@
                       , toNubListR (cxxSources libBi)
                       , toNubListR (cmmSources libBi)
                       , toNubListR (asmSources libBi)
+                      , if hasJsSupport
+                        -- JS files are C-like with GHC's JS backend: they are
+                        -- "compiled" into `.o` files (renamed with a header).
+                        -- This is a difference from GHCJS, for which we only
+                        -- pass the JS files at link time.
+                        then toNubListR (jsSources  libBi)
+                        else mempty
                       ]
       cLikeObjs   = map (`replaceExtension` objExtension) cLikeSources
       baseOpts    = componentGhcOptions verbosity lbi libBi clbi libTargetDir
@@ -602,8 +619,8 @@
                                                   else extraLibs libBi,
                       ghcOptLinkLibPath       = toNubListR $
                                                   if withFullyStaticExe lbi
-                                                    then extraLibDirsStatic libBi
-                                                    else extraLibDirs libBi,
+                                                    then cleanedExtraLibDirsStatic
+                                                    else cleanedExtraLibDirs,
                       ghcOptLinkFrameworks    = toNubListR $ PD.frameworks libBi,
                       ghcOptLinkFrameworkDirs = toNubListR $
                                                 PD.extraFrameworkDirs libBi,
@@ -688,35 +705,57 @@
       | filename <- cxxSources libBi]
 
   -- build any C sources
-  unless (not has_code || null (cSources libBi)) $ do
+  let libraryName = case libName lib of
+          LMainLibName -> "the main library"
+          LSubLibName name -> "library " <> prettyShow name
+  cSrcs' <- checkCSources verbosity libraryName (cSources libBi)
+  unless (not has_code || null cSrcs') $ do
     info verbosity "Building C Sources..."
+    forM_ cSrcs' $ \filename -> do
+       let baseCcOpts    = Internal.componentCcGhcOptions verbosity implInfo
+                           lbi libBi clbi relLibTargetDir filename
+           vanillaCcOpts = if isGhcDynamic
+                           -- Dynamic GHC requires C sources to be built
+                           -- with -fPIC for REPL to work. See #2207.
+                           then baseCcOpts { ghcOptFPic = toFlag True }
+                           else baseCcOpts
+           profCcOpts    = vanillaCcOpts `mappend` mempty {
+                             ghcOptProfilingMode = toFlag True,
+                             ghcOptObjSuffix     = toFlag "p_o"
+                           }
+           sharedCcOpts  = vanillaCcOpts `mappend` mempty {
+                             ghcOptFPic        = toFlag True,
+                             ghcOptDynLinkMode = toFlag GhcDynamicOnly,
+                             ghcOptObjSuffix   = toFlag "dyn_o"
+                           }
+           odir          = fromFlag (ghcOptObjDir vanillaCcOpts)
+       createDirectoryIfMissingVerbose verbosity True odir
+       let runGhcProgIfNeeded ccOpts = do
+             needsRecomp <- checkNeedsRecompilation filename ccOpts
+             when needsRecomp $ runGhcProg ccOpts
+       runGhcProgIfNeeded vanillaCcOpts
+       unless forRepl $
+         whenSharedLib forceSharedLib (runGhcProgIfNeeded sharedCcOpts)
+       unless forRepl $ whenProfLib (runGhcProgIfNeeded profCcOpts)
+
+  -- build any JS sources
+  unless (not has_code || not hasJsSupport || null (jsSources libBi)) $ do
+    info verbosity "Building JS Sources..."
     sequence_
-      [ do let baseCcOpts    = Internal.componentCcGhcOptions verbosity implInfo
+      [ do let vanillaJsOpts = Internal.componentJsGhcOptions verbosity implInfo
                                lbi libBi clbi relLibTargetDir filename
-               vanillaCcOpts = if isGhcDynamic
-                               -- Dynamic GHC requires C sources to be built
-                               -- with -fPIC for REPL to work. See #2207.
-                               then baseCcOpts { ghcOptFPic = toFlag True }
-                               else baseCcOpts
-               profCcOpts    = vanillaCcOpts `mappend` mempty {
+               profJsOpts    = vanillaJsOpts `mappend` mempty {
                                  ghcOptProfilingMode = toFlag True,
                                  ghcOptObjSuffix     = toFlag "p_o"
                                }
-               sharedCcOpts  = vanillaCcOpts `mappend` mempty {
-                                 ghcOptFPic        = toFlag True,
-                                 ghcOptDynLinkMode = toFlag GhcDynamicOnly,
-                                 ghcOptObjSuffix   = toFlag "dyn_o"
-                               }
-               odir          = fromFlag (ghcOptObjDir vanillaCcOpts)
+               odir          = fromFlag (ghcOptObjDir vanillaJsOpts)
            createDirectoryIfMissingVerbose verbosity True odir
-           let runGhcProgIfNeeded ccOpts = do
-                 needsRecomp <- checkNeedsRecompilation filename ccOpts
-                 when needsRecomp $ runGhcProg ccOpts
-           runGhcProgIfNeeded vanillaCcOpts
-           unless forRepl $
-             whenSharedLib forceSharedLib (runGhcProgIfNeeded sharedCcOpts)
-           unless forRepl $ whenProfLib (runGhcProgIfNeeded profCcOpts)
-      | filename <- cSources libBi]
+           let runGhcProgIfNeeded jsOpts = do
+                 needsRecomp <- checkNeedsRecompilation filename jsOpts
+                 when needsRecomp $ runGhcProg jsOpts
+           runGhcProgIfNeeded vanillaJsOpts
+           unless forRepl $ whenProfLib (runGhcProgIfNeeded profJsOpts)
+      | filename <- jsSources libBi]
 
   -- build any ASM sources
   unless (not has_code || null (asmSources libBi)) $ do
@@ -892,11 +931,11 @@
                 ghcOptPackages           = toNubListR $
                                            Internal.mkGhcOptPackages clbi ,
                 ghcOptLinkLibs           = extraLibs libBi,
-                ghcOptLinkLibPath        = toNubListR $ extraLibDirs libBi,
+                ghcOptLinkLibPath        = toNubListR $ cleanedExtraLibDirs,
                 ghcOptLinkFrameworks     = toNubListR $ PD.frameworks libBi,
                 ghcOptLinkFrameworkDirs  =
                   toNubListR $ PD.extraFrameworkDirs libBi,
-                ghcOptRPaths             = rpaths
+                ghcOptRPaths             = rpaths <> toNubListR (extraLibDirs libBi)
               }
           ghcStaticLinkArgs =
               mempty {
@@ -926,7 +965,7 @@
                 ghcOptPackages           = toNubListR $
                                            Internal.mkGhcOptPackages clbi ,
                 ghcOptLinkLibs           = extraLibs libBi,
-                ghcOptLinkLibPath        = toNubListR $ extraLibDirs libBi
+                ghcOptLinkLibPath        = toNubListR $ cleanedExtraLibDirs
               }
 
       info verbosity (show (ghcOptPackages ghcSharedLinkArgs))
@@ -1318,6 +1357,11 @@
   rpaths <- getRPaths lbi clbi
   buildSources <- gbuildSources verbosity (package pkg_descr) (specVersion pkg_descr) tmpDir bm
 
+  -- ensure extra lib dirs exist before passing to ghc
+  cleanedExtraLibDirs <- filterM doesDirectoryExist (extraLibDirs bnfo)
+  cleanedExtraLibDirsStatic <- filterM doesDirectoryExist (extraLibDirsStatic bnfo)
+
+
   let cSrcs               = cSourcesFiles buildSources
       cxxSrcs             = cxxSourceFiles buildSources
       inputFiles          = inputSourceFiles buildSources
@@ -1382,8 +1426,8 @@
                                                   else extraLibs bnfo,
                       ghcOptLinkLibPath       = toNubListR $
                                                   if withFullyStaticExe lbi
-                                                    then extraLibDirsStatic bnfo
-                                                    else extraLibDirs bnfo,
+                                                    then cleanedExtraLibDirsStatic
+                                                    else cleanedExtraLibDirs,
                       ghcOptLinkFrameworks    = toNubListR $
                                                 PD.frameworks bnfo,
                       ghcOptLinkFrameworkDirs = toNubListR $
@@ -1392,7 +1436,7 @@
                                              [tmpDir </> x | x <- cLikeObjs ++ cxxObjs]
                     }
       dynLinkerOpts = mempty {
-                      ghcOptRPaths         = rpaths,
+                      ghcOptRPaths         = rpaths <> toNubListR (extraLibDirs bnfo),
                       ghcOptInputFiles     = toNubListR
                                              [tmpDir </> x | x <- cLikeObjs ++ cxxObjs]
                    }
@@ -1486,32 +1530,32 @@
      | filename <- cxxSrcs ]
 
   -- build any C sources
-  unless (null cSrcs) $ do
-   info verbosity "Building C Sources..."
-   sequence_
-     [ do let baseCcOpts    = Internal.componentCcGhcOptions verbosity implInfo
+  cSrcs' <- checkCSources verbosity (gbuildName bm) cSrcs
+  unless (null cSrcs') $ do
+    info verbosity "Building C Sources..."
+    forM_ cSrcs' $ \filename -> do
+      let baseCcOpts    = Internal.componentCcGhcOptions verbosity implInfo
                               lbi bnfo clbi tmpDir filename
-              vanillaCcOpts = if isGhcDynamic
-                              -- Dynamic GHC requires C sources to be built
-                              -- with -fPIC for REPL to work. See #2207.
-                              then baseCcOpts { ghcOptFPic = toFlag True }
-                              else baseCcOpts
-              profCcOpts    = vanillaCcOpts `mappend` mempty {
-                                ghcOptProfilingMode = toFlag True
-                              }
-              sharedCcOpts  = vanillaCcOpts `mappend` mempty {
-                                ghcOptFPic        = toFlag True,
-                                ghcOptDynLinkMode = toFlag GhcDynamicOnly
-                              }
-              opts | needProfiling = profCcOpts
-                   | needDynamic   = sharedCcOpts
-                   | otherwise     = vanillaCcOpts
-              odir = fromFlag (ghcOptObjDir opts)
-          createDirectoryIfMissingVerbose verbosity True odir
-          needsRecomp <- checkNeedsRecompilation filename opts
-          when needsRecomp $
-            runGhcProg opts
-     | filename <- cSrcs ]
+      let vanillaCcOpts = if isGhcDynamic
+                          -- Dynamic GHC requires C sources to be built
+                          -- with -fPIC for REPL to work. See #2207.
+                          then baseCcOpts { ghcOptFPic = toFlag True }
+                          else baseCcOpts
+      let profCcOpts    = vanillaCcOpts `mappend` mempty {
+                            ghcOptProfilingMode = toFlag True
+                          }
+      let sharedCcOpts  = vanillaCcOpts `mappend` mempty {
+                            ghcOptFPic        = toFlag True,
+                            ghcOptDynLinkMode = toFlag GhcDynamicOnly
+                          }
+      let opts | needProfiling = profCcOpts
+               | needDynamic   = sharedCcOpts
+               | otherwise     = vanillaCcOpts
+      let odir = fromFlag (ghcOptObjDir opts)
+      createDirectoryIfMissingVerbose verbosity True odir
+      needsRecomp <- checkNeedsRecompilation filename opts
+      when needsRecomp $
+        runGhcProg opts
 
   -- TODO: problem here is we need the .c files built first, so we can load them
   -- with ghci, but .c files can depend on .h files generated by ghc by ffi
@@ -1817,18 +1861,12 @@
       libBi = libBuildInfo lib
       comp        = compiler lbi
       platform    = hostPlatform lbi
-      vanillaArgs0 =
+      vanillaArgs =
         (componentGhcOptions verbosity lbi libBi clbi (componentBuildDir lbi clbi))
         `mappend` mempty {
           ghcOptMode         = toFlag GhcModeAbiHash,
           ghcOptInputModules = toNubListR $ exposedModules lib
         }
-      vanillaArgs =
-          -- Package DBs unnecessary, and break ghc-cabal. See #3633
-          -- BUT, put at least the global database so that 7.4 doesn't
-          -- break.
-          vanillaArgs0 { ghcOptPackageDBs = [GlobalPackageDB]
-                       , ghcOptPackages = mempty }
       sharedArgs = vanillaArgs `mappend` mempty {
                        ghcOptDynLinkMode = toFlag GhcDynamicOnly,
                        ghcOptFPic        = toFlag True,
@@ -1852,7 +1890,7 @@
 
   (ghcProg, _) <- requireProgram verbosity ghcProgram (withPrograms lbi)
   hash <- getProgramInvocationOutput verbosity
-          (ghcInvocation ghcProg comp platform ghcArgs)
+          =<< ghcInvocation verbosity ghcProg comp platform ghcArgs
   return (takeWhile (not . isSpace) hash)
 
 componentGhcOptions :: Verbosity -> LocalBuildInfo
@@ -2052,6 +2090,10 @@
                    && null (cxxSources (libBuildInfo lib))
                    && null (cmmSources (libBuildInfo lib))
                    && null (asmSources (libBuildInfo lib))
+                   && (null (jsSources (libBuildInfo lib)) || not hasJsSupport)
+    hasJsSupport = case hostPlatform lbi of
+      Platform JavaScript _ -> True
+      _                     -> False
     has_code = not (componentIsIndefinite clbi)
     whenHasCode = when has_code
     whenVanilla = when (hasLib && withVanillaLib lbi)
@@ -2121,3 +2163,23 @@
 
 withExt :: FilePath -> String -> FilePath
 withExt fp ext = fp <.> if takeExtension fp /= ('.':ext) then ext else ""
+
+checkCSources :: Verbosity -> String -> [String] -> IO [String]
+checkCSources verbosity name cSrcs = do
+  let (headers, cSrcs') = partition (\filepath -> ".h" `isSuffixOf` filepath) cSrcs
+      others = filter (\filepath -> not (".c" `isSuffixOf` filepath)) cSrcs'
+  unless (null headers) $ do
+    let files = intercalate ", " headers
+    warn verbosity $ unlines
+      [ "The following header files listed in " <> name <> "'s c-sources will not be used: " <> files <> "."
+      , "Header files should be in the 'include' or 'install-include' stanza."
+      , "See https://cabal.readthedocs.io/en/3.10/cabal-package.html#pkg-field-includes"
+      ]
+  unless (null others) $ do
+    let files = intercalate ", " others
+    warn verbosity $ unlines
+      [ "The following files listed in " <> name <> "'s c-sources do not have the expected '.c' extension " <> files <> "."
+      , "C++ files should be in the 'cxx-sources' stanza."
+      , "See https://cabal.readthedocs.io/en/3.10/cabal-package.html#pkg-field-cxx-sources"
+      ]
+  return cSrcs'
diff --git a/cabal/Cabal/src/Distribution/Simple/GHC/ImplInfo.hs b/cabal/Cabal/src/Distribution/Simple/GHC/ImplInfo.hs
--- a/cabal/Cabal/src/Distribution/Simple/GHC/ImplInfo.hs
+++ b/cabal/Cabal/src/Distribution/Simple/GHC/ImplInfo.hs
@@ -40,6 +40,7 @@
   , alwaysNondecIndent   :: Bool -- ^ NondecreasingIndentation is always on
   , flagGhciScript       :: Bool -- ^ -ghci-script flag supported
   , flagProfAuto         :: Bool -- ^ new style -fprof-auto* flags
+  , flagProfLate         :: Bool -- ^ fprof-late flag
   , flagPackageConf      :: Bool -- ^ use package-conf instead of package-db
   , flagDebugInfo        :: Bool -- ^ -g flag supported
   , supportsDebugLevels  :: Bool -- ^ supports numeric @-g@ levels
@@ -67,6 +68,7 @@
   , alwaysNondecIndent   = v <  [7,1]
   , flagGhciScript       = v >= [7,2]
   , flagProfAuto         = v >= [7,4]
+  , flagProfLate         = v >= [9,4]
   , flagPackageConf      = v <  [7,5]
   , flagDebugInfo        = v >= [7,10]
   , supportsDebugLevels  = v >= [8,0]
@@ -86,6 +88,7 @@
   , alwaysNondecIndent   = False
   , flagGhciScript       = True
   , flagProfAuto         = True
+  , flagProfLate         = True
   , flagPackageConf      = False
   , flagDebugInfo        = False
   , supportsDebugLevels  = ghcv >= [8,0]
diff --git a/cabal/Cabal/src/Distribution/Simple/GHC/Internal.hs b/cabal/Cabal/src/Distribution/Simple/GHC/Internal.hs
--- a/cabal/Cabal/src/Distribution/Simple/GHC/Internal.hs
+++ b/cabal/Cabal/src/Distribution/Simple/GHC/Internal.hs
@@ -22,6 +22,7 @@
         componentCmmGhcOptions,
         componentCxxGhcOptions,
         componentAsmGhcOptions,
+        componentJsGhcOptions,
         componentGhcOptions,
         mkGHCiLibName,
         mkGHCiProfLibName,
@@ -100,7 +101,9 @@
     }
   . addKnownProgram ldProgram {
       programFindLocation = findProg ldProgramName extraLdPath,
-      programPostConf     = configureLd
+      programPostConf = \v cp ->
+        -- Call any existing configuration first and then add any new configuration
+        configureLd v =<< programPostConf ldProgram v cp
     }
   . addKnownProgram arProgram {
       programFindLocation = findProg arProgramName extraArPath
@@ -382,7 +385,33 @@
       ghcOptObjDir         = toFlag odir
     }
 
+componentJsGhcOptions :: Verbosity -> GhcImplInfo -> LocalBuildInfo
+                      -> BuildInfo -> ComponentLocalBuildInfo
+                      -> FilePath -> FilePath
+                      -> GhcOptions
+componentJsGhcOptions verbosity _implInfo lbi bi clbi odir filename =
+    mempty {
+      -- Respect -v0, but don't crank up verbosity on GHC if
+      -- Cabal verbosity is requested. For that, use --ghc-option=-v instead!
+      ghcOptVerbosity      = toFlag (min verbosity normal),
+      ghcOptMode           = toFlag GhcModeCompile,
+      ghcOptInputFiles     = toNubListR [filename],
 
+      ghcOptCppIncludePath = toNubListR $ [autogenComponentModulesDir lbi clbi
+                                          ,autogenPackageModulesDir lbi
+                                          ,odir]
+                                          -- includes relative to the package
+                                          ++ includeDirs bi
+                                          -- potential includes generated by `configure'
+                                          -- in the build directory
+                                          ++ [buildDir lbi </> dir | dir <- includeDirs bi],
+      ghcOptHideAllPackages= toFlag True,
+      ghcOptPackageDBs     = withPackageDB lbi,
+      ghcOptPackages       = toNubListR $ mkGhcOptPackages clbi,
+      ghcOptObjDir         = toFlag odir
+    }
+
+
 componentGhcOptions :: Verbosity -> GhcImplInfo -> LocalBuildInfo
                     -> BuildInfo -> ComponentLocalBuildInfo -> FilePath
                     -> GhcOptions
@@ -588,6 +617,7 @@
       ProfDetailExportedFunctions   -> toFlag GhcProfAutoExported
       ProfDetailToplevelFunctions   -> toFlag GhcProfAutoToplevel
       ProfDetailAllFunctions        -> toFlag GhcProfAutoAll
+      ProfDetailTopLate             -> toFlag GhcProfLate
       ProfDetailOther _             -> mempty
 
 
diff --git a/cabal/Cabal/src/Distribution/Simple/GHCJS.hs b/cabal/Cabal/src/Distribution/Simple/GHCJS.hs
--- a/cabal/Cabal/src/Distribution/Simple/GHCJS.hs
+++ b/cabal/Cabal/src/Distribution/Simple/GHCJS.hs
@@ -1573,18 +1573,12 @@
       libBi = libBuildInfo lib
       comp        = compiler lbi
       platform    = hostPlatform lbi
-      vanillaArgs0 =
+      vanillaArgs =
         (componentGhcOptions verbosity lbi libBi clbi (componentBuildDir lbi clbi))
         `mappend` mempty {
           ghcOptMode         = toFlag GhcModeAbiHash,
           ghcOptInputModules = toNubListR $ exposedModules lib
         }
-      vanillaArgs =
-          -- Package DBs unnecessary, and break ghc-cabal. See #3633
-          -- BUT, put at least the global database so that 7.4 doesn't
-          -- break.
-          vanillaArgs0 { ghcOptPackageDBs = [GlobalPackageDB]
-                       , ghcOptPackages = mempty }
       sharedArgs = vanillaArgs `mappend` mempty {
                        ghcOptDynLinkMode = toFlag GhcDynamicOnly,
                        ghcOptFPic        = toFlag True,
@@ -1608,7 +1602,7 @@
 
   (ghcjsProg, _) <- requireProgram verbosity ghcjsProgram (withPrograms lbi)
   hash <- getProgramInvocationOutput verbosity
-          (ghcInvocation ghcjsProg comp platform ghcArgs)
+          =<< ghcInvocation verbose ghcjsProg comp platform ghcArgs
   return (takeWhile (not . isSpace) hash)
 
 componentGhcOptions :: Verbosity -> LocalBuildInfo
diff --git a/cabal/Cabal/src/Distribution/Simple/Glob.hs b/cabal/Cabal/src/Distribution/Simple/Glob.hs
--- a/cabal/Cabal/src/Distribution/Simple/Glob.hs
+++ b/cabal/Cabal/src/Distribution/Simple/Glob.hs
@@ -23,6 +23,7 @@
         fileGlobMatches,
         parseFileGlob,
         explainGlobSyntaxError,
+        isRecursiveInRoot,
         Glob,
   ) where
 
@@ -336,3 +337,8 @@
   where
     step (GlobStem seg pat) = Right (seg, pat)
     step (GlobFinal pat) = Left pat
+
+
+isRecursiveInRoot :: Glob -> Bool
+isRecursiveInRoot (GlobFinal (FinalMatch Recursive _ _))  = True
+isRecursiveInRoot _ = False
diff --git a/cabal/Cabal/src/Distribution/Simple/Haddock.hs b/cabal/Cabal/src/Distribution/Simple/Haddock.hs
--- a/cabal/Cabal/src/Distribution/Simple/Haddock.hs
+++ b/cabal/Cabal/src/Distribution/Simple/Haddock.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE DeriveGeneric #-}
 {-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE NamedFieldPuns #-}
 {-# LANGUAGE RankNTypes #-}
 
 -----------------------------------------------------------------------------
@@ -19,9 +20,10 @@
 -- source, with coloured syntax highlighting.
 
 module Distribution.Simple.Haddock (
-  haddock, hscolour,
+  haddock, createHaddockIndex, hscolour,
 
-  haddockPackagePaths
+  haddockPackagePaths,
+  Visibility(..)
   ) where
 
 import Prelude ()
@@ -104,25 +106,37 @@
  -- ^ Optional custom CSS file.
  argContents :: Flag String,
  -- ^ Optional URL to contents page.
+ argGenContents :: Flag Bool,
+ -- ^ Generate contents
+ argIndex :: Flag String,
+ -- ^ Optional URL to index page.
+ argGenIndex :: Flag Bool,
+ -- ^ Generate index
+ argBaseUrl :: Flag String,
+ -- ^ Optional base url from which static files will be loaded.
  argVerbose :: Any,
  argOutput :: Flag [Output],
  -- ^ HTML or Hoogle doc or both? Required.
- argInterfaces :: [(FilePath, Maybe String, Maybe String)],
+ argInterfaces :: [(FilePath, Maybe String, Maybe String, Visibility)],
  -- ^ [(Interface file, URL to the HTML docs and hyperlinked-source for links)].
  argOutputDir :: Directory,
  -- ^ Where to generate the documentation.
  argTitle :: Flag String,
  -- ^ Page title, required.
  argPrologue :: Flag String,
- -- ^ Prologue text, required.
+ -- ^ Prologue text, required for 'haddock', ignored by 'haddocks'.
+ argPrologueFile :: Flag FilePath,
+ -- ^ Prologue file name, ignored by 'haddock', optional for 'haddocks'.
  argGhcOptions :: GhcOptions,
  -- ^ Additional flags to pass to GHC.
  argGhcLibDir :: Flag FilePath,
  -- ^ To find the correct GHC, required.
  argReexports :: [OpenModule],
  -- ^ Re-exported modules
- argTargets :: [FilePath]
+ argTargets :: [FilePath],
  -- ^ Modules to process.
+ argLib :: Flag String
+ -- ^ haddock's static \/ auxiliary files.
 } deriving Generic
 
 -- | The FilePath of a directory, it's a monoid under '(</>)'.
@@ -134,10 +148,55 @@
 type Template = String
 
 data Output = Html | Hoogle
+  deriving Eq
 
 -- ------------------------------------------------------------------------------
 -- Haddock support
 
+-- | Get Haddock program and check if it matches the request
+getHaddockProg :: Verbosity
+               -> ProgramDb
+               -> Compiler
+               -> HaddockArgs
+               -> Flag Bool -- ^ quickjump feature
+               -> IO (ConfiguredProgram, Version)
+getHaddockProg verbosity programDb comp args quickJumpFlag = do
+    let HaddockArgs { argQuickJump
+                    , argOutput
+                    } = args
+        hoogle = Hoogle `elem` fromFlagOrDefault [] argOutput
+
+    (haddockProg, version, _) <-
+      requireProgramVersion verbosity haddockProgram
+        (orLaterVersion (mkVersion [2,0])) programDb
+
+    -- various sanity checks
+    when (hoogle && version < mkVersion [2,2]) $
+      die' verbosity "Haddock 2.0 and 2.1 do not support the --hoogle flag."
+
+    when (fromFlag argQuickJump && version < mkVersion [2,19]) $ do
+      let msg = "Haddock prior to 2.19 does not support the --quickjump flag."
+          alt = "The generated documentation won't have the QuickJump feature."
+      if Flag True == quickJumpFlag
+        then die' verbosity msg
+        else warn verbosity (msg ++ "\n" ++ alt)
+
+    haddockGhcVersionStr <- getProgramOutput verbosity haddockProg
+                              ["--ghc-version"]
+    case (simpleParsec haddockGhcVersionStr, compilerCompatVersion GHC comp) of
+      (Nothing, _) -> die' verbosity "Could not get GHC version from Haddock"
+      (_, Nothing) -> die' verbosity "Could not get GHC version from compiler"
+      (Just haddockGhcVersion, Just ghcVersion)
+        | haddockGhcVersion == ghcVersion -> return ()
+        | otherwise -> die' verbosity $
+               "Haddock's internal GHC version must match the configured "
+            ++ "GHC version.\n"
+            ++ "The GHC version is " ++ prettyShow ghcVersion ++ " but "
+            ++ "haddock is using GHC version " ++ prettyShow haddockGhcVersion
+
+    return (haddockProg, version)
+
+
 haddock :: PackageDescription
         -> LocalBuildInfo
         -> [PPSuffixHandler]
@@ -181,36 +240,14 @@
         haddockTarget =
           fromFlagOrDefault ForDevelopment (haddockForHackage flags')
 
-    (haddockProg, version, _) <-
-      requireProgramVersion verbosity haddockProgram
-        (orLaterVersion (mkVersion [2,0])) (withPrograms lbi)
-
-    -- various sanity checks
-    when (flag haddockHoogle && version < mkVersion [2,2]) $
-      die' verbosity "Haddock 2.0 and 2.1 do not support the --hoogle flag."
-
-
-    when (flag haddockQuickJump && version < mkVersion [2,19]) $ do
-      let msg = "Haddock prior to 2.19 does not support the --quickjump flag."
-          alt = "The generated documentation won't have the QuickJump feature."
-      if Flag True == quickJmpFlag
-        then die' verbosity msg
-        else warn verbosity (msg ++ "\n" ++ alt)
-
-    haddockGhcVersionStr <- getProgramOutput verbosity haddockProg
-                              ["--ghc-version"]
-    case (simpleParsec haddockGhcVersionStr, compilerCompatVersion GHC comp) of
-      (Nothing, _) -> die' verbosity "Could not get GHC version from Haddock"
-      (_, Nothing) -> die' verbosity "Could not get GHC version from compiler"
-      (Just haddockGhcVersion, Just ghcVersion)
-        | haddockGhcVersion == ghcVersion -> return ()
-        | otherwise -> die' verbosity $
-               "Haddock's internal GHC version must match the configured "
-            ++ "GHC version.\n"
-            ++ "The GHC version is " ++ prettyShow ghcVersion ++ " but "
-            ++ "haddock is using GHC version " ++ prettyShow haddockGhcVersion
+    libdirArgs <- getGhcLibDir  verbosity lbi
+    let commonArgs = mconcat
+            [ libdirArgs
+            , fromFlags (haddockTemplateEnv lbi (packageId pkg_descr)) flags
+            , fromPackageDescription haddockTarget pkg_descr ]
 
-    -- the tools match the requests, we can proceed
+    (haddockProg, version) <-
+      getHaddockProg verbosity (withPrograms lbi) comp commonArgs quickJmpFlag
 
     -- We fall back to using HsColour only for versions of Haddock which don't
     -- support '--hyperlinked-sources'.
@@ -218,12 +255,6 @@
       hscolour' (warn verbosity) haddockTarget pkg_descr lbi suffixes
       (defaultHscolourFlags `mappend` haddockToHscolour flags)
 
-    libdirArgs <- getGhcLibDir  verbosity lbi
-    let commonArgs = mconcat
-            [ libdirArgs
-            , fromFlags (haddockTemplateEnv lbi (packageId pkg_descr)) flags
-            , fromPackageDescription haddockTarget pkg_descr ]
-
     targets <- readTargetInfos verbosity pkg_descr lbi (haddockArgs flags)
 
     let
@@ -258,7 +289,7 @@
                              version exe
                 let exeArgs' = commonArgs `mappend` exeArgs
                 runHaddock verbosity tmpFileOpts comp platform
-                  haddockProg exeArgs'
+                  haddockProg True exeArgs'
           Nothing -> do
            warn (fromFlag $ haddockVerbosity flags)
              "Unsupported component, skipping..."
@@ -277,7 +308,7 @@
               libArgs <- fromLibrary verbosity tmp lbi' clbi htmlTemplate
                            version lib
               let libArgs' = commonArgs `mappend` libArgs
-              runHaddock verbosity tmpFileOpts comp platform haddockProg libArgs'
+              runHaddock verbosity tmpFileOpts comp platform haddockProg True libArgs'
 
               pwd <- getCurrentDirectory
 
@@ -304,7 +335,7 @@
               flibArgs <- fromForeignLib verbosity tmp lbi' clbi htmlTemplate
                             version flib
               let libArgs' = commonArgs `mappend` flibArgs
-              runHaddock verbosity tmpFileOpts comp platform haddockProg libArgs')
+              runHaddock verbosity tmpFileOpts comp platform haddockProg True libArgs')
 
           >> return index
 
@@ -316,6 +347,22 @@
       files <- matchDirFileGlob verbosity (specVersion pkg_descr) "." fpath
       for_ files $ copyFileTo verbosity (unDir $ argOutputDir commonArgs)
 
+
+-- | Execute 'Haddock' configured with 'HaddocksFlags'.  It is used to build
+-- index and contents for documentation of multiple packages.
+--
+createHaddockIndex :: Verbosity
+                   -> ProgramDb
+                   -> Compiler
+                   -> Platform
+                   -> HaddockProjectFlags
+                   -> IO ()
+createHaddockIndex verbosity programDb comp platform flags = do
+    let args = fromHaddockProjectFlags flags
+    (haddockProg, _version) <-
+      getHaddockProg verbosity programDb comp args (Flag True)
+    runHaddock verbosity defaultTempFileOptions comp platform haddockProg False args
+
 -- ------------------------------------------------------------------------------
 -- Contributions to HaddockArgs (see also Doctest.hs for very similar code).
 
@@ -334,6 +381,12 @@
       argCssFile = haddockCss flags,
       argContents = fmap (fromPathTemplate . substPathTemplate env)
                     (haddockContents flags),
+      argGenContents = Flag False,
+      argIndex = fmap (fromPathTemplate . substPathTemplate env)
+                    (haddockIndex flags),
+      argGenIndex = Flag False,
+      argBaseUrl = haddockBaseUrl flags,
+      argLib = haddockLib flags,
       argVerbose = maybe mempty (Any . (>= deafening))
                    . flagToMaybe $ haddockVerbosity flags,
       argOutput =
@@ -348,6 +401,20 @@
     where
       ghcArgs = fromMaybe [] . lookup "ghc" . haddockProgramArgs $ flags
 
+fromHaddockProjectFlags :: HaddockProjectFlags -> HaddockArgs
+fromHaddockProjectFlags flags =
+    mempty
+      { argOutputDir = Dir (fromFlag $ haddockProjectDir flags)
+      , argQuickJump = Flag True
+      , argGenContents = Flag True
+      , argGenIndex = Flag True
+      , argPrologueFile = haddockProjectPrologue flags
+      , argInterfaces = fromFlagOrDefault [] (haddockProjectInterfaces flags)
+      , argLinkedSource = Flag True
+      , argLib = haddockProjectLib flags
+      }
+
+
 fromPackageDescription :: HaddockTarget -> PackageDescription -> HaddockArgs
 fromPackageDescription haddockTarget pkg_descr = mempty
     { argInterfaceFile = Flag $ haddockName pkg_descr
@@ -543,10 +610,11 @@
               -> Compiler
               -> Platform
               -> ConfiguredProgram
+              -> Bool -- ^ require targets
               -> HaddockArgs
               -> IO ()
-runHaddock verbosity tmpFileOpts comp platform haddockProg args
-  | null (argTargets args) = warn verbosity $
+runHaddock verbosity tmpFileOpts comp platform haddockProg requireTargets args
+  | requireTargets && null (argTargets args) = warn verbosity $
        "Haddocks are being requested, but there aren't any modules given "
     ++ "to create documentation for."
   | otherwise = do
@@ -572,34 +640,60 @@
   let haddockSupportsUTF8          = version >= mkVersion [2,14,4]
       haddockSupportsResponseFiles = version >  mkVersion [2,16,2]
   createDirectoryIfMissingVerbose verbosity True outputDir
-  withTempFileEx tmpFileOpts outputDir "haddock-prologue.txt" $
-    \prologueFileName h -> do
-          do
-             when haddockSupportsUTF8 (hSetEncoding h utf8)
-             hPutStrLn h $ fromFlag $ argPrologue args
-             hClose h
-             let pflag = "--prologue=" ++ prologueFileName
-                 renderedArgs = pflag : renderPureArgs version comp platform args
-             if haddockSupportsResponseFiles
-               then
-                 withResponseFile
-                   verbosity
-                   tmpFileOpts
-                   outputDir
-                   "haddock-response.txt"
-                   (if haddockSupportsUTF8 then Just utf8 else Nothing)
-                   renderedArgs
-                   (\responseFileName -> k (["@" ++ responseFileName], result))
-               else
-                 k (renderedArgs, result)
+  case argPrologue args of
+    Flag prologueText ->
+      withTempFileEx tmpFileOpts outputDir "haddock-prologue.txt" $
+        \prologueFileName h -> do
+              do
+                 when haddockSupportsUTF8 (hSetEncoding h utf8)
+                 hPutStrLn h prologueText
+                 hClose h
+                 let pflag = "--prologue=" ++ prologueFileName
+                     renderedArgs = pflag : renderPureArgs version comp platform args
+                 if haddockSupportsResponseFiles
+                   then
+                     withResponseFile
+                       verbosity
+                       tmpFileOpts
+                       outputDir
+                       "haddock-response.txt"
+                       (if haddockSupportsUTF8 then Just utf8 else Nothing)
+                       renderedArgs
+                       (\responseFileName -> k (["@" ++ responseFileName], result))
+                   else
+                     k (renderedArgs, result)
+    _ -> do
+      let renderedArgs = (case argPrologueFile args of
+                            Flag pfile -> ["--prologue="++pfile]
+                            _          -> [])
+                      <> renderPureArgs version comp platform args
+      if haddockSupportsResponseFiles
+        then
+          withResponseFile
+            verbosity
+            tmpFileOpts
+            outputDir
+            "haddock-response.txt"
+            (if haddockSupportsUTF8 then Just utf8 else Nothing)
+            renderedArgs
+            (\responseFileName -> k (["@" ++ responseFileName], result))
+        else
+          k (renderedArgs, result)
     where
       outputDir = (unDir $ argOutputDir args)
       result = intercalate ", "
              . map (\o -> outputDir </>
                             case o of
-                              Html -> "index.html"
+                              Html
+                                | fromFlagOrDefault False (argGenIndex args) ->
+                                    "index.html"
+                              Html
+                                | otherwise ->
+                                    mempty
                               Hoogle -> pkgstr <.> "txt")
-             $ arg argOutput
+             . fromFlagOrDefault [Html]
+             . argOutput
+             $ args
             where
               pkgstr = prettyShow $ packageName pkgid
               pkgid = arg argPackageName
@@ -607,23 +701,23 @@
 
 renderPureArgs :: Version -> Compiler -> Platform -> HaddockArgs -> [String]
 renderPureArgs version comp platform args = concat
-    [ (:[]) . (\f -> "--dump-interface="++ unDir (argOutputDir args) </> f)
-      . fromFlag . argInterfaceFile $ args
+    [ map (\f -> "--dump-interface="++ unDir (argOutputDir args) </> f)
+      . flagToList . argInterfaceFile $ args
 
-    , if isVersion 2 16
-        then (\pkg -> [ "--package-name=" ++ prettyShow (pkgName pkg)
-                      , "--package-version=" ++ prettyShow (pkgVersion pkg)
-                      ])
-             . fromFlag . argPackageName $ args
+    , if haddockSupportsPackageName
+        then maybe [] (\pkg -> [ "--package-name=" ++ prettyShow (pkgName pkg)
+                               , "--package-version=" ++ prettyShow (pkgVersion pkg)
+                               ])
+             . flagToMaybe . argPackageName $ args
         else []
 
     , [ "--since-qual=external" | isVersion 2 20 ]
 
     , [ "--quickjump" | isVersion 2 19
-                      , fromFlag . argQuickJump $ args ]
+                      , True <- flagToList . argQuickJump $ args ]
 
     , [ "--hyperlinked-source" | isVersion 2 17
-                               , fromFlag . argLinkedSource $ args ]
+                               , True <- flagToList . argLinkedSource $ args ]
 
     , (\(All b,xs) -> bool (map (("--hide=" ++) . prettyShow) xs) [] b)
                      . argHideModules $ args
@@ -641,19 +735,30 @@
 
     , maybe [] ((:[]) . ("--use-contents="++)) . flagToMaybe . argContents $ args
 
+    , bool ["--gen-contents"] [] .fromFlagOrDefault False . argGenContents $ args
+
+    , maybe [] ((:[]) . ("--use-index="++)) . flagToMaybe . argIndex $ args
+
+    , bool ["--gen-index"] [] . fromFlagOrDefault False . argGenIndex $ args
+
+    , maybe [] ((:[]) . ("--base-url="++)) . flagToMaybe . argBaseUrl $ args
+
     , bool [] [verbosityFlag] . getAny . argVerbose $ args
 
     , map (\o -> case o of Hoogle -> "--hoogle"; Html -> "--html")
-      . fromFlag . argOutput $ args
+      . fromFlagOrDefault [] . argOutput $ args
 
     , renderInterfaces . argInterfaces $ args
 
     , (:[]) . ("--odir="++) . unDir . argOutputDir $ args
 
-    , (:[]) . ("--title="++)
-      . (bool (++" (internal documentation)")
-         id (getAny $ argIgnoreExports args))
-      . fromFlag . argTitle $ args
+    , maybe []
+        ( (:[])
+        . ("--title="++)
+        . (bool (++" (internal documentation)")
+                id (getAny $ argIgnoreExports args))
+        )
+        . flagToMaybe . argTitle $ args
 
     , [ "--optghc=" ++ opt | let opts = argGhcOptions args
                            , opt <- renderGhcOptions comp platform opts ]
@@ -668,21 +773,32 @@
       ]
 
     , argTargets $ args
+    , maybe [] ((:[]) . ("--lib="++)) . flagToMaybe . argLib $ args
     ]
     where
       renderInterfaces = map renderInterface
 
-      renderInterface :: (FilePath, Maybe FilePath, Maybe FilePath) -> String
-      renderInterface (i, html, hypsrc) = "--read-interface=" ++
-        (intercalate "," $ concat [ [ x | Just x <- [html] ]
-                                  , [ x | Just _ <- [html]
-                                        -- only render hypsrc path if html path
-                                        -- is given and hyperlinked-source is
-                                        -- enabled
-                                        , Just x <- [hypsrc]
-                                        , isVersion 2 17
-                                        , fromFlag . argLinkedSource $ args
-                                        ]
+      renderInterface :: (FilePath, Maybe FilePath, Maybe FilePath, Visibility) -> String
+      renderInterface (i, html, hypsrc, visibility) = "--read-interface=" ++
+        (intercalate "," $ concat [ [ fromMaybe "" html ]
+                                  , -- only render hypsrc path if html path
+                                    -- is given and hyperlinked-source is
+                                    -- enabled
+                                    [ case (html, hypsrc) of
+                                        (Nothing, _) -> ""
+                                        (_, Nothing) -> ""
+                                        (_, Just x)  | isVersion 2 17
+                                                     , fromFlagOrDefault False . argLinkedSource $ args
+                                                     -> x
+                                                     | otherwise
+                                                     -> ""
+                                    ]
+                                  , if haddockSupportsVisibility
+                                      then [ case visibility of
+                                               Visible -> "visible"
+                                               Hidden  -> "hidden"
+                                           ]
+                                      else []
                                   , [ i ]
                                   ])
 
@@ -691,6 +807,8 @@
       verbosityFlag
        | isVersion 2 5 = "--verbosity=1"
        | otherwise     = "--verbose"
+      haddockSupportsVisibility = version >= mkVersion [2,26,1]
+      haddockSupportsPackageName = version > mkVersion [2,16]
 
 ---------------------------------------------------------------------------------
 
@@ -706,6 +824,7 @@
 
                                        , Maybe FilePath  -- url to hyperlinked
                                                          -- source
+                                       , Visibility
                                        )]
                                      , Maybe String      -- warning about
                                                          -- missing documentation
@@ -730,7 +849,7 @@
 
           exists <- doesFileExist interface
           if exists
-            then return (Right (interface, html', hypsrc'))
+            then return (Right (interface, html', hypsrc', Visible))
             else return (Left pkgid)
     | ipkg <- ipkgs, let pkgid = packageId ipkg
     , pkgName pkgid `notElem` noHaddockWhitelist
@@ -782,6 +901,7 @@
 
                             , Maybe FilePath  -- url to hyperlinked
                                               -- source
+                            , Visibility
                             )]
                           , Maybe String      -- warning about
                                               -- missing documentation
diff --git a/cabal/Cabal/src/Distribution/Simple/PreProcess.hs b/cabal/Cabal/src/Distribution/Simple/PreProcess.hs
--- a/cabal/Cabal/src/Distribution/Simple/PreProcess.hs
+++ b/cabal/Cabal/src/Distribution/Simple/PreProcess.hs
@@ -114,6 +114,8 @@
   -- | This function can reorder /all/ modules, not just those that the
   -- require the preprocessor in question. As such, this function should be
   -- well-behaved and not reorder modules it doesn't have dominion over!
+  --
+  -- @since 3.8.1.0
   ppOrdering :: Verbosity
              -> [FilePath] -- Source directories
              -> [ModuleName] -- Module names
diff --git a/cabal/Cabal/src/Distribution/Simple/Program/Builtin.hs b/cabal/Cabal/src/Distribution/Simple/Program/Builtin.hs
--- a/cabal/Cabal/src/Distribution/Simple/Program/Builtin.hs
+++ b/cabal/Cabal/src/Distribution/Simple/Program/Builtin.hs
@@ -256,8 +256,7 @@
 
 stripProgram :: Program
 stripProgram = (simpleProgram "strip") {
-    programFindVersion = \verbosity ->
-      findProgramVersion "--version" stripExtractVersion (lessVerbose verbosity)
+    programFindVersion = findProgramVersion "--version" stripExtractVersion . lessVerbose
   }
 
 hsc2hsProgram :: Program
@@ -322,8 +321,45 @@
 greencardProgram = simpleProgram "greencard"
 
 ldProgram :: Program
-ldProgram = simpleProgram "ld"
+ldProgram = (simpleProgram "ld")
+    { programPostConf = \verbosity ldProg -> do
+        -- The `lld` linker cannot create merge (relocatable) objects so we
+        -- want to detect this.
+        -- If the linker does support relocatable objects, we want to use that
+        -- to create partially pre-linked objects for GHCi, so we get much
+        -- faster loading as we do not have to do the separate loading and
+        -- in-memory linking the static linker in GHC does, but can offload
+        -- parts of this process to a pre-linking step.
+        -- However this requires the linker to support this features. Not all
+        -- linkers do, and notably as of this writing `lld` which is a popular
+        -- choice for windows linking does not support this feature. However
+        -- if using binutils ld or another linker that supports --relocatable,
+        -- we should still be good to generate pre-linked objects.
+        ldHelpOutput <-
+          getProgramInvocationOutput
+            verbosity
+            (programInvocation ldProg ["--help"])
+            -- In case the linker does not support '--help'. Eg the LLVM linker,
+            -- `lld` only accepts `-help`.
+            `catchIO` (\_ -> return "")
+        let k = "Supports relocatable output"
+            -- Standard GNU `ld` uses `--relocatable` while `ld.gold` uses
+            -- `-relocatable` (single `-`).
+            v
+              | "-relocatable" `isInfixOf` ldHelpOutput = "YES"
+              -- ld64 on macOS has this lovely response for "--help"
+              --
+              --   ld64: For information on command line options please use 'man ld'.
+              --
+              -- it does however support -r, if you read the manpage
+              -- (e.g. https://www.manpagez.com/man/1/ld64/)
+              | "ld64:" `isPrefixOf` ldHelpOutput = "YES"
+              | otherwise = "NO"
 
+            m = Map.insert k v (programProperties ldProg)
+        return $ ldProg{programProperties = m}
+    }
+
 tarProgram :: Program
 tarProgram = (simpleProgram "tar") {
   -- See #1901. Some versions of 'tar' (OpenBSD, NetBSD, ...) don't support the
@@ -334,7 +370,7 @@
                       -- Some versions of tar don't support '--help'.
                       `catchIO` (\_ -> return "")
      let k = "Supports --format"
-         v = if ("--format" `isInfixOf` tarHelpOutput) then "YES" else "NO"
+         v = if "--format" `isInfixOf` tarHelpOutput then "YES" else "NO"
          m = Map.insert k v (programProperties tarProg)
      return $ tarProg { programProperties = m }
   }
@@ -343,6 +379,14 @@
 cppProgram = simpleProgram "cpp"
 
 pkgConfigProgram :: Program
-pkgConfigProgram = (simpleProgram "pkg-config") {
-    programFindVersion = findProgramVersion "--version" id
-  }
+pkgConfigProgram =
+  (simpleProgram "pkg-config")
+    { programFindVersion = findProgramVersion "--version" id
+    , programPostConf = \_ pkgConfProg ->
+        let programOverrideEnv' =
+              programOverrideEnv pkgConfProg
+                ++ [ ("PKG_CONFIG_ALLOW_SYSTEM_CFLAGS", Just "1")
+                   , ("PKG_CONFIG_ALLOW_SYSTEM_LIBS", Just "1")
+                   ]
+         in pure $ pkgConfProg{programOverrideEnv = programOverrideEnv'}
+    }
diff --git a/cabal/Cabal/src/Distribution/Simple/Program/Db.hs b/cabal/Cabal/src/Distribution/Simple/Program/Db.hs
--- a/cabal/Cabal/src/Distribution/Simple/Program/Db.hs
+++ b/cabal/Cabal/src/Distribution/Simple/Program/Db.hs
@@ -34,6 +34,7 @@
     -- ** Query and manipulate the program db
     addKnownProgram,
     addKnownPrograms,
+    appendProgramSearchPath,
     lookupKnownProgram,
     knownPrograms,
     getProgramSearchPath,
@@ -46,6 +47,7 @@
     userSpecifyArgss,
     userSpecifiedArgs,
     lookupProgram,
+    lookupProgramByName,
     updateProgram,
     configuredPrograms,
 
@@ -222,6 +224,21 @@
 modifyProgramSearchPath f db =
   setProgramSearchPath (f $ getProgramSearchPath db) db
 
+-- | Modify the current 'ProgramSearchPath' used by the 'ProgramDb'
+-- by appending the provided extra paths. Also logs the added paths
+-- in info verbosity.
+appendProgramSearchPath
+  :: Verbosity
+  -> [FilePath]
+  -> ProgramDb
+  -> IO ProgramDb
+appendProgramSearchPath verbosity extraPaths db =
+  if not $ null extraPaths
+    then do
+      logExtraProgramSearchPath verbosity extraPaths
+      pure $ modifyProgramSearchPath (map ProgramSearchPathDir extraPaths ++) db
+    else pure db
+
 -- |User-specify this path.  Basically override any path information
 -- for this program in the configuration. If it's not a known
 -- program ignore it.
@@ -293,8 +310,11 @@
 
 -- | Try to find a configured program
 lookupProgram :: Program -> ProgramDb -> Maybe ConfiguredProgram
-lookupProgram prog = Map.lookup (programName prog) . configuredProgs
+lookupProgram = lookupProgramByName . programName
 
+-- | Try to find a configured program
+lookupProgramByName :: String -> ProgramDb -> Maybe ConfiguredProgram
+lookupProgramByName name = Map.lookup name . configuredProgs
 
 -- | Update a configured program in the database.
 updateProgram :: ConfiguredProgram -> ProgramDb
diff --git a/cabal/Cabal/src/Distribution/Simple/Program/Find.hs b/cabal/Cabal/src/Distribution/Simple/Program/Find.hs
--- a/cabal/Cabal/src/Distribution/Simple/Program/Find.hs
+++ b/cabal/Cabal/src/Distribution/Simple/Program/Find.hs
@@ -32,13 +32,17 @@
     defaultProgramSearchPath,
     findProgramOnSearchPath,
     programSearchPathAsPATHVar,
+    logExtraProgramSearchPath,
     getSystemSearchPath,
+    getExtraPathEnv,
+    simpleProgram
   ) where
 
 import Prelude ()
 import Distribution.Compat.Prelude
 
 import Distribution.Verbosity
+import Distribution.Simple.Program.Types
 import Distribution.Simple.Utils
 import Distribution.System
 import Distribution.Compat.Environment
@@ -52,30 +56,18 @@
 import qualified System.Win32 as Win32
 #endif
 
--- | A search path to use when locating executables. This is analogous
--- to the unix @$PATH@ or win32 @%PATH%@ but with the ability to use
--- the system default method for finding executables ('findExecutable' which
--- on unix is simply looking on the @$PATH@ but on win32 is a bit more
--- complicated).
---
--- The default to use is @[ProgSearchPathDefault]@ but you can add extra dirs
--- either before, after or instead of the default, e.g. here we add an extra
--- dir to search after the usual ones.
---
--- > ['ProgramSearchPathDefault', 'ProgramSearchPathDir' dir]
---
-type ProgramSearchPath = [ProgramSearchPathEntry]
-data ProgramSearchPathEntry =
-         ProgramSearchPathDir FilePath  -- ^ A specific dir
-       | ProgramSearchPathDefault       -- ^ The system default
-  deriving (Eq, Generic, Typeable)
-
-instance Binary ProgramSearchPathEntry
-instance Structured ProgramSearchPathEntry
-
 defaultProgramSearchPath :: ProgramSearchPath
 defaultProgramSearchPath = [ProgramSearchPathDefault]
 
+logExtraProgramSearchPath
+  :: Verbosity
+  -> [FilePath]
+  -> IO ()
+logExtraProgramSearchPath verbosity extraPaths =
+  info verbosity . unlines $
+    "Including the following directories in PATH:"
+      : map ("- " ++) extraPaths
+
 findProgramOnSearchPath :: Verbosity -> ProgramSearchPath
                         -> FilePath -> IO (Maybe (FilePath, [FilePath]))
 findProgramOnSearchPath verbosity searchpath prog = do
@@ -141,6 +133,25 @@
         Just _  -> return a
         Nothing -> firstJustM mas
 
+-- | Adds some paths to the "PATH" entry in the key-value environment provided
+-- or if there is none, looks up @$PATH@ in the real environment.
+getExtraPathEnv
+  :: Verbosity
+  -> [(String, Maybe String)]
+  -> [FilePath]
+  -> IO [(String, Maybe String)]
+getExtraPathEnv _ _ [] = return []
+getExtraPathEnv verbosity env extras = do
+  mb_path <- case lookup "PATH" env of
+    Just x -> return x
+    Nothing -> lookupEnv "PATH"
+  logExtraProgramSearchPath verbosity extras
+  let extra = intercalate [searchPathSeparator] extras
+      path' = case mb_path of
+        Nothing -> extra
+        Just path -> extra ++ searchPathSeparator : path
+  return [("PATH", Just path')]
+
 -- | Interpret a 'ProgramSearchPath' to construct a new @$PATH@ env var.
 -- Note that this is close but not perfect because on Windows the search
 -- algorithm looks at more than just the @%PATH%@.
@@ -196,3 +207,19 @@
         _     -> return mExe
 #endif
 
+
+-- | Make a simple named program.
+--
+-- By default we'll just search for it in the path and not try to find the
+-- version name. You can override these behaviours if necessary, eg:
+--
+-- > (simpleProgram "foo") { programFindLocation = ... , programFindVersion ... }
+--
+simpleProgram :: String -> Program
+simpleProgram name = Program {
+    programName         = name,
+    programFindLocation = \v p -> findProgramOnSearchPath v p name,
+    programFindVersion  = \_ _ -> return Nothing,
+    programPostConf     = \_ p -> return p,
+    programNormaliseArgs   = \_ _ -> id
+  }
diff --git a/cabal/Cabal/src/Distribution/Simple/Program/GHC.hs b/cabal/Cabal/src/Distribution/Simple/Program/GHC.hs
--- a/cabal/Cabal/src/Distribution/Simple/Program/GHC.hs
+++ b/cabal/Cabal/src/Distribution/Simple/Program/GHC.hs
@@ -31,8 +31,9 @@
 import Distribution.ModuleName
 import Distribution.Simple.Compiler
 import Distribution.Simple.Flag
-import Distribution.Simple.Program.Types
+import Distribution.Simple.Program.Find (getExtraPathEnv)
 import Distribution.Simple.Program.Run
+import Distribution.Simple.Program.Types
 import Distribution.System
 import Distribution.Pretty
 import Distribution.Types.ComponentId
@@ -563,20 +564,25 @@
 data GhcProfAuto = GhcProfAutoAll       -- ^ @-fprof-auto@
                  | GhcProfAutoToplevel  -- ^ @-fprof-auto-top@
                  | GhcProfAutoExported  -- ^ @-fprof-auto-exported@
+                 | GhcProfLate          -- ^ @-fprof-late
  deriving (Show, Eq)
 
 runGHC :: Verbosity -> ConfiguredProgram -> Compiler -> Platform  -> GhcOptions
        -> IO ()
 runGHC verbosity ghcProg comp platform opts = do
-  runProgramInvocation verbosity (ghcInvocation ghcProg comp platform opts)
+  runProgramInvocation verbosity =<< ghcInvocation verbosity ghcProg comp platform opts
 
+ghcInvocation :: Verbosity -> ConfiguredProgram -> Compiler -> Platform -> GhcOptions
+              -> IO ProgramInvocation
+ghcInvocation verbosity ghcProg comp platform opts = do
+  -- NOTE: GHC is the only program whose path we modify with more values than
+  -- the standard @extra-prog-path@, namely the folders of the executables in
+  -- the components, see @componentGhcOptions@.
+  let envOverrides = programOverrideEnv ghcProg
+  extraPath <- getExtraPathEnv verbosity envOverrides (fromNubListR (ghcOptExtraPath opts))
+  let ghcProg' = ghcProg{programOverrideEnv = envOverrides ++ extraPath}
 
-ghcInvocation :: ConfiguredProgram -> Compiler -> Platform -> GhcOptions
-              -> ProgramInvocation
-ghcInvocation prog comp platform opts =
-    (programInvocation prog (renderGhcOptions comp platform opts)) {
-        progInvokePathEnv = fromNubListR (ghcOptExtraPath opts)
-    }
+  pure $ programInvocation ghcProg' (renderGhcOptions comp platform opts)
 
 renderGhcOptions :: Compiler -> Platform -> GhcOptions -> [String]
 renderGhcOptions comp _platform@(Platform _arch os) opts
@@ -633,6 +639,9 @@
       Just GhcProfAutoAll
         | flagProfAuto implInfo -> ["-fprof-auto"]
         | otherwise             -> ["-auto-all"] -- not the same, but close
+      Just GhcProfLate
+        | flagProfLate implInfo -> ["-fprof-late"]
+        | otherwise             -> ["-fprof-auto-top"] -- not the same, not very close, but what we have.
       Just GhcProfAutoToplevel
         | flagProfAuto implInfo -> ["-fprof-auto-top"]
         | otherwise             -> ["-auto-all"]
diff --git a/cabal/Cabal/src/Distribution/Simple/Program/ResponseFile.hs b/cabal/Cabal/src/Distribution/Simple/Program/ResponseFile.hs
--- a/cabal/Cabal/src/Distribution/Simple/Program/ResponseFile.hs
+++ b/cabal/Cabal/src/Distribution/Simple/Program/ResponseFile.hs
@@ -57,4 +57,3 @@
         _ | isSpace c -> c:'\\':cs
           | otherwise -> c:cs
 
-
diff --git a/cabal/Cabal/src/Distribution/Simple/Program/Run.hs b/cabal/Cabal/src/Distribution/Simple/Program/Run.hs
--- a/cabal/Cabal/src/Distribution/Simple/Program/Run.hs
+++ b/cabal/Cabal/src/Distribution/Simple/Program/Run.hs
@@ -13,20 +13,19 @@
 -- This module provides a data type for program invocations and functions to
 -- run them.
 
-module Distribution.Simple.Program.Run (
-    ProgramInvocation(..),
-    IOEncoding(..),
-    emptyProgramInvocation,
-    simpleProgramInvocation,
-    programInvocation,
-    multiStageProgramInvocation,
-
-    runProgramInvocation,
-    getProgramInvocationOutput,
-    getProgramInvocationLBS,
-    getProgramInvocationOutputAndErrors,
-
-    getEffectiveEnvironment,
+module Distribution.Simple.Program.Run
+  ( ProgramInvocation (..)
+  , IOEncoding (..)
+  , emptyProgramInvocation
+  , simpleProgramInvocation
+  , programInvocation
+  , multiStageProgramInvocation
+  , runProgramInvocation
+  , getProgramInvocationOutput
+  , getProgramInvocationLBS
+  , getProgramInvocationOutputAndErrors
+  , getProgramInvocationLBSAndErrors
+  , getEffectiveEnvironment
   ) where
 
 import Distribution.Compat.Prelude
@@ -38,8 +37,6 @@
 import Distribution.Utils.Generic
 import Distribution.Verbosity
 
-import System.FilePath (searchPathSeparator)
-
 import qualified Data.ByteString.Lazy as LBS
 import qualified Data.Map             as Map
 
@@ -54,8 +51,6 @@
        progInvokePath  :: FilePath,
        progInvokeArgs  :: [String],
        progInvokeEnv   :: [(String, Maybe String)],
-       -- Extra paths to add to PATH
-       progInvokePathEnv :: [FilePath],
        progInvokeCwd   :: Maybe FilePath,
        progInvokeInput :: Maybe IOData,
        progInvokeInputEncoding  :: IOEncoding, -- ^ TODO: remove this, make user decide when constructing 'progInvokeInput'.
@@ -76,7 +71,6 @@
     progInvokePath  = "",
     progInvokeArgs  = [],
     progInvokeEnv   = [],
-    progInvokePathEnv = [],
     progInvokeCwd   = Nothing,
     progInvokeInput = Nothing,
     progInvokeInputEncoding  = IOEncodingText,
@@ -107,7 +101,6 @@
     progInvokePath  = path,
     progInvokeArgs  = args,
     progInvokeEnv   = [],
-    progInvokePathEnv = [],
     progInvokeCwd   = Nothing,
     progInvokeInput = Nothing
   } =
@@ -118,31 +111,25 @@
     progInvokePath  = path,
     progInvokeArgs  = args,
     progInvokeEnv   = envOverrides,
-    progInvokePathEnv = extraPath,
     progInvokeCwd   = mcwd,
     progInvokeInput = Nothing
   } = do
-    pathOverride <- getExtraPathEnv envOverrides extraPath
-    menv <- getEffectiveEnvironment (envOverrides ++ pathOverride)
-    exitCode <- rawSystemIOWithEnv verbosity
+    menv <- getEffectiveEnvironment envOverrides
+    maybeExit $ rawSystemIOWithEnv verbosity
                                    path args
                                    mcwd menv
                                    Nothing Nothing Nothing
-    when (exitCode /= ExitSuccess) $
-      exitWith exitCode
 
 runProgramInvocation verbosity
   ProgramInvocation {
     progInvokePath  = path,
     progInvokeArgs  = args,
     progInvokeEnv   = envOverrides,
-    progInvokePathEnv = extraPath,
     progInvokeCwd   = mcwd,
     progInvokeInput = Just inputStr,
     progInvokeInputEncoding = encoding
   } = do
-    pathOverride <- getExtraPathEnv envOverrides extraPath
-    menv <- getEffectiveEnvironment (envOverrides ++ pathOverride)
+    menv <- getEffectiveEnvironment envOverrides
     (_, errors, exitCode) <- rawSystemStdInOut verbosity
                                     path args
                                     mcwd menv
@@ -176,6 +163,13 @@
         (output', errors, exitCode) <- getProgramInvocationIODataAndErrors verbosity inv IODataModeBinary
         return (normaliseLineEndings (fromUTF8LBS output'), errors, exitCode)
 
+getProgramInvocationLBSAndErrors
+  :: Verbosity
+  -> ProgramInvocation
+  -> IO (LBS.ByteString, String, ExitCode)
+getProgramInvocationLBSAndErrors verbosity inv =
+  getProgramInvocationIODataAndErrors verbosity inv IODataModeBinary
+
 getProgramInvocationIODataAndErrors
     :: KnownIODataMode mode => Verbosity -> ProgramInvocation -> IODataMode mode
     -> IO (mode, String, ExitCode)
@@ -185,29 +179,15 @@
     { progInvokePath          = path
     , progInvokeArgs          = args
     , progInvokeEnv           = envOverrides
-    , progInvokePathEnv       = extraPath
     , progInvokeCwd           = mcwd
     , progInvokeInput         = minputStr
     , progInvokeInputEncoding = encoding
     }
   mode = do
-    pathOverride <- getExtraPathEnv envOverrides extraPath
-    menv <- getEffectiveEnvironment (envOverrides ++ pathOverride)
+    menv <- getEffectiveEnvironment envOverrides
     rawSystemStdInOut verbosity path args mcwd menv input mode
   where
     input = encodeToIOData encoding <$> minputStr
-
-getExtraPathEnv :: [(String, Maybe String)] -> [FilePath] -> IO [(String, Maybe String)]
-getExtraPathEnv _ [] = return []
-getExtraPathEnv env extras = do
-    mb_path <- case lookup "PATH" env of
-                Just x  -> return x
-                Nothing -> lookupEnv "PATH"
-    let extra = intercalate [searchPathSeparator] extras
-        path' = case mb_path of
-                    Nothing   -> extra
-                    Just path -> extra ++ searchPathSeparator : path
-    return [("PATH", Just path')]
 
 -- | Return the current environment extended with the given overrides.
 -- If an entry is specified twice in @overrides@, the second entry takes
diff --git a/cabal/Cabal/src/Distribution/Simple/Program/Types.hs b/cabal/Cabal/src/Distribution/Simple/Program/Types.hs
--- a/cabal/Cabal/src/Distribution/Simple/Program/Types.hs
+++ b/cabal/Cabal/src/Distribution/Simple/Program/Types.hs
@@ -25,7 +25,6 @@
     Program(..),
     ProgramSearchPath,
     ProgramSearchPathEntry(..),
-    simpleProgram,
 
     -- * Configured program and related functions
     ConfiguredProgram(..),
@@ -40,7 +39,6 @@
 import Distribution.Compat.Prelude
 
 import Distribution.PackageDescription
-import Distribution.Simple.Program.Find
 import Distribution.Version
 import Distribution.Verbosity
 
@@ -87,6 +85,36 @@
 
 type ProgArg = String
 
+-- | A search path to use when locating executables. This is analogous
+-- to the unix @$PATH@ or win32 @%PATH%@ but with the ability to use
+-- the system default method for finding executables ('findExecutable' which
+-- on unix is simply looking on the @$PATH@ but on win32 is a bit more
+-- complicated).
+--
+-- The default to use is @[ProgSearchPathDefault]@ but you can add extra dirs
+-- either before, after or instead of the default, e.g. here we add an extra
+-- dir to search after the usual ones.
+--
+-- > ['ProgramSearchPathDefault', 'ProgramSearchPathDir' dir]
+--
+-- We also use this path to set the environment when running child processes.
+--
+-- The @ProgramDb@ is created with a @ProgramSearchPath@ to which we
+-- @appendProgramSearchPath@ to add the ones that come from cli flags and from
+-- configurations. Then each of the programs that are configured in the db
+-- inherits the same path as part of @configureProgram@.
+type ProgramSearchPath = [ProgramSearchPathEntry]
+
+data ProgramSearchPathEntry
+  = -- | A specific dir
+    ProgramSearchPathDir FilePath
+  | -- | The system default
+    ProgramSearchPathDefault
+  deriving (Eq, Generic, Typeable)
+
+instance Binary ProgramSearchPathEntry
+instance Structured ProgramSearchPathEntry
+
 -- | Represents a program which has been configured and is thus ready to be run.
 --
 -- These are usually made by configuring a 'Program', but if you have to
@@ -156,22 +184,6 @@
 -- | Suppress any extra arguments added by the user.
 suppressOverrideArgs :: ConfiguredProgram -> ConfiguredProgram
 suppressOverrideArgs prog = prog { programOverrideArgs = [] }
-
--- | Make a simple named program.
---
--- By default we'll just search for it in the path and not try to find the
--- version name. You can override these behaviours if necessary, eg:
---
--- > (simpleProgram "foo") { programFindLocation = ... , programFindVersion ... }
---
-simpleProgram :: String -> Program
-simpleProgram name = Program {
-    programName         = name,
-    programFindLocation = \v p -> findProgramOnSearchPath v p name,
-    programFindVersion  = \_ _ -> return Nothing,
-    programPostConf     = \_ p -> return p,
-    programNormaliseArgs   = \_ _ -> id
-  }
 
 -- | Make a simple 'ConfiguredProgram'.
 --
diff --git a/cabal/Cabal/src/Distribution/Simple/Register.hs b/cabal/Cabal/src/Distribution/Simple/Register.hs
--- a/cabal/Cabal/src/Distribution/Simple/Register.hs
+++ b/cabal/Cabal/src/Distribution/Simple/Register.hs
@@ -466,9 +466,11 @@
                              || not (null (asmSources bi))
                              || not (null (cmmSources bi))
                              || not (null (cxxSources bi))
-                             || (not (null (jsSources bi)) &&
-                                compilerFlavor comp == GHCJS))
+                             || (not (null (jsSources bi)) && hasJsSupport))
                && not (componentIsIndefinite clbi)
+    hasJsSupport = case hostPlatform lbi of
+      Platform JavaScript _ -> True
+      _                     -> False
     libdirsStatic
       | hasLibrary = libdir installDirs : extraLibDirsStaticOrFallback
       | otherwise  =                      extraLibDirsStaticOrFallback
diff --git a/cabal/Cabal/src/Distribution/Simple/Setup.hs b/cabal/Cabal/src/Distribution/Simple/Setup.hs
--- a/cabal/Cabal/src/Distribution/Simple/Setup.hs
+++ b/cabal/Cabal/src/Distribution/Simple/Setup.hs
@@ -44,6 +44,8 @@
   InstallFlags(..),  emptyInstallFlags,  defaultInstallFlags,  installCommand,
   HaddockTarget(..),
   HaddockFlags(..),  emptyHaddockFlags,  defaultHaddockFlags,  haddockCommand,
+  Visibility(..),
+  HaddockProjectFlags(..), emptyHaddockProjectFlags, defaultHaddockProjectFlags, haddockProjectCommand,
   HscolourFlags(..), emptyHscolourFlags, defaultHscolourFlags, hscolourCommand,
   BuildFlags(..),    emptyBuildFlags,    defaultBuildFlags,    buildCommand,
   DumpBuildInfo(..),
@@ -59,7 +61,7 @@
   defaultBenchmarkFlags, benchmarkCommand,
   CopyDest(..),
   configureArgs, configureOptions, configureCCompiler, configureLinker,
-  buildOptions, haddockOptions, installDirsOptions,
+  buildOptions, haddockOptions, haddockProjectOptions, installDirsOptions,
   testOptions', benchmarkOptions',
   programDbOptions, programDbPaths',
   programFlagsDescription,
@@ -528,7 +530,7 @@
 
       ,option "" ["profiling-detail"]
          ("Profiling detail level for executable and library (default, " ++
-          "none, exported-functions, toplevel-functions,  all-functions).")
+          "none, exported-functions, toplevel-functions,  all-functions, late).")
          configProfDetail (\v flags -> flags { configProfDetail = v })
          (reqArg' "level" (Flag . flagToProfDetailLevel)
                           showProfDetailLevelFlag)
@@ -1377,10 +1379,13 @@
     haddockQuickJump    :: Flag Bool,
     haddockHscolourCss  :: Flag FilePath,
     haddockContents     :: Flag PathTemplate,
+    haddockIndex        :: Flag PathTemplate,
     haddockDistPref     :: Flag FilePath,
     haddockKeepTempFiles:: Flag Bool,
     haddockVerbosity    :: Flag Verbosity,
     haddockCabalFilePath :: Flag FilePath,
+    haddockBaseUrl      :: Flag String,
+    haddockLib          :: Flag String,
     haddockArgs         :: [String]
   }
   deriving (Show, Generic, Typeable)
@@ -1407,6 +1412,9 @@
     haddockKeepTempFiles= Flag False,
     haddockVerbosity    = Flag normal,
     haddockCabalFilePath = mempty,
+    haddockIndex        = NoFlag,
+    haddockBaseUrl      = NoFlag,
+    haddockLib          = NoFlag,
     haddockArgs         = mempty
   }
 
@@ -1534,6 +1542,23 @@
    (reqArg' "URL"
     (toFlag . toPathTemplate)
     (flagToList . fmap fromPathTemplate))
+
+  ,option "" ["index-location"]
+   "Use a separately-generated HTML index"
+   haddockIndex (\v flags -> flags { haddockIndex = v})
+   (reqArg' "URL"
+    (toFlag . toPathTemplate)
+    (flagToList . fmap fromPathTemplate))
+
+  ,option "" ["base-url"]
+   "Base URL for static files."
+   haddockBaseUrl (\v flags -> flags { haddockBaseUrl = v})
+   (reqArgFlag "URL")
+
+  ,option "" ["lib"]
+   "location of Haddocks static / auxiliary files"
+   haddockLib (\v flags -> flags { haddockLib = v})
+   (reqArgFlag "DIR")
   ]
 
 emptyHaddockFlags :: HaddockFlags
@@ -1544,6 +1569,245 @@
   mappend = (<>)
 
 instance Semigroup HaddockFlags where
+  (<>) = gmappend
+
+-- ------------------------------------------------------------
+-- * HaddocksFlags flags
+-- ------------------------------------------------------------
+
+-- | Governs whether modules from a given interface should be visible or
+-- hidden in the Haddock generated content page.  We don't expose this
+-- functionality to the user, but simply use 'Visible' for only local packages.
+-- Visibility of modules is available since @haddock-2.26.1@.
+--
+data Visibility = Visible | Hidden
+  deriving (Eq, Show)
+
+data HaddockProjectFlags = HaddockProjectFlags {
+    haddockProjectHackage      :: Flag Bool,
+    -- ^ a shortcut option which builds documentation linked to hackage.  It implies:
+    -- * `--html-location='https://hackage.haskell.org/package/$prg-$version/docs'
+    -- * `--quickjump`
+    -- * `--gen-index`
+    -- * `--gen-contents`
+    -- * `--hyperlinked-source`
+    haddockProjectLocal        :: Flag Bool,
+    -- ^ a shortcut option which builds self contained directory which contains
+    -- all the documentation, it implies:
+    -- * `--quickjump`
+    -- * `--gen-index`
+    -- * `--gen-contents`
+    -- * `--hyperlinked-source`
+    --
+    -- And it will also pass `--base-url` option to `haddock`.
+
+    -- options passed to @haddock@ via 'createHaddockIndex'
+    haddockProjectDir          :: Flag String,
+    -- ^ output directory of combined haddocks, the default is './haddocks'
+    haddockProjectPrologue     :: Flag String,
+    haddockProjectGenIndex     :: Flag Bool,
+    haddockProjectGenContents  :: Flag Bool,
+    haddockProjectInterfaces   :: Flag [(FilePath, Maybe FilePath, Maybe FilePath, Visibility)],
+    -- ^ 'haddocksInterfaces' is inferred by the 'haddocksAction'; currently not
+    -- exposed to the user.
+
+    -- options passed to @haddock@ via 'HaddockFlags' when building
+    -- documentation
+
+    haddockProjectProgramPaths :: [(String, FilePath)],
+    haddockProjectProgramArgs  :: [(String, [String])],
+    haddockProjectHoogle       :: Flag Bool,
+    -- haddockHtml is not supported
+    haddockProjectHtmlLocation :: Flag String,
+    -- haddockForHackage is not supported
+    haddockProjectExecutables  :: Flag Bool,
+    haddockProjectTestSuites   :: Flag Bool,
+    haddockProjectBenchmarks   :: Flag Bool,
+    haddockProjectForeignLibs  :: Flag Bool,
+    haddockProjectInternal     :: Flag Bool,
+    haddockProjectCss          :: Flag FilePath,
+    haddockProjectLinkedSource :: Flag Bool,
+    haddockProjectQuickJump    :: Flag Bool,
+    haddockProjectHscolourCss  :: Flag FilePath,
+    -- haddockContent is not supported, a fixed value is provided
+    -- haddockIndex is not supported, a fixed value is provided
+    -- haddockDistPerf is not supported, note: it changes location of the haddocks
+    haddockProjectKeepTempFiles:: Flag Bool,
+    haddockProjectVerbosity    :: Flag Verbosity,
+    -- haddockBaseUrl is not supported, a fixed value is provided
+    haddockProjectLib          :: Flag String
+  }
+  deriving (Show, Generic, Typeable)
+
+defaultHaddockProjectFlags :: HaddockProjectFlags
+defaultHaddockProjectFlags = HaddockProjectFlags {
+    haddockProjectHackage      = Flag False,
+    haddockProjectLocal        = Flag False,
+    haddockProjectDir          = Flag "./haddocks",
+    haddockProjectPrologue     = NoFlag,
+    haddockProjectGenIndex     = Flag False,
+    haddockProjectGenContents  = Flag False,
+    haddockProjectTestSuites   = Flag False,
+    haddockProjectProgramPaths = mempty,
+    haddockProjectProgramArgs  = mempty,
+    haddockProjectHoogle       = Flag False,
+    haddockProjectHtmlLocation = NoFlag,
+    haddockProjectExecutables  = Flag False,
+    haddockProjectBenchmarks   = Flag False,
+    haddockProjectForeignLibs  = Flag False,
+    haddockProjectInternal     = Flag False,
+    haddockProjectCss          = NoFlag,
+    haddockProjectLinkedSource = Flag False,
+    haddockProjectQuickJump    = Flag False,
+    haddockProjectHscolourCss  = NoFlag,
+    haddockProjectKeepTempFiles= Flag False,
+    haddockProjectVerbosity    = Flag normal,
+    haddockProjectLib          = NoFlag,
+    haddockProjectInterfaces   = NoFlag
+  }
+
+haddockProjectCommand :: CommandUI HaddockProjectFlags
+haddockProjectCommand = CommandUI
+  { commandName        = "v2-haddock-project"
+  , commandSynopsis    = "Generate Haddocks HTML documentation for the cabal project."
+  , commandDescription = Just $ \_ ->
+      "Require the programm haddock, version 2.26.\n"
+  , commandNotes       = Nothing
+  , commandUsage       = usageAlternatives "haddocks" $
+      [ "[FLAGS]"
+      , "COMPONENTS [FLAGS]"
+      ]
+  , commandDefaultFlags = defaultHaddockProjectFlags
+  , commandOptions      = \showOrParseArgs ->
+         haddockProjectOptions showOrParseArgs
+      ++ programDbPaths   progDb ParseArgs
+             haddockProjectProgramPaths (\v flags -> flags { haddockProjectProgramPaths = v})
+      ++ programDbOption  progDb showOrParseArgs
+             haddockProjectProgramArgs (\v fs -> fs { haddockProjectProgramArgs = v })
+      ++ programDbOptions progDb ParseArgs
+             haddockProjectProgramArgs  (\v flags -> flags { haddockProjectProgramArgs = v})
+  }
+  where
+    progDb = addKnownProgram haddockProgram
+             $ addKnownProgram ghcProgram
+             $ emptyProgramDb
+
+haddockProjectOptions :: ShowOrParseArgs -> [OptionField HaddockProjectFlags]
+haddockProjectOptions _showOrParseArgs =
+    [option "" ["hackage"]
+     (concat ["A short-cut option to build documentation linked to hackage; "
+             ,"it implies --quickjump, --gen-index, --gen-contents, "
+             ,"--hyperlinked-source and --html-location"
+             ])
+     haddockProjectHackage (\v flags -> flags { haddockProjectHackage = v })
+     trueArg
+
+    ,option "" ["local"]
+     (concat ["A short-cut option to build self contained documentation; "
+             ,"it implies  --quickjump, --gen-index, --gen-contents "
+             ,"and --hyperlinked-source."
+             ])
+     haddockProjectLocal (\v flags -> flags { haddockProjectLocal = v })
+     trueArg
+
+    ,option "" ["output"]
+      "Output directory"
+      haddockProjectDir (\v flags -> flags { haddockProjectDir = v })
+      (optArg' "DIRECTORY" maybeToFlag (fmap Just . flagToList))
+
+    ,option "" ["prologue"]
+     "File path to a prologue file in haddock format"
+     haddockProjectPrologue (\v flags -> flags { haddockProjectPrologue = v})
+     (optArg' "PATH" maybeToFlag (fmap Just . flagToList))
+
+    ,option "" ["gen-index"]
+     "Generate index"
+     haddockProjectGenIndex (\v flags -> flags { haddockProjectGenIndex = v})
+     trueArg
+
+    ,option "" ["gen-contents"]
+     "Generate contents"
+     haddockProjectGenContents (\v flags -> flags { haddockProjectGenContents = v})
+     trueArg
+
+    ,option "" ["hoogle"]
+     "Generate a hoogle database"
+     haddockProjectHoogle (\v flags -> flags { haddockProjectHoogle = v })
+     trueArg
+
+    ,option "" ["html-location"]
+     "Location of HTML documentation for pre-requisite packages"
+     haddockProjectHtmlLocation (\v flags -> flags { haddockProjectHtmlLocation = v })
+     (reqArgFlag "URL")
+
+    ,option "" ["executables"]
+     "Run haddock for Executables targets"
+     haddockProjectExecutables (\v flags -> flags { haddockProjectExecutables = v })
+     trueArg
+
+    ,option "" ["tests"]
+     "Run haddock for Test Suite targets"
+     haddockProjectTestSuites (\v flags -> flags { haddockProjectTestSuites = v })
+     trueArg
+
+    ,option "" ["benchmarks"]
+     "Run haddock for Benchmark targets"
+     haddockProjectBenchmarks (\v flags -> flags { haddockProjectBenchmarks = v })
+     trueArg
+
+    ,option "" ["foreign-libraries"]
+     "Run haddock for Foreign Library targets"
+     haddockProjectForeignLibs (\v flags -> flags { haddockProjectForeignLibs = v })
+     trueArg
+
+    ,option "" ["internal"]
+     "Run haddock for internal modules and include all symbols"
+     haddockProjectInternal (\v flags -> flags { haddockProjectInternal = v })
+     trueArg
+
+    ,option "" ["css"]
+     "Use PATH as the haddock stylesheet"
+     haddockProjectCss (\v flags -> flags { haddockProjectCss = v })
+     (reqArgFlag "PATH")
+
+    ,option "" ["hyperlink-source","hyperlink-sources","hyperlinked-source"]
+     "Hyperlink the documentation to the source code"
+     haddockProjectLinkedSource (\v flags -> flags { haddockProjectLinkedSource = v })
+     trueArg
+
+    ,option "" ["quickjump"]
+     "Generate an index for interactive documentation navigation"
+     haddockProjectQuickJump (\v flags -> flags { haddockProjectQuickJump = v })
+     trueArg
+
+    ,option "" ["hscolour-css"]
+     "Use PATH as the HsColour stylesheet"
+     haddockProjectHscolourCss (\v flags -> flags { haddockProjectHscolourCss = v })
+     (reqArgFlag "PATH")
+
+    ,option "" ["keep-temp-files"]
+     "Keep temporary files"
+     haddockProjectKeepTempFiles (\b flags -> flags { haddockProjectKeepTempFiles = b })
+     trueArg
+
+    ,optionVerbosity haddockProjectVerbosity
+     (\v flags -> flags { haddockProjectVerbosity = v })
+
+    ,option "" ["lib"]
+     "location of Haddocks static / auxiliary files"
+     haddockProjectLib (\v flags -> flags { haddockProjectLib = v})
+     (reqArgFlag "DIR")
+    ]
+
+
+emptyHaddockProjectFlags :: HaddockProjectFlags
+emptyHaddockProjectFlags = mempty
+
+instance Monoid HaddockProjectFlags where
+  mempty = gmempty
+  mappend = (<>)
+
+instance Semigroup HaddockProjectFlags where
   (<>) = gmappend
 
 -- ------------------------------------------------------------
diff --git a/cabal/Cabal/src/Distribution/Simple/Setup/Haddock.hs b/cabal/Cabal/src/Distribution/Simple/Setup/Haddock.hs
new file mode 100644
--- /dev/null
+++ b/cabal/Cabal/src/Distribution/Simple/Setup/Haddock.hs
@@ -0,0 +1,603 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE RankNTypes #-}
+
+-----------------------------------------------------------------------------
+
+-- |
+-- Module      :  Distribution.Simple.Setup.Haddock
+-- Copyright   :  Isaac Jones 2003-2004
+--                Duncan Coutts 2007
+-- License     :  BSD3
+--
+-- Maintainer  :  cabal-devel@haskell.org
+-- Portability :  portable
+--
+-- Definition of the haddock command-line options.
+-- See: @Distribution.Simple.Setup@
+module Distribution.Simple.Setup.Haddock
+  ( HaddockTarget (..)
+  , HaddockFlags (..)
+  , emptyHaddockFlags
+  , defaultHaddockFlags
+  , haddockCommand
+  , Visibility (..)
+  , HaddockProjectFlags (..)
+  , emptyHaddockProjectFlags
+  , defaultHaddockProjectFlags
+  , haddockProjectCommand
+  , haddockOptions
+  , haddockProjectOptions
+  ) where
+
+import Distribution.Compat.Prelude hiding (get)
+import Prelude ()
+
+import qualified Distribution.Compat.CharParsing as P
+import Distribution.Parsec
+import Distribution.Pretty
+import Distribution.Simple.Command hiding (boolOpt, boolOpt')
+import Distribution.Simple.Flag
+import Distribution.Simple.InstallDirs
+import Distribution.Simple.Program
+import Distribution.Verbosity
+import qualified Text.PrettyPrint as Disp
+
+import Distribution.Simple.Setup.Common
+
+-- ------------------------------------------------------------
+
+-- * Haddock flags
+
+-- ------------------------------------------------------------
+
+-- | When we build haddock documentation, there are two cases:
+--
+-- 1. We build haddocks only for the current development version,
+--    intended for local use and not for distribution. In this case,
+--    we store the generated documentation in @<dist>/doc/html/<package name>@.
+--
+-- 2. We build haddocks for intended for uploading them to hackage.
+--    In this case, we need to follow the layout that hackage expects
+--    from documentation tarballs, and we might also want to use different
+--    flags than for development builds, so in this case we store the generated
+--    documentation in @<dist>/doc/html/<package id>-docs@.
+data HaddockTarget = ForHackage | ForDevelopment deriving (Eq, Show, Generic, Typeable)
+
+instance Binary HaddockTarget
+instance Structured HaddockTarget
+
+instance Pretty HaddockTarget where
+  pretty ForHackage = Disp.text "for-hackage"
+  pretty ForDevelopment = Disp.text "for-development"
+
+instance Parsec HaddockTarget where
+  parsec =
+    P.choice
+      [ P.try $ P.string "for-hackage" >> return ForHackage
+      , P.string "for-development" >> return ForDevelopment
+      ]
+
+data HaddockFlags = HaddockFlags
+  { haddockProgramPaths :: [(String, FilePath)]
+  , haddockProgramArgs :: [(String, [String])]
+  , haddockHoogle :: Flag Bool
+  , haddockHtml :: Flag Bool
+  , haddockHtmlLocation :: Flag String
+  , haddockForHackage :: Flag HaddockTarget
+  , haddockExecutables :: Flag Bool
+  , haddockTestSuites :: Flag Bool
+  , haddockBenchmarks :: Flag Bool
+  , haddockForeignLibs :: Flag Bool
+  , haddockInternal :: Flag Bool
+  , haddockCss :: Flag FilePath
+  , haddockLinkedSource :: Flag Bool
+  , haddockQuickJump :: Flag Bool
+  , haddockHscolourCss :: Flag FilePath
+  , haddockContents :: Flag PathTemplate
+  , haddockIndex :: Flag PathTemplate
+  , haddockDistPref :: Flag FilePath
+  , haddockKeepTempFiles :: Flag Bool
+  , haddockVerbosity :: Flag Verbosity
+  , haddockCabalFilePath :: Flag FilePath
+  , haddockBaseUrl :: Flag String
+  , haddockLib :: Flag String
+  , haddockOutputDir :: Flag FilePath
+  , haddockArgs :: [String]
+  }
+  deriving (Show, Generic, Typeable)
+
+defaultHaddockFlags :: HaddockFlags
+defaultHaddockFlags =
+  HaddockFlags
+    { haddockProgramPaths = mempty
+    , haddockProgramArgs = []
+    , haddockHoogle = Flag False
+    , haddockHtml = Flag False
+    , haddockHtmlLocation = NoFlag
+    , haddockForHackage = NoFlag
+    , haddockExecutables = Flag False
+    , haddockTestSuites = Flag False
+    , haddockBenchmarks = Flag False
+    , haddockForeignLibs = Flag False
+    , haddockInternal = Flag False
+    , haddockCss = NoFlag
+    , haddockLinkedSource = Flag False
+    , haddockQuickJump = Flag False
+    , haddockHscolourCss = NoFlag
+    , haddockContents = NoFlag
+    , haddockDistPref = NoFlag
+    , haddockKeepTempFiles = Flag False
+    , haddockVerbosity = Flag normal
+    , haddockCabalFilePath = mempty
+    , haddockIndex = NoFlag
+    , haddockBaseUrl = NoFlag
+    , haddockLib = NoFlag
+    , haddockOutputDir = NoFlag
+    , haddockArgs = mempty
+    }
+
+haddockCommand :: CommandUI HaddockFlags
+haddockCommand =
+  CommandUI
+    { commandName = "haddock"
+    , commandSynopsis = "Generate Haddock HTML documentation."
+    , commandDescription = Just $ \_ ->
+        "Requires the program haddock, version 2.x.\n"
+    , commandNotes = Nothing
+    , commandUsage =
+        usageAlternatives "haddock" $
+          [ "[FLAGS]"
+          , "COMPONENTS [FLAGS]"
+          ]
+    , commandDefaultFlags = defaultHaddockFlags
+    , commandOptions = \showOrParseArgs ->
+        haddockOptions showOrParseArgs
+          ++ programDbPaths
+            progDb
+            ParseArgs
+            haddockProgramPaths
+            (\v flags -> flags{haddockProgramPaths = v})
+          ++ programDbOption
+            progDb
+            showOrParseArgs
+            haddockProgramArgs
+            (\v fs -> fs{haddockProgramArgs = v})
+          ++ programDbOptions
+            progDb
+            ParseArgs
+            haddockProgramArgs
+            (\v flags -> flags{haddockProgramArgs = v})
+    }
+  where
+    progDb =
+      addKnownProgram haddockProgram $
+        addKnownProgram ghcProgram $
+          emptyProgramDb
+
+haddockOptions :: ShowOrParseArgs -> [OptionField HaddockFlags]
+haddockOptions showOrParseArgs =
+  [ optionVerbosity
+      haddockVerbosity
+      (\v flags -> flags{haddockVerbosity = v})
+  , optionDistPref
+      haddockDistPref
+      (\d flags -> flags{haddockDistPref = d})
+      showOrParseArgs
+  , option
+      ""
+      ["keep-temp-files"]
+      "Keep temporary files"
+      haddockKeepTempFiles
+      (\b flags -> flags{haddockKeepTempFiles = b})
+      trueArg
+  , option
+      ""
+      ["hoogle"]
+      "Generate a hoogle database"
+      haddockHoogle
+      (\v flags -> flags{haddockHoogle = v})
+      trueArg
+  , option
+      ""
+      ["html"]
+      "Generate HTML documentation (the default)"
+      haddockHtml
+      (\v flags -> flags{haddockHtml = v})
+      trueArg
+  , option
+      ""
+      ["html-location"]
+      "Location of HTML documentation for pre-requisite packages"
+      haddockHtmlLocation
+      (\v flags -> flags{haddockHtmlLocation = v})
+      (reqArgFlag "URL")
+  , option
+      ""
+      ["for-hackage"]
+      "Collection of flags to generate documentation suitable for upload to hackage"
+      haddockForHackage
+      (\v flags -> flags{haddockForHackage = v})
+      (noArg (Flag ForHackage))
+  , option
+      ""
+      ["executables"]
+      "Run haddock for Executables targets"
+      haddockExecutables
+      (\v flags -> flags{haddockExecutables = v})
+      trueArg
+  , option
+      ""
+      ["tests"]
+      "Run haddock for Test Suite targets"
+      haddockTestSuites
+      (\v flags -> flags{haddockTestSuites = v})
+      trueArg
+  , option
+      ""
+      ["benchmarks"]
+      "Run haddock for Benchmark targets"
+      haddockBenchmarks
+      (\v flags -> flags{haddockBenchmarks = v})
+      trueArg
+  , option
+      ""
+      ["foreign-libraries"]
+      "Run haddock for Foreign Library targets"
+      haddockForeignLibs
+      (\v flags -> flags{haddockForeignLibs = v})
+      trueArg
+  , option
+      ""
+      ["all"]
+      "Run haddock for all targets"
+      ( \f ->
+          allFlags
+            [ haddockExecutables f
+            , haddockTestSuites f
+            , haddockBenchmarks f
+            , haddockForeignLibs f
+            ]
+      )
+      ( \v flags ->
+          flags
+            { haddockExecutables = v
+            , haddockTestSuites = v
+            , haddockBenchmarks = v
+            , haddockForeignLibs = v
+            }
+      )
+      trueArg
+  , option
+      ""
+      ["internal"]
+      "Run haddock for internal modules and include all symbols"
+      haddockInternal
+      (\v flags -> flags{haddockInternal = v})
+      trueArg
+  , option
+      ""
+      ["css"]
+      "Use PATH as the haddock stylesheet"
+      haddockCss
+      (\v flags -> flags{haddockCss = v})
+      (reqArgFlag "PATH")
+  , option
+      ""
+      ["hyperlink-source", "hyperlink-sources", "hyperlinked-source"]
+      "Hyperlink the documentation to the source code"
+      haddockLinkedSource
+      (\v flags -> flags{haddockLinkedSource = v})
+      trueArg
+  , option
+      ""
+      ["quickjump"]
+      "Generate an index for interactive documentation navigation"
+      haddockQuickJump
+      (\v flags -> flags{haddockQuickJump = v})
+      trueArg
+  , option
+      ""
+      ["hscolour-css"]
+      "Use PATH as the HsColour stylesheet"
+      haddockHscolourCss
+      (\v flags -> flags{haddockHscolourCss = v})
+      (reqArgFlag "PATH")
+  , option
+      ""
+      ["contents-location"]
+      "Bake URL in as the location for the contents page"
+      haddockContents
+      (\v flags -> flags{haddockContents = v})
+      ( reqArg'
+          "URL"
+          (toFlag . toPathTemplate)
+          (flagToList . fmap fromPathTemplate)
+      )
+  , option
+      ""
+      ["index-location"]
+      "Use a separately-generated HTML index"
+      haddockIndex
+      (\v flags -> flags{haddockIndex = v})
+      ( reqArg'
+          "URL"
+          (toFlag . toPathTemplate)
+          (flagToList . fmap fromPathTemplate)
+      )
+  , option
+      ""
+      ["base-url"]
+      "Base URL for static files."
+      haddockBaseUrl
+      (\v flags -> flags{haddockBaseUrl = v})
+      (reqArgFlag "URL")
+  , option
+      ""
+      ["lib"]
+      "location of Haddocks static / auxiliary files"
+      haddockLib
+      (\v flags -> flags{haddockLib = v})
+      (reqArgFlag "DIR")
+  , option
+      ""
+      ["output-dir"]
+      "Generate haddock documentation into this directory. This flag is provided as a technology preview and is subject to change in the next releases."
+      haddockOutputDir
+      (\v flags -> flags{haddockOutputDir = v})
+      (reqArgFlag "DIR")
+  ]
+
+emptyHaddockFlags :: HaddockFlags
+emptyHaddockFlags = mempty
+
+instance Monoid HaddockFlags where
+  mempty = gmempty
+  mappend = (<>)
+
+instance Semigroup HaddockFlags where
+  (<>) = gmappend
+
+-- ------------------------------------------------------------
+
+-- * HaddocksFlags flags
+
+-- ------------------------------------------------------------
+
+-- | Governs whether modules from a given interface should be visible or
+-- hidden in the Haddock generated content page.  We don't expose this
+-- functionality to the user, but simply use 'Visible' for only local packages.
+-- Visibility of modules is available since @haddock-2.26.1@.
+data Visibility = Visible | Hidden
+  deriving (Eq, Show)
+
+data HaddockProjectFlags = HaddockProjectFlags
+  { haddockProjectHackage :: Flag Bool
+  -- ^ a shortcut option which builds documentation linked to hackage.  It implies:
+  -- * `--html-location='https://hackage.haskell.org/package/$prg-$version/docs'
+  -- * `--quickjump`
+  -- * `--gen-index`
+  -- * `--gen-contents`
+  -- * `--hyperlinked-source`
+  , -- options passed to @haddock@ via 'createHaddockIndex'
+    haddockProjectDir :: Flag String
+  -- ^ output directory of combined haddocks, the default is './haddocks'
+  , haddockProjectPrologue :: Flag String
+  , haddockProjectInterfaces :: Flag [(FilePath, Maybe FilePath, Maybe FilePath, Visibility)]
+  -- ^ 'haddocksInterfaces' is inferred by the 'haddocksAction'; currently not
+  -- exposed to the user.
+  , -- options passed to @haddock@ via 'HaddockFlags' when building
+    -- documentation
+
+    haddockProjectProgramPaths :: [(String, FilePath)]
+  , haddockProjectProgramArgs :: [(String, [String])]
+  , haddockProjectHoogle :: Flag Bool
+  , -- haddockHtml is not supported
+    haddockProjectHtmlLocation :: Flag String
+  , -- haddockForHackage is not supported
+    haddockProjectExecutables :: Flag Bool
+  , haddockProjectTestSuites :: Flag Bool
+  , haddockProjectBenchmarks :: Flag Bool
+  , haddockProjectForeignLibs :: Flag Bool
+  , haddockProjectInternal :: Flag Bool
+  , haddockProjectCss :: Flag FilePath
+  , haddockProjectHscolourCss :: Flag FilePath
+  , -- haddockContent is not supported, a fixed value is provided
+    -- haddockIndex is not supported, a fixed value is provided
+    -- haddockDistPerf is not supported, note: it changes location of the haddocks
+    haddockProjectKeepTempFiles :: Flag Bool
+  , haddockProjectVerbosity :: Flag Verbosity
+  , -- haddockBaseUrl is not supported, a fixed value is provided
+    haddockProjectLib :: Flag String
+  , haddockProjectOutputDir :: Flag FilePath
+  }
+  deriving (Show, Generic, Typeable)
+
+defaultHaddockProjectFlags :: HaddockProjectFlags
+defaultHaddockProjectFlags =
+  HaddockProjectFlags
+    { haddockProjectHackage = Flag False
+    , haddockProjectDir = Flag "./haddocks"
+    , haddockProjectPrologue = NoFlag
+    , haddockProjectTestSuites = Flag False
+    , haddockProjectProgramPaths = mempty
+    , haddockProjectProgramArgs = mempty
+    , haddockProjectHoogle = Flag False
+    , haddockProjectHtmlLocation = NoFlag
+    , haddockProjectExecutables = Flag False
+    , haddockProjectBenchmarks = Flag False
+    , haddockProjectForeignLibs = Flag False
+    , haddockProjectInternal = Flag False
+    , haddockProjectCss = NoFlag
+    , haddockProjectHscolourCss = NoFlag
+    , haddockProjectKeepTempFiles = Flag False
+    , haddockProjectVerbosity = Flag normal
+    , haddockProjectLib = NoFlag
+    , haddockProjectOutputDir = NoFlag
+    , haddockProjectInterfaces = NoFlag
+    }
+
+haddockProjectCommand :: CommandUI HaddockProjectFlags
+haddockProjectCommand =
+  CommandUI
+    { commandName = "v2-haddock-project"
+    , commandSynopsis = "Generate Haddocks HTML documentation for the cabal project."
+    , commandDescription = Just $ \_ ->
+        "Require the programm haddock, version 2.26.\n"
+    , commandNotes = Nothing
+    , commandUsage =
+        usageAlternatives "haddocks" $
+          [ "[FLAGS]"
+          , "COMPONENTS [FLAGS]"
+          ]
+    , commandDefaultFlags = defaultHaddockProjectFlags
+    , commandOptions = \showOrParseArgs ->
+        haddockProjectOptions showOrParseArgs
+          ++ programDbPaths
+            progDb
+            ParseArgs
+            haddockProjectProgramPaths
+            (\v flags -> flags{haddockProjectProgramPaths = v})
+          ++ programDbOption
+            progDb
+            showOrParseArgs
+            haddockProjectProgramArgs
+            (\v fs -> fs{haddockProjectProgramArgs = v})
+          ++ programDbOptions
+            progDb
+            ParseArgs
+            haddockProjectProgramArgs
+            (\v flags -> flags{haddockProjectProgramArgs = v})
+    }
+  where
+    progDb =
+      addKnownProgram haddockProgram $
+        addKnownProgram ghcProgram $
+          emptyProgramDb
+
+haddockProjectOptions :: ShowOrParseArgs -> [OptionField HaddockProjectFlags]
+haddockProjectOptions _showOrParseArgs =
+  [ option
+      ""
+      ["hackage"]
+      ( concat
+          [ "A short-cut option to build documentation linked to hackage."
+          ]
+      )
+      haddockProjectHackage
+      (\v flags -> flags{haddockProjectHackage = v})
+      trueArg
+  , option
+      ""
+      ["output"]
+      "Output directory"
+      haddockProjectDir
+      (\v flags -> flags{haddockProjectDir = v})
+      (optArg' "DIRECTORY" maybeToFlag (fmap Just . flagToList))
+  , option
+      ""
+      ["prologue"]
+      "File path to a prologue file in haddock format"
+      haddockProjectPrologue
+      (\v flags -> flags{haddockProjectPrologue = v})
+      (optArg' "PATH" maybeToFlag (fmap Just . flagToList))
+  , option
+      ""
+      ["hoogle"]
+      "Generate a hoogle database"
+      haddockProjectHoogle
+      (\v flags -> flags{haddockProjectHoogle = v})
+      trueArg
+  , option
+      ""
+      ["html-location"]
+      "Location of HTML documentation for pre-requisite packages"
+      haddockProjectHtmlLocation
+      (\v flags -> flags{haddockProjectHtmlLocation = v})
+      (reqArgFlag "URL")
+  , option
+      ""
+      ["executables"]
+      "Run haddock for Executables targets"
+      haddockProjectExecutables
+      (\v flags -> flags{haddockProjectExecutables = v})
+      trueArg
+  , option
+      ""
+      ["tests"]
+      "Run haddock for Test Suite targets"
+      haddockProjectTestSuites
+      (\v flags -> flags{haddockProjectTestSuites = v})
+      trueArg
+  , option
+      ""
+      ["benchmarks"]
+      "Run haddock for Benchmark targets"
+      haddockProjectBenchmarks
+      (\v flags -> flags{haddockProjectBenchmarks = v})
+      trueArg
+  , option
+      ""
+      ["foreign-libraries"]
+      "Run haddock for Foreign Library targets"
+      haddockProjectForeignLibs
+      (\v flags -> flags{haddockProjectForeignLibs = v})
+      trueArg
+  , option
+      ""
+      ["internal"]
+      "Run haddock for internal modules and include all symbols"
+      haddockProjectInternal
+      (\v flags -> flags{haddockProjectInternal = v})
+      trueArg
+  , option
+      ""
+      ["css"]
+      "Use PATH as the haddock stylesheet"
+      haddockProjectCss
+      (\v flags -> flags{haddockProjectCss = v})
+      (reqArgFlag "PATH")
+  , option
+      ""
+      ["hscolour-css"]
+      "Use PATH as the HsColour stylesheet"
+      haddockProjectHscolourCss
+      (\v flags -> flags{haddockProjectHscolourCss = v})
+      (reqArgFlag "PATH")
+  , option
+      ""
+      ["keep-temp-files"]
+      "Keep temporary files"
+      haddockProjectKeepTempFiles
+      (\b flags -> flags{haddockProjectKeepTempFiles = b})
+      trueArg
+  , optionVerbosity
+      haddockProjectVerbosity
+      (\v flags -> flags{haddockProjectVerbosity = v})
+  , option
+      ""
+      ["lib"]
+      "location of Haddocks static / auxiliary files"
+      haddockProjectLib
+      (\v flags -> flags{haddockProjectLib = v})
+      (reqArgFlag "DIR")
+  , option
+      ""
+      ["output-dir"]
+      "Generate haddock documentation into this directory. This flag is provided as a technology preview and is subject to change in the next releases."
+      haddockProjectOutputDir
+      (\v flags -> flags{haddockProjectOutputDir = v})
+      (reqArgFlag "DIR")
+  ]
+
+emptyHaddockProjectFlags :: HaddockProjectFlags
+emptyHaddockProjectFlags = mempty
+
+instance Monoid HaddockProjectFlags where
+  mempty = gmempty
+  mappend = (<>)
+
+instance Semigroup HaddockProjectFlags where
+  (<>) = gmappend
diff --git a/cabal/Cabal/src/Distribution/Simple/SrcDist.hs b/cabal/Cabal/src/Distribution/Simple/SrcDist.hs
--- a/cabal/Cabal/src/Distribution/Simple/SrcDist.hs
+++ b/cabal/Cabal/src/Distribution/Simple/SrcDist.hs
@@ -361,8 +361,10 @@
       otherModules   = filter (filterFunction bi) (otherModules bi)
     }
     pathsModule = autogenPathsModuleName pkg_descr0
+    packageInfoModule = autogenPackageInfoModuleName pkg_descr0
     filterFunction bi = \mn ->
                                    mn /= pathsModule
+                                && mn /= packageInfoModule
                                 && not (mn `elem` autogenModules bi)
 
 -- | Prepare a directory tree of source files for a snapshot version.
@@ -504,10 +506,10 @@
       (errors, warnings) = partition isDistError (pureChecks ++ ioChecks)
   unless (null errors) $
       notice verbosity $ "Distribution quality errors:\n"
-                      ++ unlines (map explanation errors)
+                      ++ unlines (map ppPackageCheck errors)
   unless (null warnings) $
       notice verbosity $ "Distribution quality warnings:\n"
-                      ++ unlines (map explanation warnings)
+                      ++ unlines (map ppPackageCheck warnings)
   unless (null errors) $
       notice verbosity
         "Note: the public hackage server would reject this package."
diff --git a/cabal/Cabal/src/Distribution/Simple/Test/LibV09.hs b/cabal/Cabal/src/Distribution/Simple/Test/LibV09.hs
--- a/cabal/Cabal/src/Distribution/Simple/Test/LibV09.hs
+++ b/cabal/Cabal/src/Distribution/Simple/Test/LibV09.hs
@@ -41,7 +41,8 @@
     , setCurrentDirectory )
 import System.FilePath ( (</>), (<.>) )
 import System.IO ( hClose, hPutStr )
-import System.Process (StdStream(..), createPipe, waitForProcess)
+import Distribution.Compat.Process (proc)
+import qualified System.Process as Process
 
 runTest :: PD.PackageDescription
         -> LBI.LocalBuildInfo
@@ -78,49 +79,48 @@
 
     suiteLog <- CE.bracket openCabalTemp deleteIfExists $ \tempLog -> do
 
-        -- TODO: this setup is broken,
-        -- if the test output is too big, we will deadlock.
-        (rOut, wOut) <- createPipe
-
         -- Run test executable
-        (Just wIn, _, _, process) <- do
-                let opts = map (testOption pkg_descr lbi suite) $ testOptions flags
-                    dataDirPath = pwd </> PD.dataDir pkg_descr
-                    tixFile = pwd </> tixFilePath distPref way testName'
-                    pkgPathEnv = (pkgPathEnvVar pkg_descr "datadir", dataDirPath)
-                               : existingEnv
-                    shellEnv = [("HPCTIXFILE", tixFile) | isCoverageEnabled]
-                             ++ pkgPathEnv
-                -- Add (DY)LD_LIBRARY_PATH if needed
-                shellEnv' <-
-                  if LBI.withDynExe lbi
-                  then do
-                    let (Platform _ os) = LBI.hostPlatform lbi
-                    paths <- LBI.depLibraryPaths True False lbi clbi
-                    cpath <- canonicalizePath $ LBI.componentBuildDir lbi clbi
-                    return (addLibraryPath os (cpath : paths) shellEnv)
-                  else return shellEnv
-                case testWrapper flags of
-                  Flag path -> createProcessWithEnv verbosity path (cmd:opts) Nothing (Just shellEnv')
-                               -- these handles are closed automatically
-                               CreatePipe (UseHandle wOut) (UseHandle wOut)
-
-                  NoFlag -> createProcessWithEnv verbosity cmd opts Nothing (Just shellEnv')
-                            -- these handles are closed automatically
-                            CreatePipe (UseHandle wOut) (UseHandle wOut)
-
-        hPutStr wIn $ show (tempLog, PD.testName suite)
-        hClose wIn
+        let opts = map (testOption pkg_descr lbi suite) $ testOptions flags
+            dataDirPath = pwd </> PD.dataDir pkg_descr
+            tixFile = pwd </> tixFilePath distPref way testName'
+            pkgPathEnv = (pkgPathEnvVar pkg_descr "datadir", dataDirPath)
+                       : existingEnv
+            shellEnv = [("HPCTIXFILE", tixFile) | isCoverageEnabled]
+                     ++ pkgPathEnv
+        -- Add (DY)LD_LIBRARY_PATH if needed
+        shellEnv' <-
+          if LBI.withDynExe lbi
+          then do
+            let (Platform _ os) = LBI.hostPlatform lbi
+            paths <- LBI.depLibraryPaths True False lbi clbi
+            cpath <- canonicalizePath $ LBI.componentBuildDir lbi clbi
+            return (addLibraryPath os (cpath : paths) shellEnv)
+          else return shellEnv
+        let (cmd', opts') = case testWrapper flags of
+                              Flag path -> (path, cmd:opts)
+                              NoFlag -> (cmd, opts)
 
-        -- Append contents of temporary log file to the final human-
-        -- readable log file
-        logText <- LBS.hGetContents rOut
-        -- Force the IO manager to drain the test output pipe
-        _ <- evaluate (force logText)
+        -- TODO: this setup is broken,
+        -- if the test output is too big, we will deadlock.
+        (rOut, wOut) <- Process.createPipe
+        (exitcode, logText) <- rawSystemProcAction verbosity
+            (proc cmd' opts') { Process.env           = Just shellEnv'
+                              , Process.std_in        = Process.CreatePipe
+                              , Process.std_out       = Process.UseHandle wOut
+                              , Process.std_err       = Process.UseHandle wOut
+                              } $ \mIn _ _ -> do
+          let wIn = fromCreatePipe mIn
+          hPutStr wIn $ show (tempLog, PD.testName suite)
+          hClose wIn
 
-        exitcode <- waitForProcess process
-        unless (exitcode == ExitSuccess) $ do
-            debug verbosity $ cmd ++ " returned " ++ show exitcode
+          -- Append contents of temporary log file to the final human-
+          -- readable log file
+          logText <- LBS.hGetContents rOut
+          -- Force the IO manager to drain the test output pipe
+          _ <- evaluate (force logText)
+          return logText
+        unless (exitcode == ExitSuccess) $
+          debug verbosity $ cmd ++ " returned " ++ show exitcode
 
         -- Generate final log file name
         let finalLogName l = testLogDir
diff --git a/cabal/Cabal/src/Distribution/Simple/Utils.hs b/cabal/Cabal/src/Distribution/Simple/Utils.hs
--- a/cabal/Cabal/src/Distribution/Simple/Utils.hs
+++ b/cabal/Cabal/src/Distribution/Simple/Utils.hs
@@ -39,7 +39,6 @@
         debug, debugNoWrap,
         chattyTry,
         annotateIO,
-        printRawCommandAndArgs, printRawCommandAndArgsAndEnv,
         withOutputMarker,
 
         -- * exceptions
@@ -49,12 +48,14 @@
         -- * running programs
         rawSystemExit,
         rawSystemExitCode,
+        rawSystemProc,
+        rawSystemProcAction,
         rawSystemExitWithEnv,
         rawSystemStdout,
         rawSystemStdInOut,
         rawSystemIOWithEnv,
         rawSystemIOWithEnvAndAction,
-        createProcessWithEnv,
+        fromCreatePipe,
         maybeExit,
         xargs,
         findProgramVersion,
@@ -184,7 +185,7 @@
 import Distribution.ModuleName as ModuleName
 import Distribution.System
 import Distribution.Version
-import Distribution.Compat.Async
+import Distribution.Compat.Async (waitCatch, withAsyncNF)
 import Distribution.Compat.CopyFile
 import Distribution.Compat.FilePath as FilePath
 import Distribution.Compat.Internal.TempFile
@@ -193,7 +194,7 @@
 import Distribution.Verbosity
 import Distribution.Types.PackageId
 
-#define CABAL_VERSION 3,8,1,0
+#define CABAL_VERSION 3,10,3,0
 
 #ifdef BOOTSTRAPPED_CABAL
 import qualified Paths_Cabal (version)
@@ -227,10 +228,7 @@
 import Foreign.C.Error (Errno (..), ePIPE)
 import Data.Time.Clock.POSIX (getPOSIXTime, POSIXTime)
 import Numeric (showFFloat)
-import Distribution.Compat.Process  (createProcess, rawSystem, runInteractiveProcess)
-import System.Process
-         ( ProcessHandle
-         , showCommandForUser, waitForProcess)
+import Distribution.Compat.Process (proc)
 import qualified System.Process as Process
 import qualified GHC.IO.Exception as GHC
 
@@ -707,69 +705,115 @@
 
 -- -----------------------------------------------------------------------------
 -- rawSystem variants
+--
+-- These all use 'Distribution.Compat.Process.proc' to ensure we
+-- consistently use process jobs on Windows and Ctrl-C delegation
+-- on Unix.
+--
+-- Additionally, they take care of logging command execution.
+--
+
+-- | Helper to use with one of the 'rawSystem' variants, and exit
+-- unless the command completes successfully.
 maybeExit :: IO ExitCode -> IO ()
 maybeExit cmd = do
-  res <- cmd
-  unless (res == ExitSuccess) $ exitWith res
+  exitcode <- cmd
+  unless (exitcode == ExitSuccess) $ exitWith exitcode
 
+-- | Log a command execution (that's typically about to happen)
+-- at info level, and log working directory and environment overrides
+-- at debug level if specified.
+--
+logCommand :: Verbosity -> Process.CreateProcess -> IO ()
+logCommand verbosity cp = do
+  infoNoWrap verbosity $ "Running: " <> case Process.cmdspec cp of
+    Process.ShellCommand sh -> sh
+    Process.RawCommand path args -> Process.showCommandForUser path args
+  case Process.env cp of
+    Just env -> debugNoWrap verbosity $ "with environment: " ++ show env
+    Nothing -> return ()
+  case Process.cwd cp of
+    Just cwd -> debugNoWrap verbosity $ "with working directory: " ++ show cwd
+    Nothing -> return ()
+  hFlush stdout
 
+-- | Execute the given command with the given arguments, exiting
+-- with the same exit code if the command fails.
+--
+rawSystemExit :: Verbosity -> FilePath -> [String] -> IO ()
+rawSystemExit verbosity path args = withFrozenCallStack $
+  maybeExit $ rawSystemExitCode verbosity path args
 
-printRawCommandAndArgs :: Verbosity -> FilePath -> [String] -> IO ()
-printRawCommandAndArgs verbosity path args = withFrozenCallStack $
-    printRawCommandAndArgsAndEnv verbosity path args Nothing Nothing
+-- | Execute the given command with the given arguments, returning
+-- the command's exit code.
+--
+rawSystemExitCode :: Verbosity -> FilePath -> [String] -> IO ExitCode
+rawSystemExitCode verbosity path args = withFrozenCallStack $
+  rawSystemProc verbosity $ proc path args
 
-printRawCommandAndArgsAndEnv :: Verbosity
-                             -> FilePath
-                             -> [String]
-                             -> Maybe FilePath
-                             -> Maybe [(String, String)]
-                             -> IO ()
-printRawCommandAndArgsAndEnv verbosity path args mcwd menv = do
-    case menv of
-        Just env -> debugNoWrap verbosity ("Environment: " ++ show env)
-        Nothing -> return ()
-    case mcwd of
-        Just cwd -> debugNoWrap verbosity ("Working directory: " ++ show cwd)
-        Nothing -> return ()
-    infoNoWrap verbosity (showCommandForUser path args)
+-- | Execute the given command with the given arguments, returning
+-- the command's exit code.
+--
+-- Create the process argument with 'Distribution.Compat.Process.proc'
+-- to ensure consistent options with other 'rawSystem' functions in this
+-- module.
+--
+rawSystemProc :: Verbosity -> Process.CreateProcess -> IO ExitCode
+rawSystemProc verbosity cp = withFrozenCallStack $ do
+  (exitcode, _) <- rawSystemProcAction verbosity cp $ \_ _ _ -> return ()
+  return exitcode
 
--- Exit with the same exit code if the subcommand fails
-rawSystemExit :: Verbosity -> FilePath -> [String] -> IO ()
-rawSystemExit verbosity path args = withFrozenCallStack $ do
-  printRawCommandAndArgs verbosity path args
-  hFlush stdout
-  exitcode <- rawSystem path args
+-- | Execute the given command with the given arguments, returning
+-- the command's exit code. 'action' is executed while the command
+-- is running, and would typically be used to communicate with the
+-- process through pipes.
+--
+-- Create the process argument with 'Distribution.Compat.Process.proc'
+-- to ensure consistent options with other 'rawSystem' functions in this
+-- module.
+--
+rawSystemProcAction :: Verbosity -> Process.CreateProcess
+                    -> (Maybe Handle -> Maybe Handle -> Maybe Handle -> IO a)
+                    -> IO (ExitCode, a)
+rawSystemProcAction verbosity cp action = withFrozenCallStack $ do
+  logCommand verbosity cp
+  (exitcode, a) <- Process.withCreateProcess cp $ \mStdin mStdout mStderr p -> do
+    a <- action mStdin mStdout mStderr
+    exitcode <- Process.waitForProcess p
+    return (exitcode, a)
   unless (exitcode == ExitSuccess) $ do
-    debug verbosity $ path ++ " returned " ++ show exitcode
-    exitWith exitcode
+    let cmd = case Process.cmdspec cp of
+          Process.ShellCommand sh -> sh
+          Process.RawCommand path _args -> path
+    debug verbosity $ cmd ++ " returned " ++ show exitcode
+  return (exitcode, a)
 
-rawSystemExitCode :: Verbosity -> FilePath -> [String] -> IO ExitCode
-rawSystemExitCode verbosity path args = withFrozenCallStack $ do
-  printRawCommandAndArgs verbosity path args
-  hFlush stdout
-  exitcode <- rawSystem path args
-  unless (exitcode == ExitSuccess) $ do
-    debug verbosity $ path ++ " returned " ++ show exitcode
-  return exitcode
+-- | fromJust for dealing with 'Maybe Handle' values as obtained via
+-- 'System.Process.CreatePipe'. Creating a pipe using 'CreatePipe' guarantees
+-- a 'Just' value for the corresponding handle.
+--
+fromCreatePipe :: Maybe Handle -> Handle
+fromCreatePipe = maybe (error "fromCreatePipe: Nothing") id
 
+-- | Execute the given command with the given arguments and
+-- environment, exiting with the same exit code if the command fails.
+--
 rawSystemExitWithEnv :: Verbosity
                      -> FilePath
                      -> [String]
                      -> [(String, String)]
                      -> IO ()
-rawSystemExitWithEnv verbosity path args env = withFrozenCallStack $ do
-    printRawCommandAndArgsAndEnv verbosity path args Nothing (Just env)
-    hFlush stdout
-    (_,_,_,ph) <- createProcess $
-                  (Process.proc path args) { Process.env = (Just env)
-                                           , Process.delegate_ctlc = True
-                                           }
-    exitcode <- waitForProcess ph
-    unless (exitcode == ExitSuccess) $ do
-        debug verbosity $ path ++ " returned " ++ show exitcode
-        exitWith exitcode
+rawSystemExitWithEnv verbosity path args env = withFrozenCallStack $
+  maybeExit $ rawSystemProc verbosity $
+    (proc path args) { Process.env = Just env
+                     }
 
--- Closes the passed in handles before returning.
+-- | Execute the given command with the given arguments, returning
+-- the command's exit code.
+--
+-- Optional arguments allow setting working directory, environment
+-- and input and output handles.
+--
 rawSystemIOWithEnv :: Verbosity
                    -> FilePath
                    -> [String]
@@ -780,16 +824,20 @@
                    -> Maybe Handle  -- ^ stderr
                    -> IO ExitCode
 rawSystemIOWithEnv verbosity path args mcwd menv inp out err = withFrozenCallStack $ do
-    (_,_,_,ph) <- createProcessWithEnv verbosity path args mcwd menv
-                                       (mbToStd inp) (mbToStd out) (mbToStd err)
-    exitcode <- waitForProcess ph
-    unless (exitcode == ExitSuccess) $ do
-      debug verbosity $ path ++ " returned " ++ show exitcode
-    return exitcode
+  (exitcode, _) <- rawSystemIOWithEnvAndAction
+    verbosity path args mcwd menv action inp out err
+  return exitcode
   where
-    mbToStd :: Maybe Handle -> Process.StdStream
-    mbToStd = maybe Process.Inherit Process.UseHandle
+    action = return ()
 
+-- | Execute the given command with the given arguments, returning
+-- the command's exit code. 'action' is executed while the command
+-- is running, and would typically be used to communicate with the
+-- process through pipes.
+--
+-- Optional arguments allow setting working directory, environment
+-- and input and output handles.
+--
 rawSystemIOWithEnvAndAction
     :: Verbosity
     -> FilePath
@@ -802,46 +850,21 @@
     -> Maybe Handle  -- ^ stderr
     -> IO (ExitCode, a)
 rawSystemIOWithEnvAndAction verbosity path args mcwd menv action inp out err = withFrozenCallStack $ do
-    (_,_,_,ph) <- createProcessWithEnv verbosity path args mcwd menv
-                                       (mbToStd inp) (mbToStd out) (mbToStd err)
-    a <- action
-    exitcode <- waitForProcess ph
-    unless (exitcode == ExitSuccess) $ do
-      debug verbosity $ path ++ " returned " ++ show exitcode
-    return (exitcode, a)
+  let cp = (proc path args) { Process.cwd           = mcwd
+                            , Process.env           = menv
+                            , Process.std_in        = mbToStd inp
+                            , Process.std_out       = mbToStd out
+                            , Process.std_err       = mbToStd err
+                            }
+  rawSystemProcAction verbosity cp (\_ _ _ -> action)
   where
     mbToStd :: Maybe Handle -> Process.StdStream
     mbToStd = maybe Process.Inherit Process.UseHandle
 
-createProcessWithEnv ::
-     Verbosity
-  -> FilePath
-  -> [String]
-  -> Maybe FilePath           -- ^ New working dir or inherit
-  -> Maybe [(String, String)] -- ^ New environment or inherit
-  -> Process.StdStream  -- ^ stdin
-  -> Process.StdStream  -- ^ stdout
-  -> Process.StdStream  -- ^ stderr
-  -> IO (Maybe Handle, Maybe Handle, Maybe Handle,ProcessHandle)
-  -- ^ Any handles created for stdin, stdout, or stderr
-  -- with 'CreateProcess', and a handle to the process.
-createProcessWithEnv verbosity path args mcwd menv inp out err = withFrozenCallStack $ do
-    printRawCommandAndArgsAndEnv verbosity path args mcwd menv
-    hFlush stdout
-    (inp', out', err', ph) <- createProcess $
-                                (Process.proc path args) {
-                                    Process.cwd           = mcwd
-                                  , Process.env           = menv
-                                  , Process.std_in        = inp
-                                  , Process.std_out       = out
-                                  , Process.std_err       = err
-                                  , Process.delegate_ctlc = True
-                                  }
-    return (inp', out', err', ph)
-
--- | Run a command and return its output.
+-- | Execute the given command with the given arguments, returning
+-- the command's output. Exits if the command exits with error.
 --
--- The output is assumed to be text in the locale encoding.
+-- Provides control over the binary/text mode of the output.
 --
 rawSystemStdout :: forall mode. KnownIODataMode mode => Verbosity -> FilePath -> [String] -> IO mode
 rawSystemStdout verbosity path args = withFrozenCallStack $ do
@@ -851,10 +874,14 @@
     die' verbosity errors
   return output
 
--- | Run a command and return its output, errors and exit status. Optionally
--- also supply some input. Also provides control over whether the binary/text
--- mode of the input and output.
+-- | Execute the given command with the given arguments, returning
+-- the command's output, errors and exit code.
 --
+-- Optional arguments allow setting working directory, environment
+-- and command input.
+--
+-- Provides control over the binary/text mode of the input and output.
+--
 rawSystemStdInOut :: KnownIODataMode mode
                   => Verbosity
                   -> FilePath                 -- ^ Program location
@@ -865,13 +892,16 @@
                   -> IODataMode mode          -- ^ iodata mode, acts as proxy
                   -> IO (mode, String, ExitCode) -- ^ output, errors, exit
 rawSystemStdInOut verbosity path args mcwd menv input _ = withFrozenCallStack $ do
-  printRawCommandAndArgs verbosity path args
-
-  Exception.bracket
-     (runInteractiveProcess path args mcwd menv)
-     (\(inh,outh,errh,_) -> hClose inh >> hClose outh >> hClose errh)
-    $ \(inh,outh,errh,pid) -> do
+  let cp = (proc path args) { Process.cwd     = mcwd
+                            , Process.env     = menv
+                            , Process.std_in  = Process.CreatePipe
+                            , Process.std_out = Process.CreatePipe
+                            , Process.std_err = Process.CreatePipe
+                            }
 
+  (exitcode, (mberr1, mberr2)) <- rawSystemProcAction verbosity cp $ \mb_in mb_out mb_err -> do
+    let (inh, outh, errh) = (fromCreatePipe mb_in, fromCreatePipe mb_out, fromCreatePipe mb_err)
+    flip Exception.finally (hClose inh >> hClose outh >> hClose errh) $ do
       -- output mode depends on what the caller wants
       -- but the errors are always assumed to be text (in the current locale)
       hSetBinaryMode errh False
@@ -888,28 +918,26 @@
         -- wait for both to finish
         mberr1 <- waitCatch outA
         mberr2 <- waitCatch errA
-
-        -- wait for the program to terminate
-        exitcode <- waitForProcess pid
+        return (mberr1, mberr2)
 
-        -- get the stderr, so it can be added to error message
-        err <- reportOutputIOError mberr2
+  -- get the stderr, so it can be added to error message
+  err <- reportOutputIOError mberr2
 
-        unless (exitcode == ExitSuccess) $
-          debug verbosity $ path ++ " returned " ++ show exitcode
-                         ++ if null err then "" else
-                            " with error message:\n" ++ err
-                         ++ case input of
-                              Nothing       -> ""
-                              Just d | IOData.null d  -> ""
-                              Just (IODataText inp)   -> "\nstdin input:\n" ++ inp
-                              Just (IODataBinary inp) -> "\nstdin input (binary):\n" ++ show inp
+  unless (exitcode == ExitSuccess) $
+    debug verbosity $ path ++ " returned " ++ show exitcode
+                   ++ if null err then "" else
+                      " with error message:\n" ++ err
+                   ++ case input of
+                        Nothing       -> ""
+                        Just d | IOData.null d  -> ""
+                        Just (IODataText inp)   -> "\nstdin input:\n" ++ inp
+                        Just (IODataBinary inp) -> "\nstdin input (binary):\n" ++ show inp
 
-        -- Check if we hit an exception while consuming the output
-        -- (e.g. a text decoding error)
-        out <- reportOutputIOError mberr1
+  -- Check if we hit an exception while consuming the output
+  -- (e.g. a text decoding error)
+  out <- reportOutputIOError mberr1
 
-        return (out, err, exitcode)
+  return (out, err, exitcode)
   where
     reportOutputIOError :: Either Exception.SomeException a -> IO a
     reportOutputIOError (Right x) = return x
@@ -1506,12 +1534,13 @@
 -- | List of possible executable file extensions on the current build
 -- platform.
 exeExtensions :: [String]
-exeExtensions = case buildOS of
+exeExtensions = case (buildArch, buildOS) of
   -- Possible improvement: on Windows, read the list of extensions from the
   -- PATHEXT environment variable. By default PATHEXT is ".com; .exe; .bat;
   -- .cmd".
-  Windows -> ["", "exe"]
-  Ghcjs   -> ["", "exe"]
+  (_, Windows) -> ["", "exe"]
+  (_, Ghcjs)   -> ["", "exe"]
+  (Wasm32, _)  -> ["", "wasm"]
   _       -> [""]
 
 -- ------------------------------------------------------------
diff --git a/cabal/Cabal/src/Distribution/Types/LocalBuildInfo.hs b/cabal/Cabal/src/Distribution/Types/LocalBuildInfo.hs
--- a/cabal/Cabal/src/Distribution/Types/LocalBuildInfo.hs
+++ b/cabal/Cabal/src/Distribution/Types/LocalBuildInfo.hs
@@ -283,7 +283,7 @@
 -------------------------------------------------------------------------------
 -- Stub functions to prevent someone from accidentally defining them
 
-{-# WARNING componentNameTargets, unitIdTarget, allTargetsInBuildOrder, withAllTargetsInBuildOrder, neededTargetsInBuildOrder, withNeededTargetsInBuildOrder "By using this function, you may be introducing a bug where you retrieve a 'Component' which does not have 'HookedBuildInfo' applied to it.  See the documentation for 'HookedBuildInfo' for an explanation of the issue.  If you have a 'PakcageDescription' handy (NOT from the 'LocalBuildInfo'), try using the primed version of the function, which takes it as an extra argument." #-}
+{-# WARNING componentNameTargets, unitIdTarget, allTargetsInBuildOrder, withAllTargetsInBuildOrder, neededTargetsInBuildOrder, withNeededTargetsInBuildOrder "By using this function, you may be introducing a bug where you retrieve a 'Component' which does not have 'HookedBuildInfo' applied to it.  See the documentation for 'HookedBuildInfo' for an explanation of the issue.  If you have a 'PackageDescription' handy (NOT from the 'LocalBuildInfo'), try using the primed version of the function, which takes it as an extra argument." #-}
 
 componentNameTargets :: LocalBuildInfo -> ComponentName -> [TargetInfo]
 componentNameTargets lbi = componentNameTargets' (localPkgDescr lbi) lbi
diff --git a/cabal/LICENSE b/cabal/LICENSE
--- a/cabal/LICENSE
+++ b/cabal/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2003-2022, Cabal Development Team.
+Copyright (c) 2003-2023, Cabal Development Team.
 See the AUTHORS file for the full list of copyright holders.
 
 See */LICENSE for the copyright holders of the subcomponents.
diff --git a/cabal/Makefile b/cabal/Makefile
--- a/cabal/Makefile
+++ b/cabal/Makefile
@@ -71,15 +71,27 @@
 ghcid-cli :
 	ghcid -c 'cabal v2-repl cabal-install'
 
-# doctests (relies on .ghc.environment files)
-
+# Artem, 2023-02-03, https://github.com/haskell/cabal/issues/8504
+# The new and prefered way to call the doctest tool (as of now) is based on cabal repl --with-ghc=doctest.
+# The call below reflects the current documentation of the doctest tool except one caveat,
+# which is https://github.com/haskell/cabal/issues/6859, i.e. we have to hide allow-newer in our project
+# file from cabal/doctest. This is easy: we just select a project file with no allow-newer (e.g. cabal.project.libonly).
+#
+# TODO: Cabal-described should be added here but its doctests currently broken, see:
+#       https://github.com/haskell/cabal/issues/8734
+#       Just as well, cabal-install(-solver) doctests (the target below) bitrotted and need some care.
 doctest :
-	doctest --fast Cabal-syntax/src Cabal/src
+	cabal repl --with-ghc=doctest --build-depends=QuickCheck --build-depends=template-haskell --repl-options="-w" --project-file="cabal.project.doctest" Cabal-syntax
+	cabal repl --with-ghc=doctest --build-depends=QuickCheck --build-depends=template-haskell --repl-options="-w" --project-file="cabal.project.doctest" Cabal
 
+
 # This is not run as part of validate.sh (we need hackage-security, which is tricky to get).
 doctest-cli :
 	doctest -D__DOCTEST__ --fast cabal-install/src cabal-install-solver/src cabal-install-solver/src-assertion
 
+doctest-install:
+	cabal install doctest --overwrite-policy=always --ignore-project
+
 # tests
 
 check-tests :
@@ -137,7 +149,6 @@
 validate-dockerfiles : .docker/validate-8.6.5.dockerfile
 validate-dockerfiles : .docker/validate-8.4.4.dockerfile
 validate-dockerfiles : .docker/validate-8.2.2.dockerfile
-validate-dockerfiles : .docker/validate-8.6.5.dockerfile
 
 .docker/validate-%.dockerfile : .docker/validate.dockerfile.zinza cabal-dev-scripts/src/GenValidateDockerfile.hs
 	cabal v2-run --builddir=dist-newstyle-meta --project-file=cabal.project.meta gen-validate-dockerfile -- $* $< $@
@@ -178,13 +189,13 @@
 ##############################################################################
 
 bootstrap-json-%: phony
-	cabal v2-build --project=cabal.project.release --with-compiler=ghc-$* --dry-run cabal-install:exe:cabal
+	cabal v2-build --project-file=cabal.project.release --with-compiler=ghc-$* --dry-run cabal-install:exe:cabal
 	cp dist-newstyle/cache/plan.json bootstrap/linux-$*.plan.json
 	@# -v0 to avoid build output on stdout
 	cd bootstrap && cabal v2-run -v0 cabal-bootstrap-gen -- linux-$*.plan.json \
 		| python3 -m json.tool > linux-$*.json
 
-BOOTSTRAP_GHC_VERSIONS := 8.6.5 8.8.4 8.10.7 9.0.2 9.2.3
+BOOTSTRAP_GHC_VERSIONS := 8.10.7 9.0.2 9.2.8 9.4.8
 
 bootstrap-jsons: $(BOOTSTRAP_GHC_VERSIONS:%=bootstrap-json-%)
 
diff --git a/cabal/README.md b/cabal/README.md
--- a/cabal/README.md
+++ b/cabal/README.md
@@ -8,41 +8,54 @@
 
 <img src="https://www.haskell.org/cabal/images/Cabal-light.png" align="right">
 
-This Cabal Git repository contains the following packages:
+This Cabal Git repository contains the following main packages:
 
  * [Cabal](Cabal/README.md): the Cabal library package ([license](Cabal/LICENSE))
  * [Cabal-syntax](Cabal-syntax/README.md): the `.cabal` file format library ([license](Cabal-syntax/LICENSE))
  * [cabal-install](cabal-install/README.md): the package containing the `cabal` tool ([license](cabal-install/LICENSE))
+ * [cabal-install-solver](cabal-install-solver): the package containing the solver component of the `cabal` tool ([license](cabal-install-solver/LICENSE))
 
 The canonical upstream repository is located at
 https://github.com/haskell/cabal.
 
-Installing cabal-install (by downloading the binary)
-----------------------------------------------------
+Ways to get the `cabal-install` binary
+--------------------------------
 
-Prebuilt binary releases can be obtained from https://www.haskell.org/cabal/download.html.
-The `cabal-install` binary download for your platform should contain the `cabal` executable.
+1. _GHCup (**preferred**)_: get GHCup using [the directions on its website](https://www.haskell.org/ghcup/) and run:
 
-Installing cabal-install (preferred, with cabal-install)
---------------------------------------------------------
+    ```
+    ghcup install --set cabal latest
+    ```
 
-Assuming that you have a pre-existing, recent version of `cabal-install`, run:
+2. _[Download from official website](https://www.haskell.org/cabal/download.html)_:
+    the `cabal-install` binary download for your platform should contain the `cabal` executable.
 
-```
-cabal install cabal-install
-```
+Ways to build `cabal-install` for everyday use
+--------------------------------------------
 
-To get the latest version of `cabal-install`. (You may want to `cabal update` first.)
+1. _With cabal-install_:
+    if you have a pre-existing version of `cabal-install`, run:
 
-To install the latest version from the Git repository, clone the
-Git repository and then run:
+    ```
+    cabal install cabal-install
+    ```
 
-```
-cabal install --project-file=cabal.project.release cabal-install
-```
+    to get the latest version of `cabal-install`. (You may want to `cabal update` first.)
 
-Installing cabal-install without cabal-install
-----------------------------------------------
+2. _From Git_:
+    again with a pre-existing version of `cabal-install`,
+    you can install the latest version from the Git repository. Clone the
+    Git repository, move to its root, and run:
 
-Assuming you don't have a pre-existing copy of `cabal-install`,
-look into [`bootstrap`](bootstrap) directory.
+    ```
+    cabal install --project-file=cabal.project.release cabal-install
+    ```
+
+3. _Bootstrapping_:
+    if you don't have a pre-existing version of `cabal-install`,
+    look into the [`bootstrap`](bootstrap) directory.
+
+Build for hacking and contributing to cabal
+-------------------------------------------
+
+Refer to [CONTRIBUTING.md](CONTRIBUTING.md).
diff --git a/cabal/bootstrap/README.md b/cabal/bootstrap/README.md
--- a/cabal/bootstrap/README.md
+++ b/cabal/bootstrap/README.md
@@ -5,29 +5,38 @@
 please rather run `cabal v2-install`.
 
 The typical usage is porting to a new linux architecture,
-then the `linux-ghcvec.json` file is available in `bootstrap/` folder:
+then the `linux-{ghc-ver}.json` file is available in the `bootstrap/` folder:
 
 On a (linux) system you are bootstrapping, run
 
-    ./bootstrap/bootstrap.py -d ./bootstrap/linux-ghcver.json -w /path/to-ghc
-    
+   ./bootstrap/bootstrap.py -d ./bootstrap/linux-ghcver.json -w /path/to-ghc
+
 from the top directory of the source checkout.
 
-To generate the `platform-ghcver` files for other platforms, do:
+For offline builds, you can first run
 
+   ./bootstrap/bootstrap.py -d ./bootstrap/linux-ghcver.json -w /path/to-ghc fetch
+
+to fetch tarballs for all the dependencies. These can then be used by a further
+bootstrap command by way of the `--bootstrap-sources` argument:
+
+   ./bootstrap/bootstrap.py -w /path/to-ghc --bootstrap-sources bootstrap-sources.tar.gz
+
+To generate the `platform-{ghc-ver}` files for other platforms, do:
+
   1. On a system with functional cabal-install, install the same GHC version
      as you will use to bootstrap on the host system.
 
-  2. Build a dependency description file (`platform-ghcver.json`, e.g. `linux-8.8.3.json`) by running:
+  2. Build a dependency description file (`$PLATFORM-$GHCVER.json`, e.g. `linux-8.8.4.json`) by running:
 
        ```sh
        cabal v2-build --with-compiler=/path/to/ghc --dry-run cabal-install:exe:cabal
-       cp dist-newstyle/cache/plan.json bootstrap/platform-ghcver.plan.json
+       cp dist-newstyle/cache/plan.json bootstrap/$PLATFORM-$GHCVER.plan.json
        cd bootstrap
-       cabal v2-run -v0 cabal-bootstrap-gen -- platform-ghcver.plan.json | tee platform-ghcver.json
+       cabal v2-run -v0 cabal-bootstrap-gen -- $PLATFORM-$GHCVER.plan.json | tee $PLATFORM-$GHCVER.json
        ```
 
-  3. You may need to tweak `bootstrap/platform-ghcver.json` file manually,
+  3. You may need to tweak `bootstrap/$PLATFORM-$GHCVER.json` file manually,
      for example toggle flags.
 
-There are rules in top-level `Makefile` for generation of these files.
+There are rules in the top-level `Makefile` for generation of these files.
diff --git a/cabal/bootstrap/bootstrap.py b/cabal/bootstrap/bootstrap.py
--- a/cabal/bootstrap/bootstrap.py
+++ b/cabal/bootstrap/bootstrap.py
@@ -13,17 +13,20 @@
 please rather run `cabal v2-install .`.
 """
 
+import argparse
 from enum import Enum
 import hashlib
-import logging
 import json
 from pathlib import Path
 import platform
 import shutil
 import subprocess
+import sys
+import tempfile
+import urllib.request
 from textwrap import dedent
-from typing import Set, Optional, Dict, List, Tuple, \
-                   NewType, BinaryIO, NamedTuple, TypeVar
+from typing import Optional, Dict, List, Tuple, \
+                   NewType, BinaryIO, NamedTuple
 
 #logging.basicConfig(level=logging.INFO)
 
@@ -68,6 +71,15 @@
     ('dependencies', List[BootstrapDep]),
 ])
 
+FetchInfo = NamedTuple('FetchInfo', [
+    ('url', str),
+    ('sha256', SHA256Hash)
+])
+
+FetchPlan = Dict[Path, FetchInfo]
+
+local_packages: List[PackageName] = ["Cabal-syntax", "Cabal", "cabal-install-solver", "cabal-install"]
+
 class Compiler:
     def __init__(self, ghc_path: Path):
         if not ghc_path.is_file():
@@ -75,14 +87,17 @@
 
         self.ghc_path = ghc_path.resolve()
 
+        exe = ''
+        if platform.system() == 'Windows': exe = '.exe'
+
         info = self._get_ghc_info()
         self.version = info['Project version']
         #self.lib_dir = Path(info['LibDir'])
         #self.ghc_pkg_path = (self.lib_dir / 'bin' / 'ghc-pkg').resolve()
-        self.ghc_pkg_path = (self.ghc_path.parent / 'ghc-pkg').resolve()
+        self.ghc_pkg_path = (self.ghc_path.parent / ('ghc-pkg' + exe)).resolve()
         if not self.ghc_pkg_path.is_file():
             raise TypeError(f'ghc-pkg {self.ghc_pkg_path} is not a file')
-        self.hsc2hs_path = (self.ghc_path.parent / 'hsc2hs').resolve()
+        self.hsc2hs_path = (self.ghc_path.parent / ('hsc2hs' + exe)).resolve()
         if not self.hsc2hs_path.is_file():
             raise TypeError(f'hsc2hs {self.hsc2hs_path} is not a file')
 
@@ -118,36 +133,6 @@
     if h != expected_hash:
         raise BadTarball(f, expected_hash, h)
 
-def fetch_package(package: PackageName,
-                  version: Version,
-                  src_sha256: SHA256Hash,
-                  revision: Optional[int],
-                  cabal_sha256: Optional[SHA256Hash],
-                  ) -> (Path, Path):
-    import urllib.request
-
-    # Download source distribution
-    tarball = TARBALLS / f'{package}-{version}.tar.gz'
-    if not tarball.exists():
-        print(f'Fetching {package}-{version}...')
-        tarball.parent.mkdir(parents=True, exist_ok=True)
-        url = package_url(package, version)
-        with urllib.request.urlopen(url) as resp:
-            shutil.copyfileobj(resp, tarball.open('wb'))
-
-    verify_sha256(src_sha256, tarball)
-
-    # Download revised cabal file
-    cabal_file = TARBALLS / f'{package}.cabal'
-    if revision is not None and not cabal_file.exists():
-        assert cabal_sha256 is not None
-        url = package_cabal_url(package, version, revision)
-        with urllib.request.urlopen(url) as resp:
-            shutil.copyfileobj(resp, cabal_file.open('wb'))
-            verify_sha256(cabal_sha256, cabal_file)
-
-    return (tarball, cabal_file)
-
 def read_bootstrap_info(path: Path) -> BootstrapInfo:
     obj = json.load(path.open())
 
@@ -169,13 +154,15 @@
     print(f'Using {dep.package}-{dep.version} from GHC...')
     return
 
-def install_dep(dep: BootstrapDep, ghc: Compiler) -> None:
-    dist_dir = (DISTDIR / f'{dep.package}-{dep.version}').resolve()
-
+def resolve_dep(dep : BootstrapDep) -> Path:
     if dep.source == PackageSource.HACKAGE:
-        assert dep.src_sha256 is not None
-        (tarball, cabal_file) = fetch_package(dep.package, dep.version, dep.src_sha256,
-                                dep.revision, dep.cabal_sha256)
+
+        tarball = TARBALLS / f'{dep.package}-{dep.version}.tar.gz'
+        verify_sha256(dep.src_sha256, tarball)
+
+        cabal_file = TARBALLS / f'{dep.package}.cabal'
+        verify_sha256(dep.cabal_sha256, cabal_file)
+
         UNPACKED.mkdir(parents=True, exist_ok=True)
         shutil.unpack_archive(tarball.resolve(), UNPACKED, 'gztar')
         sdist_dir = UNPACKED / f'{dep.package}-{dep.version}'
@@ -191,17 +178,17 @@
                 f.write('main = defaultMain\n')
 
     elif dep.source == PackageSource.LOCAL:
-        if dep.package == 'Cabal':
-            sdist_dir = Path('Cabal').resolve()
-        elif dep.package == 'Cabal-syntax':
-            sdist_dir = Path('Cabal-syntax').resolve()
-        elif dep.package == 'cabal-install-solver':
-            sdist_dir = Path('cabal-install-solver').resolve()
-        elif dep.package == 'cabal-install':
-            sdist_dir = Path('cabal-install').resolve()
+        if dep.package in local_packages:
+            sdist_dir = Path(dep.package).resolve()
         else:
             raise ValueError(f'Unknown local package {dep.package}')
+    return sdist_dir
 
+def install_dep(dep: BootstrapDep, ghc: Compiler) -> None:
+    dist_dir = (DISTDIR / f'{dep.package}-{dep.version}').resolve()
+
+    sdist_dir = resolve_dep(dep)
+
     install_sdist(dist_dir, sdist_dir, ghc, dep.flags)
 
 def install_sdist(dist_dir: Path, sdist_dir: Path, ghc: Compiler, flags: List[str]):
@@ -307,7 +294,7 @@
 
     return f'cabal-install-{cabalversion}-{machine}-{version}'
 
-def make_archive(cabal_path):
+def make_distribution_archive(cabal_path):
     import tempfile
 
     print(f'Creating distribution tarball')
@@ -334,55 +321,145 @@
 
     return archivename
 
+def fetch_from_plan(plan : FetchPlan, output_dir : Path):
+  output_dir.resolve()
+  output_dir.mkdir(parents=True, exist_ok=True)
+
+  for path in plan:
+    output_path = output_dir / path
+    url = plan[path].url
+    sha = plan[path].sha256
+    if not output_path.exists():
+      print(f'Fetching {url}...')
+      with urllib.request.urlopen(url, timeout = 10) as resp:
+        shutil.copyfileobj(resp, output_path.open('wb'))
+    verify_sha256(sha, output_path)
+
+def gen_fetch_plan(info : BootstrapInfo) -> FetchPlan :
+    sources_dict = {}
+    for dep in info.dependencies:
+      if not(dep.package in local_packages):
+        sources_dict[f"{dep.package}-{dep.version}.tar.gz"] = FetchInfo(package_url(dep.package, dep.version), dep.src_sha256)
+        if dep.revision is not None:
+          sources_dict[f"{dep.package}.cabal"] = FetchInfo(package_cabal_url(dep.package, dep.version, dep.revision), dep.cabal_sha256)
+    return sources_dict
+
+def find_ghc(compiler) -> Compiler:
+  if compiler is None:
+      path = shutil.which('ghc')
+      if path is None:
+          raise ValueError("Couldn't find ghc in PATH")
+      ghc = Compiler(Path(path))
+  else:
+      ghc = Compiler(compiler)
+  return ghc
+
 def main() -> None:
-    import argparse
     parser = argparse.ArgumentParser(
         description="bootstrapping utility for cabal-install.",
         epilog = USAGE,
         formatter_class = argparse.RawDescriptionHelpFormatter)
-    parser.add_argument('-d', '--deps', type=Path, default='bootstrap-deps.json',
+    parser.add_argument('-d', '--deps', type=Path,
                         help='bootstrap dependency file')
     parser.add_argument('-w', '--with-compiler', type=Path,
                         help='path to GHC')
-    args = parser.parse_args()
+    parser.add_argument('-s', '--bootstrap-sources', type=Path,
+                        help='path to prefetched bootstrap sources archive')
+    parser.add_argument('--archive', dest='want_archive', action='store_true')
+    parser.add_argument('--no-archive', dest='want_archive', action='store_false')
+    parser.set_defaults(want_archive=True)
 
-    # Find compiler
-    if args.with_compiler is None:
-        path = shutil.which('ghc')
-        if path is None:
-            raise ValueError("Couldn't find ghc in PATH")
-        ghc = Compiler(Path(path))
-    else:
-        ghc = Compiler(args.with_compiler)
+    subparsers = parser.add_subparsers(dest="command")
 
-    print(f'Bootstrapping cabal-install with GHC {ghc.version} at {ghc.ghc_path}...')
+    parser_fetch = subparsers.add_parser('build', help='build cabal-install (default)')
 
+    parser_fetch = subparsers.add_parser('fetch', help='fetch all required sources from Hackage (for offline builds)')
+    parser_fetch.add_argument('-o','--output', type=Path, default='bootstrap-sources')
+
+    args = parser.parse_args()
+
     print(dedent("""
         DO NOT use this script if you have another recent cabal-install available.
         This script is intended only for bootstrapping cabal-install on new
         architectures.
     """))
 
+    ghc = find_ghc(args.with_compiler)
+
+    sources_fmt = 'gztar'
+    if platform.system() == 'Windows': sources_fmt = 'zip'
+
+    if args.deps is None:
+      # We have a tarball with all the required information, unpack it
+      if args.bootstrap_sources is not None:
+        print(f'Unpacking {args.bootstrap_sources} to {TARBALLS}')
+        shutil.unpack_archive(args.bootstrap_sources.resolve(), TARBALLS, sources_fmt)
+        args.deps = TARBALLS / 'plan-bootstrap.json'
+        print(f"using plan-bootstrap.json ({args.deps}) from {args.bootstrap_sources}")
+      else:
+        print("The bootstrap script requires a bootstrap plan JSON file.")
+        print("See bootstrap/README.md for more information.")
+        sys.exit(1)
+
     info = read_bootstrap_info(args.deps)
-    bootstrap(info, ghc)
-    cabal_path = (BINDIR / 'cabal').resolve()
 
-    archive = make_archive(cabal_path)
+    if args.command == 'fetch':
+        plan = gen_fetch_plan(info)
 
-    print(dedent(f'''
-        Bootstrapping finished!
+        print(f'Fetching sources to bootstrap cabal-install with GHC {ghc.version} at {ghc.ghc_path}...')
 
-        The resulting cabal-install executable can be found at
+        # In temporary directory, create a directory which we will archive
+        tmpdir = TMPDIR.resolve()
+        tmpdir.mkdir(parents=True, exist_ok=True)
 
-            {cabal_path}
+        rootdir = Path(tempfile.mkdtemp(dir=tmpdir))
 
-        It have been archived for distribution in
+        fetch_from_plan(plan, rootdir)
 
-            {archive}
+        shutil.copyfile(args.deps, rootdir / 'plan-bootstrap.json')
 
-        You now should use this to build a full cabal-install distribution
-        using v2-build.
-    '''))
+        archivename = shutil.make_archive(args.output, sources_fmt, root_dir=rootdir)
+
+        print(dedent(f"""
+            Bootstrap sources saved to {archivename}
+
+            Use these with the command:
+
+            bootstrap.py -w {ghc.ghc_path} -s {archivename}
+            """))
+
+    else: # 'build' command (default behaviour)
+
+        print(f'Bootstrapping cabal-install with GHC {ghc.version} at {ghc.ghc_path}...')
+
+        if args.bootstrap_sources is None:
+          plan = gen_fetch_plan(info)
+          fetch_from_plan(plan, TARBALLS)
+
+        bootstrap(info, ghc)
+        cabal_path = (BINDIR / 'cabal').resolve()
+
+        print(dedent(f'''
+            Bootstrapping finished!
+
+            The resulting cabal-install executable can be found at
+
+              {cabal_path}
+            '''))
+
+        if args.want_archive:
+            dist_archive = make_distribution_archive(cabal_path)
+
+            print(dedent(f'''
+                The cabal-install executable has been archived for distribution in
+
+                  {dist_archive}
+                '''))
+
+        print(dedent(f'''
+            You now should use this to build a full cabal-install distribution
+            using v2-build.
+            '''))
 
 def subprocess_run(args, **kwargs):
     "Like subprocess.run, but also print what we run"
diff --git a/cabal/bootstrap/cabal-bootstrap-gen.cabal b/cabal/bootstrap/cabal-bootstrap-gen.cabal
--- a/cabal/bootstrap/cabal-bootstrap-gen.cabal
+++ b/cabal/bootstrap/cabal-bootstrap-gen.cabal
@@ -8,13 +8,14 @@
   ghc-options:      -Wall
   main-is:          Main.hs
   build-depends:
-    , aeson                  ^>=1.5.2.0
-    , base                   ^>=4.12.0.0 || ^>=4.13.0.0 || ^>=4.14.0.0
-    , bytestring             ^>=0.10.8.2 || ^>= 0.11.0.0
-    , Cabal                  ^>=3.2.0.0
-    , cabal-install-parsers  ^>=0.3.0.1
+    , aeson                  ^>=1.5.2.0  || ^>=2.0.3.0 || ^>=2.1.0.0
+    , base                   ^>=4.12.0.0 || ^>=4.13.0.0 || ^>=4.14.0.0 || ^>=4.15.0.0 || ^>=4.16.0.0 || ^>=4.17.0.0
+    , bytestring             ^>=0.10.8.2 || ^>=0.11.0.0
+    , Cabal                  ^>=3.8.1.0 || ^>=3.10.3
+    , Cabal-syntax           ^>=3.8.1.0 || ^>=3.10.2.0
+    , cabal-install-parsers  ^>=0.3.0.1  || ^>=0.4.5 || ^>=0.6
     , cabal-plan             ^>=0.7.0.0
     , containers             ^>=0.6.0.1
-    , text                   ^>=1.2.3.0
+    , text                   ^>=1.2.3.0  || ^>=2.0.1
     , topograph              ^>=1.0.0.1
-    , transformers           ^>=0.5.6.2
+    , transformers           ^>=0.5.6.2  || ^>=0.6.0.4
diff --git a/cabal/bootstrap/linux-8.10.7.json b/cabal/bootstrap/linux-8.10.7.json
--- a/cabal/bootstrap/linux-8.10.7.json
+++ b/cabal/bootstrap/linux-8.10.7.json
@@ -1,65 +1,158 @@
 {
+    "builtin": [
+        {
+            "package": "rts",
+            "version": "1.0.1"
+        },
+        {
+            "package": "ghc-prim",
+            "version": "0.6.1"
+        },
+        {
+            "package": "integer-gmp",
+            "version": "1.0.3.0"
+        },
+        {
+            "package": "base",
+            "version": "4.14.3.0"
+        },
+        {
+            "package": "array",
+            "version": "0.5.4.0"
+        },
+        {
+            "package": "deepseq",
+            "version": "1.4.4.0"
+        },
+        {
+            "package": "bytestring",
+            "version": "0.10.12.0"
+        },
+        {
+            "package": "containers",
+            "version": "0.6.5.1"
+        },
+        {
+            "package": "binary",
+            "version": "0.8.8.0"
+        },
+        {
+            "package": "filepath",
+            "version": "1.4.2.1"
+        },
+        {
+            "package": "time",
+            "version": "1.9.3"
+        },
+        {
+            "package": "unix",
+            "version": "2.7.2.2"
+        },
+        {
+            "package": "transformers",
+            "version": "0.5.6.2"
+        },
+        {
+            "package": "mtl",
+            "version": "2.2.2"
+        },
+        {
+            "package": "ghc-boot-th",
+            "version": "8.10.7"
+        },
+        {
+            "package": "pretty",
+            "version": "1.1.3.6"
+        },
+        {
+            "package": "template-haskell",
+            "version": "2.16.0.0"
+        },
+        {
+            "package": "text",
+            "version": "1.2.4.1"
+        },
+        {
+            "package": "parsec",
+            "version": "3.1.14.0"
+        },
+        {
+            "package": "stm",
+            "version": "2.5.0.1"
+        },
+        {
+            "package": "exceptions",
+            "version": "0.10.4"
+        }
+    ],
     "dependencies": [
         {
+            "cabal_sha256": "7d16bf127fb303bd69d9c433bb146c5815f9690933af1d5a6ee45dea2e536dc5",
+            "flags": [],
+            "package": "directory",
+            "revision": 1,
+            "source": "hackage",
+            "src_sha256": "dc2785d6548cec2e80700fab007d3e9467f65d3c58ab3efa21b34d9017cf0efd",
+            "version": "1.3.7.1"
+        },
+        {
             "cabal_sha256": null,
-            "revision": null,
-            "src_sha256": null,
             "flags": [],
             "package": "Cabal-syntax",
+            "revision": null,
             "source": "local",
-            "version": "3.8.1.0"
+            "src_sha256": null,
+            "version": "3.10.3.0"
         },
         {
-            "cabal_sha256": "04df32d9497add5f0b90a27a3eceffa4bad5c2f41d038bd12ed6efc454db3faf",
-            "revision": 0,
-            "src_sha256": "44b31b6cd3129893ac1a007573dedb69dde667fa06ee108526d58f08b1a1f7ab",
+            "cabal_sha256": "8b4bce2749e4f61a440049e6088487003e8023c720e2019345e399d50888594f",
             "flags": [],
             "package": "process",
+            "revision": 2,
             "source": "hackage",
-            "version": "1.6.15.0"
+            "src_sha256": "aa5f4c4fe4974f89f5ab998c7509daa4bda3926cfb06daacd5eba892aad8a37e",
+            "version": "1.6.18.0"
         },
         {
             "cabal_sha256": null,
-            "revision": null,
-            "src_sha256": null,
             "flags": [],
             "package": "Cabal",
+            "revision": null,
             "source": "local",
-            "version": "3.8.1.0"
+            "src_sha256": null,
+            "version": "3.10.3.0"
         },
         {
-            "cabal_sha256": "e3d78b13db9512aeb106e44a334ab42b7aa48d26c097299084084cb8be5c5568",
-            "revision": 0,
-            "src_sha256": "7f7620fef1a1af3d3d6747f510e73223a5c600e7d7fd9ace073d1222bdc63d85",
+            "cabal_sha256": "e152cdb03243afb52bbc740cfbe96905ca298a6f6342f0c47b3f2e227ff19def",
             "flags": [
                 "-devel"
             ],
             "package": "network",
+            "revision": 1,
             "source": "hackage",
-            "version": "3.1.2.7"
+            "src_sha256": "b452a2afac95d9207357eb3820c719c7c7d27871ef4b6ed7bfcd03a036b9158e",
+            "version": "3.1.4.0"
         },
         {
-            "cabal_sha256": "f65819f74c6ced42b24d9e5053165508c4b6a18271c8e3229dc93b1dc8f7a5ab",
-            "revision": 1,
-            "src_sha256": "6b5059caf6714f47da92953badf2f556119877e09708c14e206b3ae98b8681c6",
+            "cabal_sha256": "f5f2c679ecc1c1b83d2d68db6cc564e5c78d53425e69e1b9e36784820e122d37",
             "flags": [],
             "package": "th-compat",
+            "revision": 4,
             "source": "hackage",
-            "version": "0.1.3"
+            "src_sha256": "d8f97ac14ab47b6b8a7b0fdb4ff95426322ec56badd01652ac15da4a44d4bab8",
+            "version": "0.1.4"
         },
         {
-            "cabal_sha256": "a4765164ed0a2d1668446eb2e03460ce98645fbf083598c690846af79b7de10d",
-            "revision": 0,
-            "src_sha256": "57856db93608a4d419f681b881c9b8d4448800d5a687587dc37e8a9e0b223584",
+            "cabal_sha256": "6fffb57373962b5651a2db8b0af732098b3bf029a7ced76a9855615de2026588",
             "flags": [],
             "package": "network-uri",
+            "revision": 1,
             "source": "hackage",
-            "version": "2.6.4.1"
+            "src_sha256": "9c188973126e893250b881f20e8811dca06c223c23402b06f7a1f2e995797228",
+            "version": "2.6.4.2"
         },
         {
-            "cabal_sha256": "16ee1212245c6e7cf0905b039689b55dbe8386a2b450094055e536d30c89ba76",
-            "revision": 0,
-            "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453",
+            "cabal_sha256": "0e37572590743e49d7a610f472e1618a594dc861410846f64d9f2347923c4f5b",
             "flags": [
                 "-conduit10",
                 "+network-uri",
@@ -67,129 +160,137 @@
                 "-warp-tests"
             ],
             "package": "HTTP",
+            "revision": 3,
             "source": "hackage",
+            "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453",
             "version": "4000.4.1"
         },
         {
-            "cabal_sha256": "eb6758d0160d607e0c45dbd6b196f515b9a589fd4f6d2f926929dd5d56282d37",
-            "revision": 0,
-            "src_sha256": "20a21c4b7adb0fd844b25e196241467406a28286b021f9b7a082ab03fa8015eb",
+            "cabal_sha256": "c4733d09f798fc4304e936924a1a7d9fc2425aefad6c46ad4592035254b46051",
             "flags": [],
             "package": "base-orphans",
+            "revision": 0,
             "source": "hackage",
-            "version": "0.8.6"
+            "src_sha256": "5bbf2da382c5b212d6a8be2f8c49edee0eba30f272a15fd32c13e6e4091ef172",
+            "version": "0.9.1"
         },
         {
-            "cabal_sha256": "0cddd0229d1aac305ea0404409c0bbfab81f075817bd74b8b2929eff58333e55",
-            "revision": 0,
-            "src_sha256": "83606edd356d914c075ecd44f6d5fe91a3b186aa0683c8dd8c9a7e8e22a47600",
+            "cabal_sha256": "ad89e28b2b046175698fbf542af2ce43e5d2af50aae9f48d12566b1bb3de1d3c",
+            "flags": [],
+            "package": "data-array-byte",
+            "revision": 2,
+            "source": "hackage",
+            "src_sha256": "1bb6eca0b3e02d057fe7f4e14c81ef395216f421ab30fdaa1b18017c9c025600",
+            "version": "0.1.0.1"
+        },
+        {
+            "cabal_sha256": "f3bf68acfa0df7a064a378ef2cdcfeb55e6fb96100675f4c593556dcbf3d7194",
             "flags": [
-                "+containers",
                 "+integer-gmp",
                 "-random-initial-seed"
             ],
             "package": "hashable",
+            "revision": 1,
             "source": "hackage",
-            "version": "1.4.0.2"
+            "src_sha256": "32efb16c2891786209b7cbe5c39df9b3a9ae51e836f1a54f646bc4602b7ab0f5",
+            "version": "1.4.3.0"
         },
         {
-            "cabal_sha256": "b83dec34a53520de84c6dd3dc7aae45d22409b46eb471c478b98108215a370f0",
-            "revision": 1,
-            "src_sha256": "484df85be0e76c4fed9376451e48e1d0c6e97952ce79735b72d54297e7e0a725",
+            "cabal_sha256": "9b8ceefce014e490f9e1335fa5f511161309926c55d01cec795016f4363b5d2d",
             "flags": [
                 "-bench"
             ],
             "package": "async",
+            "revision": 4,
             "source": "hackage",
+            "src_sha256": "484df85be0e76c4fed9376451e48e1d0c6e97952ce79735b72d54297e7e0a725",
             "version": "2.2.4"
         },
         {
-            "cabal_sha256": "64abad7816ab8cabed8489e29f807b3a6f828e0b2cec0eae404323d69d36df9a",
-            "revision": 0,
-            "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784",
+            "cabal_sha256": "a694e88f9ec9fc79f0b03f233d3fea592b68f70a34aac2ddb5bcaecb6562e2fd",
             "flags": [],
             "package": "base16-bytestring",
+            "revision": 1,
             "source": "hackage",
+            "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784",
             "version": "1.0.2.0"
         },
         {
-            "cabal_sha256": "50ec0e229255d4c45cbdd568da011311b8887f304b931564886016f4984334d8",
-            "revision": 0,
-            "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9",
+            "cabal_sha256": "45305ccf8914c66d385b518721472c7b8c858f1986945377f74f85c1e0d49803",
             "flags": [],
             "package": "base64-bytestring",
+            "revision": 1,
             "source": "hackage",
+            "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9",
             "version": "1.2.1.0"
         },
         {
-            "cabal_sha256": "714a55fd28d3e2533bd5b49e74f604ef8e5d7b06f249c8816f6c54aed431dcf1",
-            "revision": 0,
-            "src_sha256": "6d065402394e7a9117093dbb4530a21342c9b1e2ec509516c8a8d0ffed98ecaa",
+            "cabal_sha256": "bac0ae8d46a04e410666b0c8081cff63f060f29157983b569ca86ddb6e6e0dc6",
             "flags": [
                 "-optimised-mixer"
             ],
             "package": "splitmix",
+            "revision": 0,
             "source": "hackage",
-            "version": "0.1.0.4"
+            "src_sha256": "9df07a9611ef45f1b1258a0b412f4d02c920248f69d2e2ce8ccda328f7e13002",
+            "version": "0.1.0.5"
         },
         {
-            "cabal_sha256": "dea1f11e5569332dc6c8efaad1cb301016a5587b6754943a49f9de08ae0e56d9",
-            "revision": 0,
-            "src_sha256": "3e1272f7ed6a4d7bd1712b90143ec326fee9b225789222379fea20a9c90c9b76",
+            "cabal_sha256": "e7c1f881159d5cc788619c9ee8b8f340ba2ff0db571cdf3d1a1968ebc5108789",
             "flags": [],
             "package": "random",
+            "revision": 1,
             "source": "hackage",
+            "src_sha256": "3e1272f7ed6a4d7bd1712b90143ec326fee9b225789222379fea20a9c90c9b76",
             "version": "1.2.1.1"
         },
         {
             "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee",
-            "revision": 1,
-            "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a",
             "flags": [],
             "package": "edit-distance",
+            "revision": 1,
             "source": "hackage",
+            "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a",
             "version": "0.2.2.1"
         },
         {
             "cabal_sha256": null,
-            "revision": null,
-            "src_sha256": null,
             "flags": [
                 "-debug-conflict-sets",
                 "-debug-expensive-assertions",
                 "-debug-tracetree"
             ],
             "package": "cabal-install-solver",
+            "revision": null,
             "source": "local",
-            "version": "3.8.1.0"
+            "src_sha256": null,
+            "version": "3.10.3.0"
         },
         {
-            "cabal_sha256": "188d0b5a0491e8b686b32d9b144c9287760ba333d2509bf3f17e3d846fbc2332",
-            "revision": 0,
-            "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6",
+            "cabal_sha256": "03db065161987f614a3a2bbcd16264f78e47efe231fb5bd161be2043eaf20488",
             "flags": [
                 "-exe",
                 "+use-cbits"
             ],
             "package": "cryptohash-sha256",
+            "revision": 3,
             "source": "hackage",
+            "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6",
             "version": "0.11.102.1"
         },
         {
             "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42",
-            "revision": 0,
-            "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43",
             "flags": [
                 "-example"
             ],
             "package": "echo",
+            "revision": 0,
             "source": "hackage",
+            "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43",
             "version": "0.1.4"
         },
         {
-            "cabal_sha256": "24ac7b5f3d9fa3c2f70262b329f2a75f24e7fd829f88c189b388efa1bcd67eb2",
-            "revision": 5,
-            "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d",
+            "cabal_sha256": "48383789821af5cc624498f3ee1d0939a070cda9468c0bfe63c951736be81c75",
             "flags": [
                 "+no-donna",
                 "+test-doctests",
@@ -197,49 +298,49 @@
                 "+test-properties"
             ],
             "package": "ed25519",
+            "revision": 8,
             "source": "hackage",
+            "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d",
             "version": "0.0.5.0"
         },
         {
-            "cabal_sha256": "c084c043a40632d3cafcac50fb5eeff84d91edb070a54baa94945f1c976f97c0",
-            "revision": 2,
-            "src_sha256": "a80efb60cfa3dae18682c01980d76d5f7e413e191cd186992e1bf7388d48ab1f",
+            "cabal_sha256": "17786545dce60c4d5783ba6125c0a6499a1abddd3d7417b15500ccd767c35f07",
             "flags": [
                 "+ofd-locking"
             ],
             "package": "lukko",
+            "revision": 5,
             "source": "hackage",
+            "src_sha256": "a80efb60cfa3dae18682c01980d76d5f7e413e191cd186992e1bf7388d48ab1f",
             "version": "0.1.1.3"
         },
         {
-            "cabal_sha256": "bc14969ea4adfec6eee20264decf4a07c4002b38b2aa802d58d86b1a2cf7b895",
-            "revision": 5,
-            "src_sha256": "b384449f62b2b0aa3e6d2cb1004b8060b01f21ec93e7b63e7af6d8fad8a9f1de",
+            "cabal_sha256": "aaf5dd3ef327aaf203b1cb199760efd463fac2256453dd0e05d5cd707cdbd6e1",
             "flags": [
                 "-old-bytestring",
                 "-old-time"
             ],
             "package": "tar",
+            "revision": 10,
             "source": "hackage",
+            "src_sha256": "b384449f62b2b0aa3e6d2cb1004b8060b01f21ec93e7b63e7af6d8fad8a9f1de",
             "version": "0.5.1.1"
         },
         {
-            "cabal_sha256": "8214a9d37580f17f8b675109578a5dbe6853559eef156e34dc2233f1123ace33",
-            "revision": 0,
-            "src_sha256": "9eaa989ad4534438b5beb51c1d3a4c8f6a088fdff0b259a5394fbf39aaee04da",
+            "cabal_sha256": "19eb7759af71957811d5ec10ddb1e2f4c98700ddb9c0da6860c0441d811f0e6d",
             "flags": [
                 "-bundled-c-zlib",
                 "-non-blocking-ffi",
                 "-pkg-config"
             ],
             "package": "zlib",
+            "revision": 4,
             "source": "hackage",
+            "src_sha256": "9eaa989ad4534438b5beb51c1d3a4c8f6a088fdff0b259a5394fbf39aaee04da",
             "version": "0.6.3.0"
         },
         {
-            "cabal_sha256": "1d4b292bd90970f7ef52c72f2ae365f88bd2c6a75627dc34a31d24bc8f53f2e4",
-            "revision": 2,
-            "src_sha256": "bf22cd16dde7d6b7130463f4d7324b64a2964d9ef3f523df97d7cb98544d64a8",
+            "cabal_sha256": "2b2e560ac449e49f86a10d79957b2409da5be4b77edabd7425696780334cf3bf",
             "flags": [
                 "+base48",
                 "+cabal-syntax",
@@ -249,148 +350,60 @@
                 "+use-network-uri"
             ],
             "package": "hackage-security",
+            "revision": 8,
             "source": "hackage",
-            "version": "0.6.2.1"
+            "src_sha256": "52ee0576971955571d846b8e6c09638f89f4f7881f4a95173e44ccc0d856a066",
+            "version": "0.6.2.3"
         },
         {
-            "cabal_sha256": "4ff4425c710cddf440dfbac6cd52310bb6b23e17902390ff71c9fc7eaafc4fcc",
-            "revision": 1,
-            "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1",
+            "cabal_sha256": "0322b2fcd1358f3355e0c8608efa60d27b14d1c9d476451dbcb9181363bd8b27",
             "flags": [],
             "package": "regex-base",
+            "revision": 4,
             "source": "hackage",
+            "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1",
             "version": "0.94.0.2"
         },
         {
-            "cabal_sha256": "9dbba4b65a3bb6975d9740814be5593c6b2d2d6a0b3febc8ec940edb9a9bbdf4",
-            "revision": 1,
-            "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c",
+            "cabal_sha256": "816d6acc560cb86672f347a7bef8129578dde26ed760f9e79b4976ed9bd7b9fd",
             "flags": [
                 "-_regex-posix-clib"
             ],
             "package": "regex-posix",
+            "revision": 3,
             "source": "hackage",
+            "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c",
             "version": "0.96.0.1"
         },
         {
-            "cabal_sha256": "2088eb9368b920f80bbe4e3b03c3b8484090208f5c3b31645bd67a9ef7d26db4",
-            "revision": 4,
-            "src_sha256": "81a2bafad484db123cf8d17a02d98bb388a127fd0f822fa022589468a0e64671",
+            "cabal_sha256": "4868265ab5760d2fdeb96625b138c8df25d41b9ee2651fa299ed019a69403045",
             "flags": [],
             "package": "resolv",
+            "revision": 3,
             "source": "hackage",
-            "version": "0.1.2.0"
+            "src_sha256": "880d283df9132a7375fa28670f71e86480a4f49972256dc2a204c648274ae74b",
+            "version": "0.2.0.2"
         },
         {
-            "cabal_sha256": "6e9b1b233af80cc0aa17ea858d2641ba146fb11cbcc5970a52649e89d77282e2",
-            "revision": 0,
-            "src_sha256": "91ce28d8f8a6efd31788d4827ed5cdcb9a546ad4053a86c56f7947c66a30b5bf",
+            "cabal_sha256": "8bb7261bd54bd58acfcb154be6a161fb6d0d31a1852aadc8e927d2ad2d7651d1",
             "flags": [],
             "package": "safe-exceptions",
+            "revision": 1,
             "source": "hackage",
-            "version": "0.1.7.3"
+            "src_sha256": "3c51d8d50c9b60ff8bf94f942fd92e3bea9e62c5afa778dfc9f707b79da41ef6",
+            "version": "0.1.7.4"
         },
         {
             "cabal_sha256": null,
-            "revision": null,
-            "src_sha256": null,
             "flags": [
                 "+lukko",
                 "+native-dns"
             ],
             "package": "cabal-install",
+            "revision": null,
             "source": "local",
-            "version": "3.8.1.0"
-        }
-    ],
-    "builtin": [
-        {
-            "package": "rts",
-            "version": "1.0.1"
-        },
-        {
-            "package": "ghc-prim",
-            "version": "0.6.1"
-        },
-        {
-            "package": "integer-gmp",
-            "version": "1.0.3.0"
-        },
-        {
-            "package": "base",
-            "version": "4.14.3.0"
-        },
-        {
-            "package": "array",
-            "version": "0.5.4.0"
-        },
-        {
-            "package": "deepseq",
-            "version": "1.4.4.0"
-        },
-        {
-            "package": "bytestring",
-            "version": "0.10.12.0"
-        },
-        {
-            "package": "containers",
-            "version": "0.6.5.1"
-        },
-        {
-            "package": "binary",
-            "version": "0.8.8.0"
-        },
-        {
-            "package": "filepath",
-            "version": "1.4.2.1"
-        },
-        {
-            "package": "time",
-            "version": "1.9.3"
-        },
-        {
-            "package": "unix",
-            "version": "2.7.2.2"
-        },
-        {
-            "package": "directory",
-            "version": "1.3.6.0"
-        },
-        {
-            "package": "transformers",
-            "version": "0.5.6.2"
-        },
-        {
-            "package": "mtl",
-            "version": "2.2.2"
-        },
-        {
-            "package": "ghc-boot-th",
-            "version": "8.10.7"
-        },
-        {
-            "package": "pretty",
-            "version": "1.1.3.6"
-        },
-        {
-            "package": "template-haskell",
-            "version": "2.16.0.0"
-        },
-        {
-            "package": "text",
-            "version": "1.2.4.1"
-        },
-        {
-            "package": "parsec",
-            "version": "3.1.14.0"
-        },
-        {
-            "package": "stm",
-            "version": "2.5.0.1"
-        },
-        {
-            "package": "exceptions",
-            "version": "0.10.4"
+            "src_sha256": null,
+            "version": "3.10.3.0"
         }
     ]
 }
diff --git a/cabal/bootstrap/linux-8.6.5.json b/cabal/bootstrap/linux-8.6.5.json
deleted file mode 100644
--- a/cabal/bootstrap/linux-8.6.5.json
+++ /dev/null
@@ -1,403 +0,0 @@
-{
-    "dependencies": [
-        {
-            "cabal_sha256": null,
-            "revision": null,
-            "src_sha256": null,
-            "flags": [],
-            "package": "Cabal-syntax",
-            "source": "local",
-            "version": "3.8.1.0"
-        },
-        {
-            "cabal_sha256": "04df32d9497add5f0b90a27a3eceffa4bad5c2f41d038bd12ed6efc454db3faf",
-            "revision": 0,
-            "src_sha256": "44b31b6cd3129893ac1a007573dedb69dde667fa06ee108526d58f08b1a1f7ab",
-            "flags": [],
-            "package": "process",
-            "source": "hackage",
-            "version": "1.6.15.0"
-        },
-        {
-            "cabal_sha256": null,
-            "revision": null,
-            "src_sha256": null,
-            "flags": [],
-            "package": "Cabal",
-            "source": "local",
-            "version": "3.8.1.0"
-        },
-        {
-            "cabal_sha256": "e3d78b13db9512aeb106e44a334ab42b7aa48d26c097299084084cb8be5c5568",
-            "revision": 0,
-            "src_sha256": "7f7620fef1a1af3d3d6747f510e73223a5c600e7d7fd9ace073d1222bdc63d85",
-            "flags": [
-                "-devel"
-            ],
-            "package": "network",
-            "source": "hackage",
-            "version": "3.1.2.7"
-        },
-        {
-            "cabal_sha256": "f65819f74c6ced42b24d9e5053165508c4b6a18271c8e3229dc93b1dc8f7a5ab",
-            "revision": 1,
-            "src_sha256": "6b5059caf6714f47da92953badf2f556119877e09708c14e206b3ae98b8681c6",
-            "flags": [],
-            "package": "th-compat",
-            "source": "hackage",
-            "version": "0.1.3"
-        },
-        {
-            "cabal_sha256": "a4765164ed0a2d1668446eb2e03460ce98645fbf083598c690846af79b7de10d",
-            "revision": 0,
-            "src_sha256": "57856db93608a4d419f681b881c9b8d4448800d5a687587dc37e8a9e0b223584",
-            "flags": [],
-            "package": "network-uri",
-            "source": "hackage",
-            "version": "2.6.4.1"
-        },
-        {
-            "cabal_sha256": "16ee1212245c6e7cf0905b039689b55dbe8386a2b450094055e536d30c89ba76",
-            "revision": 0,
-            "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453",
-            "flags": [
-                "-conduit10",
-                "+network-uri",
-                "-warn-as-error",
-                "-warp-tests"
-            ],
-            "package": "HTTP",
-            "source": "hackage",
-            "version": "4000.4.1"
-        },
-        {
-            "cabal_sha256": "eb6758d0160d607e0c45dbd6b196f515b9a589fd4f6d2f926929dd5d56282d37",
-            "revision": 0,
-            "src_sha256": "20a21c4b7adb0fd844b25e196241467406a28286b021f9b7a082ab03fa8015eb",
-            "flags": [],
-            "package": "base-orphans",
-            "source": "hackage",
-            "version": "0.8.6"
-        },
-        {
-            "cabal_sha256": "0cddd0229d1aac305ea0404409c0bbfab81f075817bd74b8b2929eff58333e55",
-            "revision": 0,
-            "src_sha256": "83606edd356d914c075ecd44f6d5fe91a3b186aa0683c8dd8c9a7e8e22a47600",
-            "flags": [
-                "+containers",
-                "+integer-gmp",
-                "-random-initial-seed"
-            ],
-            "package": "hashable",
-            "source": "hackage",
-            "version": "1.4.0.2"
-        },
-        {
-            "cabal_sha256": "b83dec34a53520de84c6dd3dc7aae45d22409b46eb471c478b98108215a370f0",
-            "revision": 1,
-            "src_sha256": "484df85be0e76c4fed9376451e48e1d0c6e97952ce79735b72d54297e7e0a725",
-            "flags": [
-                "-bench"
-            ],
-            "package": "async",
-            "source": "hackage",
-            "version": "2.2.4"
-        },
-        {
-            "cabal_sha256": "64abad7816ab8cabed8489e29f807b3a6f828e0b2cec0eae404323d69d36df9a",
-            "revision": 0,
-            "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784",
-            "flags": [],
-            "package": "base16-bytestring",
-            "source": "hackage",
-            "version": "1.0.2.0"
-        },
-        {
-            "cabal_sha256": "50ec0e229255d4c45cbdd568da011311b8887f304b931564886016f4984334d8",
-            "revision": 0,
-            "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9",
-            "flags": [],
-            "package": "base64-bytestring",
-            "source": "hackage",
-            "version": "1.2.1.0"
-        },
-        {
-            "cabal_sha256": "714a55fd28d3e2533bd5b49e74f604ef8e5d7b06f249c8816f6c54aed431dcf1",
-            "revision": 0,
-            "src_sha256": "6d065402394e7a9117093dbb4530a21342c9b1e2ec509516c8a8d0ffed98ecaa",
-            "flags": [
-                "-optimised-mixer"
-            ],
-            "package": "splitmix",
-            "source": "hackage",
-            "version": "0.1.0.4"
-        },
-        {
-            "cabal_sha256": "dea1f11e5569332dc6c8efaad1cb301016a5587b6754943a49f9de08ae0e56d9",
-            "revision": 0,
-            "src_sha256": "3e1272f7ed6a4d7bd1712b90143ec326fee9b225789222379fea20a9c90c9b76",
-            "flags": [],
-            "package": "random",
-            "source": "hackage",
-            "version": "1.2.1.1"
-        },
-        {
-            "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee",
-            "revision": 1,
-            "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a",
-            "flags": [],
-            "package": "edit-distance",
-            "source": "hackage",
-            "version": "0.2.2.1"
-        },
-        {
-            "cabal_sha256": null,
-            "revision": null,
-            "src_sha256": null,
-            "flags": [
-                "-debug-conflict-sets",
-                "-debug-expensive-assertions",
-                "-debug-tracetree"
-            ],
-            "package": "cabal-install-solver",
-            "source": "local",
-            "version": "3.8.1.0"
-        },
-        {
-            "cabal_sha256": "188d0b5a0491e8b686b32d9b144c9287760ba333d2509bf3f17e3d846fbc2332",
-            "revision": 0,
-            "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6",
-            "flags": [
-                "-exe",
-                "+use-cbits"
-            ],
-            "package": "cryptohash-sha256",
-            "source": "hackage",
-            "version": "0.11.102.1"
-        },
-        {
-            "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42",
-            "revision": 0,
-            "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43",
-            "flags": [
-                "-example"
-            ],
-            "package": "echo",
-            "source": "hackage",
-            "version": "0.1.4"
-        },
-        {
-            "cabal_sha256": "b2c634a95ba2a68e0df3ae67d006f0dabb02edbe4dc77b321133551e308ca047",
-            "revision": 1,
-            "src_sha256": "66e3c0b4e2d32287621a3faab6b99c7e03b285a07711f335332aec6b4217bf8b",
-            "flags": [
-                "+transformers-0-4"
-            ],
-            "package": "exceptions",
-            "source": "hackage",
-            "version": "0.10.5"
-        },
-        {
-            "cabal_sha256": "24ac7b5f3d9fa3c2f70262b329f2a75f24e7fd829f88c189b388efa1bcd67eb2",
-            "revision": 5,
-            "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d",
-            "flags": [
-                "+no-donna",
-                "+test-doctests",
-                "+test-hlint",
-                "+test-properties"
-            ],
-            "package": "ed25519",
-            "source": "hackage",
-            "version": "0.0.5.0"
-        },
-        {
-            "cabal_sha256": "c084c043a40632d3cafcac50fb5eeff84d91edb070a54baa94945f1c976f97c0",
-            "revision": 2,
-            "src_sha256": "a80efb60cfa3dae18682c01980d76d5f7e413e191cd186992e1bf7388d48ab1f",
-            "flags": [
-                "+ofd-locking"
-            ],
-            "package": "lukko",
-            "source": "hackage",
-            "version": "0.1.1.3"
-        },
-        {
-            "cabal_sha256": "bc14969ea4adfec6eee20264decf4a07c4002b38b2aa802d58d86b1a2cf7b895",
-            "revision": 5,
-            "src_sha256": "b384449f62b2b0aa3e6d2cb1004b8060b01f21ec93e7b63e7af6d8fad8a9f1de",
-            "flags": [
-                "-old-bytestring",
-                "-old-time"
-            ],
-            "package": "tar",
-            "source": "hackage",
-            "version": "0.5.1.1"
-        },
-        {
-            "cabal_sha256": "8214a9d37580f17f8b675109578a5dbe6853559eef156e34dc2233f1123ace33",
-            "revision": 0,
-            "src_sha256": "9eaa989ad4534438b5beb51c1d3a4c8f6a088fdff0b259a5394fbf39aaee04da",
-            "flags": [
-                "-bundled-c-zlib",
-                "-non-blocking-ffi",
-                "-pkg-config"
-            ],
-            "package": "zlib",
-            "source": "hackage",
-            "version": "0.6.3.0"
-        },
-        {
-            "cabal_sha256": "1d4b292bd90970f7ef52c72f2ae365f88bd2c6a75627dc34a31d24bc8f53f2e4",
-            "revision": 2,
-            "src_sha256": "bf22cd16dde7d6b7130463f4d7324b64a2964d9ef3f523df97d7cb98544d64a8",
-            "flags": [
-                "+base48",
-                "+cabal-syntax",
-                "+lukko",
-                "-mtl21",
-                "-old-directory",
-                "+use-network-uri"
-            ],
-            "package": "hackage-security",
-            "source": "hackage",
-            "version": "0.6.2.1"
-        },
-        {
-            "cabal_sha256": "4ff4425c710cddf440dfbac6cd52310bb6b23e17902390ff71c9fc7eaafc4fcc",
-            "revision": 1,
-            "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1",
-            "flags": [],
-            "package": "regex-base",
-            "source": "hackage",
-            "version": "0.94.0.2"
-        },
-        {
-            "cabal_sha256": "9dbba4b65a3bb6975d9740814be5593c6b2d2d6a0b3febc8ec940edb9a9bbdf4",
-            "revision": 1,
-            "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c",
-            "flags": [
-                "-_regex-posix-clib"
-            ],
-            "package": "regex-posix",
-            "source": "hackage",
-            "version": "0.96.0.1"
-        },
-        {
-            "cabal_sha256": "2088eb9368b920f80bbe4e3b03c3b8484090208f5c3b31645bd67a9ef7d26db4",
-            "revision": 4,
-            "src_sha256": "81a2bafad484db123cf8d17a02d98bb388a127fd0f822fa022589468a0e64671",
-            "flags": [],
-            "package": "resolv",
-            "source": "hackage",
-            "version": "0.1.2.0"
-        },
-        {
-            "cabal_sha256": "6e9b1b233af80cc0aa17ea858d2641ba146fb11cbcc5970a52649e89d77282e2",
-            "revision": 0,
-            "src_sha256": "91ce28d8f8a6efd31788d4827ed5cdcb9a546ad4053a86c56f7947c66a30b5bf",
-            "flags": [],
-            "package": "safe-exceptions",
-            "source": "hackage",
-            "version": "0.1.7.3"
-        },
-        {
-            "cabal_sha256": null,
-            "revision": null,
-            "src_sha256": null,
-            "flags": [
-                "+lukko",
-                "+native-dns"
-            ],
-            "package": "cabal-install",
-            "source": "local",
-            "version": "3.8.1.0"
-        }
-    ],
-    "builtin": [
-        {
-            "package": "rts",
-            "version": "1.0"
-        },
-        {
-            "package": "ghc-prim",
-            "version": "0.5.3"
-        },
-        {
-            "package": "integer-gmp",
-            "version": "1.0.2.0"
-        },
-        {
-            "package": "base",
-            "version": "4.12.0.0"
-        },
-        {
-            "package": "array",
-            "version": "0.5.3.0"
-        },
-        {
-            "package": "deepseq",
-            "version": "1.4.4.0"
-        },
-        {
-            "package": "bytestring",
-            "version": "0.10.8.2"
-        },
-        {
-            "package": "containers",
-            "version": "0.6.0.1"
-        },
-        {
-            "package": "binary",
-            "version": "0.8.6.0"
-        },
-        {
-            "package": "filepath",
-            "version": "1.4.2.1"
-        },
-        {
-            "package": "time",
-            "version": "1.8.0.2"
-        },
-        {
-            "package": "unix",
-            "version": "2.7.2.2"
-        },
-        {
-            "package": "directory",
-            "version": "1.3.3.0"
-        },
-        {
-            "package": "transformers",
-            "version": "0.5.6.2"
-        },
-        {
-            "package": "mtl",
-            "version": "2.2.2"
-        },
-        {
-            "package": "text",
-            "version": "1.2.3.1"
-        },
-        {
-            "package": "parsec",
-            "version": "3.1.13.0"
-        },
-        {
-            "package": "pretty",
-            "version": "1.1.3.6"
-        },
-        {
-            "package": "ghc-boot-th",
-            "version": "8.6.5"
-        },
-        {
-            "package": "template-haskell",
-            "version": "2.14.0.0"
-        },
-        {
-            "package": "stm",
-            "version": "2.5.0.0"
-        }
-    ]
-}
diff --git a/cabal/bootstrap/linux-8.8.4.json b/cabal/bootstrap/linux-8.8.4.json
deleted file mode 100644
--- a/cabal/bootstrap/linux-8.8.4.json
+++ /dev/null
@@ -1,403 +0,0 @@
-{
-    "dependencies": [
-        {
-            "cabal_sha256": null,
-            "revision": null,
-            "src_sha256": null,
-            "flags": [],
-            "package": "Cabal-syntax",
-            "source": "local",
-            "version": "3.8.1.0"
-        },
-        {
-            "cabal_sha256": "04df32d9497add5f0b90a27a3eceffa4bad5c2f41d038bd12ed6efc454db3faf",
-            "revision": 0,
-            "src_sha256": "44b31b6cd3129893ac1a007573dedb69dde667fa06ee108526d58f08b1a1f7ab",
-            "flags": [],
-            "package": "process",
-            "source": "hackage",
-            "version": "1.6.15.0"
-        },
-        {
-            "cabal_sha256": null,
-            "revision": null,
-            "src_sha256": null,
-            "flags": [],
-            "package": "Cabal",
-            "source": "local",
-            "version": "3.8.1.0"
-        },
-        {
-            "cabal_sha256": "e3d78b13db9512aeb106e44a334ab42b7aa48d26c097299084084cb8be5c5568",
-            "revision": 0,
-            "src_sha256": "7f7620fef1a1af3d3d6747f510e73223a5c600e7d7fd9ace073d1222bdc63d85",
-            "flags": [
-                "-devel"
-            ],
-            "package": "network",
-            "source": "hackage",
-            "version": "3.1.2.7"
-        },
-        {
-            "cabal_sha256": "f65819f74c6ced42b24d9e5053165508c4b6a18271c8e3229dc93b1dc8f7a5ab",
-            "revision": 1,
-            "src_sha256": "6b5059caf6714f47da92953badf2f556119877e09708c14e206b3ae98b8681c6",
-            "flags": [],
-            "package": "th-compat",
-            "source": "hackage",
-            "version": "0.1.3"
-        },
-        {
-            "cabal_sha256": "a4765164ed0a2d1668446eb2e03460ce98645fbf083598c690846af79b7de10d",
-            "revision": 0,
-            "src_sha256": "57856db93608a4d419f681b881c9b8d4448800d5a687587dc37e8a9e0b223584",
-            "flags": [],
-            "package": "network-uri",
-            "source": "hackage",
-            "version": "2.6.4.1"
-        },
-        {
-            "cabal_sha256": "16ee1212245c6e7cf0905b039689b55dbe8386a2b450094055e536d30c89ba76",
-            "revision": 0,
-            "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453",
-            "flags": [
-                "-conduit10",
-                "+network-uri",
-                "-warn-as-error",
-                "-warp-tests"
-            ],
-            "package": "HTTP",
-            "source": "hackage",
-            "version": "4000.4.1"
-        },
-        {
-            "cabal_sha256": "eb6758d0160d607e0c45dbd6b196f515b9a589fd4f6d2f926929dd5d56282d37",
-            "revision": 0,
-            "src_sha256": "20a21c4b7adb0fd844b25e196241467406a28286b021f9b7a082ab03fa8015eb",
-            "flags": [],
-            "package": "base-orphans",
-            "source": "hackage",
-            "version": "0.8.6"
-        },
-        {
-            "cabal_sha256": "0cddd0229d1aac305ea0404409c0bbfab81f075817bd74b8b2929eff58333e55",
-            "revision": 0,
-            "src_sha256": "83606edd356d914c075ecd44f6d5fe91a3b186aa0683c8dd8c9a7e8e22a47600",
-            "flags": [
-                "+containers",
-                "+integer-gmp",
-                "-random-initial-seed"
-            ],
-            "package": "hashable",
-            "source": "hackage",
-            "version": "1.4.0.2"
-        },
-        {
-            "cabal_sha256": "b83dec34a53520de84c6dd3dc7aae45d22409b46eb471c478b98108215a370f0",
-            "revision": 1,
-            "src_sha256": "484df85be0e76c4fed9376451e48e1d0c6e97952ce79735b72d54297e7e0a725",
-            "flags": [
-                "-bench"
-            ],
-            "package": "async",
-            "source": "hackage",
-            "version": "2.2.4"
-        },
-        {
-            "cabal_sha256": "64abad7816ab8cabed8489e29f807b3a6f828e0b2cec0eae404323d69d36df9a",
-            "revision": 0,
-            "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784",
-            "flags": [],
-            "package": "base16-bytestring",
-            "source": "hackage",
-            "version": "1.0.2.0"
-        },
-        {
-            "cabal_sha256": "50ec0e229255d4c45cbdd568da011311b8887f304b931564886016f4984334d8",
-            "revision": 0,
-            "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9",
-            "flags": [],
-            "package": "base64-bytestring",
-            "source": "hackage",
-            "version": "1.2.1.0"
-        },
-        {
-            "cabal_sha256": "714a55fd28d3e2533bd5b49e74f604ef8e5d7b06f249c8816f6c54aed431dcf1",
-            "revision": 0,
-            "src_sha256": "6d065402394e7a9117093dbb4530a21342c9b1e2ec509516c8a8d0ffed98ecaa",
-            "flags": [
-                "-optimised-mixer"
-            ],
-            "package": "splitmix",
-            "source": "hackage",
-            "version": "0.1.0.4"
-        },
-        {
-            "cabal_sha256": "dea1f11e5569332dc6c8efaad1cb301016a5587b6754943a49f9de08ae0e56d9",
-            "revision": 0,
-            "src_sha256": "3e1272f7ed6a4d7bd1712b90143ec326fee9b225789222379fea20a9c90c9b76",
-            "flags": [],
-            "package": "random",
-            "source": "hackage",
-            "version": "1.2.1.1"
-        },
-        {
-            "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee",
-            "revision": 1,
-            "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a",
-            "flags": [],
-            "package": "edit-distance",
-            "source": "hackage",
-            "version": "0.2.2.1"
-        },
-        {
-            "cabal_sha256": null,
-            "revision": null,
-            "src_sha256": null,
-            "flags": [
-                "-debug-conflict-sets",
-                "-debug-expensive-assertions",
-                "-debug-tracetree"
-            ],
-            "package": "cabal-install-solver",
-            "source": "local",
-            "version": "3.8.1.0"
-        },
-        {
-            "cabal_sha256": "188d0b5a0491e8b686b32d9b144c9287760ba333d2509bf3f17e3d846fbc2332",
-            "revision": 0,
-            "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6",
-            "flags": [
-                "-exe",
-                "+use-cbits"
-            ],
-            "package": "cryptohash-sha256",
-            "source": "hackage",
-            "version": "0.11.102.1"
-        },
-        {
-            "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42",
-            "revision": 0,
-            "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43",
-            "flags": [
-                "-example"
-            ],
-            "package": "echo",
-            "source": "hackage",
-            "version": "0.1.4"
-        },
-        {
-            "cabal_sha256": "b2c634a95ba2a68e0df3ae67d006f0dabb02edbe4dc77b321133551e308ca047",
-            "revision": 1,
-            "src_sha256": "66e3c0b4e2d32287621a3faab6b99c7e03b285a07711f335332aec6b4217bf8b",
-            "flags": [
-                "+transformers-0-4"
-            ],
-            "package": "exceptions",
-            "source": "hackage",
-            "version": "0.10.5"
-        },
-        {
-            "cabal_sha256": "24ac7b5f3d9fa3c2f70262b329f2a75f24e7fd829f88c189b388efa1bcd67eb2",
-            "revision": 5,
-            "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d",
-            "flags": [
-                "+no-donna",
-                "+test-doctests",
-                "+test-hlint",
-                "+test-properties"
-            ],
-            "package": "ed25519",
-            "source": "hackage",
-            "version": "0.0.5.0"
-        },
-        {
-            "cabal_sha256": "c084c043a40632d3cafcac50fb5eeff84d91edb070a54baa94945f1c976f97c0",
-            "revision": 2,
-            "src_sha256": "a80efb60cfa3dae18682c01980d76d5f7e413e191cd186992e1bf7388d48ab1f",
-            "flags": [
-                "+ofd-locking"
-            ],
-            "package": "lukko",
-            "source": "hackage",
-            "version": "0.1.1.3"
-        },
-        {
-            "cabal_sha256": "bc14969ea4adfec6eee20264decf4a07c4002b38b2aa802d58d86b1a2cf7b895",
-            "revision": 5,
-            "src_sha256": "b384449f62b2b0aa3e6d2cb1004b8060b01f21ec93e7b63e7af6d8fad8a9f1de",
-            "flags": [
-                "-old-bytestring",
-                "-old-time"
-            ],
-            "package": "tar",
-            "source": "hackage",
-            "version": "0.5.1.1"
-        },
-        {
-            "cabal_sha256": "8214a9d37580f17f8b675109578a5dbe6853559eef156e34dc2233f1123ace33",
-            "revision": 0,
-            "src_sha256": "9eaa989ad4534438b5beb51c1d3a4c8f6a088fdff0b259a5394fbf39aaee04da",
-            "flags": [
-                "-bundled-c-zlib",
-                "-non-blocking-ffi",
-                "-pkg-config"
-            ],
-            "package": "zlib",
-            "source": "hackage",
-            "version": "0.6.3.0"
-        },
-        {
-            "cabal_sha256": "1d4b292bd90970f7ef52c72f2ae365f88bd2c6a75627dc34a31d24bc8f53f2e4",
-            "revision": 2,
-            "src_sha256": "bf22cd16dde7d6b7130463f4d7324b64a2964d9ef3f523df97d7cb98544d64a8",
-            "flags": [
-                "+base48",
-                "+cabal-syntax",
-                "+lukko",
-                "-mtl21",
-                "-old-directory",
-                "+use-network-uri"
-            ],
-            "package": "hackage-security",
-            "source": "hackage",
-            "version": "0.6.2.1"
-        },
-        {
-            "cabal_sha256": "4ff4425c710cddf440dfbac6cd52310bb6b23e17902390ff71c9fc7eaafc4fcc",
-            "revision": 1,
-            "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1",
-            "flags": [],
-            "package": "regex-base",
-            "source": "hackage",
-            "version": "0.94.0.2"
-        },
-        {
-            "cabal_sha256": "9dbba4b65a3bb6975d9740814be5593c6b2d2d6a0b3febc8ec940edb9a9bbdf4",
-            "revision": 1,
-            "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c",
-            "flags": [
-                "-_regex-posix-clib"
-            ],
-            "package": "regex-posix",
-            "source": "hackage",
-            "version": "0.96.0.1"
-        },
-        {
-            "cabal_sha256": "2088eb9368b920f80bbe4e3b03c3b8484090208f5c3b31645bd67a9ef7d26db4",
-            "revision": 4,
-            "src_sha256": "81a2bafad484db123cf8d17a02d98bb388a127fd0f822fa022589468a0e64671",
-            "flags": [],
-            "package": "resolv",
-            "source": "hackage",
-            "version": "0.1.2.0"
-        },
-        {
-            "cabal_sha256": "6e9b1b233af80cc0aa17ea858d2641ba146fb11cbcc5970a52649e89d77282e2",
-            "revision": 0,
-            "src_sha256": "91ce28d8f8a6efd31788d4827ed5cdcb9a546ad4053a86c56f7947c66a30b5bf",
-            "flags": [],
-            "package": "safe-exceptions",
-            "source": "hackage",
-            "version": "0.1.7.3"
-        },
-        {
-            "cabal_sha256": null,
-            "revision": null,
-            "src_sha256": null,
-            "flags": [
-                "+lukko",
-                "+native-dns"
-            ],
-            "package": "cabal-install",
-            "source": "local",
-            "version": "3.8.1.0"
-        }
-    ],
-    "builtin": [
-        {
-            "package": "rts",
-            "version": "1.0"
-        },
-        {
-            "package": "ghc-prim",
-            "version": "0.5.3"
-        },
-        {
-            "package": "integer-gmp",
-            "version": "1.0.2.0"
-        },
-        {
-            "package": "base",
-            "version": "4.13.0.0"
-        },
-        {
-            "package": "array",
-            "version": "0.5.4.0"
-        },
-        {
-            "package": "deepseq",
-            "version": "1.4.4.0"
-        },
-        {
-            "package": "bytestring",
-            "version": "0.10.10.1"
-        },
-        {
-            "package": "containers",
-            "version": "0.6.2.1"
-        },
-        {
-            "package": "binary",
-            "version": "0.8.7.0"
-        },
-        {
-            "package": "filepath",
-            "version": "1.4.2.1"
-        },
-        {
-            "package": "time",
-            "version": "1.9.3"
-        },
-        {
-            "package": "unix",
-            "version": "2.7.2.2"
-        },
-        {
-            "package": "directory",
-            "version": "1.3.6.0"
-        },
-        {
-            "package": "transformers",
-            "version": "0.5.6.2"
-        },
-        {
-            "package": "mtl",
-            "version": "2.2.2"
-        },
-        {
-            "package": "ghc-boot-th",
-            "version": "8.8.4"
-        },
-        {
-            "package": "pretty",
-            "version": "1.1.3.6"
-        },
-        {
-            "package": "template-haskell",
-            "version": "2.15.0.0"
-        },
-        {
-            "package": "text",
-            "version": "1.2.4.0"
-        },
-        {
-            "package": "parsec",
-            "version": "3.1.14.0"
-        },
-        {
-            "package": "stm",
-            "version": "2.5.0.0"
-        }
-    ]
-}
diff --git a/cabal/bootstrap/linux-9.0.2.json b/cabal/bootstrap/linux-9.0.2.json
--- a/cabal/bootstrap/linux-9.0.2.json
+++ b/cabal/bootstrap/linux-9.0.2.json
@@ -1,65 +1,158 @@
 {
+    "builtin": [
+        {
+            "package": "rts",
+            "version": "1.0.2"
+        },
+        {
+            "package": "ghc-prim",
+            "version": "0.7.0"
+        },
+        {
+            "package": "ghc-bignum",
+            "version": "1.1"
+        },
+        {
+            "package": "base",
+            "version": "4.15.1.0"
+        },
+        {
+            "package": "array",
+            "version": "0.5.4.0"
+        },
+        {
+            "package": "deepseq",
+            "version": "1.4.5.0"
+        },
+        {
+            "package": "bytestring",
+            "version": "0.10.12.1"
+        },
+        {
+            "package": "containers",
+            "version": "0.6.4.1"
+        },
+        {
+            "package": "binary",
+            "version": "0.8.8.0"
+        },
+        {
+            "package": "filepath",
+            "version": "1.4.2.1"
+        },
+        {
+            "package": "time",
+            "version": "1.9.3"
+        },
+        {
+            "package": "unix",
+            "version": "2.7.2.2"
+        },
+        {
+            "package": "transformers",
+            "version": "0.5.6.2"
+        },
+        {
+            "package": "mtl",
+            "version": "2.2.2"
+        },
+        {
+            "package": "ghc-boot-th",
+            "version": "9.0.2"
+        },
+        {
+            "package": "pretty",
+            "version": "1.1.3.6"
+        },
+        {
+            "package": "template-haskell",
+            "version": "2.17.0.0"
+        },
+        {
+            "package": "text",
+            "version": "1.2.5.0"
+        },
+        {
+            "package": "parsec",
+            "version": "3.1.14.0"
+        },
+        {
+            "package": "stm",
+            "version": "2.5.0.0"
+        },
+        {
+            "package": "exceptions",
+            "version": "0.10.4"
+        }
+    ],
     "dependencies": [
         {
+            "cabal_sha256": "7d16bf127fb303bd69d9c433bb146c5815f9690933af1d5a6ee45dea2e536dc5",
+            "flags": [],
+            "package": "directory",
+            "revision": 1,
+            "source": "hackage",
+            "src_sha256": "dc2785d6548cec2e80700fab007d3e9467f65d3c58ab3efa21b34d9017cf0efd",
+            "version": "1.3.7.1"
+        },
+        {
             "cabal_sha256": null,
-            "revision": null,
-            "src_sha256": null,
             "flags": [],
             "package": "Cabal-syntax",
+            "revision": null,
             "source": "local",
-            "version": "3.8.1.0"
+            "src_sha256": null,
+            "version": "3.10.3.0"
         },
         {
-            "cabal_sha256": "04df32d9497add5f0b90a27a3eceffa4bad5c2f41d038bd12ed6efc454db3faf",
-            "revision": 0,
-            "src_sha256": "44b31b6cd3129893ac1a007573dedb69dde667fa06ee108526d58f08b1a1f7ab",
+            "cabal_sha256": "8b4bce2749e4f61a440049e6088487003e8023c720e2019345e399d50888594f",
             "flags": [],
             "package": "process",
+            "revision": 2,
             "source": "hackage",
-            "version": "1.6.15.0"
+            "src_sha256": "aa5f4c4fe4974f89f5ab998c7509daa4bda3926cfb06daacd5eba892aad8a37e",
+            "version": "1.6.18.0"
         },
         {
             "cabal_sha256": null,
-            "revision": null,
-            "src_sha256": null,
             "flags": [],
             "package": "Cabal",
+            "revision": null,
             "source": "local",
-            "version": "3.8.1.0"
+            "src_sha256": null,
+            "version": "3.10.3.0"
         },
         {
-            "cabal_sha256": "e3d78b13db9512aeb106e44a334ab42b7aa48d26c097299084084cb8be5c5568",
-            "revision": 0,
-            "src_sha256": "7f7620fef1a1af3d3d6747f510e73223a5c600e7d7fd9ace073d1222bdc63d85",
+            "cabal_sha256": "e152cdb03243afb52bbc740cfbe96905ca298a6f6342f0c47b3f2e227ff19def",
             "flags": [
                 "-devel"
             ],
             "package": "network",
+            "revision": 1,
             "source": "hackage",
-            "version": "3.1.2.7"
+            "src_sha256": "b452a2afac95d9207357eb3820c719c7c7d27871ef4b6ed7bfcd03a036b9158e",
+            "version": "3.1.4.0"
         },
         {
-            "cabal_sha256": "f65819f74c6ced42b24d9e5053165508c4b6a18271c8e3229dc93b1dc8f7a5ab",
-            "revision": 1,
-            "src_sha256": "6b5059caf6714f47da92953badf2f556119877e09708c14e206b3ae98b8681c6",
+            "cabal_sha256": "f5f2c679ecc1c1b83d2d68db6cc564e5c78d53425e69e1b9e36784820e122d37",
             "flags": [],
             "package": "th-compat",
+            "revision": 4,
             "source": "hackage",
-            "version": "0.1.3"
+            "src_sha256": "d8f97ac14ab47b6b8a7b0fdb4ff95426322ec56badd01652ac15da4a44d4bab8",
+            "version": "0.1.4"
         },
         {
-            "cabal_sha256": "a4765164ed0a2d1668446eb2e03460ce98645fbf083598c690846af79b7de10d",
-            "revision": 0,
-            "src_sha256": "57856db93608a4d419f681b881c9b8d4448800d5a687587dc37e8a9e0b223584",
+            "cabal_sha256": "6fffb57373962b5651a2db8b0af732098b3bf029a7ced76a9855615de2026588",
             "flags": [],
             "package": "network-uri",
+            "revision": 1,
             "source": "hackage",
-            "version": "2.6.4.1"
+            "src_sha256": "9c188973126e893250b881f20e8811dca06c223c23402b06f7a1f2e995797228",
+            "version": "2.6.4.2"
         },
         {
-            "cabal_sha256": "16ee1212245c6e7cf0905b039689b55dbe8386a2b450094055e536d30c89ba76",
-            "revision": 0,
-            "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453",
+            "cabal_sha256": "0e37572590743e49d7a610f472e1618a594dc861410846f64d9f2347923c4f5b",
             "flags": [
                 "-conduit10",
                 "+network-uri",
@@ -67,129 +160,137 @@
                 "-warp-tests"
             ],
             "package": "HTTP",
+            "revision": 3,
             "source": "hackage",
+            "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453",
             "version": "4000.4.1"
         },
         {
-            "cabal_sha256": "eb6758d0160d607e0c45dbd6b196f515b9a589fd4f6d2f926929dd5d56282d37",
-            "revision": 0,
-            "src_sha256": "20a21c4b7adb0fd844b25e196241467406a28286b021f9b7a082ab03fa8015eb",
+            "cabal_sha256": "c4733d09f798fc4304e936924a1a7d9fc2425aefad6c46ad4592035254b46051",
             "flags": [],
             "package": "base-orphans",
+            "revision": 0,
             "source": "hackage",
-            "version": "0.8.6"
+            "src_sha256": "5bbf2da382c5b212d6a8be2f8c49edee0eba30f272a15fd32c13e6e4091ef172",
+            "version": "0.9.1"
         },
         {
-            "cabal_sha256": "0cddd0229d1aac305ea0404409c0bbfab81f075817bd74b8b2929eff58333e55",
-            "revision": 0,
-            "src_sha256": "83606edd356d914c075ecd44f6d5fe91a3b186aa0683c8dd8c9a7e8e22a47600",
+            "cabal_sha256": "ad89e28b2b046175698fbf542af2ce43e5d2af50aae9f48d12566b1bb3de1d3c",
+            "flags": [],
+            "package": "data-array-byte",
+            "revision": 2,
+            "source": "hackage",
+            "src_sha256": "1bb6eca0b3e02d057fe7f4e14c81ef395216f421ab30fdaa1b18017c9c025600",
+            "version": "0.1.0.1"
+        },
+        {
+            "cabal_sha256": "f3bf68acfa0df7a064a378ef2cdcfeb55e6fb96100675f4c593556dcbf3d7194",
             "flags": [
-                "+containers",
                 "+integer-gmp",
                 "-random-initial-seed"
             ],
             "package": "hashable",
+            "revision": 1,
             "source": "hackage",
-            "version": "1.4.0.2"
+            "src_sha256": "32efb16c2891786209b7cbe5c39df9b3a9ae51e836f1a54f646bc4602b7ab0f5",
+            "version": "1.4.3.0"
         },
         {
-            "cabal_sha256": "b83dec34a53520de84c6dd3dc7aae45d22409b46eb471c478b98108215a370f0",
-            "revision": 1,
-            "src_sha256": "484df85be0e76c4fed9376451e48e1d0c6e97952ce79735b72d54297e7e0a725",
+            "cabal_sha256": "9b8ceefce014e490f9e1335fa5f511161309926c55d01cec795016f4363b5d2d",
             "flags": [
                 "-bench"
             ],
             "package": "async",
+            "revision": 4,
             "source": "hackage",
+            "src_sha256": "484df85be0e76c4fed9376451e48e1d0c6e97952ce79735b72d54297e7e0a725",
             "version": "2.2.4"
         },
         {
-            "cabal_sha256": "64abad7816ab8cabed8489e29f807b3a6f828e0b2cec0eae404323d69d36df9a",
-            "revision": 0,
-            "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784",
+            "cabal_sha256": "a694e88f9ec9fc79f0b03f233d3fea592b68f70a34aac2ddb5bcaecb6562e2fd",
             "flags": [],
             "package": "base16-bytestring",
+            "revision": 1,
             "source": "hackage",
+            "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784",
             "version": "1.0.2.0"
         },
         {
-            "cabal_sha256": "50ec0e229255d4c45cbdd568da011311b8887f304b931564886016f4984334d8",
-            "revision": 0,
-            "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9",
+            "cabal_sha256": "45305ccf8914c66d385b518721472c7b8c858f1986945377f74f85c1e0d49803",
             "flags": [],
             "package": "base64-bytestring",
+            "revision": 1,
             "source": "hackage",
+            "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9",
             "version": "1.2.1.0"
         },
         {
-            "cabal_sha256": "714a55fd28d3e2533bd5b49e74f604ef8e5d7b06f249c8816f6c54aed431dcf1",
-            "revision": 0,
-            "src_sha256": "6d065402394e7a9117093dbb4530a21342c9b1e2ec509516c8a8d0ffed98ecaa",
+            "cabal_sha256": "bac0ae8d46a04e410666b0c8081cff63f060f29157983b569ca86ddb6e6e0dc6",
             "flags": [
                 "-optimised-mixer"
             ],
             "package": "splitmix",
+            "revision": 0,
             "source": "hackage",
-            "version": "0.1.0.4"
+            "src_sha256": "9df07a9611ef45f1b1258a0b412f4d02c920248f69d2e2ce8ccda328f7e13002",
+            "version": "0.1.0.5"
         },
         {
-            "cabal_sha256": "dea1f11e5569332dc6c8efaad1cb301016a5587b6754943a49f9de08ae0e56d9",
-            "revision": 0,
-            "src_sha256": "3e1272f7ed6a4d7bd1712b90143ec326fee9b225789222379fea20a9c90c9b76",
+            "cabal_sha256": "e7c1f881159d5cc788619c9ee8b8f340ba2ff0db571cdf3d1a1968ebc5108789",
             "flags": [],
             "package": "random",
+            "revision": 1,
             "source": "hackage",
+            "src_sha256": "3e1272f7ed6a4d7bd1712b90143ec326fee9b225789222379fea20a9c90c9b76",
             "version": "1.2.1.1"
         },
         {
             "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee",
-            "revision": 1,
-            "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a",
             "flags": [],
             "package": "edit-distance",
+            "revision": 1,
             "source": "hackage",
+            "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a",
             "version": "0.2.2.1"
         },
         {
             "cabal_sha256": null,
-            "revision": null,
-            "src_sha256": null,
             "flags": [
                 "-debug-conflict-sets",
                 "-debug-expensive-assertions",
                 "-debug-tracetree"
             ],
             "package": "cabal-install-solver",
+            "revision": null,
             "source": "local",
-            "version": "3.8.1.0"
+            "src_sha256": null,
+            "version": "3.10.3.0"
         },
         {
-            "cabal_sha256": "188d0b5a0491e8b686b32d9b144c9287760ba333d2509bf3f17e3d846fbc2332",
-            "revision": 0,
-            "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6",
+            "cabal_sha256": "03db065161987f614a3a2bbcd16264f78e47efe231fb5bd161be2043eaf20488",
             "flags": [
                 "-exe",
                 "+use-cbits"
             ],
             "package": "cryptohash-sha256",
+            "revision": 3,
             "source": "hackage",
+            "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6",
             "version": "0.11.102.1"
         },
         {
             "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42",
-            "revision": 0,
-            "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43",
             "flags": [
                 "-example"
             ],
             "package": "echo",
+            "revision": 0,
             "source": "hackage",
+            "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43",
             "version": "0.1.4"
         },
         {
-            "cabal_sha256": "24ac7b5f3d9fa3c2f70262b329f2a75f24e7fd829f88c189b388efa1bcd67eb2",
-            "revision": 5,
-            "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d",
+            "cabal_sha256": "48383789821af5cc624498f3ee1d0939a070cda9468c0bfe63c951736be81c75",
             "flags": [
                 "+no-donna",
                 "+test-doctests",
@@ -197,49 +298,49 @@
                 "+test-properties"
             ],
             "package": "ed25519",
+            "revision": 8,
             "source": "hackage",
+            "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d",
             "version": "0.0.5.0"
         },
         {
-            "cabal_sha256": "c084c043a40632d3cafcac50fb5eeff84d91edb070a54baa94945f1c976f97c0",
-            "revision": 2,
-            "src_sha256": "a80efb60cfa3dae18682c01980d76d5f7e413e191cd186992e1bf7388d48ab1f",
+            "cabal_sha256": "17786545dce60c4d5783ba6125c0a6499a1abddd3d7417b15500ccd767c35f07",
             "flags": [
                 "+ofd-locking"
             ],
             "package": "lukko",
+            "revision": 5,
             "source": "hackage",
+            "src_sha256": "a80efb60cfa3dae18682c01980d76d5f7e413e191cd186992e1bf7388d48ab1f",
             "version": "0.1.1.3"
         },
         {
-            "cabal_sha256": "bc14969ea4adfec6eee20264decf4a07c4002b38b2aa802d58d86b1a2cf7b895",
-            "revision": 5,
-            "src_sha256": "b384449f62b2b0aa3e6d2cb1004b8060b01f21ec93e7b63e7af6d8fad8a9f1de",
+            "cabal_sha256": "aaf5dd3ef327aaf203b1cb199760efd463fac2256453dd0e05d5cd707cdbd6e1",
             "flags": [
                 "-old-bytestring",
                 "-old-time"
             ],
             "package": "tar",
+            "revision": 10,
             "source": "hackage",
+            "src_sha256": "b384449f62b2b0aa3e6d2cb1004b8060b01f21ec93e7b63e7af6d8fad8a9f1de",
             "version": "0.5.1.1"
         },
         {
-            "cabal_sha256": "8214a9d37580f17f8b675109578a5dbe6853559eef156e34dc2233f1123ace33",
-            "revision": 0,
-            "src_sha256": "9eaa989ad4534438b5beb51c1d3a4c8f6a088fdff0b259a5394fbf39aaee04da",
+            "cabal_sha256": "19eb7759af71957811d5ec10ddb1e2f4c98700ddb9c0da6860c0441d811f0e6d",
             "flags": [
                 "-bundled-c-zlib",
                 "-non-blocking-ffi",
                 "-pkg-config"
             ],
             "package": "zlib",
+            "revision": 4,
             "source": "hackage",
+            "src_sha256": "9eaa989ad4534438b5beb51c1d3a4c8f6a088fdff0b259a5394fbf39aaee04da",
             "version": "0.6.3.0"
         },
         {
-            "cabal_sha256": "1d4b292bd90970f7ef52c72f2ae365f88bd2c6a75627dc34a31d24bc8f53f2e4",
-            "revision": 2,
-            "src_sha256": "bf22cd16dde7d6b7130463f4d7324b64a2964d9ef3f523df97d7cb98544d64a8",
+            "cabal_sha256": "2b2e560ac449e49f86a10d79957b2409da5be4b77edabd7425696780334cf3bf",
             "flags": [
                 "+base48",
                 "+cabal-syntax",
@@ -249,148 +350,60 @@
                 "+use-network-uri"
             ],
             "package": "hackage-security",
+            "revision": 8,
             "source": "hackage",
-            "version": "0.6.2.1"
+            "src_sha256": "52ee0576971955571d846b8e6c09638f89f4f7881f4a95173e44ccc0d856a066",
+            "version": "0.6.2.3"
         },
         {
-            "cabal_sha256": "4ff4425c710cddf440dfbac6cd52310bb6b23e17902390ff71c9fc7eaafc4fcc",
-            "revision": 1,
-            "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1",
+            "cabal_sha256": "0322b2fcd1358f3355e0c8608efa60d27b14d1c9d476451dbcb9181363bd8b27",
             "flags": [],
             "package": "regex-base",
+            "revision": 4,
             "source": "hackage",
+            "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1",
             "version": "0.94.0.2"
         },
         {
-            "cabal_sha256": "9dbba4b65a3bb6975d9740814be5593c6b2d2d6a0b3febc8ec940edb9a9bbdf4",
-            "revision": 1,
-            "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c",
+            "cabal_sha256": "816d6acc560cb86672f347a7bef8129578dde26ed760f9e79b4976ed9bd7b9fd",
             "flags": [
                 "-_regex-posix-clib"
             ],
             "package": "regex-posix",
+            "revision": 3,
             "source": "hackage",
+            "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c",
             "version": "0.96.0.1"
         },
         {
-            "cabal_sha256": "2088eb9368b920f80bbe4e3b03c3b8484090208f5c3b31645bd67a9ef7d26db4",
-            "revision": 4,
-            "src_sha256": "81a2bafad484db123cf8d17a02d98bb388a127fd0f822fa022589468a0e64671",
+            "cabal_sha256": "4868265ab5760d2fdeb96625b138c8df25d41b9ee2651fa299ed019a69403045",
             "flags": [],
             "package": "resolv",
+            "revision": 3,
             "source": "hackage",
-            "version": "0.1.2.0"
+            "src_sha256": "880d283df9132a7375fa28670f71e86480a4f49972256dc2a204c648274ae74b",
+            "version": "0.2.0.2"
         },
         {
-            "cabal_sha256": "6e9b1b233af80cc0aa17ea858d2641ba146fb11cbcc5970a52649e89d77282e2",
-            "revision": 0,
-            "src_sha256": "91ce28d8f8a6efd31788d4827ed5cdcb9a546ad4053a86c56f7947c66a30b5bf",
+            "cabal_sha256": "8bb7261bd54bd58acfcb154be6a161fb6d0d31a1852aadc8e927d2ad2d7651d1",
             "flags": [],
             "package": "safe-exceptions",
+            "revision": 1,
             "source": "hackage",
-            "version": "0.1.7.3"
+            "src_sha256": "3c51d8d50c9b60ff8bf94f942fd92e3bea9e62c5afa778dfc9f707b79da41ef6",
+            "version": "0.1.7.4"
         },
         {
             "cabal_sha256": null,
-            "revision": null,
-            "src_sha256": null,
             "flags": [
                 "+lukko",
                 "+native-dns"
             ],
             "package": "cabal-install",
+            "revision": null,
             "source": "local",
-            "version": "3.8.1.0"
-        }
-    ],
-    "builtin": [
-        {
-            "package": "rts",
-            "version": "1.0.2"
-        },
-        {
-            "package": "ghc-prim",
-            "version": "0.7.0"
-        },
-        {
-            "package": "ghc-bignum",
-            "version": "1.1"
-        },
-        {
-            "package": "base",
-            "version": "4.15.1.0"
-        },
-        {
-            "package": "array",
-            "version": "0.5.4.0"
-        },
-        {
-            "package": "deepseq",
-            "version": "1.4.5.0"
-        },
-        {
-            "package": "bytestring",
-            "version": "0.10.12.1"
-        },
-        {
-            "package": "containers",
-            "version": "0.6.4.1"
-        },
-        {
-            "package": "binary",
-            "version": "0.8.8.0"
-        },
-        {
-            "package": "filepath",
-            "version": "1.4.2.1"
-        },
-        {
-            "package": "time",
-            "version": "1.9.3"
-        },
-        {
-            "package": "unix",
-            "version": "2.7.2.2"
-        },
-        {
-            "package": "directory",
-            "version": "1.3.6.2"
-        },
-        {
-            "package": "transformers",
-            "version": "0.5.6.2"
-        },
-        {
-            "package": "mtl",
-            "version": "2.2.2"
-        },
-        {
-            "package": "ghc-boot-th",
-            "version": "9.0.2"
-        },
-        {
-            "package": "pretty",
-            "version": "1.1.3.6"
-        },
-        {
-            "package": "template-haskell",
-            "version": "2.17.0.0"
-        },
-        {
-            "package": "text",
-            "version": "1.2.5.0"
-        },
-        {
-            "package": "parsec",
-            "version": "3.1.14.0"
-        },
-        {
-            "package": "stm",
-            "version": "2.5.0.0"
-        },
-        {
-            "package": "exceptions",
-            "version": "0.10.4"
+            "src_sha256": null,
+            "version": "3.10.3.0"
         }
     ]
 }
diff --git a/cabal/bootstrap/linux-9.2.3.json b/cabal/bootstrap/linux-9.2.3.json
deleted file mode 100644
--- a/cabal/bootstrap/linux-9.2.3.json
+++ /dev/null
@@ -1,387 +0,0 @@
-{
-    "dependencies": [
-        {
-            "cabal_sha256": null,
-            "revision": null,
-            "src_sha256": null,
-            "flags": [],
-            "package": "Cabal-syntax",
-            "source": "local",
-            "version": "3.8.1.0"
-        },
-        {
-            "cabal_sha256": "04df32d9497add5f0b90a27a3eceffa4bad5c2f41d038bd12ed6efc454db3faf",
-            "revision": 0,
-            "src_sha256": "44b31b6cd3129893ac1a007573dedb69dde667fa06ee108526d58f08b1a1f7ab",
-            "flags": [],
-            "package": "process",
-            "source": "hackage",
-            "version": "1.6.15.0"
-        },
-        {
-            "cabal_sha256": null,
-            "revision": null,
-            "src_sha256": null,
-            "flags": [],
-            "package": "Cabal",
-            "source": "local",
-            "version": "3.8.1.0"
-        },
-        {
-            "cabal_sha256": "e3d78b13db9512aeb106e44a334ab42b7aa48d26c097299084084cb8be5c5568",
-            "revision": 0,
-            "src_sha256": "7f7620fef1a1af3d3d6747f510e73223a5c600e7d7fd9ace073d1222bdc63d85",
-            "flags": [
-                "-devel"
-            ],
-            "package": "network",
-            "source": "hackage",
-            "version": "3.1.2.7"
-        },
-        {
-            "cabal_sha256": "f65819f74c6ced42b24d9e5053165508c4b6a18271c8e3229dc93b1dc8f7a5ab",
-            "revision": 1,
-            "src_sha256": "6b5059caf6714f47da92953badf2f556119877e09708c14e206b3ae98b8681c6",
-            "flags": [],
-            "package": "th-compat",
-            "source": "hackage",
-            "version": "0.1.3"
-        },
-        {
-            "cabal_sha256": "a4765164ed0a2d1668446eb2e03460ce98645fbf083598c690846af79b7de10d",
-            "revision": 0,
-            "src_sha256": "57856db93608a4d419f681b881c9b8d4448800d5a687587dc37e8a9e0b223584",
-            "flags": [],
-            "package": "network-uri",
-            "source": "hackage",
-            "version": "2.6.4.1"
-        },
-        {
-            "cabal_sha256": "16ee1212245c6e7cf0905b039689b55dbe8386a2b450094055e536d30c89ba76",
-            "revision": 0,
-            "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453",
-            "flags": [
-                "-conduit10",
-                "+network-uri",
-                "-warn-as-error",
-                "-warp-tests"
-            ],
-            "package": "HTTP",
-            "source": "hackage",
-            "version": "4000.4.1"
-        },
-        {
-            "cabal_sha256": "0cddd0229d1aac305ea0404409c0bbfab81f075817bd74b8b2929eff58333e55",
-            "revision": 0,
-            "src_sha256": "83606edd356d914c075ecd44f6d5fe91a3b186aa0683c8dd8c9a7e8e22a47600",
-            "flags": [
-                "+containers",
-                "+integer-gmp",
-                "-random-initial-seed"
-            ],
-            "package": "hashable",
-            "source": "hackage",
-            "version": "1.4.0.2"
-        },
-        {
-            "cabal_sha256": "b83dec34a53520de84c6dd3dc7aae45d22409b46eb471c478b98108215a370f0",
-            "revision": 1,
-            "src_sha256": "484df85be0e76c4fed9376451e48e1d0c6e97952ce79735b72d54297e7e0a725",
-            "flags": [
-                "-bench"
-            ],
-            "package": "async",
-            "source": "hackage",
-            "version": "2.2.4"
-        },
-        {
-            "cabal_sha256": "64abad7816ab8cabed8489e29f807b3a6f828e0b2cec0eae404323d69d36df9a",
-            "revision": 0,
-            "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784",
-            "flags": [],
-            "package": "base16-bytestring",
-            "source": "hackage",
-            "version": "1.0.2.0"
-        },
-        {
-            "cabal_sha256": "50ec0e229255d4c45cbdd568da011311b8887f304b931564886016f4984334d8",
-            "revision": 0,
-            "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9",
-            "flags": [],
-            "package": "base64-bytestring",
-            "source": "hackage",
-            "version": "1.2.1.0"
-        },
-        {
-            "cabal_sha256": "714a55fd28d3e2533bd5b49e74f604ef8e5d7b06f249c8816f6c54aed431dcf1",
-            "revision": 0,
-            "src_sha256": "6d065402394e7a9117093dbb4530a21342c9b1e2ec509516c8a8d0ffed98ecaa",
-            "flags": [
-                "-optimised-mixer"
-            ],
-            "package": "splitmix",
-            "source": "hackage",
-            "version": "0.1.0.4"
-        },
-        {
-            "cabal_sha256": "dea1f11e5569332dc6c8efaad1cb301016a5587b6754943a49f9de08ae0e56d9",
-            "revision": 0,
-            "src_sha256": "3e1272f7ed6a4d7bd1712b90143ec326fee9b225789222379fea20a9c90c9b76",
-            "flags": [],
-            "package": "random",
-            "source": "hackage",
-            "version": "1.2.1.1"
-        },
-        {
-            "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee",
-            "revision": 1,
-            "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a",
-            "flags": [],
-            "package": "edit-distance",
-            "source": "hackage",
-            "version": "0.2.2.1"
-        },
-        {
-            "cabal_sha256": null,
-            "revision": null,
-            "src_sha256": null,
-            "flags": [
-                "-debug-conflict-sets",
-                "-debug-expensive-assertions",
-                "-debug-tracetree"
-            ],
-            "package": "cabal-install-solver",
-            "source": "local",
-            "version": "3.8.1.0"
-        },
-        {
-            "cabal_sha256": "188d0b5a0491e8b686b32d9b144c9287760ba333d2509bf3f17e3d846fbc2332",
-            "revision": 0,
-            "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6",
-            "flags": [
-                "-exe",
-                "+use-cbits"
-            ],
-            "package": "cryptohash-sha256",
-            "source": "hackage",
-            "version": "0.11.102.1"
-        },
-        {
-            "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42",
-            "revision": 0,
-            "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43",
-            "flags": [
-                "-example"
-            ],
-            "package": "echo",
-            "source": "hackage",
-            "version": "0.1.4"
-        },
-        {
-            "cabal_sha256": "24ac7b5f3d9fa3c2f70262b329f2a75f24e7fd829f88c189b388efa1bcd67eb2",
-            "revision": 5,
-            "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d",
-            "flags": [
-                "+no-donna",
-                "+test-doctests",
-                "+test-hlint",
-                "+test-properties"
-            ],
-            "package": "ed25519",
-            "source": "hackage",
-            "version": "0.0.5.0"
-        },
-        {
-            "cabal_sha256": "c084c043a40632d3cafcac50fb5eeff84d91edb070a54baa94945f1c976f97c0",
-            "revision": 2,
-            "src_sha256": "a80efb60cfa3dae18682c01980d76d5f7e413e191cd186992e1bf7388d48ab1f",
-            "flags": [
-                "+ofd-locking"
-            ],
-            "package": "lukko",
-            "source": "hackage",
-            "version": "0.1.1.3"
-        },
-        {
-            "cabal_sha256": "bc14969ea4adfec6eee20264decf4a07c4002b38b2aa802d58d86b1a2cf7b895",
-            "revision": 5,
-            "src_sha256": "b384449f62b2b0aa3e6d2cb1004b8060b01f21ec93e7b63e7af6d8fad8a9f1de",
-            "flags": [
-                "-old-bytestring",
-                "-old-time"
-            ],
-            "package": "tar",
-            "source": "hackage",
-            "version": "0.5.1.1"
-        },
-        {
-            "cabal_sha256": "8214a9d37580f17f8b675109578a5dbe6853559eef156e34dc2233f1123ace33",
-            "revision": 0,
-            "src_sha256": "9eaa989ad4534438b5beb51c1d3a4c8f6a088fdff0b259a5394fbf39aaee04da",
-            "flags": [
-                "-bundled-c-zlib",
-                "-non-blocking-ffi",
-                "-pkg-config"
-            ],
-            "package": "zlib",
-            "source": "hackage",
-            "version": "0.6.3.0"
-        },
-        {
-            "cabal_sha256": "1d4b292bd90970f7ef52c72f2ae365f88bd2c6a75627dc34a31d24bc8f53f2e4",
-            "revision": 2,
-            "src_sha256": "bf22cd16dde7d6b7130463f4d7324b64a2964d9ef3f523df97d7cb98544d64a8",
-            "flags": [
-                "+base48",
-                "+cabal-syntax",
-                "+lukko",
-                "-mtl21",
-                "-old-directory",
-                "+use-network-uri"
-            ],
-            "package": "hackage-security",
-            "source": "hackage",
-            "version": "0.6.2.1"
-        },
-        {
-            "cabal_sha256": "4ff4425c710cddf440dfbac6cd52310bb6b23e17902390ff71c9fc7eaafc4fcc",
-            "revision": 1,
-            "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1",
-            "flags": [],
-            "package": "regex-base",
-            "source": "hackage",
-            "version": "0.94.0.2"
-        },
-        {
-            "cabal_sha256": "9dbba4b65a3bb6975d9740814be5593c6b2d2d6a0b3febc8ec940edb9a9bbdf4",
-            "revision": 1,
-            "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c",
-            "flags": [
-                "-_regex-posix-clib"
-            ],
-            "package": "regex-posix",
-            "source": "hackage",
-            "version": "0.96.0.1"
-        },
-        {
-            "cabal_sha256": "2088eb9368b920f80bbe4e3b03c3b8484090208f5c3b31645bd67a9ef7d26db4",
-            "revision": 4,
-            "src_sha256": "81a2bafad484db123cf8d17a02d98bb388a127fd0f822fa022589468a0e64671",
-            "flags": [],
-            "package": "resolv",
-            "source": "hackage",
-            "version": "0.1.2.0"
-        },
-        {
-            "cabal_sha256": "6e9b1b233af80cc0aa17ea858d2641ba146fb11cbcc5970a52649e89d77282e2",
-            "revision": 0,
-            "src_sha256": "91ce28d8f8a6efd31788d4827ed5cdcb9a546ad4053a86c56f7947c66a30b5bf",
-            "flags": [],
-            "package": "safe-exceptions",
-            "source": "hackage",
-            "version": "0.1.7.3"
-        },
-        {
-            "cabal_sha256": null,
-            "revision": null,
-            "src_sha256": null,
-            "flags": [
-                "+lukko",
-                "+native-dns"
-            ],
-            "package": "cabal-install",
-            "source": "local",
-            "version": "3.8.1.0"
-        }
-    ],
-    "builtin": [
-        {
-            "package": "rts",
-            "version": "1.0.2"
-        },
-        {
-            "package": "ghc-prim",
-            "version": "0.8.0"
-        },
-        {
-            "package": "ghc-bignum",
-            "version": "1.2"
-        },
-        {
-            "package": "base",
-            "version": "4.16.2.0"
-        },
-        {
-            "package": "array",
-            "version": "0.5.4.0"
-        },
-        {
-            "package": "deepseq",
-            "version": "1.4.6.1"
-        },
-        {
-            "package": "ghc-boot-th",
-            "version": "9.2.3"
-        },
-        {
-            "package": "pretty",
-            "version": "1.1.3.6"
-        },
-        {
-            "package": "template-haskell",
-            "version": "2.18.0.0"
-        },
-        {
-            "package": "bytestring",
-            "version": "0.11.3.1"
-        },
-        {
-            "package": "containers",
-            "version": "0.6.5.1"
-        },
-        {
-            "package": "binary",
-            "version": "0.8.9.0"
-        },
-        {
-            "package": "filepath",
-            "version": "1.4.2.2"
-        },
-        {
-            "package": "time",
-            "version": "1.11.1.1"
-        },
-        {
-            "package": "unix",
-            "version": "2.7.2.2"
-        },
-        {
-            "package": "directory",
-            "version": "1.3.6.2"
-        },
-        {
-            "package": "transformers",
-            "version": "0.5.6.2"
-        },
-        {
-            "package": "mtl",
-            "version": "2.2.2"
-        },
-        {
-            "package": "text",
-            "version": "1.2.5.0"
-        },
-        {
-            "package": "parsec",
-            "version": "3.1.15.0"
-        },
-        {
-            "package": "stm",
-            "version": "2.5.0.2"
-        },
-        {
-            "package": "exceptions",
-            "version": "0.10.4"
-        }
-    ]
-}
diff --git a/cabal/bootstrap/linux-9.2.8.json b/cabal/bootstrap/linux-9.2.8.json
new file mode 100644
--- /dev/null
+++ b/cabal/bootstrap/linux-9.2.8.json
@@ -0,0 +1,400 @@
+{
+    "builtin": [
+        {
+            "package": "rts",
+            "version": "1.0.2"
+        },
+        {
+            "package": "ghc-prim",
+            "version": "0.8.0"
+        },
+        {
+            "package": "ghc-bignum",
+            "version": "1.2"
+        },
+        {
+            "package": "base",
+            "version": "4.16.4.0"
+        },
+        {
+            "package": "array",
+            "version": "0.5.4.0"
+        },
+        {
+            "package": "deepseq",
+            "version": "1.4.6.1"
+        },
+        {
+            "package": "ghc-boot-th",
+            "version": "9.2.8"
+        },
+        {
+            "package": "pretty",
+            "version": "1.1.3.6"
+        },
+        {
+            "package": "template-haskell",
+            "version": "2.18.0.0"
+        },
+        {
+            "package": "bytestring",
+            "version": "0.11.4.0"
+        },
+        {
+            "package": "containers",
+            "version": "0.6.5.1"
+        },
+        {
+            "package": "binary",
+            "version": "0.8.9.0"
+        },
+        {
+            "package": "filepath",
+            "version": "1.4.2.2"
+        },
+        {
+            "package": "time",
+            "version": "1.11.1.1"
+        },
+        {
+            "package": "unix",
+            "version": "2.7.2.2"
+        },
+        {
+            "package": "transformers",
+            "version": "0.5.6.2"
+        },
+        {
+            "package": "mtl",
+            "version": "2.2.2"
+        },
+        {
+            "package": "text",
+            "version": "1.2.5.0"
+        },
+        {
+            "package": "parsec",
+            "version": "3.1.15.0"
+        },
+        {
+            "package": "stm",
+            "version": "2.5.0.2"
+        },
+        {
+            "package": "exceptions",
+            "version": "0.10.4"
+        }
+    ],
+    "dependencies": [
+        {
+            "cabal_sha256": "7d16bf127fb303bd69d9c433bb146c5815f9690933af1d5a6ee45dea2e536dc5",
+            "flags": [],
+            "package": "directory",
+            "revision": 1,
+            "source": "hackage",
+            "src_sha256": "dc2785d6548cec2e80700fab007d3e9467f65d3c58ab3efa21b34d9017cf0efd",
+            "version": "1.3.7.1"
+        },
+        {
+            "cabal_sha256": null,
+            "flags": [],
+            "package": "Cabal-syntax",
+            "revision": null,
+            "source": "local",
+            "src_sha256": null,
+            "version": "3.10.3.0"
+        },
+        {
+            "cabal_sha256": "8b4bce2749e4f61a440049e6088487003e8023c720e2019345e399d50888594f",
+            "flags": [],
+            "package": "process",
+            "revision": 2,
+            "source": "hackage",
+            "src_sha256": "aa5f4c4fe4974f89f5ab998c7509daa4bda3926cfb06daacd5eba892aad8a37e",
+            "version": "1.6.18.0"
+        },
+        {
+            "cabal_sha256": null,
+            "flags": [],
+            "package": "Cabal",
+            "revision": null,
+            "source": "local",
+            "src_sha256": null,
+            "version": "3.10.3.0"
+        },
+        {
+            "cabal_sha256": "e152cdb03243afb52bbc740cfbe96905ca298a6f6342f0c47b3f2e227ff19def",
+            "flags": [
+                "-devel"
+            ],
+            "package": "network",
+            "revision": 1,
+            "source": "hackage",
+            "src_sha256": "b452a2afac95d9207357eb3820c719c7c7d27871ef4b6ed7bfcd03a036b9158e",
+            "version": "3.1.4.0"
+        },
+        {
+            "cabal_sha256": "f5f2c679ecc1c1b83d2d68db6cc564e5c78d53425e69e1b9e36784820e122d37",
+            "flags": [],
+            "package": "th-compat",
+            "revision": 4,
+            "source": "hackage",
+            "src_sha256": "d8f97ac14ab47b6b8a7b0fdb4ff95426322ec56badd01652ac15da4a44d4bab8",
+            "version": "0.1.4"
+        },
+        {
+            "cabal_sha256": "6fffb57373962b5651a2db8b0af732098b3bf029a7ced76a9855615de2026588",
+            "flags": [],
+            "package": "network-uri",
+            "revision": 1,
+            "source": "hackage",
+            "src_sha256": "9c188973126e893250b881f20e8811dca06c223c23402b06f7a1f2e995797228",
+            "version": "2.6.4.2"
+        },
+        {
+            "cabal_sha256": "0e37572590743e49d7a610f472e1618a594dc861410846f64d9f2347923c4f5b",
+            "flags": [
+                "-conduit10",
+                "+network-uri",
+                "-warn-as-error",
+                "-warp-tests"
+            ],
+            "package": "HTTP",
+            "revision": 3,
+            "source": "hackage",
+            "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453",
+            "version": "4000.4.1"
+        },
+        {
+            "cabal_sha256": "ad89e28b2b046175698fbf542af2ce43e5d2af50aae9f48d12566b1bb3de1d3c",
+            "flags": [],
+            "package": "data-array-byte",
+            "revision": 2,
+            "source": "hackage",
+            "src_sha256": "1bb6eca0b3e02d057fe7f4e14c81ef395216f421ab30fdaa1b18017c9c025600",
+            "version": "0.1.0.1"
+        },
+        {
+            "cabal_sha256": "f3bf68acfa0df7a064a378ef2cdcfeb55e6fb96100675f4c593556dcbf3d7194",
+            "flags": [
+                "+integer-gmp",
+                "-random-initial-seed"
+            ],
+            "package": "hashable",
+            "revision": 1,
+            "source": "hackage",
+            "src_sha256": "32efb16c2891786209b7cbe5c39df9b3a9ae51e836f1a54f646bc4602b7ab0f5",
+            "version": "1.4.3.0"
+        },
+        {
+            "cabal_sha256": "9b8ceefce014e490f9e1335fa5f511161309926c55d01cec795016f4363b5d2d",
+            "flags": [
+                "-bench"
+            ],
+            "package": "async",
+            "revision": 4,
+            "source": "hackage",
+            "src_sha256": "484df85be0e76c4fed9376451e48e1d0c6e97952ce79735b72d54297e7e0a725",
+            "version": "2.2.4"
+        },
+        {
+            "cabal_sha256": "a694e88f9ec9fc79f0b03f233d3fea592b68f70a34aac2ddb5bcaecb6562e2fd",
+            "flags": [],
+            "package": "base16-bytestring",
+            "revision": 1,
+            "source": "hackage",
+            "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784",
+            "version": "1.0.2.0"
+        },
+        {
+            "cabal_sha256": "45305ccf8914c66d385b518721472c7b8c858f1986945377f74f85c1e0d49803",
+            "flags": [],
+            "package": "base64-bytestring",
+            "revision": 1,
+            "source": "hackage",
+            "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9",
+            "version": "1.2.1.0"
+        },
+        {
+            "cabal_sha256": "bac0ae8d46a04e410666b0c8081cff63f060f29157983b569ca86ddb6e6e0dc6",
+            "flags": [
+                "-optimised-mixer"
+            ],
+            "package": "splitmix",
+            "revision": 0,
+            "source": "hackage",
+            "src_sha256": "9df07a9611ef45f1b1258a0b412f4d02c920248f69d2e2ce8ccda328f7e13002",
+            "version": "0.1.0.5"
+        },
+        {
+            "cabal_sha256": "e7c1f881159d5cc788619c9ee8b8f340ba2ff0db571cdf3d1a1968ebc5108789",
+            "flags": [],
+            "package": "random",
+            "revision": 1,
+            "source": "hackage",
+            "src_sha256": "3e1272f7ed6a4d7bd1712b90143ec326fee9b225789222379fea20a9c90c9b76",
+            "version": "1.2.1.1"
+        },
+        {
+            "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee",
+            "flags": [],
+            "package": "edit-distance",
+            "revision": 1,
+            "source": "hackage",
+            "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a",
+            "version": "0.2.2.1"
+        },
+        {
+            "cabal_sha256": null,
+            "flags": [
+                "-debug-conflict-sets",
+                "-debug-expensive-assertions",
+                "-debug-tracetree"
+            ],
+            "package": "cabal-install-solver",
+            "revision": null,
+            "source": "local",
+            "src_sha256": null,
+            "version": "3.10.3.0"
+        },
+        {
+            "cabal_sha256": "03db065161987f614a3a2bbcd16264f78e47efe231fb5bd161be2043eaf20488",
+            "flags": [
+                "-exe",
+                "+use-cbits"
+            ],
+            "package": "cryptohash-sha256",
+            "revision": 3,
+            "source": "hackage",
+            "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6",
+            "version": "0.11.102.1"
+        },
+        {
+            "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42",
+            "flags": [
+                "-example"
+            ],
+            "package": "echo",
+            "revision": 0,
+            "source": "hackage",
+            "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43",
+            "version": "0.1.4"
+        },
+        {
+            "cabal_sha256": "48383789821af5cc624498f3ee1d0939a070cda9468c0bfe63c951736be81c75",
+            "flags": [
+                "+no-donna",
+                "+test-doctests",
+                "+test-hlint",
+                "+test-properties"
+            ],
+            "package": "ed25519",
+            "revision": 8,
+            "source": "hackage",
+            "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d",
+            "version": "0.0.5.0"
+        },
+        {
+            "cabal_sha256": "17786545dce60c4d5783ba6125c0a6499a1abddd3d7417b15500ccd767c35f07",
+            "flags": [
+                "+ofd-locking"
+            ],
+            "package": "lukko",
+            "revision": 5,
+            "source": "hackage",
+            "src_sha256": "a80efb60cfa3dae18682c01980d76d5f7e413e191cd186992e1bf7388d48ab1f",
+            "version": "0.1.1.3"
+        },
+        {
+            "cabal_sha256": "aaf5dd3ef327aaf203b1cb199760efd463fac2256453dd0e05d5cd707cdbd6e1",
+            "flags": [
+                "-old-bytestring",
+                "-old-time"
+            ],
+            "package": "tar",
+            "revision": 10,
+            "source": "hackage",
+            "src_sha256": "b384449f62b2b0aa3e6d2cb1004b8060b01f21ec93e7b63e7af6d8fad8a9f1de",
+            "version": "0.5.1.1"
+        },
+        {
+            "cabal_sha256": "19eb7759af71957811d5ec10ddb1e2f4c98700ddb9c0da6860c0441d811f0e6d",
+            "flags": [
+                "-bundled-c-zlib",
+                "-non-blocking-ffi",
+                "-pkg-config"
+            ],
+            "package": "zlib",
+            "revision": 4,
+            "source": "hackage",
+            "src_sha256": "9eaa989ad4534438b5beb51c1d3a4c8f6a088fdff0b259a5394fbf39aaee04da",
+            "version": "0.6.3.0"
+        },
+        {
+            "cabal_sha256": "2b2e560ac449e49f86a10d79957b2409da5be4b77edabd7425696780334cf3bf",
+            "flags": [
+                "+base48",
+                "+cabal-syntax",
+                "+lukko",
+                "-mtl21",
+                "-old-directory",
+                "+use-network-uri"
+            ],
+            "package": "hackage-security",
+            "revision": 8,
+            "source": "hackage",
+            "src_sha256": "52ee0576971955571d846b8e6c09638f89f4f7881f4a95173e44ccc0d856a066",
+            "version": "0.6.2.3"
+        },
+        {
+            "cabal_sha256": "0322b2fcd1358f3355e0c8608efa60d27b14d1c9d476451dbcb9181363bd8b27",
+            "flags": [],
+            "package": "regex-base",
+            "revision": 4,
+            "source": "hackage",
+            "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1",
+            "version": "0.94.0.2"
+        },
+        {
+            "cabal_sha256": "816d6acc560cb86672f347a7bef8129578dde26ed760f9e79b4976ed9bd7b9fd",
+            "flags": [
+                "-_regex-posix-clib"
+            ],
+            "package": "regex-posix",
+            "revision": 3,
+            "source": "hackage",
+            "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c",
+            "version": "0.96.0.1"
+        },
+        {
+            "cabal_sha256": "4868265ab5760d2fdeb96625b138c8df25d41b9ee2651fa299ed019a69403045",
+            "flags": [],
+            "package": "resolv",
+            "revision": 3,
+            "source": "hackage",
+            "src_sha256": "880d283df9132a7375fa28670f71e86480a4f49972256dc2a204c648274ae74b",
+            "version": "0.2.0.2"
+        },
+        {
+            "cabal_sha256": "8bb7261bd54bd58acfcb154be6a161fb6d0d31a1852aadc8e927d2ad2d7651d1",
+            "flags": [],
+            "package": "safe-exceptions",
+            "revision": 1,
+            "source": "hackage",
+            "src_sha256": "3c51d8d50c9b60ff8bf94f942fd92e3bea9e62c5afa778dfc9f707b79da41ef6",
+            "version": "0.1.7.4"
+        },
+        {
+            "cabal_sha256": null,
+            "flags": [
+                "+lukko",
+                "+native-dns"
+            ],
+            "package": "cabal-install",
+            "revision": null,
+            "source": "local",
+            "src_sha256": null,
+            "version": "3.10.3.0"
+        }
+    ]
+}
diff --git a/cabal/bootstrap/linux-9.4.8.json b/cabal/bootstrap/linux-9.4.8.json
new file mode 100644
--- /dev/null
+++ b/cabal/bootstrap/linux-9.4.8.json
@@ -0,0 +1,381 @@
+{
+    "builtin": [
+        {
+            "package": "rts",
+            "version": "1.0.2"
+        },
+        {
+            "package": "ghc-prim",
+            "version": "0.9.1"
+        },
+        {
+            "package": "ghc-bignum",
+            "version": "1.3"
+        },
+        {
+            "package": "base",
+            "version": "4.17.2.1"
+        },
+        {
+            "package": "array",
+            "version": "0.5.4.0"
+        },
+        {
+            "package": "deepseq",
+            "version": "1.4.8.0"
+        },
+        {
+            "package": "ghc-boot-th",
+            "version": "9.4.8"
+        },
+        {
+            "package": "pretty",
+            "version": "1.1.3.6"
+        },
+        {
+            "package": "template-haskell",
+            "version": "2.19.0.0"
+        },
+        {
+            "package": "bytestring",
+            "version": "0.11.5.3"
+        },
+        {
+            "package": "containers",
+            "version": "0.6.7"
+        },
+        {
+            "package": "binary",
+            "version": "0.8.9.1"
+        },
+        {
+            "package": "filepath",
+            "version": "1.4.2.2"
+        },
+        {
+            "package": "time",
+            "version": "1.12.2"
+        },
+        {
+            "package": "unix",
+            "version": "2.7.3"
+        },
+        {
+            "package": "directory",
+            "version": "1.3.7.1"
+        },
+        {
+            "package": "transformers",
+            "version": "0.5.6.2"
+        },
+        {
+            "package": "mtl",
+            "version": "2.2.2"
+        },
+        {
+            "package": "text",
+            "version": "2.0.2"
+        },
+        {
+            "package": "parsec",
+            "version": "3.1.16.1"
+        },
+        {
+            "package": "process",
+            "version": "1.6.18.0"
+        },
+        {
+            "package": "stm",
+            "version": "2.5.1.0"
+        },
+        {
+            "package": "exceptions",
+            "version": "0.10.5"
+        }
+    ],
+    "dependencies": [
+        {
+            "cabal_sha256": null,
+            "flags": [],
+            "package": "Cabal-syntax",
+            "revision": null,
+            "source": "local",
+            "src_sha256": null,
+            "version": "3.10.3.0"
+        },
+        {
+            "cabal_sha256": null,
+            "flags": [],
+            "package": "Cabal",
+            "revision": null,
+            "source": "local",
+            "src_sha256": null,
+            "version": "3.10.3.0"
+        },
+        {
+            "cabal_sha256": "e152cdb03243afb52bbc740cfbe96905ca298a6f6342f0c47b3f2e227ff19def",
+            "flags": [
+                "-devel"
+            ],
+            "package": "network",
+            "revision": 1,
+            "source": "hackage",
+            "src_sha256": "b452a2afac95d9207357eb3820c719c7c7d27871ef4b6ed7bfcd03a036b9158e",
+            "version": "3.1.4.0"
+        },
+        {
+            "cabal_sha256": "f5f2c679ecc1c1b83d2d68db6cc564e5c78d53425e69e1b9e36784820e122d37",
+            "flags": [],
+            "package": "th-compat",
+            "revision": 4,
+            "source": "hackage",
+            "src_sha256": "d8f97ac14ab47b6b8a7b0fdb4ff95426322ec56badd01652ac15da4a44d4bab8",
+            "version": "0.1.4"
+        },
+        {
+            "cabal_sha256": "6fffb57373962b5651a2db8b0af732098b3bf029a7ced76a9855615de2026588",
+            "flags": [],
+            "package": "network-uri",
+            "revision": 1,
+            "source": "hackage",
+            "src_sha256": "9c188973126e893250b881f20e8811dca06c223c23402b06f7a1f2e995797228",
+            "version": "2.6.4.2"
+        },
+        {
+            "cabal_sha256": "0e37572590743e49d7a610f472e1618a594dc861410846f64d9f2347923c4f5b",
+            "flags": [
+                "-conduit10",
+                "+network-uri",
+                "-warn-as-error",
+                "-warp-tests"
+            ],
+            "package": "HTTP",
+            "revision": 3,
+            "source": "hackage",
+            "src_sha256": "df31d8efec775124dab856d7177ddcba31be9f9e0836ebdab03d94392f2dd453",
+            "version": "4000.4.1"
+        },
+        {
+            "cabal_sha256": "f3bf68acfa0df7a064a378ef2cdcfeb55e6fb96100675f4c593556dcbf3d7194",
+            "flags": [
+                "+integer-gmp",
+                "-random-initial-seed"
+            ],
+            "package": "hashable",
+            "revision": 1,
+            "source": "hackage",
+            "src_sha256": "32efb16c2891786209b7cbe5c39df9b3a9ae51e836f1a54f646bc4602b7ab0f5",
+            "version": "1.4.3.0"
+        },
+        {
+            "cabal_sha256": "9b8ceefce014e490f9e1335fa5f511161309926c55d01cec795016f4363b5d2d",
+            "flags": [
+                "-bench"
+            ],
+            "package": "async",
+            "revision": 4,
+            "source": "hackage",
+            "src_sha256": "484df85be0e76c4fed9376451e48e1d0c6e97952ce79735b72d54297e7e0a725",
+            "version": "2.2.4"
+        },
+        {
+            "cabal_sha256": "a694e88f9ec9fc79f0b03f233d3fea592b68f70a34aac2ddb5bcaecb6562e2fd",
+            "flags": [],
+            "package": "base16-bytestring",
+            "revision": 1,
+            "source": "hackage",
+            "src_sha256": "1d5a91143ef0e22157536093ec8e59d226a68220ec89378d5dcaeea86472c784",
+            "version": "1.0.2.0"
+        },
+        {
+            "cabal_sha256": "45305ccf8914c66d385b518721472c7b8c858f1986945377f74f85c1e0d49803",
+            "flags": [],
+            "package": "base64-bytestring",
+            "revision": 1,
+            "source": "hackage",
+            "src_sha256": "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9",
+            "version": "1.2.1.0"
+        },
+        {
+            "cabal_sha256": "bac0ae8d46a04e410666b0c8081cff63f060f29157983b569ca86ddb6e6e0dc6",
+            "flags": [
+                "-optimised-mixer"
+            ],
+            "package": "splitmix",
+            "revision": 0,
+            "source": "hackage",
+            "src_sha256": "9df07a9611ef45f1b1258a0b412f4d02c920248f69d2e2ce8ccda328f7e13002",
+            "version": "0.1.0.5"
+        },
+        {
+            "cabal_sha256": "e7c1f881159d5cc788619c9ee8b8f340ba2ff0db571cdf3d1a1968ebc5108789",
+            "flags": [],
+            "package": "random",
+            "revision": 1,
+            "source": "hackage",
+            "src_sha256": "3e1272f7ed6a4d7bd1712b90143ec326fee9b225789222379fea20a9c90c9b76",
+            "version": "1.2.1.1"
+        },
+        {
+            "cabal_sha256": "4d33a49cd383d50af090f1b888642d10116e43809f9da6023d9fc6f67d2656ee",
+            "flags": [],
+            "package": "edit-distance",
+            "revision": 1,
+            "source": "hackage",
+            "src_sha256": "3e8885ee2f56ad4da940f043ae8f981ee2fe336b5e8e4ba3f7436cff4f526c4a",
+            "version": "0.2.2.1"
+        },
+        {
+            "cabal_sha256": null,
+            "flags": [
+                "-debug-conflict-sets",
+                "-debug-expensive-assertions",
+                "-debug-tracetree"
+            ],
+            "package": "cabal-install-solver",
+            "revision": null,
+            "source": "local",
+            "src_sha256": null,
+            "version": "3.10.3.0"
+        },
+        {
+            "cabal_sha256": "03db065161987f614a3a2bbcd16264f78e47efe231fb5bd161be2043eaf20488",
+            "flags": [
+                "-exe",
+                "+use-cbits"
+            ],
+            "package": "cryptohash-sha256",
+            "revision": 3,
+            "source": "hackage",
+            "src_sha256": "73a7dc7163871a80837495039a099967b11f5c4fe70a118277842f7a713c6bf6",
+            "version": "0.11.102.1"
+        },
+        {
+            "cabal_sha256": "ccce771562c49a2b29a52046ca68c62179e97e8fbeacdae32ca84a85445e8f42",
+            "flags": [
+                "-example"
+            ],
+            "package": "echo",
+            "revision": 0,
+            "source": "hackage",
+            "src_sha256": "c9fe1bf2904825a65b667251ec644f197b71dc5c209d2d254be5de3d496b0e43",
+            "version": "0.1.4"
+        },
+        {
+            "cabal_sha256": "48383789821af5cc624498f3ee1d0939a070cda9468c0bfe63c951736be81c75",
+            "flags": [
+                "+no-donna",
+                "+test-doctests",
+                "+test-hlint",
+                "+test-properties"
+            ],
+            "package": "ed25519",
+            "revision": 8,
+            "source": "hackage",
+            "src_sha256": "d8a5958ebfa9309790efade64275dc5c441b568645c45ceed1b0c6ff36d6156d",
+            "version": "0.0.5.0"
+        },
+        {
+            "cabal_sha256": "17786545dce60c4d5783ba6125c0a6499a1abddd3d7417b15500ccd767c35f07",
+            "flags": [
+                "+ofd-locking"
+            ],
+            "package": "lukko",
+            "revision": 5,
+            "source": "hackage",
+            "src_sha256": "a80efb60cfa3dae18682c01980d76d5f7e413e191cd186992e1bf7388d48ab1f",
+            "version": "0.1.1.3"
+        },
+        {
+            "cabal_sha256": "aaf5dd3ef327aaf203b1cb199760efd463fac2256453dd0e05d5cd707cdbd6e1",
+            "flags": [
+                "-old-bytestring",
+                "-old-time"
+            ],
+            "package": "tar",
+            "revision": 10,
+            "source": "hackage",
+            "src_sha256": "b384449f62b2b0aa3e6d2cb1004b8060b01f21ec93e7b63e7af6d8fad8a9f1de",
+            "version": "0.5.1.1"
+        },
+        {
+            "cabal_sha256": "19eb7759af71957811d5ec10ddb1e2f4c98700ddb9c0da6860c0441d811f0e6d",
+            "flags": [
+                "-bundled-c-zlib",
+                "-non-blocking-ffi",
+                "-pkg-config"
+            ],
+            "package": "zlib",
+            "revision": 4,
+            "source": "hackage",
+            "src_sha256": "9eaa989ad4534438b5beb51c1d3a4c8f6a088fdff0b259a5394fbf39aaee04da",
+            "version": "0.6.3.0"
+        },
+        {
+            "cabal_sha256": "2b2e560ac449e49f86a10d79957b2409da5be4b77edabd7425696780334cf3bf",
+            "flags": [
+                "+base48",
+                "+cabal-syntax",
+                "+lukko",
+                "-mtl21",
+                "-old-directory",
+                "+use-network-uri"
+            ],
+            "package": "hackage-security",
+            "revision": 8,
+            "source": "hackage",
+            "src_sha256": "52ee0576971955571d846b8e6c09638f89f4f7881f4a95173e44ccc0d856a066",
+            "version": "0.6.2.3"
+        },
+        {
+            "cabal_sha256": "0322b2fcd1358f3355e0c8608efa60d27b14d1c9d476451dbcb9181363bd8b27",
+            "flags": [],
+            "package": "regex-base",
+            "revision": 4,
+            "source": "hackage",
+            "src_sha256": "7b99408f580f5bb67a1c413e0bc735886608251331ad36322020f2169aea2ef1",
+            "version": "0.94.0.2"
+        },
+        {
+            "cabal_sha256": "816d6acc560cb86672f347a7bef8129578dde26ed760f9e79b4976ed9bd7b9fd",
+            "flags": [
+                "-_regex-posix-clib"
+            ],
+            "package": "regex-posix",
+            "revision": 3,
+            "source": "hackage",
+            "src_sha256": "c7827c391919227711e1cff0a762b1678fd8739f9c902fc183041ff34f59259c",
+            "version": "0.96.0.1"
+        },
+        {
+            "cabal_sha256": "4868265ab5760d2fdeb96625b138c8df25d41b9ee2651fa299ed019a69403045",
+            "flags": [],
+            "package": "resolv",
+            "revision": 3,
+            "source": "hackage",
+            "src_sha256": "880d283df9132a7375fa28670f71e86480a4f49972256dc2a204c648274ae74b",
+            "version": "0.2.0.2"
+        },
+        {
+            "cabal_sha256": "8bb7261bd54bd58acfcb154be6a161fb6d0d31a1852aadc8e927d2ad2d7651d1",
+            "flags": [],
+            "package": "safe-exceptions",
+            "revision": 1,
+            "source": "hackage",
+            "src_sha256": "3c51d8d50c9b60ff8bf94f942fd92e3bea9e62c5afa778dfc9f707b79da41ef6",
+            "version": "0.1.7.4"
+        },
+        {
+            "cabal_sha256": null,
+            "flags": [
+                "+lukko",
+                "+native-dns"
+            ],
+            "package": "cabal-install",
+            "revision": null,
+            "source": "local",
+            "src_sha256": null,
+            "version": "3.10.3.0"
+        }
+    ]
+}
diff --git a/cabal/bootstrap/src/Main.hs b/cabal/bootstrap/src/Main.hs
--- a/cabal/bootstrap/src/Main.hs
+++ b/cabal/bootstrap/src/Main.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE CPP #-}
+
 module Main (main) where
 
 import Control.Monad      (when)
@@ -34,9 +36,15 @@
 
 main1 :: FilePath -> IO ()
 main1 planPath = do
-    meta <- I.cachedHackageMetadata
+    meta <- getMap <$> I.cachedHackageMetadata
     plan <- P.decodePlanJson planPath
     main2 meta plan
+  where
+#if MIN_VERSION_cabal_install_parsers(0,4,0)
+    getMap = snd
+#else
+    getMap = id
+#endif
 
 main2 :: Map.Map C.PackageName I.PackageInfo -> P.PlanJson -> IO ()
 main2 meta plan = do
@@ -73,7 +81,7 @@
                   { builtinPackageName = pkgname
                   , builtinVersion     = ver
                   }
-            
+
             _ -> do
                 (src, rev, revhash) <- case P.uSha256 unit of
                     Just _  -> do
@@ -85,7 +93,7 @@
                         return
                             ( Hackage
                             , Just $ fromIntegral (I.riRevision relInfo)
-                            , P.sha256FromByteString $ I.getSHA256 $ I.riCabal relInfo
+                            , P.sha256FromByteString $ I.getSHA256 $ getHash relInfo
                             )
 
                     Nothing -> case P.uType unit of
@@ -109,6 +117,12 @@
         { resBuiltin      = builtin
         , resDependencies = deps
         }
+  where
+#if MIN_VERSION_cabal_install_parsers(0,6,0)
+    getHash = I.riCabalHash
+#else
+    getHash = I.riCabal
+#endif
 
 bfs :: P.PlanJson -> P.Unit -> IO [P.Unit]
 bfs plan unit0 = do
diff --git a/cabal/buildinfo-reference-generator/template.zinza b/cabal/buildinfo-reference-generator/template.zinza
--- a/cabal/buildinfo-reference-generator/template.zinza
+++ b/cabal/buildinfo-reference-generator/template.zinza
@@ -86,10 +86,10 @@
 
 
   .. math::
-      
+
       \mathbf{fix}\; \mathit{expr}\; \mathbf{in}\; \mathit{digit}
       \mid \mathit{expr} \circ \mathord{``}\mathtt{+}\mathord{"} \circ \mathit{expr}
-      \mid \mathord{``}\mathtt{(} \mathord{"} \circ \mathit{expr} \circ \mathord{``}\mathtt{)}\mathord{"} 
+      \mid \mathord{``}\mathtt{(} \mathord{"} \circ \mathit{expr} \circ \mathord{``}\mathtt{)}\mathord{"}
 
 Lists
 -----
diff --git a/cabal/cabal-benchmarks/LICENSE b/cabal/cabal-benchmarks/LICENSE
--- a/cabal/cabal-benchmarks/LICENSE
+++ b/cabal/cabal-benchmarks/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2003-2022, Cabal Development Team.
+Copyright (c) 2003-2023, Cabal Development Team.
 See the AUTHORS file for the full list of copyright holders.
 
 See */LICENSE for the copyright holders of the subcomponents.
diff --git a/cabal/cabal-benchmarks/cabal-benchmarks.cabal b/cabal/cabal-benchmarks/cabal-benchmarks.cabal
--- a/cabal/cabal-benchmarks/cabal-benchmarks.cabal
+++ b/cabal/cabal-benchmarks/cabal-benchmarks.cabal
@@ -1,7 +1,7 @@
 cabal-version:      2.2
 name:               cabal-benchmarks
 version:            3
-copyright:          2003-2022, Cabal Development Team (see AUTHORS file)
+copyright:          2003-2023, Cabal Development Team (see AUTHORS file)
 license:            BSD-3-Clause
 license-file:       LICENSE
 author:             Cabal Development Team <cabal-devel@haskell.org>
@@ -31,4 +31,4 @@
       base
     , bytestring
     , Cabal-syntax
-    , criterion   >=1.5.6.2 && <1.6
+    , criterion   >=1.5.6.2 && <1.7
diff --git a/cabal/cabal-dev-scripts/LICENSE b/cabal/cabal-dev-scripts/LICENSE
--- a/cabal/cabal-dev-scripts/LICENSE
+++ b/cabal/cabal-dev-scripts/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2003-2022, Cabal Development Team.
+Copyright (c) 2003-2023, Cabal Development Team.
 See the AUTHORS file for the full list of copyright holders.
 
 See */LICENSE for the copyright holders of the subcomponents.
diff --git a/cabal/cabal-dev-scripts/cabal-dev-scripts.cabal b/cabal/cabal-dev-scripts/cabal-dev-scripts.cabal
--- a/cabal/cabal-dev-scripts/cabal-dev-scripts.cabal
+++ b/cabal/cabal-dev-scripts/cabal-dev-scripts.cabal
@@ -18,7 +18,7 @@
   ghc-options:      -Wall
   build-depends:
     , aeson                 ^>=1.4.1.0 || ^>=1.5.2.0 || ^>=2.1.1.0
-    , base                  >=4.10     && <4.18
+    , base                  >=4.10     && <4.19
     , bytestring
     , containers
     , Diff                  ^>=0.4
@@ -35,7 +35,7 @@
   ghc-options:      -Wall
   build-depends:
     , aeson                 ^>=1.4.1.0 || ^>=1.5.2.0 || ^>=2.1.1.0
-    , base                  >=4.10     && <4.18
+    , base                  >=4.10     && <4.19
     , bytestring
     , containers
     , Diff                  ^>=0.4
diff --git a/cabal/cabal-dev-scripts/src/GenCabalInstallCabal.hs b/cabal/cabal-dev-scripts/src/GenCabalInstallCabal.hs
--- a/cabal/cabal-dev-scripts/src/GenCabalInstallCabal.hs
+++ b/cabal/cabal-dev-scripts/src/GenCabalInstallCabal.hs
@@ -25,7 +25,7 @@
     parseBool "True"  = Just True
     parseBool "False" = Just False
     parseBool _       = Nothing
-    
+
 
 main :: IO ()
 main = withIO $ \dev src tgt -> do
diff --git a/cabal/cabal-dev-scripts/src/GenUtils.hs b/cabal/cabal-dev-scripts/src/GenUtils.hs
--- a/cabal/cabal-dev-scripts/src/GenUtils.hs
+++ b/cabal/cabal-dev-scripts/src/GenUtils.hs
@@ -31,7 +31,7 @@
     | SPDXLicenseListVersion_3_6
     | SPDXLicenseListVersion_3_9
     | SPDXLicenseListVersion_3_10
-    | SPDXLicenseListVersion_3_16 
+    | SPDXLicenseListVersion_3_16
   deriving (Eq, Ord, Show, Enum, Bounded)
 
 allVers :: Set.Set SPDXLicenseListVersion
diff --git a/cabal/cabal-install-solver/ChangeLog.md b/cabal/cabal-install-solver/ChangeLog.md
--- a/cabal/cabal-install-solver/ChangeLog.md
+++ b/cabal/cabal-install-solver/ChangeLog.md
@@ -1,1 +1,1 @@
-Please see https://hackage.haskell.org/package/cabal-install/changelog
+Please see https://github.com/haskell/cabal/blob/master/release-notes/cabal-install-3.10.3.0.md
diff --git a/cabal/cabal-install-solver/LICENSE b/cabal/cabal-install-solver/LICENSE
--- a/cabal/cabal-install-solver/LICENSE
+++ b/cabal/cabal-install-solver/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2003-2022, Cabal Development Team.
+Copyright (c) 2003-2023, Cabal Development Team.
 See the AUTHORS file for the full list of copyright holders.
 
 See */LICENSE for the copyright holders of the subcomponents.
diff --git a/cabal/cabal-install-solver/cabal-install-solver.cabal b/cabal/cabal-install-solver/cabal-install-solver.cabal
--- a/cabal/cabal-install-solver/cabal-install-solver.cabal
+++ b/cabal/cabal-install-solver/cabal-install-solver.cabal
@@ -1,6 +1,6 @@
 cabal-version: 2.2
 name:          cabal-install-solver
-version:       3.8.1.0
+version:       3.10.3.0
 synopsis:      The command-line interface for Cabal and Hackage.
 description:
   The solver component used in cabal-install command-line program
@@ -11,10 +11,10 @@
 license-file:  LICENSE
 author:        Cabal Development Team (see AUTHORS file)
 maintainer:    Cabal Development Team <cabal-devel@haskell.org>
-copyright:     2003-2022, Cabal Development Team
+copyright:     2003-2023, Cabal Development Team
 category:      Distribution
 build-type:    Simple
-Extra-Source-Files:
+extra-doc-files:
   ChangeLog.md
 
 source-repository head
@@ -105,23 +105,24 @@
 
   build-depends:
     , array         >=0.4      && <0.6
-    , base          >=4.10     && <4.18
-    , bytestring    >=0.10.6.0 && <0.12
-    , Cabal         ^>=3.8
-    , Cabal-syntax  ^>=3.8
-    , containers    >=0.5.6.2  && <0.7
+    , base          >=4.10     && <4.20
+    , bytestring    >=0.10.6.0 && <0.13
+    , Cabal         ^>=3.10.3
+    , Cabal-syntax  ^>=3.10
+    , containers    >=0.5.6.2  && <0.8
     , edit-distance ^>= 0.2.2
-    , filepath      ^>=1.4.0.0
-    , mtl           >=2.0      && <2.3
+    , filepath      ^>=1.4.0.0 || ^>=1.5.0.0
+    , mtl           >=2.0      && <2.4
     , pretty        ^>=1.1
-    , transformers  >=0.4.2.0  && <0.6
+    , transformers  >=0.4.2.0  && <0.7
+    , text          (>= 1.2.3.0  && < 1.3) || (>= 2.0 && < 2.2)
 
   if flag(debug-expensive-assertions)
     cpp-options: -DDEBUG_EXPENSIVE_ASSERTIONS
 
   if flag(debug-conflict-sets)
     cpp-options:   -DDEBUG_CONFLICT_SETS
-    build-depends: base >=4.8
+    build-depends: base >=4.9
 
   if flag(debug-tracetree)
     cpp-options:   -DDEBUG_TRACETREE
@@ -138,10 +139,10 @@
      UnitTests.Distribution.Solver.Modular.MessageUtils
 
    build-depends:
-     , base        >= 4.10  && <4.18
+     , base        >= 4.10  && <4.20
      , Cabal
      , Cabal-syntax
      , cabal-install-solver
-     , tasty       >= 1.2.3 && <1.5
+     , tasty       >= 1.2.3 && <1.6
      , tasty-quickcheck
      , tasty-hunit >= 0.10
diff --git a/cabal/cabal-install-solver/src/Distribution/Solver/Modular/Linking.hs b/cabal/cabal-install-solver/src/Distribution/Solver/Modular/Linking.hs
--- a/cabal/cabal-install-solver/src/Distribution/Solver/Modular/Linking.hs
+++ b/cabal/cabal-install-solver/src/Distribution/Solver/Modular/Linking.hs
@@ -1,4 +1,3 @@
-{-# LANGUAGE CPP #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
 
@@ -12,11 +11,10 @@
 import Distribution.Solver.Compat.Prelude hiding (get,put)
 
 import Control.Exception (assert)
-#if MIN_VERSION_mtl(2,3,0)
-import Control.Monad
-#endif
-import Control.Monad.Reader
-import Control.Monad.State
+import Control.Monad (forM_, zipWithM_)
+import Control.Monad.Reader (Reader, runReader, local, ask)
+import Control.Monad.State (MonadState, StateT, get, put, modify, execStateT)
+import Control.Monad.Trans (lift)
 import Data.Map ((!))
 import qualified Data.Map         as M
 import qualified Data.Set         as S
diff --git a/cabal/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs b/cabal/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs
--- a/cabal/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs
+++ b/cabal/cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs
@@ -162,7 +162,11 @@
     nonInstallable =
         L.map mkPackageName
              [ "base"
+             , "ghc-bignum"
              , "ghc-prim"
+             , "ghc-boot"
+             , "ghc"
+             , "ghci"
              , "integer-gmp"
              , "integer-simple"
              , "template-haskell"
diff --git a/cabal/cabal-install-solver/src/Distribution/Solver/Modular/Validate.hs b/cabal/cabal-install-solver/src/Distribution/Solver/Modular/Validate.hs
--- a/cabal/cabal-install-solver/src/Distribution/Solver/Modular/Validate.hs
+++ b/cabal/cabal-install-solver/src/Distribution/Solver/Modular/Validate.hs
@@ -12,10 +12,8 @@
 -- assignment returned by exploration of the tree should be a complete valid
 -- assignment, i.e., actually constitute a solution.
 
-#if MIN_VERSION_mtl(2,3,0)
-import Control.Monad
-#endif
-import Control.Monad.Reader
+import Control.Monad (foldM, mzero, liftM2)
+import Control.Monad.Reader (MonadReader, Reader, runReader, local, asks)
 import Data.Either (lefts)
 import Data.Function (on)
 
diff --git a/cabal/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs b/cabal/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs
--- a/cabal/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs
+++ b/cabal/cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE LambdaCase         #-}
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Distribution.Solver.Types.PkgConfigDb
@@ -23,17 +24,23 @@
 import Distribution.Solver.Compat.Prelude
 import Prelude ()
 
-import           Control.Exception (handle)
-import           Control.Monad     (mapM)
-import qualified Data.Map          as M
-import           System.FilePath   (splitSearchPath)
+import           Control.Exception        (handle)
+import           Control.Monad            (mapM)
+import           Data.ByteString          (ByteString)
+import qualified Data.ByteString.Lazy     as LBS
+import qualified Data.Map                 as M
+import qualified Data.Text                as T
+import qualified Data.Text.Encoding       as T
+import qualified Data.Text.Encoding.Error as T
+import           System.FilePath          (splitSearchPath)
 
 import Distribution.Compat.Environment          (lookupEnv)
 import Distribution.Package                     (PkgconfigName, mkPkgconfigName)
 import Distribution.Parsec
 import Distribution.Simple.Program
        (ProgramDb, getProgramOutput, pkgConfigProgram, needProgram, ConfiguredProgram)
-import Distribution.Simple.Program.Run          (getProgramInvocationOutputAndErrors, programInvocation)
+import Distribution.Simple.Program.Run
+       (getProgramInvocationOutputAndErrors, programInvocation, getProgramInvocationLBSAndErrors)
 import Distribution.Simple.Utils                (info)
 import Distribution.Types.PkgconfigVersion
 import Distribution.Types.PkgconfigVersionRange
@@ -63,19 +70,53 @@
     case mpkgConfig of
       Nothing             -> noPkgConfig "Cannot find pkg-config program"
       Just (pkgConfig, _) -> do
-        pkgList <- lines <$> getProgramOutput verbosity pkgConfig ["--list-all"]
-        -- The output of @pkg-config --list-all@ also includes a description
-        -- for each package, which we do not need.
-        let pkgNames = map (takeWhile (not . isSpace)) pkgList
-        (pkgVersions, _errs, exitCode) <-
+        -- To prevent malformed Unicode in the descriptions from crashing cabal,
+        -- read without interpreting any encoding first. (#9608)
+        (listAllOutput, listAllErrs, listAllExitcode) <-
+          getProgramInvocationLBSAndErrors verbosity (programInvocation pkgConfig ["--list-all"])
+        when (listAllExitcode /= ExitSuccess) $
+          ioError (userError ("pkg-config --list-all failed: " ++ listAllErrs))
+        let pkgList = LBS.split (fromIntegral (ord '\n')) listAllOutput
+        -- Now decode the package *names* to a String. The ones where decoding
+        -- failed end up in 'failedPkgNames'.
+        let (failedPkgNames, pkgNames) =
+              partitionEithers
+              -- Drop empty package names. This will handle empty lines
+              -- in pkg-config's output, including the spurious one
+              -- after the last newline (because of LBS.split).
+              . filter (either (const True) (not . null))
+              -- Try decoding strictly; if it fails, put the lenient
+              -- decoding in a Left for later reporting.
+              . map (\bsname ->
+                       let sbsname = LBS.toStrict bsname
+                       in case T.decodeUtf8' sbsname of
+                            Left _ -> Left (T.unpack (decodeUtf8LenientCompat sbsname))
+                            Right name -> Right (T.unpack name))
+              -- The output of @pkg-config --list-all@ also includes a
+              -- description for each package, which we do not need.
+              -- We don't use Data.Char.isSpace because that would also
+              -- include 0xA0, the non-breaking space, which can occur
+              -- in multi-byte UTF-8 sequences.
+              . map (LBS.takeWhile (not . isAsciiSpace))
+              $ pkgList
+        when (not (null failedPkgNames)) $
+          info verbosity ("Some pkg-config packages have names containing invalid unicode: " ++ intercalate ", " failedPkgNames)
+        (outs, _errs, exitCode) <-
                      getProgramInvocationOutputAndErrors verbosity
                        (programInvocation pkgConfig ("--modversion" : pkgNames))
-        case exitCode of
-          ExitSuccess -> (return . pkgConfigDbFromList . zip pkgNames) (lines pkgVersions)
-          -- if there's a single broken pc file the above fails, so we fall back into calling it individually
-          _ -> do
-             info verbosity ("call to pkg-config --modversion on all packages failed. Falling back to querying pkg-config individually on each package")
-             pkgConfigDbFromList . catMaybes <$> mapM (getIndividualVersion pkgConfig) pkgNames
+        let pkgVersions = lines outs
+        if exitCode == ExitSuccess && length pkgVersions == length pkgNames
+          then (return . pkgConfigDbFromList . zip pkgNames) pkgVersions
+          else
+          -- if there's a single broken pc file the above fails, so we fall back
+          -- into calling it individually
+          --
+          -- Also some implementations of @pkg-config@ do not provide more than
+          -- one package version, so if the returned list is shorter than the
+          -- requested one, we fall back to querying one by one.
+          do
+            info verbosity ("call to pkg-config --modversion on all packages failed. Falling back to querying pkg-config individually on each package")
+            pkgConfigDbFromList . catMaybes <$> mapM (getIndividualVersion pkgConfig) pkgNames
   where
     -- For when pkg-config invocation fails (possibly because of a
     -- too long command line).
@@ -96,6 +137,15 @@
        return $ case exitCode of
          ExitSuccess -> Just (pkg, pkgVersion)
          _ -> Nothing
+
+    isAsciiSpace :: Word8 -> Bool
+    isAsciiSpace c = c `elem` map (fromIntegral . ord) " \t"
+
+    -- The decodeUtf8Lenient function is defined starting with text-2.0.1; this
+    -- function simply reimplements it. When the minimum supported GHC version
+    -- is >= 9.4, switch to decodeUtf8Lenient.
+    decodeUtf8LenientCompat :: ByteString -> T.Text
+    decodeUtf8LenientCompat = T.decodeUtf8With T.lenientDecode
 
 -- | Create a `PkgConfigDb` from a list of @(packageName, version)@ pairs.
 pkgConfigDbFromList :: [(String, String)] -> PkgConfigDb
diff --git a/cabal/cabal-install/LICENSE b/cabal/cabal-install/LICENSE
--- a/cabal/cabal-install/LICENSE
+++ b/cabal/cabal-install/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2003-2022, Cabal Development Team.
+Copyright (c) 2003-2023, Cabal Development Team.
 See the AUTHORS file for the full list of copyright holders.
 
 See */LICENSE for the copyright holders of the subcomponents.
diff --git a/cabal/cabal-install/cabal-install.cabal b/cabal/cabal-install/cabal-install.cabal
--- a/cabal/cabal-install/cabal-install.cabal
+++ b/cabal/cabal-install/cabal-install.cabal
@@ -1,7 +1,7 @@
 Cabal-Version:      2.2
 
 Name:               cabal-install
-Version:            3.8.1.0
+Version:            3.10.3.0
 Synopsis:           The command-line interface for Cabal and Hackage.
 Description:
     The \'cabal\' command-line program simplifies the process of managing
@@ -13,12 +13,13 @@
 License-File:       LICENSE
 Author:             Cabal Development Team (see AUTHORS file)
 Maintainer:         Cabal Development Team <cabal-devel@haskell.org>
-Copyright:          2003-2022, Cabal Development Team
+Copyright:          2003-2023, Cabal Development Team
 Category:           Distribution
 Build-type:         Simple
 Extra-Source-Files:
-  README.md
   bash-completion/cabal
+extra-doc-files:
+  README.md
   changelog
 
 source-repository head
@@ -48,22 +49,27 @@
       ghc-options: -Wunused-packages
 
 common base-dep
-    build-depends: base >=4.10 && <4.18
+    build-depends: base >=4.10 && <4.20
 
 common cabal-dep
-    build-depends: Cabal ^>=3.8
+    build-depends: Cabal ^>=3.10.3
 
 common cabal-syntax-dep
-    build-depends: Cabal-syntax ^>=3.8
+    build-depends: Cabal-syntax ^>=3.10
 
 common cabal-install-solver-dep
-    build-depends: cabal-install-solver ^>=3.8
+    build-depends: cabal-install-solver ^>=3.10
 
 library
     import: warnings, base-dep, cabal-dep, cabal-syntax-dep, cabal-install-solver-dep
     default-language: Haskell2010
+    default-extensions: TypeOperators
 
     hs-source-dirs:   src
+    autogen-modules:
+        Paths_cabal_install
+    other-modules:
+        Paths_cabal_install
     exposed-modules:
         -- this modules are moved from Cabal
         -- they are needed for as long until cabal-install moves to parsec parser
@@ -85,6 +91,7 @@
         Distribution.Client.CmdExec
         Distribution.Client.CmdFreeze
         Distribution.Client.CmdHaddock
+        Distribution.Client.CmdHaddockProject
         Distribution.Client.CmdInstall
         Distribution.Client.CmdInstall.ClientInstallFlags
         Distribution.Client.CmdInstall.ClientInstallTargetSelector
@@ -100,7 +107,6 @@
         Distribution.Client.Compat.ExecutablePath
         Distribution.Client.Compat.Orphans
         Distribution.Client.Compat.Prelude
-        Distribution.Client.Compat.Process
         Distribution.Client.Compat.Semaphore
         Distribution.Client.Compat.Tar
         Distribution.Client.Config
@@ -142,6 +148,7 @@
         Distribution.Client.InstallSymlink
         Distribution.Client.JobControl
         Distribution.Client.List
+        Distribution.Client.Main
         Distribution.Client.Manpage
         Distribution.Client.ManpageFlags
         Distribution.Client.Nix
@@ -169,6 +176,7 @@
         Distribution.Client.Security.HTTP
         Distribution.Client.Setup
         Distribution.Client.SetupWrapper
+        Distribution.Client.Signal
         Distribution.Client.SolverInstallPlan
         Distribution.Client.SourceFiles
         Distribution.Client.SrcDist
@@ -206,17 +214,17 @@
         array      >= 0.4      && < 0.6,
         base16-bytestring >= 0.1.1 && < 1.1.0.0,
         binary     >= 0.7.3    && < 0.9,
-        bytestring >= 0.10.6.0 && < 0.12,
-        containers >= 0.5.6.2  && < 0.7,
+        bytestring >= 0.10.6.0 && < 0.13,
+        containers >= 0.5.6.2  && < 0.8,
         cryptohash-sha256 >= 0.11 && < 0.12,
-        directory  >= 1.2.2.0  && < 1.4,
+        directory  >= 1.3.7.0  && < 1.4,
         echo       >= 0.1.3    && < 0.2,
         edit-distance >= 0.2.2 && < 0.3,
         exceptions >= 0.10.4   && < 0.11,
-        filepath   >= 1.4.0.0  && < 1.5,
+        filepath   >= 1.4.0.0  && < 1.6,
         hashable   >= 1.0      && < 1.5,
         HTTP       >= 4000.1.5 && < 4000.5,
-        mtl        >= 2.0      && < 2.3,
+        mtl        >= 2.0      && < 2.4,
         network-uri >= 2.6.0.2 && < 2.7,
         pretty     >= 1.1      && < 1.2,
         process    >= 1.2.3.0  && < 1.7,
@@ -224,9 +232,9 @@
         stm        >= 2.0      && < 2.6,
         tar        >= 0.5.0.3  && < 0.7,
         time       >= 1.5.0.1  && < 1.13,
-        zlib       >= 0.5.3    && < 0.7,
+        zlib       >= 0.5.3    && < 0.8,
         hackage-security >= 0.6.2.0 && < 0.7,
-        text       >= 1.2.3    && < 1.3 || >= 2.0 && < 2.1,
+        text       >= 1.2.3    && < 1.3 || >= 2.0 && < 2.2,
         parsec     >= 3.1.13.0 && < 3.2,
         regex-base  >= 0.94.0.0 && <0.95,
         regex-posix >= 0.96.0.0 && <0.97,
@@ -236,7 +244,7 @@
       if os(windows)
         build-depends: windns      >= 0.1.0 && < 0.2
       else
-        build-depends: resolv      >= 0.1.1 && < 0.2
+        build-depends: resolv      >= 0.1.1 && < 0.3
 
     if os(windows)
       -- newer directory for symlinks
@@ -253,7 +261,7 @@
 
 
 executable cabal
-    import: warnings, base-dep, cabal-dep, cabal-syntax-dep
+    import: warnings, base-dep
     main-is: Main.hs
     hs-source-dirs: main
     default-language: Haskell2010
@@ -265,15 +273,14 @@
         extra-libraries: bsd
 
     build-depends:
-        cabal-install,
-        directory,
-        filepath
+        cabal-install
 
 -- Small, fast running tests.
 --
 test-suite unit-tests
     import: warnings, base-dep, cabal-dep, cabal-syntax-dep, cabal-install-solver-dep
     default-language: Haskell2010
+    default-extensions: TypeOperators
     ghc-options: -rtsopts -threaded
 
     type: exitcode-stdio-1.0
@@ -330,12 +337,12 @@
           tar,
           time,
           zlib,
-          tasty >= 1.2.3 && <1.5,
+          tasty >= 1.2.3 && <1.6,
           tasty-golden >=2.3.1.1 && <2.4,
           tasty-quickcheck,
           tasty-hunit >= 0.10,
           tree-diff,
-          QuickCheck >= 2.14 && <2.15
+          QuickCheck >= 2.14.3 && <2.15
 
 
 -- Tests to run with a limited stack and heap size
@@ -360,7 +367,7 @@
   build-depends:
         cabal-install,
         containers,
-        tasty >= 1.2.3 && <1.5,
+        tasty >= 1.2.3 && <1.6,
         tasty-hunit >= 0.10
 
 
@@ -380,7 +387,7 @@
         containers,
         directory,
         filepath,
-        tasty >= 1.2.3 && <1.5,
+        tasty >= 1.2.3 && <1.6,
         tasty-hunit >= 0.10,
         tagged
 
@@ -416,7 +423,7 @@
         network-uri >= 2.6.2.0 && <2.7,
         random,
         tagged,
-        tasty >= 1.2.3 && <1.5,
+        tasty >= 1.2.3 && <1.6,
         tasty-expected-failure,
         tasty-hunit >= 0.10,
         tasty-quickcheck,
diff --git a/cabal/cabal-install/changelog b/cabal/cabal-install/changelog
--- a/cabal/cabal-install/changelog
+++ b/cabal/cabal-install/changelog
@@ -1,5 +1,17 @@
 -*-change-log-*-
 
+3.10.3.0 Hécate <hecate+github@glitchbra.in> January 2024
+	* See https://github.com/haskell/cabal/blob/master/release-notes/cabal-install-3.10.3.0.md
+
+3.10.2.1 Hécate <hecate+github@glitchbra.in> November 2023
+	* See https://github.com/haskell/cabal/blob/master/release-notes/cabal-install-3.10.2.1.md
+
+3.10.2.0 Hécate <hecate+github@glitchbra.in> November 2023
+	* See https://github.com/haskell/cabal/blob/master/release-notes/cabal-install-3.10.2.0.md
+
+3.10.1.0 Mikolaj Konarski <mikolaj@well-typed.com> March 2023
+	* See https://github.com/haskell/cabal/blob/master/release-notes/cabal-install-3.10.1.0.md
+
 3.8.1.0 Mikolaj Konarski <mikolaj@well-typed.com> August 2022
 	* See https://github.com/haskell/cabal/blob/master/release-notes/cabal-install-3.8.1.0.md
 
@@ -169,7 +181,7 @@
 	* Default changelog generated by 'cabal init' is now named
 	  'CHANGELOG.md' (#5441).
 	* Align output of 'new-build' command phases (#4040).
-	* Add suport for specifying remote VCS dependencies via new
+	* Add support for specifying remote VCS dependencies via new
 	  'source-repository-package' stanzas in 'cabal.project' files
 	  (#5351).
 
@@ -206,7 +218,7 @@
 	* Use [lfxtb] letters to differentiate component kind instead of
 	opaque "c" in dist-dir layout.
 	* 'cabal configure' now supports '--enable-static', which can be
-	used to build static libaries with GHC via GHC's `-staticlib`
+	used to build static libraries with GHC via GHC's `-staticlib`
 	flag.
 	* 'cabal user-config now supports '--augment' which can append
 	additional lines to a new or updated cabal config file.
@@ -226,7 +238,7 @@
 	when it wasn't necessary (#4444).
 	* Packages installed in sandboxes via 'add-source' now have
 	their timestamps updated correctly and so will not be reinstalled
-	unncecessarily if the main install command fails (#1375).
+	unnecessarily if the main install command fails (#1375).
 	* Add Windows device path support for copyFile, renameFile. Allows cabal
 	new-build to use temporary store path of up to 32k length
 	(#3972, #4914, #4515).
@@ -577,9 +589,9 @@
 	* Improved bootstrap.sh
 
 0.5.2 Duncan Coutts <duncan@haskell.org> Aug 2008
-	* Suport building haddock documentaion
+	* Support building haddock documentation
 	* Self-reinstall now works on Windows
-	* Allow adding symlinks to excutables into a separate bindir
+	* Allow adding symlinks to executables into a separate bindir
 	* New self-documenting config file
 	* New install --reinstall flag
 	* More helpful status messages in a couple places
diff --git a/cabal/cabal-install/main/Main.hs b/cabal/cabal-install/main/Main.hs
--- a/cabal/cabal-install/main/Main.hs
+++ b/cabal/cabal-install/main/Main.hs
@@ -1,980 +1,11 @@
-{-# LANGUAGE CPP #-}
-
------------------------------------------------------------------------------
--- |
--- Module      :  Main
--- Copyright   :  (c) David Himmelstrup 2005
--- License     :  BSD-like
---
--- Maintainer  :  lemmih@gmail.com
--- Stability   :  provisional
--- Portability :  portable
---
--- Entry point to the default cabal-install front-end.
------------------------------------------------------------------------------
-
 module Main (main) where
 
-import Distribution.Client.Setup
-         ( GlobalFlags(..), globalCommand, withRepoContext
-         , ConfigFlags(..)
-         , ConfigExFlags(..), defaultConfigExFlags, configureExCommand
-         , reconfigureCommand
-         , configCompilerAux', configPackageDB'
-         , BuildFlags(..)
-         , buildCommand, replCommand, testCommand, benchmarkCommand
-         , InstallFlags(..), defaultInstallFlags
-         , installCommand
-         , FetchFlags(..), fetchCommand
-         , FreezeFlags(..), freezeCommand
-         , genBoundsCommand
-         , GetFlags(..), getCommand, unpackCommand
-         , checkCommand
-         , formatCommand
-         , ListFlags(..), listCommand, listNeedsCompiler
-         , InfoFlags(..), infoCommand
-         , UploadFlags(..), uploadCommand
-         , ReportFlags(..), reportCommand
-         , runCommand
-         , InitFlags(initVerbosity, initHcPath), initCommand
-         , ActAsSetupFlags(..), actAsSetupCommand
-         , UserConfigFlags(..), userConfigCommand
-         , reportCommand
-         , manpageCommand
-         , haddockCommand
-         , cleanCommand
-         , copyCommand
-         , registerCommand
-         )
-import Distribution.Simple.Setup
-         ( HaddockTarget(..)
-         , HaddockFlags(..), defaultHaddockFlags
-         , HscolourFlags(..), hscolourCommand
-         , ReplFlags(..)
-         , CopyFlags(..)
-         , RegisterFlags(..)
-         , CleanFlags(..)
-         , TestFlags(..), BenchmarkFlags(..)
-         , Flag(..), fromFlag, fromFlagOrDefault, flagToMaybe, toFlag
-         , configAbsolutePaths
-         )
-
 import Prelude ()
-import Distribution.Client.Compat.Prelude hiding (get)
-
-import Distribution.Client.SetupWrapper
-         ( setupWrapper, SetupScriptOptions(..), defaultSetupScriptOptions )
-import Distribution.Client.Config
-         ( SavedConfig(..), loadConfig, defaultConfigFile, userConfigDiff
-         , userConfigUpdate, createDefaultConfigFile, getConfigFilePath )
-import Distribution.Client.Targets
-         ( readUserTargets )
-import qualified Distribution.Client.List as List
-         ( list, info )
-
-import qualified Distribution.Client.CmdConfigure as CmdConfigure
-import qualified Distribution.Client.CmdUpdate    as CmdUpdate
-import qualified Distribution.Client.CmdBuild     as CmdBuild
-import qualified Distribution.Client.CmdRepl      as CmdRepl
-import qualified Distribution.Client.CmdFreeze    as CmdFreeze
-import qualified Distribution.Client.CmdHaddock   as CmdHaddock
-import qualified Distribution.Client.CmdInstall   as CmdInstall
-import qualified Distribution.Client.CmdRun       as CmdRun
-import qualified Distribution.Client.CmdTest      as CmdTest
-import qualified Distribution.Client.CmdBench     as CmdBench
-import qualified Distribution.Client.CmdExec      as CmdExec
-import qualified Distribution.Client.CmdClean     as CmdClean
-import qualified Distribution.Client.CmdSdist     as CmdSdist
-import qualified Distribution.Client.CmdListBin   as CmdListBin
-import qualified Distribution.Client.CmdOutdated  as CmdOutdated
-import           Distribution.Client.CmdLegacy
-
-import Distribution.Client.Install            (install)
-import Distribution.Client.Configure          (configure, writeConfigFlags)
-import Distribution.Client.Fetch              (fetch)
-import Distribution.Client.Freeze             (freeze)
-import Distribution.Client.GenBounds          (genBounds)
-import Distribution.Client.Check as Check     (check)
---import Distribution.Client.Clean            (clean)
-import qualified Distribution.Client.Upload as Upload
-import Distribution.Client.Run                (run, splitRunArgs)
-import Distribution.Client.Get                (get)
-import Distribution.Client.Reconfigure        (Check(..), reconfigure)
-import Distribution.Client.Nix                (nixInstantiate
-                                              ,nixShell
-                                              )
-import Distribution.Client.Sandbox            (loadConfigOrSandboxConfig
-                                              ,findSavedDistPref
-                                              ,updateInstallDirs)
-import Distribution.Client.Tar                (createTarGzFile)
-import Distribution.Client.Types.Credentials  (Password (..))
-import Distribution.Client.Init               (initCmd)
-import Distribution.Client.Manpage            (manpageCmd)
-import Distribution.Client.ManpageFlags       (ManpageFlags (..))
-import Distribution.Client.Utils
-         ( determineNumJobs, relaxEncodingErrors )
-import Distribution.Client.Version
-         ( cabalInstallVersion )
-
-import Distribution.Package (packageId)
-import Distribution.PackageDescription
-         ( BuildType(..), Executable(..), buildable )
-
-import Distribution.PackageDescription.PrettyPrint
-         ( writeGenericPackageDescription )
-import qualified Distribution.Simple as Simple
-import qualified Distribution.Make as Make
-import qualified Distribution.Types.UnqualComponentName as Make
-import Distribution.Simple.Build
-         ( startInterpreter )
-import Distribution.Simple.Command
-         ( CommandParse(..), CommandUI(..), Command, CommandSpec(..)
-         , CommandType(..), commandsRun, commandAddAction, hiddenCommand
-         , commandFromSpec, commandShowOptions )
-import Distribution.Simple.Compiler (PackageDBStack)
-import Distribution.Simple.Configure
-         ( configCompilerAuxEx, ConfigStateFileError(..)
-         , getPersistBuildConfig, interpretPackageDbFlags
-         , tryGetPersistBuildConfig )
-import qualified Distribution.Simple.LocalBuildInfo as LBI
-import Distribution.Simple.PackageDescription ( readGenericPackageDescription )
-import Distribution.Simple.Program (defaultProgramDb
-                                   ,configureAllKnownPrograms
-                                   ,simpleProgramInvocation
-                                   ,getProgramInvocationOutput)
-import Distribution.Simple.Program.Db (reconfigurePrograms)
-import qualified Distribution.Simple.Setup as Cabal
-import Distribution.Simple.Utils
-         ( cabalVersion, die', dieNoVerbosity, info, notice, topHandler
-         , findPackageDesc, tryFindPackageDesc, createDirectoryIfMissingVerbose )
-import Distribution.Text
-         ( display )
-import Distribution.Verbosity as Verbosity
-         ( normal )
-import Distribution.Version
-         ( Version, mkVersion, orLaterVersion )
+import Distribution.Client.Compat.Prelude
 
-import Distribution.Compat.ResponseFile
-import System.Environment       (getArgs, getProgName)
-import System.FilePath          ( dropExtension, splitExtension
-                                , takeExtension, (</>), (<.>) )
-import System.IO                ( BufferMode(LineBuffering), hSetBuffering
-                                , stderr, stdout )
-import System.Directory         ( doesFileExist, getCurrentDirectory
-                                , withCurrentDirectory)
-import Data.Monoid              (Any(..))
-import Control.Exception        (try)
+import System.Environment (getArgs)
 
+import qualified Distribution.Client.Main as Client
 
--- | Entry point
---
 main :: IO ()
-main = do
-  -- Enable line buffering so that we can get fast feedback even when piped.
-  -- This is especially important for CI and build systems.
-  hSetBuffering stdout LineBuffering
-  -- If the locale encoding for CLI doesn't support all Unicode characters,
-  -- printing to it may fail unless we relax the handling of encoding errors
-  -- when writing to stderr and stdout.
-  relaxEncodingErrors stdout
-  relaxEncodingErrors stderr
-  (args0, args1) <- break (== "--") <$> getArgs
-  mainWorker =<< (++ args1) <$> expandResponse args0
-
-mainWorker :: [String] -> IO ()
-mainWorker args = do
-  maybeScriptAndArgs <- case args of
-    []     -> return Nothing
-    (h:tl) -> (\b -> if b then Just (h:|tl) else Nothing) <$> CmdRun.validScript h
-
-  topHandler $
-    case commandsRun (globalCommand commands) commands args of
-      CommandHelp   help                 -> printGlobalHelp help
-      CommandList   opts                 -> printOptionsList opts
-      CommandErrors errs                 -> printErrors errs
-      CommandReadyToGo (globalFlags, commandParse)  ->
-        case commandParse of
-          _ | fromFlagOrDefault False (globalVersion globalFlags)
-              -> printVersion
-            | fromFlagOrDefault False (globalNumericVersion globalFlags)
-              -> printNumericVersion
-          CommandHelp     help           -> printCommandHelp help
-          CommandList     opts           -> printOptionsList opts
-          CommandErrors   errs           -> maybe (printErrors errs) go maybeScriptAndArgs where
-            go (script:|scriptArgs) = CmdRun.handleShebang script scriptArgs
-          CommandReadyToGo action        -> action globalFlags
-
-  where
-    printCommandHelp help = do
-      pname <- getProgName
-      putStr (help pname)
-    printGlobalHelp help = do
-      pname <- getProgName
-      configFile <- defaultConfigFile
-      putStr (help pname)
-      putStr $ "\nYou can edit the cabal configuration file to set defaults:\n"
-            ++ "  " ++ configFile ++ "\n"
-      exists <- doesFileExist configFile
-      unless exists $
-          putStrLn $ "This file will be generated with sensible "
-                  ++ "defaults if you run 'cabal update'."
-    printOptionsList = putStr . unlines
-    printErrors errs = dieNoVerbosity $ intercalate "\n" errs
-    printNumericVersion = putStrLn $ display cabalInstallVersion
-    printVersion        = putStrLn $ "cabal-install version "
-                                  ++ display cabalInstallVersion
-                                  ++ "\ncompiled using version "
-                                  ++ display cabalVersion
-                                  ++ " of the Cabal library "
-
-    commands = map commandFromSpec commandSpecs
-    commandSpecs =
-      [ regularCmd listCommand listAction
-      , regularCmd infoCommand infoAction
-      , regularCmd fetchCommand fetchAction
-      , regularCmd getCommand getAction
-      , regularCmd unpackCommand unpackAction
-      , regularCmd checkCommand checkAction
-      , regularCmd uploadCommand uploadAction
-      , regularCmd reportCommand reportAction
-      , regularCmd initCommand initAction
-      , regularCmd userConfigCommand userConfigAction
-      , regularCmd genBoundsCommand genBoundsAction
-      , regularCmd CmdOutdated.outdatedCommand CmdOutdated.outdatedAction
-      , wrapperCmd hscolourCommand hscolourVerbosity hscolourDistPref
-      , hiddenCmd  formatCommand formatAction
-      , hiddenCmd  actAsSetupCommand actAsSetupAction
-      , hiddenCmd  manpageCommand (manpageAction commandSpecs)
-      , regularCmd CmdListBin.listbinCommand     CmdListBin.listbinAction
-
-      ] ++ concat
-      [ newCmd  CmdConfigure.configureCommand CmdConfigure.configureAction
-      , newCmd  CmdUpdate.updateCommand       CmdUpdate.updateAction
-      , newCmd  CmdBuild.buildCommand         CmdBuild.buildAction
-      , newCmd  CmdRepl.replCommand           CmdRepl.replAction
-      , newCmd  CmdFreeze.freezeCommand       CmdFreeze.freezeAction
-      , newCmd  CmdHaddock.haddockCommand     CmdHaddock.haddockAction
-      , newCmd  CmdInstall.installCommand     CmdInstall.installAction
-      , newCmd  CmdRun.runCommand             CmdRun.runAction
-      , newCmd  CmdTest.testCommand           CmdTest.testAction
-      , newCmd  CmdBench.benchCommand         CmdBench.benchAction
-      , newCmd  CmdExec.execCommand           CmdExec.execAction
-      , newCmd  CmdClean.cleanCommand         CmdClean.cleanAction
-      , newCmd  CmdSdist.sdistCommand         CmdSdist.sdistAction
-
-      , legacyCmd configureExCommand configureAction
-      , legacyCmd buildCommand buildAction
-      , legacyCmd replCommand replAction
-      , legacyCmd freezeCommand freezeAction
-      , legacyCmd haddockCommand haddockAction
-      , legacyCmd installCommand installAction
-      , legacyCmd runCommand runAction
-      , legacyCmd testCommand testAction
-      , legacyCmd benchmarkCommand benchmarkAction
-      , legacyCmd cleanCommand cleanAction
-      , legacyWrapperCmd copyCommand copyVerbosity copyDistPref
-      , legacyWrapperCmd registerCommand regVerbosity regDistPref
-      , legacyCmd reconfigureCommand reconfigureAction
-      ]
-
-type Action = GlobalFlags -> IO ()
-
--- Duplicated in Distribution.Client.CmdLegacy. Any changes must be
--- reflected there, as well.
-regularCmd :: CommandUI flags -> (flags -> [String] -> action)
-           -> CommandSpec action
-regularCmd ui action =
-  CommandSpec ui ((flip commandAddAction) action) NormalCommand
-
-hiddenCmd :: CommandUI flags -> (flags -> [String] -> action)
-          -> CommandSpec action
-hiddenCmd ui action =
-  CommandSpec ui (\ui' -> hiddenCommand (commandAddAction ui' action))
-  HiddenCommand
-
-wrapperCmd :: Monoid flags => CommandUI flags -> (flags -> Flag Verbosity)
-           -> (flags -> Flag String) -> CommandSpec Action
-wrapperCmd ui verbosity distPref =
-  CommandSpec ui (\ui' -> wrapperAction ui' verbosity distPref) NormalCommand
-
-wrapperAction :: Monoid flags
-              => CommandUI flags
-              -> (flags -> Flag Verbosity)
-              -> (flags -> Flag String)
-              -> Command Action
-wrapperAction command verbosityFlag distPrefFlag =
-  commandAddAction command
-    { commandDefaultFlags = mempty } $ \flags extraArgs globalFlags -> do
-    let verbosity = fromFlagOrDefault normal (verbosityFlag flags)
-    load <- try (loadConfigOrSandboxConfig verbosity globalFlags)
-    let config = either (\(SomeException _) -> mempty) id load
-    distPref <- findSavedDistPref config (distPrefFlag flags)
-    let setupScriptOptions = defaultSetupScriptOptions { useDistPref = distPref }
-    setupWrapper verbosity setupScriptOptions Nothing
-                 command (const flags) (const extraArgs)
-
-configureAction :: (ConfigFlags, ConfigExFlags)
-                -> [String] -> Action
-configureAction (configFlags, configExFlags) extraArgs globalFlags = do
-  let verbosity = fromFlagOrDefault normal (configVerbosity configFlags)
-  config <- updateInstallDirs (configUserInstall configFlags)
-                          <$> loadConfigOrSandboxConfig verbosity globalFlags
-  distPref <- findSavedDistPref config (configDistPref configFlags)
-  nixInstantiate verbosity distPref True globalFlags config
-  nixShell verbosity distPref globalFlags config $ do
-    let configFlags'   = savedConfigureFlags   config `mappend` configFlags
-        configExFlags' = savedConfigureExFlags config `mappend` configExFlags
-        globalFlags'   = savedGlobalFlags      config `mappend` globalFlags
-    (comp, platform, progdb) <- configCompilerAuxEx configFlags'
-
-    writeConfigFlags verbosity distPref (configFlags', configExFlags')
-
-    -- What package database(s) to use
-    let packageDBs :: PackageDBStack
-        packageDBs
-          = interpretPackageDbFlags
-            (fromFlag (configUserInstall configFlags'))
-            (configPackageDBs configFlags')
-
-    withRepoContext verbosity globalFlags' $ \repoContext ->
-        configure verbosity packageDBs repoContext
-                  comp platform progdb configFlags' configExFlags' extraArgs
-
-reconfigureAction :: (ConfigFlags, ConfigExFlags)
-                  -> [String] -> Action
-reconfigureAction flags@(configFlags, _) _ globalFlags = do
-  let verbosity = fromFlagOrDefault normal (configVerbosity configFlags)
-  config <- updateInstallDirs (configUserInstall configFlags)
-                          <$> loadConfigOrSandboxConfig verbosity globalFlags
-  distPref <- findSavedDistPref config (configDistPref configFlags)
-  let checkFlags = Check $ \_ saved -> do
-        let flags' = saved <> flags
-        unless (saved == flags') $ info verbosity message
-        pure (Any True, flags')
-        where
-          -- This message is correct, but not very specific: it will list all
-          -- of the new flags, even if some have not actually changed. The
-          -- *minimal* set of changes is more difficult to determine.
-          message =
-            "flags changed: "
-            ++ unwords (commandShowOptions configureExCommand flags)
-  nixInstantiate verbosity distPref True globalFlags config
-  _ <-
-    reconfigure configureAction
-    verbosity distPref NoFlag
-    checkFlags [] globalFlags config
-  pure ()
-
-buildAction :: BuildFlags -> [String] -> Action
-buildAction buildFlags extraArgs globalFlags = do
-  let verbosity = fromFlagOrDefault normal (buildVerbosity buildFlags)
-  config <- loadConfigOrSandboxConfig verbosity globalFlags
-  distPref <- findSavedDistPref config (buildDistPref buildFlags)
-  -- Calls 'configureAction' to do the real work, so nothing special has to be
-  -- done to support sandboxes.
-  config' <-
-    reconfigure configureAction
-    verbosity distPref (buildNumJobs buildFlags)
-    mempty [] globalFlags config
-  nixShell verbosity distPref globalFlags config $ do
-    build verbosity config' distPref buildFlags extraArgs
-
-
--- | Actually do the work of building the package. This is separate from
--- 'buildAction' so that 'testAction' and 'benchmarkAction' do not invoke
--- 'reconfigure' twice.
-build :: Verbosity -> SavedConfig -> FilePath -> BuildFlags -> [String] -> IO ()
-build verbosity config distPref buildFlags extraArgs =
-  setupWrapper verbosity setupOptions Nothing
-               (Cabal.buildCommand progDb) mkBuildFlags (const extraArgs)
-  where
-    progDb       = defaultProgramDb
-    setupOptions = defaultSetupScriptOptions { useDistPref = distPref }
-
-    mkBuildFlags version = filterBuildFlags version config buildFlags'
-    buildFlags' = buildFlags
-      { buildVerbosity = toFlag verbosity
-      , buildDistPref  = toFlag distPref
-      }
-
--- | Make sure that we don't pass new flags to setup scripts compiled against
--- old versions of Cabal.
-filterBuildFlags :: Version -> SavedConfig -> BuildFlags -> BuildFlags
-filterBuildFlags version config buildFlags
-  | version >= mkVersion [1,19,1] = buildFlags_latest
-  -- Cabal < 1.19.1 doesn't support 'build -j'.
-  | otherwise                      = buildFlags_pre_1_19_1
-  where
-    buildFlags_pre_1_19_1 = buildFlags {
-      buildNumJobs = NoFlag
-      }
-    buildFlags_latest     = buildFlags {
-      -- Take the 'jobs' setting '~/.cabal/config' into account.
-      buildNumJobs = Flag . Just . determineNumJobs $
-                     (numJobsConfigFlag `mappend` numJobsCmdLineFlag)
-      }
-    numJobsConfigFlag  = installNumJobs . savedInstallFlags $ config
-    numJobsCmdLineFlag = buildNumJobs buildFlags
-
-
-replAction :: ReplFlags -> [String] -> Action
-replAction replFlags extraArgs globalFlags = do
-  let verbosity = fromFlagOrDefault normal (replVerbosity replFlags)
-  config <- loadConfigOrSandboxConfig verbosity globalFlags
-  distPref <- findSavedDistPref config (replDistPref replFlags)
-  cwd     <- getCurrentDirectory
-  pkgDesc <- findPackageDesc cwd
-  let
-    -- There is a .cabal file in the current directory: start a REPL and load
-    -- the project's modules.
-    onPkgDesc = do
-      -- Calls 'configureAction' to do the real work, so nothing special has to
-      -- be done to support sandboxes.
-      _ <-
-        reconfigure configureAction
-        verbosity distPref NoFlag
-        mempty [] globalFlags config
-      let progDb = defaultProgramDb
-          setupOptions = defaultSetupScriptOptions
-            { useCabalVersion = orLaterVersion $ mkVersion [1,18,0]
-            , useDistPref     = distPref
-            }
-          replFlags'   = replFlags
-            { replVerbosity = toFlag verbosity
-            , replDistPref  = toFlag distPref
-            }
-
-      nixShell verbosity distPref globalFlags config $
-        setupWrapper verbosity setupOptions Nothing (Cabal.replCommand progDb) (const replFlags') (const extraArgs)
-
-    -- No .cabal file in the current directory: just start the REPL (possibly
-    -- using the sandbox package DB).
-    onNoPkgDesc = do
-      let configFlags = savedConfigureFlags config
-      (comp, platform, programDb) <- configCompilerAux' configFlags
-      programDb' <- reconfigurePrograms verbosity
-                                        (replProgramPaths replFlags)
-                                        (replProgramArgs replFlags)
-                                        programDb
-      nixShell verbosity distPref globalFlags config $ do
-        startInterpreter verbosity programDb' comp platform
-                        (configPackageDB' configFlags)
-
-  either (const onNoPkgDesc) (const onPkgDesc) pkgDesc
-
-installAction :: ( ConfigFlags, ConfigExFlags, InstallFlags
-                 , HaddockFlags, TestFlags, BenchmarkFlags )
-              -> [String] -> Action
-installAction (configFlags, _, installFlags, _, _, _) _ globalFlags
-  | fromFlagOrDefault False (installOnly installFlags) = do
-      let verb = fromFlagOrDefault normal (configVerbosity configFlags)
-      config <- loadConfigOrSandboxConfig verb globalFlags
-      dist <- findSavedDistPref config (configDistPref configFlags)
-      let setupOpts = defaultSetupScriptOptions { useDistPref = dist }
-      setupWrapper
-        verb setupOpts Nothing
-        installCommand (const (mempty, mempty, mempty, mempty, mempty, mempty))
-                       (const [])
-
-installAction
-  ( configFlags, configExFlags, installFlags
-  , haddockFlags, testFlags, benchmarkFlags )
-  extraArgs globalFlags = do
-  let verb = fromFlagOrDefault normal (configVerbosity configFlags)
-  config <- updateInstallDirs (configUserInstall configFlags)
-                          <$> loadConfigOrSandboxConfig verb globalFlags
-
-  dist <- findSavedDistPref config (configDistPref configFlags)
-
-  do
-    targets <- readUserTargets verb extraArgs
-
-    let configFlags'    = maybeForceTests installFlags' $
-                          savedConfigureFlags   config `mappend`
-                          configFlags { configDistPref = toFlag dist }
-        configExFlags'  = defaultConfigExFlags         `mappend`
-                          savedConfigureExFlags config `mappend` configExFlags
-        installFlags'   = defaultInstallFlags          `mappend`
-                          savedInstallFlags     config `mappend` installFlags
-        haddockFlags'   = defaultHaddockFlags          `mappend`
-                          savedHaddockFlags     config `mappend`
-                          haddockFlags { haddockDistPref = toFlag dist }
-        testFlags'      = Cabal.defaultTestFlags       `mappend`
-                          savedTestFlags        config `mappend`
-                          testFlags { testDistPref = toFlag dist }
-        benchmarkFlags' = Cabal.defaultBenchmarkFlags  `mappend`
-                          savedBenchmarkFlags   config `mappend`
-                          benchmarkFlags { benchmarkDistPref = toFlag dist }
-        globalFlags'    = savedGlobalFlags      config `mappend` globalFlags
-    (comp, platform, progdb) <- configCompilerAux' configFlags'
-
-    -- TODO: Redesign ProgramDB API to prevent such problems as #2241 in the
-    -- future.
-    progdb' <- configureAllKnownPrograms verb progdb
-
-    configFlags'' <- configAbsolutePaths configFlags'
-
-    withRepoContext verb globalFlags' $ \repoContext ->
-        install verb
-                (configPackageDB' configFlags'')
-                repoContext
-                comp platform progdb'
-                globalFlags' configFlags'' configExFlags'
-                installFlags' haddockFlags' testFlags' benchmarkFlags'
-                targets
-
-      where
-        -- '--run-tests' implies '--enable-tests'.
-        maybeForceTests installFlags' configFlags' =
-          if fromFlagOrDefault False (installRunTests installFlags')
-          then configFlags' { configTests = toFlag True }
-          else configFlags'
-
-testAction :: (BuildFlags, TestFlags) -> [String] -> GlobalFlags
-           -> IO ()
-testAction (buildFlags, testFlags) extraArgs globalFlags = do
-  let verbosity      = fromFlagOrDefault normal (buildVerbosity buildFlags)
-  config <- loadConfigOrSandboxConfig verbosity globalFlags
-  distPref <- findSavedDistPref config (testDistPref testFlags)
-  let buildFlags'    = buildFlags
-                      { buildVerbosity = testVerbosity testFlags }
-      checkFlags = Check $ \_ flags@(configFlags, configExFlags) ->
-        if fromFlagOrDefault False (configTests configFlags)
-          then pure (mempty, flags)
-          else do
-            info verbosity "reconfiguring to enable tests"
-            let flags' = ( configFlags { configTests = toFlag True }
-                        , configExFlags
-                        )
-            pure (Any True, flags')
-
-  _ <-
-    reconfigure configureAction
-    verbosity distPref (buildNumJobs buildFlags')
-    checkFlags [] globalFlags config
-  nixShell verbosity distPref globalFlags config $ do
-    let setupOptions   = defaultSetupScriptOptions { useDistPref = distPref }
-        testFlags'     = testFlags { testDistPref = toFlag distPref }
-
-    -- The package was just configured, so the LBI must be available.
-    names <- componentNamesFromLBI verbosity distPref "test suites"
-              (\c -> case c of { LBI.CTest{} -> True; _ -> False })
-    let extraArgs'
-          | null extraArgs = case names of
-            ComponentNamesUnknown -> []
-            ComponentNames names' -> [ Make.unUnqualComponentName name
-                                    | LBI.CTestName name <- names' ]
-          | otherwise      = extraArgs
-
-    build verbosity config distPref buildFlags' extraArgs'
-    setupWrapper verbosity setupOptions Nothing Cabal.testCommand (const testFlags') (const extraArgs')
-
-data ComponentNames = ComponentNamesUnknown
-                    | ComponentNames [LBI.ComponentName]
-
--- | Return the names of all buildable components matching a given predicate.
-componentNamesFromLBI :: Verbosity -> FilePath -> String
-                         -> (LBI.Component -> Bool)
-                         -> IO ComponentNames
-componentNamesFromLBI verbosity distPref targetsDescr compPred = do
-  eLBI <- tryGetPersistBuildConfig distPref
-  case eLBI of
-    Left err -> case err of
-      -- Note: the build config could have been generated by a custom setup
-      -- script built against a different Cabal version, so it's crucial that
-      -- we ignore the bad version error here.
-      ConfigStateFileBadVersion _ _ _ -> return ComponentNamesUnknown
-      _                               -> die' verbosity (show err)
-    Right lbi -> do
-      let pkgDescr = LBI.localPkgDescr lbi
-          names    = map LBI.componentName
-                     . filter (buildable . LBI.componentBuildInfo)
-                     . filter compPred $
-                     LBI.pkgComponents pkgDescr
-      if null names
-        then do notice verbosity $ "Package has no buildable "
-                  ++ targetsDescr ++ "."
-                exitSuccess -- See #3215.
-
-        else return $! (ComponentNames names)
-
-benchmarkAction :: (BuildFlags, BenchmarkFlags)
-                   -> [String] -> GlobalFlags
-                   -> IO ()
-benchmarkAction
-  (buildFlags, benchmarkFlags)
-  extraArgs globalFlags = do
-  let verbosity      = fromFlagOrDefault normal
-                       (buildVerbosity buildFlags)
-
-  config <- loadConfigOrSandboxConfig verbosity globalFlags
-  distPref <- findSavedDistPref config (benchmarkDistPref benchmarkFlags)
-  let buildFlags'    = buildFlags
-                      { buildVerbosity = benchmarkVerbosity benchmarkFlags }
-
-  let checkFlags = Check $ \_ flags@(configFlags, configExFlags) ->
-        if fromFlagOrDefault False (configBenchmarks configFlags)
-          then pure (mempty, flags)
-          else do
-            info verbosity "reconfiguring to enable benchmarks"
-            let flags' = ( configFlags { configBenchmarks = toFlag True }
-                        , configExFlags
-                        )
-            pure (Any True, flags')
-
-  config' <-
-    reconfigure configureAction
-    verbosity distPref (buildNumJobs buildFlags')
-    checkFlags [] globalFlags config
-  nixShell verbosity distPref globalFlags config $ do
-    let setupOptions   = defaultSetupScriptOptions { useDistPref = distPref }
-        benchmarkFlags'= benchmarkFlags { benchmarkDistPref = toFlag distPref }
-
-    -- The package was just configured, so the LBI must be available.
-    names <- componentNamesFromLBI verbosity distPref "benchmarks"
-            (\c -> case c of { LBI.CBench{} -> True; _ -> False; })
-    let extraArgs'
-          | null extraArgs = case names of
-            ComponentNamesUnknown -> []
-            ComponentNames names' -> [ Make.unUnqualComponentName name
-                                    | LBI.CBenchName name <- names']
-          | otherwise      = extraArgs
-
-    build verbosity config' distPref buildFlags' extraArgs'
-    setupWrapper verbosity setupOptions Nothing Cabal.benchmarkCommand (const benchmarkFlags') (const extraArgs')
-
-haddockAction :: HaddockFlags -> [String] -> Action
-haddockAction haddockFlags extraArgs globalFlags = do
-  let verbosity = fromFlag (haddockVerbosity haddockFlags)
-  config <- loadConfigOrSandboxConfig verbosity globalFlags
-  distPref <- findSavedDistPref config (haddockDistPref haddockFlags)
-  config' <-
-    reconfigure configureAction
-    verbosity distPref NoFlag
-    mempty [] globalFlags config
-  nixShell verbosity distPref globalFlags config $ do
-    let haddockFlags' = defaultHaddockFlags      `mappend`
-                        savedHaddockFlags config' `mappend`
-                        haddockFlags { haddockDistPref = toFlag distPref }
-        setupScriptOptions = defaultSetupScriptOptions
-                             { useDistPref = distPref }
-    setupWrapper verbosity setupScriptOptions Nothing
-      haddockCommand (const haddockFlags') (const extraArgs)
-    when (haddockForHackage haddockFlags == Flag ForHackage) $ do
-      pkg <- fmap LBI.localPkgDescr (getPersistBuildConfig distPref)
-      let dest = distPref </> name <.> "tar.gz"
-          name = display (packageId pkg) ++ "-docs"
-          docDir = distPref </> "doc" </> "html"
-      createTarGzFile dest docDir name
-      notice verbosity $ "Documentation tarball created: " ++ dest
-
-cleanAction :: CleanFlags -> [String] -> Action
-cleanAction cleanFlags extraArgs globalFlags = do
-  load <- try (loadConfigOrSandboxConfig verbosity globalFlags)
-  let config = either (\(SomeException _) -> mempty) id load
-  distPref <- findSavedDistPref config (cleanDistPref cleanFlags)
-  let setupScriptOptions = defaultSetupScriptOptions
-                           { useDistPref = distPref
-                           , useWin32CleanHack = True
-                           }
-      cleanFlags' = cleanFlags { cleanDistPref = toFlag distPref }
-  setupWrapper verbosity setupScriptOptions Nothing
-               cleanCommand (const cleanFlags') (const extraArgs)
-  where
-    verbosity = fromFlagOrDefault normal (cleanVerbosity cleanFlags)
-
-listAction :: ListFlags -> [String] -> Action
-listAction listFlags extraArgs globalFlags = do
-  let verbosity = fromFlag (listVerbosity listFlags)
-  config <- loadConfigOrSandboxConfig verbosity globalFlags
-  let configFlags' = savedConfigureFlags config
-      configFlags  = configFlags'
-        { configPackageDBs = configPackageDBs configFlags'
-                           `mappend` listPackageDBs listFlags
-        , configHcPath     = listHcPath listFlags
-        }
-      globalFlags' = savedGlobalFlags    config `mappend` globalFlags
-  compProgdb <- if listNeedsCompiler listFlags
-      then do
-          (comp, _, progdb) <- configCompilerAux' configFlags
-          return (Just (comp, progdb))
-      else return Nothing
-  withRepoContext verbosity globalFlags' $ \repoContext ->
-    List.list verbosity
-       (configPackageDB' configFlags)
-       repoContext
-       compProgdb
-       listFlags
-       extraArgs
-
-infoAction :: InfoFlags -> [String] -> Action
-infoAction infoFlags extraArgs globalFlags = do
-  let verbosity = fromFlag (infoVerbosity infoFlags)
-  targets <- readUserTargets verbosity extraArgs
-  config <- loadConfigOrSandboxConfig verbosity globalFlags
-  let configFlags' = savedConfigureFlags config
-      configFlags  = configFlags' {
-        configPackageDBs = configPackageDBs configFlags'
-                           `mappend` infoPackageDBs infoFlags
-        }
-      globalFlags' = savedGlobalFlags    config `mappend` globalFlags
-  (comp, _, progdb) <- configCompilerAuxEx configFlags
-  withRepoContext verbosity globalFlags' $ \repoContext ->
-    List.info verbosity
-       (configPackageDB' configFlags)
-       repoContext
-       comp
-       progdb
-       globalFlags'
-       infoFlags
-       targets
-
-fetchAction :: FetchFlags -> [String] -> Action
-fetchAction fetchFlags extraArgs globalFlags = do
-  let verbosity = fromFlag (fetchVerbosity fetchFlags)
-  targets <- readUserTargets verbosity extraArgs
-  config <- loadConfig verbosity (globalConfigFile globalFlags)
-  let configFlags  = savedConfigureFlags config
-      globalFlags' = savedGlobalFlags config `mappend` globalFlags
-  (comp, platform, progdb) <- configCompilerAux' configFlags
-  withRepoContext verbosity globalFlags' $ \repoContext ->
-    fetch verbosity
-        (configPackageDB' configFlags)
-        repoContext
-        comp platform progdb globalFlags' fetchFlags
-        targets
-
-freezeAction :: FreezeFlags -> [String] -> Action
-freezeAction freezeFlags _extraArgs globalFlags = do
-  let verbosity = fromFlag (freezeVerbosity freezeFlags)
-  config <- loadConfigOrSandboxConfig verbosity globalFlags
-  distPref <- findSavedDistPref config NoFlag
-  nixShell verbosity distPref globalFlags config $ do
-    let configFlags  = savedConfigureFlags config
-        globalFlags' = savedGlobalFlags config `mappend` globalFlags
-    (comp, platform, progdb) <- configCompilerAux' configFlags
-
-    withRepoContext verbosity globalFlags' $ \repoContext ->
-        freeze verbosity
-            (configPackageDB' configFlags)
-            repoContext
-            comp platform progdb
-            globalFlags' freezeFlags
-
-genBoundsAction :: FreezeFlags -> [String] -> GlobalFlags -> IO ()
-genBoundsAction freezeFlags _extraArgs globalFlags = do
-  let verbosity = fromFlag (freezeVerbosity freezeFlags)
-  config <- loadConfigOrSandboxConfig verbosity globalFlags
-  distPref <- findSavedDistPref config NoFlag
-  nixShell verbosity distPref globalFlags config $ do
-    let configFlags  = savedConfigureFlags config
-        globalFlags' = savedGlobalFlags config `mappend` globalFlags
-    (comp, platform, progdb) <- configCompilerAux' configFlags
-
-    withRepoContext verbosity globalFlags' $ \repoContext ->
-        genBounds verbosity
-                (configPackageDB' configFlags)
-                repoContext
-                comp platform progdb
-                globalFlags' freezeFlags
-
-uploadAction :: UploadFlags -> [String] -> Action
-uploadAction uploadFlags extraArgs globalFlags = do
-  config <- loadConfig verbosity (globalConfigFile globalFlags)
-  let uploadFlags' = savedUploadFlags config `mappend` uploadFlags
-      globalFlags' = savedGlobalFlags config `mappend` globalFlags
-      tarfiles     = extraArgs
-  when (null tarfiles && not (fromFlag (uploadDoc uploadFlags'))) $
-    die' verbosity "the 'upload' command expects at least one .tar.gz archive."
-  checkTarFiles extraArgs
-  maybe_password <-
-    case uploadPasswordCmd uploadFlags'
-    of Flag (xs:xss) -> Just . Password <$>
-                        getProgramInvocationOutput verbosity
-                        (simpleProgramInvocation xs xss)
-       _             -> pure $ flagToMaybe $ uploadPassword uploadFlags'
-  withRepoContext verbosity globalFlags' $ \repoContext -> do
-    if fromFlag (uploadDoc uploadFlags')
-    then do
-      when (length tarfiles > 1) $
-       die' verbosity $ "the 'upload' command can only upload documentation "
-             ++ "for one package at a time."
-      tarfile <- maybe (generateDocTarball config) return $ listToMaybe tarfiles
-      Upload.uploadDoc verbosity
-                       repoContext
-                       (flagToMaybe $ uploadUsername uploadFlags')
-                       maybe_password
-                       (fromFlag (uploadCandidate uploadFlags'))
-                       tarfile
-    else do
-      Upload.upload verbosity
-                    repoContext
-                    (flagToMaybe $ uploadUsername uploadFlags')
-                    maybe_password
-                    (fromFlag (uploadCandidate uploadFlags'))
-                    tarfiles
-    where
-    verbosity = fromFlag (uploadVerbosity uploadFlags)
-    checkTarFiles tarfiles
-      | not (null otherFiles)
-      = die' verbosity $ "the 'upload' command expects only .tar.gz archives: "
-           ++ intercalate ", " otherFiles
-      | otherwise = sequence_
-                      [ do exists <- doesFileExist tarfile
-                           unless exists $ die' verbosity $ "file not found: " ++ tarfile
-                      | tarfile <- tarfiles ]
-
-      where otherFiles = filter (not . isTarGzFile) tarfiles
-            isTarGzFile file = case splitExtension file of
-              (file', ".gz") -> takeExtension file' == ".tar"
-              _              -> False
-    generateDocTarball config = do
-      notice verbosity $
-        "No documentation tarball specified. "
-        ++ "Building a documentation tarball with default settings...\n"
-        ++ "If you need to customise Haddock options, "
-        ++ "run 'haddock --for-hackage' first "
-        ++ "to generate a documentation tarball."
-      haddockAction (defaultHaddockFlags { haddockForHackage = Flag ForHackage })
-                    [] globalFlags
-      distPref <- findSavedDistPref config NoFlag
-      pkg <- fmap LBI.localPkgDescr (getPersistBuildConfig distPref)
-      return $ distPref </> display (packageId pkg) ++ "-docs" <.> "tar.gz"
-
-checkAction :: Flag Verbosity -> [String] -> Action
-checkAction verbosityFlag extraArgs _globalFlags = do
-  let verbosity = fromFlag verbosityFlag
-  unless (null extraArgs) $
-    die' verbosity $ "'check' doesn't take any extra arguments: " ++ unwords extraArgs
-  allOk <- Check.check (fromFlag verbosityFlag)
-  unless allOk exitFailure
-
-formatAction :: Flag Verbosity -> [String] -> Action
-formatAction verbosityFlag extraArgs _globalFlags = do
-  let verbosity = fromFlag verbosityFlag
-  path <- case extraArgs of
-    [] -> do cwd <- getCurrentDirectory
-             tryFindPackageDesc verbosity cwd
-    (p:_) -> return p
-  pkgDesc <- readGenericPackageDescription verbosity path
-  -- Uses 'writeFileAtomic' under the hood.
-  writeGenericPackageDescription path pkgDesc
-
-reportAction :: ReportFlags -> [String] -> Action
-reportAction reportFlags extraArgs globalFlags = do
-  let verbosity = fromFlag (reportVerbosity reportFlags)
-  unless (null extraArgs) $
-    die' verbosity $ "'report' doesn't take any extra arguments: " ++ unwords extraArgs
-  config <- loadConfig verbosity (globalConfigFile globalFlags)
-  let globalFlags' = savedGlobalFlags config `mappend` globalFlags
-      reportFlags' = savedReportFlags config `mappend` reportFlags
-
-  withRepoContext verbosity globalFlags' $ \repoContext ->
-   Upload.report verbosity repoContext
-    (flagToMaybe $ reportUsername reportFlags')
-    (flagToMaybe $ reportPassword reportFlags')
-
-runAction :: BuildFlags -> [String] -> Action
-runAction buildFlags extraArgs globalFlags = do
-  let verbosity   = fromFlagOrDefault normal (buildVerbosity buildFlags)
-  config <- loadConfigOrSandboxConfig verbosity globalFlags
-  distPref <- findSavedDistPref config (buildDistPref buildFlags)
-  config' <-
-    reconfigure configureAction
-    verbosity distPref (buildNumJobs buildFlags)
-    mempty [] globalFlags config
-  nixShell verbosity distPref globalFlags config $ do
-    lbi <- getPersistBuildConfig distPref
-    (exe, exeArgs) <- splitRunArgs verbosity lbi extraArgs
-
-    build verbosity config' distPref buildFlags ["exe:" ++ display (exeName exe)]
-    run verbosity lbi exe exeArgs
-
-getAction :: GetFlags -> [String] -> Action
-getAction getFlags extraArgs globalFlags = do
-  let verbosity = fromFlag (getVerbosity getFlags)
-  targets <- readUserTargets verbosity extraArgs
-  config <- loadConfigOrSandboxConfig verbosity globalFlags
-  let globalFlags' = savedGlobalFlags config `mappend` globalFlags
-  withRepoContext verbosity (savedGlobalFlags config) $ \repoContext ->
-   get verbosity
-    repoContext
-    globalFlags'
-    getFlags
-    targets
-
-unpackAction :: GetFlags -> [String] -> Action
-unpackAction getFlags extraArgs globalFlags = do
-  getAction getFlags extraArgs globalFlags
-
-initAction :: InitFlags -> [String] -> Action
-initAction initFlags extraArgs globalFlags = do
-  -- it takes the first value within extraArgs (if there's one)
-  -- and uses it as the root directory for the new project
-  case extraArgs of
-    [] -> initAction'
-    [projectDir] -> do
-      createDirectoryIfMissingVerbose verbosity True projectDir
-      withCurrentDirectory projectDir initAction'
-    _ -> die' verbosity $
-      "'init' only takes a single, optional, extra " ++
-      "argument for the project root directory"
-  where
-    initAction' = do
-      confFlags <- loadConfigOrSandboxConfig verbosity globalFlags
-      -- override with `--with-compiler` from CLI if available
-      let confFlags' = savedConfigureFlags confFlags `mappend` compFlags
-          initFlags' = savedInitFlags confFlags `mappend` initFlags
-          globalFlags' = savedGlobalFlags confFlags `mappend` globalFlags
-
-      (comp, _, progdb) <- configCompilerAux' confFlags'
-
-      withRepoContext verbosity globalFlags' $ \repoContext ->
-        initCmd verbosity (configPackageDB' confFlags')
-          repoContext comp progdb initFlags'
-
-    verbosity = fromFlag (initVerbosity initFlags)
-    compFlags = mempty { configHcPath = initHcPath initFlags }
-
-userConfigAction :: UserConfigFlags -> [String] -> Action
-userConfigAction ucflags extraArgs globalFlags = do
-  let verbosity  = fromFlag (userConfigVerbosity ucflags)
-      frc        = fromFlag (userConfigForce ucflags)
-      extraLines = fromFlag (userConfigAppendLines ucflags)
-  case extraArgs of
-    ("init":_) -> do
-      path       <- configFile
-      fileExists <- doesFileExist path
-      if (not fileExists || (fileExists && frc))
-      then void $ createDefaultConfigFile verbosity extraLines path
-      else die' verbosity $ path ++ " already exists."
-    ("diff":_) -> traverse_ putStrLn =<< userConfigDiff verbosity globalFlags extraLines
-    ("update":_) -> userConfigUpdate verbosity globalFlags extraLines
-    -- Error handling.
-    [] -> die' verbosity $ "Please specify a subcommand (see 'help user-config')"
-    _  -> die' verbosity $ "Unknown 'user-config' subcommand: " ++ unwords extraArgs
-  where configFile = getConfigFilePath (globalConfigFile globalFlags)
-
--- | Used as an entry point when cabal-install needs to invoke itself
--- as a setup script. This can happen e.g. when doing parallel builds.
---
-actAsSetupAction :: ActAsSetupFlags -> [String] -> Action
-actAsSetupAction actAsSetupFlags args _globalFlags =
-  let bt = fromFlag (actAsSetupBuildType actAsSetupFlags)
-  in case bt of
-    Simple    -> Simple.defaultMainArgs args
-    Configure -> Simple.defaultMainWithHooksArgs
-                  Simple.autoconfUserHooks args
-    Make      -> Make.defaultMainArgs args
-    Custom    -> error "actAsSetupAction Custom"
-
-manpageAction :: [CommandSpec action] -> ManpageFlags -> [String] -> Action
-manpageAction commands flags extraArgs _ = do
-  let verbosity = fromFlag (manpageVerbosity flags)
-  unless (null extraArgs) $
-    die' verbosity $ "'man' doesn't take any extra arguments: " ++ unwords extraArgs
-  pname <- getProgName
-  let cabalCmd = if takeExtension pname == ".exe"
-                 then dropExtension pname
-                 else pname
-  manpageCmd cabalCmd commands flags
+main = getArgs >>= Client.main
diff --git a/cabal/cabal-install/src/Distribution/Client/BuildReports/Anonymous.hs b/cabal/cabal-install/src/Distribution/Client/BuildReports/Anonymous.hs
--- a/cabal/cabal-install/src/Distribution/Client/BuildReports/Anonymous.hs
+++ b/cabal/cabal-install/src/Distribution/Client/BuildReports/Anonymous.hs
@@ -37,7 +37,7 @@
 import Distribution.Client.Version            (cabalInstallVersion)
 import Distribution.Compiler                  (CompilerId (..))
 import Distribution.FieldGrammar
-import Distribution.Fields                   
+import Distribution.Fields
 import Distribution.Package                   (PackageIdentifier (..), mkPackageName)
 import Distribution.PackageDescription        (FlagAssignment)
 import Distribution.Parsec
diff --git a/cabal/cabal-install/src/Distribution/Client/Check.hs b/cabal/cabal-install/src/Distribution/Client/Check.hs
--- a/cabal/cabal-install/src/Distribution/Client/Check.hs
+++ b/cabal/cabal-install/src/Distribution/Client/Check.hs
@@ -26,7 +26,7 @@
 import Distribution.PackageDescription.Configuration (flattenPackageDescription)
 import Distribution.PackageDescription.Parsec
        (parseGenericPackageDescription, runParseResult)
-import Distribution.Parsec                           (PWarning (..), showPError, showPWarning)
+import Distribution.Parsec                           (PWarning (..), showPError)
 import Distribution.Simple.Utils                     (defaultPackageDesc, die', notice, warn)
 import System.IO                                     (hPutStr, stderr)
 
@@ -55,8 +55,7 @@
     pdfile <- defaultPackageDesc verbosity
     (ws, ppd) <- readGenericPackageDescriptionCheck verbosity pdfile
     -- convert parse warnings into PackageChecks
-    -- Note: we /could/ pick different levels, based on warning type.
-    let ws' = [ PackageDistSuspicious (showPWarning pdfile w) | w <- ws ]
+    let ws' = map (wrapParseWarning pdfile) ws
     -- flatten the generic package description into a regular package
     -- description
     -- TODO: this may give more warnings than it should give;
@@ -111,4 +110,6 @@
     return (not . any isCheckError $ packageChecks)
 
   where
-    printCheckMessages = traverse_ (warn verbosity . explanation)
+    printCheckMessages :: [PackageCheck] -> IO ()
+    printCheckMessages = traverse_ (warn verbosity) . map show
+        -- xxx mapM_ o traverse?
diff --git a/cabal/cabal-install/src/Distribution/Client/CmdBench.hs b/cabal/cabal-install/src/Distribution/Client/CmdBench.hs
--- a/cabal/cabal-install/src/Distribution/Client/CmdBench.hs
+++ b/cabal/cabal-install/src/Distribution/Client/CmdBench.hs
@@ -118,7 +118,7 @@
     runProjectPostBuildPhase verbosity baseCtx buildCtx buildOutcomes
   where
     verbosity = fromFlagOrDefault normal (configVerbosity configFlags)
-    cliConfig = commandLineFlagsToProjectConfig globalFlags flags 
+    cliConfig = commandLineFlagsToProjectConfig globalFlags flags
                   mempty -- ClientInstallFlags, not needed here
 
 -- | This defines what a 'TargetSelector' means for the @bench@ command.
diff --git a/cabal/cabal-install/src/Distribution/Client/CmdBuild.hs b/cabal/cabal-install/src/Distribution/Client/CmdBuild.hs
--- a/cabal/cabal-install/src/Distribution/Client/CmdBuild.hs
+++ b/cabal/cabal-install/src/Distribution/Client/CmdBuild.hs
@@ -101,7 +101,7 @@
 --
 buildAction :: NixStyleFlags BuildFlags -> [String] -> GlobalFlags -> IO ()
 buildAction flags@NixStyleFlags { extraFlags = buildFlags, ..} targetStrings globalFlags
-  = withContextAndSelectors RejectNoTargets Nothing flags targetStrings globalFlags $ \targetCtx ctx targetSelectors -> do
+  = withContextAndSelectors RejectNoTargets Nothing flags targetStrings globalFlags BuildCommand $ \targetCtx ctx targetSelectors -> do
     -- TODO: This flags defaults business is ugly
     let onlyConfigure = fromFlag (buildOnlyConfigure defaultBuildFlags
                                  <> buildOnlyConfigure buildFlags)
diff --git a/cabal/cabal-install/src/Distribution/Client/CmdClean.hs b/cabal/cabal-install/src/Distribution/Client/CmdClean.hs
--- a/cabal/cabal-install/src/Distribution/Client/CmdClean.hs
+++ b/cabal/cabal-install/src/Distribution/Client/CmdClean.hs
@@ -4,12 +4,12 @@
 import Prelude ()
 import Distribution.Client.Compat.Prelude
 
+import Distribution.Client.Config
+    ( defaultScriptBuildsDir )
 import Distribution.Client.DistDirLayout
     ( DistDirLayout(..), defaultDistDirLayout )
 import Distribution.Client.ProjectConfig
     ( findProjectRoot )
-import Distribution.Client.ScriptUtils
-    ( getScriptCacheDirectoryRoot )
 import Distribution.Client.Setup
     ( GlobalFlags )
 import Distribution.ReadE ( succeedReadE )
@@ -121,7 +121,7 @@
     -- There is currently no good way to specify to only clean orphaned caches.
     -- It would be better as part of an explicit gc step (see issue #3333)
     toClean  <- Set.fromList <$> mapM canonicalizePath extraArgs
-    cacheDir <- getScriptCacheDirectoryRoot
+    cacheDir <- defaultScriptBuildsDir
     existsCD <- doesDirectoryExist cacheDir
     caches   <- if existsCD then listDirectory cacheDir else return []
     paths    <- fmap concat . forM caches $ \cache -> do
diff --git a/cabal/cabal-install/src/Distribution/Client/CmdErrorMessages.hs b/cabal/cabal-install/src/Distribution/Client/CmdErrorMessages.hs
--- a/cabal/cabal-install/src/Distribution/Client/CmdErrorMessages.hs
+++ b/cabal/cabal-install/src/Distribution/Client/CmdErrorMessages.hs
@@ -72,6 +72,13 @@
 renderListCommaAnd [x,x'] = x ++ " and " ++ x'
 renderListCommaAnd (x:xs) = x ++ ", " ++ renderListCommaAnd xs
 
+renderListTabular :: [String] -> String
+renderListTabular = ("\n"++) . unlines . map ("| * "++)
+
+renderListPretty :: [String] -> String
+renderListPretty xs = if length xs > 5 then renderListTabular xs
+                                       else renderListCommaAnd xs
+
 -- | Render a list of things in the style @blah blah; this that; and the other@
 renderListSemiAnd :: [String] -> String
 renderListSemiAnd []     = ""
diff --git a/cabal/cabal-install/src/Distribution/Client/CmdExec.hs b/cabal/cabal-install/src/Distribution/Client/CmdExec.hs
--- a/cabal/cabal-install/src/Distribution/Client/CmdExec.hs
+++ b/cabal/cabal-install/src/Distribution/Client/CmdExec.hs
@@ -27,6 +27,10 @@
   ( ConfigFlags(configVerbosity)
   , GlobalFlags
   )
+import Distribution.Client.ProjectConfig.Types
+  ( ProjectConfig (projectConfigShared)
+  , ProjectConfigShared (projectConfigProgPathExtra)
+  )
 import Distribution.Client.ProjectFlags
   ( removeIgnoreProjectOption
   )
@@ -54,13 +58,13 @@
 import Distribution.Simple.Command
   ( CommandUI(..) )
 import Distribution.Simple.Program.Db
-  ( modifyProgramSearchPath
+  ( appendProgramSearchPath
+  , configuredPrograms
   , requireProgram
   , configuredPrograms
   )
 import Distribution.Simple.Program.Find
-  ( ProgramSearchPathEntry(..)
-  )
+  ( simpleProgram )
 import Distribution.Simple.Program.Run
   ( programInvocation
   , runProgramInvocation
@@ -69,7 +73,6 @@
   ( programOverrideEnv
   , programDefaultArgs
   , programPath
-  , simpleProgram
   , ConfiguredProgram
   )
 import Distribution.Simple.GHC
@@ -80,12 +83,14 @@
   )
 import Distribution.Simple.Utils
   ( die'
-  , info
   , createDirectoryIfMissingVerbose
   , withTempDirectory
   , wrapText
   , notice
   )
+import Distribution.Utils.NubList
+  ( fromNubList
+  )
 import Distribution.Verbosity
   ( normal
   )
@@ -147,13 +152,16 @@
     mempty
 
   -- Some dependencies may have executables. Let's put those on the PATH.
-  extraPaths <- pathAdditions verbosity baseCtx buildCtx
-  let programDb = modifyProgramSearchPath
-                  (map ProgramSearchPathDir extraPaths ++)
-                . pkgConfigCompilerProgs
-                . elaboratedShared
-                $ buildCtx
+  let extraPaths = pathAdditions baseCtx buildCtx
 
+  programDb <-
+    appendProgramSearchPath
+      verbosity
+      extraPaths
+      . pkgConfigCompilerProgs
+      . elaboratedShared
+      $ buildCtx
+
   -- Now that we have the packages, set up the environment. We accomplish this
   -- by creating an environment file that selects the databases and packages we
   -- computed in the previous step, and setting an environment variable to
@@ -235,15 +243,21 @@
        buildStatus
      action envOverrides)
 
-pathAdditions :: Verbosity -> ProjectBaseContext -> ProjectBuildContext -> IO [FilePath]
-pathAdditions verbosity ProjectBaseContext{..}ProjectBuildContext{..} = do
-  info verbosity . unlines $ "Including the following directories in PATH:"
-                           : paths
-  return paths
+-- | Get paths to all dependency executables to be included in PATH.
+pathAdditions :: ProjectBaseContext -> ProjectBuildContext -> [FilePath]
+pathAdditions ProjectBaseContext{..} ProjectBuildContext{..} =
+  paths ++ cabalConfigPaths
   where
-  paths = S.toList
-        $ binDirectories distDirLayout elaboratedShared elaboratedPlanToExecute
+    cabalConfigPaths =
+      fromNubList
+        . projectConfigProgPathExtra
+        . projectConfigShared
+        $ projectConfig
+    paths =
+      S.toList $
+        binDirectories distDirLayout elaboratedShared elaboratedPlanToExecute
 
+-- | Get paths to all dependency executables to be included in PATH.
 binDirectories
   :: DistDirLayout
   -> ElaboratedSharedConfig
diff --git a/cabal/cabal-install/src/Distribution/Client/CmdFreeze.hs b/cabal/cabal-install/src/Distribution/Client/CmdFreeze.hs
--- a/cabal/cabal-install/src/Distribution/Client/CmdFreeze.hs
+++ b/cabal/cabal-install/src/Distribution/Client/CmdFreeze.hs
@@ -115,6 +115,7 @@
                          distDirLayout cabalDirLayout
                          projectConfig
                          localPackages
+                         Nothing
 
     let freezeConfig = projectFreezeConfig elaboratedPlan totalIndexState activeRepos
         dryRun = buildSettingDryRun buildSettings
@@ -233,4 +234,3 @@
         | InstallPlan.Configured elab <- InstallPlan.toList plan
         , elabLocalToProject elab
         ]
-
diff --git a/cabal/cabal-install/src/Distribution/Client/CmdHaddock.hs b/cabal/cabal-install/src/Distribution/Client/CmdHaddock.hs
--- a/cabal/cabal-install/src/Distribution/Client/CmdHaddock.hs
+++ b/cabal/cabal-install/src/Distribution/Client/CmdHaddock.hs
@@ -18,17 +18,23 @@
 import Prelude ()
 
 import Distribution.Client.ProjectOrchestration
+import Distribution.Client.ProjectPlanning
+         ( ElaboratedSharedConfig(..) )
 import Distribution.Client.CmdErrorMessages
 import Distribution.Client.TargetProblem
          ( TargetProblem (..), TargetProblem' )
 import Distribution.Client.NixStyleOptions
          ( NixStyleFlags (..), nixStyleOptions, defaultNixStyleFlags )
 import Distribution.Client.Setup
-         ( GlobalFlags, ConfigFlags(..) )
+         ( GlobalFlags, ConfigFlags(..), InstallFlags (..))
 import Distribution.Simple.Setup
          ( HaddockFlags(..), fromFlagOrDefault, trueArg )
 import Distribution.Simple.Command
          ( CommandUI(..), usageAlternatives, ShowOrParseArgs, OptionField, option )
+import Distribution.Simple.Program.Builtin
+         ( haddockProgram )
+import Distribution.Simple.Program.Db
+         ( addKnownProgram, reconfigurePrograms )
 import Distribution.Verbosity
          ( normal )
 import Distribution.Simple.Utils
@@ -120,11 +126,26 @@
 
     printPlan verbosity baseCtx buildCtx
 
-    buildOutcomes <- runProjectBuildPhase verbosity baseCtx buildCtx
-    runProjectPostBuildPhase verbosity baseCtx buildCtx buildOutcomes
+    progs <- reconfigurePrograms verbosity
+               (haddockProgramPaths haddockFlags)
+               (haddockProgramArgs haddockFlags)
+             -- we need to insert 'haddockProgram' before we reconfigure it,
+             -- otherwise 'set
+           . addKnownProgram haddockProgram
+           . pkgConfigCompilerProgs
+           . elaboratedShared
+           $ buildCtx
+    let buildCtx' = buildCtx { elaboratedShared =
+                               (elaboratedShared buildCtx)
+                               { pkgConfigCompilerProgs = progs } }
+
+    buildOutcomes <- runProjectBuildPhase verbosity baseCtx buildCtx'
+    runProjectPostBuildPhase verbosity baseCtx buildCtx' buildOutcomes
   where
     verbosity = fromFlagOrDefault normal (configVerbosity configFlags)
-    cliConfig = commandLineFlagsToProjectConfig globalFlags flags mempty -- ClientInstallFlags, not needed here
+    installDoc = fromFlagOrDefault True (installDocumentation installFlags)
+    flags' = flags { installFlags = installFlags { installDocumentation = Flag installDoc } }
+    cliConfig = commandLineFlagsToProjectConfig globalFlags flags' mempty -- ClientInstallFlags, not needed here
 
 -- | This defines what a 'TargetSelector' means for the @haddock@ command.
 -- It selects the 'AvailableTarget's that the 'TargetSelector' refers to,
diff --git a/cabal/cabal-install/src/Distribution/Client/CmdHaddockProject.hs b/cabal/cabal-install/src/Distribution/Client/CmdHaddockProject.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-install/src/Distribution/Client/CmdHaddockProject.hs
@@ -0,0 +1,330 @@
+module Distribution.Client.CmdHaddockProject
+  ( haddockProjectCommand
+  , haddockProjectAction
+  ) where
+
+import Prelude ()
+import Distribution.Client.Compat.Prelude hiding (get)
+
+import qualified Distribution.Client.CmdBuild   as CmdBuild
+import qualified Distribution.Client.CmdHaddock as CmdHaddock
+
+import Distribution.Client.DistDirLayout      (DistDirLayout(..)
+                                              ,CabalDirLayout(..)
+                                              ,StoreDirLayout(..))
+import Distribution.Client.InstallPlan        (foldPlanPackage)
+import qualified Distribution.Client.InstallPlan as InstallPlan
+import qualified Distribution.Client.NixStyleOptions as NixStyleOptions
+import Distribution.Client.ProjectOrchestration
+                                              (AvailableTarget(..)
+                                              ,AvailableTargetStatus(..)
+                                              ,CurrentCommand(..)
+                                              ,ProjectBaseContext(..)
+                                              ,ProjectBuildContext(..)
+                                              ,TargetSelector(..)
+                                              ,printPlan
+                                              ,pruneInstallPlanToTargets
+                                              ,resolveTargets
+                                              ,runProjectPreBuildPhase
+                                              ,selectComponentTargetBasic)
+import Distribution.Client.ProjectPlanning    (ElaboratedConfiguredPackage(..)
+                                              ,ElaboratedInstallPlan
+                                              ,ElaboratedSharedConfig(..)
+                                              ,TargetAction(..))
+import Distribution.Client.ProjectPlanning.Types
+                                              (elabDistDirParams)
+import Distribution.Client.Setup              (GlobalFlags(..)
+                                              ,ConfigFlags(..))
+import Distribution.Client.ScriptUtils        (AcceptNoTargets(..)
+                                              ,TargetContext(..)
+                                              ,updateContextAndWriteProjectFile
+                                              ,withContextAndSelectors)
+import Distribution.Client.TargetProblem      (TargetProblem(..))
+
+import Distribution.Types.PackageId (pkgName)
+import Distribution.Types.PackageName (unPackageName)
+import Distribution.Types.UnitId (unUnitId)
+import Distribution.Types.Version (mkVersion)
+import Distribution.Types.VersionRange (orLaterVersion)
+import Distribution.Types.InstalledPackageInfo (InstalledPackageInfo (..))
+import Distribution.Simple.Command
+         ( CommandUI(..) )
+import Distribution.Simple.Compiler
+         ( Compiler (..) )
+import Distribution.Simple.Flag
+        ( Flag(..)
+        , fromFlag
+        , fromFlagOrDefault
+        )
+import Distribution.Simple.InstallDirs
+         ( toPathTemplate )
+import Distribution.Simple.Haddock (createHaddockIndex)
+import Distribution.Simple.Utils
+         ( die', createDirectoryIfMissingVerbose
+         , copyDirectoryRecursive, warn )
+import Distribution.Simple.Program.Builtin
+         ( haddockProgram )
+import Distribution.Simple.Program.Db
+         ( addKnownProgram, reconfigurePrograms, requireProgramVersion )
+import Distribution.Simple.Setup
+         ( HaddockFlags(..), defaultHaddockFlags
+         , HaddockProjectFlags(..)
+         , Visibility(..)
+         , haddockProjectCommand
+         )
+import Distribution.Verbosity as Verbosity
+         ( normal )
+
+import System.FilePath          ( takeDirectory, normalise, (</>), (<.>) )
+import System.Directory         ( doesDirectoryExist, doesFileExist )
+
+haddockProjectAction :: HaddockProjectFlags -> [String] -> GlobalFlags -> IO ()
+haddockProjectAction flags _extraArgs globalFlags = do
+    -- create destination directory if it does not exist
+    let outputDir = normalise $ fromFlag (haddockProjectDir flags)
+    createDirectoryIfMissingVerbose verbosity True outputDir
+
+    warn verbosity "haddock-project command is experimental, it might break in the future"
+
+    -- build all packages with appropriate haddock flags
+    let haddockFlags = defaultHaddockFlags
+          { haddockHtml         = Flag True
+          -- one can either use `--haddock-base-url` or
+          -- `--haddock-html-location`.
+          , haddockBaseUrl      = if localStyle
+                                  then Flag ".."
+                                  else NoFlag
+          , haddockProgramPaths = haddockProjectProgramPaths  flags
+          , haddockProgramArgs  = haddockProjectProgramArgs   flags
+          , haddockHtmlLocation = if fromFlagOrDefault False (haddockProjectHackage flags)
+                                  then Flag "https://hackage.haskell.org/package/$pkg-$version/docs"
+                                  else haddockProjectHtmlLocation flags
+          , haddockHoogle       = haddockProjectHoogle        flags
+          , haddockExecutables  = haddockProjectExecutables   flags
+          , haddockTestSuites   = haddockProjectTestSuites    flags
+          , haddockBenchmarks   = haddockProjectBenchmarks    flags
+          , haddockForeignLibs  = haddockProjectForeignLibs   flags
+          , haddockInternal     = haddockProjectInternal      flags
+          , haddockCss          = haddockProjectCss           flags
+          , haddockLinkedSource = Flag True
+          , haddockQuickJump = Flag True
+          , haddockHscolourCss  = haddockProjectHscolourCss    flags
+          , haddockContents     = if localStyle then Flag (toPathTemplate "../index.html")
+                                                else NoFlag
+          , haddockIndex        = if localStyle then Flag (toPathTemplate "../doc-index.html")
+                                                else NoFlag
+          , haddockKeepTempFiles= haddockProjectKeepTempFiles flags
+          , haddockVerbosity    = haddockProjectVerbosity     flags
+          , haddockLib          = haddockProjectLib           flags
+          }
+        nixFlags = (commandDefaultFlags CmdHaddock.haddockCommand)
+                   { NixStyleOptions.haddockFlags = haddockFlags
+                   , NixStyleOptions.configFlags  =
+                       (NixStyleOptions.configFlags (commandDefaultFlags CmdBuild.buildCommand))
+                       { configVerbosity = haddockProjectVerbosity flags }
+                   }
+
+    --
+    -- Construct the build plan and infer the list of packages which haddocks
+    -- we need.
+    --
+
+    withContextAndSelectors RejectNoTargets Nothing (commandDefaultFlags CmdBuild.buildCommand) ["all"] globalFlags HaddockCommand $ \targetCtx ctx targetSelectors -> do
+      baseCtx <- case targetCtx of
+        ProjectContext             -> return ctx
+        GlobalContext              -> return ctx
+        ScriptContext path exemeta -> updateContextAndWriteProjectFile ctx path exemeta
+      let distLayout  = distDirLayout baseCtx
+          cabalLayout = cabalDirLayout baseCtx
+      buildCtx <-
+        runProjectPreBuildPhase verbosity baseCtx $ \elaboratedPlan -> do
+              -- Interpret the targets on the command line as build targets
+              -- (as opposed to say repl or haddock targets).
+              targets <- either reportTargetProblems return
+                       $ resolveTargets
+                           selectPackageTargets
+                           selectComponentTargetBasic
+                           elaboratedPlan
+                           Nothing
+                           targetSelectors
+
+              let elaboratedPlan' = pruneInstallPlanToTargets
+                                      TargetActionBuild
+                                      targets
+                                      elaboratedPlan
+              return (elaboratedPlan', targets)
+
+      printPlan verbosity baseCtx buildCtx
+
+      let elaboratedPlan :: ElaboratedInstallPlan
+          elaboratedPlan = elaboratedPlanOriginal buildCtx
+
+          sharedConfig :: ElaboratedSharedConfig
+          sharedConfig = elaboratedShared buildCtx
+
+          pkgs :: [Either InstalledPackageInfo ElaboratedConfiguredPackage ]
+          pkgs = matchingPackages elaboratedPlan
+
+      progs <- reconfigurePrograms verbosity
+                 (haddockProjectProgramPaths flags)
+                 (haddockProjectProgramArgs flags)
+               -- we need to insert 'haddockProgram' before we reconfigure it,
+               -- otherwise 'set
+             . addKnownProgram haddockProgram
+             . pkgConfigCompilerProgs
+             $ sharedConfig
+      let sharedConfig' = sharedConfig { pkgConfigCompilerProgs = progs }
+
+      _ <- requireProgramVersion
+             verbosity haddockProgram
+             (orLaterVersion (mkVersion [2,26,1])) progs
+
+      --
+      -- Build project; we need to build dependencies.
+      -- Issue #8958.
+      --
+
+      when localStyle $
+        CmdBuild.buildAction
+          (commandDefaultFlags CmdBuild.buildCommand)
+          ["all"]
+          globalFlags
+      --
+      -- Build haddocks of each components
+      --
+
+      CmdHaddock.haddockAction
+        nixFlags
+        ["all"]
+        globalFlags
+
+      --
+      -- Copy haddocks to the destination folder
+      --
+
+      packageInfos <- fmap (nub . concat) $ for pkgs $ \pkg ->
+        case pkg of
+          Left _ | not localStyle ->
+            return []
+          Left package -> do
+            -- TODO: this might not work for public packages with sublibraries.
+            -- Issue #9026.
+            let packageName = unPackageName (pkgName $ sourcePackageId package)
+                destDir = outputDir </> packageName
+            fmap catMaybes $ for (haddockInterfaces package) $ \interfacePath -> do
+              let docDir = takeDirectory interfacePath
+              a <- doesFileExist interfacePath
+              case a of
+                True -> copyDirectoryRecursive verbosity docDir destDir
+                     >> return (Just ( packageName
+                                     , interfacePath
+                                     , Hidden
+                                     ))
+                False -> return Nothing
+
+          Right package ->
+            case elabLocalToProject package of
+              True -> do
+                let distDirParams = elabDistDirParams sharedConfig' package
+                    unitId = unUnitId (elabUnitId package)
+                    buildDir = distBuildDirectory distLayout distDirParams
+                    packageName = unPackageName (pkgName $ elabPkgSourceId package)
+                let docDir = buildDir
+                         </> "doc" </> "html"
+                         </> packageName
+                    destDir = outputDir </> unitId
+                    interfacePath = destDir
+                                </> packageName <.> "haddock"
+                a <- doesDirectoryExist docDir
+                case a of
+                  True  -> copyDirectoryRecursive verbosity docDir destDir
+                        >> return [( packageName
+                                   , interfacePath
+                                   , Visible
+                                   )]
+                  False -> do
+                    warn verbosity
+                         ("haddocks of "
+                          ++ show unitId
+                          ++ " not found in the store")
+                    return []
+              False | not localStyle ->
+                return []
+              False -> do
+                let packageName = unPackageName (pkgName $ elabPkgSourceId package)
+                    unitId = unUnitId (elabUnitId package)
+                    packageDir = storePackageDirectory (cabalStoreDirLayout cabalLayout)
+                                   (compilerId (pkgConfigCompiler sharedConfig'))
+                                   (elabUnitId package)
+                    docDir = packageDir </> "share" </> "doc" </> "html"
+                    destDir = outputDir </> packageName
+                    interfacePath = destDir
+                                </> packageName <.> "haddock"
+                a <- doesDirectoryExist docDir
+                case a of
+                  True  -> copyDirectoryRecursive verbosity docDir destDir
+                        -- non local packages will be hidden in haddock's
+                        -- generated contents page
+                        >> return [( unitId
+                                   , interfacePath
+                                   , Hidden
+                                   )]
+                  False -> do
+                    warn verbosity
+                         ("haddocks of "
+                          ++ show unitId
+                          ++ " not found in the store")
+                    return []
+
+      --
+      -- generate index, content, etc.
+      --
+
+      let flags' = flags
+            { haddockProjectDir         = Flag outputDir
+            , haddockProjectInterfaces  = Flag
+                [ ( interfacePath
+                  , Just name
+                  , Just name
+                  , visibility
+                  )
+                | (name, interfacePath, visibility) <- packageInfos
+                ]
+            }
+      createHaddockIndex verbosity
+                         (pkgConfigCompilerProgs sharedConfig')
+                         (pkgConfigCompiler sharedConfig')
+                         (pkgConfigPlatform sharedConfig')
+                         flags'
+  where
+    verbosity = fromFlagOrDefault normal (haddockProjectVerbosity flags)
+
+    -- Build a self contained directory which contains haddocks of all
+    -- transitive dependencies; or depend on `--haddocks-html-location` to
+    -- provide location of the documentation of dependencies.
+    localStyle =
+      let hackage  = fromFlagOrDefault False (haddockProjectHackage flags)
+          location = fromFlagOrDefault False (const True <$> haddockProjectHtmlLocation flags)
+      in not hackage && not location
+
+    reportTargetProblems :: Show x => [x] -> IO a
+    reportTargetProblems =
+        die' verbosity . unlines . map show
+
+    -- TODO: this is just a sketch
+    selectPackageTargets :: TargetSelector
+                         -> [AvailableTarget k]
+                         -> Either (TargetProblem ()) [k]
+    selectPackageTargets _ ts = Right $
+      mapMaybe
+        (\t -> case availableTargetStatus t of
+            TargetBuildable k _ | availableTargetLocalToProject t
+                                -> Just k
+            _                   -> Nothing)
+        ts
+
+    matchingPackages :: ElaboratedInstallPlan
+                     -> [Either InstalledPackageInfo ElaboratedConfiguredPackage]
+    matchingPackages =
+        fmap (foldPlanPackage Left Right)
+      . InstallPlan.toList
diff --git a/cabal/cabal-install/src/Distribution/Client/CmdInstall.hs b/cabal/cabal-install/src/Distribution/Client/CmdInstall.hs
--- a/cabal/cabal-install/src/Distribution/Client/CmdInstall.hs
+++ b/cabal/cabal-install/src/Distribution/Client/CmdInstall.hs
@@ -33,7 +33,7 @@
 import Distribution.Client.CmdInstall.ClientInstallTargetSelector
 
 import Distribution.Client.Setup
-         ( GlobalFlags(..), ConfigFlags(..) )
+         ( GlobalFlags(..), ConfigFlags(..), InstallFlags(..) )
 import Distribution.Client.Types
          ( PackageSpecifier(..), PackageLocation(..), UnresolvedSourcePackage
          , SourcePackageDb(..) )
@@ -53,18 +53,17 @@
 import Distribution.Client.ProjectConfig.Types
          ( ProjectConfig(..), ProjectConfigShared(..)
          , ProjectConfigBuildOnly(..), PackageConfig(..)
+         , MapMappend(..)
          , getMapLast, getMapMappend, projectConfigLogsDir
          , projectConfigStoreDir, projectConfigBuildOnly
          , projectConfigConfigFile )
 import Distribution.Simple.Program.Db
          ( userSpecifyPaths, userSpecifyArgss, defaultProgramDb
-         , modifyProgramSearchPath, ProgramDb )
+         , appendProgramSearchPath )
 import Distribution.Simple.BuildPaths
          ( exeExtension )
-import Distribution.Simple.Program.Find
-         ( ProgramSearchPathEntry(..) )
 import Distribution.Client.Config
-         ( defaultInstallPath, getCabalDir, loadConfig, SavedConfig(..) )
+         ( defaultInstallPath, loadConfig, SavedConfig(..) )
 import qualified Distribution.Simple.PackageIndex as PI
 import Distribution.Solver.Types.PackageIndex
          ( lookupPackageName, searchByName )
@@ -96,16 +95,16 @@
 import Distribution.Simple.Flag
          ( fromFlagOrDefault, flagToMaybe, flagElim )
 import Distribution.Simple.Setup
-         ( Flag(..) )
+         ( Flag(..), installDirsOptions )
 import Distribution.Solver.Types.SourcePackage
          ( SourcePackage(..) )
 import Distribution.Simple.Command
-         ( CommandUI(..), usageAlternatives )
+         ( CommandUI(..), usageAlternatives, optionName )
 import Distribution.Simple.Configure
          ( configCompilerEx )
 import Distribution.Simple.Compiler
          ( Compiler(..), CompilerId(..), CompilerFlavor(..)
-         , PackageDBStack )
+         , PackageDBStack, PackageDB(..) )
 import Distribution.Simple.GHC
          ( ghcPlatformAndVersionString, getGhcAppDir
          , GhcImplInfo(..), getImplInfo
@@ -122,14 +121,15 @@
 import Distribution.Simple.Utils
          ( wrapText, die', notice, warn
          , withTempDirectory, createDirectoryIfMissingVerbose
-         , ordNub )
+         , ordNub, safeHead )
 import Distribution.Utils.Generic
-         ( safeHead, writeFileAtomic )
+         ( writeFileAtomic )
 
 import qualified Data.ByteString.Lazy.Char8 as BS
 import Data.Ord
          ( Down(..) )
 import qualified Data.Map as Map
+import qualified Data.Set as S
 import qualified Data.List.NonEmpty as NE
 import Distribution.Utils.NubList
          ( fromNubList )
@@ -150,7 +150,7 @@
   , commandDescription  = Just $ \_ -> wrapText $
     "Installs one or more packages. This is done by installing them "
     ++ "in the store and symlinking/copying the executables in the directory "
-    ++ "specified by the --installdir flag (`~/.cabal/bin/` by default). "
+    ++ "specified by the --installdir flag (`~/.local/bin/` by default). "
     ++ "If you want the installed executables to be available globally, "
     ++ "make sure that the PATH environment variable contains that directory. "
     ++ "\n\n"
@@ -168,10 +168,15 @@
       ++ "  " ++ pname ++ " v2-install ./pkgfoo\n"
       ++ "    Install the package in the ./pkgfoo directory\n"
 
-  , commandOptions      = nixStyleOptions clientInstallOptions
+  , commandOptions      = \x -> filter notInstallDirOpt $ nixStyleOptions clientInstallOptions x
   , commandDefaultFlags = defaultNixStyleFlags defaultClientInstallFlags
   }
+ where
+  -- install doesn't take installDirs flags, since it always installs into the store in a fixed way.
+  notInstallDirOpt x = not $ optionName x `elem` installDirOptNames
+  installDirOptNames = map optionName installDirsOptions
 
+
 -- | The @install@ command actually serves four different needs. It installs:
 -- * exes:
 --   For example a program from hackage. The behavior is similar to the old
@@ -204,6 +209,15 @@
     targetFilter   = if installLibs then Just LibKind else Just ExeKind
     targetStrings' = if null targetStrings then ["."] else targetStrings
 
+    -- Note the logic here is rather goofy. Target selectors of the form "foo:bar" also parse as uris.
+    -- However, we want install to also take uri arguments. Hence, we only parse uri arguments in the case where
+    -- no project file is present (including an implicit one derived from being in a package directory)
+    -- or where the --ignore-project flag is passed explicitly. In such a case we only parse colon-free target selectors
+    -- as selectors, and otherwise parse things as URIs.
+
+    -- However, in the special case where --ignore-project is passed with no selectors, we want to act as though this is
+    -- a "normal" ignore project that actually builds and installs the selected package.
+
     withProject :: IO ([PackageSpecifier UnresolvedSourcePackage], [URI], [TargetSelector], ProjectConfig)
     withProject = do
       let reducedVerbosity = lessVerbose verbosity
@@ -233,7 +247,7 @@
         packageTargets =
           flip TargetPackageNamed targetFilter . pkgName <$> packageIds
 
-      if null targetStrings'
+      if null targetStrings'' -- if every selector is already resolved as a packageid, return without further parsing.
         then return (packageSpecifiers, [], packageTargets, projectConfig localBaseCtx)
         else do
           targetSelectors <-
@@ -250,11 +264,10 @@
                  , selectors ++ packageTargets
                  , projectConfig localBaseCtx )
 
-    withoutProject :: ProjectConfig -> IO ([PackageSpecifier pkg], [URI], [TargetSelector], ProjectConfig)
+    withoutProject :: ProjectConfig -> IO ([PackageSpecifier UnresolvedSourcePackage], [URI], [TargetSelector], ProjectConfig)
+    withoutProject _ | null targetStrings = withProject -- if there's no targets, we don't parse specially, but treat it as install in a standard cabal package dir
     withoutProject globalConfig = do
       tss <- traverse (parseWithoutProjectTargetSelector verbosity) targetStrings'
-
-      cabalDir <- getCabalDir
       let
         projectConfig = globalConfig <> cliConfig
 
@@ -268,8 +281,9 @@
 
         mlogsDir = flagToMaybe projectConfigLogsDir
         mstoreDir = flagToMaybe projectConfigStoreDir
-        cabalDirLayout = mkCabalDirLayout cabalDir mstoreDir mlogsDir
+      cabalDirLayout <- mkCabalDirLayout mstoreDir mlogsDir
 
+      let
         buildSettings = resolveBuildTimeSettings
                           verbosity cabalDirLayout
                           projectConfig
@@ -308,7 +322,8 @@
         projectConfigHcFlavor,
         projectConfigHcPath,
         projectConfigHcPkg,
-        projectConfigStoreDir
+        projectConfigStoreDir,
+        projectConfigProgPathExtra
       },
       projectConfigLocalPackages = PackageConfig {
         packageConfigProgramPaths,
@@ -321,14 +336,13 @@
     hcPath   = flagToMaybe projectConfigHcPath
     hcPkg    = flagToMaybe projectConfigHcPkg
 
+  configProgDb <- appendProgramSearchPath verbosity ((fromNubList packageConfigProgramPathExtra) ++ (fromNubList projectConfigProgPathExtra)) defaultProgramDb
+  let
     -- ProgramDb with directly user specified paths
     preProgDb =
-        userSpecifyPaths (Map.toList (getMapLast packageConfigProgramPaths))
-      . userSpecifyArgss (Map.toList (getMapMappend packageConfigProgramArgs))
-      . modifyProgramSearchPath
-          (++ [ ProgramSearchPathDir dir
-              | dir <- fromNubList packageConfigProgramPathExtra ])
-      $ defaultProgramDb
+      userSpecifyPaths (Map.toList (getMapLast packageConfigProgramPaths))
+        . userSpecifyArgss (Map.toList (getMapMappend packageConfigProgramArgs))
+        $ configProgDb
 
   -- progDb is a program database with compiler tools configured properly
   (compiler@Compiler { compilerId =
@@ -363,14 +377,37 @@
       (projectConfigBuildOnly config)
       [ ProjectPackageRemoteTarball uri | uri <- uris ]
 
+    -- check for targets already in env
+    let getPackageName :: PackageSpecifier UnresolvedSourcePackage -> PackageName
+        getPackageName (NamedPackage pn _) = pn
+        getPackageName (SpecificSourcePackage (SourcePackage pkgId _ _ _)) = pkgName pkgId
+        targetNames = S.fromList $ map getPackageName (specs ++ uriSpecs)
+        envNames = S.fromList $ map getPackageName envSpecs
+        forceInstall = fromFlagOrDefault False $ installOverrideReinstall installFlags
+        nameIntersection = S.intersection targetNames envNames
+
+    -- we check for intersections in targets with the existing env
+    (envSpecs', nonGlobalEnvEntries') <- if null nameIntersection
+      then pure (envSpecs, map snd nonGlobalEnvEntries)
+      else if forceInstall
+             then let es = filter (\e -> not $ getPackageName e `S.member` nameIntersection) envSpecs
+                      nge = map snd . filter (\e -> not $ fst e `S.member` nameIntersection) $ nonGlobalEnvEntries
+                  in pure (es, nge)
+             else die' verbosity $ "Packages requested to install already exist in environment file at " ++ envFile ++ ". Overwriting them may break other packages. Use --force-reinstalls to proceed anyway. Packages: " ++ intercalate ", " (map prettyShow $ S.toList nameIntersection)
+
+    -- we construct an installed index of files in the cleaned target environment (absent overwrites) so that we can solve with regards to packages installed locally but not in the upstream repo
+    let installedPacks = PI.allPackagesByName installedIndex
+        newEnvNames = S.fromList $ map getPackageName envSpecs'
+        installedIndex' = PI.fromList . concatMap snd . filter (\p -> fst p `S.member` newEnvNames) $ installedPacks
+
     baseCtx <- establishDummyProjectBaseContext
                  verbosity
                  config
                  distDirLayout
-                 (envSpecs ++ specs ++ uriSpecs)
+                 (envSpecs' ++ specs ++ uriSpecs)
                  InstallCommand
 
-    buildCtx <- constructProjectBuildContext verbosity baseCtx targetSelectors
+    buildCtx <- constructProjectBuildContext verbosity (baseCtx {installedPackages = Just installedIndex'}) targetSelectors
 
     printPlan verbosity baseCtx buildCtx
 
@@ -387,19 +424,31 @@
     unless dryRun $
       if installLibs
       then installLibraries verbosity
-           buildCtx compiler packageDbs progDb envFile nonGlobalEnvEntries
+           buildCtx installedIndex compiler packageDbs envFile nonGlobalEnvEntries'
       else installExes verbosity
            baseCtx buildCtx platform compiler configFlags clientInstallFlags
   where
     configFlags' = disableTestsBenchsByDefault configFlags
     verbosity = fromFlagOrDefault normal (configVerbosity configFlags')
     ignoreProject = flagIgnoreProject projectFlags
-    cliConfig = commandLineFlagsToProjectConfig
-                  globalFlags
-                  flags { configFlags = configFlags' }
-                  clientInstallFlags'
+    baseCliConfig = commandLineFlagsToProjectConfig
+                        globalFlags
+                        flags { configFlags = configFlags' }
+                        clientInstallFlags'
+    cliConfig = addLocalConfigToTargets baseCliConfig targetStrings
     globalConfigFlag = projectConfigConfigFile (projectConfigShared cliConfig)
 
+-- | Treat all direct targets of install command as local packages: #8637
+addLocalConfigToTargets :: ProjectConfig -> [String] -> ProjectConfig
+addLocalConfigToTargets config targetStrings
+    = config {
+        projectConfigSpecificPackage = projectConfigSpecificPackage config
+                                       <> MapMappend (Map.fromList targetPackageConfigs)
+    }
+  where
+    localConfig = projectConfigLocalPackages config
+    targetPackageConfigs = map (\x -> (mkPackageName x, localConfig)) targetStrings
+
 -- | Verify that invalid config options were not passed to the install command.
 --
 -- If an invalid configuration is found the command will @die'@.
@@ -605,7 +654,7 @@
   installdir <- fromFlagOrDefault
                 (warn verbosity installdirUnknown >> pure installPath) $
                 pure <$> cinstInstalldir clientInstallFlags
-  createDirectoryIfMissingVerbose verbosity False installdir
+  createDirectoryIfMissingVerbose verbosity True installdir
   warnIfNoExes verbosity buildCtx
 
   installMethod <- flagElim defaultMethod return $
@@ -638,30 +687,30 @@
 installLibraries
   :: Verbosity
   -> ProjectBuildContext
+  -> PI.PackageIndex InstalledPackageInfo
   -> Compiler
   -> PackageDBStack
-  -> ProgramDb
   -> FilePath -- ^ Environment file
   -> [GhcEnvironmentFileEntry]
   -> IO ()
-installLibraries verbosity buildCtx compiler
-                 packageDbs programDb envFile envEntries = do
-  -- Why do we get it again? If we updated a globalPackage then we need
-  -- the new version.
-  installedIndex <- getInstalledPackages verbosity compiler packageDbs programDb
+installLibraries verbosity buildCtx installedIndex compiler
+                 packageDbs' envFile envEntries = do
   if supportsPkgEnvFiles $ getImplInfo compiler
     then do
+      let validDb (SpecificPackageDB fp) = doesPathExist fp
+          validDb _ = pure True
+      -- if a user "installs" a global package and no existing cabal db exists, none will be created.
+      -- this ensures we don't add the "phantom" path to the file.
+      packageDbs <- filterM validDb packageDbs'
       let
-        getLatest :: PackageName -> [InstalledPackageInfo]
         getLatest = (=<<) (maybeToList . safeHead . snd) . take 1 . sortBy (comparing (Down . fst))
                   . PI.lookupPackageName installedIndex
         globalLatest = concat (getLatest <$> globalPackages)
-
+        globalEntries = GhcEnvFilePackageId . installedUnitId <$> globalLatest
         baseEntries =
           GhcEnvFileClearPackageDbStack : fmap GhcEnvFilePackageDb packageDbs
-        globalEntries = GhcEnvFilePackageId . installedUnitId <$> globalLatest
         pkgEntries = ordNub $
-              globalEntries
+             globalEntries
           ++ envEntries
           ++ entriesForLibraryComponents (targetsMap buildCtx)
         contents' = renderGhcEnvironmentFile (baseEntries ++ pkgEntries)
@@ -673,6 +722,12 @@
         ++ "so only executables will be available. (Library installation is "
         ++ "supported on GHC 8.0+ only)"
 
+-- See ticket #8894. This is safe to include any nonreinstallable boot pkg,
+-- but the particular package users will always expect to be in scope without specific installation
+-- is base, so that they can access prelude, regardles of if they specifically asked for it.
+globalPackages :: [PackageName]
+globalPackages = mkPackageName <$> [ "base" ]
+
 warnIfNoExes :: Verbosity -> ProjectBuildContext -> IO ()
 warnIfNoExes verbosity buildCtx =
   when noExes $
@@ -700,21 +755,12 @@
     exeMaybe (ComponentTarget (CExeName exe) _) = Just exe
     exeMaybe _                                  = Nothing
 
-globalPackages :: [PackageName]
-globalPackages = mkPackageName <$>
-  [ "ghc", "hoopl", "bytestring", "unix", "base", "time", "hpc", "filepath"
-  , "process", "array", "integer-gmp", "containers", "ghc-boot", "binary"
-  , "ghc-prim", "ghci", "rts", "terminfo", "transformers", "deepseq"
-  , "ghc-boot-th", "pretty", "template-haskell", "directory", "text"
-  , "bin-package-db"
-  ]
-
 -- | Return the package specifiers and non-global environment file entries.
 getEnvSpecsAndNonGlobalEntries
   :: PI.InstalledPackageIndex
   -> [GhcEnvironmentFileEntry]
   -> Bool
-  -> ([PackageSpecifier a], [GhcEnvironmentFileEntry])
+  -> ([PackageSpecifier a], [(PackageName, GhcEnvironmentFileEntry)])
 getEnvSpecsAndNonGlobalEntries installedIndex entries installLibs =
   if installLibs
   then (envSpecs, envEntries')
@@ -724,7 +770,7 @@
 
 environmentFileToSpecifiers
   :: PI.InstalledPackageIndex -> [GhcEnvironmentFileEntry]
-  -> ([PackageSpecifier a], [GhcEnvironmentFileEntry])
+  -> ([PackageSpecifier a], [(PackageName, GhcEnvironmentFileEntry)])
 environmentFileToSpecifiers ipi = foldMap $ \case
     (GhcEnvFilePackageId unitId)
         | Just InstalledPackageInfo
@@ -732,9 +778,7 @@
           <- PI.lookupUnitId ipi unitId
         , let pkgSpec = NamedPackage pkgName
                         [PackagePropertyVersion (thisVersion pkgVersion)]
-        -> if pkgName `elem` globalPackages
-          then ([pkgSpec], [])
-          else ([pkgSpec], [GhcEnvFilePackageId installedUnitId])
+        -> ([pkgSpec], [(pkgName, GhcEnvFilePackageId installedUnitId)])
     _ -> ([], [])
 
 
@@ -912,11 +956,10 @@
   -> Flag FilePath
   -> IO PackageDBStack
 getPackageDbStack compilerId storeDirFlag logsDirFlag = do
-  cabalDir <- getCabalDir
   mstoreDir <- traverse makeAbsolute $ flagToMaybe storeDirFlag
   let
     mlogsDir    = flagToMaybe logsDirFlag
-    cabalLayout = mkCabalDirLayout cabalDir mstoreDir mlogsDir
+  cabalLayout <- mkCabalDirLayout mstoreDir mlogsDir
   pure $ storePackageDBStack (cabalStoreDirLayout cabalLayout) compilerId
 
 -- | This defines what a 'TargetSelector' means for the @bench@ command.
diff --git a/cabal/cabal-install/src/Distribution/Client/CmdInstall/ClientInstallFlags.hs b/cabal/cabal-install/src/Distribution/Client/CmdInstall/ClientInstallFlags.hs
--- a/cabal/cabal-install/src/Distribution/Client/CmdInstall/ClientInstallFlags.hs
+++ b/cabal/cabal-install/src/Distribution/Client/CmdInstall/ClientInstallFlags.hs
@@ -66,7 +66,7 @@
     "How to handle already existing symlinks."
     cinstOverwritePolicy (\v flags -> flags { cinstOverwritePolicy = v })
     $ reqArg "always|never|prompt"
-        (parsecToReadE (\err -> "Error parsing overwrite-policy: " ++ err) (toFlag `fmap` parsec)) 
+        (parsecToReadE (\err -> "Error parsing overwrite-policy: " ++ err) (toFlag `fmap` parsec))
         (map prettyShow . flagToList)
   , option [] ["install-method"]
     "How to install the executables."
diff --git a/cabal/cabal-install/src/Distribution/Client/CmdListBin.hs b/cabal/cabal-install/src/Distribution/Client/CmdListBin.hs
--- a/cabal/cabal-install/src/Distribution/Client/CmdListBin.hs
+++ b/cabal/cabal-install/src/Distribution/Client/CmdListBin.hs
@@ -28,13 +28,15 @@
 import Distribution.Client.ProjectOrchestration
 import Distribution.Client.ProjectPlanning.Types
 import Distribution.Client.ScriptUtils
-       (AcceptNoTargets(..), TargetContext(..), updateContextAndWriteProjectFile, withContextAndSelectors)
+       ( AcceptNoTargets(..), TargetContext(..)
+       , updateContextAndWriteProjectFile, withContextAndSelectors
+       , movedExePath )
 import Distribution.Client.Setup                 (GlobalFlags (..))
 import Distribution.Client.TargetProblem         (TargetProblem (..))
 import Distribution.Simple.BuildPaths            (dllExtension, exeExtension)
 import Distribution.Simple.Command               (CommandUI (..))
 import Distribution.Simple.Setup                 (configVerbosity, fromFlagOrDefault)
-import Distribution.Simple.Utils                 (die', wrapText)
+import Distribution.Simple.Utils                 (die', withOutputMarker, wrapText)
 import Distribution.System                       (Platform)
 import Distribution.Types.ComponentName          (showComponentName)
 import Distribution.Types.UnitId                 (UnitId)
@@ -78,7 +80,7 @@
       _   -> die' verbosity "One target is required, given multiple"
 
   -- configure and elaborate target selectors
-  withContextAndSelectors RejectNoTargets (Just ExeKind) flags [target] globalFlags $ \targetCtx ctx targetSelectors -> do
+  withContextAndSelectors RejectNoTargets (Just ExeKind) flags [target] globalFlags OtherCommand $ \targetCtx ctx targetSelectors -> do
     baseCtx <- case targetCtx of
       ProjectContext             -> return ctx
       GlobalContext              -> return ctx
@@ -133,7 +135,18 @@
 
     case binfiles of
         []     -> die' verbosity "No target found"
-        [exe] -> putStrLn exe
+        [exe]  -> putStr $ withOutputMarker verbosity $ exe ++ "\n"
+                    -- Andreas, 2023-01-13, issue #8400:
+                    -- Regular output of `list-bin` should go to stdout unconditionally,
+                    -- but for the sake of the testsuite, we want to mark it so it goes
+                    -- into the golden value for the test.
+                    -- Note: 'withOutputMarker' only checks 'isVerboseMarkOutput',
+                    -- thus, we can reuse @verbosity@ here, even if other components
+                    -- of @verbosity@ may be wrong (like 'VStderr', verbosity level etc.).
+                    -- Andreas, 2023-01-20:
+                    -- Appending the newline character here rather than using 'putStrLn'
+                    -- because an active 'withOutputMarker' produces text that ends
+                    -- in newline characters.
         _ -> die' verbosity "Multiple targets found"
   where
     defaultVerbosity = verboseStderr silent
@@ -159,7 +172,7 @@
 
         bin_file c = case c of
             CD.ComponentExe s
-               | s == selectedComponent -> [bin_file' s]
+               | s == selectedComponent -> [moved_bin_file s]
             CD.ComponentTest s
                | s == selectedComponent -> [bin_file' s]
             CD.ComponentBench s
@@ -182,6 +195,8 @@
             if elabBuildStyle elab == BuildInplaceOnly
             then dist_dir </> "build" </> prettyShow s </> ("lib" ++ prettyShow s) <.> dllExtension plat
             else InstallDirs.bindir (elabInstallDirs elab) </> ("lib" ++ prettyShow s) <.> dllExtension plat
+
+        moved_bin_file s = fromMaybe (bin_file' s) (movedExePath selectedComponent distDirLayout elaboratedSharedConfig elab)
 
 -------------------------------------------------------------------------------
 -- Target Problem: the very similar to CmdRun
diff --git a/cabal/cabal-install/src/Distribution/Client/CmdOutdated.hs b/cabal/cabal-install/src/Distribution/Client/CmdOutdated.hs
--- a/cabal/cabal-install/src/Distribution/Client/CmdOutdated.hs
+++ b/cabal/cabal-install/src/Distribution/Client/CmdOutdated.hs
@@ -30,7 +30,7 @@
     , DistDirLayout(distProjectRootDirectory, distProjectFile) )
 import Distribution.Client.ProjectConfig
 import Distribution.Client.ProjectConfig.Legacy
-    ( instantiateProjectConfigSkeleton )
+    ( instantiateProjectConfigSkeletonWithCompiler )
 import Distribution.Client.ProjectFlags
     ( projectFlagsOptions, ProjectFlags(..), defaultProjectFlags
     , removeIgnoreProjectOption )
@@ -306,7 +306,7 @@
                       {- TODO: Support dist dir override -} Nothing
   projectConfig <- runRebuild (distProjectRootDirectory distDirLayout) $ do
                       pcs <- readProjectLocalFreezeConfig verbosity httpTransport distDirLayout
-                      pure $ instantiateProjectConfigSkeleton os arch (compilerInfo compiler) mempty pcs
+                      pure $ instantiateProjectConfigSkeletonWithCompiler os arch (compilerInfo compiler) mempty pcs
   let ucnstrs = map fst . projectConfigConstraints . projectConfigShared
                 $ projectConfig
       deps    = userConstraintsToDependencies ucnstrs
diff --git a/cabal/cabal-install/src/Distribution/Client/CmdRepl.hs b/cabal/cabal-install/src/Distribution/Client/CmdRepl.hs
--- a/cabal/cabal-install/src/Distribution/Client/CmdRepl.hs
+++ b/cabal/cabal-install/src/Distribution/Client/CmdRepl.hs
@@ -75,7 +75,7 @@
 import Distribution.Types.ComponentName
          ( componentNameString )
 import Distribution.Types.CondTree
-         ( CondTree(..), traverseCondTreeC )
+         ( CondTree(..) )
 import Distribution.Types.Dependency
          ( Dependency(..), mainLibSet )
 import Distribution.Types.Library
@@ -187,7 +187,7 @@
 --
 replAction :: NixStyleFlags (ReplOptions, EnvFlags) -> [String] -> GlobalFlags -> IO ()
 replAction flags@NixStyleFlags { extraFlags = (replOpts, envFlags), ..} targetStrings globalFlags
-  = withContextAndSelectors AcceptNoTargets (Just LibKind) flags targetStrings globalFlags $ \targetCtx ctx targetSelectors -> do
+  = withContextAndSelectors AcceptNoTargets (Just LibKind) flags targetStrings globalFlags ReplCommand $ \targetCtx ctx targetSelectors -> do
     when (buildSettingOnlyDeps (buildSettings ctx)) $
       die' verbosity $ "The repl command does not support '--only-dependencies'. "
           ++ "You may wish to use 'build --only-dependencies' and then "
@@ -338,7 +338,12 @@
       | packageId pkg /= pkgId = SpecificSourcePackage pkg
       | SourcePackage{..} <- pkg =
         SpecificSourcePackage $ pkg { srcpkgDescription =
-          srcpkgDescription & (\f -> L.allCondTrees $ traverseCondTreeC f)
+          -- New dependencies are added to the original ones found in the
+          -- `targetBuildDepends` field.
+          -- `traverseBuildInfos` is used in order to update _all_ the
+          -- occurrences of the field `targetBuildDepends`. It ensures that
+          -- fields depending on the latter are also consistently updated.
+          srcpkgDescription &  (L.traverseBuildInfos . L.targetBuildDepends)
                             %~ (deps ++)
         }
     addDeps spec = spec
diff --git a/cabal/cabal-install/src/Distribution/Client/CmdRun.hs b/cabal/cabal-install/src/Distribution/Client/CmdRun.hs
--- a/cabal/cabal-install/src/Distribution/Client/CmdRun.hs
+++ b/cabal/cabal-install/src/Distribution/Client/CmdRun.hs
@@ -22,49 +22,62 @@
 import Prelude ()
 import Distribution.Client.Compat.Prelude hiding (toList)
 
-import Distribution.Client.ProjectOrchestration
 import Distribution.Client.CmdErrorMessages
          ( renderTargetSelector, showTargetSelector,
            renderTargetProblem,
            renderTargetProblemNoTargets, plural, targetSelectorPluralPkgs,
-           targetSelectorFilter, renderListCommaAnd )
-import Distribution.Client.TargetProblem
-         ( TargetProblem (..) )
-
+           targetSelectorFilter, renderListCommaAnd,
+           renderListPretty )
+import Distribution.Client.GlobalFlags
+         ( defaultGlobalFlags )
+import Distribution.Client.InstallPlan
+         ( toList, foldPlanPackage )
 import Distribution.Client.NixStyleOptions
          ( NixStyleFlags (..), nixStyleOptions, defaultNixStyleFlags )
+import Distribution.Client.ProjectConfig.Types
+import Distribution.Client.ProjectOrchestration
+import Distribution.Client.ProjectPlanning
+         ( ElaboratedConfiguredPackage(..)
+         , ElaboratedInstallPlan, binDirectoryFor
+         )
+import Distribution.Client.ProjectPlanning.Types
+         ( dataDirsEnvironmentForPlan, elabExeDependencyPaths )
+import Distribution.Client.ScriptUtils
+         ( AcceptNoTargets(..), TargetContext(..)
+         , updateContextAndWriteProjectFile, withContextAndSelectors
+         , movedExePath )
 import Distribution.Client.Setup
          ( GlobalFlags(..), ConfigFlags(..) )
-import Distribution.Client.GlobalFlags
-         ( defaultGlobalFlags )
-import Distribution.Simple.Flag
-         ( fromFlagOrDefault )
+import Distribution.Client.TargetProblem
+         ( TargetProblem (..) )
 import Distribution.Simple.Command
          ( CommandUI(..), usageAlternatives )
-import Distribution.Types.ComponentName
-         ( showComponentName )
-import Distribution.Verbosity
-         ( normal, silent )
-import Distribution.Simple.Utils
-         ( wrapText, die', info, notice )
-import Distribution.Client.ProjectPlanning
-         ( ElaboratedConfiguredPackage(..)
-         , ElaboratedInstallPlan, binDirectoryFor )
-import Distribution.Client.ProjectPlanning.Types
-         ( dataDirsEnvironmentForPlan )
-import Distribution.Client.InstallPlan
-         ( toList, foldPlanPackage )
-import Distribution.Types.UnqualComponentName
-         ( UnqualComponentName, unUnqualComponentName )
+import Distribution.Simple.Flag
+         ( fromFlagOrDefault )
+import Distribution.Simple.Program.Find
+         ( ProgramSearchPathEntry(..), defaultProgramSearchPath,
+           programSearchPathAsPATHVar, logExtraProgramSearchPath
+         )
 import Distribution.Simple.Program.Run
          ( runProgramInvocation, ProgramInvocation(..),
            emptyProgramInvocation )
+import Distribution.Simple.Utils
+         ( wrapText, die', info, notice, safeHead )
+import Distribution.Types.ComponentName
+         ( componentNameRaw )
 import Distribution.Types.UnitId
          ( UnitId )
-import Distribution.Client.ScriptUtils
-         ( AcceptNoTargets(..), withContextAndSelectors, updateContextAndWriteProjectFile, TargetContext(..) )
+import Distribution.Utils.NubList
+         ( fromNubList )
 
+import Distribution.Types.UnqualComponentName
+         ( UnqualComponentName, unUnqualComponentName )
+import Distribution.Verbosity
+         ( normal, silent )
+
+import Data.List (group)
 import qualified Data.Set as Set
+
 import System.Directory
          ( doesFileExist )
 import System.FilePath
@@ -120,7 +133,7 @@
 --
 runAction :: NixStyleFlags () -> [String] -> GlobalFlags -> IO ()
 runAction flags@NixStyleFlags {..} targetAndArgs globalFlags
-  = withContextAndSelectors RejectNoTargets (Just ExeKind) flags targetStr globalFlags $ \targetCtx ctx targetSelectors -> do
+  = withContextAndSelectors RejectNoTargets (Just ExeKind) flags targetStr globalFlags OtherCommand $ \targetCtx ctx targetSelectors -> do
     (baseCtx, defaultVerbosity) <- case targetCtx of
       ProjectContext             -> return (ctx, normal)
       GlobalContext              -> return (ctx, normal)
@@ -214,14 +227,31 @@
         ++ exeName
         ++ ":\n"
         ++ unlines (fmap (\p -> " - in package " ++ prettyShow (elabUnitId p)) elabPkgs)
-    let exePath = binDirectoryFor (distDirLayout baseCtx)
-                                  (elaboratedShared buildCtx)
-                                  pkg
-                                  exeName
-               </> exeName
+
+    let defaultExePath = binDirectoryFor
+                            (distDirLayout baseCtx)
+                            (elaboratedShared buildCtx)
+                             pkg
+                             exeName
+                       </> exeName
+        exePath = fromMaybe defaultExePath (movedExePath selectedComponent (distDirLayout baseCtx) (elaboratedShared buildCtx) pkg)
+
     let dryRun = buildSettingDryRun (buildSettings baseCtx)
               || buildSettingOnlyDownload (buildSettings baseCtx)
 
+    let extraPath =
+          elabExeDependencyPaths pkg
+            ++ ( fromNubList
+                  . projectConfigProgPathExtra
+                  . projectConfigShared
+                  . projectConfig
+                  $ baseCtx
+               )
+
+    logExtraProgramSearchPath verbosity extraPath
+
+    progPath <- programSearchPathAsPATHVar (map ProgramSearchPathDir extraPath ++ defaultProgramSearchPath)
+
     if dryRun
        then notice verbosity "Running of executable suppressed by flag(s)"
        else
@@ -230,7 +260,8 @@
            emptyProgramInvocation {
              progInvokePath  = exePath,
              progInvokeArgs  = args,
-             progInvokeEnv   = dataDirsEnvironmentForPlan
+             progInvokeEnv   = ("PATH", Just $ progPath)
+                             : dataDirsEnvironmentForPlan
                                  (distDirLayout baseCtx)
                                  elaboratedPlan
            }
@@ -424,14 +455,13 @@
 renderRunProblem (TargetProblemMatchesMultiple targetSelector targets) =
     "The run command is for running a single executable at once. The target '"
  ++ showTargetSelector targetSelector ++ "' refers to "
- ++ renderTargetSelector targetSelector ++ " which includes "
- ++ renderListCommaAnd ( ("the "++) <$>
-                         showComponentName <$>
-                         availableTargetComponentName <$>
-                         foldMap
-                           (\kind -> filterTargetsKind kind targets)
-                           [ExeKind, TestKind, BenchKind] )
- ++ "."
+ ++ renderTargetSelector targetSelector ++ " which includes \n"
+ ++ unlines ((\(label, xs) -> "- " ++ label ++ ": " ++ renderListPretty xs)
+    <$> (zip ["executables", "test-suites", "benchmarks"]
+     $  filter (not . null) . map removeDuplicates
+     $  map (componentNameRaw . availableTargetComponentName)
+    <$> (flip filterTargetsKind $ targets) <$> [ExeKind, TestKind, BenchKind] ))
+    where removeDuplicates = catMaybes . map safeHead . group . sort
 
 renderRunProblem (TargetProblemMultipleTargets selectorMap) =
     "The run command is for running a single executable at once. The targets "
diff --git a/cabal/cabal-install/src/Distribution/Client/CmdSdist.hs b/cabal/cabal-install/src/Distribution/Client/CmdSdist.hs
--- a/cabal/cabal-install/src/Distribution/Client/CmdSdist.hs
+++ b/cabal/cabal-install/src/Distribution/Client/CmdSdist.hs
@@ -137,7 +137,7 @@
 -------------------------------------------------------------------------------
 
 sdistAction :: (ProjectFlags, SdistFlags) -> [String] -> GlobalFlags -> IO ()
-sdistAction (ProjectFlags{..}, SdistFlags{..}) targetStrings globalFlags = do
+sdistAction (pf@ProjectFlags{..}, SdistFlags{..}) targetStrings globalFlags = do
     (baseCtx, distDirLayout) <- withProjectOrGlobalConfig verbosity flagIgnoreProject globalConfigFlag withProject withoutProject
 
     let localPkgs = localPackages baseCtx
@@ -196,6 +196,7 @@
             { configVerbosity = sdistVerbosity
             , configDistPref = sdistDistDir
             }
+          , projectFlags = pf
           }
         mempty
 
diff --git a/cabal/cabal-install/src/Distribution/Client/CmdUpdate.hs b/cabal/cabal-install/src/Distribution/Client/CmdUpdate.hs
--- a/cabal/cabal-install/src/Distribution/Client/CmdUpdate.hs
+++ b/cabal/cabal-install/src/Distribution/Client/CmdUpdate.hs
@@ -199,10 +199,12 @@
       -- NB: always update the timestamp, even if we didn't actually
       -- download anything
       writeIndexTimestamp index indexState
-      ce <- if repoContextIgnoreExpiry repoCtxt
-              then Just `fmap` getCurrentTime
-              else return Nothing
-      updated <- Sec.uncheckClientErrors $ Sec.checkForUpdates repoSecure ce
+      -- typically we get the current time to check expiry against
+      -- but if the flag is set, we don't.
+      now' <- case repoContextIgnoreExpiry repoCtxt of
+                 False -> Just <$> getCurrentTime
+                 True  -> pure Nothing
+      updated <- Sec.uncheckClientErrors $ Sec.checkForUpdates repoSecure now'
       -- this resolves indexState (which could be HEAD) into a timestamp
       new_ts <- currentIndexTimestamp (lessVerbose verbosity) repoCtxt repo
       let rname = remoteRepoName (repoRemote repo)
diff --git a/cabal/cabal-install/src/Distribution/Client/Compat/Process.hs b/cabal/cabal-install/src/Distribution/Client/Compat/Process.hs
deleted file mode 100644
--- a/cabal/cabal-install/src/Distribution/Client/Compat/Process.hs
+++ /dev/null
@@ -1,48 +0,0 @@
------------------------------------------------------------------------------
--- |
--- Module      :  Distribution.Client.Compat.Process
--- Copyright   :  (c) 2013 Liu Hao, Brent Yorgey
--- License     :  BSD-style (see the file LICENSE)
---
--- Maintainer  :  cabal-devel@haskell.org
--- Stability   :  provisional
--- Portability :  portable
---
--- Cross-platform utilities for invoking processes.
---
------------------------------------------------------------------------------
-
-module Distribution.Client.Compat.Process (
-  readProcessWithExitCode
-) where
-
-import Prelude (FilePath, IO, String, return, (||))
-
-import           Control.Exception (catch, throw)
-import           System.Exit       (ExitCode (ExitFailure))
-import           System.IO.Error   (isDoesNotExistError, isPermissionError)
-import qualified System.Process    as P
-
--- | @readProcessWithExitCode@ creates an external process, reads its
---   standard output and standard error strictly, waits until the
---   process terminates, and then returns the @ExitCode@ of the
---   process, the standard output, and the standard error.
---
---   See the documentation of the version from @System.Process@ for
---   more information.
---
---   The version from @System.Process@ behaves inconsistently across
---   platforms when an executable with the given name is not found: in
---   some cases it returns an @ExitFailure@, in others it throws an
---   exception.  This variant catches \"does not exist\" and
---   \"permission denied\" exceptions and turns them into
---   @ExitFailure@s.
---
--- TODO: this doesn't use 'Distrubution.Compat.Process'.
---
-readProcessWithExitCode :: FilePath -> [String] -> String -> IO (ExitCode, String, String)
-readProcessWithExitCode cmd args input =
-  P.readProcessWithExitCode cmd args input
-    `catch` \e -> if isDoesNotExistError e || isPermissionError e
-                    then return (ExitFailure 127, "", "")
-                    else throw e
diff --git a/cabal/cabal-install/src/Distribution/Client/Config.hs b/cabal/cabal-install/src/Distribution/Client/Config.hs
--- a/cabal/cabal-install/src/Distribution/Client/Config.hs
+++ b/cabal/cabal-install/src/Distribution/Client/Config.hs
@@ -24,12 +24,14 @@
     showConfigWithComments,
     parseConfig,
 
-    getCabalDir,
     defaultConfigFile,
     defaultCacheDir,
+    defaultScriptBuildsDir,
+    defaultStoreDir,
     defaultCompiler,
     defaultInstallPath,
     defaultLogsDir,
+    defaultReportsDir,
     defaultUserInstall,
 
     baseSavedConfig,
@@ -48,6 +50,7 @@
     postProcessRepo,
   ) where
 
+import Distribution.Compat.Environment (lookupEnv)
 import Distribution.Client.Compat.Prelude
 import Prelude ()
 
@@ -92,7 +95,7 @@
          , Flag(..), toFlag, flagToMaybe, fromFlagOrDefault )
 import Distribution.Simple.InstallDirs
          ( InstallDirs(..), defaultInstallDirs
-         , PathTemplate, toPathTemplate )
+         , PathTemplate, toPathTemplate)
 import Distribution.Deprecated.ParseUtils
          ( FieldDescr(..), liftField, runP
          , ParseResult(..), PError(..), PWarning(..)
@@ -132,7 +135,7 @@
 import Text.PrettyPrint.HughesPJ
          ( text, Doc )
 import System.Directory
-         ( createDirectoryIfMissing, getAppUserDataDirectory, renameFile )
+         ( createDirectoryIfMissing, getHomeDirectory, getXdgDirectory, XdgDirectory(XdgCache, XdgConfig, XdgState), renameFile, getAppUserDataDirectory, doesDirectoryExist, doesFileExist )
 import Network.URI
          ( URI(..), URIAuth(..), parseURI )
 import System.FilePath
@@ -140,7 +143,7 @@
 import System.IO.Error
          ( isDoesNotExistError )
 import Distribution.Compat.Environment
-         ( getEnvironment, lookupEnv )
+         ( getEnvironment )
 import qualified Data.Map as M
 import qualified Data.ByteString as BS
 
@@ -490,6 +493,9 @@
         haddockKeepTempFiles = combine haddockKeepTempFiles,
         haddockVerbosity     = combine haddockVerbosity,
         haddockCabalFilePath = combine haddockCabalFilePath,
+        haddockIndex         = combine haddockIndex,
+        haddockBaseUrl       = combine haddockBaseUrl,
+        haddockLib           = combine haddockLib,
         haddockArgs          = lastNonEmpty haddockArgs
         }
         where
@@ -538,7 +544,7 @@
 --
 baseSavedConfig :: IO SavedConfig
 baseSavedConfig = do
-  userPrefix <- getCabalDir
+  userPrefix <- defaultInstallPrefix
   cacheDir   <- defaultCacheDir
   logsDir    <- defaultLogsDir
   return mempty {
@@ -564,62 +570,125 @@
 --
 initialSavedConfig :: IO SavedConfig
 initialSavedConfig = do
-  cacheDir    <- defaultCacheDir
-  logsDir     <- defaultLogsDir
-  extraPath   <- defaultExtraPath
+  cacheDir <- defaultCacheDir
+  logsDir <- defaultLogsDir
   installPath <- defaultInstallPath
-  return mempty {
-    savedGlobalFlags     = mempty {
-      globalCacheDir     = toFlag cacheDir,
-      globalRemoteRepos  = toNubList [defaultRemoteRepo]
-    },
-    savedConfigureFlags  = mempty {
-      configProgramPathExtra = toNubList extraPath
-    },
-    savedInstallFlags    = mempty {
-      installSummaryFile = toNubList [toPathTemplate (logsDir </> "build.log")],
-      installBuildReports= toFlag NoReports,
-      installNumJobs     = toFlag Nothing
-    },
-    savedClientInstallFlags = mempty {
-      cinstInstalldir = toFlag installPath
-    }
-  }
+  return
+    mempty
+      { savedGlobalFlags =
+          mempty
+            { globalCacheDir = toFlag cacheDir
+            , globalRemoteRepos = toNubList [defaultRemoteRepo]
+            }
+      , savedInstallFlags =
+          mempty
+            { installSummaryFile = toNubList [toPathTemplate (logsDir </> "build.log")]
+            , installBuildReports = toFlag NoReports
+            , installNumJobs = toFlag Nothing
+            }
+      , savedClientInstallFlags =
+          mempty
+            { cinstInstalldir = toFlag installPath
+            }
+      }
 
-defaultCabalDir :: IO FilePath
-defaultCabalDir = getAppUserDataDirectory "cabal"
+-- | Issue a warning if both @$XDG_CONFIG_HOME/cabal/config@ and
+-- @~/.cabal@ exists.
+warnOnTwoConfigs :: Verbosity -> IO ()
+warnOnTwoConfigs verbosity = do
+  defaultDir <- getAppUserDataDirectory "cabal"
+  xdgCfgDir <- getXdgDirectory XdgConfig "cabal"
+  when (defaultDir /= xdgCfgDir) $ do
+    dotCabalExists <- doesDirectoryExist defaultDir
+    let xdgCfg = xdgCfgDir </> "config"
+    xdgCfgExists <- doesFileExist xdgCfg
+    when (dotCabalExists && xdgCfgExists) $
+      warn verbosity $
+        "Both "
+          <> defaultDir
+          <> " and "
+          <> xdgCfg
+          <> " exist - ignoring the former.\n"
+          <> "It is advisable to remove one of them. In that case, we will use the remaining one by default (unless '$CABAL_DIR' is explicitly set)."
 
-getCabalDir :: IO FilePath
-getCabalDir = do
+-- | If @CABAL\_DIR@ is set, return @Just@ its value. Otherwise, if
+-- @~/.cabal@ exists and @$XDG_CONFIG_HOME/cabal/config@ does not
+-- exist, return @Just "~/.cabal"@.  Otherwise, return @Nothing@.  If
+-- this function returns Nothing, then it implies that we are not
+-- using a single directory for everything, but instead use XDG paths.
+-- Fundamentally, this function is used to implement transparent
+-- backwards compatibility with pre-XDG versions of cabal-install.
+maybeGetCabalDir :: IO (Maybe FilePath)
+maybeGetCabalDir = do
   mDir <- lookupEnv "CABAL_DIR"
   case mDir of
-    Nothing -> defaultCabalDir
-    Just dir -> return dir
+    Just dir -> return $ Just dir
+    Nothing -> do
+      defaultDir <- getAppUserDataDirectory "cabal"
+      dotCabalExists <- doesDirectoryExist defaultDir
+      xdgCfg <- getXdgDirectory XdgConfig ("cabal" </> "config")
+      xdgCfgExists <- doesFileExist xdgCfg
+      if dotCabalExists && not xdgCfgExists
+        then return $ Just defaultDir
+        else return Nothing
 
+-- | The default behaviour of cabal-install is to use the XDG
+-- directory standard.  However, if @CABAL_DIR@ is set, we instead use
+-- that directory as a single store for everything cabal-related, like
+-- the old @~/.cabal@ behaviour.  Also, for backwards compatibility,
+-- if @~/.cabal@ exists we treat that as equivalent to @CABAL_DIR@
+-- being set.  This function abstracts that decision-making.
+getDefaultDir :: XdgDirectory -> FilePath -> IO FilePath
+getDefaultDir xdg subdir = do
+  mDir <- maybeGetCabalDir
+  case mDir of
+    Just dir -> return $ dir </> subdir
+    Nothing -> getXdgDirectory xdg $ "cabal" </> subdir
+
+-- | The default prefix used for installation.
+defaultInstallPrefix :: IO FilePath
+defaultInstallPrefix = do
+  mDir <- maybeGetCabalDir
+  case mDir of
+    Just dir ->
+      return dir
+    Nothing -> do
+      dir <- getHomeDirectory
+      return $ dir </> ".local"
+
 defaultConfigFile :: IO FilePath
-defaultConfigFile = do
-  dir <- getCabalDir
-  return $ dir </> "config"
+defaultConfigFile =
+  getDefaultDir XdgConfig "config"
 
 defaultCacheDir :: IO FilePath
-defaultCacheDir = do
-  dir <- getCabalDir
-  return $ dir </> "packages"
+defaultCacheDir =
+  getDefaultDir XdgCache "packages"
 
+defaultScriptBuildsDir :: IO FilePath
+defaultScriptBuildsDir =
+  getDefaultDir XdgCache "script-builds"
+
+defaultStoreDir :: IO FilePath
+defaultStoreDir =
+  getDefaultDir XdgState "store"
+
 defaultLogsDir :: IO FilePath
-defaultLogsDir = do
-  dir <- getCabalDir
-  return $ dir </> "logs"
+defaultLogsDir =
+  getDefaultDir XdgCache "logs"
 
-defaultExtraPath :: IO [FilePath]
-defaultExtraPath = do
-  dir <- getCabalDir
-  return [dir </> "bin"]
+defaultReportsDir :: IO FilePath
+defaultReportsDir =
+  getDefaultDir XdgCache "reports"
 
 defaultInstallPath :: IO FilePath
 defaultInstallPath = do
-  dir <- getCabalDir
-  return (dir </> "bin")
+  mDir <- maybeGetCabalDir
+  case mDir of
+    Just dir ->
+      return $ dir </> "bin"
+    Nothing -> do
+      dir <- getHomeDirectory
+      return $ dir </> ".local" </> "bin"
 
 defaultCompiler :: CompilerFlavor
 defaultCompiler = fromMaybe GHC defaultCompilerFlavor
@@ -635,7 +704,7 @@
     str  = "hackage.haskell.org"
     name = RepoName str
     uri  = URI "http:" (Just (URIAuth "" str "")) "/" "" ""
-    -- Note that lots of old ~/.cabal/config files will have the old url
+    -- Note that lots of old config files will have the old url
     -- http://hackage.haskell.org/packages/archive
     -- but new config files can use the new url (without the /packages/archive)
     -- and avoid having to do a http redirect
@@ -682,12 +751,29 @@
 --
 defaultHackageRemoteRepoKeys :: [String]
 defaultHackageRemoteRepoKeys =
-    [ "fe331502606802feac15e514d9b9ea83fee8b6ffef71335479a2e68d84adc6b0",
-      "1ea9ba32c526d1cc91ab5e5bd364ec5e9e8cb67179a471872f6e26f0ae773d42",
-      "2c6c3627bd6c982990239487f1abd02e08a02e6cf16edb105a8012d444d870c3",
-      "0a5c7ea47cd1b15f01f5f51a33adda7e655bc0f0b0615baa8e271f4c3351e21d",
-      "51f0161b906011b52c6613376b1ae937670da69322113a246a09f807c62f6921"
-    ]
+  -- Key owners and public keys are provided as a convenience to readers.
+  -- The canonical source for this mapping data is the hackage-root-keys
+  -- repository and Hackage's root.json file.
+  --
+  -- Links:
+  --  * https://github.com/haskell-infra/hackage-root-keys
+  --  * https://hackage.haskell.org/root.json
+  -- Please consult root.json on Hackage to map key IDs to public keys,
+  -- and the hackage-root-keys repository to map public keys to their
+  -- owners.
+  [ -- Adam Gundry (uRPdSiL3/MNsk50z6NB55ABo0OrrNDXigtCul4vtzmw=)
+    "fe331502606802feac15e514d9b9ea83fee8b6ffef71335479a2e68d84adc6b0"
+  , -- Gershom Bazerman (bYoUXXQ9TtX10UriaMiQtTccuXPGnmldP68djzZ7cLo=)
+    "1ea9ba32c526d1cc91ab5e5bd364ec5e9e8cb67179a471872f6e26f0ae773d42"
+  , -- John Wiegley (zazm5w480r+zPO6Z0+8fjGuxZtb9pAuoVmQ+VkuCvgU=)
+    "0a5c7ea47cd1b15f01f5f51a33adda7e655bc0f0b0615baa8e271f4c3351e21d"
+  , -- Norman Ramsey (ZI8di3a9Un0s2RBrt5GwVRvfOXVuywADfXGPZfkiDb0=)
+    "51f0161b906011b52c6613376b1ae937670da69322113a246a09f807c62f6921"
+  , -- Mathieu Boespflug (ydN1nGGQ79K1Q0nN+ul+Ln8MxikTB95w0YdGd3v3kmg=)
+    "be75553f3c7ba1dbe298da81f1d1b05c9d39dd8ed2616c9bddf1525ca8c03e48"
+  , -- Joachim Breitner (5iUgwqZCWrCJktqMx0bBMIuoIyT4A1RYGozzchRN9rA=)
+    "d26e46f3b631aae1433b89379a6c68bd417eb5d1c408f0643dcc07757fece522"
+  ]
 
 -- | The required threshold of root key signatures for hackage.haskell.org
 --
@@ -704,6 +790,7 @@
 --
 loadConfig :: Verbosity -> Flag FilePath -> IO SavedConfig
 loadConfig verbosity configFileFlag = do
+  warnOnTwoConfigs verbosity
   config <- loadRawConfig verbosity configFileFlag
   extendToEffectiveConfig config
 
@@ -845,7 +932,8 @@
   globalInstallDirs <- defaultInstallDirs defaultCompiler False True
   let conf0 = mempty {
         savedGlobalFlags       = defaultGlobalFlags {
-            globalRemoteRepos = toNubList [defaultRemoteRepo]
+            globalRemoteRepos = toNubList [defaultRemoteRepo],
+            globalNix         = mempty
             },
         savedInitFlags       = mempty {
             IT.interactive     = toFlag False,
@@ -1194,6 +1282,14 @@
                    , configConfigureArgs      = splitMultiPath
                                                 (configConfigureArgs scf)
                }
+       , savedGlobalFlags =
+           let sgf = savedGlobalFlags conf
+           in sgf {
+                    globalProgPathExtra =
+                      toNubList $
+                        splitMultiPath
+                          (fromNubList $ globalProgPathExtra sgf)
+               }
       }
 
     parse = parseFields (configFieldDescriptions src
@@ -1429,7 +1525,7 @@
       unlines (map (showPWarning "Error parsing additional config lines") ws)
 
 -- | Get the differences (as a pseudo code diff) between the user's
--- '~/.cabal/config' and the one that cabal would generate if it didn't exist.
+-- config file and the one that cabal would generate if it didn't exist.
 userConfigDiff :: Verbosity -> GlobalFlags -> [String] -> IO [String]
 userConfigDiff verbosity globalFlags extraLines = do
   userConfig <- loadRawConfig normal (globalConfigFile globalFlags)
@@ -1476,7 +1572,7 @@
         in (topAndTail left, topAndTail (drop 1 right))
 
 
--- | Update the user's ~/.cabal/config' keeping the user's customizations.
+-- | Update the user's config file keeping the user's customizations.
 userConfigUpdate :: Verbosity -> GlobalFlags -> [String] -> IO ()
 userConfigUpdate verbosity globalFlags extraLines = do
   userConfig  <- loadRawConfig normal (globalConfigFile globalFlags)
diff --git a/cabal/cabal-install/src/Distribution/Client/Configure.hs b/cabal/cabal-install/src/Distribution/Client/Configure.hs
--- a/cabal/cabal-install/src/Distribution/Client/Configure.hs
+++ b/cabal/cabal-install/src/Distribution/Client/Configure.hs
@@ -73,8 +73,8 @@
 import Distribution.PackageDescription.Configuration
          ( finalizePD )
 import Distribution.Version
-         ( Version, mkVersion, anyVersion, thisVersion
-         , VersionRange, orLaterVersion )
+         ( Version, anyVersion, thisVersion
+         , VersionRange )
 import Distribution.Simple.Utils as Utils
          ( warn, notice, debug, die'
          , defaultPackageDesc )
@@ -84,21 +84,12 @@
 import System.FilePath ( (</>) )
 
 -- | Choose the Cabal version such that the setup scripts compiled against this
--- version will support the given command-line flags.
+-- version will support the given command-line flags. Currently, it implements no
+-- specific restrictions and allows any version, unless the second argument is
+-- filled with a 'Version', in which case this version is picked.
 chooseCabalVersion :: ConfigExFlags -> Maybe Version -> VersionRange
-chooseCabalVersion configExFlags maybeVersion =
-  maybe defaultVersionRange thisVersion maybeVersion
-  where
-    -- Cabal < 1.19.2 doesn't support '--exact-configuration' which is needed
-    -- for '--allow-newer' to work.
-    allowNewer = isRelaxDeps
-                 (maybe mempty unAllowNewer $ configAllowNewer configExFlags)
-    allowOlder = isRelaxDeps
-                 (maybe mempty unAllowOlder $ configAllowOlder configExFlags)
-
-    defaultVersionRange = if allowOlder || allowNewer
-                          then orLaterVersion (mkVersion [1,19,2])
-                          else anyVersion
+chooseCabalVersion _configExFlags maybeVersion =
+  maybe anyVersion thisVersion maybeVersion
 
 -- | Configure the package found in the local directory
 configure :: Verbosity
diff --git a/cabal/cabal-install/src/Distribution/Client/Dependency.hs b/cabal/cabal-install/src/Distribution/Client/Dependency.hs
--- a/cabal/cabal-install/src/Distribution/Client/Dependency.hs
+++ b/cabal/cabal-install/src/Distribution/Client/Dependency.hs
@@ -397,21 +397,50 @@
       | Set.notMember (mkPackageName "base") (depResolverTargets params)
       -- If you change this enumeration, make sure to update the list in
       -- "Distribution.Solver.Modular.Solver" as well
-      , pkgname <- [ mkPackageName "base"
-                   , mkPackageName "ghc-bignum"
-                   , mkPackageName "ghc-prim"
-                   , mkPackageName "integer-gmp"
-                   , mkPackageName "integer-simple"
-                   , mkPackageName "template-haskell"
-                   ]
+      , pkgname <- nonUpgradeablePackages
       , isInstalled pkgname ]
 
     isInstalled = not . null
                 . InstalledPackageIndex.lookupPackageName
                                  (depResolverInstalledPkgIndex params)
 
-addSourcePackages :: [UnresolvedSourcePackage]
-                  -> DepResolverParams -> DepResolverParams
+-- | The set of non-reinstallable packages includes those which cannot be
+-- rebuilt using a GHC installation and Hackage-published source distribution.
+-- There are a few reasons why this might be true:
+--
+--  * the package overrides its unit ID (e.g. with ghc's @-this-unit-id@ flag),
+--    which can result in multiple indistinguishable packages (having potentially
+--    different ABIs) with the same unit ID.
+--
+--  * the package contains definitions of wired-in declarations which tie
+--    it to a particular compiler (e.g. we can't build link against
+--    @base-4.18.0.0@ using GHC 9.6.1).
+--
+--  * the package does not have a complete (that is, buildable) source distribution.
+--    For instance, some packages provided by GHC rely on files outside of the
+--    source tree generated by GHC's build system.
+--
+-- Note: the list of non-upgradable/non-installable packages used to be
+-- respectively in this module and in `Distribution.Solver.Modular.Solver`.
+-- Since they were kept synced, they are now combined in the following list.
+--
+-- See: https://github.com/haskell/cabal/issues/8581 and
+-- https://github.com/haskell/cabal/issues/9064.
+nonUpgradeablePackages :: [PackageName]
+nonUpgradeablePackages =
+  [ mkPackageName "base"
+  , mkPackageName "ghc-bignum"
+  , mkPackageName "ghc-prim"
+  , mkPackageName "ghc"
+  , mkPackageName "integer-gmp"
+  , mkPackageName "integer-simple"
+  , mkPackageName "template-haskell"
+  ]
+
+addSourcePackages
+  :: [UnresolvedSourcePackage]
+  -> DepResolverParams
+  -> DepResolverParams
 addSourcePackages pkgs params =
     params {
       depResolverSourcePkgIndex =
diff --git a/cabal/cabal-install/src/Distribution/Client/DistDirLayout.hs b/cabal/cabal-install/src/Distribution/Client/DistDirLayout.hs
--- a/cabal/cabal-install/src/Distribution/Client/DistDirLayout.hs
+++ b/cabal/cabal-install/src/Distribution/Client/DistDirLayout.hs
@@ -27,6 +27,8 @@
 
 import System.FilePath
 
+import Distribution.Client.Config
+         ( defaultStoreDir, defaultLogsDir)
 import Distribution.Package
          ( PackageId, PackageIdentifier, ComponentId, UnitId )
 import Distribution.Compiler
@@ -292,19 +294,16 @@
       storeIncomingDirectory compid </> prettyShow unitid <.> "lock"
 
 
-defaultCabalDirLayout :: FilePath -> CabalDirLayout
-defaultCabalDirLayout cabalDir =
-    mkCabalDirLayout cabalDir Nothing Nothing
+defaultCabalDirLayout :: IO CabalDirLayout
+defaultCabalDirLayout =
+    mkCabalDirLayout Nothing Nothing
 
-mkCabalDirLayout :: FilePath -- ^ Cabal directory
-                 -> Maybe FilePath -- ^ Store directory. Must be absolute
+mkCabalDirLayout :: Maybe FilePath -- ^ Store directory. Must be absolute
                  -> Maybe FilePath -- ^ Log directory
-                 -> CabalDirLayout
-mkCabalDirLayout cabalDir mstoreDir mlogDir =
-    CabalDirLayout {..}
-  where
-    cabalStoreDirLayout :: StoreDirLayout
-    cabalStoreDirLayout =
-        defaultStoreDirLayout (fromMaybe (cabalDir </> "store") mstoreDir)
-    cabalLogsDirectory :: FilePath
-    cabalLogsDirectory = fromMaybe (cabalDir </> "logs") mlogDir
+                 -> IO CabalDirLayout
+mkCabalDirLayout mstoreDir mlogDir = do
+    cabalStoreDirLayout <-
+      defaultStoreDirLayout <$> maybe defaultStoreDir pure mstoreDir
+    cabalLogsDirectory <-
+      maybe defaultLogsDir pure mlogDir
+    pure $ CabalDirLayout {..}
diff --git a/cabal/cabal-install/src/Distribution/Client/FetchUtils.hs b/cabal/cabal-install/src/Distribution/Client/FetchUtils.hs
--- a/cabal/cabal-install/src/Distribution/Client/FetchUtils.hs
+++ b/cabal/cabal-install/src/Distribution/Client/FetchUtils.hs
@@ -11,7 +11,7 @@
 --
 -- Functions for fetching packages
 -----------------------------------------------------------------------------
-{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE RecordWildCards, ScopedTypeVariables #-}
 module Distribution.Client.FetchUtils (
 
     -- * fetching packages
@@ -22,6 +22,7 @@
     -- ** specifically for repo packages
     checkRepoTarballFetched,
     fetchRepoTarball,
+    verifyFetchedTarball,
 
     -- ** fetching packages asynchronously
     asyncFetchPackages,
@@ -43,7 +44,7 @@
 import Distribution.Package
          ( PackageId, packageName, packageVersion )
 import Distribution.Simple.Utils
-         ( notice, info, debug, die' )
+         ( notice, info, debug, warn, die' )
 import Distribution.Verbosity
          ( verboseUnmarkOutput )
 import Distribution.Client.GlobalFlags
@@ -56,7 +57,8 @@
 import Control.Concurrent.Async
 import Control.Concurrent.MVar
 import System.Directory
-         ( doesFileExist, createDirectoryIfMissing, getTemporaryDirectory )
+         ( doesFileExist, createDirectoryIfMissing, getTemporaryDirectory
+         , getFileSize )
 import System.IO
          ( openTempFile, hClose )
 import System.FilePath
@@ -67,6 +69,8 @@
          ( URI(uriPath) )
 
 import qualified Hackage.Security.Client as Sec
+import qualified Hackage.Security.Util.Path as Sec
+import qualified Hackage.Security.Util.Checked as Sec
 
 -- ------------------------------------------------------------
 -- * Actually fetch things
@@ -118,6 +122,38 @@
       then return (Just file)
       else return Nothing
 
+verifyFetchedTarball :: Verbosity -> RepoContext -> Repo -> PackageId -> IO Bool
+verifyFetchedTarball verbosity repoCtxt repo pkgid =
+   let file = packageFile repo pkgid
+       handleError :: IO Bool -> IO Bool
+       handleError act = do
+         res <- Safe.try act
+         case res of
+           Left e -> warn verbosity ("Error verifying fetched tarball " ++ file ++ ", will redownload: " ++ show (e :: SomeException)) >> pure False
+           Right b -> pure b
+   in handleError $ do
+        exists <- doesFileExist file
+        if not exists
+          then return True -- if the file does not exist, it vacuously passes validation, since it will be downloaded as necessary with what we will then check is a valid hash.
+          else case repo of
+            -- a secure repo has hashes we can compare against to confirm this is the correct file.
+                RepoSecure{} ->
+                 repoContextWithSecureRepo repoCtxt repo $ \repoSecure ->
+                   Sec.withIndex repoSecure $ \callbacks ->
+                     let warnAndFail s = warn verbosity ("Fetched tarball " ++ file ++ " does not match server, will redownload: " ++ s) >> return False
+                     -- the do block in parens is due to dealing with the checked exceptions mechanism.
+                     in (do fileInfo <- Sec.indexLookupFileInfo callbacks pkgid
+                            sz <- Sec.FileLength . fromInteger <$> getFileSize file
+                            if sz /= Sec.fileInfoLength (Sec.trusted fileInfo)
+                              then warnAndFail "file length mismatch"
+                              else do
+                                res <- Sec.compareTrustedFileInfo (Sec.trusted fileInfo) <$> Sec.computeFileInfo (Sec.Path file :: Sec.Path Sec.Absolute)
+                                if res
+                                  then pure True
+                                  else warnAndFail "file hash mismatch")
+                       `Sec.catchChecked` (\(e :: Sec.InvalidPackageException) -> warnAndFail (show e))
+                       `Sec.catchChecked` (\(e :: Sec.VerificationError) -> warnAndFail (show e))
+                _ -> pure True
 
 -- | Fetch a package if we don't have it already.
 --
@@ -290,7 +326,7 @@
 -- ------------------------------------------------------------
 
 -- | Generate the full path to the locally cached copy of
--- the tarball for a given @PackageIdentifer@.
+-- the tarball for a given @PackageIdentifier@.
 --
 packageFile :: Repo -> PackageId -> FilePath
 packageFile repo pkgid = packageDir repo pkgid
@@ -298,7 +334,7 @@
                      <.> "tar.gz"
 
 -- | Generate the full path to the directory where the local cached copy of
--- the tarball for a given @PackageIdentifer@ is stored.
+-- the tarball for a given @PackageIdentifier@ is stored.
 --
 packageDir :: Repo -> PackageId -> FilePath
 packageDir (RepoLocalNoIndex (LocalRepo _ dir _) _) _pkgid = dir
diff --git a/cabal/cabal-install/src/Distribution/Client/GenBounds.hs b/cabal/cabal-install/src/Distribution/Client/GenBounds.hs
--- a/cabal/cabal-install/src/Distribution/Client/GenBounds.hs
+++ b/cabal/cabal-install/src/Distribution/Client/GenBounds.hs
@@ -19,7 +19,7 @@
 import Distribution.Client.Compat.Prelude
 
 import Distribution.Client.Utils
-         ( incVersion )
+         ( hasElem, incVersion )
 import Distribution.Client.Freeze
          ( getFreezePkgs )
 import Distribution.Client.Setup
@@ -40,7 +40,7 @@
 import Distribution.Simple.Program
          ( ProgramDb )
 import Distribution.Simple.Utils
-         ( tryFindPackageDesc )
+         ( notice, tryFindPackageDesc )
 import Distribution.System
          ( Platform )
 import Distribution.Version
@@ -106,33 +106,29 @@
     case epd of
       Left _ -> putStrLn "finalizePD failed"
       Right (pd,_) -> do
-        let needBounds = filter (not . hasUpperBound . depVersion) $
+       let needBounds = map depName $ filter (not . hasUpperBound . depVersion) $
                          enabledBuildDepends pd defaultComponentRequestedSpec
 
-        if (null needBounds)
-          then putStrLn
-               "Congratulations, all your dependencies have upper bounds!"
-          else go needBounds
-  where
-     go needBounds = do
        pkgs  <- getFreezePkgs
                   verbosity packageDBs repoCtxt comp platform progdb
                   globalFlags freezeFlags
 
-       putStrLn boundsNeededMsg
-
-       let isNeeded pkg = unPackageName (packageName pkg)
-                          `elem` map depName needBounds
+       let isNeeded = hasElem needBounds . unPackageName . packageName
        let thePkgs = filter isNeeded pkgs
 
        let padTo = maximum $ map (length . unPackageName . packageName) pkgs
-       traverse_ (putStrLn . (++",") . showBounds padTo) thePkgs
 
-     depName :: Dependency -> String
-     depName (Dependency pn _ _) = unPackageName pn
+       if null thePkgs then notice verbosity
+         "Congratulations, all your dependencies have upper bounds!"
+        else do
+         notice verbosity boundsNeededMsg
+         traverse_ (notice verbosity . (++",") . showBounds padTo) thePkgs
 
-     depVersion :: Dependency -> VersionRange
-     depVersion (Dependency _ vr _) = vr
+depName :: Dependency -> String
+depName (Dependency pn _ _) = unPackageName pn
+
+depVersion :: Dependency -> VersionRange
+depVersion (Dependency _ vr _) = vr
 
 -- | The message printed when some dependencies are found to be lacking proper
 -- PVP-mandated bounds.
diff --git a/cabal/cabal-install/src/Distribution/Client/Get.hs b/cabal/cabal-install/src/Distribution/Client/Get.hs
--- a/cabal/cabal-install/src/Distribution/Client/Get.hs
+++ b/cabal/cabal-install/src/Distribution/Client/Get.hs
@@ -31,12 +31,14 @@
 import Distribution.Simple.Setup
          ( Flag(..), fromFlag, fromFlagOrDefault, flagToMaybe )
 import Distribution.Simple.Utils
-         ( notice, die', info, writeFileAtomic )
+         ( notice, die', info, warn, writeFileAtomic )
 import qualified Distribution.PackageDescription as PD
 import Distribution.Simple.Program
          ( programName )
 import Distribution.Types.SourceRepo (RepoKind (..))
 import Distribution.Client.Types.SourceRepo (SourceRepositoryPackage (..), SourceRepoProxy, srpToProxy)
+import Distribution.Utils.NubList
+         ( fromNubList )
 
 import Distribution.Client.Setup
          ( GlobalFlags(..), GetFlags(..), RepoContext(..) )
@@ -49,8 +51,12 @@
 import Distribution.Client.IndexUtils
         ( getSourcePackagesAtIndexState, TotalIndexState, ActiveRepos )
 import Distribution.Solver.Types.SourcePackage
+import Distribution.PackageDescription.PrettyPrint
+        ( writeGenericPackageDescription )
 
 import qualified Data.Map as Map
+import Control.Monad ( mapM_ )
+
 import System.Directory
          ( createDirectoryIfMissing, doesDirectoryExist, doesFileExist )
 import System.FilePath
@@ -67,7 +73,7 @@
 get verbosity _ _ _ [] =
     notice verbosity "No packages requested. Nothing to do."
 
-get verbosity repoCtxt _ getFlags userTargets = do
+get verbosity repoCtxt globalFlags getFlags userTargets = do
   let useSourceRepo = case getSourceRepository getFlags of
                         NoFlag -> False
                         _      -> True
@@ -94,21 +100,31 @@
   unless (null prefix) $
     createDirectoryIfMissing True prefix
 
-  if useSourceRepo
-    then clone  pkgs
-    else unpack pkgs
+  if onlyPkgDescr
+    then do
+      when useSourceRepo $
+        warn verbosity $
+          "Ignoring --source-repository for --only-package-description"
 
+      mapM_ (unpackOnlyPkgDescr verbosity prefix) pkgs
+    else
+      if useSourceRepo
+        then clone pkgs
+        else unpack pkgs
+
   where
     resolverParams :: SourcePackageDb -> [PackageSpecifier UnresolvedSourcePackage] -> DepResolverParams
     resolverParams sourcePkgDb pkgSpecifiers =
         --TODO: add command-line constraint and preference args for unpack
         standardInstallPolicy mempty sourcePkgDb pkgSpecifiers
 
+    onlyPkgDescr = fromFlagOrDefault False (getOnlyPkgDescr getFlags)
+
     prefix :: String
     prefix = fromFlagOrDefault "" (getDestDir getFlags)
 
     clone :: [UnresolvedSourcePackage] -> IO ()
-    clone = clonePackagesFromSourceRepo verbosity prefix kind
+    clone = clonePackagesFromSourceRepo verbosity prefix kind (fromNubList $ globalProgPathExtra globalFlags)
           . map (\pkg -> (packageId pkg, packageSourceRepos pkg))
       where
         kind :: Maybe RepoKind
@@ -189,6 +205,23 @@
         writeFileAtomic descFilePath pkgtxt
 
 
+-- | Write a @pkgId.cabal@ file with the package description to the destination
+-- directory, unless one already exists.
+unpackOnlyPkgDescr :: Verbosity -> FilePath -> UnresolvedSourcePackage -> IO ()
+unpackOnlyPkgDescr verbosity dstDir pkg = do
+    let pkgFile = dstDir </> prettyShow (packageId pkg) <.> "cabal"
+    existsFile <- doesFileExist pkgFile
+    when existsFile $ die' verbosity $
+      "The file \"" ++ pkgFile ++ "\" already exists, not overwriting."
+    existsDir <- doesDirectoryExist (addTrailingPathSeparator pkgFile)
+    when existsDir $ die' verbosity $
+      "A directory \"" ++ pkgFile ++ "\" is in the way, not unpacking."
+    notice verbosity $ "Writing package description to " ++ pkgFile
+    case srcpkgDescrOverride pkg of
+      Just pkgTxt -> writeFileAtomic pkgFile pkgTxt
+      Nothing ->
+        writeGenericPackageDescription pkgFile (srcpkgDescription pkg)
+
 -- ------------------------------------------------------------
 -- * Cloning packages from their declared source repositories
 -- ------------------------------------------------------------
@@ -248,18 +281,19 @@
 clonePackagesFromSourceRepo :: Verbosity
                             -> FilePath            -- ^ destination dir prefix
                             -> Maybe RepoKind      -- ^ preferred 'RepoKind'
+                            -> [FilePath]          -- ^ Extra prog paths
                             -> [(PackageId, [PD.SourceRepo])]
                                                    -- ^ the packages and their
                                                    -- available 'SourceRepo's
                             -> IO ()
 clonePackagesFromSourceRepo verbosity destDirPrefix
-                            preferredRepoKind pkgrepos = do
+                            preferredRepoKind progPaths pkgrepos = do
 
     -- Do a bunch of checks and collect the required info
     pkgrepos' <- traverse preCloneChecks pkgrepos
 
     -- Configure the VCS drivers for all the repository types we may need
-    vcss <- configureVCSs verbosity $
+    vcss <- configureVCSs verbosity progPaths $
               Map.fromList [ (vcsRepoType vcs, vcs)
                            | (_, _, vcs, _) <- pkgrepos' ]
 
diff --git a/cabal/cabal-install/src/Distribution/Client/Haddock.hs b/cabal/cabal-install/src/Distribution/Client/Haddock.hs
--- a/cabal/cabal-install/src/Distribution/Client/Haddock.hs
+++ b/cabal/cabal-install/src/Distribution/Client/Haddock.hs
@@ -41,7 +41,7 @@
                        -> IO ()
 regenerateHaddockIndex verbosity pkgs progdb index = do
       (paths, warns) <- haddockPackagePaths pkgs' Nothing
-      let paths' = [ (interface, html) | (interface, Just html, _) <- paths]
+      let paths' = [ (interface, html) | (interface, Just html, _, _) <- paths]
       for_ warns (debug verbosity)
 
       (confHaddock, _, _) <-
diff --git a/cabal/cabal-install/src/Distribution/Client/HashValue.hs b/cabal/cabal-install/src/Distribution/Client/HashValue.hs
--- a/cabal/cabal-install/src/Distribution/Client/HashValue.hs
+++ b/cabal/cabal-install/src/Distribution/Client/HashValue.hs
@@ -15,9 +15,9 @@
 
 import qualified Hackage.Security.Client as Sec
 
-import qualified Crypto.Hash.SHA256         as SHA256
-import qualified Data.ByteString.Base16     as Base16
-import qualified Data.ByteString.Char8      as BS
+import qualified Crypto.Hash.SHA256 as SHA256
+import qualified Data.ByteString.Base16 as Base16
+import qualified Data.ByteString.Char8 as BS
 import qualified Data.ByteString.Lazy.Char8 as LBS
 
 import System.IO         (IOMode (..), withBinaryFile)
diff --git a/cabal/cabal-install/src/Distribution/Client/HttpUtils.hs b/cabal/cabal-install/src/Distribution/Client/HttpUtils.hs
--- a/cabal/cabal-install/src/Distribution/Client/HttpUtils.hs
+++ b/cabal/cabal-install/src/Distribution/Client/HttpUtils.hs
@@ -54,13 +54,12 @@
 import Distribution.Simple.Program
          ( Program, simpleProgram, ConfiguredProgram, programPath
          , ProgramInvocation(..), programInvocation
-         , ProgramSearchPathEntry(..)
          , getProgramInvocationOutput )
 import Distribution.Simple.Program.Db
          ( ProgramDb, emptyProgramDb, addKnownPrograms
          , configureAllKnownPrograms
          , requireProgram, lookupProgram
-         , modifyProgramSearchPath )
+         , appendProgramSearchPath )
 import Distribution.Simple.Program.Run
          ( getProgramInvocationOutputAndErrors )
 import Numeric (showHex)
@@ -336,7 +335,7 @@
     case find (\(name',_,_,_) -> name' == name) supportedTransports of
       Just (_, mprog, _tls, mkTrans) -> do
 
-        let baseProgDb = modifyProgramSearchPath (\p -> map ProgramSearchPathDir extraPath ++ p) emptyProgramDb
+        baseProgDb <- appendProgramSearchPath verbosity extraPath emptyProgramDb
         progdb <- case mprog of
           Nothing   -> return emptyProgramDb
           Just prog -> snd <$> requireProgram verbosity prog baseProgDb
@@ -356,7 +355,7 @@
 
     -- for all the transports except plain-http we need to try and find
     -- their external executable
-    let baseProgDb = modifyProgramSearchPath (\p -> map ProgramSearchPathDir extraPath ++ p) emptyProgramDb
+    baseProgDb <- appendProgramSearchPath verbosity extraPath emptyProgramDb
     progdb <- configureAllKnownPrograms  verbosity $
                 addKnownPrograms
                   [ prog | (_, Just prog, _, _) <- supportedTransports ]
@@ -500,7 +499,7 @@
             warningMsg     =  "the 'wget' transport currently doesn't support"
                            ++ " range requests, which wastes network bandwidth."
                            ++ " To fix this, set 'http-transport' to 'curl' or"
-                           ++ " 'plain-http' in '~/.cabal/config'."
+                           ++ " 'plain-http' in '~/.config/cabal/config'."
                            ++ " Note that the 'plain-http' transport doesn't"
                            ++ " support HTTPS.\n"
 
diff --git a/cabal/cabal-install/src/Distribution/Client/Init/Format.hs b/cabal/cabal-install/src/Distribution/Client/Init/Format.hs
--- a/cabal/cabal-install/src/Distribution/Client/Init/Format.hs
+++ b/cabal/cabal-install/src/Distribution/Client/Init/Format.hs
@@ -123,7 +123,7 @@
 mkCommonStanza :: WriteOpts -> PrettyField FieldAnnotation
 mkCommonStanza opts = case specHasCommonStanzas $ _optCabalSpec opts of
   NoCommonStanzas -> PrettyEmpty
-  _ -> PrettySection 
+  _ -> PrettySection
     annNoComments
     "common"
     [text "warnings"]
@@ -136,7 +136,7 @@
         NoCommonStanzas -> PrettyEmpty
         _ -> field "import" (hsep . map text) ["warnings"]
           ["Import common warning flags."]
-          False 
+          False
           opts
 
     , field "exposed-modules" formatExposedModules (toList expMods)
@@ -182,9 +182,9 @@
           NoCommonStanzas -> PrettyEmpty
           _ -> field "import" (hsep . map text) ["warnings"]
             ["Import common warning flags."]
-            False 
+            False
             opts
-      
+
       , field "main-is" unsafeFromHs exeMain
          [".hs or .lhs file containing the Main module."]
          True
@@ -230,9 +230,9 @@
            NoCommonStanzas -> PrettyEmpty
            _ -> field "import" (hsep . map text) ["warnings"]
              ["Import common warning flags."]
-             False 
+             False
              opts
-      
+
        , field "default-language" id lang
          ["Base language which the package is written in."]
          True
diff --git a/cabal/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs b/cabal/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs
--- a/cabal/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs
+++ b/cabal/cabal-install/src/Distribution/Client/Init/Interactive/Command.hs
@@ -356,14 +356,10 @@
       else fmap prettyShow knownLicenses
 
 authorPrompt :: Interactive m => InitFlags -> m String
-authorPrompt flags = getAuthor flags $ do
-    name <- guessAuthorName
-    promptStr "Author name" (DefaultPrompt name)
+authorPrompt flags = getAuthor flags $ guessAuthorName >>= promptOrDefault "Author name"
 
 emailPrompt :: Interactive m => InitFlags -> m String
-emailPrompt flags = getEmail flags $ do
-    email' <- guessAuthorEmail
-    promptStr "Maintainer email" (DefaultPrompt email')
+emailPrompt flags = getEmail flags $ guessAuthorEmail >>= promptOrDefault "Maintainer email"
 
 homepagePrompt :: Interactive m => InitFlags -> m String
 homepagePrompt flags = getHomepage flags $
@@ -416,7 +412,7 @@
     let h2010   = "Haskell2010"
         h98     = "Haskell98"
         ghc2021 = "GHC2021 (requires at least GHC 9.2)"
-          
+
     l <- promptList ("Choose a language for your " ++ pkgType)
       [h2010, h98, ghc2021]
       (DefaultPrompt h2010)
@@ -427,13 +423,7 @@
       | l == h2010       -> return Haskell2010
       | l == h98         -> return Haskell98
       | l == ghc2021     -> return GHC2021
-      | all isAlphaNum l -> return $ UnknownLanguage l
-      | otherwise        -> do
-        putStrLn
-          $ "\nThe language must be alphanumeric. "
-          ++ "Please enter a different language."
-
-        languagePrompt flags pkgType
+      | otherwise        -> return $ UnknownLanguage l
 
 noCommentsPrompt :: Interactive m => InitFlags -> m Bool
 noCommentsPrompt flags = getNoComments flags $ do
@@ -474,3 +464,6 @@
       True
 
     return [dir]
+
+promptOrDefault :: Interactive m => String -> Maybe String -> m String
+promptOrDefault s = maybe (promptStr s MandatoryPrompt)  (promptStr s . DefaultPrompt)
diff --git a/cabal/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs b/cabal/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs
--- a/cabal/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs
+++ b/cabal/cabal-install/src/Distribution/Client/Init/NonInteractive/Command.hs
@@ -139,7 +139,7 @@
       return $ ProjectSettings
         (mkOpts comments cabalSpec) pkgDesc (Just libTarget)
         (Just exeTarget) testTarget
-    
+
     TestSuite -> do
       testTarget <- genTestTarget initFlags comp pkgIx cabalSpec
 
@@ -274,14 +274,16 @@
 licenseHeuristics flags = getLicense flags $ guessLicense flags
 
 -- | The author's name. Prompt, or try to guess from an existing
---   darcs repo.
+--   git repo.
 authorHeuristics :: Interactive m => InitFlags -> m String
-authorHeuristics flags = getAuthor flags guessAuthorEmail
+authorHeuristics flags = guessAuthorName >>=
+  maybe (getAuthor flags $ return "Unknown") (getAuthor flags . return)
 
 -- | The author's email. Prompt, or try to guess from an existing
---   darcs repo.
+--   git repo.
 emailHeuristics :: Interactive m => InitFlags -> m String
-emailHeuristics flags = getEmail flags guessAuthorName
+emailHeuristics flags = guessAuthorEmail >>=
+  maybe (getEmail flags $ return "Unknown") (getEmail flags . return)
 
 -- | Prompt for a homepage URL for the package.
 homepageHeuristics :: Interactive m => InitFlags -> m String
@@ -358,7 +360,7 @@
 
           otherModules' <- libOtherModulesHeuristics flags
           return $ filter (`notElem` otherModules') modulesNames
-        
+
         else
           return []
 
diff --git a/cabal/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs b/cabal/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs
--- a/cabal/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs
+++ b/cabal/cabal-install/src/Distribution/Client/Init/NonInteractive/Heuristics.hs
@@ -107,7 +107,7 @@
 guessPackageType flags = do
   if fromFlagOrDefault False (initializeTestSuite flags)
     then
-      return TestSuite 
+      return TestSuite
     else do
       let lastDir dirs   = L.last . splitDirectories $ dirs
           srcCandidates  = [defaultSourceDir, "src", "source"]
@@ -151,18 +151,23 @@
     True  -> ["src"]
 
 -- | Guess author and email using git configuration options.
-guessAuthorName :: Interactive m => m String
+guessAuthorName :: Interactive m => m (Maybe String)
 guessAuthorName = guessGitInfo "user.name"
 
-guessAuthorEmail :: Interactive m => m String
+guessAuthorEmail :: Interactive m => m (Maybe String)
 guessAuthorEmail = guessGitInfo "user.email"
 
-guessGitInfo :: Interactive m => String -> m String
+guessGitInfo :: Interactive m => String -> m (Maybe String)
 guessGitInfo target = do
-  info <- readProcessWithExitCode "git" ["config", "--local", target] ""
-  if null $ snd' info
-    then trim . snd' <$> readProcessWithExitCode "git" ["config", "--global", target] ""
-    else return . trim $ snd' info
+  localInfo <- readProcessWithExitCode "git" ["config", "--local", target] ""
+  if null $ snd' localInfo
+    then do
+      globalInfo <- readProcessWithExitCode "git" ["config", "--global", target] ""
+      case fst' globalInfo of
+        ExitSuccess -> return $  Just (trim $ snd' globalInfo)
+        _           -> return Nothing
+    else return $  Just (trim $ snd' localInfo)
 
   where
+    fst' (x, _, _) = x
     snd' (_, x, _) = x
diff --git a/cabal/cabal-install/src/Distribution/Client/Init/Simple.hs b/cabal/cabal-install/src/Distribution/Client/Init/Simple.hs
--- a/cabal/cabal-install/src/Distribution/Client/Init/Simple.hs
+++ b/cabal/cabal-install/src/Distribution/Client/Init/Simple.hs
@@ -16,7 +16,7 @@
 import qualified Data.List.NonEmpty as NEL
 import Distribution.Client.Init.Utils (currentDirPkgName, mkPackageNameDep, fixupDocFiles)
 import Distribution.Client.Init.Defaults
-import Distribution.Simple.Flag (fromFlagOrDefault, flagElim, Flag(..))
+import Distribution.Simple.Flag (fromFlagOrDefault, flagElim, Flag (..))
 import Distribution.Client.Init.FlagExtractors
 import qualified Data.Set as Set
 import Distribution.Types.Dependency
@@ -170,6 +170,6 @@
       return $ initFlags
         { dependencies = Flag $ based ++ as
         }
-  _ -> do
+  NoFlag -> do
     based <- dependenciesPrompt pkgIx initFlags
     return initFlags { dependencies = Flag based }
diff --git a/cabal/cabal-install/src/Distribution/Client/Init/Types.hs b/cabal/cabal-install/src/Distribution/Client/Init/Types.hs
--- a/cabal/cabal-install/src/Distribution/Client/Init/Types.hs
+++ b/cabal/cabal-install/src/Distribution/Client/Init/Types.hs
@@ -72,7 +72,7 @@
 import qualified System.IO
 
 import qualified System.Directory as P
-import qualified System.Process as P
+import qualified System.Process as Process
 import qualified Distribution.Compat.Environment as P
 import System.FilePath
 import Distribution.FieldGrammar.Newtypes (SpecLicense)
@@ -342,7 +342,7 @@
     doesDirectoryExist = P.doesDirectoryExist
     doesFileExist = P.doesFileExist
     canonicalizePathNoThrow = P.canonicalizePathNoThrow
-    readProcessWithExitCode = P.readProcessWithExitCode
+    readProcessWithExitCode = Process.readProcessWithExitCode
     getEnvironment = P.getEnvironment
     getCurrentYear = P.getCurrentYear
     listFilesInside = P.listFilesInside
diff --git a/cabal/cabal-install/src/Distribution/Client/Install.hs b/cabal/cabal-install/src/Distribution/Client/Install.hs
--- a/cabal/cabal-install/src/Distribution/Client/Install.hs
+++ b/cabal/cabal-install/src/Distribution/Client/Install.hs
@@ -71,7 +71,7 @@
          , ConfigExFlags(..), InstallFlags(..)
          , filterTestFlags )
 import Distribution.Client.Config
-         ( getCabalDir, defaultUserInstall )
+         ( defaultReportsDir, defaultUserInstall )
 import Distribution.Client.Tar (extractTarGzFile)
 import Distribution.Client.Types as Source
 import Distribution.Client.BuildReports.Types
@@ -197,7 +197,7 @@
         warn verbosity $ "--root-cmd is no longer supported, "
         ++ "see https://github.com/haskell/cabal/issues/3353"
         ++ " (if you didn't type --root-cmd, comment out root-cmd"
-        ++ " in your ~/.cabal/config file)"
+        ++ " in your ~/.config/cabal/config file)"
     let userOrSandbox = fromFlag (configUserInstall configFlags)
     unless userOrSandbox $
         warn verbosity $ "the --global flag is deprecated -- "
@@ -831,10 +831,10 @@
 storeDetailedBuildReports :: Verbosity -> FilePath
                           -> [(BuildReports.BuildReport, Maybe Repo)] -> IO ()
 storeDetailedBuildReports verbosity logsDir reports = sequence_
-  [ do dotCabal <- getCabalDir
+  [ do allReportsDir <- defaultReportsDir
        let logFileName = prettyShow (BuildReports.package report) <.> "log"
            logFile     = logsDir </> logFileName
-           reportsDir  = dotCabal </> "reports" </> unRepoName (remoteRepoName remoteRepo)
+           reportsDir  = allReportsDir </> unRepoName (remoteRepoName remoteRepo)
            reportFile  = reportsDir </> logFileName
 
        handleMissingLogFile $ do
diff --git a/cabal/cabal-install/src/Distribution/Client/Main.hs b/cabal/cabal-install/src/Distribution/Client/Main.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-install/src/Distribution/Client/Main.hs
@@ -0,0 +1,1013 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Main
+-- Copyright   :  (c) David Himmelstrup 2005
+-- License     :  BSD-like
+--
+-- Maintainer  :  lemmih@gmail.com
+-- Stability   :  provisional
+-- Portability :  portable
+--
+-- Entry point to the default cabal-install front-end.
+--
+-- @since 3.10.0.0
+-----------------------------------------------------------------------------
+
+module Distribution.Client.Main (main) where
+
+import Distribution.Client.Setup
+         ( GlobalFlags(..), globalCommand, withRepoContext
+         , ConfigFlags(..)
+         , ConfigExFlags(..), defaultConfigExFlags, configureExCommand
+         , reconfigureCommand
+         , configCompilerAux', configPackageDB'
+         , BuildFlags(..)
+         , buildCommand, replCommand, testCommand, benchmarkCommand
+         , InstallFlags(..), defaultInstallFlags
+         , installCommand
+         , FetchFlags(..), fetchCommand
+         , FreezeFlags(..), freezeCommand
+         , genBoundsCommand
+         , GetFlags(..), getCommand, unpackCommand
+         , checkCommand
+         , formatCommand
+         , ListFlags(..), listCommand, listNeedsCompiler
+         , InfoFlags(..), infoCommand
+         , UploadFlags(..), uploadCommand
+         , ReportFlags(..), reportCommand
+         , runCommand
+         , InitFlags(initVerbosity, initHcPath), initCommand
+         , ActAsSetupFlags(..), actAsSetupCommand
+         , UserConfigFlags(..), userConfigCommand
+         , reportCommand
+         , manpageCommand
+         , haddockCommand
+         , cleanCommand
+         , copyCommand
+         , registerCommand
+         )
+import Distribution.Simple.Setup
+         ( HaddockTarget(..)
+         , HaddockFlags(..), defaultHaddockFlags
+         , HscolourFlags(..), hscolourCommand
+         , ReplFlags(..)
+         , CopyFlags(..)
+         , RegisterFlags(..)
+         , CleanFlags(..)
+         , TestFlags(..), BenchmarkFlags(..)
+         , Flag(..), fromFlag, fromFlagOrDefault, flagToMaybe, toFlag
+         , configAbsolutePaths
+         )
+
+import Prelude ()
+import Distribution.Client.Compat.Prelude hiding (get)
+
+import Distribution.Client.SetupWrapper
+         ( setupWrapper, SetupScriptOptions(..), defaultSetupScriptOptions )
+import Distribution.Client.Config
+         ( SavedConfig(..), loadConfig, defaultConfigFile, userConfigDiff
+         , userConfigUpdate, createDefaultConfigFile, getConfigFilePath )
+import Distribution.Client.Targets
+         ( readUserTargets )
+import qualified Distribution.Client.List as List
+         ( list, info )
+
+import qualified Distribution.Client.CmdConfigure as CmdConfigure
+import qualified Distribution.Client.CmdUpdate    as CmdUpdate
+import qualified Distribution.Client.CmdBuild     as CmdBuild
+import qualified Distribution.Client.CmdRepl      as CmdRepl
+import qualified Distribution.Client.CmdFreeze    as CmdFreeze
+import qualified Distribution.Client.CmdHaddock   as CmdHaddock
+import qualified Distribution.Client.CmdHaddockProject as CmdHaddockProject
+import qualified Distribution.Client.CmdInstall   as CmdInstall
+import qualified Distribution.Client.CmdRun       as CmdRun
+import qualified Distribution.Client.CmdTest      as CmdTest
+import qualified Distribution.Client.CmdBench     as CmdBench
+import qualified Distribution.Client.CmdExec      as CmdExec
+import qualified Distribution.Client.CmdClean     as CmdClean
+import qualified Distribution.Client.CmdSdist     as CmdSdist
+import qualified Distribution.Client.CmdListBin   as CmdListBin
+import qualified Distribution.Client.CmdOutdated  as CmdOutdated
+import           Distribution.Client.CmdLegacy
+
+import Distribution.Client.Install            (install)
+import Distribution.Client.Configure          (configure, writeConfigFlags)
+import Distribution.Client.Fetch              (fetch)
+import Distribution.Client.Freeze             (freeze)
+import Distribution.Client.GenBounds          (genBounds)
+import Distribution.Client.Check as Check     (check)
+--import Distribution.Client.Clean            (clean)
+import qualified Distribution.Client.Upload as Upload
+import Distribution.Client.Run                (run, splitRunArgs)
+import Distribution.Client.Get                (get)
+import Distribution.Client.Reconfigure        (Check(..), reconfigure)
+import Distribution.Client.Nix                (nixInstantiate
+                                              ,nixShell
+                                              )
+import Distribution.Client.Sandbox            (loadConfigOrSandboxConfig
+                                              ,findSavedDistPref
+                                              ,updateInstallDirs)
+import Distribution.Client.Tar                (createTarGzFile)
+import Distribution.Client.Types.Credentials  (Password (..))
+import Distribution.Client.Init               (initCmd)
+import Distribution.Client.Manpage            (manpageCmd)
+import Distribution.Client.ManpageFlags       (ManpageFlags (..))
+import Distribution.Client.Utils
+         ( determineNumJobs, relaxEncodingErrors )
+import Distribution.Client.Signal
+         ( installTerminationHandler )
+import Distribution.Client.Version
+         ( cabalInstallVersion )
+
+import Distribution.Package (packageId)
+import Distribution.PackageDescription
+         ( BuildType(..), Executable(..), buildable )
+
+import Distribution.PackageDescription.PrettyPrint
+         ( writeGenericPackageDescription )
+import qualified Distribution.Simple as Simple
+import qualified Distribution.Make as Make
+import qualified Distribution.Types.UnqualComponentName as Make
+import Distribution.Simple.Build
+         ( startInterpreter )
+import Distribution.Simple.Command
+         ( CommandParse(..), CommandUI(..), Command, CommandSpec(..)
+         , CommandType(..), commandsRun, commandAddAction, hiddenCommand
+         , commandFromSpec, commandShowOptions )
+import Distribution.Simple.Compiler (PackageDBStack)
+import Distribution.Simple.Configure
+         ( configCompilerAuxEx, ConfigStateFileError(..)
+         , getPersistBuildConfig, interpretPackageDbFlags
+         , tryGetPersistBuildConfig )
+import qualified Distribution.Simple.LocalBuildInfo as LBI
+import Distribution.Simple.PackageDescription ( readGenericPackageDescription )
+import Distribution.Simple.Program (defaultProgramDb
+                                   ,configureAllKnownPrograms
+                                   ,simpleProgramInvocation
+                                   ,getProgramInvocationOutput)
+import Distribution.Simple.Program.Db (reconfigurePrograms)
+import qualified Distribution.Simple.Setup as Cabal
+import Distribution.Simple.Utils
+         ( cabalVersion, die', dieNoVerbosity, info, notice, topHandler
+         , findPackageDesc, tryFindPackageDesc, createDirectoryIfMissingVerbose )
+import Distribution.Text
+         ( display )
+import Distribution.Verbosity as Verbosity
+         ( normal )
+import Distribution.Version
+         ( Version, mkVersion, orLaterVersion )
+
+import Distribution.Compat.ResponseFile
+import System.Environment       (getProgName)
+import System.FilePath          ( dropExtension, splitExtension
+                                , takeExtension, (</>), (<.>) )
+import System.IO                ( BufferMode(LineBuffering), hSetBuffering
+                                , hPutStrLn, stderr, stdout )
+import System.Directory         ( doesFileExist, getCurrentDirectory
+                                , withCurrentDirectory)
+import Data.Monoid              (Any(..))
+import Control.Exception        (AssertionFailed, assert, try)
+
+
+-- | Entry point
+--
+main :: [String] -> IO ()
+main args = do
+  installTerminationHandler
+  -- Enable line buffering so that we can get fast feedback even when piped.
+  -- This is especially important for CI and build systems.
+  hSetBuffering stdout LineBuffering
+
+  -- If the locale encoding for CLI doesn't support all Unicode characters,
+  -- printing to it may fail unless we relax the handling of encoding errors
+  -- when writing to stderr and stdout.
+  relaxEncodingErrors stdout
+  relaxEncodingErrors stderr
+  let (args0, args1) = break (== "--") args
+
+  mainWorker =<< (++ args1) <$> expandResponse args0
+
+-- | Check whether assertions are enabled and print a warning in that case.
+warnIfAssertionsAreEnabled :: IO ()
+warnIfAssertionsAreEnabled =
+  assert False (return ()) `catch`
+  (\(_e :: AssertionFailed) -> hPutStrLn stderr assertionsEnabledMsg)
+    -- Andreas, 2022-12-30, issue #8654:
+    -- The verbosity machinery is not in place at this point (option -v not parsed),
+    -- so instead of using function @warn@, we print straight to stderr.
+  where
+    assertionsEnabledMsg =
+      "Warning: this is a debug build of cabal-install with assertions enabled."
+
+mainWorker :: [String] -> IO ()
+mainWorker args = do
+  topHandler $
+    case commandsRun (globalCommand commands) commands args of
+      CommandHelp   help                 -> printGlobalHelp help
+      CommandList   opts                 -> printOptionsList opts
+      CommandErrors errs                 -> printErrors errs
+      CommandReadyToGo (globalFlags, commandParse)  ->
+        case commandParse of
+          _ | fromFlagOrDefault False (globalVersion globalFlags)
+              -> printVersion
+            | fromFlagOrDefault False (globalNumericVersion globalFlags)
+              -> printNumericVersion
+          CommandHelp     help           -> printCommandHelp help
+          CommandList     opts           -> printOptionsList opts
+
+          CommandErrors   errs           -> do
+            -- Check whether cabal is called from a script, like #!/path/to/cabal.
+            case args of
+              []      -> printErrors errs
+              script : scriptArgs -> CmdRun.validScript script >>= \case
+                False -> printErrors errs
+                True  -> do
+                  -- In main operation (not help, version etc.) print warning if assertions are on.
+                  warnIfAssertionsAreEnabled
+                  CmdRun.handleShebang script scriptArgs
+
+          CommandReadyToGo action        -> do
+            -- In main operation (not help, version etc.) print warning if assertions are on.
+            warnIfAssertionsAreEnabled
+            action globalFlags
+
+  where
+    printCommandHelp help = do
+      pname <- getProgName
+      putStr (help pname)
+    printGlobalHelp help = do
+      pname <- getProgName
+      configFile <- defaultConfigFile
+      putStr (help pname)
+      putStr $ "\nYou can edit the cabal configuration file to set defaults:\n"
+            ++ "  " ++ configFile ++ "\n"
+      exists <- doesFileExist configFile
+      unless exists $
+          putStrLn $ "This file will be generated with sensible "
+                  ++ "defaults if you run 'cabal update'."
+    printOptionsList = putStr . unlines
+    printErrors errs = dieNoVerbosity $ intercalate "\n" errs
+    printNumericVersion = putStrLn $ display cabalInstallVersion
+    printVersion        = putStrLn $ "cabal-install version "
+                                  ++ display cabalInstallVersion
+                                  ++ "\ncompiled using version "
+                                  ++ display cabalVersion
+                                  ++ " of the Cabal library "
+
+    commands = map commandFromSpec commandSpecs
+    commandSpecs =
+      [ regularCmd listCommand listAction
+      , regularCmd infoCommand infoAction
+      , regularCmd fetchCommand fetchAction
+      , regularCmd getCommand getAction
+      , regularCmd unpackCommand unpackAction
+      , regularCmd checkCommand checkAction
+      , regularCmd uploadCommand uploadAction
+      , regularCmd reportCommand reportAction
+      , regularCmd initCommand initAction
+      , regularCmd userConfigCommand userConfigAction
+      , regularCmd genBoundsCommand genBoundsAction
+      , regularCmd CmdOutdated.outdatedCommand CmdOutdated.outdatedAction
+      , wrapperCmd hscolourCommand hscolourVerbosity hscolourDistPref
+      , hiddenCmd  formatCommand formatAction
+      , hiddenCmd  actAsSetupCommand actAsSetupAction
+      , hiddenCmd  manpageCommand (manpageAction commandSpecs)
+      , regularCmd CmdListBin.listbinCommand     CmdListBin.listbinAction
+
+      ] ++ concat
+      [ newCmd  CmdConfigure.configureCommand CmdConfigure.configureAction
+      , newCmd  CmdUpdate.updateCommand       CmdUpdate.updateAction
+      , newCmd  CmdBuild.buildCommand         CmdBuild.buildAction
+      , newCmd  CmdRepl.replCommand           CmdRepl.replAction
+      , newCmd  CmdFreeze.freezeCommand       CmdFreeze.freezeAction
+      , newCmd  CmdHaddock.haddockCommand     CmdHaddock.haddockAction
+      , newCmd  CmdHaddockProject.haddockProjectCommand
+                                              CmdHaddockProject.haddockProjectAction
+      , newCmd  CmdInstall.installCommand     CmdInstall.installAction
+      , newCmd  CmdRun.runCommand             CmdRun.runAction
+      , newCmd  CmdTest.testCommand           CmdTest.testAction
+      , newCmd  CmdBench.benchCommand         CmdBench.benchAction
+      , newCmd  CmdExec.execCommand           CmdExec.execAction
+      , newCmd  CmdClean.cleanCommand         CmdClean.cleanAction
+      , newCmd  CmdSdist.sdistCommand         CmdSdist.sdistAction
+
+      , legacyCmd configureExCommand configureAction
+      , legacyCmd buildCommand buildAction
+      , legacyCmd replCommand replAction
+      , legacyCmd freezeCommand freezeAction
+      , legacyCmd haddockCommand haddockAction
+      , legacyCmd installCommand installAction
+      , legacyCmd runCommand runAction
+      , legacyCmd testCommand testAction
+      , legacyCmd benchmarkCommand benchmarkAction
+      , legacyCmd cleanCommand cleanAction
+      , legacyWrapperCmd copyCommand copyVerbosity copyDistPref
+      , legacyWrapperCmd registerCommand regVerbosity regDistPref
+      , legacyCmd reconfigureCommand reconfigureAction
+      ]
+
+type Action = GlobalFlags -> IO ()
+
+-- Duplicated in Distribution.Client.CmdLegacy. Any changes must be
+-- reflected there, as well.
+regularCmd :: CommandUI flags -> (flags -> [String] -> action)
+           -> CommandSpec action
+regularCmd ui action =
+  CommandSpec ui ((flip commandAddAction) action) NormalCommand
+
+hiddenCmd :: CommandUI flags -> (flags -> [String] -> action)
+          -> CommandSpec action
+hiddenCmd ui action =
+  CommandSpec ui (\ui' -> hiddenCommand (commandAddAction ui' action))
+  HiddenCommand
+
+wrapperCmd :: Monoid flags => CommandUI flags -> (flags -> Flag Verbosity)
+           -> (flags -> Flag String) -> CommandSpec Action
+wrapperCmd ui verbosity distPref =
+  CommandSpec ui (\ui' -> wrapperAction ui' verbosity distPref) NormalCommand
+
+wrapperAction :: Monoid flags
+              => CommandUI flags
+              -> (flags -> Flag Verbosity)
+              -> (flags -> Flag String)
+              -> Command Action
+wrapperAction command verbosityFlag distPrefFlag =
+  commandAddAction command
+    { commandDefaultFlags = mempty } $ \flags extraArgs globalFlags -> do
+    let verbosity = fromFlagOrDefault normal (verbosityFlag flags)
+    load <- try (loadConfigOrSandboxConfig verbosity globalFlags)
+    let config = either (\(SomeException _) -> mempty) id load
+    distPref <- findSavedDistPref config (distPrefFlag flags)
+    let setupScriptOptions = defaultSetupScriptOptions { useDistPref = distPref }
+    setupWrapper verbosity setupScriptOptions Nothing
+                 command (const flags) (const extraArgs)
+
+configureAction :: (ConfigFlags, ConfigExFlags)
+                -> [String] -> Action
+configureAction (configFlags, configExFlags) extraArgs globalFlags = do
+  let verbosity = fromFlagOrDefault normal (configVerbosity configFlags)
+  config <- updateInstallDirs (configUserInstall configFlags)
+                          <$> loadConfigOrSandboxConfig verbosity globalFlags
+  distPref <- findSavedDistPref config (configDistPref configFlags)
+  nixInstantiate verbosity distPref True globalFlags config
+  nixShell verbosity distPref globalFlags config $ do
+    let configFlags'   = savedConfigureFlags   config `mappend` configFlags
+        configExFlags' = savedConfigureExFlags config `mappend` configExFlags
+        globalFlags'   = savedGlobalFlags      config `mappend` globalFlags
+    (comp, platform, progdb) <- configCompilerAuxEx configFlags'
+
+    writeConfigFlags verbosity distPref (configFlags', configExFlags')
+
+    -- What package database(s) to use
+    let packageDBs :: PackageDBStack
+        packageDBs
+          = interpretPackageDbFlags
+            (fromFlag (configUserInstall configFlags'))
+            (configPackageDBs configFlags')
+
+    withRepoContext verbosity globalFlags' $ \repoContext ->
+        configure verbosity packageDBs repoContext
+                  comp platform progdb configFlags' configExFlags' extraArgs
+
+reconfigureAction :: (ConfigFlags, ConfigExFlags)
+                  -> [String] -> Action
+reconfigureAction flags@(configFlags, _) _ globalFlags = do
+  let verbosity = fromFlagOrDefault normal (configVerbosity configFlags)
+  config <- updateInstallDirs (configUserInstall configFlags)
+                          <$> loadConfigOrSandboxConfig verbosity globalFlags
+  distPref <- findSavedDistPref config (configDistPref configFlags)
+  let checkFlags = Check $ \_ saved -> do
+        let flags' = saved <> flags
+        unless (saved == flags') $ info verbosity message
+        pure (Any True, flags')
+        where
+          -- This message is correct, but not very specific: it will list all
+          -- of the new flags, even if some have not actually changed. The
+          -- *minimal* set of changes is more difficult to determine.
+          message =
+            "flags changed: "
+            ++ unwords (commandShowOptions configureExCommand flags)
+  nixInstantiate verbosity distPref True globalFlags config
+  _ <-
+    reconfigure configureAction
+    verbosity distPref NoFlag
+    checkFlags [] globalFlags config
+  pure ()
+
+buildAction :: BuildFlags -> [String] -> Action
+buildAction buildFlags extraArgs globalFlags = do
+  let verbosity = fromFlagOrDefault normal (buildVerbosity buildFlags)
+  config <- loadConfigOrSandboxConfig verbosity globalFlags
+  distPref <- findSavedDistPref config (buildDistPref buildFlags)
+  -- Calls 'configureAction' to do the real work, so nothing special has to be
+  -- done to support sandboxes.
+  config' <-
+    reconfigure configureAction
+    verbosity distPref (buildNumJobs buildFlags)
+    mempty [] globalFlags config
+  nixShell verbosity distPref globalFlags config $ do
+    build verbosity config' distPref buildFlags extraArgs
+
+
+-- | Actually do the work of building the package. This is separate from
+-- 'buildAction' so that 'testAction' and 'benchmarkAction' do not invoke
+-- 'reconfigure' twice.
+build :: Verbosity -> SavedConfig -> FilePath -> BuildFlags -> [String] -> IO ()
+build verbosity config distPref buildFlags extraArgs =
+  setupWrapper verbosity setupOptions Nothing
+               (Cabal.buildCommand progDb) mkBuildFlags (const extraArgs)
+  where
+    progDb       = defaultProgramDb
+    setupOptions = defaultSetupScriptOptions { useDistPref = distPref }
+
+    mkBuildFlags version = filterBuildFlags version config buildFlags'
+    buildFlags' = buildFlags
+      { buildVerbosity = toFlag verbosity
+      , buildDistPref  = toFlag distPref
+      }
+
+-- | Make sure that we don't pass new flags to setup scripts compiled against
+-- old versions of Cabal.
+filterBuildFlags :: Version -> SavedConfig -> BuildFlags -> BuildFlags
+filterBuildFlags version config buildFlags
+  | version >= mkVersion [1,19,1] = buildFlags_latest
+  -- Cabal < 1.19.1 doesn't support 'build -j'.
+  | otherwise                      = buildFlags_pre_1_19_1
+  where
+    buildFlags_pre_1_19_1 = buildFlags {
+      buildNumJobs = NoFlag
+      }
+    buildFlags_latest     = buildFlags {
+      -- Take the 'jobs' setting config file into account.
+      buildNumJobs = Flag . Just . determineNumJobs $
+                     (numJobsConfigFlag `mappend` numJobsCmdLineFlag)
+      }
+    numJobsConfigFlag  = installNumJobs . savedInstallFlags $ config
+    numJobsCmdLineFlag = buildNumJobs buildFlags
+
+
+replAction :: ReplFlags -> [String] -> Action
+replAction replFlags extraArgs globalFlags = do
+  let verbosity = fromFlagOrDefault normal (replVerbosity replFlags)
+  config <- loadConfigOrSandboxConfig verbosity globalFlags
+  distPref <- findSavedDistPref config (replDistPref replFlags)
+  cwd     <- getCurrentDirectory
+  pkgDesc <- findPackageDesc cwd
+  let
+    -- There is a .cabal file in the current directory: start a REPL and load
+    -- the project's modules.
+    onPkgDesc = do
+      -- Calls 'configureAction' to do the real work, so nothing special has to
+      -- be done to support sandboxes.
+      _ <-
+        reconfigure configureAction
+        verbosity distPref NoFlag
+        mempty [] globalFlags config
+      let progDb = defaultProgramDb
+          setupOptions = defaultSetupScriptOptions
+            { useCabalVersion = orLaterVersion $ mkVersion [1,18,0]
+            , useDistPref     = distPref
+            }
+          replFlags'   = replFlags
+            { replVerbosity = toFlag verbosity
+            , replDistPref  = toFlag distPref
+            }
+
+      nixShell verbosity distPref globalFlags config $
+        setupWrapper verbosity setupOptions Nothing (Cabal.replCommand progDb) (const replFlags') (const extraArgs)
+
+    -- No .cabal file in the current directory: just start the REPL (possibly
+    -- using the sandbox package DB).
+    onNoPkgDesc = do
+      let configFlags = savedConfigureFlags config
+      (comp, platform, programDb) <- configCompilerAux' configFlags
+      programDb' <- reconfigurePrograms verbosity
+                                        (replProgramPaths replFlags)
+                                        (replProgramArgs replFlags)
+                                        programDb
+      nixShell verbosity distPref globalFlags config $ do
+        startInterpreter verbosity programDb' comp platform
+                        (configPackageDB' configFlags)
+
+  either (const onNoPkgDesc) (const onPkgDesc) pkgDesc
+
+installAction :: ( ConfigFlags, ConfigExFlags, InstallFlags
+                 , HaddockFlags, TestFlags, BenchmarkFlags )
+              -> [String] -> Action
+installAction (configFlags, _, installFlags, _, _, _) _ globalFlags
+  | fromFlagOrDefault False (installOnly installFlags) = do
+      let verb = fromFlagOrDefault normal (configVerbosity configFlags)
+      config <- loadConfigOrSandboxConfig verb globalFlags
+      dist <- findSavedDistPref config (configDistPref configFlags)
+      let setupOpts = defaultSetupScriptOptions { useDistPref = dist }
+      setupWrapper
+        verb setupOpts Nothing
+        installCommand (const (mempty, mempty, mempty, mempty, mempty, mempty))
+                       (const [])
+
+installAction
+  ( configFlags, configExFlags, installFlags
+  , haddockFlags, testFlags, benchmarkFlags )
+  extraArgs globalFlags = do
+  let verb = fromFlagOrDefault normal (configVerbosity configFlags)
+  config <- updateInstallDirs (configUserInstall configFlags)
+                          <$> loadConfigOrSandboxConfig verb globalFlags
+
+  dist <- findSavedDistPref config (configDistPref configFlags)
+
+  do
+    targets <- readUserTargets verb extraArgs
+
+    let configFlags'    = maybeForceTests installFlags' $
+                          savedConfigureFlags   config `mappend`
+                          configFlags { configDistPref = toFlag dist }
+        configExFlags'  = defaultConfigExFlags         `mappend`
+                          savedConfigureExFlags config `mappend` configExFlags
+        installFlags'   = defaultInstallFlags          `mappend`
+                          savedInstallFlags     config `mappend` installFlags
+        haddockFlags'   = defaultHaddockFlags          `mappend`
+                          savedHaddockFlags     config `mappend`
+                          haddockFlags { haddockDistPref = toFlag dist }
+        testFlags'      = Cabal.defaultTestFlags       `mappend`
+                          savedTestFlags        config `mappend`
+                          testFlags { testDistPref = toFlag dist }
+        benchmarkFlags' = Cabal.defaultBenchmarkFlags  `mappend`
+                          savedBenchmarkFlags   config `mappend`
+                          benchmarkFlags { benchmarkDistPref = toFlag dist }
+        globalFlags'    = savedGlobalFlags      config `mappend` globalFlags
+    (comp, platform, progdb) <- configCompilerAux' configFlags'
+
+    -- TODO: Redesign ProgramDB API to prevent such problems as #2241 in the
+    -- future.
+    progdb' <- configureAllKnownPrograms verb progdb
+
+    configFlags'' <- configAbsolutePaths configFlags'
+
+    withRepoContext verb globalFlags' $ \repoContext ->
+        install verb
+                (configPackageDB' configFlags'')
+                repoContext
+                comp platform progdb'
+                globalFlags' configFlags'' configExFlags'
+                installFlags' haddockFlags' testFlags' benchmarkFlags'
+                targets
+
+      where
+        -- '--run-tests' implies '--enable-tests'.
+        maybeForceTests installFlags' configFlags' =
+          if fromFlagOrDefault False (installRunTests installFlags')
+          then configFlags' { configTests = toFlag True }
+          else configFlags'
+
+testAction :: (BuildFlags, TestFlags) -> [String] -> GlobalFlags
+           -> IO ()
+testAction (buildFlags, testFlags) extraArgs globalFlags = do
+  let verbosity      = fromFlagOrDefault normal (buildVerbosity buildFlags)
+  config <- loadConfigOrSandboxConfig verbosity globalFlags
+  distPref <- findSavedDistPref config (testDistPref testFlags)
+  let buildFlags'    = buildFlags
+                      { buildVerbosity = testVerbosity testFlags }
+      checkFlags = Check $ \_ flags@(configFlags, configExFlags) ->
+        if fromFlagOrDefault False (configTests configFlags)
+          then pure (mempty, flags)
+          else do
+            info verbosity "reconfiguring to enable tests"
+            let flags' = ( configFlags { configTests = toFlag True }
+                        , configExFlags
+                        )
+            pure (Any True, flags')
+
+  _ <-
+    reconfigure configureAction
+    verbosity distPref (buildNumJobs buildFlags')
+    checkFlags [] globalFlags config
+  nixShell verbosity distPref globalFlags config $ do
+    let setupOptions   = defaultSetupScriptOptions { useDistPref = distPref }
+        testFlags'     = testFlags { testDistPref = toFlag distPref }
+
+    -- The package was just configured, so the LBI must be available.
+    names <- componentNamesFromLBI verbosity distPref "test suites"
+              (\c -> case c of { LBI.CTest{} -> True; _ -> False })
+    let extraArgs'
+          | null extraArgs = case names of
+            ComponentNamesUnknown -> []
+            ComponentNames names' -> [ Make.unUnqualComponentName name
+                                    | LBI.CTestName name <- names' ]
+          | otherwise      = extraArgs
+
+    build verbosity config distPref buildFlags' extraArgs'
+    setupWrapper verbosity setupOptions Nothing Cabal.testCommand (const testFlags') (const extraArgs')
+
+data ComponentNames = ComponentNamesUnknown
+                    | ComponentNames [LBI.ComponentName]
+
+-- | Return the names of all buildable components matching a given predicate.
+componentNamesFromLBI :: Verbosity -> FilePath -> String
+                         -> (LBI.Component -> Bool)
+                         -> IO ComponentNames
+componentNamesFromLBI verbosity distPref targetsDescr compPred = do
+  eLBI <- tryGetPersistBuildConfig distPref
+  case eLBI of
+    Left err -> case err of
+      -- Note: the build config could have been generated by a custom setup
+      -- script built against a different Cabal version, so it's crucial that
+      -- we ignore the bad version error here.
+      ConfigStateFileBadVersion _ _ _ -> return ComponentNamesUnknown
+      _                               -> die' verbosity (show err)
+    Right lbi -> do
+      let pkgDescr = LBI.localPkgDescr lbi
+          names    = map LBI.componentName
+                     . filter (buildable . LBI.componentBuildInfo)
+                     . filter compPred $
+                     LBI.pkgComponents pkgDescr
+      if null names
+        then do notice verbosity $ "Package has no buildable "
+                  ++ targetsDescr ++ "."
+                exitSuccess -- See #3215.
+
+        else return $! (ComponentNames names)
+
+benchmarkAction :: (BuildFlags, BenchmarkFlags)
+                   -> [String] -> GlobalFlags
+                   -> IO ()
+benchmarkAction
+  (buildFlags, benchmarkFlags)
+  extraArgs globalFlags = do
+  let verbosity      = fromFlagOrDefault normal
+                       (buildVerbosity buildFlags)
+
+  config <- loadConfigOrSandboxConfig verbosity globalFlags
+  distPref <- findSavedDistPref config (benchmarkDistPref benchmarkFlags)
+  let buildFlags'    = buildFlags
+                      { buildVerbosity = benchmarkVerbosity benchmarkFlags }
+
+  let checkFlags = Check $ \_ flags@(configFlags, configExFlags) ->
+        if fromFlagOrDefault False (configBenchmarks configFlags)
+          then pure (mempty, flags)
+          else do
+            info verbosity "reconfiguring to enable benchmarks"
+            let flags' = ( configFlags { configBenchmarks = toFlag True }
+                        , configExFlags
+                        )
+            pure (Any True, flags')
+
+  config' <-
+    reconfigure configureAction
+    verbosity distPref (buildNumJobs buildFlags')
+    checkFlags [] globalFlags config
+  nixShell verbosity distPref globalFlags config $ do
+    let setupOptions   = defaultSetupScriptOptions { useDistPref = distPref }
+        benchmarkFlags'= benchmarkFlags { benchmarkDistPref = toFlag distPref }
+
+    -- The package was just configured, so the LBI must be available.
+    names <- componentNamesFromLBI verbosity distPref "benchmarks"
+            (\c -> case c of { LBI.CBench{} -> True; _ -> False; })
+    let extraArgs'
+          | null extraArgs = case names of
+            ComponentNamesUnknown -> []
+            ComponentNames names' -> [ Make.unUnqualComponentName name
+                                    | LBI.CBenchName name <- names']
+          | otherwise      = extraArgs
+
+    build verbosity config' distPref buildFlags' extraArgs'
+    setupWrapper verbosity setupOptions Nothing Cabal.benchmarkCommand (const benchmarkFlags') (const extraArgs')
+
+haddockAction :: HaddockFlags -> [String] -> Action
+haddockAction haddockFlags extraArgs globalFlags = do
+  let verbosity = fromFlag (haddockVerbosity haddockFlags)
+  config <- loadConfigOrSandboxConfig verbosity globalFlags
+  distPref <- findSavedDistPref config (haddockDistPref haddockFlags)
+  config' <-
+    reconfigure configureAction
+    verbosity distPref NoFlag
+    mempty [] globalFlags config
+  nixShell verbosity distPref globalFlags config $ do
+    let haddockFlags' = defaultHaddockFlags      `mappend`
+                        savedHaddockFlags config' `mappend`
+                        haddockFlags { haddockDistPref = toFlag distPref }
+        setupScriptOptions = defaultSetupScriptOptions
+                             { useDistPref = distPref }
+    setupWrapper verbosity setupScriptOptions Nothing
+      haddockCommand (const haddockFlags') (const extraArgs)
+    when (haddockForHackage haddockFlags == Flag ForHackage) $ do
+      pkg <- fmap LBI.localPkgDescr (getPersistBuildConfig distPref)
+      let dest = distPref </> name <.> "tar.gz"
+          name = display (packageId pkg) ++ "-docs"
+          docDir = distPref </> "doc" </> "html"
+      createTarGzFile dest docDir name
+      notice verbosity $ "Documentation tarball created: " ++ dest
+
+cleanAction :: CleanFlags -> [String] -> Action
+cleanAction cleanFlags extraArgs globalFlags = do
+  load <- try (loadConfigOrSandboxConfig verbosity globalFlags)
+  let config = either (\(SomeException _) -> mempty) id load
+  distPref <- findSavedDistPref config (cleanDistPref cleanFlags)
+  let setupScriptOptions = defaultSetupScriptOptions
+                           { useDistPref = distPref
+                           , useWin32CleanHack = True
+                           }
+      cleanFlags' = cleanFlags { cleanDistPref = toFlag distPref }
+  setupWrapper verbosity setupScriptOptions Nothing
+               cleanCommand (const cleanFlags') (const extraArgs)
+  where
+    verbosity = fromFlagOrDefault normal (cleanVerbosity cleanFlags)
+
+listAction :: ListFlags -> [String] -> Action
+listAction listFlags extraArgs globalFlags = do
+  let verbosity = fromFlag (listVerbosity listFlags)
+  config <- loadConfigOrSandboxConfig verbosity globalFlags
+  let configFlags' = savedConfigureFlags config
+      configFlags  = configFlags'
+        { configPackageDBs = configPackageDBs configFlags'
+                           `mappend` listPackageDBs listFlags
+        , configHcPath     = listHcPath listFlags
+        }
+      globalFlags' = savedGlobalFlags    config `mappend` globalFlags
+  compProgdb <- if listNeedsCompiler listFlags
+      then do
+          (comp, _, progdb) <- configCompilerAux' configFlags
+          return (Just (comp, progdb))
+      else return Nothing
+  withRepoContext verbosity globalFlags' $ \repoContext ->
+    List.list verbosity
+       (configPackageDB' configFlags)
+       repoContext
+       compProgdb
+       listFlags
+       extraArgs
+
+infoAction :: InfoFlags -> [String] -> Action
+infoAction infoFlags extraArgs globalFlags = do
+  let verbosity = fromFlag (infoVerbosity infoFlags)
+  targets <- readUserTargets verbosity extraArgs
+  config <- loadConfigOrSandboxConfig verbosity globalFlags
+  let configFlags' = savedConfigureFlags config
+      configFlags  = configFlags' {
+        configPackageDBs = configPackageDBs configFlags'
+                           `mappend` infoPackageDBs infoFlags
+        }
+      globalFlags' = savedGlobalFlags    config `mappend` globalFlags
+  (comp, _, progdb) <- configCompilerAuxEx configFlags
+  withRepoContext verbosity globalFlags' $ \repoContext ->
+    List.info verbosity
+       (configPackageDB' configFlags)
+       repoContext
+       comp
+       progdb
+       globalFlags'
+       infoFlags
+       targets
+
+fetchAction :: FetchFlags -> [String] -> Action
+fetchAction fetchFlags extraArgs globalFlags = do
+  let verbosity = fromFlag (fetchVerbosity fetchFlags)
+  targets <- readUserTargets verbosity extraArgs
+  config <- loadConfig verbosity (globalConfigFile globalFlags)
+  let configFlags  = savedConfigureFlags config
+      globalFlags' = savedGlobalFlags config `mappend` globalFlags
+  (comp, platform, progdb) <- configCompilerAux' configFlags
+  withRepoContext verbosity globalFlags' $ \repoContext ->
+    fetch verbosity
+        (configPackageDB' configFlags)
+        repoContext
+        comp platform progdb globalFlags' fetchFlags
+        targets
+
+freezeAction :: FreezeFlags -> [String] -> Action
+freezeAction freezeFlags _extraArgs globalFlags = do
+  let verbosity = fromFlag (freezeVerbosity freezeFlags)
+  config <- loadConfigOrSandboxConfig verbosity globalFlags
+  distPref <- findSavedDistPref config NoFlag
+  nixShell verbosity distPref globalFlags config $ do
+    let configFlags  = savedConfigureFlags config
+        globalFlags' = savedGlobalFlags config `mappend` globalFlags
+    (comp, platform, progdb) <- configCompilerAux' configFlags
+
+    withRepoContext verbosity globalFlags' $ \repoContext ->
+        freeze verbosity
+            (configPackageDB' configFlags)
+            repoContext
+            comp platform progdb
+            globalFlags' freezeFlags
+
+genBoundsAction :: FreezeFlags -> [String] -> GlobalFlags -> IO ()
+genBoundsAction freezeFlags _extraArgs globalFlags = do
+  let verbosity = fromFlag (freezeVerbosity freezeFlags)
+  config <- loadConfigOrSandboxConfig verbosity globalFlags
+  distPref <- findSavedDistPref config NoFlag
+  nixShell verbosity distPref globalFlags config $ do
+    let configFlags  = savedConfigureFlags config
+        globalFlags' = savedGlobalFlags config `mappend` globalFlags
+    (comp, platform, progdb) <- configCompilerAux' configFlags
+
+    withRepoContext verbosity globalFlags' $ \repoContext ->
+        genBounds verbosity
+                (configPackageDB' configFlags)
+                repoContext
+                comp platform progdb
+                globalFlags' freezeFlags
+
+uploadAction :: UploadFlags -> [String] -> Action
+uploadAction uploadFlags extraArgs globalFlags = do
+  config <- loadConfig verbosity (globalConfigFile globalFlags)
+  let uploadFlags' = savedUploadFlags config `mappend` uploadFlags
+      globalFlags' = savedGlobalFlags config `mappend` globalFlags
+      tarfiles     = extraArgs
+  when (null tarfiles && not (fromFlag (uploadDoc uploadFlags'))) $
+    die' verbosity "the 'upload' command expects at least one .tar.gz archive."
+  checkTarFiles extraArgs
+  maybe_password <-
+    case uploadPasswordCmd uploadFlags'
+    of Flag (xs:xss) -> Just . Password <$>
+                        getProgramInvocationOutput verbosity
+                        (simpleProgramInvocation xs xss)
+       _             -> pure $ flagToMaybe $ uploadPassword uploadFlags'
+  withRepoContext verbosity globalFlags' $ \repoContext -> do
+    if fromFlag (uploadDoc uploadFlags')
+    then do
+      when (length tarfiles > 1) $
+       die' verbosity $ "the 'upload' command can only upload documentation "
+             ++ "for one package at a time."
+      tarfile <- maybe (generateDocTarball config) return $ listToMaybe tarfiles
+      Upload.uploadDoc verbosity
+                       repoContext
+                       (flagToMaybe $ uploadUsername uploadFlags')
+                       maybe_password
+                       (fromFlag (uploadCandidate uploadFlags'))
+                       tarfile
+    else do
+      Upload.upload verbosity
+                    repoContext
+                    (flagToMaybe $ uploadUsername uploadFlags')
+                    maybe_password
+                    (fromFlag (uploadCandidate uploadFlags'))
+                    tarfiles
+    where
+    verbosity = fromFlag (uploadVerbosity uploadFlags)
+    checkTarFiles tarfiles
+      | not (null otherFiles)
+      = die' verbosity $ "the 'upload' command expects only .tar.gz archives: "
+           ++ intercalate ", " otherFiles
+      | otherwise = sequence_
+                      [ do exists <- doesFileExist tarfile
+                           unless exists $ die' verbosity $ "file not found: " ++ tarfile
+                      | tarfile <- tarfiles ]
+
+      where otherFiles = filter (not . isTarGzFile) tarfiles
+            isTarGzFile file = case splitExtension file of
+              (file', ".gz") -> takeExtension file' == ".tar"
+              _              -> False
+    generateDocTarball config = do
+      notice verbosity $
+        "No documentation tarball specified. "
+        ++ "Building a documentation tarball with default settings...\n"
+        ++ "If you need to customise Haddock options, "
+        ++ "run 'haddock --for-hackage' first "
+        ++ "to generate a documentation tarball."
+      haddockAction (defaultHaddockFlags { haddockForHackage = Flag ForHackage })
+                    [] globalFlags
+      distPref <- findSavedDistPref config NoFlag
+      pkg <- fmap LBI.localPkgDescr (getPersistBuildConfig distPref)
+      return $ distPref </> display (packageId pkg) ++ "-docs" <.> "tar.gz"
+
+checkAction :: Flag Verbosity -> [String] -> Action
+checkAction verbosityFlag extraArgs _globalFlags = do
+  let verbosity = fromFlag verbosityFlag
+  unless (null extraArgs) $
+    die' verbosity $ "'check' doesn't take any extra arguments: " ++ unwords extraArgs
+  allOk <- Check.check (fromFlag verbosityFlag)
+  unless allOk exitFailure
+
+formatAction :: Flag Verbosity -> [String] -> Action
+formatAction verbosityFlag extraArgs _globalFlags = do
+  let verbosity = fromFlag verbosityFlag
+  path <- case extraArgs of
+    [] -> do cwd <- getCurrentDirectory
+             tryFindPackageDesc verbosity cwd
+    (p:_) -> return p
+  pkgDesc <- readGenericPackageDescription verbosity path
+  -- Uses 'writeFileAtomic' under the hood.
+  writeGenericPackageDescription path pkgDesc
+
+reportAction :: ReportFlags -> [String] -> Action
+reportAction reportFlags extraArgs globalFlags = do
+  let verbosity = fromFlag (reportVerbosity reportFlags)
+  unless (null extraArgs) $
+    die' verbosity $ "'report' doesn't take any extra arguments: " ++ unwords extraArgs
+  config <- loadConfig verbosity (globalConfigFile globalFlags)
+  let globalFlags' = savedGlobalFlags config `mappend` globalFlags
+      reportFlags' = savedReportFlags config `mappend` reportFlags
+
+  withRepoContext verbosity globalFlags' $ \repoContext ->
+   Upload.report verbosity repoContext
+    (flagToMaybe $ reportUsername reportFlags')
+    (flagToMaybe $ reportPassword reportFlags')
+
+runAction :: BuildFlags -> [String] -> Action
+runAction buildFlags extraArgs globalFlags = do
+  let verbosity   = fromFlagOrDefault normal (buildVerbosity buildFlags)
+  config <- loadConfigOrSandboxConfig verbosity globalFlags
+  distPref <- findSavedDistPref config (buildDistPref buildFlags)
+  config' <-
+    reconfigure configureAction
+    verbosity distPref (buildNumJobs buildFlags)
+    mempty [] globalFlags config
+  nixShell verbosity distPref globalFlags config $ do
+    lbi <- getPersistBuildConfig distPref
+    (exe, exeArgs) <- splitRunArgs verbosity lbi extraArgs
+
+    build verbosity config' distPref buildFlags ["exe:" ++ display (exeName exe)]
+    run verbosity lbi exe exeArgs
+
+getAction :: GetFlags -> [String] -> Action
+getAction getFlags extraArgs globalFlags = do
+  let verbosity = fromFlag (getVerbosity getFlags)
+  targets <- readUserTargets verbosity extraArgs
+  config <- loadConfigOrSandboxConfig verbosity globalFlags
+  let globalFlags' = savedGlobalFlags config `mappend` globalFlags
+  withRepoContext verbosity (savedGlobalFlags config) $ \repoContext ->
+   get verbosity
+    repoContext
+    globalFlags'
+    getFlags
+    targets
+
+unpackAction :: GetFlags -> [String] -> Action
+unpackAction getFlags extraArgs globalFlags = do
+  getAction getFlags extraArgs globalFlags
+
+initAction :: InitFlags -> [String] -> Action
+initAction initFlags extraArgs globalFlags = do
+  -- it takes the first value within extraArgs (if there's one)
+  -- and uses it as the root directory for the new project
+  case extraArgs of
+    [] -> initAction'
+    [projectDir] -> do
+      createDirectoryIfMissingVerbose verbosity True projectDir
+      withCurrentDirectory projectDir initAction'
+    _ -> die' verbosity $
+      "'init' only takes a single, optional, extra " ++
+      "argument for the project root directory"
+  where
+    initAction' = do
+      confFlags <- loadConfigOrSandboxConfig verbosity globalFlags
+      -- override with `--with-compiler` from CLI if available
+      let confFlags' = savedConfigureFlags confFlags `mappend` compFlags
+          initFlags' = savedInitFlags confFlags `mappend` initFlags
+          globalFlags' = savedGlobalFlags confFlags `mappend` globalFlags
+
+      (comp, _, progdb) <- configCompilerAux' confFlags'
+
+      withRepoContext verbosity globalFlags' $ \repoContext ->
+        initCmd verbosity (configPackageDB' confFlags')
+          repoContext comp progdb initFlags'
+
+    verbosity = fromFlag (initVerbosity initFlags)
+    compFlags = mempty { configHcPath = initHcPath initFlags }
+
+userConfigAction :: UserConfigFlags -> [String] -> Action
+userConfigAction ucflags extraArgs globalFlags = do
+  let verbosity  = fromFlag (userConfigVerbosity ucflags)
+      frc        = fromFlag (userConfigForce ucflags)
+      extraLines = fromFlag (userConfigAppendLines ucflags)
+  case extraArgs of
+    ("init":_) -> do
+      path       <- configFile
+      fileExists <- doesFileExist path
+      if (not fileExists || (fileExists && frc))
+      then void $ createDefaultConfigFile verbosity extraLines path
+      else die' verbosity $ path ++ " already exists."
+    ("diff":_) -> traverse_ putStrLn =<< userConfigDiff verbosity globalFlags extraLines
+    ("update":_) -> userConfigUpdate verbosity globalFlags extraLines
+    -- Error handling.
+    [] -> die' verbosity $ "Please specify a subcommand (see 'help user-config')"
+    _  -> die' verbosity $ "Unknown 'user-config' subcommand: " ++ unwords extraArgs
+  where configFile = getConfigFilePath (globalConfigFile globalFlags)
+
+-- | Used as an entry point when cabal-install needs to invoke itself
+-- as a setup script. This can happen e.g. when doing parallel builds.
+--
+actAsSetupAction :: ActAsSetupFlags -> [String] -> Action
+actAsSetupAction actAsSetupFlags args _globalFlags =
+  let bt = fromFlag (actAsSetupBuildType actAsSetupFlags)
+  in case bt of
+    Simple    -> Simple.defaultMainArgs args
+    Configure -> Simple.defaultMainWithHooksArgs
+                  Simple.autoconfUserHooks args
+    Make      -> Make.defaultMainArgs args
+    Custom    -> error "actAsSetupAction Custom"
+
+manpageAction :: [CommandSpec action] -> ManpageFlags -> [String] -> Action
+manpageAction commands flags extraArgs _ = do
+  let verbosity = fromFlag (manpageVerbosity flags)
+  unless (null extraArgs) $
+    die' verbosity $ "'man' doesn't take any extra arguments: " ++ unwords extraArgs
+  pname <- getProgName
+  let cabalCmd = if takeExtension pname == ".exe"
+                 then dropExtension pname
+                 else pname
+  manpageCmd cabalCmd commands flags
diff --git a/cabal/cabal-install/src/Distribution/Client/Manpage.hs b/cabal/cabal-install/src/Distribution/Client/Manpage.hs
--- a/cabal/cabal-install/src/Distribution/Client/Manpage.hs
+++ b/cabal/cabal-install/src/Distribution/Client/Manpage.hs
@@ -27,15 +27,14 @@
 import Distribution.Client.Init.Utils   (trim)
 import Distribution.Client.ManpageFlags
 import Distribution.Client.Setup        (globalCommand)
+import Distribution.Compat.Process      (proc)
 import Distribution.Simple.Command
-import Distribution.Simple.Flag         (fromFlagOrDefault)
+import Distribution.Simple.Flag         (fromFlag, fromFlagOrDefault)
 import Distribution.Simple.Utils
-  ( IOData(..), IODataMode(..), createProcessWithEnv, ignoreSigPipe, rawSystemStdInOut )
-import qualified Distribution.Verbosity as Verbosity
+  ( IOData(..), IODataMode(..), ignoreSigPipe, rawSystemStdInOut, rawSystemProcAction,
+    fromCreatePipe, die' )
 import System.IO                        (hClose, hPutStr)
 import System.Environment               (lookupEnv)
-import System.FilePath                  (takeFileName)
-
 import qualified System.Process as Process
 
 data FileInfo = FileInfo String String -- ^ path, description
@@ -47,7 +46,7 @@
 -- | A list of files that should be documented in the manual page.
 files :: [FileInfo]
 files =
-  [ (FileInfo "~/.cabal/config" "The defaults that can be overridden with command-line options.")
+  [ (FileInfo "~/.config/cabal/config" "The defaults that can be overridden with command-line options.")
   ]
 
 manpageCmd :: String -> [CommandSpec a] -> ManpageFlags -> IO ()
@@ -69,7 +68,7 @@
 
         -- Feed contents into @nroff -man /dev/stdin@
         (formatted, _errors, ec1) <- rawSystemStdInOut
-          Verbosity.normal
+          verbosity
           "nroff"
           [ "-man", "/dev/stdin" ]
           Nothing  -- Inherit working directory
@@ -79,26 +78,23 @@
 
         unless (ec1 == ExitSuccess) $ exitWith ec1
 
-        pager <- fromMaybe "less" <$> lookupEnv "PAGER"
-        -- 'less' is borked with color sequences otherwise
-        let pagerArgs = if takeFileName pager == "less" then ["-R"] else []
+        pagerAndArgs <- fromMaybe "less -R" <$> lookupEnv "PAGER"
+        -- 'less' is borked with color sequences otherwise, hence -R
+        (pager, pagerArgs) <- case words pagerAndArgs of
+          []     -> die' verbosity "man: empty value of the PAGER environment variable"
+          (p:pa) -> pure (p, pa)
         -- Pipe output of @nroff@ into @less@
-        (Just inLess, _, _, procLess) <- createProcessWithEnv
-          Verbosity.normal
-          pager
-          pagerArgs
-          Nothing  -- Inherit working directory
-          Nothing  -- Inherit environment
-          Process.CreatePipe  -- in
-          Process.Inherit     -- out
-          Process.Inherit     -- err
-
-        hPutStr inLess formatted
-        hClose  inLess
-        exitWith =<< Process.waitForProcess procLess
+        (ec2, _) <- rawSystemProcAction verbosity
+            (proc pager pagerArgs) { Process.std_in = Process.CreatePipe }
+              $ \mIn _ _ -> do
+          let wIn = fromCreatePipe mIn
+          hPutStr wIn formatted
+          hClose  wIn
+        exitWith ec2
   where
     contents :: String
     contents = manpage pname commands
+    verbosity = fromFlag $ manpageVerbosity flags
 
 -- | Produces a manual page with @troff@ markup.
 manpage :: String -> [CommandSpec a] -> String
diff --git a/cabal/cabal-install/src/Distribution/Client/PackageHash.hs b/cabal/cabal-install/src/Distribution/Client/PackageHash.hs
--- a/cabal/cabal-install/src/Distribution/Client/PackageHash.hs
+++ b/cabal/cabal-install/src/Distribution/Client/PackageHash.hs
@@ -196,6 +196,7 @@
        pkgHashDebugInfo           :: DebugInfoLevel,
        pkgHashProgramArgs         :: Map String [String],
        pkgHashExtraLibDirs        :: [FilePath],
+       pkgHashExtraLibDirsStatic  :: [FilePath],
        pkgHashExtraFrameworkDirs  :: [FilePath],
        pkgHashExtraIncludeDirs    :: [FilePath],
        pkgHashProgPrefix          :: Maybe PathTemplate,
@@ -215,7 +216,10 @@
        pkgHashHaddockCss          :: Maybe FilePath,
        pkgHashHaddockLinkedSource :: Bool,
        pkgHashHaddockQuickJump    :: Bool,
-       pkgHashHaddockContents     :: Maybe PathTemplate
+       pkgHashHaddockContents     :: Maybe PathTemplate,
+       pkgHashHaddockIndex        :: Maybe PathTemplate,
+       pkgHashHaddockBaseUrl      :: Maybe String,
+       pkgHashHaddockLib          :: Maybe String
 
 --     TODO: [required eventually] pkgHashToolsVersions     ?
 --     TODO: [required eventually] pkgHashToolsExtraOptions ?
@@ -290,6 +294,7 @@
       , opt   "stripped-exe" True  prettyShow pkgHashStripExes
       , opt   "debug-info"   NormalDebugInfo (show . fromEnum) pkgHashDebugInfo
       , opt   "extra-lib-dirs"     [] unwords pkgHashExtraLibDirs
+      , opt   "extra-lib-dirs-static" [] unwords pkgHashExtraLibDirsStatic
       , opt   "extra-framework-dirs" [] unwords pkgHashExtraFrameworkDirs
       , opt   "extra-include-dirs" [] unwords pkgHashExtraIncludeDirs
       , opt   "prog-prefix" Nothing (maybe "" fromPathTemplate) pkgHashProgPrefix
@@ -309,6 +314,9 @@
       , opt   "haddock-hyperlink-source" False prettyShow pkgHashHaddockLinkedSource
       , opt   "haddock-quickjump" False prettyShow pkgHashHaddockQuickJump
       , opt   "haddock-contents-location" Nothing (maybe "" fromPathTemplate) pkgHashHaddockContents
+      , opt   "haddock-index-location" Nothing (maybe "" fromPathTemplate) pkgHashHaddockIndex
+      , opt   "haddock-base-url" Nothing (fromMaybe "") pkgHashHaddockBaseUrl
+      , opt   "haddock-lib" Nothing (fromMaybe "") pkgHashHaddockLib
 
       ] ++ Map.foldrWithKey (\prog args acc -> opt (prog ++ "-options") [] unwords args : acc) [] pkgHashProgramArgs
   where
diff --git a/cabal/cabal-install/src/Distribution/Client/ProjectConfig.hs b/cabal/cabal-install/src/Distribution/Client/ProjectConfig.hs
--- a/cabal/cabal-install/src/Distribution/Client/ProjectConfig.hs
+++ b/cabal/cabal-install/src/Distribution/Client/ProjectConfig.hs
@@ -31,6 +31,7 @@
     readProjectLocalFreezeConfig,
     reportParseResult,
     showProjectConfig,
+    withGlobalConfig,
     withProjectOrGlobalConfig,
     writeProjectLocalExtraConfig,
     writeProjectLocalFreezeConfig,
@@ -119,7 +120,7 @@
          ( PathTemplate, fromPathTemplate
          , toPathTemplate, substPathTemplate, initialPathTemplateEnv )
 import Distribution.Simple.Utils
-         ( die', warn, notice, info, createDirectoryIfMissingVerbose, rawSystemIOWithEnv )
+         ( die', warn, notice, info, createDirectoryIfMissingVerbose, maybeExit, rawSystemIOWithEnv )
 import Distribution.Client.Utils
          ( determineNumJobs )
 import Distribution.Utils.NubList
@@ -462,12 +463,21 @@
 renderBadProjectRoot (BadProjectRootExplicitFile projectFile) =
     "The given project file '" ++ projectFile ++ "' does not exist."
 
+withGlobalConfig
+    :: Verbosity                  -- ^ verbosity
+    -> Flag FilePath              -- ^ @--cabal-config@
+    -> (ProjectConfig -> IO a)    -- ^ with global
+    -> IO a
+withGlobalConfig verbosity gcf with = do
+    globalConfig <- runRebuild "" $ readGlobalConfig verbosity gcf
+    with globalConfig
+
 withProjectOrGlobalConfig
     :: Verbosity                  -- ^ verbosity
     -> Flag Bool                  -- ^ whether to ignore local project (--ignore-project flag)
     -> Flag FilePath              -- ^ @--cabal-config@
     -> IO a                       -- ^ with project
-    -> (ProjectConfig -> IO a)    -- ^ without projet
+    -> (ProjectConfig -> IO a)    -- ^ without project
     -> IO a
 withProjectOrGlobalConfig verbosity (Flag True) gcf _with without = do
     globalConfig <- runRebuild "" $ readGlobalConfig verbosity gcf
@@ -622,7 +632,7 @@
     writeFile file . showProjectConfig
 
 
--- | Read the user's @~/.cabal/config@ file.
+-- | Read the user's cabal-install config file.
 --
 readGlobalConfig :: Verbosity -> Flag FilePath -> Rebuild ProjectConfig
 readGlobalConfig verbosity configFileFlag = do
@@ -1139,11 +1149,10 @@
                             [ ((rtype, rloc), [(repo, vcsRepoType vcs)])
                             | (repo, rloc, rtype, vcs) <- repos' ]
 
-    --TODO: pass progPathExtra on to 'configureVCS'
-    let _progPathExtra = fromNubList projectConfigProgPathExtra
+    let progPathExtra = fromNubList projectConfigProgPathExtra
     getConfiguredVCS <- delayInitSharedResources $ \repoType ->
                           let vcs = Map.findWithDefault (error $ "Unknown VCS: " ++ prettyShow repoType) repoType knownVCSs in
-                          configureVCS verbosity {-progPathExtra-} vcs
+                          configureVCS verbosity progPathExtra vcs
 
     concat <$> sequenceA
       [ rerunIfChanged verbosity monitor repoGroup' $ do
@@ -1177,8 +1186,7 @@
         -- Run post-checkout-command if it is specified
         for_ repoGroupWithPaths $ \(repo, _, repoPath) ->
             for_ (nonEmpty (srpCommand repo)) $ \(cmd :| args) -> liftIO $ do
-                exitCode <- rawSystemIOWithEnv verbosity cmd args (Just repoPath) Nothing Nothing Nothing Nothing
-                unless (exitCode == ExitSuccess) $ exitWith exitCode
+                maybeExit $ rawSystemIOWithEnv verbosity cmd args (Just repoPath) Nothing Nothing Nothing Nothing
 
         -- But for reading we go through each 'SourceRepo' including its subdir
         -- value and have to know which path each one ended up in.
diff --git a/cabal/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs b/cabal/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs
--- a/cabal/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs
+++ b/cabal/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs
@@ -7,7 +7,8 @@
    -- Project config skeletons
     ProjectConfigSkeleton,
     parseProjectSkeleton,
-    instantiateProjectConfigSkeleton,
+    instantiateProjectConfigSkeletonFetchingCompiler,
+    instantiateProjectConfigSkeletonWithCompiler,
     singletonProjectConfigSkeleton,
     projectSkeletonImports,
 
@@ -44,7 +45,7 @@
          ( ClientInstallFlags(..), defaultClientInstallFlags
          , clientInstallOptions )
 
-import Distribution.Compat.Lens (view)
+import Distribution.Compat.Lens (view, toListOf)
 
 import Distribution.Solver.Types.ConstraintSource
 
@@ -52,7 +53,7 @@
 import Distribution.Package
 import Distribution.Types.SourceRepo (RepoType)
 import Distribution.Types.CondTree
-         ( CondTree (..), CondBranch (..), mapTreeConds, traverseCondTreeC )
+         ( CondTree (..), CondBranch (..), mapTreeConds, traverseCondTreeC, traverseCondTreeV, ignoreConditions )
 import Distribution.PackageDescription
          ( dispFlagAssignment, Condition (..), ConfVar (..), FlagAssignment )
 import Distribution.PackageDescription.Configuration (simplifyWithSysParams)
@@ -66,7 +67,7 @@
          , TestFlags(..), testOptions', defaultTestFlags
          , BenchmarkFlags(..), benchmarkOptions', defaultBenchmarkFlags
          , programDbPaths', splitArgs, DumpBuildInfo (NoDumpBuildInfo, DumpBuildInfo)
-         , readPackageDb, showPackageDb
+         , readPackageDb, showPackageDb, installDirsOptions
          )
 import Distribution.Client.NixStyleOptions (NixStyleFlags (..))
 import Distribution.Client.ProjectFlags (ProjectFlags (..), projectFlagsOptions, defaultProjectFlags)
@@ -101,7 +102,7 @@
 import Distribution.Client.ParseUtils
 import Distribution.Simple.Command
          ( CommandUI(commandOptions), ShowOrParseArgs(..)
-         , OptionField, option, reqArg' )
+         , OptionField(..), option, reqArg' )
 import Distribution.Types.PackageVersionConstraint
          ( PackageVersionConstraint )
 import Distribution.Parsec (ParsecParser, parsecToken)
@@ -116,7 +117,7 @@
 import Distribution.Fields.ConfVar (parseConditionConfVarFromClause)
 
 import Distribution.Client.HttpUtils
-import System.FilePath ((</>), isPathSeparator, makeValid)
+import System.FilePath ((</>), isPathSeparator, makeValid, isAbsolute, takeDirectory)
 import System.Directory (createDirectoryIfMissing)
 
 
@@ -135,8 +136,16 @@
 singletonProjectConfigSkeleton :: ProjectConfig -> ProjectConfigSkeleton
 singletonProjectConfigSkeleton x = CondNode x mempty mempty
 
-instantiateProjectConfigSkeleton :: OS -> Arch -> CompilerInfo -> FlagAssignment -> ProjectConfigSkeleton -> ProjectConfig
-instantiateProjectConfigSkeleton os arch impl _flags skel = go $ mapTreeConds (fst . simplifyWithSysParams os arch impl) skel
+instantiateProjectConfigSkeletonFetchingCompiler :: Monad m =>  m (OS, Arch, CompilerInfo) -> FlagAssignment -> ProjectConfigSkeleton -> m ProjectConfig
+instantiateProjectConfigSkeletonFetchingCompiler fetch flags skel
+   | null (toListOf traverseCondTreeV skel) = pure $ fst (ignoreConditions skel)
+   | otherwise = do
+       (os, arch, impl) <- fetch
+       pure $ instantiateProjectConfigSkeletonWithCompiler os arch impl flags skel
+
+
+instantiateProjectConfigSkeletonWithCompiler :: OS -> Arch -> CompilerInfo -> FlagAssignment -> ProjectConfigSkeleton -> ProjectConfig
+instantiateProjectConfigSkeletonWithCompiler os arch impl _flags skel = go $ mapTreeConds (fst . simplifyWithSysParams os arch impl) skel
     where
         go :: CondTree
                FlagName
@@ -215,7 +224,8 @@
             createDirectoryIfMissing True cacheDir
             _ <- downloadURI httpTransport verbosity uri fp
             BS.readFile fp
-         Nothing -> BS.readFile pci
+         Nothing -> BS.readFile $
+           if isAbsolute pci then pci else takeDirectory source </> pci
 
     modifiesCompiler :: ProjectConfig -> Bool
     modifiesCompiler pc = isSet projectConfigHcFlavor || isSet projectConfigHcPath || isSet projectConfigHcPkg
@@ -356,7 +366,7 @@
                                   , packageConfigHaddockLinkedSource = packageConfigHaddockLinkedSource pc
                                   })
 
--- | Convert from the types currently used for the user-wide @~/.cabal/config@
+-- | Convert from the types currently used for the user-wide Cabal config
 -- file into the 'ProjectConfig' type.
 --
 -- Only a subset of the 'ProjectConfig' can be represented in the user-wide
@@ -492,7 +502,7 @@
       configHcPath              = projectConfigHcPath,
       configHcPkg               = projectConfigHcPkg,
     --configProgramPathExtra    = projectConfigProgPathExtra DELETE ME
-    --configInstallDirs         = projectConfigInstallDirs,
+      configInstallDirs         = projectConfigInstallDirs,
     --configUserInstall         = projectConfigUserInstall,
       configPackageDBs          = projectConfigPackageDBs
     } = configFlags
@@ -604,7 +614,10 @@
       haddockLinkedSource       = packageConfigHaddockLinkedSource,
       haddockQuickJump          = packageConfigHaddockQuickJump,
       haddockHscolourCss        = packageConfigHaddockHscolourCss,
-      haddockContents           = packageConfigHaddockContents
+      haddockContents           = packageConfigHaddockContents,
+      haddockIndex              = packageConfigHaddockIndex,
+      haddockBaseUrl            = packageConfigHaddockBaseUrl,
+      haddockLib                = packageConfigHaddockLib
     } = haddockFlags
 
     TestFlags {
@@ -733,7 +746,8 @@
     configFlags = mempty {
       configVerbosity     = projectConfigVerbosity,
       configDistPref      = projectConfigDistDir,
-      configPackageDBs    = projectConfigPackageDBs
+      configPackageDBs    = projectConfigPackageDBs,
+      configInstallDirs   = projectConfigInstallDirs
     }
 
     configExFlags = ConfigExFlags {
@@ -831,7 +845,7 @@
       configOptimization        = mempty,
       configProgPrefix          = mempty,
       configProgSuffix          = mempty,
-      configInstallDirs         = mempty,
+      configInstallDirs         = projectConfigInstallDirs,
       configScratchDir          = mempty,
       configDistPref            = mempty,
       configCabalFilePath       = mempty,
@@ -966,6 +980,9 @@
       haddockKeepTempFiles = mempty,
       haddockVerbosity     = mempty,
       haddockCabalFilePath = mempty,
+      haddockIndex         = packageConfigHaddockIndex,
+      haddockBaseUrl       = packageConfigHaddockBaseUrl,
+      haddockLib           = packageConfigHaddockLib,
       haddockArgs          = mempty
     }
 
@@ -1125,7 +1142,7 @@
         (Disp.text . showPackageDb) (fmap readPackageDb parsecToken)
         configPackageDBs (\v conf -> conf { configPackageDBs = v })
       ]
-  . filterFields ["verbose", "builddir" ]
+  . filterFields (["verbose", "builddir"] ++ map optionName installDirsOptions)
   . commandOptionsToFields
   $ configureOptions ParseArgs
 
@@ -1285,7 +1302,8 @@
       , "foreign-libraries"
       , "executables", "tests", "benchmarks", "all", "internal", "css"
       , "hyperlink-source", "quickjump", "hscolour-css"
-      , "contents-location", "keep-temp-files"
+      , "contents-location", "index-location", "keep-temp-files", "base-url"
+      , "lib"
       ]
   . commandOptionsToFields
   ) (haddockOptions ParseArgs)
@@ -1320,7 +1338,6 @@
       []
   . commandOptionsToFields
   ) (benchmarkOptions' ParseArgs)
-
 
   where
     overrideFieldCompiler =
diff --git a/cabal/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs b/cabal/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs
--- a/cabal/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs
+++ b/cabal/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs
@@ -61,7 +61,7 @@
 import Distribution.Simple.Setup
          ( Flag, HaddockTarget(..), TestShowDetails(..), DumpBuildInfo (..) )
 import Distribution.Simple.InstallDirs
-         ( PathTemplate )
+         ( PathTemplate, InstallDirs )
 import Distribution.Utils.NubList
          ( NubList )
 
@@ -73,7 +73,7 @@
 
 -- | This type corresponds directly to what can be written in the
 -- @cabal.project@ file. Other sources of configuration can also be injected
--- into this type, such as the user-wide @~/.cabal/config@ file and the
+-- into this type, such as the user-wide config file and the
 -- command line of @cabal configure@ or @cabal build@.
 --
 -- Since it corresponds to the external project file it is an instance of
@@ -169,12 +169,11 @@
        projectConfigHcPkg             :: Flag FilePath,
        projectConfigHaddockIndex      :: Flag PathTemplate,
 
-       -- Things that only make sense for manual mode, not --local mode
+       -- Only makes sense for manual mode, not --local mode
        -- too much control!
      --projectConfigUserInstall       :: Flag Bool,
-     --projectConfigInstallDirs       :: InstallDirs (Flag PathTemplate),
-     --TODO: [required eventually] decide what to do with InstallDirs
-     -- currently we don't allow it to be specified in the config file
+
+       projectConfigInstallDirs       :: InstallDirs (Flag PathTemplate),
        projectConfigPackageDBs        :: [Maybe PackageDB],
 
        -- configuration used both by the solver and other phases
@@ -288,6 +287,9 @@
        packageConfigHaddockQuickJump    :: Flag Bool, --TODO: [required eventually] use this
        packageConfigHaddockHscolourCss  :: Flag FilePath, --TODO: [required eventually] use this
        packageConfigHaddockContents     :: Flag PathTemplate, --TODO: [required eventually] use this
+       packageConfigHaddockIndex        :: Flag PathTemplate, --TODO: [required eventually] use this
+       packageConfigHaddockBaseUrl      :: Flag String, --TODO: [required eventually] use this
+       packageConfigHaddockLib          :: Flag String, --TODO: [required eventually] use this
        packageConfigHaddockForHackage   :: Flag HaddockTarget,
        -- Test options
        packageConfigTestHumanLog        :: Flag PathTemplate,
diff --git a/cabal/cabal-install/src/Distribution/Client/ProjectOrchestration.hs b/cabal/cabal-install/src/Distribution/Client/ProjectOrchestration.hs
--- a/cabal/cabal-install/src/Distribution/Client/ProjectOrchestration.hs
+++ b/cabal/cabal-install/src/Distribution/Client/ProjectOrchestration.hs
@@ -138,7 +138,6 @@
 import qualified Distribution.Client.BuildReports.Storage as BuildReports
          ( storeLocal )
 
-import           Distribution.Client.Config (getCabalDir)
 import           Distribution.Client.HttpUtils
 import           Distribution.Client.Setup hiding (packageName)
 import           Distribution.Compiler
@@ -162,7 +161,7 @@
 import qualified Distribution.Simple.Setup as Setup
 import           Distribution.Simple.Command (commandShowOptions)
 import           Distribution.Simple.Configure (computeEffectiveProfiling)
-
+import           Distribution.Simple.PackageIndex (InstalledPackageIndex)
 import           Distribution.Simple.Utils
                    ( die', warn, notice, noticeNoWrap, debugNoWrap, createDirectoryIfMissingVerbose, ordNub )
 import           Distribution.Verbosity
@@ -187,11 +186,11 @@
 
 -- | Tracks what command is being executed, because we need to hide this somewhere
 -- for cases that need special handling (usually for error reporting).
-data CurrentCommand = InstallCommand | HaddockCommand | OtherCommand
+data CurrentCommand = InstallCommand | HaddockCommand | BuildCommand | ReplCommand | OtherCommand
                     deriving (Show, Eq)
 
 -- | This holds the context of a project prior to solving: the content of the
--- @cabal.project@ and all the local package @.cabal@ files.
+-- @cabal.project@, @cabal/config@ and all the local package @.cabal@ files.
 --
 data ProjectBaseContext = ProjectBaseContext {
        distDirLayout  :: DistDirLayout,
@@ -199,7 +198,8 @@
        projectConfig  :: ProjectConfig,
        localPackages  :: [PackageSpecifier UnresolvedSourcePackage],
        buildSettings  :: BuildTimeSettings,
-       currentCommand :: CurrentCommand
+       currentCommand :: CurrentCommand,
+       installedPackages :: Maybe InstalledPackageIndex
      }
 
 establishProjectBaseContext
@@ -222,8 +222,6 @@
     -> CurrentCommand
     -> IO ProjectBaseContext
 establishProjectBaseContextWithRoot verbosity cliConfig projectRoot currentCommand = do
-    cabalDir <- getCabalDir
-
     let distDirLayout  = defaultDistDirLayout projectRoot mdistDirectory
 
     httpTransport <- configureTransport verbosity
@@ -247,9 +245,9 @@
         mlogsDir = Setup.flagToMaybe projectConfigLogsDir
     mstoreDir <- sequenceA $ makeAbsolute
                  <$> Setup.flagToMaybe projectConfigStoreDir
-    let cabalDirLayout = mkCabalDirLayout cabalDir mstoreDir mlogsDir
+    cabalDirLayout <- mkCabalDirLayout mstoreDir mlogsDir
 
-        buildSettings = resolveBuildTimeSettings
+    let  buildSettings = resolveBuildTimeSettings
                           verbosity cabalDirLayout
                           projectConfig
 
@@ -263,11 +261,13 @@
       projectConfig,
       localPackages,
       buildSettings,
-      currentCommand
+      currentCommand,
+      installedPackages
     }
   where
     mdistDirectory = Setup.flagToMaybe projectConfigDistDir
     ProjectConfigShared { projectConfigDistDir } = projectConfigShared cliConfig
+    installedPackages = Nothing
 
 
 -- | This holds the context between the pre-build, build and post-build phases.
@@ -312,7 +312,8 @@
       distDirLayout,
       cabalDirLayout,
       projectConfig,
-      localPackages
+      localPackages,
+      installedPackages
     }
     action = do
     -- Take the project configuration and make a plan for how to build
@@ -324,6 +325,7 @@
                          distDirLayout cabalDirLayout
                          projectConfig
                          localPackages
+                         installedPackages
     action elaboratedPlan elaboratedShared
 
 runProjectPreBuildPhase
@@ -337,7 +339,8 @@
       distDirLayout,
       cabalDirLayout,
       projectConfig,
-      localPackages
+      localPackages,
+      installedPackages
     }
     selectPlanSubset = do
     -- Take the project configuration and make a plan for how to build
@@ -349,6 +352,7 @@
                          distDirLayout cabalDirLayout
                          projectConfig
                          localPackages
+                         installedPackages
 
     -- The plan for what to do is represented by an 'ElaboratedInstallPlan'
 
@@ -862,26 +866,26 @@
           ProjectBaseContext {
             buildSettings = BuildTimeSettings{buildSettingDryRun},
             projectConfig = ProjectConfig {
+              projectConfigAllPackages =
+                  PackageConfig {packageConfigOptimization = globalOptimization},
               projectConfigLocalPackages =
-                  PackageConfig {packageConfigOptimization}
-            }
+                  PackageConfig {packageConfigOptimization = localOptimization}
+            },
+            currentCommand
           }
           ProjectBuildContext {
             elaboratedPlanToExecute = elaboratedPlan,
             elaboratedShared,
             pkgsBuildStatus
           }
-
-  | null pkgs
-  = notice verbosity "Up to date"
-
-  | otherwise
-  = noticeNoWrap verbosity $ unlines $
+  | null pkgs && currentCommand == BuildCommand
+    = notice verbosity "Up to date"
+  | not (null pkgs) = noticeNoWrap verbosity $ unlines $
       (showBuildProfile ++ "In order, the following "
        ++ wouldWill ++ " be built"
        ++ ifNormal " (use -v for more details)" ++ ":")
     : map showPkgAndReason pkgs
-
+  | otherwise = return ()
   where
     pkgs = InstallPlan.executionOrder elaboratedPlan
 
@@ -997,7 +1001,7 @@
     showBuildProfile :: String
     showBuildProfile = "Build profile: " ++ unwords [
       "-w " ++ (showCompilerId . pkgConfigCompiler) elaboratedShared,
-      "-O" ++  (case packageConfigOptimization of
+      "-O" ++  (case globalOptimization <> localOptimization of -- if local is not set, read global
                 Setup.Flag NoOptimisation      -> "0"
                 Setup.Flag NormalOptimisation  -> "1"
                 Setup.Flag MaximumOptimisation -> "2"
@@ -1153,7 +1157,7 @@
       , [pkg]              <- rootpkgs
       , installedUnitId pkg == pkgid
       , isFailureSelfExplanatory (buildFailureReason failure)
-      , currentCommand /= InstallCommand
+      , currentCommand `notElem` [InstallCommand, BuildCommand, ReplCommand]
       = True
       | otherwise
       = False
@@ -1319,8 +1323,6 @@
   -> CurrentCommand
   -> IO ProjectBaseContext
 establishDummyProjectBaseContext verbosity projectConfig distDirLayout localPackages currentCommand = do
-    cabalDir <- getCabalDir
-
     let ProjectConfigBuildOnly {
           projectConfigLogsDir
         } = projectConfigBuildOnly projectConfig
@@ -1331,12 +1333,14 @@
 
         mlogsDir = flagToMaybe projectConfigLogsDir
         mstoreDir = flagToMaybe projectConfigStoreDir
-        cabalDirLayout = mkCabalDirLayout cabalDir mstoreDir mlogsDir
 
-        buildSettings :: BuildTimeSettings
+    cabalDirLayout <- mkCabalDirLayout mstoreDir mlogsDir
+
+    let buildSettings :: BuildTimeSettings
         buildSettings = resolveBuildTimeSettings
                           verbosity cabalDirLayout
                           projectConfig
+        installedPackages = Nothing
 
     return ProjectBaseContext {
       distDirLayout,
@@ -1344,7 +1348,8 @@
       projectConfig,
       localPackages,
       buildSettings,
-      currentCommand
+      currentCommand,
+      installedPackages
     }
 
 establishDummyDistDirLayout :: Verbosity -> ProjectConfig -> FilePath -> IO DistDirLayout
diff --git a/cabal/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal/cabal-install/src/Distribution/Client/ProjectPlanning.hs
--- a/cabal/cabal-install/src/Distribution/Client/ProjectPlanning.hs
+++ b/cabal/cabal-install/src/Distribution/Client/ProjectPlanning.hs
@@ -170,10 +170,9 @@
 import qualified Text.PrettyPrint as Disp
 import qualified Data.Map as Map
 import qualified Data.Set as Set
-#if MIN_VERSION_mtl(2,3,0)
-import           Control.Monad
-#endif
-import           Control.Monad.State as State
+import           Control.Monad (sequence, forM)
+import           Control.Monad.IO.Class (liftIO)
+import           Control.Monad.State as State (State, execState, runState, state)
 import           Control.Exception (assert)
 import           Data.List (groupBy, deleteBy)
 import qualified Data.List.NonEmpty as NE
@@ -322,9 +321,17 @@
                      }
                      cliConfig = do
 
+    progsearchpath <- liftIO $ getSystemSearchPath
+
+    let fileMonitorProjectConfig = newFileMonitor (distProjectCacheFile "config")
+
     fileMonitorProjectConfigKey <- do
       configPath <- getConfigFilePath projectConfigConfigFile
-      return (configPath, distProjectFile "")
+      return (configPath, distProjectFile "",
+                        (projectConfigHcFlavor, projectConfigHcPath, projectConfigHcPkg),
+                        progsearchpath,
+                        packageConfigProgramPaths,
+                        packageConfigProgramPathExtra)
 
     (projectConfig, localPackages) <-
       runRebuild distProjectRootDirectory
@@ -333,11 +340,14 @@
                        fileMonitorProjectConfigKey -- todo check deps too?
       $ do
           liftIO $ info verbosity "Project settings changed, reconfiguring..."
-          liftIO $ createDirectoryIfMissingVerbose verbosity True distProjectCacheDirectory
           projectConfigSkeleton <- phaseReadProjectConfig
-          -- have to create the cache directory before configuring the compiler
-          (compiler, Platform arch os, _) <- configureCompiler verbosity distDirLayout ((fst $ PD.ignoreConditions projectConfigSkeleton) <> cliConfig)
-          let projectConfig = instantiateProjectConfigSkeleton os arch (compilerInfo compiler) mempty projectConfigSkeleton
+          let fetchCompiler = do
+                 -- have to create the cache directory before configuring the compiler
+                 liftIO $ createDirectoryIfMissingVerbose verbosity True distProjectCacheDirectory
+                 (compiler, Platform arch os, _) <- configureCompiler verbosity distDirLayout ((fst $ PD.ignoreConditions projectConfigSkeleton) <> cliConfig)
+                 pure (os, arch, compilerInfo compiler)
+
+          projectConfig <- instantiateProjectConfigSkeletonFetchingCompiler fetchCompiler mempty projectConfigSkeleton
           localPackages <- phaseReadLocalPackages (projectConfig <> cliConfig)
           return (projectConfig, localPackages)
 
@@ -352,18 +362,11 @@
 
   where
 
-    ProjectConfigShared { projectConfigConfigFile } =
-      projectConfigShared cliConfig
-
-    ProjectConfigShared { projectConfigIgnoreProject } =
+    ProjectConfigShared { projectConfigHcFlavor, projectConfigHcPath, projectConfigHcPkg, projectConfigIgnoreProject, projectConfigConfigFile } =
       projectConfigShared cliConfig
 
-    fileMonitorProjectConfig ::
-      FileMonitor
-        (FilePath, FilePath)
-        (ProjectConfig, [PackageSpecifier UnresolvedSourcePackage])
-    fileMonitorProjectConfig =
-      newFileMonitor (distProjectCacheFile "config")
+    PackageConfig { packageConfigProgramPaths, packageConfigProgramPathExtra } =
+      projectConfigLocalPackages cliConfig
 
     -- Read the cabal.project (or implicit config) and combine it with
     -- arguments from the command line
@@ -423,10 +426,12 @@
                         packageConfigProgramPathExtra) $ do
 
           liftIO $ info verbosity "Compiler settings changed, reconfiguring..."
-          result@(_, _, progdb') <- liftIO $
+          progdb <- liftIO $ appendProgramSearchPath verbosity (fromNubList packageConfigProgramPathExtra) defaultProgramDb
+          let progdb' = userSpecifyPaths (Map.toList (getMapLast packageConfigProgramPaths)) progdb
+          result@(_, _, progdb'') <- liftIO $
             Cabal.configCompilerEx
               hcFlavor hcPath hcPkg
-              progdb verbosity
+              progdb' verbosity
 
         -- Note that we added the user-supplied program locations and args
         -- for /all/ programs, not just those for the compiler prog and
@@ -434,21 +439,16 @@
         -- the compiler will configure (and it does vary between compilers).
         -- We do know however that the compiler will only configure the
         -- programs it cares about, and those are the ones we monitor here.
-          monitorFiles (programsMonitorFiles progdb')
+          monitorFiles (programsMonitorFiles progdb'')
 
           return result
       where
         hcFlavor = flagToMaybe projectConfigHcFlavor
         hcPath   = flagToMaybe projectConfigHcPath
         hcPkg    = flagToMaybe projectConfigHcPkg
-        progdb   =
-            userSpecifyPaths (Map.toList (getMapLast packageConfigProgramPaths))
-          . modifyProgramSearchPath
-              (++ [ ProgramSearchPathDir dir
-                  | dir <- fromNubList packageConfigProgramPathExtra ])
-          $ defaultProgramDb
 
 
+
 -- | Return an up-to-date elaborated install plan.
 --
 -- Two variants of the install plan are returned: with and without packages
@@ -466,6 +466,7 @@
                    -> DistDirLayout -> CabalDirLayout
                    -> ProjectConfig
                    -> [PackageSpecifier UnresolvedSourcePackage]
+                   -> Maybe InstalledPackageIndex
                    -> IO ( ElaboratedInstallPlan  -- with store packages
                          , ElaboratedInstallPlan  -- with source packages
                          , ElaboratedSharedConfig
@@ -480,7 +481,7 @@
                    }
                    CabalDirLayout {
                      cabalStoreDirLayout
-                   } = \projectConfig localPackages ->
+                   } = \projectConfig localPackages mbInstalledPackages ->
     runRebuild distProjectRootDirectory $ do
     progsearchpath <- liftIO $ getSystemSearchPath
     let projectConfigMonitored = projectConfig { projectConfigBuildOnly = mempty }
@@ -503,6 +504,7 @@
                         <- phaseRunSolver         projectConfig
                                                   compilerEtc
                                                   localPackages
+                                                  (fromMaybe mempty mbInstalledPackages)
           (elaboratedPlan,
            elaboratedShared) <- phaseElaboratePlan projectConfig
                                                    compilerEtc pkgConfigDB
@@ -576,13 +578,15 @@
         :: ProjectConfig
         -> (Compiler, Platform, ProgramDb)
         -> [PackageSpecifier UnresolvedSourcePackage]
+        -> InstalledPackageIndex
         -> Rebuild (SolverInstallPlan, PkgConfigDb, IndexUtils.TotalIndexState, IndexUtils.ActiveRepos)
     phaseRunSolver projectConfig@ProjectConfig {
                      projectConfigShared,
                      projectConfigBuildOnly
                    }
                    (compiler, platform, progdb)
-                   localPackages =
+                   localPackages
+                   installedPackages =
         rerunIfChanged verbosity fileMonitorSolverPlan
                        (solverSettings,
                         localPackages, localPackagesEnabledStanzas,
@@ -609,7 +613,7 @@
             notice verbosity "Resolving dependencies..."
             planOrError <- foldProgress logMsg (pure . Left) (pure . Right) $
               planPackages verbosity compiler platform solver solverSettings
-                           installedPkgIndex sourcePkgDb pkgConfigDB
+                           (installedPackages <> installedPkgIndex) sourcePkgDb pkgConfigDB
                            localPackages localPackagesEnabledStanzas
             case planOrError of
               Left msg -> do reportPlanningFailure projectConfig compiler platform localPackages
@@ -679,6 +683,7 @@
             getPackageSourceHashes verbosity withRepoCtx solverPlan
 
         defaultInstallDirs <- liftIO $ userInstallDirTemplates compiler
+        let installDirs = fmap Cabal.fromFlag $ (fmap Flag defaultInstallDirs) <> (projectConfigInstallDirs projectConfigShared)
         (elaboratedPlan, elaboratedShared)
           <- liftIO . runLogProgress verbosity $
               elaborateInstallPlan
@@ -689,7 +694,7 @@
                 solverPlan
                 localPackages
                 sourcePackageHashes
-                defaultInstallDirs
+                installDirs
                 projectConfigShared
                 projectConfigAllPackages
                 projectConfigLocalPackages
@@ -697,7 +702,7 @@
         let instantiatedPlan
               = instantiateInstallPlan
                   cabalStoreDirLayout
-                  defaultInstallDirs
+                  installDirs
                   elaboratedShared
                   elaboratedPlan
         liftIO $ debugNoWrap verbosity (InstallPlan.showInstallPlan instantiatedPlan)
@@ -916,9 +921,9 @@
         -- Tarballs from repositories, either where the repository provides
         -- hashes as part of the repo metadata, or where we will have to
         -- download and hash the tarball.
-        repoTarballPkgsWithMetadata    :: [(PackageId, Repo)]
+        repoTarballPkgsWithMetadataUnvalidated    :: [(PackageId, Repo)]
         repoTarballPkgsWithoutMetadata :: [(PackageId, Repo)]
-        (repoTarballPkgsWithMetadata,
+        (repoTarballPkgsWithMetadataUnvalidated,
          repoTarballPkgsWithoutMetadata) =
           partitionEithers
           [ case repo of
@@ -926,10 +931,16 @@
               _            -> Right (pkgid, repo)
           | (pkgid, RepoTarballPackage repo _ _) <- allPkgLocations ]
 
+    (repoTarballPkgsWithMetadata, repoTarballPkgsToDownloadWithMeta) <- fmap partitionEithers $
+      liftIO $ withRepoCtx $ \repoctx -> forM repoTarballPkgsWithMetadataUnvalidated $
+        \x@(pkg, repo) -> verifyFetchedTarball verbosity repoctx repo pkg >>= \b -> case b of
+                          True -> return $ Left x
+                          False -> return $ Right x
+
     -- For tarballs from repos that do not have hashes available we now have
     -- to check if the packages were downloaded already.
     --
-    (repoTarballPkgsToDownload,
+    (repoTarballPkgsToDownloadWithNoMeta,
      repoTarballPkgsDownloaded)
       <- fmap partitionEithers $
          liftIO $ sequence
@@ -939,6 +950,7 @@
                   Just tarball -> return (Right (pkgid, tarball))
            | (pkgid, repo) <- repoTarballPkgsWithoutMetadata ]
 
+    let repoTarballPkgsToDownload = repoTarballPkgsToDownloadWithMeta ++ repoTarballPkgsToDownloadWithNoMeta
     (hashesFromRepoMetadata,
      repoTarballPkgsNewlyDownloaded) <-
       -- Avoid having to initialise the repository (ie 'withRepoCtx') if we
@@ -1033,7 +1045,6 @@
 planPackages verbosity comp platform solver SolverSettings{..}
              installedPkgIndex sourcePkgDb pkgConfigDB
              localPackages pkgStanzasEnable =
-
     resolveDependencies
       platform (compilerInfo comp)
       pkgConfigDB solver
@@ -1187,6 +1198,7 @@
     -- respective major Cabal version bundled with the respective GHC
     -- release).
     --
+    -- etc.
     -- GHC 9.2   needs  Cabal >= 3.6
     -- GHC 9.0   needs  Cabal >= 3.4
     -- GHC 8.10  needs  Cabal >= 3.2
@@ -1203,6 +1215,8 @@
     -- TODO: long-term, this compatibility matrix should be
     --       stored as a field inside 'Distribution.Compiler.Compiler'
     setupMinCabalVersionConstraint
+      | isGHC, compVer >= mkVersion [9,8]  = mkVersion [3,10,2]
+      | isGHC, compVer >= mkVersion [9,6]  = mkVersion [3,10]
       | isGHC, compVer >= mkVersion [9,4]  = mkVersion [3,8]
       | isGHC, compVer >= mkVersion [9,2]  = mkVersion [3,6]
       | isGHC, compVer >= mkVersion [9,0]  = mkVersion [3,4]
@@ -1961,6 +1975,9 @@
         elabHaddockQuickJump    = perPkgOptionFlag pkgid False packageConfigHaddockQuickJump
         elabHaddockHscolourCss  = perPkgOptionMaybe pkgid packageConfigHaddockHscolourCss
         elabHaddockContents     = perPkgOptionMaybe pkgid packageConfigHaddockContents
+        elabHaddockIndex        = perPkgOptionMaybe pkgid packageConfigHaddockIndex
+        elabHaddockBaseUrl      = perPkgOptionMaybe pkgid packageConfigHaddockBaseUrl
+        elabHaddockLib          = perPkgOptionMaybe pkgid packageConfigHaddockLib
 
         elabTestMachineLog      = perPkgOptionMaybe pkgid packageConfigTestMachineLog
         elabTestHumanLog        = perPkgOptionMaybe pkgid packageConfigTestHumanLog
@@ -3377,7 +3394,10 @@
       useDistPref              = builddir,
       useLoggingHandle         = Nothing, -- this gets set later
       useWorkingDir            = Just srcdir,
-      useExtraPathEnv          = elabExeDependencyPaths elab,
+      useExtraPathEnv = elabExeDependencyPaths elab ++ elabProgramPathExtra,
+        -- note that the above adds the extra-prog-path directly following the elaborated
+        -- dep paths, so that it overrides the normal path, but _not_ the elaborated extensions
+        -- for build-tools-depends.
       useExtraEnvOverrides     = dataDirsEnvironmentForPlan distdir plan,
       useWin32CleanHack        = False,   --TODO: [required eventually]
       forceExternalSetupMethod = isParallelBuild,
@@ -3438,7 +3458,6 @@
     sysconfdir   = prefix </> "etc"
 
 
-
 computeInstallDirs :: StoreDirLayout
                    -> InstallDirs.InstallDirTemplates
                    -> ElaboratedSharedConfig
@@ -3747,9 +3766,13 @@
                     -> Verbosity
                     -> FilePath
                     -> Cabal.HaddockFlags
-setupHsHaddockFlags (ElaboratedConfiguredPackage{..}) _ verbosity builddir =
+setupHsHaddockFlags (ElaboratedConfiguredPackage{..}) (ElaboratedSharedConfig{..}) verbosity builddir =
     Cabal.HaddockFlags {
-      haddockProgramPaths  = mempty, --unused, set at configure time
+      haddockProgramPaths  =
+        case lookupProgram haddockProgram pkgConfigCompilerProgs of
+          Nothing  -> mempty
+          Just prg -> [( programName haddockProgram
+                       , locationPath (programLocation prg) )],
       haddockProgramArgs   = mempty, --unused, set at configure time
       haddockHoogle        = toFlag elabHaddockHoogle,
       haddockHtml          = toFlag elabHaddockHtml,
@@ -3769,6 +3792,9 @@
       haddockKeepTempFiles = mempty, --TODO: from build settings
       haddockVerbosity     = toFlag verbosity,
       haddockCabalFilePath = mempty,
+      haddockIndex         = maybe mempty toFlag elabHaddockIndex,
+      haddockBaseUrl       = maybe mempty toFlag elabHaddockBaseUrl,
+      haddockLib           = maybe mempty toFlag elabHaddockLib,
       haddockArgs          = mempty
     }
 
@@ -3903,6 +3929,7 @@
       pkgHashDebugInfo           = elabDebugInfo,
       pkgHashProgramArgs         = elabProgramArgs,
       pkgHashExtraLibDirs        = elabExtraLibDirs,
+      pkgHashExtraLibDirsStatic  = elabExtraLibDirsStatic,
       pkgHashExtraFrameworkDirs  = elabExtraFrameworkDirs,
       pkgHashExtraIncludeDirs    = elabExtraIncludeDirs,
       pkgHashProgPrefix          = elabProgPrefix,
@@ -3921,7 +3948,10 @@
       pkgHashHaddockCss          = elabHaddockCss,
       pkgHashHaddockLinkedSource = elabHaddockLinkedSource,
       pkgHashHaddockQuickJump    = elabHaddockQuickJump,
-      pkgHashHaddockContents     = elabHaddockContents
+      pkgHashHaddockContents     = elabHaddockContents,
+      pkgHashHaddockIndex        = elabHaddockIndex,
+      pkgHashHaddockBaseUrl      = elabHaddockBaseUrl,
+      pkgHashHaddockLib          = elabHaddockLib
     }
   where
     ElaboratedConfiguredPackage{..} = normaliseConfiguredPackage shared pkg
diff --git a/cabal/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs b/cabal/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs
--- a/cabal/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs
+++ b/cabal/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs
@@ -292,6 +292,9 @@
        elabHaddockQuickJump      :: Bool,
        elabHaddockHscolourCss    :: Maybe FilePath,
        elabHaddockContents       :: Maybe PathTemplate,
+       elabHaddockIndex          :: Maybe PathTemplate,
+       elabHaddockBaseUrl        :: Maybe String,
+       elabHaddockLib            :: Maybe String,
 
        elabTestMachineLog        :: Maybe PathTemplate,
        elabTestHumanLog          :: Maybe PathTemplate,
diff --git a/cabal/cabal-install/src/Distribution/Client/Sandbox/PackageEnvironment.hs b/cabal/cabal-install/src/Distribution/Client/Sandbox/PackageEnvironment.hs
--- a/cabal/cabal-install/src/Distribution/Client/Sandbox/PackageEnvironment.hs
+++ b/cabal/cabal-install/src/Distribution/Client/Sandbox/PackageEnvironment.hs
@@ -25,7 +25,7 @@
 import Distribution.Client.Compat.Prelude
 import Prelude ()
 
-import Distribution.Client.Config      ( SavedConfig(..) 
+import Distribution.Client.Config      ( SavedConfig(..)
                                        , configFieldDescriptions
                                        , haddockFlagsFields
                                        , installDirsFields, withProgramsFields
@@ -45,7 +45,7 @@
                                        , commaListFieldParsec, commaNewLineListFieldParsec
                                        , liftField, lineNo, locatedErrorMsg
                                        , readFields
-                                       , showPWarning 
+                                       , showPWarning
                                        , syntaxError, warning )
 import System.Directory                ( doesFileExist )
 import System.FilePath                 ( (</>) )
@@ -81,7 +81,7 @@
 -- | Type of the current package environment.
 data PackageEnvironmentType
   = UserPackageEnvironment    -- ^ './cabal.config'
-  | AmbientPackageEnvironment -- ^ '~/.cabal/config'
+  | AmbientPackageEnvironment -- ^ '~/.config/cabal/config'
 
 -- | Is there a 'cabal.config' in this directory?
 classifyPackageEnvironment :: FilePath -> IO PackageEnvironmentType
@@ -271,7 +271,7 @@
 showPackageEnvironment pkgEnv = showPackageEnvironmentWithComments Nothing pkgEnv
 
 -- | Pretty-print the package environment with default values for empty fields
--- commented out (just like the default ~/.cabal/config).
+-- commented out (just like the default Cabal config file).
 showPackageEnvironmentWithComments :: (Maybe PackageEnvironment)
                                       -> PackageEnvironment
                                       -> String
diff --git a/cabal/cabal-install/src/Distribution/Client/ScriptUtils.hs b/cabal/cabal-install/src/Distribution/Client/ScriptUtils.hs
--- a/cabal/cabal-install/src/Distribution/Client/ScriptUtils.hs
+++ b/cabal/cabal-install/src/Distribution/Client/ScriptUtils.hs
@@ -6,10 +6,11 @@
 -- | Utilities to help commands with scripts
 --
 module Distribution.Client.ScriptUtils (
-    getScriptCacheDirectoryRoot, getScriptHash, getScriptCacheDirectory, ensureScriptCacheDirectory,
+    getScriptHash, getScriptCacheDirectory, ensureScriptCacheDirectory,
     withContextAndSelectors, AcceptNoTargets(..), TargetContext(..),
     updateContextAndWriteProjectFile, updateContextAndWriteProjectFile',
-    fakeProjectSourcePackage, lSrcpkgDescription
+    fakeProjectSourcePackage, lSrcpkgDescription,
+    movedExePath
   ) where
 
 import Prelude ()
@@ -22,24 +23,26 @@
     ( CabalSpecVersion (..), cabalSpecLatest)
 import Distribution.Client.ProjectOrchestration
 import Distribution.Client.Config
-    ( getCabalDir )
+    ( defaultScriptBuildsDir )
 import Distribution.Client.DistDirLayout
-    ( DistDirLayout(..) )
+    ( DistDirLayout(..), DistDirParams(..) )
 import Distribution.Client.HashValue
-    ( hashValue, showHashValue )
+    ( hashValue, showHashValue, truncateHash )
 import Distribution.Client.HttpUtils
          ( HttpTransport, configureTransport )
 import Distribution.Client.NixStyleOptions
     ( NixStyleFlags (..) )
 import Distribution.Client.ProjectConfig
-    ( ProjectConfig(..), ProjectConfigShared(..)
-    , reportParseResult, withProjectOrGlobalConfig
+    ( ProjectConfig(..), ProjectConfigShared(..), PackageConfig(..)
+    , reportParseResult, withGlobalConfig, withProjectOrGlobalConfig
     , projectConfigHttpTransport )
 import Distribution.Client.ProjectConfig.Legacy
     ( ProjectConfigSkeleton
-    , parseProjectSkeleton, instantiateProjectConfigSkeleton )
+    , parseProjectSkeleton, instantiateProjectConfigSkeletonFetchingCompiler )
 import Distribution.Client.ProjectFlags
     ( flagIgnoreProject )
+import Distribution.Client.ProjectPlanning
+    ( ElaboratedSharedConfig(..), ElaboratedConfiguredPackage(..) )
 import Distribution.Client.RebuildMonad
     ( runRebuild )
 import Distribution.Client.Setup
@@ -48,6 +51,8 @@
     ( TargetSelectorProblem(..), TargetString(..) )
 import Distribution.Client.Types
     ( PackageLocation(..), PackageSpecifier(..), UnresolvedSourcePackage )
+import Distribution.Compiler
+    ( CompilerId(..), perCompilerFlavorToList )
 import Distribution.FieldGrammar
     ( parseFieldGrammar, takeFields )
 import Distribution.Fields
@@ -67,7 +72,7 @@
 import Distribution.Simple.Setup
     ( Flag(..) )
 import Distribution.Simple.Compiler
-    ( compilerInfo )
+    ( Compiler(..), OptimisationLevel(..), compilerInfo )
 import Distribution.Simple.Utils
     ( createDirectoryIfMissingVerbose, createTempDirectory, die', handleDoesNotExist, readUTF8File, warn, writeUTF8File )
 import qualified Distribution.SPDX.License as SPDX
@@ -77,6 +82,8 @@
     ( Platform(..) )
 import Distribution.Types.BuildInfo
     ( BuildInfo(..) )
+import Distribution.Types.ComponentId
+    ( mkComponentId )
 import Distribution.Types.CondTree
     ( CondTree(..) )
 import Distribution.Types.Executable
@@ -87,6 +94,10 @@
     ( PackageDescription(..), emptyPackageDescription )
 import Distribution.Types.PackageName.Magic
     ( fakePackageCabalFileName, fakePackageId )
+import Distribution.Types.UnitId
+    ( newSimpleUnitId )
+import Distribution.Types.UnqualComponentName
+    ( UnqualComponentName )
 import Distribution.Utils.NubList
     ( fromNubList )
 import Distribution.Client.ProjectPlanning
@@ -106,7 +117,7 @@
 import System.Directory
     ( canonicalizePath, doesFileExist, getTemporaryDirectory, removeDirectoryRecursive )
 import System.FilePath
-    ( (</>), takeFileName )
+    ( (</>), makeRelative, takeDirectory, takeFileName )
 import qualified Text.Parsec as P
 
 -- A note on multi-module script support #6787:
@@ -120,32 +131,30 @@
 --    repl to deal with the fact that the repl is relative to the working directory and not
 --    the project root.
 
--- | Get the directory where script builds are cached.
---
--- @CABAL_DIR\/script-builds\/@
-getScriptCacheDirectoryRoot :: IO FilePath
-getScriptCacheDirectoryRoot = do
-  cabalDir <- getCabalDir
-  return $ cabalDir </> "script-builds"
-
--- | Get the hash of a script's absolute path)
+-- | Get the hash of a script's absolute path.
 --
 -- Two hashes will be the same as long as the absolute paths
 -- are the same.
 getScriptHash :: FilePath -> IO String
-getScriptHash script = showHashValue . hashValue . fromString <$> canonicalizePath script
+getScriptHash script =
+  -- Truncation here tries to help with long path issues on Windows.
+  showHashValue
+    . truncateHash 26
+    . hashValue
+    . fromString
+    <$> canonicalizePath script
 
 -- | Get the directory for caching a script build.
 --
 -- The only identity of a script is it's absolute path, so append the
--- hashed path to @CABAL_DIR\/script-builds\/@ to get the cache directory.
+-- hashed path to the @script-builds@ dir to get the cache directory.
 getScriptCacheDirectory :: FilePath -> IO FilePath
-getScriptCacheDirectory script = (</>) <$> getScriptCacheDirectoryRoot <*> getScriptHash script
+getScriptCacheDirectory script = (</>) <$> defaultScriptBuildsDir <*> getScriptHash script
 
 -- | Get the directory for caching a script build and ensure it exists.
 --
 -- The only identity of a script is it's absolute path, so append the
--- hashed path to @CABAL_DIR\/script-builds\/@ to get the cache directory.
+-- hashed path to the @script-builds@ dir to get the cache directory.
 ensureScriptCacheDirectory :: Verbosity -> FilePath -> IO FilePath
 ensureScriptCacheDirectory verbosity script = do
   cacheDir <- getScriptCacheDirectory script
@@ -179,12 +188,13 @@
   -> NixStyleFlags a     -- ^ Command line flags
   -> [String]            -- ^ Target strings or a script and args.
   -> GlobalFlags         -- ^ Global flags.
+  -> CurrentCommand      -- ^ Current Command (usually for error reporting).
   -> (TargetContext -> ProjectBaseContext -> [TargetSelector] -> IO b)
   -- ^ The body of your command action.
   -> IO b
-withContextAndSelectors noTargets kind flags@NixStyleFlags {..} targetStrings globalFlags act
+withContextAndSelectors noTargets kind flags@NixStyleFlags {..} targetStrings globalFlags cmd act
   = withTemporaryTempDirectory $ \mkTmpDir -> do
-    (tc, ctx) <- withProjectOrGlobalConfig verbosity ignoreProject globalConfigFlag with (without mkTmpDir)
+    (tc, ctx) <- withProjectOrGlobalConfig verbosity ignoreProject globalConfigFlag withProject (withoutProject mkTmpDir)
 
     (tc', ctx', sels) <- case targetStrings of
       -- Only script targets may contain spaces and or end with ':'.
@@ -216,19 +226,25 @@
     globalConfigFlag = projectConfigConfigFile (projectConfigShared cliConfig)
     defaultTarget = [TargetPackage TargetExplicitNamed [fakePackageId] Nothing]
 
-    with = do
-      ctx <- establishProjectBaseContext verbosity cliConfig OtherCommand
+    withProject = do
+      ctx <- establishProjectBaseContext verbosity cliConfig cmd
       return (ProjectContext, ctx)
-    without mkDir globalConfig = do
-      distDirLayout <- establishDummyDistDirLayout verbosity (globalConfig <> cliConfig) =<< mkDir
-      ctx <- establishDummyProjectBaseContext verbosity (globalConfig <> cliConfig) distDirLayout [] OtherCommand
+    withoutProject mkTmpDir globalConfig = do
+      distDirLayout <- establishDummyDistDirLayout verbosity (globalConfig <> cliConfig) =<< mkTmpDir
+      ctx <- establishDummyProjectBaseContext verbosity (globalConfig <> cliConfig) distDirLayout [] cmd
       return (GlobalContext, ctx)
+
+    scriptBaseCtx script globalConfig = do
+      let noDistDir = mempty { projectConfigShared = mempty { projectConfigDistDir = Flag "" } }
+      let cfg = noDistDir <> globalConfig <> cliConfig
+      rootDir <- ensureScriptCacheDirectory verbosity script
+      distDirLayout <- establishDummyDistDirLayout verbosity cfg rootDir
+      establishDummyProjectBaseContext verbosity cfg distDirLayout [] cmd
+
     scriptOrError script err = do
       exists <- doesFileExist script
       if exists then do
-        -- In the script case we always want a dummy context even when ignoreProject is False
-        let mkCacheDir = ensureScriptCacheDirectory verbosity script
-        (_, ctx) <- withProjectOrGlobalConfig verbosity (Flag True) globalConfigFlag with (without mkCacheDir)
+        ctx <- withGlobalConfig verbosity globalConfigFlag (scriptBaseCtx script)
 
         let projectRoot = distProjectRootDirectory $ distDirLayout ctx
         writeFile (projectRoot </> "scriptlocation") =<< canonicalizePath script
@@ -243,12 +259,22 @@
 
         projectCfgSkeleton <- readProjectBlockFromScript verbosity httpTransport (distDirLayout ctx) (takeFileName script) scriptContents
 
-        (compiler, Platform arch os, _) <- runRebuild (distProjectRootDirectory . distDirLayout $ ctx) $ configureCompiler verbosity (distDirLayout ctx) ((fst $ ignoreConditions projectCfgSkeleton) <> projectConfig ctx)
+        createDirectoryIfMissingVerbose verbosity True (distProjectCacheDirectory $ distDirLayout ctx)
+        (compiler, platform@(Platform arch os), _) <- runRebuild projectRoot $ configureCompiler verbosity (distDirLayout ctx) (fst (ignoreConditions projectCfgSkeleton) <> projectConfig ctx)
 
-        let projectCfg = instantiateProjectConfigSkeleton os arch (compilerInfo compiler) mempty projectCfgSkeleton :: ProjectConfig
+        projectCfg <- instantiateProjectConfigSkeletonFetchingCompiler (pure (os, arch, compilerInfo compiler)) mempty projectCfgSkeleton
 
-        let executable' = executable & L.buildInfo . L.defaultLanguage %~ maybe (Just Haskell2010) Just
-            ctx'        = ctx & lProjectConfig %~ (<> projectCfg)
+        let ctx' = ctx & lProjectConfig %~ (<> projectCfg)
+
+            build_dir = distBuildDirectory (distDirLayout ctx') $ (scriptDistDirParams script) ctx' compiler platform
+            exePath = build_dir </> "bin" </> scriptExeFileName script
+            exePathRel = makeRelative projectRoot exePath
+
+            executable' = executable & L.buildInfo . L.defaultLanguage %~ maybe (Just Haskell2010) Just
+                                     & L.buildInfo . L.options %~ fmap (setExePath exePathRel)
+
+        createDirectoryIfMissingVerbose verbosity True (takeDirectory exePath)
+
         return (ScriptContext script executable', ctx', defaultTarget)
       else reportTargetSelectorProblems verbosity err
 
@@ -265,6 +291,36 @@
       return tmpDir
     rmTmp m _ = tryTakeMVar m >>= maybe (return ()) (handleDoesNotExist () . removeDirectoryRecursive)
 
+scriptComponenetName :: IsString s => FilePath -> s
+scriptComponenetName scriptPath = fromString cname
+  where
+    cname = "script-" ++ map censor (takeFileName scriptPath)
+    censor c | c `S.member` ccNamecore = c
+             | otherwise               = '_'
+
+scriptExeFileName :: FilePath -> FilePath
+scriptExeFileName scriptPath = "cabal-script-" ++ takeFileName scriptPath
+
+scriptDistDirParams :: FilePath -> ProjectBaseContext -> Compiler -> Platform -> DistDirParams
+scriptDistDirParams scriptPath ctx compiler platform = DistDirParams
+  { distParamUnitId         = newSimpleUnitId cid
+  , distParamPackageId      = fakePackageId
+  , distParamComponentId    = cid
+  , distParamComponentName  = Just $ CExeName cn
+  , distParamCompilerId     = compilerId compiler
+  , distParamPlatform       = platform
+  , distParamOptimization   = fromFlagOrDefault NormalOptimisation optimization
+  }
+  where
+      cn = scriptComponenetName scriptPath
+      cid = mkComponentId $ prettyShow fakePackageId <> "-inplace-" <> prettyShow cn
+      optimization = (packageConfigOptimization . projectConfigLocalPackages . projectConfig) ctx
+
+setExePath :: FilePath -> [String] -> [String]
+setExePath exePath options
+  | "-o" `notElem` options = "-o" : exePath : options
+  | otherwise              = options
+
 -- | Add the 'SourcePackage' to the context and use it to write a .cabal file.
 updateContextAndWriteProjectFile' :: ProjectBaseContext -> SourcePackage (PackageLocation (Maybe FilePath)) -> IO ProjectBaseContext
 updateContextAndWriteProjectFile' ctx srcPkg = do
@@ -289,15 +345,9 @@
 
   absScript <- canonicalizePath scriptPath
   let
-    -- Replace characters which aren't allowed in the executable component name with '_'
-    -- Prefix with "cabal-script-" to make it clear to end users that the name may be mangled
-    scriptExeName = "cabal-script-" ++ map censor (takeFileName scriptPath)
-    censor c | c `S.member` ccNamecore = c
-             | otherwise               = '_'
-
     sourcePackage = fakeProjectSourcePackage projectRoot
       & lSrcpkgDescription . L.condExecutables
-      .~ [(fromString scriptExeName, CondNode executable (targetBuildDepends $ buildInfo executable) [])]
+      .~ [(scriptComponenetName scriptPath, CondNode executable (targetBuildDepends $ buildInfo executable) [])]
     executable = scriptExecutable
       & L.modulePath .~ absScript
 
@@ -399,6 +449,15 @@
       , specVersion = CabalSpecV2_2
       , licenseRaw = Left SPDX.NONE
       }
+
+-- | Find the path of an exe that has been relocated with a "-o" option
+movedExePath :: UnqualComponentName -> DistDirLayout -> ElaboratedSharedConfig -> ElaboratedConfiguredPackage -> Maybe FilePath
+movedExePath selectedComponent distDirLayout elabShared elabConfigured = do
+  exe <- find ((== selectedComponent) . exeName) . executables $ elabPkgDescription elabConfigured
+  let CompilerId flavor _ = (compilerId . pkgConfigCompiler) elabShared
+  opts <- lookup flavor (perCompilerFlavorToList . options $ buildInfo exe)
+  let projectRoot = distProjectRootDirectory distDirLayout
+  fmap (projectRoot </>) . lookup "-o" $ reverse (zip opts (drop 1 opts))
 
 -- Lenses
 -- | A lens for the 'srcpkgDescription' field of 'SourcePackage'
diff --git a/cabal/cabal-install/src/Distribution/Client/Setup.hs b/cabal/cabal-install/src/Distribution/Client/Setup.hs
--- a/cabal/cabal-install/src/Distribution/Client/Setup.hs
+++ b/cabal/cabal-install/src/Distribution/Client/Setup.hs
@@ -72,7 +72,11 @@
 import qualified Distribution.Client.Init.Types as IT
 import qualified Distribution.Client.Init.Defaults as IT
 import Distribution.Client.Targets
-         ( UserConstraint, readUserConstraint )
+  ( UserConstraint
+  , readUserConstraint
+  )
+import Distribution.Deprecated.ParseUtils (parseSpaceList, parseTokenQ)
+import Distribution.Deprecated.ReadP (readP_to_E)
 import Distribution.Utils.NubList
          ( NubList, toNubList, fromNubList)
 
@@ -112,7 +116,7 @@
 import Distribution.Types.UnqualComponentName
          ( unqualComponentNameToPackageName )
 import Distribution.PackageDescription
-         ( BuildType(..), RepoKind(..), LibraryName(..) )
+         ( BuildType(..), RepoKind(..), LibraryName(..), Dependency )
 import Distribution.System ( Platform )
 import Distribution.ReadE
          ( ReadE(..), succeedReadE, parsecToReadE, parsecToReadEErr, unexpectMsgString )
@@ -127,6 +131,8 @@
          )
 import Distribution.Client.ManpageFlags (ManpageFlags, defaultManpageFlags, manpageOptions)
 import Distribution.FieldGrammar.Newtypes (SpecVersion (..))
+import Distribution.Parsec
+         ( parsecCommaList  )
 
 import Data.List
          ( deleteFirstsBy )
@@ -238,41 +244,49 @@
          "Commands:\n"
       ++ unlines (
         [ startGroup "global"
-        , addCmd "update"
-        , addCmd "install"
-        , par
+        , addCmd "user-config"
         , addCmd "help"
-        , addCmd "info"
+        , par
+        , startGroup "package database"
+        , addCmd "update"
         , addCmd "list"
-        , addCmd "fetch"
-        , addCmd "user-config"
+        , addCmd "info"
         , par
-        , startGroup "package"
-        , addCmd "get"
-        , addCmd "unpack"
+        , startGroup "initialization and download"
         , addCmd "init"
+        , addCmd "fetch"
+        , addCmd "get"
         , par
+        , startGroup "project configuration"
         , addCmd "configure"
+        , addCmd "freeze"
+        , addCmd "gen-bounds"
+        , addCmd "outdated"
+        , par
+        , startGroup "project building and installing"
         , addCmd "build"
+        , addCmd "install"
+        , addCmd "haddock"
+        , addCmd "haddock-project"
         , addCmd "clean"
         , par
-        , addCmd "run"
+        , startGroup "running and testing"
+        , addCmd "list-bin"
         , addCmd "repl"
-        , addCmd "test"
+        , addCmd "run"
         , addCmd "bench"
+        , addCmd "test"
+        , addCmd "exec"
         , par
+        , startGroup "sanity checks and shipping"
         , addCmd "check"
         , addCmd "sdist"
         , addCmd "upload"
         , addCmd "report"
         , par
-        , addCmd "freeze"
-        , addCmd "gen-bounds"
-        , addCmd "outdated"
-        , addCmd "haddock"
+        , startGroup "deprecated"
+        , addCmd "unpack"
         , addCmd "hscolour"
-        , addCmd "exec"
-        , addCmd "list-bin"
         , par
         , startGroup "new-style projects (forwards-compatible aliases)"
         , addCmd "v2-build"
@@ -298,12 +312,8 @@
         , addCmd "v1-bench"
         , addCmd "v1-freeze"
         , addCmd "v1-haddock"
-        , addCmd "v1-exec"
-        , addCmd "v1-update"
         , addCmd "v1-install"
         , addCmd "v1-clean"
-        , addCmd "v1-sdist"
-        , addCmd "v1-doctest"
         , addCmd "v1-copy"
         , addCmd "v1-register"
         , addCmd "v1-reconfigure"
@@ -360,6 +370,11 @@
       ,multiOption "nix"
         globalNix (\v flags -> flags { globalNix = v })
         [
+          optArg' "(True or False)" (maybeToFlag . (readMaybe =<<)) (\case
+            Flag True -> [Just "enable"]
+            Flag False -> [Just "disable"]
+            NoFlag -> []) "" ["nix"] -- Must be empty because we need to return PP.empty from viewAsFieldDescr
+            "Nix integration: run commands through nix-shell if a 'shell.nix' file exists (default is False)",
           noArg (Flag True) [] ["enable-nix"]
           "Enable Nix integration: run commands through nix-shell if a 'shell.nix' file exists",
           noArg (Flag False) [] ["disable-nix"]
@@ -409,7 +424,6 @@
          "Set a location for a cabal.config file for projects without their own cabal.config freeze file."
          globalConstraintsFile (\v flags -> flags {globalConstraintsFile = v})
          (reqArgFlag "FILE")
-
       ]
 
 -- ------------------------------------------------------------
@@ -497,7 +511,7 @@
     flags_2_5_0 = flags_3_7_0 {
       -- Cabal < 2.5 does not understand --dependency=pkg:component=cid
       -- (public sublibraries), so we convert it to the legacy
-      -- --dependency=pkg_or_internal_compoent=cid
+      -- --dependency=pkg_or_internal_component=cid
         configDependencies =
           let convertToLegacyInternalDep (GivenComponent _ (LSubLibName cn) cid) =
                 Just $ GivenComponent
@@ -1270,7 +1284,7 @@
     commandSynopsis     = "Upload build reports to a remote server.",
     commandDescription  = Nothing,
     commandNotes        = Just $ \_ ->
-         "You can store your Hackage login in the ~/.cabal/config file\n",
+         "You can store your Hackage login in the ~/.config/cabal/config file\n",
     commandUsage        = usageAlternatives "report" ["[FLAGS]"],
     commandDefaultFlags = defaultReportFlags,
     commandOptions      = \_ ->
@@ -1303,6 +1317,7 @@
 
 data GetFlags = GetFlags {
     getDestDir          :: Flag FilePath,
+    getOnlyPkgDescr     :: Flag Bool,
     getPristine         :: Flag Bool,
     getIndexState       :: Flag TotalIndexState,
     getActiveRepos      :: Flag ActiveRepos,
@@ -1313,6 +1328,7 @@
 defaultGetFlags :: GetFlags
 defaultGetFlags = GetFlags {
     getDestDir          = mempty,
+    getOnlyPkgDescr     = mempty,
     getPristine         = mempty,
     getIndexState       = mempty,
     getActiveRepos      = mempty,
@@ -1358,6 +1374,16 @@
                                       (toFlag `fmap` parsec))
                           (flagToList . fmap prettyShow))
 
+       , option [] ["only-package-description"]
+           "Unpack only the package description file."
+           getOnlyPkgDescr (\v flags -> flags { getOnlyPkgDescr = v })
+           trueArg
+
+       , option [] ["package-description-only"]
+           "A synonym for --only-package-description."
+           getOnlyPkgDescr (\v flags -> flags { getOnlyPkgDescr = v })
+           trueArg
+
        , option [] ["pristine"]
            ("Unpack the original pristine tarball, rather than updating the "
            ++ ".cabal file with the latest revision from the package archive.")
@@ -1665,7 +1691,7 @@
      ++ " `v1-configure` for a list of commands being affected.\n"
      ++ "\n"
      ++ "Installed executables will by default"
-     ++ " be put into `~/.cabal/bin/`."
+     ++ " be put into `~/.local/bin/`."
      ++ " If you want installed executable to be available globally, make"
      ++ " sure that the PATH environment variable contains that directory.\n"
      ++ "\n",
@@ -1757,7 +1783,7 @@
     , name `elem` ["hoogle", "html", "html-location"
                   ,"executables", "tests", "benchmarks", "all", "internal", "css"
                   ,"hyperlink-source", "quickjump", "hscolour-css"
-                  ,"contents-location", "for-hackage"]
+                  ,"contents-location", "use-index", "for-hackage", "base-url", "lib"]
     ]
 
 testOptions :: ShowOrParseArgs -> [OptionField TestFlags]
@@ -1982,51 +2008,77 @@
   }
 
 uploadCommand :: CommandUI UploadFlags
-uploadCommand = CommandUI {
-    commandName         = "upload",
-    commandSynopsis     = "Uploads source packages or documentation to Hackage.",
-    commandDescription  = Nothing,
-    commandNotes        = Just $ \_ ->
-         "You can store your Hackage login in the ~/.cabal/config file\n"
-      ++ relevantConfigValuesText ["username", "password", "password-command"],
-    commandUsage        = \pname ->
-         "Usage: " ++ pname ++ " upload [FLAGS] TARFILES\n",
-    commandDefaultFlags = defaultUploadFlags,
-    commandOptions      = \_ ->
-      [optionVerbosity uploadVerbosity
-       (\v flags -> flags { uploadVerbosity = v })
-
-      ,option [] ["publish"]
-        "Publish the package instead of uploading it as a candidate."
-        uploadCandidate (\v flags -> flags { uploadCandidate = v })
-        (noArg (Flag IsPublished))
-
-      ,option ['d'] ["documentation"]
-        ("Upload documentation instead of a source package. "
-        ++ "By default, this uploads documentation for a package candidate. "
-        ++ "To upload documentation for "
-        ++ "a published package, combine with --publish.")
-        uploadDoc (\v flags -> flags { uploadDoc = v })
-        trueArg
-
-      ,option ['u'] ["username"]
-        "Hackage username."
-        uploadUsername (\v flags -> flags { uploadUsername = v })
-        (reqArg' "USERNAME" (toFlag . Username)
-                            (flagToList . fmap unUsername))
-
-      ,option ['p'] ["password"]
-        "Hackage password."
-        uploadPassword (\v flags -> flags { uploadPassword = v })
-        (reqArg' "PASSWORD" (toFlag . Password)
-                            (flagToList . fmap unPassword))
-
-      ,option ['P'] ["password-command"]
-        "Command to get Hackage password."
-        uploadPasswordCmd (\v flags -> flags { uploadPasswordCmd = v })
-        (reqArg' "PASSWORD" (Flag . words) (fromMaybe [] . flagToMaybe))
-      ]
-  }
+uploadCommand =
+  CommandUI
+    { commandName = "upload"
+    , commandSynopsis = "Uploads source packages or documentation to Hackage."
+    , commandDescription = Nothing
+    , commandNotes = Just $ \_ ->
+        "You can store your Hackage login in the ~/.config/cabal/config file\n"
+          ++ relevantConfigValuesText ["username", "password", "password-command"]
+    , commandUsage = \pname ->
+        "Usage: " ++ pname ++ " upload [FLAGS] TARFILES\n"
+    , commandDefaultFlags = defaultUploadFlags
+    , commandOptions = \_ ->
+        [ optionVerbosity
+            uploadVerbosity
+            (\v flags -> flags{uploadVerbosity = v})
+        , option
+            []
+            ["publish"]
+            "Publish the package instead of uploading it as a candidate."
+            uploadCandidate
+            (\v flags -> flags{uploadCandidate = v})
+            (noArg (Flag IsPublished))
+        , option
+            ['d']
+            ["documentation"]
+            ( "Upload documentation instead of a source package. "
+                ++ "By default, this uploads documentation for a package candidate. "
+                ++ "To upload documentation for "
+                ++ "a published package, combine with --publish."
+            )
+            uploadDoc
+            (\v flags -> flags{uploadDoc = v})
+            trueArg
+        , option
+            ['u']
+            ["username"]
+            "Hackage username."
+            uploadUsername
+            (\v flags -> flags{uploadUsername = v})
+            ( reqArg'
+                "USERNAME"
+                (toFlag . Username)
+                (flagToList . fmap unUsername)
+            )
+        , option
+            ['p']
+            ["password"]
+            "Hackage password."
+            uploadPassword
+            (\v flags -> flags{uploadPassword = v})
+            ( reqArg'
+                "PASSWORD"
+                (toFlag . Password)
+                (flagToList . fmap unPassword)
+            )
+        , option
+            ['P']
+            ["password-command"]
+            "Command to get Hackage password."
+            uploadPasswordCmd
+            (\v flags -> flags{uploadPasswordCmd = v})
+            ( reqArg
+                "COMMAND"
+                ( readP_to_E
+                    ("Cannot parse command: " ++)
+                    (Flag <$> parseSpaceList parseTokenQ)
+                )
+                (flagElim [] (pure . unwords . fmap show))
+            )
+        ]
+    }
 
 instance Monoid UploadFlags where
   mempty = gmempty
@@ -2146,12 +2198,14 @@
 
   , option ['x'] ["extra-source-file"]
     "Extra source file to be distributed with tarball."
-    IT.extraSrc (\v flags -> flags { IT.extraSrc = v })
+    IT.extraSrc
+    (\v flags -> flags { IT.extraSrc = mergeListFlag (IT.extraSrc flags) v })
     (reqArg' "FILE" (Flag . (:[]))
                     (fromFlagOrDefault []))
   , option [] ["extra-doc-file"]
     "Extra doc file to be distributed with tarball."
-    IT.extraDoc (\v flags -> flags { IT.extraDoc = v })
+    IT.extraDoc
+    (\v flags -> flags { IT.extraDoc = mergeListFlag (IT.extraDoc flags) v })
     (reqArg' "FILE" (Flag . (:[])) (fromFlagOrDefault []))
 
   , option [] ["lib", "is-library"]
@@ -2179,7 +2233,8 @@
 
       , option [] ["test-dir"]
         "Directory containing tests."
-        IT.testDirs (\v flags -> flags { IT.testDirs = v })
+        IT.testDirs (\v flags ->
+          flags { IT.testDirs = mergeListFlag (IT.testDirs flags) v })
         (reqArg' "DIR" (Flag . (:[]))
                        (fromFlagOrDefault []))
 
@@ -2206,7 +2261,8 @@
   , option ['o'] ["expose-module"]
     "Export a module from the package."
     IT.exposedModules
-    (\v flags -> flags { IT.exposedModules = v })
+    (\v flags -> flags { IT.exposedModules =
+      mergeListFlag (IT.exposedModules flags) v})
     (reqArg "MODULE" (parsecToReadE ("Cannot parse module name: "++)
                                  (Flag . (:[]) <$> parsec))
                      (flagElim [] (fmap prettyShow)))
@@ -2214,33 +2270,38 @@
   , option [] ["extension"]
     "Use a LANGUAGE extension (in the other-extensions field)."
     IT.otherExts
-    (\v flags -> flags { IT.otherExts = v })
+    (\v flags -> flags { IT.otherExts =
+      mergeListFlag (IT.otherExts flags) v })
     (reqArg "EXTENSION" (parsecToReadE ("Cannot parse extension: "++)
                                     (Flag . (:[]) <$> parsec))
                         (flagElim [] (fmap prettyShow)))
 
   , option ['d'] ["dependency"]
-    "Package dependency."
-    IT.dependencies (\v flags -> flags { IT.dependencies = v })
-    (reqArg "PACKAGE" (parsecToReadE ("Cannot parse dependency: "++)
-                                  (Flag . (:[]) <$> parsec))
-                      (flagElim [] (fmap prettyShow)))
+    "Package dependencies. Permits comma separated list of dependencies."
+    IT.dependencies
+    (\v flags -> flags { IT.dependencies =
+      mergeListFlag (IT.dependencies flags) v })
+    (reqArg "DEPENDENCIES" (fmap Flag dependenciesReadE)
+                           (fmap prettyShow . fromFlagOrDefault []))
 
   , option [] ["application-dir"]
     "Directory containing package application executable."
-    IT.applicationDirs (\v flags -> flags { IT.applicationDirs = v})
+    IT.applicationDirs (\v flags -> flags { IT.applicationDirs =
+      mergeListFlag (IT.applicationDirs flags) v})
     (reqArg' "DIR" (Flag . (:[]))
                    (fromFlagOrDefault []))
 
   , option [] ["source-dir", "sourcedir"]
     "Directory containing package library source."
-    IT.sourceDirs (\v flags -> flags { IT.sourceDirs = v })
+    IT.sourceDirs (\v flags -> flags { IT.sourceDirs =
+      mergeListFlag (IT.sourceDirs flags) v })
     (reqArg' "DIR" (Flag. (:[]))
                    (fromFlagOrDefault []))
 
   , option [] ["build-tool"]
     "Required external build tool."
-    IT.buildTools (\v flags -> flags { IT.buildTools = v })
+    IT.buildTools (\v flags -> flags { IT.buildTools =
+      mergeListFlag (IT.buildTools flags) v })
     (reqArg' "TOOL" (Flag . (:[]))
                     (fromFlagOrDefault []))
 
@@ -2252,7 +2313,17 @@
 
   , optionVerbosity IT.initVerbosity (\v flags -> flags { IT.initVerbosity = v })
   ]
+  where
+    dependenciesReadE :: ReadE [Dependency]
+    dependenciesReadE =
+      parsecToReadE
+        ("Cannot parse dependencies: " ++)
+        (parsecCommaList parsec)
 
+    mergeListFlag :: Flag [a] -> Flag [a] -> Flag [a]
+    mergeListFlag currentFlags v =
+      Flag $ concat (flagToList currentFlags ++ flagToList v)
+
 -- ------------------------------------------------------------
 -- * Copy and Register
 -- ------------------------------------------------------------
@@ -2342,18 +2413,18 @@
   commandDescription  = Just $ \_ -> wrapText $
        "When upgrading cabal, the set of configuration keys and their default"
     ++ " values may change. This command provides means to merge the existing"
-    ++ " config in ~/.cabal/config"
+    ++ " config in ~/.config/cabal/config"
     ++ " (i.e. all bindings that are actually defined and not commented out)"
     ++ " and the default config of the new version.\n"
     ++ "\n"
-    ++ "init: Creates a new config file at either ~/.cabal/config or as"
+    ++ "init: Creates a new config file at either ~/.config/cabal/config or as"
     ++ " specified by --config-file, if given. An existing file won't be "
     ++ " overwritten unless -f or --force is given.\n"
-    ++ "diff: Shows a pseudo-diff of the user's ~/.cabal/config file and"
+    ++ "diff: Shows a pseudo-diff of the user's ~/.config/cabal/config file and"
     ++ " the default configuration that would be created by cabal if the"
     ++ " config file did not exist.\n"
     ++ "update: Applies the pseudo-diff to the configuration that would be"
-    ++ " created by default, and write the result back to ~/.cabal/config.",
+    ++ " created by default, and write the result back to ~/.config/cabal/config.",
 
   commandNotes        = Nothing,
   commandUsage        = usageAlternatives "user-config" ["init", "diff", "update"],
diff --git a/cabal/cabal-install/src/Distribution/Client/SetupWrapper.hs b/cabal/cabal-install/src/Distribution/Client/SetupWrapper.hs
--- a/cabal/cabal-install/src/Distribution/Client/SetupWrapper.hs
+++ b/cabal/cabal-install/src/Distribution/Client/SetupWrapper.hs
@@ -29,6 +29,7 @@
 import Distribution.CabalSpecVersion (cabalSpecMinimumLibraryVersion)
 import qualified Distribution.Make as Make
 import qualified Distribution.Simple as Simple
+
 import Distribution.Version
          ( Version, mkVersion, versionNumbers, VersionRange, anyVersion
          , intersectVersionRanges, orLaterVersion
@@ -59,9 +60,10 @@
          ( ProgramDb, emptyProgramDb
          , getProgramSearchPath, getDbProgramOutput, runDbProgram, ghcProgram
          , ghcjsProgram )
+import Distribution.Simple.Program.Db
+         ( appendProgramSearchPath )
 import Distribution.Simple.Program.Find
-         ( programSearchPathAsPATHVar
-         , ProgramSearchPathEntry(ProgramSearchPathDir) )
+         ( programSearchPathAsPATHVar )
 import Distribution.Simple.Program.Run
          ( getEffectiveEnvironment )
 import qualified Distribution.Simple.Program.Strip as Strip
@@ -77,7 +79,7 @@
 import qualified Distribution.InstalledPackageInfo as IPI
 import Distribution.Client.Types
 import Distribution.Client.Config
-         ( getCabalDir )
+         ( defaultCacheDir )
 import Distribution.Client.IndexUtils
          ( getInstalledPackages )
 import Distribution.Client.JobControl
@@ -87,8 +89,8 @@
 import Distribution.Utils.Generic
          ( safeHead )
 import Distribution.Simple.Utils
-         ( die', debug, info, infoNoWrap
-         , cabalVersion, tryFindPackageDesc
+         ( die', debug, info, infoNoWrap, maybeExit
+         , cabalVersion, tryFindPackageDesc, rawSystemProc
          , createDirectoryIfMissingVerbose, installExecutableFile
          , copyFileVerbose, rewriteFileEx, rewriteFileLBS )
 import Distribution.Client.Utils
@@ -109,9 +111,8 @@
 import System.Directory    ( doesFileExist )
 import System.FilePath     ( (</>), (<.>) )
 import System.IO           ( Handle, hPutStr )
-import Distribution.Compat.Process (createProcess)
-import System.Process      ( StdStream(..), proc, waitForProcess
-                           , ProcessHandle )
+import Distribution.Compat.Process (proc)
+import System.Process      ( StdStream(..) )
 import qualified System.Process as Process
 import Data.List           ( foldl1' )
 import Distribution.Client.Compat.ExecutablePath  ( getExecutablePath )
@@ -241,7 +242,7 @@
     -- When we are installing in parallel, we always use the external setup
     -- method. Since compiling the setup script each time adds noticeable
     -- overhead, we use a shared setup script cache
-    -- ('~/.cabal/setup-exe-cache'). For each (compiler, platform, Cabal
+    -- ('$XDG_CACHE_HOME/cabal/setup-exe-cache'). For each (compiler, platform, Cabal
     -- version) combination the cache holds a compiled setup script
     -- executable. This only affects the Simple build type; for the Custom,
     -- Configure and Make build types we always compile the setup script anew.
@@ -437,35 +438,32 @@
 buildTypeAction Make      = Make.defaultMainArgs
 buildTypeAction Custom               = error "buildTypeAction Custom"
 
+invoke :: Verbosity -> FilePath -> [String] -> SetupScriptOptions -> IO ()
+invoke verbosity path args options = do
+  info verbosity $ unwords (path : args)
+  case useLoggingHandle options of
+    Nothing        -> return ()
+    Just logHandle -> info verbosity $ "Redirecting build log to " ++ show logHandle
 
--- | @runProcess'@ is a version of @runProcess@ where we have
--- the additional option to decide whether or not we should
--- delegate CTRL+C to the spawned process.
-runProcess' :: FilePath                 -- ^ Filename of the executable
-            -> [String]                 -- ^ Arguments to pass to executable
-            -> Maybe FilePath           -- ^ Optional path to working directory
-            -> Maybe [(String, String)] -- ^ Optional environment
-            -> Maybe Handle             -- ^ Handle for @stdin@
-            -> Maybe Handle             -- ^ Handle for @stdout@
-            -> Maybe Handle             -- ^ Handle for @stderr@
-            -> Bool                     -- ^ Delegate Ctrl+C ?
-            -> IO ProcessHandle
-runProcess' cmd args mb_cwd mb_env mb_stdin mb_stdout mb_stderr _delegate = do
-  (_,_,_,ph) <-
-    createProcess
-      (proc cmd args){ Process.cwd = mb_cwd
-                     , Process.env = mb_env
-                     , Process.std_in  = mbToStd mb_stdin
-                     , Process.std_out = mbToStd mb_stdout
-                     , Process.std_err = mbToStd mb_stderr
-                     , Process.delegate_ctlc = _delegate
-                     }
-  return ph
-  where
-    mbToStd :: Maybe Handle -> StdStream
-    mbToStd Nothing = Inherit
-    mbToStd (Just hdl) = UseHandle hdl
+  progDb <- appendProgramSearchPath verbosity (useExtraPathEnv options) (useProgramDb options)
 
+  searchpath <- programSearchPathAsPATHVar $ getProgramSearchPath progDb
+  env       <- getEffectiveEnvironment $
+                 [ ("PATH", Just searchpath)
+                 , ("HASKELL_DIST_DIR", Just (useDistPref options))
+                 ] ++ useExtraEnvOverrides options
+
+  let loggingHandle = case useLoggingHandle options of
+                        Nothing -> Inherit
+                        Just hdl -> UseHandle hdl
+      cp = (proc path args) { Process.cwd = useWorkingDir options
+                            , Process.env = env
+                            , Process.std_out = loggingHandle
+                            , Process.std_err = loggingHandle
+                            , Process.delegate_ctlc = isInteractive options
+                            }
+  maybeExit $ rawSystemProc verbosity cp
+
 -- ------------------------------------------------------------
 -- * Self-Exec SetupMethod
 -- ------------------------------------------------------------
@@ -478,83 +476,43 @@
   info verbosity $ "Using self-exec internal setup method with build-type "
                  ++ show bt ++ " and args:\n  " ++ show args
   path <- getExecutablePath
-  info verbosity $ unwords (path : args)
-  case useLoggingHandle options of
-    Nothing        -> return ()
-    Just logHandle -> info verbosity $ "Redirecting build log to "
-                                    ++ show logHandle
-
-  searchpath <- programSearchPathAsPATHVar
-                (map ProgramSearchPathDir (useExtraPathEnv options) ++
-                 getProgramSearchPath (useProgramDb options))
-  env       <- getEffectiveEnvironment $
-                 [ ("PATH", Just searchpath)
-                 , ("HASKELL_DIST_DIR", Just (useDistPref options))
-                 ] ++ useExtraEnvOverrides options
-  process <- runProcess' path args
-             (useWorkingDir options) env Nothing
-             (useLoggingHandle options) (useLoggingHandle options)
-             (isInteractive options)
-  exitCode <- waitForProcess process
-  unless (exitCode == ExitSuccess) $ exitWith exitCode
+  invoke verbosity path args options
 
 -- ------------------------------------------------------------
 -- * External SetupMethod
 -- ------------------------------------------------------------
 
 externalSetupMethod :: WithCallStack (FilePath -> SetupRunner)
-externalSetupMethod path verbosity options _ args = do
-  info verbosity $ unwords (path : args)
-  case useLoggingHandle options of
-    Nothing        -> return ()
-    Just logHandle -> info verbosity $ "Redirecting build log to "
-                                    ++ show logHandle
-
-  -- See 'Note: win32 clean hack' above.
-#ifdef mingw32_HOST_OS
-  if useWin32CleanHack options then doWin32CleanHack path else doInvoke path
+externalSetupMethod path verbosity options _ args =
+#ifndef mingw32_HOST_OS
+  invoke verbosity path args options
 #else
-  doInvoke path
-#endif
-
+  -- See 'Note: win32 clean hack' above.
+  if useWin32CleanHack options
+    then invokeWithWin32CleanHack path
+    else invoke' path
   where
-    doInvoke path' = do
-      searchpath <- programSearchPathAsPATHVar
-                    (map ProgramSearchPathDir (useExtraPathEnv options) ++
-                      getProgramSearchPath (useProgramDb options))
-      env        <- getEffectiveEnvironment $
-                      [ ("PATH", Just searchpath)
-                      , ("HASKELL_DIST_DIR", Just (useDistPref options))
-                      ] ++ useExtraEnvOverrides options
-
-      debug verbosity $ "Setup arguments: "++unwords args
-      process <- runProcess' path' args
-                  (useWorkingDir options) env Nothing
-                  (useLoggingHandle options) (useLoggingHandle options)
-                  (isInteractive options)
-      exitCode <- waitForProcess process
-      unless (exitCode == ExitSuccess) $ exitWith exitCode
+    invoke' p = invoke verbosity p args options
 
-#ifdef mingw32_HOST_OS
-    doWin32CleanHack path' = do
+    invokeWithWin32CleanHack origPath = do
       info verbosity $ "Using the Win32 clean hack."
       -- Recursively removes the temp dir on exit.
       withTempDirectory verbosity (workingDir options) "cabal-tmp" $ \tmpDir ->
-          bracket (moveOutOfTheWay tmpDir path')
-                  (maybeRestore path')
-                  doInvoke
+          bracket (moveOutOfTheWay tmpDir origPath)
+                  (\tmpPath -> maybeRestore origPath tmpPath)
+                  (\tmpPath -> invoke' tmpPath)
 
-    moveOutOfTheWay tmpDir path' = do
-      let newPath = tmpDir </> "setup" <.> exeExtension buildPlatform
-      Win32.moveFile path' newPath
-      return newPath
+    moveOutOfTheWay tmpDir origPath = do
+      let tmpPath = tmpDir </> "setup" <.> exeExtension buildPlatform
+      Win32.moveFile origPath tmpPath
+      return tmpPath
 
-    maybeRestore oldPath path' = do
-      let oldPathDir = takeDirectory oldPath
-      oldPathDirExists <- doesDirectoryExist oldPathDir
+    maybeRestore origPath tmpPath = do
+      let origPathDir = takeDirectory origPath
+      origPathDirExists <- doesDirectoryExist origPathDir
       -- 'setup clean' didn't complete, 'dist/setup' still exists.
-      when oldPathDirExists $
-        Win32.moveFile path' oldPath
+      when origPathDirExists $
+        Win32.moveFile tmpPath origPath
 #endif
 
 getExternalSetupMethod
@@ -784,8 +742,8 @@
   cachedSetupDirAndProg :: SetupScriptOptions -> Version
                         -> IO (FilePath, FilePath)
   cachedSetupDirAndProg options' cabalLibVersion = do
-    cabalDir <- getCabalDir
-    let setupCacheDir       = cabalDir </> "setup-exe-cache"
+    cacheDir <- defaultCacheDir
+    let setupCacheDir       = cacheDir </> "setup-exe-cache"
         cachedSetupProgFile = setupCacheDir
                               </> ("setup-" ++ buildTypeString ++ "-"
                                    ++ cabalVersionString ++ "-"
diff --git a/cabal/cabal-install/src/Distribution/Client/Signal.hs b/cabal/cabal-install/src/Distribution/Client/Signal.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-install/src/Distribution/Client/Signal.hs
@@ -0,0 +1,49 @@
+{-# LANGUAGE CPP #-}
+module Distribution.Client.Signal
+  ( installTerminationHandler
+  , Terminated(..)
+  )
+where
+
+import qualified Control.Exception as Exception
+
+#ifndef mingw32_HOST_OS
+import Control.Concurrent (myThreadId)
+import Control.Monad (void)
+import qualified System.Posix.Signals as Signals
+#endif
+
+-- | Terminated is an asynchronous exception, thrown when
+-- SIGTERM is received. It's to 'kill' what 'UserInterrupt'
+-- is to Ctrl-C.
+data Terminated = Terminated
+
+instance Exception.Exception Terminated where
+  toException = Exception.asyncExceptionToException
+  fromException = Exception.asyncExceptionFromException
+
+instance Show Terminated where
+  show Terminated = "terminated"
+
+-- | Install a signal handler that initiates a controlled shutdown on receiving
+-- SIGTERM by throwing an asynchronous exception at the main thread. Must be
+-- called from the main thread.
+--
+-- It is a noop on Windows.
+--
+installTerminationHandler :: IO ()
+
+#ifdef mingw32_HOST_OS
+
+installTerminationHandler = return ()
+
+#else
+
+installTerminationHandler = do
+  mainThreadId <- myThreadId
+  void $ Signals.installHandler
+    Signals.sigTERM
+    (Signals.CatchOnce $ Exception.throwTo mainThreadId Terminated)
+    Nothing
+
+#endif
diff --git a/cabal/cabal-install/src/Distribution/Client/SourceFiles.hs b/cabal/cabal-install/src/Distribution/Client/SourceFiles.hs
--- a/cabal/cabal-install/src/Distribution/Client/SourceFiles.hs
+++ b/cabal/cabal-install/src/Distribution/Client/SourceFiles.hs
@@ -39,7 +39,7 @@
 
 import Prelude ()
 import Distribution.Client.Compat.Prelude
-import Distribution.Verbosity (silent)
+import Distribution.Verbosity (normal)
 
 import System.FilePath
 
@@ -150,7 +150,8 @@
     -- A.hs-boot; need to track both.
     findNeededModules ["hs", "lhs", "hsig", "lhsig"]
     findNeededModules ["hs-boot", "lhs-boot"]
-    expandedExtraSrcFiles <- liftIO $ fmap concat . for (extraSrcFiles pkg_descr) $ \fpath -> matchDirFileGlobWithDie silent (\ _ _ -> return []) (specVersion pkg_descr) "." fpath
+    root <- askRoot
+    expandedExtraSrcFiles <- liftIO $ fmap concat . for (extraSrcFiles pkg_descr) $ \fpath -> matchDirFileGlobWithDie normal (\ _ _ -> return []) (specVersion pkg_descr) root fpath
     traverse_ needIfExists $ concat
         [ cSources bi
         , cxxSources bi
diff --git a/cabal/cabal-install/src/Distribution/Client/TargetSelector.hs b/cabal/cabal-install/src/Distribution/Client/TargetSelector.hs
--- a/cabal/cabal-install/src/Distribution/Client/TargetSelector.hs
+++ b/cabal/cabal-install/src/Distribution/Client/TargetSelector.hs
@@ -713,21 +713,26 @@
     case [ (t, m, ms) | MatchingInternalError t m ms <- problems ] of
       [] -> return ()
       ((target, originalMatch, renderingsAndMatches):_) ->
-        die' verbosity $ "Internal error in target matching. It should always "
-           ++ "be possible to find a syntax that's sufficiently qualified to "
-           ++ "give an unambiguous match. However when matching '"
-           ++ showTargetString target ++ "'  we found "
-           ++ showTargetSelector originalMatch
-           ++ " (" ++ showTargetSelectorKind originalMatch ++ ") which does "
-           ++ "not have an unambiguous syntax. The possible syntax and the "
-           ++ "targets they match are as follows:\n"
+        die' verbosity $ "Internal error in target matching: could not make an "
+           ++ "unambiguous fully qualified target selector for '"
+           ++ showTargetString target ++ "'.\n"
+           ++ "We made the target '" ++ showTargetSelector originalMatch ++ "' ("
+           ++ showTargetSelectorKind originalMatch ++ ") that was expected to "
+           ++ "be unambiguous but matches the following targets:\n"
            ++ unlines
-                [ "'" ++ showTargetString rendering ++ "' which matches "
-                  ++ intercalate ", "
+                [ "'" ++ showTargetString rendering ++ "', matching:"
+                  ++ concatMap ("\n  - " ++)
                        [ showTargetSelector match ++
                          " (" ++ showTargetSelectorKind match ++ ")"
                        | match <- matches ]
                 | (rendering, matches) <- renderingsAndMatches ]
+           ++ "\nNote: Cabal expects to be able to make a single fully "
+           ++ "qualified name for a target or provide a more specific error. "
+           ++ "Our failure to do so is a bug in cabal. "
+           ++ "Tracking issue: https://github.com/haskell/cabal/issues/8684"
+           ++ "\n\nHint: this may be caused by trying to build a package that "
+           ++ "exists in the project directory but is missing from "
+           ++ "the 'packages' stanza in your cabal project file."
 
     case [ (t, e, g) | TargetSelectorExpected t e g <- problems ] of
       []      -> return ()
diff --git a/cabal/cabal-install/src/Distribution/Client/Types/ConfiguredPackage.hs b/cabal/cabal-install/src/Distribution/Client/Types/ConfiguredPackage.hs
--- a/cabal/cabal-install/src/Distribution/Client/Types/ConfiguredPackage.hs
+++ b/cabal/cabal-install/src/Distribution/Client/Types/ConfiguredPackage.hs
@@ -82,5 +82,3 @@
 instance PackageInstalled (ConfiguredPackage loc) where
   installedDepends = CD.flatDeps . depends
 
-
-
diff --git a/cabal/cabal-install/src/Distribution/Client/Upload.hs b/cabal/cabal-install/src/Distribution/Client/Upload.hs
--- a/cabal/cabal-install/src/Distribution/Client/Upload.hs
+++ b/cabal/cabal-install/src/Distribution/Client/Upload.hs
@@ -183,9 +183,9 @@
       let auth        :: (String, String)
           auth        = (username, password)
 
-      dotCabal <- getCabalDir
+      reportsDir <- defaultReportsDir
       let srcDir :: FilePath
-          srcDir = dotCabal </> "reports" </> unRepoName (remoteRepoName remoteRepo)
+          srcDir = reportsDir </> unRepoName (remoteRepoName remoteRepo)
       -- We don't want to bomb out just because we haven't built any packages
       -- from this repo yet.
       srcExists <- doesDirectoryExist srcDir
diff --git a/cabal/cabal-install/src/Distribution/Client/Utils.hs b/cabal/cabal-install/src/Distribution/Client/Utils.hs
--- a/cabal/cabal-install/src/Distribution/Client/Utils.hs
+++ b/cabal/cabal-install/src/Distribution/Client/Utils.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE ForeignFunctionInterface, ScopedTypeVariables, CPP #-}
+{-# LANGUAGE ScopedTypeVariables, CPP #-}
 
 module Distribution.Client.Utils
   ( MergeResult(..)
@@ -28,6 +28,7 @@
   , listFilesRecursive
   , listFilesInside
   , safeRead
+  , hasElem
   ) where
 
 import Prelude ()
@@ -47,7 +48,6 @@
          ( zipWithM_ )
 import Data.List
          ( groupBy )
-import Foreign.C.Types ( CInt(..) )
 import qualified Control.Exception as Exception
          ( finally )
 import qualified Control.Exception.Safe as Safe
@@ -61,6 +61,7 @@
          )
 import System.IO.Unsafe ( unsafePerformIO )
 
+import GHC.Conc.Sync ( getNumProcessors )
 import GHC.IO.Encoding
          ( recover, TextEncoding(TextEncoding) )
 import GHC.IO.Encoding.Failure
@@ -73,7 +74,7 @@
 import qualified System.Directory as Dir
 import qualified System.IO.Error as IOError
 #endif
-
+import qualified Data.Set as Set
 
 -- | Generic merging utility. For sorted input lists this is a full outer join.
 --
@@ -145,9 +146,7 @@
 withEnv k v m = do
   mb_old <- lookupEnv k
   setEnv k v
-  m `Exception.finally` (case mb_old of
-    Nothing -> unsetEnv k
-    Just old -> setEnv k old)
+  m `Exception.finally` setOrUnsetEnv k mb_old
 
 -- | Executes the action with a list of environment variables and
 -- corresponding overrides, where
@@ -160,15 +159,15 @@
 withEnvOverrides :: [(String, Maybe FilePath)] -> IO a -> IO a
 withEnvOverrides overrides m = do
   mb_olds <- traverse lookupEnv envVars
-  traverse_ (uncurry update) overrides
-  m `Exception.finally` zipWithM_ update envVars mb_olds
+  traverse_ (uncurry setOrUnsetEnv) overrides
+  m `Exception.finally` zipWithM_ setOrUnsetEnv envVars mb_olds
    where
     envVars :: [String]
     envVars = map fst overrides
 
-    update :: String -> Maybe FilePath -> IO ()
-    update var Nothing    = unsetEnv var
-    update var (Just val) = setEnv var val
+setOrUnsetEnv :: String -> Maybe String -> IO ()
+setOrUnsetEnv var Nothing    = unsetEnv var
+setOrUnsetEnv var (Just val) = setEnv var val
 
 -- | Executes the action, increasing the PATH environment
 -- in some way
@@ -197,12 +196,10 @@
   m `Exception.finally`
     (l $ "cabal: Leaving directory '" ++ d ++ "'\n")
 
-foreign import ccall "getNumberOfProcessors" c_getNumberOfProcessors :: IO CInt
-
 -- The number of processors is not going to change during the duration of the
 -- program, so unsafePerformIO is safe here.
 numberOfProcessors :: Int
-numberOfProcessors = fromEnum $ unsafePerformIO c_getNumberOfProcessors
+numberOfProcessors = unsafePerformIO getNumProcessors
 
 -- | Determine the number of jobs to use given the value of the '-j' flag.
 determineNumJobs :: Flag (Maybe Int) -> Int
@@ -433,7 +430,7 @@
 -- | From System.Directory.Extra
 --   https://hackage.haskell.org/package/extra-1.7.9
 listFilesInside :: (FilePath -> IO Bool) -> FilePath -> IO [FilePath]
-listFilesInside test dir = ifM (notM $ test $ dropTrailingPathSeparator dir) (pure []) $ do
+listFilesInside test dir = ifNotM (test $ dropTrailingPathSeparator dir) (pure []) $ do
     (dirs,files) <- partitionM doesDirectoryExist =<< listContents dir
     rest <- concatMapM (listFilesInside test) dirs
     pure $ files ++ rest
@@ -455,6 +452,11 @@
 ifM :: Monad m => m Bool -> m a -> m a -> m a
 ifM b t f = do b' <- b; if b' then t else f
 
+-- | 'ifM' with swapped branches:
+--   @ifNotM b t f = ifM (not <$> b) t f@
+ifNotM :: Monad m => m Bool -> m a -> m a -> m a
+ifNotM = flip . ifM
+
 -- | From Control.Monad.Extra
 --   https://hackage.haskell.org/package/extra-1.7.9
 concatMapM :: Monad m => (a -> m [b]) -> [a] -> m [b]
@@ -471,12 +473,18 @@
     (as,bs) <- partitionM f xs
     pure ([x | res]++as, [x | not res]++bs)
 
--- | From Control.Monad.Extra
---   https://hackage.haskell.org/package/extra-1.7.9
-notM :: Functor m => m Bool -> m Bool
-notM = fmap not
-
 safeRead :: Read a => String -> Maybe a
 safeRead s
   | [(x, "")] <- reads s = Just x
   | otherwise = Nothing
+
+-- | @hasElem xs x = elem x xs@ except that @xs@ is turned into a 'Set' first.
+--   Use underapplied to speed up subsequent lookups, e.g. @filter (hasElem xs) ys@.
+--   Only amortized when used several times!
+--
+--   Time complexity \(O((n+m) \log(n))\) for \(m\) lookups in a list of length \(n\).
+--   (Compare this to 'elem''s \(O(nm)\).)
+--
+--   This is [Agda.Utils.List.hasElem](https://hackage.haskell.org/package/Agda-2.6.2.2/docs/Agda-Utils-List.html#v:hasElem).
+hasElem :: Ord a => [a] -> a -> Bool
+hasElem xs = (`Set.member` Set.fromList xs)
diff --git a/cabal/cabal-install/src/Distribution/Client/VCS.hs b/cabal/cabal-install/src/Distribution/Client/VCS.hs
--- a/cabal/cabal-install/src/Distribution/Client/VCS.hs
+++ b/cabal/cabal-install/src/Distribution/Client/VCS.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE LambdaCase #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE NamedFieldPuns, RecordWildCards, RankNTypes #-}
@@ -49,12 +50,17 @@
          , simpleProgram, findProgramVersion
          , ProgramInvocation(..), programInvocation, runProgramInvocation, getProgramInvocationOutput
          , emptyProgramDb, requireProgram )
+import Distribution.Simple.Program.Db
+         ( appendProgramSearchPath )
 import Distribution.Version
          ( mkVersion )
 import qualified Distribution.PackageDescription as PD
 
+#if !MIN_VERSION_base(4,18,0)
 import Control.Applicative
          ( liftA2 )
+#endif
+
 import Control.Exception
          ( throw, try )
 import Control.Monad.Trans
@@ -165,17 +171,20 @@
 
 
 configureVCS :: Verbosity
+             -> [FilePath] -- ^ Extra prog paths
              -> VCS Program
              -> IO (VCS ConfiguredProgram)
-configureVCS verbosity vcs@VCS{vcsProgram = prog} =
-    asVcsConfigured <$> requireProgram verbosity prog emptyProgramDb
+configureVCS verbosity progPaths vcs@VCS{vcsProgram = prog} = do
+    progPath <- appendProgramSearchPath verbosity progPaths emptyProgramDb
+    asVcsConfigured <$> requireProgram verbosity prog progPath
   where
     asVcsConfigured (prog', _) = vcs { vcsProgram = prog' }
 
 configureVCSs :: Verbosity
+              -> [FilePath] -- ^ Extra prog paths
               -> Map RepoType (VCS Program)
               -> IO (Map RepoType (VCS ConfiguredProgram))
-configureVCSs verbosity = traverse (configureVCS verbosity)
+configureVCSs verbosity progPaths = traverse (configureVCS verbosity progPaths)
 
 
 -- ------------------------------------------------------------
@@ -205,7 +214,7 @@
                                srcuri destdir
 
 
--- | Syncronise a set of 'SourceRepo's referring to the same repository with
+-- | Synchronise a set of 'SourceRepo's referring to the same repository with
 -- corresponding local directories. The local directories may or may not
 -- already exist.
 --
@@ -654,7 +663,7 @@
 --
 --
 --                    ----->  foo on branch B ----->
---    resolve confict                                  Initial patch
+--    resolve conflict                                  Initial patch
 --                    ----->  foo on branch A ----->
 --
 --    Which is seems reasonable.
diff --git a/cabal/cabal-install/src/Distribution/Client/Version.hs b/cabal/cabal-install/src/Distribution/Client/Version.hs
--- a/cabal/cabal-install/src/Distribution/Client/Version.hs
+++ b/cabal/cabal-install/src/Distribution/Client/Version.hs
@@ -6,11 +6,7 @@
 
 import Distribution.Version
 
--- This value determines the `cabal-install --version` output.
--- 
--- It is used in several places throughout the project, including anonymous build reports, client configuration, 
--- and project planning output. Historically, this was a @Paths_*@ module, however, this conflicted with 
--- program coverage information generated by HPC, and hence was moved to be a standalone value.  
---
+-- |
+-- This value determines the output of `cabal-install --version`.
 cabalInstallVersion :: Version
-cabalInstallVersion = mkVersion [3,8,1,0]
+cabalInstallVersion = mkVersion [3,10,3,0]
diff --git a/cabal/cabal-install/src/Distribution/Deprecated/ParseUtils.hs b/cabal/cabal-install/src/Distribution/Deprecated/ParseUtils.hs
--- a/cabal/cabal-install/src/Distribution/Deprecated/ParseUtils.hs
+++ b/cabal/cabal-install/src/Distribution/Deprecated/ParseUtils.hs
@@ -21,25 +21,43 @@
 
 {-# OPTIONS_HADDOCK hide #-}
 {-# LANGUAGE Rank2Types #-}
-module Distribution.Deprecated.ParseUtils (
-        LineNo, PError(..), PWarning(..), locatedErrorMsg, syntaxError, warning,
-        runP, runE, ParseResult(..), parseFail, showPWarning,
-        Field(..), lineNo,
-        FieldDescr(..), readFields,
-        parseHaskellString, parseTokenQ,
-        parseOptCommaList,
-        showFilePath, showToken, showFreeText,
-        field, simpleField, listField, listFieldWithSep, spaceListField,
-        newLineListField,
-        liftField,
-        readPToMaybe,
-
-        fieldParsec, simpleFieldParsec,
-        listFieldParsec,
-        commaListFieldParsec,
-        commaNewLineListFieldParsec,
-
-        UnrecFieldParser,
+module Distribution.Deprecated.ParseUtils
+  ( LineNo
+  , PError (..)
+  , PWarning (..)
+  , locatedErrorMsg
+  , syntaxError
+  , warning
+  , runP
+  , runE
+  , ParseResult (..)
+  , parseFail
+  , showPWarning
+  , Field (..)
+  , lineNo
+  , FieldDescr (..)
+  , readFields
+  , parseHaskellString
+  , parseTokenQ
+  , parseSpaceList
+  , parseOptCommaList
+  , showFilePath
+  , showToken
+  , showFreeText
+  , field
+  , simpleField
+  , listField
+  , listFieldWithSep
+  , spaceListField
+  , newLineListField
+  , liftField
+  , readPToMaybe
+  , fieldParsec
+  , simpleFieldParsec
+  , listFieldParsec
+  , commaListFieldParsec
+  , commaNewLineListFieldParsec
+  , UnrecFieldParser
   ) where
 
 import Distribution.Client.Compat.Prelude hiding (get)
diff --git a/cabal/cabal-install/src/Distribution/Deprecated/ViewAsFieldDescr.hs b/cabal/cabal-install/src/Distribution/Deprecated/ViewAsFieldDescr.hs
--- a/cabal/cabal-install/src/Distribution/Deprecated/ViewAsFieldDescr.hs
+++ b/cabal/cabal-install/src/Distribution/Deprecated/ViewAsFieldDescr.hs
@@ -81,4 +81,3 @@
 getChoiceByLongFlag _ _ =
   error "Distribution.command.getChoiceByLongFlag: expected a choice option"
 
-
diff --git a/cabal/cabal-install/tests/IntegrationTests2.hs b/cabal/cabal-install/tests/IntegrationTests2.hs
--- a/cabal/cabal-install/tests/IntegrationTests2.hs
+++ b/cabal/cabal-install/tests/IntegrationTests2.hs
@@ -15,7 +15,6 @@
 
 import Distribution.Client.DistDirLayout
 import Distribution.Client.ProjectConfig
-import Distribution.Client.Config (getCabalDir)
 import Distribution.Client.HttpUtils
 import Distribution.Client.TargetSelector hiding (DirActions(..))
 import qualified Distribution.Client.TargetSelector as TS (DirActions(..))
@@ -38,19 +37,20 @@
 import Distribution.Solver.Types.PackageConstraint
          ( PackageProperty(PackagePropertySource) )
 
-import qualified Distribution.Client.CmdBuild   as CmdBuild
-import qualified Distribution.Client.CmdRepl    as CmdRepl
-import qualified Distribution.Client.CmdRun     as CmdRun
-import qualified Distribution.Client.CmdTest    as CmdTest
-import qualified Distribution.Client.CmdBench   as CmdBench
-import qualified Distribution.Client.CmdHaddock as CmdHaddock
-import qualified Distribution.Client.CmdListBin as CmdListBin
+import qualified Distribution.Client.CmdBuild          as CmdBuild
+import qualified Distribution.Client.CmdRepl           as CmdRepl
+import qualified Distribution.Client.CmdRun            as CmdRun
+import qualified Distribution.Client.CmdTest           as CmdTest
+import qualified Distribution.Client.CmdBench          as CmdBench
+import qualified Distribution.Client.CmdHaddock        as CmdHaddock
+import qualified Distribution.Client.CmdListBin        as CmdListBin
 
 import Distribution.Package
 import Distribution.PackageDescription
 import Distribution.InstalledPackageInfo (InstalledPackageInfo)
 import Distribution.Simple.Setup (toFlag, HaddockFlags(..), defaultHaddockFlags)
 import Distribution.Client.Setup (globalCommand)
+import Distribution.Client.Config (loadConfig, SavedConfig(savedGlobalFlags), createDefaultConfigFile)
 import Distribution.Simple.Compiler
 import Distribution.Simple.Command
 import qualified Distribution.Simple.Flag as Flag
@@ -59,9 +59,15 @@
 import Distribution.ModuleName (ModuleName)
 import Distribution.Text
 import Distribution.Utils.Path
+import qualified Distribution.Client.CmdHaddockProject as CmdHaddockProject
+import Distribution.Client.Setup (globalStoreDir)
+import Distribution.Client.GlobalFlags (defaultGlobalFlags)
+import Distribution.Simple.Setup (HaddockProjectFlags(..), defaultHaddockProjectFlags)
 
 import qualified Data.Map as Map
 import qualified Data.Set as Set
+import Data.List (isInfixOf)
+
 import Control.Monad
 import Control.Concurrent (threadDelay)
 import Control.Exception hiding (assert)
@@ -73,6 +79,7 @@
 import Test.Tasty.HUnit
 import Test.Tasty.Options
 import Data.Tagged (Tagged(..))
+import qualified Data.List as L
 
 import qualified Data.ByteString as BS
 import Distribution.Client.GlobalFlags (GlobalFlags, globalNix)
@@ -149,8 +156,12 @@
   , testGroup "Flag tests" $
     [
       testCase "Test Nix Flag" testNixFlags,
+      testCase "Test Config options for commented options" testConfigOptionComments,
       testCase "Test Ignore Project Flag" testIgnoreProjectFlag
     ]
+  , testGroup "haddock-project"
+    [ testCase "dependencies" (testHaddockProjectDependencies config)
+    ]
   ]
 
 testFindProjectRoot :: Assertion
@@ -1678,8 +1689,7 @@
 
 configureProject :: FilePath -> ProjectConfig -> IO ProjDetails
 configureProject testdir cliConfig = do
-    cabalDir <- getCabalDir
-    let cabalDirLayout = defaultCabalDirLayout cabalDir
+    cabalDirLayout <- defaultCabalDirLayout
 
     projectRootDir <- canonicalizePath (basedir </> testdir)
     isexplict      <- doesFileExist (projectRootDir </> "cabal.project")
@@ -1730,6 +1740,7 @@
                          distDirLayout cabalDirLayout
                          projectConfig
                          localPackages
+                         Nothing
 
     return (projDetails,
             elaboratedPlan,
@@ -1956,6 +1967,14 @@
   Just True @=? (fromFlag . globalNix . fromJust $ nixEnabledFlags)
   Just False @=? (fromFlag . globalNix . fromJust $ nixDisabledFlags)
   Nothing @=? (fromFlag . globalNix . fromJust $ nixDefaultFlags)
+
+  -- Config file options
+  trueConfig <- loadConfig verbosity (Flag (basedir </> "nix-config/nix-true"))
+  falseConfig <- loadConfig verbosity (Flag (basedir </> "nix-config/nix-false"))
+
+  Just True @=? (fromFlag . globalNix . savedGlobalFlags $ trueConfig)
+  Just False @=? (fromFlag . globalNix . savedGlobalFlags $ falseConfig)
+
   where
     fromFlag :: Flag Bool -> Maybe Bool
     fromFlag (Flag x) = Just x
@@ -1964,6 +1983,225 @@
     getFlags cui (CommandReadyToGo (mkflags, _)) = Just . mkflags . commandDefaultFlags $ cui
     getFlags _ _ = Nothing
 
+-- Tests whether config options are commented or not
+testConfigOptionComments :: Assertion
+testConfigOptionComments = do
+  _ <- createDefaultConfigFile verbosity [] (basedir </> "config/default-config")
+  defaultConfigFile <- readFile (basedir </> "config/default-config")
+
+  "  url" @=? findLineWith False "url" defaultConfigFile
+  "  -- secure" @=? findLineWith True "secure" defaultConfigFile
+  "  -- root-keys" @=? findLineWith True "root-keys" defaultConfigFile
+  "  -- key-threshold" @=? findLineWith True "key-threshold" defaultConfigFile
+
+  "-- ignore-expiry" @=? findLineWith True "ignore-expiry" defaultConfigFile
+  "-- http-transport" @=? findLineWith True "http-transport" defaultConfigFile
+  "-- nix" @=? findLineWith True "nix" defaultConfigFile
+  "-- store-dir" @=? findLineWith True "store-dir" defaultConfigFile
+  "-- active-repositories" @=? findLineWith True "active-repositories" defaultConfigFile
+  "-- local-no-index-repo" @=? findLineWith True "local-no-index-repo" defaultConfigFile
+  "remote-repo-cache"  @=? findLineWith False "remote-repo-cache" defaultConfigFile
+  "-- logs-dir"  @=? findLineWith True "logs-dir" defaultConfigFile
+  "-- default-user-config" @=? findLineWith True "default-user-config" defaultConfigFile
+  "-- verbose" @=? findLineWith True "verbose" defaultConfigFile
+  "-- compiler" @=? findLineWith True "compiler" defaultConfigFile
+  "-- cabal-file" @=? findLineWith True "cabal-file" defaultConfigFile
+  "-- with-compiler" @=? findLineWith True "with-compiler" defaultConfigFile
+  "-- with-hc-pkg" @=? findLineWith True "with-hc-pkg" defaultConfigFile
+  "-- program-prefix" @=? findLineWith True "program-prefix" defaultConfigFile
+  "-- program-suffix" @=? findLineWith True "program-suffix" defaultConfigFile
+  "-- library-vanilla" @=? findLineWith True "library-vanilla" defaultConfigFile
+  "-- library-profiling" @=? findLineWith True "library-profiling" defaultConfigFile
+  "-- shared" @=? findLineWith True "shared" defaultConfigFile
+  "-- static" @=? findLineWith True "static" defaultConfigFile
+  "-- executable-dynamic" @=? findLineWith True "executable-dynamic" defaultConfigFile
+  "-- executable-static" @=? findLineWith True "executable-static" defaultConfigFile
+  "-- profiling" @=? findLineWith True "profiling" defaultConfigFile
+  "-- executable-profiling" @=? findLineWith True "executable-profiling" defaultConfigFile
+  "-- profiling-detail" @=? findLineWith True "profiling-detail" defaultConfigFile
+  "-- library-profiling-detail" @=? findLineWith True "library-profiling-detail" defaultConfigFile
+  "-- optimization" @=? findLineWith True "optimization" defaultConfigFile
+  "-- debug-info" @=? findLineWith True "debug-info" defaultConfigFile
+  "-- build-info" @=? findLineWith True "build-info" defaultConfigFile
+  "-- library-for-ghci" @=? findLineWith True "library-for-ghci" defaultConfigFile
+  "-- split-sections" @=? findLineWith True "split-sections" defaultConfigFile
+  "-- split-objs" @=? findLineWith True "split-objs" defaultConfigFile
+  "-- executable-stripping" @=? findLineWith True "executable-stripping" defaultConfigFile
+  "-- library-stripping" @=? findLineWith True "library-stripping" defaultConfigFile
+  "-- configure-option" @=? findLineWith True "configure-option" defaultConfigFile
+  "-- user-install"  @=? findLineWith True "user-install" defaultConfigFile
+  "-- package-db"  @=? findLineWith True "package-db" defaultConfigFile
+  "-- flags" @=? findLineWith True "flags" defaultConfigFile
+  "-- extra-include-dirs" @=? findLineWith True "extra-include-dirs" defaultConfigFile
+  "-- deterministic" @=? findLineWith True "deterministic" defaultConfigFile
+  "-- cid" @=? findLineWith True "cid" defaultConfigFile
+  "-- extra-lib-dirs" @=? findLineWith True "extra-lib-dirs" defaultConfigFile
+  "-- extra-lib-dirs-static" @=? findLineWith True "extra-lib-dirs-static" defaultConfigFile
+  "-- extra-framework-dirs" @=? findLineWith True "extra-framework-dirs" defaultConfigFile
+  "-- extra-prog-path"  @=? findLineWith False "extra-prog-path" defaultConfigFile
+  "-- instantiate-with" @=? findLineWith True "instantiate-with" defaultConfigFile
+  "-- tests" @=? findLineWith True "tests" defaultConfigFile
+  "-- coverage" @=? findLineWith True "coverage" defaultConfigFile
+  "-- library-coverage" @=? findLineWith True "library-coverage" defaultConfigFile
+  "-- exact-configuration" @=? findLineWith True "exact-configuration" defaultConfigFile
+  "-- benchmarks" @=? findLineWith True "benchmarks" defaultConfigFile
+  "-- relocatable"  @=? findLineWith True "relocatable" defaultConfigFile
+  "-- response-files" @=? findLineWith True "response-files" defaultConfigFile
+  "-- allow-depending-on-private-libs" @=? findLineWith True "allow-depending-on-private-libs" defaultConfigFile
+  "-- cabal-lib-version" @=? findLineWith True "cabal-lib-version" defaultConfigFile
+  "-- append" @=? findLineWith True "append" defaultConfigFile
+  "-- backup" @=? findLineWith True "backup" defaultConfigFile
+  "-- constraint" @=? findLineWith True "constraint" defaultConfigFile
+  "-- preference" @=? findLineWith True "preference" defaultConfigFile
+  "-- solver"  @=? findLineWith True "solver" defaultConfigFile
+  "-- allow-older"  @=? findLineWith True "allow-older" defaultConfigFile
+  "-- allow-newer"  @=? findLineWith True "allow-newer" defaultConfigFile
+  "-- write-ghc-environment-files" @=? findLineWith True "write-ghc-environment-files" defaultConfigFile
+  "-- documentation"  @=? findLineWith True "documentation" defaultConfigFile
+  "-- doc-index-file"  @=? findLineWith True "doc-index-file" defaultConfigFile
+  "-- only-download"  @=? findLineWith True "only-download" defaultConfigFile
+  "-- target-package-db" @=? findLineWith True "target-package-db" defaultConfigFile
+  "-- max-backjumps"  @=? findLineWith True "max-backjumps" defaultConfigFile
+  "-- reorder-goals"  @=? findLineWith True "reorder-goals" defaultConfigFile
+  "-- count-conflicts"  @=? findLineWith True "count-conflicts" defaultConfigFile
+  "-- fine-grained-conflicts"  @=? findLineWith True "fine-grained-conflicts" defaultConfigFile
+  "-- minimize-conflict-set"  @=? findLineWith True "minimize-conflict-set" defaultConfigFile
+  "-- independent-goals"  @=? findLineWith True "independent-goals" defaultConfigFile
+  "-- prefer-oldest"  @=? findLineWith True "prefer-oldest" defaultConfigFile
+  "-- shadow-installed-packages"  @=? findLineWith True "shadow-installed-packages" defaultConfigFile
+  "-- strong-flags"  @=? findLineWith True "strong-flags" defaultConfigFile
+  "-- allow-boot-library-installs"  @=? findLineWith True "allow-boot-library-installs" defaultConfigFile
+  "-- reject-unconstrained-dependencies"  @=? findLineWith True "reject-unconstrained-dependencies" defaultConfigFile
+  "-- reinstall"  @=? findLineWith True "reinstall" defaultConfigFile
+  "-- avoid-reinstalls"  @=? findLineWith True "avoid-reinstalls" defaultConfigFile
+  "-- force-reinstalls"  @=? findLineWith True "force-reinstalls" defaultConfigFile
+  "-- upgrade-dependencies"  @=? findLineWith True "upgrade-dependencies" defaultConfigFile
+  "-- index-state" @=? findLineWith True "index-state" defaultConfigFile
+  "-- root-cmd" @=? findLineWith True "root-cmd" defaultConfigFile
+  "-- symlink-bindir" @=? findLineWith True "symlink-bindir" defaultConfigFile
+  "build-summary"  @=? findLineWith False "build-summary" defaultConfigFile
+  "-- build-log" @=? findLineWith True "build-log" defaultConfigFile
+  "remote-build-reporting"  @=? findLineWith False "remote-build-reporting" defaultConfigFile
+  "-- report-planning-failure"  @=? findLineWith True "report-planning-failure" defaultConfigFile
+  "-- per-component"  @=? findLineWith True "per-component" defaultConfigFile
+  "-- run-tests" @=? findLineWith True "run-tests" defaultConfigFile
+  "jobs"  @=? findLineWith False "jobs" defaultConfigFile
+  "-- keep-going"  @=? findLineWith True "keep-going" defaultConfigFile
+  "-- offline"  @=? findLineWith True "offline" defaultConfigFile
+  "-- lib" @=? findLineWith True "lib" defaultConfigFile
+  "-- package-env" @=? findLineWith True "package-env" defaultConfigFile
+  "-- overwrite-policy" @=? findLineWith True "overwrite-policy" defaultConfigFile
+  "-- install-method" @=? findLineWith True "install-method" defaultConfigFile
+  "installdir"  @=? findLineWith False "installdir" defaultConfigFile
+  "-- username" @=? findLineWith True "username" defaultConfigFile
+  "-- password" @=? findLineWith True "password" defaultConfigFile
+  "-- password-command" @=? findLineWith True "password-command" defaultConfigFile
+  "-- builddir" @=? findLineWith True "builddir" defaultConfigFile
+
+  "  -- keep-temp-files" @=? findLineWith True "keep-temp-files" defaultConfigFile
+  "  -- hoogle" @=? findLineWith True "hoogle" defaultConfigFile
+  "  -- html" @=? findLineWith True "html" defaultConfigFile
+  "  -- html-location" @=? findLineWith True "html-location" defaultConfigFile
+  "  -- executables" @=? findLineWith True "executables" defaultConfigFile
+  "  -- foreign-libraries" @=? findLineWith True "foreign-libraries" defaultConfigFile
+  "  -- all" @=? findLineWith True "all" defaultConfigFile
+  "  -- internal" @=? findLineWith True "internal" defaultConfigFile
+  "  -- css" @=? findLineWith True "css" defaultConfigFile
+  "  -- hyperlink-source" @=? findLineWith True "hyperlink-source" defaultConfigFile
+  "  -- quickjump" @=? findLineWith True "quickjump" defaultConfigFile
+  "  -- hscolour-css" @=? findLineWith True "hscolour-css" defaultConfigFile
+  "  -- contents-location" @=? findLineWith True "contents-location" defaultConfigFile
+  "  -- index-location" @=? findLineWith True "index-location" defaultConfigFile
+  "  -- base-url" @=? findLineWith True "base-url" defaultConfigFile
+
+  "  -- interactive" @=? findLineWith True "interactive" defaultConfigFile
+  "  -- cabal-version" @=? findLineWith True "cabal-version" defaultConfigFile
+  "  -- license" @=? findLineWith True "license" defaultConfigFile
+  "  -- extra-doc-file" @=? findLineWith True "extra-doc-file" defaultConfigFile
+  "  -- test-dir" @=? findLineWith True "test-dir" defaultConfigFile
+  "  -- language" @=? findLineWith True "language" defaultConfigFile
+  "  -- application-dir" @=? findLineWith True "application-dir" defaultConfigFile
+  "  -- source-dir" @=? findLineWith True "source-dir" defaultConfigFile
+
+  "  -- prefix"  @=? findLineWith True "prefix" defaultConfigFile
+  "  -- bindir"@=? findLineWith True "bindir" defaultConfigFile
+  "  -- libdir" @=? findLineWith True "libdir" defaultConfigFile
+  "  -- libsubdir" @=? findLineWith True "libsubdir" defaultConfigFile
+  "  -- dynlibdir" @=? findLineWith True "dynlibdir" defaultConfigFile
+  "  -- libexecdir" @=? findLineWith True "libexecdir" defaultConfigFile
+  "  -- libexecsubdir" @=? findLineWith True "libexecsubdir" defaultConfigFile
+  "  -- datadir" @=? findLineWith True "datadir" defaultConfigFile
+  "  -- datasubdir" @=? findLineWith True "datasubdir" defaultConfigFile
+  "  -- docdir" @=? findLineWith True "docdir" defaultConfigFile
+  "  -- htmldir" @=? findLineWith True "htmldir" defaultConfigFile
+  "  -- haddockdir" @=? findLineWith True "haddockdir" defaultConfigFile
+  "  -- sysconfdir" @=? findLineWith True "sysconfdir" defaultConfigFile
+
+  "  -- alex-location" @=? findLineWith True "alex-location" defaultConfigFile
+  "  -- ar-location" @=? findLineWith True "ar-location" defaultConfigFile
+  "  -- c2hs-location" @=? findLineWith True "c2hs-location" defaultConfigFile
+  "  -- cpphs-location" @=? findLineWith True "cpphs-location" defaultConfigFile
+  "  -- doctest-location" @=? findLineWith True "doctest-location" defaultConfigFile
+  "  -- gcc-location" @=? findLineWith True "gcc-location" defaultConfigFile
+  "  -- ghc-location" @=? findLineWith True "ghc-location" defaultConfigFile
+  "  -- ghc-pkg-location" @=? findLineWith True "ghc-pkg-location" defaultConfigFile
+  "  -- ghcjs-location" @=? findLineWith True "ghcjs-location" defaultConfigFile
+  "  -- ghcjs-pkg-location" @=? findLineWith True "ghcjs-pkg-location" defaultConfigFile
+  "  -- greencard-location" @=? findLineWith True "greencard-location" defaultConfigFile
+  "  -- haddock-location" @=? findLineWith True "haddock-location" defaultConfigFile
+  "  -- happy-location" @=? findLineWith True "happy-location" defaultConfigFile
+  "  -- haskell-suite-location" @=? findLineWith True "haskell-suite-location" defaultConfigFile
+  "  -- haskell-suite-pkg-location" @=? findLineWith True "haskell-suite-pkg-location" defaultConfigFile
+  "  -- hmake-location" @=? findLineWith True "hmake-location" defaultConfigFile
+  "  -- hpc-location" @=? findLineWith True "hpc-location" defaultConfigFile
+  "  -- hscolour-location" @=? findLineWith True "hscolour-location" defaultConfigFile
+  "  -- jhc-location" @=? findLineWith True "jhc-location" defaultConfigFile
+  "  -- ld-location" @=? findLineWith True "ld-location" defaultConfigFile
+  "  -- pkg-config-location" @=? findLineWith True "pkg-config-location" defaultConfigFile
+  "  -- runghc-location" @=? findLineWith True "runghc-location" defaultConfigFile
+  "  -- strip-location" @=? findLineWith True "strip-location" defaultConfigFile
+  "  -- tar-location" @=? findLineWith True "tar-location" defaultConfigFile
+  "  -- uhc-location" @=? findLineWith True "uhc-location" defaultConfigFile
+
+  "  -- alex-options" @=? findLineWith True "alex-options" defaultConfigFile
+  "  -- ar-options" @=? findLineWith True "ar-options" defaultConfigFile
+  "  -- c2hs-options" @=? findLineWith True "c2hs-options" defaultConfigFile
+  "  -- cpphs-options" @=? findLineWith True "cpphs-options" defaultConfigFile
+  "  -- doctest-options" @=? findLineWith True "doctest-options" defaultConfigFile
+  "  -- gcc-options" @=? findLineWith True "gcc-options" defaultConfigFile
+  "  -- ghc-options" @=? findLineWith True "ghc-options" defaultConfigFile
+  "  -- ghc-pkg-options" @=? findLineWith True "ghc-pkg-options" defaultConfigFile
+  "  -- ghcjs-options" @=? findLineWith True "ghcjs-options" defaultConfigFile
+  "  -- ghcjs-pkg-options" @=? findLineWith True "ghcjs-pkg-options" defaultConfigFile
+  "  -- greencard-options" @=? findLineWith True "greencard-options" defaultConfigFile
+  "  -- haddock-options" @=? findLineWith True "haddock-options" defaultConfigFile
+  "  -- happy-options" @=? findLineWith True "happy-options" defaultConfigFile
+  "  -- haskell-suite-options" @=? findLineWith True "haskell-suite-options" defaultConfigFile
+  "  -- haskell-suite-pkg-options" @=? findLineWith True "haskell-suite-pkg-options" defaultConfigFile
+  "  -- hmake-options" @=? findLineWith True "hmake-options" defaultConfigFile
+  "  -- hpc-options" @=? findLineWith True "hpc-options" defaultConfigFile
+  "  -- hsc2hs-options" @=? findLineWith True "hsc2hs-options" defaultConfigFile
+  "  -- hscolour-options" @=? findLineWith True "hscolour-options" defaultConfigFile
+  "  -- jhc-options" @=? findLineWith True "jhc-options" defaultConfigFile
+  "  -- ld-options" @=? findLineWith True "ld-options" defaultConfigFile
+  "  -- pkg-config-options" @=? findLineWith True "pkg-config-options" defaultConfigFile
+  "  -- runghc-options" @=? findLineWith True "runghc-options" defaultConfigFile
+  "  -- strip-options" @=? findLineWith True "strip-options" defaultConfigFile
+  "  -- tar-options" @=? findLineWith True "tar-options" defaultConfigFile
+  "  -- uhc-options" @=? findLineWith True "uhc-options" defaultConfigFile
+  where
+    -- | Find lines containing a target string.
+    findLineWith :: Bool -> String -> String -> String
+    findLineWith isComment target text
+      | not . null $ findLinesWith isComment target text = removeCommentValue . L.head $ findLinesWith isComment target text
+      | otherwise  = text
+    findLinesWith :: Bool -> String -> String -> [String]
+    findLinesWith isComment target
+      | isComment = filter (isInfixOf (" " ++ target ++ ":")) . lines
+      | otherwise = filter (isInfixOf (target ++ ":")) . lines
+    removeCommentValue :: String -> String
+    removeCommentValue = takeWhile (/= ':')
+
 testIgnoreProjectFlag :: Assertion
 testIgnoreProjectFlag = do
   -- Coverage flag should be false globally by default (~/.cabal folder)
@@ -1979,3 +2217,36 @@
     emptyConfig = mempty
     ignoreSetConfig :: ProjectConfig
     ignoreSetConfig = mempty { projectConfigShared = mempty { projectConfigIgnoreProject = Flag True } }
+
+
+cleanHaddockProject :: FilePath -> IO ()
+cleanHaddockProject testdir = do
+    cleanProject testdir
+    let haddocksdir = basedir </> testdir </> "haddocks"
+    alreadyExists <- doesDirectoryExist haddocksdir
+    when alreadyExists $ removePathForcibly haddocksdir
+    let storedir = basedir </> testdir </> "store"
+    alreadyExists' <- doesDirectoryExist storedir
+    when alreadyExists' $ removePathForcibly storedir
+
+
+testHaddockProjectDependencies :: ProjectConfig -> Assertion
+testHaddockProjectDependencies config = do
+    (_,_,sharedConfig) <- planProject testdir config
+    -- `haddock-project` is only supported by `haddock-2.26.1` and above which is
+    -- shipped with `ghc-9.4`
+    when (compilerVersion (pkgConfigCompiler sharedConfig) > mkVersion [9,4]) $ do
+      let dir = basedir </> testdir
+      cleanHaddockProject testdir
+      withCurrentDirectory dir $ do
+        CmdHaddockProject.haddockProjectAction
+          defaultHaddockProjectFlags { haddockProjectVerbosity = Flag verbosity }
+          ["all"]
+          defaultGlobalFlags { globalStoreDir = Flag "store" }
+
+        let haddock = "haddocks" </> "async" </> "async.haddock"
+        hasHaddock <- doesFileExist haddock
+        unless hasHaddock $ assertFailure ("File `" ++ haddock ++ "` does not exist.")
+      cleanHaddockProject testdir
+  where
+    testdir = "haddock-project/dependencies"
diff --git a/cabal/cabal-install/tests/IntegrationTests2/build/ignore-project/a.cabal b/cabal/cabal-install/tests/IntegrationTests2/build/ignore-project/a.cabal
--- a/cabal/cabal-install/tests/IntegrationTests2/build/ignore-project/a.cabal
+++ b/cabal/cabal-install/tests/IntegrationTests2/build/ignore-project/a.cabal
diff --git a/cabal/cabal-install/tests/IntegrationTests2/config/default-config b/cabal/cabal-install/tests/IntegrationTests2/config/default-config
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-install/tests/IntegrationTests2/config/default-config
@@ -0,0 +1,246 @@
+-- This is the configuration file for the 'cabal' command line tool.
+--
+-- The available configuration options are listed below.
+-- Some of them have default values listed.
+--
+-- Lines (like this one) beginning with '--' are comments.
+-- Be careful with spaces and indentation because they are
+-- used to indicate layout for nested sections.
+--
+-- This config file was generated using the following versions
+-- of Cabal and cabal-install:
+-- Cabal library version: 3.11.0.0
+-- cabal-install version: 3.11
+
+
+repository hackage.haskell.org
+  url: http://hackage.haskell.org/
+  -- secure: True
+  -- root-keys:
+  -- key-threshold: 3
+
+-- ignore-expiry: False
+-- http-transport:
+-- nix:
+-- store-dir:
+-- active-repositories:
+-- local-no-index-repo:
+remote-repo-cache: /home/colton/.cabal/packages
+-- logs-dir: /home/colton/.cabal/logs
+-- default-user-config:
+-- verbose: 1
+-- compiler: ghc
+-- cabal-file:
+-- with-compiler:
+-- with-hc-pkg:
+-- program-prefix: 
+-- program-suffix: 
+-- library-vanilla: True
+-- library-profiling:
+-- shared:
+-- static:
+-- executable-dynamic: False
+-- executable-static: False
+-- profiling:
+-- executable-profiling:
+-- profiling-detail:
+-- library-profiling-detail:
+-- optimization: True
+-- debug-info: False
+-- build-info:
+-- library-for-ghci:
+-- split-sections: False
+-- split-objs: False
+-- executable-stripping:
+-- library-stripping:
+-- configure-option:
+-- user-install: True
+-- package-db:
+-- flags:
+-- extra-include-dirs:
+-- deterministic:
+-- cid:
+-- extra-lib-dirs:
+-- extra-lib-dirs-static:
+-- extra-framework-dirs:
+-- extra-prog-path:
+-- instantiate-with:
+-- tests: False
+-- coverage: False
+-- library-coverage:
+-- exact-configuration: False
+-- benchmarks: False
+-- relocatable: False
+-- response-files:
+-- allow-depending-on-private-libs:
+-- cabal-lib-version:
+-- append:
+-- backup:
+-- constraint:
+-- preference:
+-- solver: modular
+-- allow-older: False
+-- allow-newer: False
+-- write-ghc-environment-files:
+-- documentation: False
+-- doc-index-file: $datadir/doc/$arch-$os-$compiler/index.html
+-- only-download: False
+-- target-package-db:
+-- max-backjumps: 4000
+-- reorder-goals: False
+-- count-conflicts: True
+-- fine-grained-conflicts: True
+-- minimize-conflict-set: False
+-- independent-goals: False
+-- prefer-oldest: False
+-- shadow-installed-packages: False
+-- strong-flags: False
+-- allow-boot-library-installs: False
+-- reject-unconstrained-dependencies: none
+-- reinstall: False
+-- avoid-reinstalls: False
+-- force-reinstalls: False
+-- upgrade-dependencies: False
+-- index-state:
+-- root-cmd:
+-- symlink-bindir:
+build-summary: /home/colton/.cabal/logs/build.log
+-- build-log:
+remote-build-reporting: none
+-- report-planning-failure: False
+-- per-component: True
+-- run-tests:
+jobs: $ncpus
+-- keep-going: False
+-- offline: False
+-- lib: False
+-- package-env:
+-- overwrite-policy:
+-- install-method:
+installdir: /home/colton/.cabal/bin
+-- username:
+-- password:
+-- password-command:
+-- builddir:
+
+haddock
+  -- keep-temp-files: False
+  -- hoogle: False
+  -- html: False
+  -- html-location:
+  -- executables: False
+  -- tests: False
+  -- benchmarks: False
+  -- foreign-libraries: False
+  -- all:
+  -- internal: False
+  -- css:
+  -- hyperlink-source: False
+  -- quickjump: False
+  -- hscolour-css:
+  -- contents-location:
+  -- index-location:
+  -- base-url:
+  -- lib:
+  -- output-dir:
+
+init
+  -- interactive: False
+  -- quiet: False
+  -- no-comments: False
+  -- minimal: False
+  -- cabal-version: 3.0
+  -- license:
+  -- extra-doc-file:
+  -- tests:
+  -- test-dir:
+  -- simple: False
+  -- language: Haskell2010
+  -- application-dir: app
+  -- source-dir: src
+
+install-dirs user
+  -- prefix: /home/colton/.cabal
+  -- bindir: $prefix/bin
+  -- libdir: $prefix/lib
+  -- libsubdir: $abi/$libname
+  -- dynlibdir: $libdir/$abi
+  -- libexecdir: $prefix/libexec
+  -- libexecsubdir: $abi/$pkgid
+  -- datadir: $prefix/share
+  -- datasubdir: $abi/$pkgid
+  -- docdir: $datadir/doc/$abi/$pkgid
+  -- htmldir: $docdir/html
+  -- haddockdir: $htmldir
+  -- sysconfdir: $prefix/etc
+
+install-dirs global
+  -- prefix: /usr/local
+  -- bindir: $prefix/bin
+  -- libdir: $prefix/lib
+  -- libsubdir: $abi/$libname
+  -- dynlibdir: $libdir/$abi
+  -- libexecdir: $prefix/libexec
+  -- libexecsubdir: $abi/$pkgid
+  -- datadir: $prefix/share
+  -- datasubdir: $abi/$pkgid
+  -- docdir: $datadir/doc/$abi/$pkgid
+  -- htmldir: $docdir/html
+  -- haddockdir: $htmldir
+  -- sysconfdir: $prefix/etc
+
+program-locations
+  -- alex-location:
+  -- ar-location:
+  -- c2hs-location:
+  -- cpphs-location:
+  -- doctest-location:
+  -- gcc-location:
+  -- ghc-location:
+  -- ghc-pkg-location:
+  -- ghcjs-location:
+  -- ghcjs-pkg-location:
+  -- greencard-location:
+  -- haddock-location:
+  -- happy-location:
+  -- haskell-suite-location:
+  -- haskell-suite-pkg-location:
+  -- hmake-location:
+  -- hpc-location:
+  -- hsc2hs-location:
+  -- hscolour-location:
+  -- jhc-location:
+  -- ld-location:
+  -- pkg-config-location:
+  -- runghc-location:
+  -- strip-location:
+  -- tar-location:
+  -- uhc-location:
+
+program-default-options
+  -- alex-options:
+  -- ar-options:
+  -- c2hs-options:
+  -- cpphs-options:
+  -- doctest-options:
+  -- gcc-options:
+  -- ghc-options:
+  -- ghc-pkg-options:
+  -- ghcjs-options:
+  -- ghcjs-pkg-options:
+  -- greencard-options:
+  -- haddock-options:
+  -- happy-options:
+  -- haskell-suite-options:
+  -- haskell-suite-pkg-options:
+  -- hmake-options:
+  -- hpc-options:
+  -- hsc2hs-options:
+  -- hscolour-options:
+  -- jhc-options:
+  -- ld-options:
+  -- pkg-config-options:
+  -- runghc-options:
+  -- strip-options:
+  -- tar-options:
+  -- uhc-options:
diff --git a/cabal/cabal-install/tests/IntegrationTests2/haddock-project/dependencies/a.cabal b/cabal/cabal-install/tests/IntegrationTests2/haddock-project/dependencies/a.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-install/tests/IntegrationTests2/haddock-project/dependencies/a.cabal
@@ -0,0 +1,10 @@
+name: a
+version: 0.1.0.0
+build-type: Simple
+cabal-version: >= 1.10
+
+library
+    exposed-modules:  MyLib
+    build-depends:    base, async
+    hs-source-dirs:   src
+    default-language: Haskell2010
diff --git a/cabal/cabal-install/tests/IntegrationTests2/haddock-project/dependencies/cabal.project b/cabal/cabal-install/tests/IntegrationTests2/haddock-project/dependencies/cabal.project
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-install/tests/IntegrationTests2/haddock-project/dependencies/cabal.project
@@ -0,0 +1,8 @@
+packages: .
+-- `jobs` is necessary to use `InternalMethod :: SetupMethod`.
+jobs: 1
+
+documentation: True
+
+package async
+  documentation: True
diff --git a/cabal/cabal-install/tests/IntegrationTests2/haddock-project/dependencies/src/MyLib.hs b/cabal/cabal-install/tests/IntegrationTests2/haddock-project/dependencies/src/MyLib.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-install/tests/IntegrationTests2/haddock-project/dependencies/src/MyLib.hs
@@ -0,0 +1,6 @@
+module MyLib (someFunc) where
+
+import Control.Concurrent.Async
+
+someFunc :: IO (Async ())
+someFunc = async (return ())
diff --git a/cabal/cabal-install/tests/IntegrationTests2/nix-config/nix-false b/cabal/cabal-install/tests/IntegrationTests2/nix-config/nix-false
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-install/tests/IntegrationTests2/nix-config/nix-false
@@ -0,0 +1,229 @@
+-- This is the configuration file for the 'cabal' command line tool.
+--
+-- The available configuration options are listed below.
+-- Some of them have default values listed.
+--
+-- Lines (like this one) beginning with '--' are comments.
+-- Be careful with spaces and indentation because they are
+-- used to indicate layout for nested sections.
+--
+-- This config file was generated using the following versions
+-- of Cabal and cabal-install:
+-- Cabal library version: 3.6.2.0
+-- cabal-install version: 3.6.2.0
+
+
+repository hackage.haskell.org
+  url: http://hackage.haskell.org/
+  -- secure: True
+  -- root-keys:
+  -- key-threshold: 3
+
+-- default-user-config:
+-- ignore-expiry: False
+-- http-transport:
+nix: False
+-- local-no-index-repo:
+
+--debug-info: 1
+-- store-dir:
+-- active-repositories:
+-- verbose: 1
+-- compiler: ghc
+-- cabal-file:
+-- with-compiler:
+-- with-hc-pkg:
+-- program-prefix: 
+-- program-suffix: 
+-- library-vanilla: True
+-- library-profiling:
+-- shared:
+-- static:
+-- executable-dynamic: False
+-- executable-static: False
+-- profiling:
+-- executable-profiling:
+-- profiling-detail:
+-- library-profiling-detail:
+-- optimization: True
+-- debug-info: False
+-- library-for-ghci:
+-- split-sections: False
+-- split-objs: False
+-- executable-stripping:
+-- library-stripping:
+-- configure-option:
+-- user-install: True
+-- package-db:
+-- flags:
+-- extra-include-dirs:
+-- deterministic:
+-- cid:
+-- extra-lib-dirs:
+-- extra-framework-dirs:
+-- instantiate-with:
+-- tests: False
+-- coverage: False
+-- library-coverage:
+-- exact-configuration: False
+-- benchmarks: False
+-- relocatable: False
+-- response-files:
+-- allow-depending-on-private-libs:
+-- cabal-lib-version:
+-- constraint:
+-- preference:
+-- solver: modular
+-- allow-older: False
+-- allow-newer: False
+-- write-ghc-environment-files:
+-- documentation: False
+-- doc-index-file: $datadir/doc/$arch-$os-$compiler/index.html
+-- only-download: False
+-- target-package-db:
+-- max-backjumps: 4000
+-- reorder-goals: False
+-- count-conflicts: True
+-- fine-grained-conflicts: True
+-- minimize-conflict-set: False
+-- independent-goals: False
+-- shadow-installed-packages: False
+-- strong-flags: False
+-- allow-boot-library-installs: False
+-- reject-unconstrained-dependencies: none
+-- reinstall: False
+-- avoid-reinstalls: False
+-- force-reinstalls: False
+-- upgrade-dependencies: False
+-- index-state:
+-- root-cmd:
+-- symlink-bindir:
+-- build-log:
+remote-build-reporting: none
+-- report-planning-failure: False
+-- per-component: True
+-- one-shot: False
+-- run-tests:
+jobs: $ncpus
+-- keep-going: False
+-- offline: False
+-- lib: False
+-- package-env:
+-- overwrite-policy:
+-- install-method:
+-- username:
+-- password:
+-- password-command:
+-- builddir:
+
+haddock
+  -- keep-temp-files: False
+  -- hoogle: False
+  -- html: False
+  -- html-location:
+  -- executables: False
+  -- tests: False
+  -- benchmarks: False
+  -- foreign-libraries: False
+  -- all:
+  -- internal: False
+  -- css:
+  -- hyperlink-source: False
+  -- quickjump: False
+  -- hscolour-css:
+  -- contents-location:
+
+init
+  -- interactive: False
+  -- cabal-version: 2.4
+  -- license:
+  -- tests:
+  -- test-dir:
+  -- language: Haskell2010
+  -- application-dir: app
+  -- source-dir: src
+
+install-dirs user
+  -- bindir: $prefix/bin
+  -- libdir: $prefix/lib
+  -- libsubdir: $abi/$libname
+  -- dynlibdir: $libdir/$abi
+  -- libexecdir: $prefix/libexec
+  -- libexecsubdir: $abi/$pkgid
+  -- datadir: $prefix/share
+  -- datasubdir: $abi/$pkgid
+  -- docdir: $datadir/doc/$abi/$pkgid
+  -- htmldir: $docdir/html
+  -- haddockdir: $htmldir
+  -- sysconfdir: $prefix/etc
+
+install-dirs global
+  -- prefix: /usr/local
+  -- bindir: $prefix/bin
+  -- libdir: $prefix/lib
+  -- libsubdir: $abi/$libname
+  -- dynlibdir: $libdir/$abi
+  -- libexecdir: $prefix/libexec
+  -- libexecsubdir: $abi/$pkgid
+  -- datadir: $prefix/share
+  -- datasubdir: $abi/$pkgid
+  -- docdir: $datadir/doc/$abi/$pkgid
+  -- htmldir: $docdir/html
+  -- haddockdir: $htmldir
+  -- sysconfdir: $prefix/etc
+
+program-locations
+  -- alex-location:
+  -- ar-location:
+  -- c2hs-location:
+  -- cpphs-location:
+  -- doctest-location:
+  -- gcc-location:
+  -- ghc-location:
+  -- ghc-pkg-location:
+  -- ghcjs-location:
+  -- ghcjs-pkg-location:
+  -- greencard-location:
+  -- haddock-location:
+  -- happy-location:
+  -- haskell-suite-location:
+  -- haskell-suite-pkg-location:
+  -- hmake-location:
+  -- hpc-location:
+  -- hsc2hs-location:
+  -- hscolour-location:
+  -- jhc-location:
+  -- ld-location:
+  -- pkg-config-location:
+  -- runghc-location:
+  -- strip-location:
+  -- tar-location:
+  -- uhc-location:
+
+program-default-options
+  -- alex-options:
+  -- ar-options:
+  -- c2hs-options:
+  -- cpphs-options:
+  -- doctest-options:
+  -- gcc-options:
+  -- ghc-options:
+  -- ghc-pkg-options:
+  -- ghcjs-options:
+  -- ghcjs-pkg-options:
+  -- greencard-options:
+  -- haddock-options:
+  -- happy-options:
+  -- haskell-suite-options:
+  -- haskell-suite-pkg-options:
+  -- hmake-options:
+  -- hpc-options:
+  -- hsc2hs-options:
+  -- hscolour-options:
+  -- jhc-options:
+  -- ld-options:
+  -- pkg-config-options:
+  -- runghc-options:
+  -- strip-options:
+  -- tar-options:
+  -- uhc-options:
diff --git a/cabal/cabal-install/tests/IntegrationTests2/nix-config/nix-true b/cabal/cabal-install/tests/IntegrationTests2/nix-config/nix-true
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-install/tests/IntegrationTests2/nix-config/nix-true
@@ -0,0 +1,229 @@
+-- This is the configuration file for the 'cabal' command line tool.
+--
+-- The available configuration options are listed below.
+-- Some of them have default values listed.
+--
+-- Lines (like this one) beginning with '--' are comments.
+-- Be careful with spaces and indentation because they are
+-- used to indicate layout for nested sections.
+--
+-- This config file was generated using the following versions
+-- of Cabal and cabal-install:
+-- Cabal library version: 3.6.2.0
+-- cabal-install version: 3.6.2.0
+
+
+repository hackage.haskell.org
+  url: http://hackage.haskell.org/
+  -- secure: True
+  -- root-keys:
+  -- key-threshold: 3
+
+-- default-user-config:
+-- ignore-expiry: False
+-- http-transport:
+nix: True
+-- local-no-index-repo:
+
+--debug-info: 1
+-- store-dir:
+-- active-repositories:
+-- verbose: 1
+-- compiler: ghc
+-- cabal-file:
+-- with-compiler:
+-- with-hc-pkg:
+-- program-prefix: 
+-- program-suffix: 
+-- library-vanilla: True
+-- library-profiling:
+-- shared:
+-- static:
+-- executable-dynamic: False
+-- executable-static: False
+-- profiling:
+-- executable-profiling:
+-- profiling-detail:
+-- library-profiling-detail:
+-- optimization: True
+-- debug-info: False
+-- library-for-ghci:
+-- split-sections: False
+-- split-objs: False
+-- executable-stripping:
+-- library-stripping:
+-- configure-option:
+-- user-install: True
+-- package-db:
+-- flags:
+-- extra-include-dirs:
+-- deterministic:
+-- cid:
+-- extra-lib-dirs:
+-- extra-framework-dirs:
+-- instantiate-with:
+-- tests: False
+-- coverage: False
+-- library-coverage:
+-- exact-configuration: False
+-- benchmarks: False
+-- relocatable: False
+-- response-files:
+-- allow-depending-on-private-libs:
+-- cabal-lib-version:
+-- constraint:
+-- preference:
+-- solver: modular
+-- allow-older: False
+-- allow-newer: False
+-- write-ghc-environment-files:
+-- documentation: False
+-- doc-index-file: $datadir/doc/$arch-$os-$compiler/index.html
+-- only-download: False
+-- target-package-db:
+-- max-backjumps: 4000
+-- reorder-goals: False
+-- count-conflicts: True
+-- fine-grained-conflicts: True
+-- minimize-conflict-set: False
+-- independent-goals: False
+-- shadow-installed-packages: False
+-- strong-flags: False
+-- allow-boot-library-installs: False
+-- reject-unconstrained-dependencies: none
+-- reinstall: False
+-- avoid-reinstalls: False
+-- force-reinstalls: False
+-- upgrade-dependencies: False
+-- index-state:
+-- root-cmd:
+-- symlink-bindir:
+-- build-log:
+remote-build-reporting: none
+-- report-planning-failure: False
+-- per-component: True
+-- one-shot: False
+-- run-tests:
+jobs: $ncpus
+-- keep-going: False
+-- offline: False
+-- lib: False
+-- package-env:
+-- overwrite-policy:
+-- install-method:
+-- username:
+-- password:
+-- password-command:
+-- builddir:
+
+haddock
+  -- keep-temp-files: False
+  -- hoogle: False
+  -- html: False
+  -- html-location:
+  -- executables: False
+  -- tests: False
+  -- benchmarks: False
+  -- foreign-libraries: False
+  -- all:
+  -- internal: False
+  -- css:
+  -- hyperlink-source: False
+  -- quickjump: False
+  -- hscolour-css:
+  -- contents-location:
+
+init
+  -- interactive: False
+  -- cabal-version: 2.4
+  -- license:
+  -- tests:
+  -- test-dir:
+  -- language: Haskell2010
+  -- application-dir: app
+  -- source-dir: src
+
+install-dirs user
+  -- bindir: $prefix/bin
+  -- libdir: $prefix/lib
+  -- libsubdir: $abi/$libname
+  -- dynlibdir: $libdir/$abi
+  -- libexecdir: $prefix/libexec
+  -- libexecsubdir: $abi/$pkgid
+  -- datadir: $prefix/share
+  -- datasubdir: $abi/$pkgid
+  -- docdir: $datadir/doc/$abi/$pkgid
+  -- htmldir: $docdir/html
+  -- haddockdir: $htmldir
+  -- sysconfdir: $prefix/etc
+
+install-dirs global
+  -- prefix: /usr/local
+  -- bindir: $prefix/bin
+  -- libdir: $prefix/lib
+  -- libsubdir: $abi/$libname
+  -- dynlibdir: $libdir/$abi
+  -- libexecdir: $prefix/libexec
+  -- libexecsubdir: $abi/$pkgid
+  -- datadir: $prefix/share
+  -- datasubdir: $abi/$pkgid
+  -- docdir: $datadir/doc/$abi/$pkgid
+  -- htmldir: $docdir/html
+  -- haddockdir: $htmldir
+  -- sysconfdir: $prefix/etc
+
+program-locations
+  -- alex-location:
+  -- ar-location:
+  -- c2hs-location:
+  -- cpphs-location:
+  -- doctest-location:
+  -- gcc-location:
+  -- ghc-location:
+  -- ghc-pkg-location:
+  -- ghcjs-location:
+  -- ghcjs-pkg-location:
+  -- greencard-location:
+  -- haddock-location:
+  -- happy-location:
+  -- haskell-suite-location:
+  -- haskell-suite-pkg-location:
+  -- hmake-location:
+  -- hpc-location:
+  -- hsc2hs-location:
+  -- hscolour-location:
+  -- jhc-location:
+  -- ld-location:
+  -- pkg-config-location:
+  -- runghc-location:
+  -- strip-location:
+  -- tar-location:
+  -- uhc-location:
+
+program-default-options
+  -- alex-options:
+  -- ar-options:
+  -- c2hs-options:
+  -- cpphs-options:
+  -- doctest-options:
+  -- gcc-options:
+  -- ghc-options:
+  -- ghc-pkg-options:
+  -- ghcjs-options:
+  -- ghcjs-pkg-options:
+  -- greencard-options:
+  -- haddock-options:
+  -- happy-options:
+  -- haskell-suite-options:
+  -- haskell-suite-pkg-options:
+  -- hmake-options:
+  -- hpc-options:
+  -- hsc2hs-options:
+  -- hscolour-options:
+  -- jhc-options:
+  -- ld-options:
+  -- pkg-config-options:
+  -- runghc-options:
+  -- strip-options:
+  -- tar-options:
+  -- uhc-options:
diff --git a/cabal/cabal-install/tests/IntegrationTests2/targets/simple/p.cabal b/cabal/cabal-install/tests/IntegrationTests2/targets/simple/p.cabal
--- a/cabal/cabal-install/tests/IntegrationTests2/targets/simple/p.cabal
+++ b/cabal/cabal-install/tests/IntegrationTests2/targets/simple/p.cabal
diff --git a/cabal/cabal-install/tests/IntegrationTests2/targets/variety/p.cabal b/cabal/cabal-install/tests/IntegrationTests2/targets/variety/p.cabal
--- a/cabal/cabal-install/tests/IntegrationTests2/targets/variety/p.cabal
+++ b/cabal/cabal-install/tests/IntegrationTests2/targets/variety/p.cabal
@@ -17,7 +17,7 @@
 
 test-suite a-testsuite
   main-is: Test.hs
-  other-modules: AModule  
+  other-modules: AModule
 
 benchmark a-benchmark
   type: exitcode-stdio-1.0
diff --git a/cabal/cabal-install/tests/UnitTests/Distribution/Client/ArbitraryInstances.hs b/cabal/cabal-install/tests/UnitTests/Distribution/Client/ArbitraryInstances.hs
--- a/cabal/cabal-install/tests/UnitTests/Distribution/Client/ArbitraryInstances.hs
+++ b/cabal/cabal-install/tests/UnitTests/Distribution/Client/ArbitraryInstances.hs
@@ -43,8 +43,8 @@
 
 import Data.Coerce                      (Coercible, coerce)
 import Network.URI                      (URI (..), URIAuth (..), isUnreserved)
-import Test.QuickCheck hiding (shrinkBoundedEnum)
-import Test.QuickCheck.GenericArbitrary
+import Test.QuickCheck
+import Test.QuickCheck.GenericArbitrary (genericArbitrary)
 import Test.QuickCheck.Instances.Cabal ()
 
 -- note: there are plenty of instances defined in ProjectConfig test file.
@@ -106,11 +106,6 @@
 -------------------------------------------------------------------------------
 -- cabal-install (and Cabal) types
 -------------------------------------------------------------------------------
-
-shrinkBoundedEnum :: (Eq a, Enum a, Bounded a) => a -> [a]
-shrinkBoundedEnum x
-    | x == minBound = []
-    | otherwise     = [pred x]
 
 adjustSize :: (Int -> Int) -> Gen a -> Gen a
 adjustSize adjust gen = sized (\n -> resize (adjust n) gen)
diff --git a/cabal/cabal-install/tests/UnitTests/Distribution/Client/Configure.hs b/cabal/cabal-install/tests/UnitTests/Distribution/Client/Configure.hs
--- a/cabal/cabal-install/tests/UnitTests/Distribution/Client/Configure.hs
+++ b/cabal/cabal-install/tests/UnitTests/Distribution/Client/Configure.hs
@@ -18,26 +18,26 @@
 import Distribution.Simple.Flag
 
 tests :: [TestTree]
-tests = 
+tests =
     [ configureTests
     ]
 
 configureTests :: TestTree
 configureTests = testGroup "Configure tests"
     [ testCase "New config" $ do
-        let flags = (defaultNixStyleFlags ()) 
+        let flags = (defaultNixStyleFlags ())
               { configFlags = mempty
                   { configOptimization = Flag MaximumOptimisation
                   , configVerbosity = Flag silent
                   }
               }
         projConfig <- configureAction' flags [] defaultGlobalFlags
-        
+
         Flag MaximumOptimisation @=?
           (packageConfigOptimization . projectConfigLocalPackages $ snd projConfig)
 
     , testCase "Replacement + new config" $ do
-        let flags = (defaultNixStyleFlags ()) 
+        let flags = (defaultNixStyleFlags ())
               { configExFlags = mempty
                   { configAppend = Flag True }
               , configFlags = mempty
@@ -51,9 +51,9 @@
 
         Flag NoOptimisation @=? packageConfigOptimization projectConfigLocalPackages
         Flag silent         @=? projectConfigVerbosity projectConfigBuildOnly
-    
+
     , testCase "Old + new config" $ do
-        let flags = (defaultNixStyleFlags ()) 
+        let flags = (defaultNixStyleFlags ())
               { configExFlags = mempty
                   { configAppend = Flag True }
               , configFlags = mempty
@@ -65,9 +65,9 @@
 
         Flag MaximumOptimisation @=? packageConfigOptimization projectConfigLocalPackages
         Flag silent              @=? projectConfigVerbosity projectConfigBuildOnly
-    
+
     , testCase "Old + new config, no appending" $ do
-        let flags = (defaultNixStyleFlags ()) 
+        let flags = (defaultNixStyleFlags ())
               { configFlags = mempty
                   { configVerbosity = Flag silent }
               , projectFlags = mempty
@@ -77,9 +77,9 @@
 
         NoFlag      @=? packageConfigOptimization projectConfigLocalPackages
         Flag silent @=? projectConfigVerbosity projectConfigBuildOnly
-    
+
     , testCase "Old + new config, backup check" $ do
-        let flags = (defaultNixStyleFlags ()) 
+        let flags = (defaultNixStyleFlags ())
               { configFlags = mempty
                   { configVerbosity = Flag silent }
               , projectFlags = mempty
@@ -88,7 +88,7 @@
             backup = projectFile <.> "local~"
 
         exists <- doesFileExist backup
-        when exists $ 
+        when exists $
           removeFile backup
 
         _ <- configureAction' flags [] defaultGlobalFlags
diff --git a/cabal/cabal-install/tests/UnitTests/Distribution/Client/Get.hs b/cabal/cabal-install/tests/UnitTests/Distribution/Client/Get.hs
--- a/cabal/cabal-install/tests/UnitTests/Distribution/Client/Get.hs
+++ b/cabal/cabal-install/tests/UnitTests/Distribution/Client/Get.hs
@@ -39,7 +39,7 @@
   , askOption $ \(RunNetworkTests doRunNetTests) ->
     testGroup "forkPackages, network tests" $
     includeTestsIf doRunNetTests $
-    [ testCase "git clone"                   testNetworkGitClone 
+    [ testCase "git clone"                   testNetworkGitClone
     ]
   ]
   where
@@ -62,7 +62,7 @@
 testNoRepos :: Assertion
 testNoRepos = do
     e <- assertException $
-           clonePackagesFromSourceRepo verbosity "." Nothing pkgrepos
+           clonePackagesFromSourceRepo verbosity "." Nothing [] pkgrepos
     e @?= ClonePackageNoSourceRepos pkgidfoo
   where
     pkgrepos = [(pkgidfoo, [])]
@@ -71,7 +71,7 @@
 testNoReposOfKind :: Assertion
 testNoReposOfKind = do
     e <- assertException $
-           clonePackagesFromSourceRepo verbosity "." repokind pkgrepos
+           clonePackagesFromSourceRepo verbosity "." repokind [] pkgrepos
     e @?= ClonePackageNoSourceReposOfKind pkgidfoo repokind
   where
     pkgrepos = [(pkgidfoo, [repo])]
@@ -82,7 +82,7 @@
 testNoRepoType :: Assertion
 testNoRepoType = do
     e <- assertException $
-           clonePackagesFromSourceRepo verbosity "." Nothing pkgrepos
+           clonePackagesFromSourceRepo verbosity "." Nothing []pkgrepos
     e @?= ClonePackageNoRepoType pkgidfoo repo
   where
     pkgrepos = [(pkgidfoo, [repo])]
@@ -92,7 +92,7 @@
 testUnsupportedRepoType :: Assertion
 testUnsupportedRepoType = do
     e <- assertException $
-           clonePackagesFromSourceRepo verbosity "." Nothing pkgrepos
+           clonePackagesFromSourceRepo verbosity "." Nothing [] pkgrepos
     e @?= ClonePackageUnsupportedRepoType pkgidfoo repo' repotype
   where
     pkgrepos = [(pkgidfoo, [repo])]
@@ -114,7 +114,7 @@
 testNoRepoLocation :: Assertion
 testNoRepoLocation = do
     e <- assertException $
-           clonePackagesFromSourceRepo verbosity "." Nothing pkgrepos
+           clonePackagesFromSourceRepo verbosity "." Nothing [] pkgrepos
     e @?= ClonePackageNoRepoLocation pkgidfoo repo
   where
     pkgrepos = [(pkgidfoo, [repo])]
@@ -133,7 +133,7 @@
            e' <- test requestedRepoType (reverse pkgrepos)
            e' @?= ClonePackageNoRepoType pkgidfoo expectedRepo
       | let test rt rs = assertException $
-                           clonePackagesFromSourceRepo verbosity "." rt rs
+                           clonePackagesFromSourceRepo verbosity "." rt [] rs
       , (requestedRepoType, expectedRepo) <- cases
       ]
   where
@@ -154,14 +154,14 @@
       let pkgdir = tmpdir </> "foo"
       createDirectory pkgdir
       e1 <- assertException $
-              clonePackagesFromSourceRepo verbosity tmpdir Nothing pkgrepos
+              clonePackagesFromSourceRepo verbosity tmpdir Nothing [] pkgrepos
       e1 @?= ClonePackageDestinationExists pkgidfoo pkgdir True {- isdir -}
 
       removeDirectory pkgdir
 
       writeFile pkgdir ""
       e2 <- assertException $
-              clonePackagesFromSourceRepo verbosity tmpdir Nothing pkgrepos
+              clonePackagesFromSourceRepo verbosity tmpdir Nothing [] pkgrepos
       e2 @?= ClonePackageDestinationExists pkgidfoo pkgdir False {- isfile -}
   where
     pkgrepos = [(pkgidfoo, [repo])]
@@ -189,7 +189,7 @@
                      }
           pkgrepos = [(pkgidfoo, [repo])]
       e1 <- assertException $
-              clonePackagesFromSourceRepo verbosity tmpdir Nothing pkgrepos
+              clonePackagesFromSourceRepo verbosity tmpdir Nothing [] pkgrepos
       e1 @?= ClonePackageFailedWithExitCode pkgidfoo repo' "git" (ExitFailure 128)
 
 
@@ -200,7 +200,7 @@
                     repoType     = Just (KnownRepoType Git),
                     repoLocation = Just "https://github.com/haskell/zlib.git"
                   }
-      clonePackagesFromSourceRepo verbosity tmpdir Nothing
+      clonePackagesFromSourceRepo verbosity tmpdir Nothing []
                                   [(mkpkgid "zlib1", [repo1])]
       assertFileContains (tmpdir </> "zlib1/zlib.cabal") ["name:", "zlib"]
 
@@ -208,7 +208,7 @@
                     repoType     = Just (KnownRepoType Git),
                     repoLocation = Just (tmpdir </> "zlib1")
                   }
-      clonePackagesFromSourceRepo verbosity tmpdir Nothing
+      clonePackagesFromSourceRepo verbosity tmpdir Nothing []
                                   [(mkpkgid "zlib2", [repo2])]
       assertFileContains (tmpdir </> "zlib2/zlib.cabal") ["name:", "zlib"]
 
@@ -217,7 +217,7 @@
                     repoLocation = Just (tmpdir </> "zlib1"),
                     repoTag      = Just "0.5.0.0"
                   }
-      clonePackagesFromSourceRepo verbosity tmpdir Nothing
+      clonePackagesFromSourceRepo verbosity tmpdir Nothing []
                                   [(mkpkgid "zlib3", [repo3])]
       assertFileContains (tmpdir </> "zlib3/zlib.cabal") ["version:", "0.5.0.0"]
   where
@@ -234,7 +234,7 @@
     case r of
       Left e  -> return e
       Right _ -> assertFailure $ "expected exception of type "
-                              ++ show (typeOf (undefined :: e)) 
+                              ++ show (typeOf (undefined :: e))
 
 
 -- | Expect that one line in a file matches exactly the given words (i.e. at
diff --git a/cabal/cabal-install/tests/UnitTests/Distribution/Client/IndexUtils.hs b/cabal/cabal-install/tests/UnitTests/Distribution/Client/IndexUtils.hs
--- a/cabal/cabal-install/tests/UnitTests/Distribution/Client/IndexUtils.hs
+++ b/cabal/cabal-install/tests/UnitTests/Distribution/Client/IndexUtils.hs
diff --git a/cabal/cabal-install/tests/UnitTests/Distribution/Client/Init/FileCreators.hs b/cabal/cabal-install/tests/UnitTests/Distribution/Client/Init/FileCreators.hs
--- a/cabal/cabal-install/tests/UnitTests/Distribution/Client/Init/FileCreators.hs
+++ b/cabal/cabal-install/tests/UnitTests/Distribution/Client/Init/FileCreators.hs
@@ -18,7 +18,7 @@
 import Distribution.Simple.PackageIndex
 import Distribution.Verbosity
 
-tests 
+tests
     :: Verbosity
     -> InitFlags
     -> Compiler
@@ -44,7 +44,9 @@
               }
             inputs =
               -- createProject stuff
-              [ "True"
+              [ "Foobar"
+              , "foobar@qux.com"
+              , "True"
               , "[\"quxTest/Main.hs\"]"
               -- writeProject stuff
               -- writeLicense
@@ -82,6 +84,6 @@
 
           Left (BreakException ex) -> assertFailure $ show ex
           Right _ -> return ()
-        
+
 
     ]
diff --git a/cabal/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs b/cabal/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs
--- a/cabal/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs
+++ b/cabal/cabal-install/tests/UnitTests/Distribution/Client/Init/Golden.hs
@@ -215,7 +215,7 @@
       (goldenTest "test-build-tools-with-comments.golden") $
         let opts = WriteOpts False False False v pkgDir Library pkgName defaultCabalVersion
         in runGoldenTest opts testArgs (emptyFlags {buildTools = Flag ["happy"]})
-    
+
     , goldenVsString "Standalone tests, empty flags, not simple, no options, no comments"
       (goldenTest "standalone-test-no-comments.golden") $
         let opts = WriteOpts False False True v pkgDir TestSuite pkgName defaultCabalVersion
@@ -256,7 +256,7 @@
     , goldenVsString "Library, empty flags, not simple, no comments + no minimal"
       (goldenCabal "cabal-lib-no-comments.golden") $
         runGoldenTest (libProjArgs "N") emptyFlags
-    
+
     , goldenVsString "Test suite, empty flags, not simple, with comments + no minimal"
       (goldenCabal "cabal-test-suite-with-comments.golden") $
         runGoldenTest (testProjArgs "Y") emptyFlags
@@ -286,12 +286,12 @@
               testStanza = mkTestStanza opts $ testTarget {_testDependencies = mangleBaseDep testTarget _testDependencies}
 
           mkStanza $ pkgFields ++ [commonStanza, libStanza, testStanza]
-        
+
         (Right (ProjectSettings opts pkgDesc Nothing Nothing (Just testTarget), _)) -> do
           let pkgFields = mkPkgDescription opts pkgDesc
               commonStanza = mkCommonStanza opts
               testStanza = mkTestStanza opts $ testTarget {_testDependencies = mangleBaseDep testTarget _testDependencies}
-          
+
           mkStanza $ pkgFields ++ [commonStanza, testStanza]
 
         (Right (ProjectSettings _ _ l e t, _)) -> assertFailure $
diff --git a/cabal/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs b/cabal/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs
--- a/cabal/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs
+++ b/cabal/cabal-install/tests/UnitTests/Distribution/Client/Init/Interactive.hs
@@ -324,7 +324,7 @@
             exe  @?= Nothing
             test @?! Nothing
           Left e -> assertFailure $ show e
-    
+
     , testCase "Check the interactive library workflow" $ do
         let inputs = fromList
               -- package type
@@ -931,14 +931,13 @@
             , "Haskell2022"
             ]
         , testSimplePrompt "Invalid language"
-            (`languagePrompt` "test") Haskell2010
+            (`languagePrompt` "test") (UnknownLanguage "Lang_TS!")
             [ "4"
             , "Lang_TS!"
-            , "1"
             ]
         ]
     , testGroup "Check srcDirsPrompt output"
-        [ testNumberedPrompt "Soruce dirs indices" srcDirsPrompt
+        [ testNumberedPrompt "Source dirs indices" srcDirsPrompt
             [[defaultSourceDir], ["lib"], ["src-lib"]]
         , testSimplePrompt "Other source dir"
             srcDirsPrompt ["src"]
diff --git a/cabal/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs b/cabal/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs
--- a/cabal/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs
+++ b/cabal/cabal-install/tests/UnitTests/Distribution/Client/Init/NonInteractive.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE LambdaCase #-}
 module UnitTests.Distribution.Client.Init.NonInteractive
   ( tests
   ) where
@@ -24,6 +25,8 @@
 import qualified Data.Set as Set
 import Distribution.Client.Init.Utils (mkPackageNameDep, mkStringyDep)
 import Distribution.FieldGrammar.Newtypes
+import Distribution.Simple.Command
+import Distribution.Client.Setup (initCommand)
 
 tests
     :: Verbosity
@@ -43,6 +46,9 @@
     , testGroup "non-interactive tests"
       [ nonInteractiveTests pkgIx srcDb comp
       ]
+    , testGroup "cli parser tests"
+      [ cliListParserTests
+      ]
     ]
 
 driverFunctionTest
@@ -67,7 +73,9 @@
               , dependencies = Flag []
               }
             inputs = NEL.fromList
-              [ "True"
+              ["Foobar"
+              , "foobar@qux.com"
+              , "True"
               , "[\"quxTest/Main.hs\"]"
               ]
 
@@ -143,8 +151,11 @@
               , dependencies = Flag []
               }
             inputs = NEL.fromList
+
+              [ "Foobar"
+              , "foobar@qux.com"
               -- extra sources
-              [ "[\"CHANGELOG.md\"]"
+              , "[\"CHANGELOG.md\"]"
               -- lib other modules
               , "False"
               -- exe other modules
@@ -331,7 +342,7 @@
               , "[\"test/Main.hs\", \"test/Foo.hs\", \"test/bar.y\"]"
               ]
 
-        case (_runPrompt $ createProject comp silent pkgIx srcDb (emptyFlags 
+        case (_runPrompt $ createProject comp silent pkgIx srcDb (emptyFlags
             { initializeTestSuite = Flag True
             , packageType = Flag LibraryAndExecutable
             })) inputs of
@@ -475,7 +486,7 @@
               , "[\"test/Main.hs\", \"test/Foo.hs\", \"test/bar.y\"]"
               ]
 
-        case (_runPrompt $ createProject comp silent pkgIx srcDb (emptyFlags 
+        case (_runPrompt $ createProject comp silent pkgIx srcDb (emptyFlags
             { initializeTestSuite = Flag True
             , packageType = Flag Library
             })) inputs of
@@ -515,7 +526,7 @@
             _testOtherExts    test @?= map EnableExtension [OverloadedStrings, LambdaCase, RankNTypes, RecordWildCards]
             _testDependencies test @?! []
             _testBuildTools   test @?= [mkStringyDep "happy:happy"]
-            
+
             assertBool "The library should be a dependency of the test executable" $
               mkPackageNameDep (_optPkgName opts) `elem` _testDependencies test
 
@@ -1265,3 +1276,136 @@
   case (_runPrompt $ f emptyFlags) (NEL.fromList inputs) of
     Left  x -> g x
     Right x -> h x
+
+cliListParserTests :: TestTree
+cliListParserTests = testGroup "cli list parser"
+  [ testCase "Single extraSrc" $ do
+      flags <- runParserTest ["-x", "Generated.hs"]
+      flags @?= emptyFlags
+        { extraSrc = Flag ["Generated.hs"]
+        }
+  , testCase "Multiple extraSrc" $ do
+      flags <- runParserTest ["-x", "Gen1.hs", "-x", "Gen2.hs", "-x", "Gen3.hs"]
+      flags @?= emptyFlags
+        { extraSrc = Flag ["Gen1.hs", "Gen2.hs", "Gen3.hs"]
+        }
+  , testCase "Single extraDoc" $ do
+      flags <- runParserTest ["--extra-doc-file", "README"]
+      flags @?= emptyFlags
+        { extraDoc = Flag $ ["README"]
+        }
+  , testCase "Multiple extraDoc" $ do
+      flags <- runParserTest ["--extra-doc-file", "README",
+                              "--extra-doc-file", "CHANGELOG",
+                              "--extra-doc-file", "LICENSE"]
+      flags @?= emptyFlags
+        { extraDoc = Flag $ map fromString ["README", "CHANGELOG", "LICENSE"]
+        }
+  , testCase "Single exposedModules" $ do
+      flags <- runParserTest ["-o", "Test"]
+      flags @?= emptyFlags
+        { exposedModules = Flag $ map fromString ["Test"]
+        }
+  , testCase "Multiple exposedModules" $ do
+      flags <- runParserTest ["-o", "Test", "-o", "Test2", "-o", "Test3"]
+      flags @?= emptyFlags
+        { exposedModules = Flag $ map fromString ["Test", "Test2", "Test3"]
+        }
+  -- there is no otherModules cli flag
+  -- , testCase "Single otherModules" $ do
+  --     flags <- runParserTest ["-o", "Test"]
+  --     flags @?= dummyFlags
+  --       { otherModules = Flag $ map fromString ["Test"]
+  --       }
+  -- , testCase "Multiple otherModules" $ do
+  --     flags <- runParserTest ["-o", "Test", "-o", "Test2", "-o", "Test3"]
+  --     flags @?= dummyFlags
+  --       { otherModules = Flag $ map fromString ["Test", "Test2", "Test3"]
+  --       }
+  , testCase "Single otherExts" $ do
+      flags <- runParserTest ["--extension", "OverloadedStrings"]
+      flags @?= emptyFlags
+        { otherExts = Flag [EnableExtension OverloadedStrings]
+        }
+  , testCase "Multiple otherExts" $ do
+      flags <- runParserTest ["--extension", "OverloadedStrings",
+                              "--extension", "FlexibleInstances",
+                              "--extension", "FlexibleContexts"]
+      flags @?= emptyFlags
+        { otherExts = Flag [EnableExtension OverloadedStrings,
+                            EnableExtension FlexibleInstances,
+                            EnableExtension FlexibleContexts]
+        }
+  , testCase "Single dependency" $ do
+      flags <- runParserTest ["-d", "base"]
+      flags @?= emptyFlags
+        { dependencies = Flag [mkStringyDep "base"]
+        }
+  , testCase "Multiple dependency flags" $ do
+      flags <- runParserTest ["-d", "base", "-d", "vector"]
+      flags @?= emptyFlags
+        { dependencies = Flag $ fmap mkStringyDep ["base", "vector"]
+        }
+  , testCase "Comma separated list of dependencies" $ do
+      flags <- runParserTest ["-d", "base,vector"]
+      flags @?= emptyFlags
+        { dependencies = Flag $ fmap mkStringyDep ["base", "vector"]
+        }
+  , testCase "Single applicationDirs" $ do
+      flags <- runParserTest ["--application-dir", "app"]
+      flags @?= emptyFlags
+        { applicationDirs = Flag ["app"]
+        }
+  , testCase "Multiple applicationDirs" $ do
+      flags <- runParserTest ["--application-dir", "app",
+                              "--application-dir", "exe",
+                              "--application-dir", "srcapp"]
+      flags @?= emptyFlags
+        { applicationDirs = Flag ["app", "exe", "srcapp"]
+        }
+  , testCase "Single sourceDirs" $ do
+      flags <- runParserTest ["--source-dir", "src"]
+      flags @?= emptyFlags
+        { sourceDirs = Flag ["src"]
+        }
+  , testCase "Multiple sourceDirs" $ do
+      flags <- runParserTest ["--source-dir", "src",
+                              "--source-dir", "lib",
+                              "--source-dir", "sources"]
+      flags @?= emptyFlags
+        { sourceDirs = Flag ["src", "lib", "sources"]
+        }
+  , testCase "Single buildTools" $ do
+      flags <- runParserTest ["--build-tool", "happy"]
+      flags @?= emptyFlags
+        { buildTools = Flag ["happy"]
+        }
+  , testCase "Multiple buildTools" $ do
+      flags <- runParserTest ["--build-tool", "happy",
+                              "--build-tool", "alex",
+                              "--build-tool", "make"]
+      flags @?= emptyFlags
+        { buildTools = Flag ["happy", "alex", "make"]
+        }
+  , testCase "Single testDirs" $ do
+      flags <- runParserTest ["--test-dir", "test"]
+      flags @?= emptyFlags
+        { testDirs = Flag ["test"]
+        }
+  , testCase "Multiple testDirs" $ do
+      flags <- runParserTest ["--test-dir", "test",
+                              "--test-dir", "tests",
+                              "--test-dir", "testsuite"]
+      flags @?= emptyFlags
+        { testDirs = Flag ["test", "tests", "testsuite"]
+        }
+  ]
+  where
+    assumeAllParse :: CommandParse (InitFlags -> InitFlags, [String]) -> IO InitFlags
+    assumeAllParse = \case
+      CommandReadyToGo (flagsF, []) -> pure (flagsF emptyFlags)
+      _ -> assertFailure "Expected successful parse"
+
+    runParserTest :: [String] -> IO InitFlags
+    runParserTest opts = do
+      assumeAllParse $ commandParseArgs initCommand False opts
diff --git a/cabal/cabal-install/tests/UnitTests/Distribution/Client/Init/Utils.hs b/cabal/cabal-install/tests/UnitTests/Distribution/Client/Init/Utils.hs
--- a/cabal/cabal-install/tests/UnitTests/Distribution/Client/Init/Utils.hs
+++ b/cabal/cabal-install/tests/UnitTests/Distribution/Client/Init/Utils.hs
@@ -51,7 +51,7 @@
 emptyFlags :: InitFlags
 emptyFlags = mempty
 
--- | Retireves the proper base version based on the GHC version
+-- | Retrieves the proper base version based on the GHC version
 baseVersion :: Compiler -> VersionRange
 baseVersion Compiler {compilerId = CompilerId GHC ver} =
   let ghcToBase = baseVersion' . prettyShow $ ver in
diff --git a/cabal/cabal-install/tests/UnitTests/Distribution/Client/InstallPlan.hs b/cabal/cabal-install/tests/UnitTests/Distribution/Client/InstallPlan.hs
--- a/cabal/cabal-install/tests/UnitTests/Distribution/Client/InstallPlan.hs
+++ b/cabal/cabal-install/tests/UnitTests/Distribution/Client/InstallPlan.hs
@@ -124,7 +124,7 @@
             (Just ixu, Just ixv) -> ixu > ixv
             _                    -> True
         | let ixs = array (bounds g)
-                          (zip (range (bounds g)) (repeat Nothing) ++ 
+                          (zip (range (bounds g)) (repeat Nothing) ++
                            zip vs (map Just [0::Int ..]))
         , (u,v) <- edges g ]
 
diff --git a/cabal/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs b/cabal/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs
--- a/cabal/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs
+++ b/cabal/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs
@@ -29,6 +29,7 @@
 import Distribution.Simple.Program.Types
 import Distribution.Simple.Program.Db
 import Distribution.Simple.Utils (toUTF8BS)
+import qualified Distribution.Simple.InstallDirs as InstallDirs
 import Distribution.Types.PackageVersionConstraint
 
 import Distribution.Parsec
@@ -456,6 +457,7 @@
         projectConfigHcPath               <- arbitraryFlag arbitraryShortToken
         projectConfigHcPkg                <- arbitraryFlag arbitraryShortToken
         projectConfigHaddockIndex         <- arbitrary
+        projectConfigInstallDirs          <- fixInstallDirs <$> arbitrary
         projectConfigPackageDBs           <- shortListOf 2 arbitrary
         projectConfigRemoteRepos          <- arbitrary
         projectConfigLocalNoIndexRepos    <- arbitrary
@@ -486,6 +488,7 @@
         arbitraryConstraints :: Gen [(UserConstraint, ConstraintSource)]
         arbitraryConstraints =
             fmap (\uc -> (uc, projectConfigConstraintSource)) <$> arbitrary
+        fixInstallDirs x = x {InstallDirs.includedir = mempty, InstallDirs.mandir = mempty, InstallDirs.flibdir = mempty}
 
     shrink ProjectConfigShared {..} = runShrinker $ pure ProjectConfigShared
         <*> shrinker projectConfigDistDir
@@ -496,6 +499,7 @@
         <*> shrinkerAla (fmap NonEmpty) projectConfigHcPath
         <*> shrinkerAla (fmap NonEmpty) projectConfigHcPkg
         <*> shrinker projectConfigHaddockIndex
+        <*> shrinker projectConfigInstallDirs
         <*> shrinker projectConfigPackageDBs
         <*> shrinker projectConfigRemoteRepos
         <*> shrinker projectConfigLocalNoIndexRepos
@@ -573,10 +577,13 @@
         <*> arbitraryFlag arbitraryShortToken
         <*> arbitrary
         <*> arbitrary
+        <*> arbitraryFlag arbitraryShortToken
+        <*> arbitraryFlag arbitraryShortToken
         <*> arbitrary
         <*> arbitrary
         <*> arbitrary
         <*> arbitrary
+        <*> arbitrary
         <*> arbitraryFlag arbitraryShortToken
         <*> arbitrary
         <*> shortListOf 5 arbitrary
@@ -636,6 +643,9 @@
                          , packageConfigHaddockHscolourCss = x39
                          , packageConfigHaddockContents = x40
                          , packageConfigHaddockForHackage = x41
+                         , packageConfigHaddockIndex = x54
+                         , packageConfigHaddockBaseUrl = x55
+                         , packageConfigHaddockLib = x56
                          , packageConfigTestHumanLog = x44
                          , packageConfigTestMachineLog = x45
                          , packageConfigTestShowDetails = x46
@@ -693,6 +703,9 @@
                       , packageConfigHaddockHscolourCss = fmap getNonEmpty x39'
                       , packageConfigHaddockContents = x40'
                       , packageConfigHaddockForHackage = x41'
+                      , packageConfigHaddockIndex = x54'
+                      , packageConfigHaddockBaseUrl = x55'
+                      , packageConfigHaddockLib = x56'
                       , packageConfigTestHumanLog = x44'
                       , packageConfigTestMachineLog = x45'
                       , packageConfigTestShowDetails = x46'
@@ -710,7 +723,8 @@
           (x30', x31', x32', (x33', x33_1'), x34'),
           (x35', x36', x37', x38', x43', x39'),
           (x40', x41'),
-          (x44', x45', x46', x47', x48', x49', x51', x52')))
+          (x44', x45', x46', x47', x48', x49', x51', x52', x54', x55'),
+          x56'))
           <- shrink
              (((preShrink_Paths x00, preShrink_Args x01, x02, x03, x04),
                 (x05, x42, x06, x50, x07, x08, x09),
@@ -724,7 +738,7 @@
                  (x30, x31, x32, (x33, x33_1), x34),
                  (x35, x36, fmap NonEmpty x37, x38, x43, fmap NonEmpty x39),
                  (x40, x41),
-                 (x44, x45, x46, x47, x48, x49, x51, x52)))
+                 (x44, x45, x46, x47, x48, x49, x51, x52, x54, x55), x56))
       ]
       where
         preShrink_Paths  = Map.map NonEmpty
diff --git a/cabal/cabal-install/tests/UnitTests/Distribution/Client/VCS.hs b/cabal/cabal-install/tests/UnitTests/Distribution/Client/VCS.hs
--- a/cabal/cabal-install/tests/UnitTests/Distribution/Client/VCS.hs
+++ b/cabal/cabal-install/tests/UnitTests/Distribution/Client/VCS.hs
@@ -179,7 +179,7 @@
           -> IO a
 testSetup vcs mkVCSTestDriver repoRecipe theTest = do
     -- test setup
-    vcs' <- configureVCS verbosity vcs
+    vcs' <- configureVCS verbosity [] vcs
     withTestDir verbosity "vcstest" $ \tmpdir -> do
       let srcRepoPath = tmpdir </> "src"
           submodulesPath = tmpdir </> "submodules"
@@ -301,7 +301,7 @@
 --
 -- So, given a source repo dir, the corresponding 'RepoState' and a number of
 -- target repo dirs, pick a sequence of (lists of) sync targets from the
--- 'RepoState' and syncronise the target dirs with those targets, checking for
+-- 'RepoState' and synchronise the target dirs with those targets, checking for
 -- each one that the actual working state matches the expected repo state.
 --
 checkSyncRepos
diff --git a/cabal/cabal-install/tests/UnitTests/Distribution/Solver/Modular/DSL.hs b/cabal/cabal-install/tests/UnitTests/Distribution/Solver/Modular/DSL.hs
--- a/cabal/cabal-install/tests/UnitTests/Distribution/Solver/Modular/DSL.hs
+++ b/cabal/cabal-install/tests/UnitTests/Distribution/Solver/Modular/DSL.hs
@@ -474,12 +474,14 @@
               }
             }
         pkgCheckErrors =
-          -- We ignore these warnings because some unit tests test that the
-          -- solver allows unknown extensions/languages when the compiler
-          -- supports them.
-          let ignore = ["Unknown extensions:", "Unknown languages:"]
-          in [ err | err <- C.checkPackage (srcpkgDescription package) Nothing
-             , not $ any (`isPrefixOf` C.explanation err) ignore ]
+          -- We ignore unknown extensions/languages warnings because
+          -- some there are some unit tests test in which the solver allows
+          -- unknown extensions/languages when the compiler supports them.
+          -- Furthermore we ignore missing upper bound warnings because
+          -- they are not related to this test suite, and are tested
+          -- with golden tests.
+          let checks = C.checkPackage (srcpkgDescription package) Nothing
+          in filter (\x -> not (isMissingUpperBound x) && not (isUnknownLangExt x)) checks
     in if null pkgCheckErrors
        then package
        else error $ "invalid GenericPackageDescription for package "
@@ -665,6 +667,18 @@
       case splitDeps deps of
         (directDeps, []) -> map mkDirect directDeps
         _                -> error "mkSetupDeps: custom setup has non-simple deps"
+
+    -- Check for `UnknownLanguages` and `UnknownExtensions`. See
+    isUnknownLangExt :: C.PackageCheck -> Bool
+    isUnknownLangExt pc = case C.explanation pc of
+                            C.UnknownExtensions {} -> True
+                            C.UnknownLanguages {} -> True
+                            _ -> False
+    isMissingUpperBound :: C.PackageCheck -> Bool
+    isMissingUpperBound pc = case C.explanation pc of
+                            C.MissingUpperBounds {} -> True
+                            _ -> False
+
 
 mkSimpleVersion :: ExamplePkgVersion -> C.Version
 mkSimpleVersion n = C.mkVersion [n, 0, 0]
diff --git a/cabal/cabal-install/tests/UnitTests/Distribution/Solver/Modular/Solver.hs b/cabal/cabal-install/tests/UnitTests/Distribution/Solver/Modular/Solver.hs
--- a/cabal/cabal-install/tests/UnitTests/Distribution/Solver/Modular/Solver.hs
+++ b/cabal/cabal-install/tests/UnitTests/Distribution/Solver/Modular/Solver.hs
@@ -148,11 +148,13 @@
         , runTest $ mkTest db12 "baseShim5" ["D"] anySolverFailure
         , runTest $ mkTest db12 "baseShim6" ["E"] (solverSuccess [("E", 1), ("syb", 2)])
         ]
-    , testGroup "Base" [
+    , testGroup "Base and Nonupgradable" [
           runTest $ mkTest dbBase "Refuse to install base without --allow-boot-library-installs" ["base"] $
                       solverFailure (isInfixOf "only already installed instances can be used")
         , runTest $ allowBootLibInstalls $ mkTest dbBase "Install base with --allow-boot-library-installs" ["base"] $
                       solverSuccess [("base", 1), ("ghc-prim", 1), ("integer-gmp", 1), ("integer-simple", 1)]
+        , runTest $ mkTest dbNonupgrade "Refuse to install newer ghc requested by another library" ["A"] $
+                      solverFailure (isInfixOf "rejecting: ghc-2.0.0 (constraint from non-upgradeable package requires installed instance)")
         ]
     , testGroup "reject-unconstrained" [
           runTest $ onlyConstrained $ mkTest db12 "missing syb" ["E"] $
@@ -1122,6 +1124,13 @@
     , Right $ exAv "integer-simple" 1 []
     , Right $ exAv "integer-gmp" 1 []
     ]
+
+dbNonupgrade :: ExampleDb
+dbNonupgrade = [
+    Left $ exInst "ghc" 1 "ghc-1" []
+  , Right $ exAv "ghc" 2 []
+  , Right $ exAv "A" 1 [ExFix "ghc" 2]
+  ]
 
 db13 :: ExampleDb
 db13 = [
diff --git a/cabal/cabal-install/tests/fixtures/configure/cabal.project.local b/cabal/cabal-install/tests/fixtures/configure/cabal.project.local
--- a/cabal/cabal-install/tests/fixtures/configure/cabal.project.local
+++ b/cabal/cabal-install/tests/fixtures/configure/cabal.project.local
diff --git a/cabal/cabal-testsuite/LICENSE b/cabal/cabal-testsuite/LICENSE
--- a/cabal/cabal-testsuite/LICENSE
+++ b/cabal/cabal-testsuite/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2003-2022, Cabal Development Team.
+Copyright (c) 2003-2023, Cabal Development Team.
 See the AUTHORS file for the full list of copyright holders.
 
 See */LICENSE for the copyright holders of the subcomponents.
diff --git a/cabal/cabal-testsuite/PackageTests/AutogenModules/Package/my.cabal b/cabal/cabal-testsuite/PackageTests/AutogenModules/Package/my.cabal
--- a/cabal/cabal-testsuite/PackageTests/AutogenModules/Package/my.cabal
+++ b/cabal/cabal-testsuite/PackageTests/AutogenModules/Package/my.cabal
@@ -17,6 +17,7 @@
     build-depends: base
     exposed-modules:
         MyLibrary
+        PackageInfo_AutogenModules
         Paths_AutogenModules
         MyLibHelperModule
     other-modules:
@@ -30,6 +31,7 @@
     build-depends: base
     other-modules:
         MyExeModule
+        PackageInfo_AutogenModules
         Paths_AutogenModules
         MyExeHelperModule
     autogen-modules:
@@ -42,6 +44,7 @@
     build-depends: base
     other-modules:
         MyTestModule
+        PackageInfo_AutogenModules
         Paths_AutogenModules
         MyTestHelperModule
     autogen-modules:
@@ -54,6 +57,7 @@
     build-depends: base
     other-modules:
         MyBenchModule
+        PackageInfo_AutogenModules
         Paths_AutogenModules
         MyBenchHelperModule
     autogen-modules:
diff --git a/cabal/cabal-testsuite/PackageTests/AutogenModules/Package/setup.cabal.out b/cabal/cabal-testsuite/PackageTests/AutogenModules/Package/setup.cabal.out
--- a/cabal/cabal-testsuite/PackageTests/AutogenModules/Package/setup.cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/AutogenModules/Package/setup.cabal.out
@@ -14,6 +14,8 @@
 On test suite 'Test' an 'autogen-module' is not on 'other-modules'
 On benchmark 'Bench' an 'autogen-module' is not on 'other-modules'
 Packages using 'cabal-version: 2.0' and the autogenerated module Paths_* must include it also on the 'autogen-modules' field besides 'exposed-modules' and 'other-modules'. This specifies that the module does not come with the package and is generated on setup. Modules built with a custom Setup.hs script also go here to ensure that commands like sdist don't fail.
+Packages using 'cabal-version: 2.0' and the autogenerated module PackageInfo_* must include it in 'autogen-modules' as well as 'exposed-modules' and 'other-modules'. This specifies that the module does not come with the package and is generated on setup. Modules built with a custom Setup.hs script also go here to ensure that commands like sdist don't fail.
+To use the autogenerated module PackageInfo_* you need to specify `cabal-version: 3.12` or higher. This is not possible in `cabal 3.10`. To use this feature and be able to upload your package to Hackage, download `cabal 3.12`!
 The filename './my.cabal' does not match package name (expected: 'AutogenModules.cabal')
 Note: the public hackage server would reject this package.
 Building source dist for AutogenModules-0.1...
diff --git a/cabal/cabal-testsuite/PackageTests/AutogenModules/Package/setup.out b/cabal/cabal-testsuite/PackageTests/AutogenModules/Package/setup.out
--- a/cabal/cabal-testsuite/PackageTests/AutogenModules/Package/setup.out
+++ b/cabal/cabal-testsuite/PackageTests/AutogenModules/Package/setup.out
@@ -14,6 +14,8 @@
 On test suite 'Test' an 'autogen-module' is not on 'other-modules'
 On benchmark 'Bench' an 'autogen-module' is not on 'other-modules'
 Packages using 'cabal-version: 2.0' and the autogenerated module Paths_* must include it also on the 'autogen-modules' field besides 'exposed-modules' and 'other-modules'. This specifies that the module does not come with the package and is generated on setup. Modules built with a custom Setup.hs script also go here to ensure that commands like sdist don't fail.
+Packages using 'cabal-version: 2.0' and the autogenerated module PackageInfo_* must include it in 'autogen-modules' as well as 'exposed-modules' and 'other-modules'. This specifies that the module does not come with the package and is generated on setup. Modules built with a custom Setup.hs script also go here to ensure that commands like sdist don't fail.
+To use the autogenerated module PackageInfo_* you need to specify `cabal-version: 3.12` or higher. This is not possible in `cabal 3.10`. To use this feature and be able to upload your package to Hackage, download `cabal 3.12`!
 The filename './my.cabal' does not match package name (expected: 'AutogenModules.cabal')
 Note: the public hackage server would reject this package.
 Building source dist for AutogenModules-0.1...
diff --git a/cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/AutogenModules.cabal b/cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/AutogenModules.cabal
--- a/cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/AutogenModules.cabal
+++ b/cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/AutogenModules.cabal
@@ -17,11 +17,13 @@
     build-depends: base
     exposed-modules:
         MyLibrary
+        PackageInfo_AutogenModules
         Paths_AutogenModules
         MyLibHelperModule
     other-modules:
         MyLibModule
     autogen-modules:
+        PackageInfo_AutogenModules
         Paths_AutogenModules
         MyLibHelperModule
 
@@ -31,9 +33,11 @@
     build-depends: base
     other-modules:
         MyExeModule
+        PackageInfo_AutogenModules
         Paths_AutogenModules
         MyExeHelperModule
     autogen-modules:
+        PackageInfo_AutogenModules
         Paths_AutogenModules
         MyExeHelperModule
 
@@ -44,9 +48,11 @@
     build-depends: base
     other-modules:
         MyTestModule
+        PackageInfo_AutogenModules
         Paths_AutogenModules
         MyTestHelperModule
     autogen-modules:
+        PackageInfo_AutogenModules
         Paths_AutogenModules
         MyTestHelperModule
 
@@ -57,8 +63,10 @@
     build-depends: base
     other-modules:
         MyBenchModule
+        PackageInfo_AutogenModules
         Paths_AutogenModules
         MyBenchHelperModule
     autogen-modules:
+        PackageInfo_AutogenModules
         Paths_AutogenModules
         MyBenchHelperModule
diff --git a/cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/setup.cabal.out b/cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/setup.cabal.out
--- a/cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/setup.cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/setup.cabal.out
@@ -1,6 +1,9 @@
 # Setup configure
 Configuring AutogenModules-0.1...
 # Setup sdist
+Distribution quality errors:
+To use the autogenerated module PackageInfo_* you need to specify `cabal-version: 3.12` or higher. This is not possible in `cabal 3.10`. To use this feature and be able to upload your package to Hackage, download `cabal 3.12`!
+Note: the public hackage server would reject this package.
 Building source dist for AutogenModules-0.1...
 Source tarball created: setup.cabal.dist/work/dist/AutogenModules-0.1.tar.gz
 # Setup sdist
diff --git a/cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/setup.out b/cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/setup.out
--- a/cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/setup.out
+++ b/cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/setup.out
@@ -1,6 +1,9 @@
 # Setup configure
 Configuring AutogenModules-0.1...
 # Setup sdist
+Distribution quality errors:
+To use the autogenerated module PackageInfo_* you need to specify `cabal-version: 3.12` or higher. This is not possible in `cabal 3.10`. To use this feature and be able to upload your package to Hackage, download `cabal 3.12`!
+Note: the public hackage server would reject this package.
 Building source dist for AutogenModules-0.1...
 Source tarball created: setup.dist/work/dist/AutogenModules-0.1.tar.gz
 # Setup sdist
diff --git a/cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/setup.test.hs b/cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/setup.test.hs
--- a/cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/setup.test.hs
+++ b/cabal/cabal-testsuite/PackageTests/AutogenModules/SrcDist/setup.test.hs
@@ -25,16 +25,16 @@
         let gotTestSuite  = head $ testSuites  (localPkgDescr lbi)
         let gotBenchmark  = head $ benchmarks  (localPkgDescr lbi)
         assertEqual "library 'autogen-modules' field does not match expected"
-                [fromString "Paths_AutogenModules", fromString "MyLibHelperModule"]
+                [fromString "PackageInfo_AutogenModules", fromString "Paths_AutogenModules", fromString "MyLibHelperModule"]
                 (libModulesAutogen gotLibrary)
         assertEqual "executable 'autogen-modules' field does not match expected"
-                [fromString "Paths_AutogenModules", fromString "MyExeHelperModule"]
+                [fromString "PackageInfo_AutogenModules", fromString "Paths_AutogenModules", fromString "MyExeHelperModule"]
                 (exeModulesAutogen gotExecutable)
         assertEqual "test-suite 'autogen-modules' field does not match expected"
-                [fromString "Paths_AutogenModules", fromString "MyTestHelperModule"]
+                [fromString "PackageInfo_AutogenModules", fromString "Paths_AutogenModules", fromString "MyTestHelperModule"]
                 (testModulesAutogen gotTestSuite)
         assertEqual "benchmark 'autogen-modules' field does not match expected"
-                [fromString "Paths_AutogenModules", fromString "MyBenchHelperModule"]
+                [fromString "PackageInfo_AutogenModules", fromString "Paths_AutogenModules", fromString "MyBenchHelperModule"]
                 (benchmarkModulesAutogen gotBenchmark)
 
         -- Package check messages.
@@ -61,7 +61,6 @@
         assertOutputDoesNotContain pathsAutogenMsg configureResult
 
         -- Asserts for the undesired check messages after sdist.
-        assertOutputDoesNotContain "Distribution quality errors:" sdistResult
         assertOutputDoesNotContain libAutogenMsg   sdistResult
         assertOutputDoesNotContain exeAutogenMsg   sdistResult
         assertOutputDoesNotContain testAutogenMsg  sdistResult
diff --git a/cabal/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.cabal.out b/cabal/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.cabal.out
--- a/cabal/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.cabal.out
@@ -8,7 +8,7 @@
 Preprocessing library for mylib-0.1.0.0..
 Running Haddock on library instantiated with Database = <Database>
 for mylib-0.1.0.0..
-Documentation created: ../setup-external.cabal.dist/work/mylib/dist/doc/html/mylib/index.html
+Documentation created: ../setup-external.cabal.dist/work/mylib/dist/doc/html/mylib/
 # Setup copy
 Installing library in <PATH>
 # Setup register
@@ -22,7 +22,7 @@
 # Setup haddock
 Preprocessing library for mysql-0.1.0.0..
 Running Haddock on library for mysql-0.1.0.0..
-Documentation created: ../setup-external.cabal.dist/work/mysql/dist/doc/html/mysql/index.html
+Documentation created: ../setup-external.cabal.dist/work/mysql/dist/doc/html/mysql/
 # Setup copy
 Installing library in <PATH>
 # Setup register
@@ -35,7 +35,7 @@
 # Setup haddock
 Preprocessing library for postgresql-0.1.0.0..
 Running Haddock on library for postgresql-0.1.0.0..
-Documentation created: ../setup-external.cabal.dist/work/postgresql/dist/doc/html/postgresql/index.html
+Documentation created: ../setup-external.cabal.dist/work/postgresql/dist/doc/html/postgresql/
 # Setup copy
 Installing library in <PATH>
 # Setup register
@@ -51,7 +51,7 @@
 Running Haddock on library instantiated with
   Database = mysql-0.1.0.0:Database.MySQL
 for mylib-0.1.0.0..
-Documentation created: ../setup-external.cabal.dist/work/mylib/dist/doc/html/mylib/index.html
+Documentation created: ../setup-external.cabal.dist/work/mylib/dist/doc/html/mylib/
 # Setup copy
 Installing library in <PATH>
 # Setup register
@@ -69,7 +69,7 @@
 Running Haddock on library instantiated with
   Database = postgresql-0.1.0.0:Database.PostgreSQL
 for mylib-0.1.0.0..
-Documentation created: ../setup-external.cabal.dist/work/mylib/dist/doc/html/mylib/index.html
+Documentation created: ../setup-external.cabal.dist/work/mylib/dist/doc/html/mylib/
 # Setup copy
 Installing library in <PATH>
 # Setup register
@@ -84,7 +84,7 @@
 # Setup haddock
 Preprocessing library for src-0.1.0.0..
 Running Haddock on library for src-0.1.0.0..
-Documentation created: ../setup-external.cabal.dist/work/src/dist/doc/html/src/index.html
+Documentation created: ../setup-external.cabal.dist/work/src/dist/doc/html/src/
 # Setup copy
 Installing library in <PATH>
 # Setup register
diff --git a/cabal/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.out b/cabal/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.out
--- a/cabal/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.out
+++ b/cabal/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.out
@@ -8,7 +8,7 @@
 Preprocessing library for mylib-0.1.0.0..
 Running Haddock on library instantiated with Database = <Database>
 for mylib-0.1.0.0..
-Documentation created: ../setup-external.dist/work/mylib/dist/doc/html/mylib/index.html
+Documentation created: ../setup-external.dist/work/mylib/dist/doc/html/mylib/
 # Setup copy
 Installing library in <PATH>
 # Setup register
@@ -22,7 +22,7 @@
 # Setup haddock
 Preprocessing library for mysql-0.1.0.0..
 Running Haddock on library for mysql-0.1.0.0..
-Documentation created: ../setup-external.dist/work/mysql/dist/doc/html/mysql/index.html
+Documentation created: ../setup-external.dist/work/mysql/dist/doc/html/mysql/
 # Setup copy
 Installing library in <PATH>
 # Setup register
@@ -35,7 +35,7 @@
 # Setup haddock
 Preprocessing library for postgresql-0.1.0.0..
 Running Haddock on library for postgresql-0.1.0.0..
-Documentation created: ../setup-external.dist/work/postgresql/dist/doc/html/postgresql/index.html
+Documentation created: ../setup-external.dist/work/postgresql/dist/doc/html/postgresql/
 # Setup copy
 Installing library in <PATH>
 # Setup register
@@ -51,7 +51,7 @@
 Running Haddock on library instantiated with
   Database = mysql-0.1.0.0:Database.MySQL
 for mylib-0.1.0.0..
-Documentation created: ../setup-external.dist/work/mylib/dist/doc/html/mylib/index.html
+Documentation created: ../setup-external.dist/work/mylib/dist/doc/html/mylib/
 # Setup copy
 Installing library in <PATH>
 # Setup register
@@ -69,7 +69,7 @@
 Running Haddock on library instantiated with
   Database = postgresql-0.1.0.0:Database.PostgreSQL
 for mylib-0.1.0.0..
-Documentation created: ../setup-external.dist/work/mylib/dist/doc/html/mylib/index.html
+Documentation created: ../setup-external.dist/work/mylib/dist/doc/html/mylib/
 # Setup copy
 Installing library in <PATH>
 # Setup register
@@ -84,7 +84,7 @@
 # Setup haddock
 Preprocessing library for src-0.1.0.0..
 Running Haddock on library for src-0.1.0.0..
-Documentation created: ../setup-external.dist/work/src/dist/doc/html/src/index.html
+Documentation created: ../setup-external.dist/work/src/dist/doc/html/src/
 # Setup copy
 Installing library in <PATH>
 # Setup register
diff --git a/cabal/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.test.hs b/cabal/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.test.hs
--- a/cabal/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.test.hs
+++ b/cabal/cabal-testsuite/PackageTests/Backpack/Includes2/setup-external.test.hs
@@ -1,7 +1,7 @@
 import Test.Cabal.Prelude
 main = setupAndCabalTest $ do
   skipUnlessGhcVersion ">= 8.1"
-  ghc <- isGhcVersion "== 9.0.2 || == 9.2.*"
+  ghc <- isGhcVersion "== 9.0.2 || == 9.2.* || == 9.4.* || == 9.6.*"
   expectBrokenIf ghc 7987 $ do
     withPackageDb $ do
       withDirectory "mylib" $ setup_install_with_docs ["--ipid", "mylib-0.1.0.0"]
diff --git a/cabal/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.out b/cabal/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.out
--- a/cabal/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.out
+++ b/cabal/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.out
@@ -8,7 +8,7 @@
 Preprocessing library 'mylib' for Includes2-0.1.0.0..
 Running Haddock on library 'mylib' instantiated with Database = <Database>
 for Includes2-0.1.0.0..
-Documentation created: setup-per-component.dist/work/dist/doc/html/Includes2/index.html
+Documentation created: setup-per-component.dist/work/dist/doc/html/Includes2/
 # Setup copy
 Installing internal library mylib in <PATH>
 # Setup register
@@ -22,7 +22,7 @@
 # Setup haddock
 Preprocessing library 'mysql' for Includes2-0.1.0.0..
 Running Haddock on library 'mysql' for Includes2-0.1.0.0..
-Documentation created: setup-per-component.dist/work/dist/doc/html/Includes2/index.html
+Documentation created: setup-per-component.dist/work/dist/doc/html/Includes2/
 # Setup copy
 Installing internal library mysql in <PATH>
 # Setup register
@@ -35,7 +35,7 @@
 # Setup haddock
 Preprocessing library 'postgresql' for Includes2-0.1.0.0..
 Running Haddock on library 'postgresql' for Includes2-0.1.0.0..
-Documentation created: setup-per-component.dist/work/dist/doc/html/Includes2/index.html
+Documentation created: setup-per-component.dist/work/dist/doc/html/Includes2/
 # Setup copy
 Installing internal library postgresql in <PATH>
 # Setup register
@@ -54,7 +54,7 @@
 Running Haddock on library 'mylib' instantiated with
   Database = mysql-0.1.0.0:Database.MySQL
 for Includes2-0.1.0.0..
-Documentation created: setup-per-component.dist/work/dist/doc/html/Includes2/index.html
+Documentation created: setup-per-component.dist/work/dist/doc/html/Includes2/
 # Setup copy
 Installing internal library mylib in <PATH>
 # Setup register
@@ -75,7 +75,7 @@
 Running Haddock on library 'mylib' instantiated with
   Database = postgresql-0.1.0.0:Database.PostgreSQL
 for Includes2-0.1.0.0..
-Documentation created: setup-per-component.dist/work/dist/doc/html/Includes2/index.html
+Documentation created: setup-per-component.dist/work/dist/doc/html/Includes2/
 # Setup copy
 Installing internal library mylib in <PATH>
 # Setup register
@@ -90,7 +90,7 @@
 # Setup haddock
 Preprocessing library for Includes2-0.1.0.0..
 Running Haddock on library for Includes2-0.1.0.0..
-Documentation created: setup-per-component.dist/work/dist/doc/html/Includes2/index.html
+Documentation created: setup-per-component.dist/work/dist/doc/html/Includes2/
 # Setup copy
 Installing library in <PATH>
 # Setup register
diff --git a/cabal/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.test.hs b/cabal/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.test.hs
--- a/cabal/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.test.hs
+++ b/cabal/cabal-testsuite/PackageTests/Backpack/Includes2/setup-per-component.test.hs
@@ -2,7 +2,7 @@
 main = setupTest $ do
   -- No cabal test because per-component is broken with it
   skipUnlessGhcVersion ">= 8.1"
-  ghc <- isGhcVersion "== 9.0.2 || == 9.2.*"
+  ghc <- isGhcVersion "== 9.0.2 || == 9.2.* || == 9.4.* || == 9.6.*"
   expectBrokenIf ghc 7987 $
     withPackageDb $ do
       let setup_install' args = setup_install_with_docs (["--cabal-file", "Includes2.cabal"] ++ args)
diff --git a/cabal/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-explicit.out b/cabal/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-explicit.out
--- a/cabal/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-explicit.out
+++ b/cabal/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-explicit.out
@@ -8,7 +8,7 @@
 Preprocessing library for sigs-0.1.0.0..
 Running Haddock on library instantiated with Data.Map = <Data.Map>
 for sigs-0.1.0.0..
-Documentation created: ../../setup-external-explicit.dist/work/repo/sigs-0.1.0.0/dist/doc/html/sigs/index.html
+Documentation created: ../../setup-external-explicit.dist/work/repo/sigs-0.1.0.0/dist/doc/html/sigs/
 # Setup copy
 Installing library in <PATH>
 # Setup register
@@ -24,7 +24,7 @@
 Preprocessing library for indef-0.1.0.0..
 Running Haddock on library instantiated with Data.Map = <Data.Map>
 for indef-0.1.0.0..
-Documentation created: ../../setup-external-explicit.dist/work/repo/indef-0.1.0.0/dist/doc/html/indef/index.html
+Documentation created: ../../setup-external-explicit.dist/work/repo/indef-0.1.0.0/dist/doc/html/indef/
 # Setup copy
 Installing library in <PATH>
 # Setup register
diff --git a/cabal/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.cabal.out b/cabal/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.cabal.out
--- a/cabal/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.cabal.out
@@ -8,7 +8,7 @@
 Preprocessing library for sigs-0.1.0.0..
 Running Haddock on library instantiated with Data.Map = <Data.Map>
 for sigs-0.1.0.0..
-Documentation created: ../../setup-external-ok.cabal.dist/work/repo/sigs-0.1.0.0/dist/doc/html/sigs/index.html
+Documentation created: ../../setup-external-ok.cabal.dist/work/repo/sigs-0.1.0.0/dist/doc/html/sigs/
 # Setup copy
 Installing library in <PATH>
 # Setup register
@@ -24,7 +24,7 @@
 Preprocessing library for indef-0.1.0.0..
 Running Haddock on library instantiated with Data.Map = <Data.Map>
 for indef-0.1.0.0..
-Documentation created: ../../setup-external-ok.cabal.dist/work/repo/indef-0.1.0.0/dist/doc/html/indef/index.html
+Documentation created: ../../setup-external-ok.cabal.dist/work/repo/indef-0.1.0.0/dist/doc/html/indef/
 # Setup copy
 Installing library in <PATH>
 # Setup register
@@ -41,7 +41,7 @@
 Running Haddock on library instantiated with
   Data.Map = containers-<VERSION>:Data.Map
 for sigs-0.1.0.0..
-Documentation created: ../../setup-external-ok.cabal.dist/work/repo/sigs-0.1.0.0/dist/doc/html/sigs/index.html
+Documentation created: ../../setup-external-ok.cabal.dist/work/repo/sigs-0.1.0.0/dist/doc/html/sigs/
 # Setup copy
 Installing library in <PATH>
 # Setup register
@@ -58,7 +58,7 @@
 Running Haddock on library instantiated with
   Data.Map = containers-<VERSION>:Data.Map
 for indef-0.1.0.0..
-Documentation created: ../../setup-external-ok.cabal.dist/work/repo/indef-0.1.0.0/dist/doc/html/indef/index.html
+Documentation created: ../../setup-external-ok.cabal.dist/work/repo/indef-0.1.0.0/dist/doc/html/indef/
 # Setup copy
 Installing library in <PATH>
 # Setup register
diff --git a/cabal/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.out b/cabal/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.out
--- a/cabal/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.out
+++ b/cabal/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.out
@@ -8,7 +8,7 @@
 Preprocessing library for sigs-0.1.0.0..
 Running Haddock on library instantiated with Data.Map = <Data.Map>
 for sigs-0.1.0.0..
-Documentation created: ../../setup-external-ok.dist/work/repo/sigs-0.1.0.0/dist/doc/html/sigs/index.html
+Documentation created: ../../setup-external-ok.dist/work/repo/sigs-0.1.0.0/dist/doc/html/sigs/
 # Setup copy
 Installing library in <PATH>
 # Setup register
@@ -24,7 +24,7 @@
 Preprocessing library for indef-0.1.0.0..
 Running Haddock on library instantiated with Data.Map = <Data.Map>
 for indef-0.1.0.0..
-Documentation created: ../../setup-external-ok.dist/work/repo/indef-0.1.0.0/dist/doc/html/indef/index.html
+Documentation created: ../../setup-external-ok.dist/work/repo/indef-0.1.0.0/dist/doc/html/indef/
 # Setup copy
 Installing library in <PATH>
 # Setup register
@@ -41,7 +41,7 @@
 Running Haddock on library instantiated with
   Data.Map = containers-<VERSION>:Data.Map
 for sigs-0.1.0.0..
-Documentation created: ../../setup-external-ok.dist/work/repo/sigs-0.1.0.0/dist/doc/html/sigs/index.html
+Documentation created: ../../setup-external-ok.dist/work/repo/sigs-0.1.0.0/dist/doc/html/sigs/
 # Setup copy
 Installing library in <PATH>
 # Setup register
@@ -58,7 +58,7 @@
 Running Haddock on library instantiated with
   Data.Map = containers-<VERSION>:Data.Map
 for indef-0.1.0.0..
-Documentation created: ../../setup-external-ok.dist/work/repo/indef-0.1.0.0/dist/doc/html/indef/index.html
+Documentation created: ../../setup-external-ok.dist/work/repo/indef-0.1.0.0/dist/doc/html/indef/
 # Setup copy
 Installing library in <PATH>
 # Setup register
diff --git a/cabal/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.test.hs b/cabal/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.test.hs
--- a/cabal/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.test.hs
+++ b/cabal/cabal-testsuite/PackageTests/Backpack/Includes3/setup-external-ok.test.hs
@@ -3,7 +3,7 @@
 import qualified Data.Char as Char
 main = setupAndCabalTest $ do
   skipUnlessGhcVersion ">= 8.1"
-  ghc <- isGhcVersion "== 9.0.2 || == 9.2.*"
+  ghc <- isGhcVersion "== 9.0.2 || == 9.2.* || == 9.4.* || == 9.6.*"
   expectBrokenIf ghc 7987 $
     withPackageDb $ do
       containers_id <- getIPID "containers"
diff --git a/cabal/cabal-testsuite/PackageTests/Backpack/Reexport1/setup.cabal.out b/cabal/cabal-testsuite/PackageTests/Backpack/Reexport1/setup.cabal.out
--- a/cabal/cabal-testsuite/PackageTests/Backpack/Reexport1/setup.cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/Backpack/Reexport1/setup.cabal.out
@@ -6,7 +6,7 @@
 # Setup haddock
 Preprocessing library for p-0.1.0.0..
 Running Haddock on library for p-0.1.0.0..
-Documentation created: ../setup.cabal.dist/work/p/dist/doc/html/p/index.html
+Documentation created: ../setup.cabal.dist/work/p/dist/doc/html/p/
 # Setup copy
 Installing library in <PATH>
 # Setup register
@@ -19,4 +19,4 @@
 # Setup haddock
 Preprocessing library for q-0.1.0.0..
 Running Haddock on library for q-0.1.0.0..
-Documentation created: ../setup.cabal.dist/work/q/dist/doc/html/q/index.html
+Documentation created: ../setup.cabal.dist/work/q/dist/doc/html/q/
diff --git a/cabal/cabal-testsuite/PackageTests/Backpack/Reexport1/setup.out b/cabal/cabal-testsuite/PackageTests/Backpack/Reexport1/setup.out
--- a/cabal/cabal-testsuite/PackageTests/Backpack/Reexport1/setup.out
+++ b/cabal/cabal-testsuite/PackageTests/Backpack/Reexport1/setup.out
@@ -6,7 +6,7 @@
 # Setup haddock
 Preprocessing library for p-0.1.0.0..
 Running Haddock on library for p-0.1.0.0..
-Documentation created: ../setup.dist/work/p/dist/doc/html/p/index.html
+Documentation created: ../setup.dist/work/p/dist/doc/html/p/
 # Setup copy
 Installing library in <PATH>
 # Setup register
@@ -19,4 +19,4 @@
 # Setup haddock
 Preprocessing library for q-0.1.0.0..
 Running Haddock on library for q-0.1.0.0..
-Documentation created: ../setup.dist/work/q/dist/doc/html/q/index.html
+Documentation created: ../setup.dist/work/q/dist/doc/html/q/
diff --git a/cabal/cabal-testsuite/PackageTests/Backpack/T8582/Main.hs b/cabal/cabal-testsuite/PackageTests/Backpack/T8582/Main.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Backpack/T8582/Main.hs
@@ -0,0 +1,2 @@
+module Main where
+main = return ()
diff --git a/cabal/cabal-testsuite/PackageTests/Backpack/T8582/T8582.cabal b/cabal/cabal-testsuite/PackageTests/Backpack/T8582/T8582.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Backpack/T8582/T8582.cabal
@@ -0,0 +1,22 @@
+name: T8582
+version: 1.0
+build-type: Simple
+cabal-version: 2.0
+
+library sig
+    default-language: Haskell2010
+    hs-source-dirs: sig
+    signatures: A
+    build-depends: base
+
+library impl
+    default-language: Haskell2010
+    hs-source-dirs: impl
+    exposed-modules: ImplA
+    reexported-modules: ImplA as A
+    build-depends: base, sig
+
+executable exe
+    default-language: Haskell2010
+    main-is: Main.hs
+    build-depends: base, impl, sig
diff --git a/cabal/cabal-testsuite/PackageTests/Backpack/T8582/cabal.project b/cabal/cabal-testsuite/PackageTests/Backpack/T8582/cabal.project
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Backpack/T8582/cabal.project
@@ -0,0 +1,1 @@
+packages: .
diff --git a/cabal/cabal-testsuite/PackageTests/Backpack/T8582/impl/ImplA.hs b/cabal/cabal-testsuite/PackageTests/Backpack/T8582/impl/ImplA.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Backpack/T8582/impl/ImplA.hs
@@ -0,0 +1,1 @@
+module ImplA where
diff --git a/cabal/cabal-testsuite/PackageTests/Backpack/T8582/setup.cabal.out b/cabal/cabal-testsuite/PackageTests/Backpack/T8582/setup.cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Backpack/T8582/setup.cabal.out
@@ -0,0 +1,7 @@
+# Setup configure
+Configuring T8582-1.0...
+Error:
+    Cannot instantiate requirement 'ImplA'
+    Ensure "build-depends:" doesn't include any library with signatures: 'A'
+    as this creates a cyclic dependency, which GHC does not support.
+    In the stanza executable exe
diff --git a/cabal/cabal-testsuite/PackageTests/Backpack/T8582/setup.out b/cabal/cabal-testsuite/PackageTests/Backpack/T8582/setup.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Backpack/T8582/setup.out
@@ -0,0 +1,7 @@
+# Setup configure
+Configuring T8582-1.0...
+Error:
+    Cannot instantiate requirement 'ImplA'
+    Ensure "build-depends:" doesn't include any library with signatures: 'A'
+    as this creates a cyclic dependency, which GHC does not support.
+    In the stanza executable exe
diff --git a/cabal/cabal-testsuite/PackageTests/Backpack/T8582/setup.test.hs b/cabal/cabal-testsuite/PackageTests/Backpack/T8582/setup.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Backpack/T8582/setup.test.hs
@@ -0,0 +1,4 @@
+import Test.Cabal.Prelude
+main = setupAndCabalTest $ do
+    skipUnlessGhcVersion ">= 8.1"
+    fails $ setup "configure" []
diff --git a/cabal/cabal-testsuite/PackageTests/Backpack/T8582/sig/A.sig b/cabal/cabal-testsuite/PackageTests/Backpack/T8582/sig/A.sig
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Backpack/T8582/sig/A.sig
@@ -0,0 +1,1 @@
+signature A where
diff --git a/cabal/cabal-testsuite/PackageTests/BuildToolDependsInternalMissing/setup.cabal.out b/cabal/cabal-testsuite/PackageTests/BuildToolDependsInternalMissing/setup.cabal.out
--- a/cabal/cabal-testsuite/PackageTests/BuildToolDependsInternalMissing/setup.cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/BuildToolDependsInternalMissing/setup.cabal.out
@@ -1,3 +1,3 @@
 # Setup configure
 Configuring build-tool-depends-missing-0.1.0.0...
-Error: cabal: The package depends on a missing internal executable: 
+Error: cabal: The package depends on a missing internal executable: build-tool-depends-missing:hello-world
diff --git a/cabal/cabal-testsuite/PackageTests/BuildToolDependsInternalMissing/setup.out b/cabal/cabal-testsuite/PackageTests/BuildToolDependsInternalMissing/setup.out
--- a/cabal/cabal-testsuite/PackageTests/BuildToolDependsInternalMissing/setup.out
+++ b/cabal/cabal-testsuite/PackageTests/BuildToolDependsInternalMissing/setup.out
@@ -1,3 +1,3 @@
 # Setup configure
 Configuring build-tool-depends-missing-0.1.0.0...
-Error: setup: The package depends on a missing internal executable: 
+Error: setup: The package depends on a missing internal executable: build-tool-depends-missing:hello-world
diff --git a/cabal/cabal-testsuite/PackageTests/CCompilerOverride/custom-cc.bat b/cabal/cabal-testsuite/PackageTests/CCompilerOverride/custom-cc.bat
--- a/cabal/cabal-testsuite/PackageTests/CCompilerOverride/custom-cc.bat
+++ b/cabal/cabal-testsuite/PackageTests/CCompilerOverride/custom-cc.bat
diff --git a/cabal/cabal-testsuite/PackageTests/CCompilerOverride/setup.test.hs b/cabal/cabal-testsuite/PackageTests/CCompilerOverride/setup.test.hs
--- a/cabal/cabal-testsuite/PackageTests/CCompilerOverride/setup.test.hs
+++ b/cabal/cabal-testsuite/PackageTests/CCompilerOverride/setup.test.hs
@@ -6,14 +6,16 @@
 main = setupAndCabalTest $ do
   skipUnlessGhcVersion ">= 8.8"
   isWin <- isWindows
+  ghc94 <- isGhcVersion "== 9.4.*"
   env   <- getTestEnv
   let pwd      = testCurrentDir env
       customCC = pwd ++ "/custom-cc" ++ if isWin then ".bat" else ""
 
-  setup "configure"
-    [ "--ghc-option=-DNOERROR1"
-    , "--ghc-option=-optc=-DNOERROR2"
-    , "--ghc-option=-optP=-DNOERROR3"
-    , "--with-gcc=" ++ customCC
-    ]
-  setup "build" ["-v2"]
+  expectBrokenIf (isWin && ghc94) 8451 $ do
+    setup "configure"
+      [ "--ghc-option=-DNOERROR1"
+      , "--ghc-option=-optc=-DNOERROR2"
+      , "--ghc-option=-optP=-DNOERROR3"
+      , "--with-gcc=" ++ customCC
+      ]
+    setup "build" ["-v2"]
diff --git a/cabal/cabal-testsuite/PackageTests/CSourcesSanitisation/Main.hs b/cabal/cabal-testsuite/PackageTests/CSourcesSanitisation/Main.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/CSourcesSanitisation/Main.hs
@@ -0,0 +1,4 @@
+module Main where
+
+main :: IO ()
+main = putStrLn "main"
diff --git a/cabal/cabal-testsuite/PackageTests/CSourcesSanitisation/build.out b/cabal/cabal-testsuite/PackageTests/CSourcesSanitisation/build.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/CSourcesSanitisation/build.out
@@ -0,0 +1,42 @@
+# cabal build
+Resolving dependencies...
+Build profile: -w ghc-<GHCVER> -O1
+In order, the following will be built:
+ - repro-0.1.0.0 (lib) (first run)
+ - repro-0.1.0.0 (exe:exec1) (first run)
+ - repro-0.1.0.0 (lib:lib2) (first run)
+ - repro-0.1.0.0 (lib:lib3) (first run)
+ - repro-0.1.0.0 (lib:lib4) (first run)
+Configuring library for repro-0.1.0.0..
+Preprocessing library for repro-0.1.0.0..
+Building library for repro-0.1.0.0..
+Warning: The following header files listed in the main library's c-sources will not be used: cbits/gwinsz.h.
+Header files should be in the 'include' or 'install-include' stanza.
+See https://cabal.readthedocs.io/en/3.10/cabal-package.html#pkg-field-includes
+Configuring executable 'exec1' for repro-0.1.0.0..
+Preprocessing executable 'exec1' for repro-0.1.0.0..
+Building executable 'exec1' for repro-0.1.0.0..
+Warning: The following header files listed in exec1's c-sources will not be used: cbits/gwinsz.h.
+Header files should be in the 'include' or 'install-include' stanza.
+See https://cabal.readthedocs.io/en/3.10/cabal-package.html#pkg-field-includes
+Configuring library 'lib2' for repro-0.1.0.0..
+Preprocessing library 'lib2' for repro-0.1.0.0..
+Building library 'lib2' for repro-0.1.0.0..
+Warning: The following header files listed in library lib2's c-sources will not be used: cbits/gwinsz.h.
+Header files should be in the 'include' or 'install-include' stanza.
+See https://cabal.readthedocs.io/en/3.10/cabal-package.html#pkg-field-includes
+Configuring library 'lib3' for repro-0.1.0.0..
+Preprocessing library 'lib3' for repro-0.1.0.0..
+Building library 'lib3' for repro-0.1.0.0..
+Warning: The following header files listed in library lib3's c-sources will not be used: cbits/gwinsz.h.
+Header files should be in the 'include' or 'install-include' stanza.
+See https://cabal.readthedocs.io/en/3.10/cabal-package.html#pkg-field-includes
+Warning: The following files listed in library lib3's c-sources do not have the expected '.c' extension cbits/gwinsz.cc.
+C++ files should be in the 'cxx-sources' stanza.
+See https://cabal.readthedocs.io/en/3.10/cabal-package.html#pkg-field-cxx-sources
+Configuring library 'lib4' for repro-0.1.0.0..
+Preprocessing library 'lib4' for repro-0.1.0.0..
+Building library 'lib4' for repro-0.1.0.0..
+Warning: The following files listed in library lib4's c-sources do not have the expected '.c' extension cbits/gwinsz.cc.
+C++ files should be in the 'cxx-sources' stanza.
+See https://cabal.readthedocs.io/en/3.10/cabal-package.html#pkg-field-cxx-sources
diff --git a/cabal/cabal-testsuite/PackageTests/CSourcesSanitisation/build.test.hs b/cabal/cabal-testsuite/PackageTests/CSourcesSanitisation/build.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/CSourcesSanitisation/build.test.hs
@@ -0,0 +1,4 @@
+import Test.Cabal.Prelude
+
+main = cabalTest $ do
+  cabal "build" []
diff --git a/cabal/cabal-testsuite/PackageTests/CSourcesSanitisation/cabal.project b/cabal/cabal-testsuite/PackageTests/CSourcesSanitisation/cabal.project
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/CSourcesSanitisation/cabal.project
@@ -0,0 +1,1 @@
+packages: .
diff --git a/cabal/cabal-testsuite/PackageTests/CSourcesSanitisation/cbits/gwinsz.c b/cabal/cabal-testsuite/PackageTests/CSourcesSanitisation/cbits/gwinsz.c
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/CSourcesSanitisation/cbits/gwinsz.c
diff --git a/cabal/cabal-testsuite/PackageTests/CSourcesSanitisation/cbits/gwinsz.cc b/cabal/cabal-testsuite/PackageTests/CSourcesSanitisation/cbits/gwinsz.cc
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/CSourcesSanitisation/cbits/gwinsz.cc
diff --git a/cabal/cabal-testsuite/PackageTests/CSourcesSanitisation/cbits/gwinsz.h b/cabal/cabal-testsuite/PackageTests/CSourcesSanitisation/cbits/gwinsz.h
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/CSourcesSanitisation/cbits/gwinsz.h
diff --git a/cabal/cabal-testsuite/PackageTests/CSourcesSanitisation/repro.cabal b/cabal/cabal-testsuite/PackageTests/CSourcesSanitisation/repro.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/CSourcesSanitisation/repro.cabal
@@ -0,0 +1,34 @@
+cabal-version:      3.0
+name:               repro
+version:            0.1.0.0
+build-type:         Simple
+
+library
+    default-language: Haskell2010
+    c-sources:        cbits/gwinsz.h
+                      cbits/gwinsz.c
+    build-depends:    base
+
+library lib2
+    default-language: Haskell2010
+    c-sources:        cbits/gwinsz.h
+                      cbits/gwinsz.c
+    build-depends:    base
+
+library lib3
+    default-language: Haskell2010
+    c-sources:        cbits/gwinsz.h
+                      cbits/gwinsz.cc
+    build-depends:    base
+
+library lib4
+    default-language: Haskell2010
+    c-sources:        cbits/gwinsz.cc
+    build-depends:    base
+
+executable exec1
+    main-is: Main.hs
+    default-language: Haskell2010
+    c-sources:        cbits/gwinsz.h
+                      cbits/gwinsz.c
+    build-depends:    base
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CCOptionsExtraLibDirs/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CCOptionsExtraLibDirs/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CCOptionsExtraLibDirs/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following warnings are likely to affect your build negatively:
+Warning: Instead of 'cc-options: -Llibdir' use 'extra-lib-dirs: libdir'
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CCOptionsExtraLibDirs/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CCOptionsExtraLibDirs/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CCOptionsExtraLibDirs/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- `cc-options`, use `extra-lib-dirs` instead of `-L`.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CCOptionsExtraLibDirs/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CCOptionsExtraLibDirs/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CCOptionsExtraLibDirs/pkg.cabal
@@ -0,0 +1,13 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Module
+  default-language: Haskell2010
+  cc-options: -Llibdir
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CCOptionsInclude/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CCOptionsInclude/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CCOptionsInclude/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following warnings are likely to affect your build negatively:
+Warning: Instead of 'cc-options: -Ifolder' use 'include-dirs: folder'
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CCOptionsInclude/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CCOptionsInclude/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CCOptionsInclude/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- `cc-options`, use `include-dirs` instead of `-I`.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CCOptionsInclude/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CCOptionsInclude/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CCOptionsInclude/pkg.cabal
@@ -0,0 +1,13 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Module
+  default-language: Haskell2010
+  cc-options: -Ifolder
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CppNotPortable/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CppNotPortable/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CppNotPortable/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following warnings are likely to affect your build negatively:
+Warning: 'cpp-options: -Q' is not a portable C-preprocessor flag.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CppNotPortable/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CppNotPortable/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CppNotPortable/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- `cpp-options`, do not use use non portable flags.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CppNotPortable/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CppNotPortable/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CppNotPortable/pkg.cabal
@@ -0,0 +1,13 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Module
+  default-language: Haskell2010
+  cpp-options: -Q
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CxxOptionsExtraLibraries/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CxxOptionsExtraLibraries/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CxxOptionsExtraLibraries/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following warnings are likely to affect your build negatively:
+Warning: Instead of 'cxx-options: -lgame' use 'extra-libraries: game'
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CxxOptionsExtraLibraries/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CxxOptionsExtraLibraries/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CxxOptionsExtraLibraries/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- `cxx-options`, use `extra-libraries` instead of `-l`.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CxxOptionsExtraLibraries/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CxxOptionsExtraLibraries/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CxxOptionsExtraLibraries/pkg.cabal
@@ -0,0 +1,13 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Module
+  default-language: Haskell2010
+  cxx-options: -lgame
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CxxOs/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CxxOs/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CxxOs/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: 'cxx-options: -O[n]' is generally not needed. When building with  optimisations Cabal automatically adds '-O2' for C++ code. Setting it yourself interferes with the --disable-optimization flag.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CxxOs/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CxxOs/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CxxOs/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- `cxx-options`, do not use `-O1`.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CxxOs/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CxxOs/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/COptions/CxxOs/pkg.cabal
@@ -0,0 +1,13 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Module
+  default-language: Haskell2010
+  cxx-options: -O1
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/AutoGenMods/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/AutoGenMods/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/AutoGenMods/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/AutoGenMods/Setup.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/AutoGenMods/Setup.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/AutoGenMods/Setup.hs
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/AutoGenMods/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/AutoGenMods/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/AutoGenMods/cabal.out
@@ -0,0 +1,6 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: Packages using 'cabal-version: 2.0' and the autogenerated module Paths_* must include it also on the 'autogen-modules' field besides 'exposed-modules' and 'other-modules'. This specifies that the module does not come with the package and is generated on setup. Modules built with a custom Setup.hs script also go here to ensure that commands like sdist don't fail.
+Warning: Packages using 'cabal-version: 2.0' and the autogenerated module PackageInfo_* must include it in 'autogen-modules' as well as 'exposed-modules' and 'other-modules'. This specifies that the module does not come with the package and is generated on setup. Modules built with a custom Setup.hs script also go here to ensure that commands like sdist don't fail.
+Warning: To use the autogenerated module PackageInfo_* you need to specify `cabal-version: 3.12` or higher. This is not possible in `cabal 3.10`. To use this feature and be able to upload your package to Hackage, download `cabal 3.12`!
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/AutoGenMods/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/AutoGenMods/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/AutoGenMods/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- autogenerated modules in `autogen-modules` w/ ≥ 2.0.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/AutoGenMods/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/AutoGenMods/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/AutoGenMods/pkg.cabal
@@ -0,0 +1,17 @@
+cabal-version: 2.0
+build-type: Simple
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3
+license-file: LICENSE
+
+library
+  exposed-modules: Module
+  other-modules:
+    PackageInfo_pkg
+    Paths_pkg
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/CustomSetup/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/CustomSetup/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/CustomSetup/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/CustomSetup/Setup.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/CustomSetup/Setup.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/CustomSetup/Setup.hs
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/CustomSetup/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/CustomSetup/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/CustomSetup/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: From version 1.24 cabal supports specifying explicit dependencies for Custom setup scripts. Consider using 'cabal-version: 1.24' or higher and adding a 'custom-setup' section with a 'setup-depends' field that specifies the dependencies of the Setup.hs script itself. The 'setup-depends' field uses the same syntax as 'build-depends', so a simple example would be 'setup-depends: base, Cabal'.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/CustomSetup/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/CustomSetup/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/CustomSetup/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- `custom-setup` on ≥1.24.
+main = cabalTest $
+  cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/CustomSetup/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/CustomSetup/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/CustomSetup/pkg.cabal
@@ -0,0 +1,14 @@
+cabal-version: 1.12
+build-type: Custom
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3
+license-file: LICENSE
+
+library
+  exposed-modules: Module
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultExtension/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultExtension/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultExtension/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultExtension/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultExtension/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultExtension/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: pkg.cabal:14:3: The field "default-extensions" is available only since the Cabal specification version 1.10. This field will be ignored.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultExtension/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultExtension/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultExtension/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- `default-extensions` need ≥1.10.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultExtension/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultExtension/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultExtension/pkg.cabal
@@ -0,0 +1,14 @@
+cabal-version: >= 1.8
+build-type: Simple
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3
+license-file: LICENSE
+
+library
+  exposed-modules: Module
+  default-extensions: ScopedTypeVariables
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultLanguage/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultLanguage/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultLanguage/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultLanguage/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultLanguage/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultLanguage/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: pkg.cabal:14:3: The field "default-language" is available only since the Cabal specification version 1.10. This field will be ignored.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultLanguage/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultLanguage/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultLanguage/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- `default-language` need ≥1.10.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultLanguage/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultLanguage/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultLanguage/pkg.cabal
@@ -0,0 +1,14 @@
+cabal-version: >= 1.8
+build-type: Simple
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3
+license-file: LICENSE
+
+library
+  exposed-modules: Module
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultLanguageSpec/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultLanguageSpec/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultLanguageSpec/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following warnings are likely to affect your build negatively:
+Warning: Packages using 'cabal-version: >= 1.10' and before 'cabal-version: 3.4' must specify the 'default-language' field for each component (e.g. Haskell98 or Haskell2010). If a component uses different languages in different modules then list the other ones in the 'other-languages' field.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultLanguageSpec/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultLanguageSpec/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultLanguageSpec/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- You need to specify `default-language`.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultLanguageSpec/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultLanguageSpec/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/DefaultLanguageSpec/pkg.cabal
@@ -0,0 +1,11 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Module
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtensionBreak/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtensionBreak/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtensionBreak/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtensionBreak/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtensionBreak/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtensionBreak/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: Unfortunately the language extensions 'MonoPatBinds' break the parser in earlier Cabal versions so you need to specify 'cabal-version: >= 1.4'. Alternatively if you require compatibility with earlier Cabal versions then you may be able to use an equivalent compiler-specific flag.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtensionBreak/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtensionBreak/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtensionBreak/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Some extension need ≥1.2.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtensionBreak/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtensionBreak/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtensionBreak/pkg.cabal
@@ -0,0 +1,14 @@
+cabal-version: >= 1.2
+build-type: Simple
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: BSD3
+license-file: LICENSE
+
+library
+  exposed-modules: Module
+  extensions: MonoPatBinds
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Extensions/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Extensions/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Extensions/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Extensions/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Extensions/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Extensions/cabal.out
@@ -0,0 +1,6 @@
+# cabal check
+Warning: The following warnings are likely to affect your build negatively:
+Warning: For packages using 'cabal-version: >= 1.10' the 'extensions' field is deprecated. The new 'default-extensions' field lists extensions that are used in all modules in the component, while the 'other-extensions' field lists extensions that are used in some modules, e.g. via the {-# LANGUAGE #-} pragma.
+Warning: These warnings may cause trouble when distributing the package:
+Warning: pkg.cabal:14:3: The field "extensions" is deprecated in the Cabal specification version 1.12. Please use 'default-extensions' or 'other-extensions' fields.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Extensions/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Extensions/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Extensions/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- `extensions` deprecated.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Extensions/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Extensions/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Extensions/pkg.cabal
@@ -0,0 +1,15 @@
+cabal-version: 1.12
+build-type: Simple
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3
+license-file: LICENSE
+
+library
+  exposed-modules: Module
+  extensions: ScopedTypeVariables
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraDoc/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraDoc/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraDoc/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraDoc/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraDoc/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraDoc/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: To use the 'extra-doc-files' field the package needs to specify 'cabal-version: 1.18' or higher.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraDoc/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraDoc/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraDoc/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- `extra-doc-files` need ≥1.18.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraDoc/docs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraDoc/docs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraDoc/docs
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraDoc/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraDoc/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraDoc/pkg.cabal
@@ -0,0 +1,16 @@
+cabal-version: >= 1.10
+build-type: Simple
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3
+license-file: LICENSE
+extra-doc-files: docs
+
+test-suite test
+  main-is: Main.hs
+  type: exitcode-stdio-1.0
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraDynamicLibraryFlavour/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraDynamicLibraryFlavour/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraDynamicLibraryFlavour/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraDynamicLibraryFlavour/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraDynamicLibraryFlavour/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraDynamicLibraryFlavour/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: pkg.cabal:14:3: The field "extra-dynamic-library-flavours" is available only since the Cabal specification version 3.0. This field will be ignored.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraDynamicLibraryFlavour/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraDynamicLibraryFlavour/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraDynamicLibraryFlavour/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- `extra-dynamic-library-flavour` need ≥3.0.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraDynamicLibraryFlavour/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraDynamicLibraryFlavour/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraDynamicLibraryFlavour/pkg.cabal
@@ -0,0 +1,15 @@
+cabal-version: 1.12
+build-type: Simple
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3
+license-file: LICENSE
+
+library
+  exposed-modules: Module
+  extra-dynamic-library-flavours: asm
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraFrameworkDirs/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraFrameworkDirs/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraFrameworkDirs/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraFrameworkDirs/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraFrameworkDirs/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraFrameworkDirs/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: To use the 'extra-framework-dirs' field the package needs to specify 'cabal-version: 1.24' or higher.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraFrameworkDirs/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraFrameworkDirs/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraFrameworkDirs/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- `extra-framework-dirs` need ≥1.24. (just warning)
+main = cabalTest $
+  cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraFrameworkDirs/dir/file b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraFrameworkDirs/dir/file
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraFrameworkDirs/dir/file
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraFrameworkDirs/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraFrameworkDirs/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/ExtraFrameworkDirs/pkg.cabal
@@ -0,0 +1,15 @@
+cabal-version: >= 1.10
+build-type: Simple
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3
+license-file: LICENSE
+
+library
+  exposed-modules: Module
+  default-language: Haskell98
+  extra-framework-dirs: dir
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Mixins/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Mixins/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Mixins/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Mixins/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Mixins/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Mixins/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: pkg.cabal:15:3: The field "mixins" is available only since the Cabal specification version 2.0. This field will be ignored.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Mixins/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Mixins/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Mixins/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- `mixins` need ≥2.0.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Mixins/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Mixins/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Mixins/pkg.cabal
@@ -0,0 +1,15 @@
+cabal-version: >= 1.10
+build-type: Simple
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3
+license-file: LICENSE
+
+library
+  exposed-modules: Module
+  default-language: Haskell98
+  mixins: base
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/MultiLibs/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/MultiLibs/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/MultiLibs/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/MultiLibs/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/MultiLibs/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/MultiLibs/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: To use multiple 'library' sections or a named library section the package needs to specify at least 'cabal-version: 2.0'.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/MultiLibs/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/MultiLibs/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/MultiLibs/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Multilibs or named libs need ≥2.0.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/MultiLibs/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/MultiLibs/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/MultiLibs/pkg.cabal
@@ -0,0 +1,13 @@
+cabal-version: >= 1.8
+build-type: Simple
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3
+license-file: LICENSE
+
+library lib
+  exposed-modules: Module
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Reexported/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Reexported/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Reexported/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Reexported/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Reexported/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Reexported/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: To use the 'reexported-module' field the package needs to specify 'cabal-version: 1.22' or higher.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Reexported/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Reexported/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Reexported/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- `reexported-module` need ≥1.22.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Reexported/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Reexported/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Reexported/pkg.cabal
@@ -0,0 +1,15 @@
+cabal-version: >= 1.10
+build-type: Simple
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3
+license-file: LICENSE
+
+library
+  exposed-modules: Module
+  default-language: Haskell98
+  reexported-modules: Mu
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/SourceRepository/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/SourceRepository/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/SourceRepository/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/SourceRepository/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/SourceRepository/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/SourceRepository/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: The 'source-repository' section is new in Cabal 1.6. Unfortunately it messes up the parser in earlier Cabal versions so you need to specify 'cabal-version: >= 1.6'.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/SourceRepository/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/SourceRepository/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/SourceRepository/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- `source-repository` need ≥1.6.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/SourceRepository/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/SourceRepository/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/SourceRepository/pkg.cabal
@@ -0,0 +1,17 @@
+cabal-version: >= 1.4
+build-type: Simple
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3
+license-file: LICENSE
+
+library
+  exposed-modules: Module
+
+source-repository head
+  type: darcs
+  location: http://www.example.org/darcs
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Sources/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Sources/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Sources/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Sources/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Sources/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Sources/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: pkg.cabal:14:3: The field "cmm-sources" is available only since the Cabal specification version 3.0. This field will be ignored.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Sources/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Sources/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Sources/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- `cmm-sources` and friends need ≥3.0.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Sources/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Sources/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Sources/pkg.cabal
@@ -0,0 +1,15 @@
+cabal-version: 1.12
+build-type: Simple
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3
+license-file: LICENSE
+
+library
+  exposed-modules: Module
+  cmm-sources: asm
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Testsuite1.8/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Testsuite1.8/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Testsuite1.8/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Testsuite1.8/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Testsuite1.8/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Testsuite1.8/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: The 'test-suite' section is new in Cabal 1.10. Unfortunately it messes up the parser in older Cabal versions so you must specify at least 'cabal-version: >= 1.8', but note that only Cabal 1.10 and later can actually run such test suites.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Testsuite1.8/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Testsuite1.8/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Testsuite1.8/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- test-suite need ≥1.8.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Testsuite1.8/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Testsuite1.8/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/Testsuite1.8/pkg.cabal
@@ -0,0 +1,14 @@
+cabal-version: >= 1.4
+build-type: Simple
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3
+license-file: LICENSE
+
+test-suite test
+  main-is: Main.hs
+  type: exitcode-stdio-1.0
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/VirtualModules/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/VirtualModules/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/VirtualModules/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/VirtualModules/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/VirtualModules/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/VirtualModules/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: pkg.cabal:14:3: The field "virtual-modules" is available only since the Cabal specification version 2.2. This field will be ignored.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/VirtualModules/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/VirtualModules/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/VirtualModules/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- `virtual-modules` need ≥2.2.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/VirtualModules/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/VirtualModules/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/VirtualModules/pkg.cabal
@@ -0,0 +1,15 @@
+cabal-version: 1.12
+build-type: Simple
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3
+license-file: LICENSE
+
+library
+  exposed-modules: Module
+  virtual-modules: Virtual
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/DeprecatedExtension/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/DeprecatedExtension/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/DeprecatedExtension/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: Deprecated extensions: 'RecordPuns'. Instead of 'RecordPuns' use 'NamedFieldPuns'.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/DeprecatedExtension/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/DeprecatedExtension/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/DeprecatedExtension/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Deprecated extension.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/DeprecatedExtension/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/DeprecatedExtension/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/DeprecatedExtension/pkg.cabal
@@ -0,0 +1,13 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Module
+  default-language: Haskell2010
+  default-extensions: RecordPuns
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/ImpossibleVersionRangeLib/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/ImpossibleVersionRangeLib/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/ImpossibleVersionRangeLib/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The package will not build sanely due to these errors:
+Warning: The package has an impossible version range for a dependency on an internal library: pkg:internal >1.0. This version range does not include the current package, and must be removed as the current package's library will always be used.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/ImpossibleVersionRangeLib/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/ImpossibleVersionRangeLib/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/ImpossibleVersionRangeLib/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Impossible version range for internal library.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/ImpossibleVersionRangeLib/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/ImpossibleVersionRangeLib/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/ImpossibleVersionRangeLib/pkg.cabal
@@ -0,0 +1,18 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Module
+  build-depends: base == 4.*,
+                 internal > 1.0
+  default-language: Haskell2010
+
+library internal
+  exposed-modules: Module
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/InvalidTestedWithRange/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/InvalidTestedWithRange/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/InvalidTestedWithRange/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: Invalid 'tested-with' version range: ghc ==6.10 && ==7.1. To indicate that you have tested a package with multiple different versions of the same compiler use multiple entries, for example 'tested-with: GHC==6.10.4, GHC==6.12.3' and not 'tested-with: GHC==6.10.4 && ==6.12.3'.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/InvalidTestedWithRange/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/InvalidTestedWithRange/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/InvalidTestedWithRange/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Invalid `tested-with` range.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/InvalidTestedWithRange/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/InvalidTestedWithRange/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/InvalidTestedWithRange/pkg.cabal
@@ -0,0 +1,13 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+tested-with: GHC== 6.10 && ==7.1
+
+library
+  exposed-modules: Module
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/KnownTypeAbstractions/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/KnownTypeAbstractions/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/KnownTypeAbstractions/cabal.out
@@ -0,0 +1,2 @@
+# cabal check
+No errors or warnings could be found in the package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/KnownTypeAbstractions/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/KnownTypeAbstractions/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/KnownTypeAbstractions/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Uknown extension, exception for TypeAbstractions, see #9496
+main = cabalTest $
+  cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/KnownTypeAbstractions/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/KnownTypeAbstractions/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/KnownTypeAbstractions/pkg.cabal
@@ -0,0 +1,13 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Module
+  default-language: Haskell2010
+  default-extensions: TypeAbstractions
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/LanguageAsExtension/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/LanguageAsExtension/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/LanguageAsExtension/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following warnings are likely to affect your build negatively:
+Warning: Languages listed as extensions: Haskell98. Languages must be specified in either the 'default-language'  or the 'other-languages' field.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/LanguageAsExtension/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/LanguageAsExtension/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/LanguageAsExtension/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Language listed as extension.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/LanguageAsExtension/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/LanguageAsExtension/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/LanguageAsExtension/pkg.cabal
@@ -0,0 +1,13 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Module
+  default-language: Haskell2010
+  default-extensions: Haskell98
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoBuildTypeSpecified/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoBuildTypeSpecified/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoBuildTypeSpecified/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoBuildTypeSpecified/Setup.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoBuildTypeSpecified/Setup.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoBuildTypeSpecified/Setup.hs
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoBuildTypeSpecified/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoBuildTypeSpecified/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoBuildTypeSpecified/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following warnings are likely to affect your build negatively:
+Warning: No 'build-type' specified. If you do not need a custom Setup.hs or ./configure script then use 'build-type: Simple'.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoBuildTypeSpecified/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoBuildTypeSpecified/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoBuildTypeSpecified/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- No build-type specified.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoBuildTypeSpecified/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoBuildTypeSpecified/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoBuildTypeSpecified/pkg.cabal
@@ -0,0 +1,15 @@
+cabal-version: 2.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3
+license-file: LICENSE
+
+custom-setup
+
+library
+  exposed-modules: Module
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoCategory/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoCategory/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoCategory/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: No 'category' field.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoCategory/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoCategory/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoCategory/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- No category.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoCategory/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoCategory/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoCategory/pkg.cabal
@@ -0,0 +1,11 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Module
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoCustom/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoCustom/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoCustom/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following warnings are likely to affect your build negatively:
+Warning: Ignoring the 'custom-setup' section because the 'build-type' is not 'Custom'. Use 'build-type: Custom' if you need to use a custom Setup.hs script.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoCustom/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoCustom/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoCustom/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- No custom-setup with build-type: simple.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoCustom/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoCustom/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoCustom/pkg.cabal
@@ -0,0 +1,15 @@
+cabal-version: 3.0
+build-type: Simple
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+custom-setup
+
+library
+  exposed-modules: Module
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoDescription/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoDescription/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoDescription/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: No 'description' field.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoDescription/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoDescription/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoDescription/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- No description.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoDescription/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoDescription/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoDescription/pkg.cabal
@@ -0,0 +1,11 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Module
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoMaintainer/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoMaintainer/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoMaintainer/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: No 'maintainer' field.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoMaintainer/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoMaintainer/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoMaintainer/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- No maintainer.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoMaintainer/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoMaintainer/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoMaintainer/pkg.cabal
@@ -0,0 +1,11 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Module
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoSynopsis/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoSynopsis/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoSynopsis/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: No 'synopsis' field.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoSynopsis/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoSynopsis/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoSynopsis/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- No synopsis.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoSynopsis/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoSynopsis/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoSynopsis/pkg.cabal
@@ -0,0 +1,11 @@
+cabal-version: 3.0
+name: pkg
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Module
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoZPrefix/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoZPrefix/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoZPrefix/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: Package names with the prefix 'z-' are reserved by Cabal and cannot be used.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoZPrefix/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoZPrefix/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoZPrefix/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- no z-prefixed package names
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoZPrefix/z-pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoZPrefix/z-pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NoZPrefix/z-pkg.cabal
@@ -0,0 +1,12 @@
+cabal-version: 3.0
+name: z-pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Module
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/ShortDescription/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/ShortDescription/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/ShortDescription/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: The 'description' field should be longer than the 'synopsis' field. It's useful to provide an informative 'description' to allow Haskell programmers who have never heard about your package to understand the purpose of your package. The 'description' field content is typically shown by tooling (e.g. 'cabal info', Haddock, Hackage) below the 'synopsis' which serves as a headline. Please refer to <https://cabal.readthedocs.io/en/stable/cabal-package.html#package-properties> for more details.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/ShortDescription/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/ShortDescription/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/ShortDescription/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Description should be longer than synopsis.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/ShortDescription/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/ShortDescription/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/ShortDescription/pkg.cabal
@@ -0,0 +1,12 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis, elaborated one
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Module
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/UnknownCompiler/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/UnknownCompiler/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/UnknownCompiler/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following warnings are likely to affect your build negatively:
+Warning: Unknown compiler 'figforth' in 'tested-with' field.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/UnknownCompiler/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/UnknownCompiler/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/UnknownCompiler/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Uknown compiler in `tested-with`.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/UnknownCompiler/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/UnknownCompiler/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/UnknownCompiler/pkg.cabal
@@ -0,0 +1,13 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+tested-with: figforth
+
+library
+  exposed-modules: Module
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/UnknownExtension/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/UnknownExtension/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/UnknownExtension/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following warnings are likely to affect your build negatively:
+Warning: Unknown extensions: ObliqueTypes
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/UnknownExtension/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/UnknownExtension/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/UnknownExtension/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Uknown extension.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/UnknownExtension/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/UnknownExtension/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/UnknownExtension/pkg.cabal
@@ -0,0 +1,13 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Module
+  default-language: Haskell2010
+  default-extensions: ObliqueTypes
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/UnknownLanguage/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/UnknownLanguage/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/UnknownLanguage/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following warnings are likely to affect your build negatively:
+Warning: Unknown languages: Haskell2030
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/UnknownLanguage/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/UnknownLanguage/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/UnknownLanguage/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Uknown language.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/UnknownLanguage/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/UnknownLanguage/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/UnknownLanguage/pkg.cabal
@@ -0,0 +1,12 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Module
+  default-language: Haskell2030
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/GHCOptions/GHCOptions/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/GHCOptions/GHCOptions/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/GHCOptions/GHCOptions/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: 'ghc-options: -fasm' is unnecessary and will not work on CPU architectures other than x86, x86-64, ppc or sparc.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/GHCOptions/GHCOptions/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/GHCOptions/GHCOptions/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/GHCOptions/GHCOptions/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Tricky option in `ghc-options`.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/GHCOptions/GHCOptions/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/GHCOptions/GHCOptions/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/GHCOptions/GHCOptions/pkg.cabal
@@ -0,0 +1,13 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Module
+  default-language: Haskell2010
+  ghc-options: -fasm
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/GHCOptions/GHCProfOptions/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/GHCOptions/GHCProfOptions/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/GHCOptions/GHCProfOptions/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following warnings are likely to affect your build negatively:
+Warning: 'ghc-prof-options: -o' is not needed. The output files are named automatically.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/GHCOptions/GHCProfOptions/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/GHCOptions/GHCProfOptions/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/GHCOptions/GHCProfOptions/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Tricky option in `ghc-prof-options`.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/GHCOptions/GHCProfOptions/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/GHCOptions/GHCProfOptions/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/GHCOptions/GHCProfOptions/pkg.cabal
@@ -0,0 +1,13 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Module
+  default-language: Haskell2010
+  ghc-prof-options: -o
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/GHCOptions/GHCSharedOptions/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/GHCOptions/GHCSharedOptions/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/GHCOptions/GHCSharedOptions/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: Instead of 'ghc-shared-options: -fglasgow-exts' it is preferable to use the 'extensions' field.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/GHCOptions/GHCSharedOptions/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/GHCOptions/GHCSharedOptions/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/GHCOptions/GHCSharedOptions/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Tricky option in `ghc-shared-options`.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/GHCOptions/GHCSharedOptions/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/GHCOptions/GHCSharedOptions/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/GHCOptions/GHCSharedOptions/pkg.cabal
@@ -0,0 +1,13 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Module
+  default-language: Haskell2010
+  ghc-shared-options: -fglasgow-exts
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/Compatibility/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/Compatibility/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/Compatibility/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/Compatibility/Setup.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/Compatibility/Setup.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/Compatibility/Setup.hs
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/Compatibility/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/Compatibility/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/Compatibility/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: Unfortunately the license 'ISC' messes up the parser in earlier Cabal versions so you need to specify 'cabal-version: >= 1.4'. Alternatively if you require compatibility with earlier Cabal versions then use 'OtherLicense'.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/Compatibility/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/Compatibility/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/Compatibility/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Compatibility w/ ≤1.4.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/Compatibility/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/Compatibility/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/Compatibility/pkg.cabal
@@ -0,0 +1,15 @@
+cabal-version: >= 1.2
+build-type: Custom
+name: pkg
+version: 0
+category: example
+maintainer: none@example.com
+synopsis: synopsis
+description: description
+license: ISC
+license-file: LICENSE
+
+custom-setup
+
+library
+  exposed-modules: Foo
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoFileSpecified/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoFileSpecified/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoFileSpecified/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoFileSpecified/Setup.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoFileSpecified/Setup.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoFileSpecified/Setup.hs
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoFileSpecified/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoFileSpecified/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoFileSpecified/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: A 'license-file' is not specified.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoFileSpecified/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoFileSpecified/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoFileSpecified/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- `licence-file` missing.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoFileSpecified/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoFileSpecified/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoFileSpecified/pkg.cabal
@@ -0,0 +1,15 @@
+cabal-version: 2.0
+build-type: Custom
+name: pkg
+version: 0
+category: example
+maintainer: none@example.com
+synopsis: synopsis
+description: description
+license: GPL-3
+
+custom-setup
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoLicense/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoLicense/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoLicense/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: The 'license' field is missing or is NONE.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoLicense/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoLicense/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoLicense/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- No license.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoLicense/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoLicense/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoLicense/pkg.cabal
@@ -0,0 +1,11 @@
+cabal-version: 3.0
+name: pkg
+version: 0
+category: example
+maintainer: none@example.com
+synopsis: synopsis
+description: description
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoneLicense/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoneLicense/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoneLicense/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: The 'license' field is missing or is NONE.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoneLicense/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoneLicense/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoneLicense/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- NONE license.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoneLicense/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoneLicense/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/NoneLicense/pkg.cabal
@@ -0,0 +1,12 @@
+cabal-version: 3.0
+name: pkg
+version: 0
+category: example
+maintainer: none@example.com
+synopsis: synopsis
+description: description
+license: NONE
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/SuspiciousLicense/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/SuspiciousLicense/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/SuspiciousLicense/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/SuspiciousLicense/Setup.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/SuspiciousLicense/Setup.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/SuspiciousLicense/Setup.hs
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/SuspiciousLicense/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/SuspiciousLicense/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/SuspiciousLicense/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: Using 'license: BSD4' is almost always a misunderstanding. 'BSD4' refers to the old 4-clause BSD license with the advertising clause. 'BSD3' refers the new 3-clause BSD license.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/SuspiciousLicense/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/SuspiciousLicense/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/SuspiciousLicense/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Suspicious license BSD4.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/SuspiciousLicense/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/SuspiciousLicense/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/SuspiciousLicense/pkg.cabal
@@ -0,0 +1,16 @@
+cabal-version: 2.0
+build-type: Custom
+name: pkg
+version: 0
+category: example
+maintainer: none@example.com
+synopsis: synopsis
+description: description
+license: BSD4
+license-file: LICENSE
+
+custom-setup
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/SuspiciousVersion/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/SuspiciousVersion/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/SuspiciousVersion/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/SuspiciousVersion/Setup.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/SuspiciousVersion/Setup.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/SuspiciousVersion/Setup.hs
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/SuspiciousVersion/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/SuspiciousVersion/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/SuspiciousVersion/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: 'license: GPL-5' is not a known version of that license. The known versions are 2, 3. If this is not a mistake and you think it should be a known version then please file a ticket.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/SuspiciousVersion/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/SuspiciousVersion/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/SuspiciousVersion/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Suspicious license version.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/SuspiciousVersion/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/SuspiciousVersion/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/SuspiciousVersion/pkg.cabal
@@ -0,0 +1,16 @@
+cabal-version: 2.0
+build-type: Custom
+name: pkg
+version: 0
+category: example
+maintainer: none@example.com
+synopsis: synopsis
+description: description
+license: GPL-5
+license-file: LICENSE
+
+custom-setup
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/UnknownLicence/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/UnknownLicence/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/UnknownLicence/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/UnknownLicence/Setup.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/UnknownLicence/Setup.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/UnknownLicence/Setup.hs
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/UnknownLicence/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/UnknownLicence/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/UnknownLicence/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following warnings are likely to affect your build negatively:
+Warning: 'license: Illiberal' is not a recognised license. The known licenses are: GPL, GPL-2, GPL-3, LGPL, LGPL-2.1, LGPL-3, AGPL, AGPL-3, BSD2, BSD3, MIT, ISC, MPL-2.0, Apache, Apache-2.0, PublicDomain, AllRightsReserved, OtherLicense
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/UnknownLicence/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/UnknownLicence/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/UnknownLicence/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Unknown license.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/UnknownLicence/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/UnknownLicence/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/UnknownLicence/pkg.cabal
@@ -0,0 +1,16 @@
+cabal-version: 2.0
+build-type: Custom
+name: pkg
+version: 0
+category: example
+maintainer: none@example.com
+synopsis: synopsis
+description: description
+license: Illiberal
+license-file: LICENSE
+
+custom-setup
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/WarnAllRightsReserved/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/WarnAllRightsReserved/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/WarnAllRightsReserved/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/WarnAllRightsReserved/Setup.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/WarnAllRightsReserved/Setup.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/WarnAllRightsReserved/Setup.hs
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/WarnAllRightsReserved/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/WarnAllRightsReserved/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/WarnAllRightsReserved/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: The 'license' is AllRightsReserved. Is that really what you want?
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/WarnAllRightsReserved/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/WarnAllRightsReserved/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/WarnAllRightsReserved/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Dubious AllRightsReserved.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/WarnAllRightsReserved/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/WarnAllRightsReserved/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/License/WarnAllRightsReserved/pkg.cabal
@@ -0,0 +1,16 @@
+cabal-version: 2.0
+build-type: Custom
+name: pkg
+version: 0
+category: example
+maintainer: none@example.com
+synopsis: synopsis
+description: description
+license: AllRightsReserved
+license-file: LICENSE
+
+custom-setup
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/AbsolutePath/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/AbsolutePath/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/AbsolutePath/cabal.out
@@ -0,0 +1,7 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: In 'extra-source-files': the pattern '/home/user/file' does not match any files.
+Warning: The following errors will cause portability problems on other environments:
+Warning: 'extra-source-files: /home/user/file' specifies an absolute path, but the 'extra-source-files' field must use relative paths.
+Warning: 'extra-source-files: /home/user/file' is not a good relative path: "posix absolute path"
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/AbsolutePath/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/AbsolutePath/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/AbsolutePath/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Absolute path.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/AbsolutePath/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/AbsolutePath/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/AbsolutePath/pkg.cabal
@@ -0,0 +1,13 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+extra-source-files: /home/user/file
+
+library
+  exposed-modules: Module
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/DistPoint/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/DistPoint/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/DistPoint/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: 'ghc-options' path 'dist/file' points inside the 'dist' directory. This is not reliable because the location of this directory is configurable by the user (or package manager). In addition the layout of the 'dist' directory is subject to change in future versions of Cabal.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/DistPoint/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/DistPoint/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/DistPoint/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Points to dist.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/DistPoint/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/DistPoint/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/DistPoint/pkg.cabal
@@ -0,0 +1,13 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Module
+  default-language: Haskell2010
+  ghc-options: -m dist/file
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/InvalidWin/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/InvalidWin/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/InvalidWin/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: The path 'n?ul/*.a' is invalid on Windows, which would cause portability problems for this package. Windows file names cannot contain any of the characters ":*?<>|" and there a few reserved names including "aux", "nul", "con", "prn", "com1-9", "lpt1-9" and "clock$".
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/InvalidWin/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/InvalidWin/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/InvalidWin/cabal.test.hs
@@ -0,0 +1,13 @@
+import Test.Cabal.Prelude
+
+import System.Directory (createDirectoryIfMissing)
+
+-- Invalid Windows filepath.
+main = cabalTest . withSourceCopy $ do
+  skipIfWindows
+  cwd <- testCurrentDir <$> getTestEnv
+  liftIO $ createDirectoryIfMissing False $ cwd </> "n?ul"
+  liftIO $ writeFile (cwd </> "n?ul" </> "test.a") ""
+    -- A directory named like `n?ul` on Windows will make external
+    -- tools like git — and hence the whole testsuite — error.
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/InvalidWin/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/InvalidWin/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/InvalidWin/pkg.cabal
@@ -0,0 +1,13 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+extra-source-files: n?ul/*.a
+
+library
+  exposed-modules: Module
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/RecursiveGlobInRoot/a.dat b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/RecursiveGlobInRoot/a.dat
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/RecursiveGlobInRoot/a.dat
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/RecursiveGlobInRoot/a.md b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/RecursiveGlobInRoot/a.md
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/RecursiveGlobInRoot/a.md
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/RecursiveGlobInRoot/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/RecursiveGlobInRoot/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/RecursiveGlobInRoot/cabal.out
@@ -0,0 +1,11 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: In the 'data-files': glob '**/*.dat' starts at project root
+directory, this might include `.git/`, ``dist-newstyle/``, or other large
+directories!
+Warning: In the 'extra-source-files': glob '**/*.hs' starts at project root
+directory, this might include `.git/`, ``dist-newstyle/``, or other large
+directories!
+Warning: In the 'extra-doc-files': glob '**/*.md' starts at project root
+directory, this might include `.git/`, ``dist-newstyle/``, or other large
+directories!
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/RecursiveGlobInRoot/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/RecursiveGlobInRoot/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/RecursiveGlobInRoot/cabal.test.hs
@@ -0,0 +1,4 @@
+import Test.Cabal.Prelude
+
+main = cabalTest $
+  cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/RecursiveGlobInRoot/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/RecursiveGlobInRoot/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/RecursiveGlobInRoot/pkg.cabal
@@ -0,0 +1,19 @@
+cabal-version: 3.8
+name: pkg
+version: 0
+extra-source-files:
+  **/*.hs
+data-files:
+  **/*.dat
+extra-doc-files:
+  **/*.md
+license: BSD-3-Clause
+synopsis: no
+description: none
+category: Test
+maintainer: none
+
+library
+  default-language: Haskell2010
+  exposed-modules:
+    Foo
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/RelativeOutside/RelativeOutsideInner/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/RelativeOutside/RelativeOutsideInner/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/RelativeOutside/RelativeOutsideInner/cabal.out
@@ -0,0 +1,6 @@
+# cabal check
+Warning: The following warnings are likely to affect your build negatively:
+Warning: 'extra-source-files: ../outside' is a relative path outside of the source tree. This will not work when generating a tarball with 'sdist'.
+Warning: The following errors will cause portability problems on other environments:
+Warning: 'extra-source-files: ../outside' is not a good relative path: "parent directory segment: .."
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/RelativeOutside/RelativeOutsideInner/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/RelativeOutside/RelativeOutsideInner/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/RelativeOutside/RelativeOutsideInner/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Relative filepath outside source tree.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/RelativeOutside/RelativeOutsideInner/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/RelativeOutside/RelativeOutsideInner/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/RelativeOutside/RelativeOutsideInner/pkg.cabal
@@ -0,0 +1,13 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+extra-source-files: ../outside
+
+library
+  exposed-modules: Module
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/RelativeOutside/outside b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/RelativeOutside/outside
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Paths/RelativeOutside/outside
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOther/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOther/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOther/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The package will not build sanely due to these errors:
+Warning: An 'autogen-module' is neither on 'exposed-modules' or 'other-modules'.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOther/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOther/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOther/cabal.test.hs
@@ -0,0 +1,6 @@
+import Test.Cabal.Prelude
+
+-- All `autogen-modules` have to appear in `other-modules` or
+-- `exposed-modules`.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOther/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOther/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOther/pkg.cabal
@@ -0,0 +1,13 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
+  autogen-modules: AutoGenMod
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOtherBenchmark/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOtherBenchmark/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOtherBenchmark/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The package will not build sanely due to these errors:
+Warning: On benchmark 'benchmark' an 'autogen-module' is not on 'other-modules'
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOtherBenchmark/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOtherBenchmark/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOtherBenchmark/cabal.test.hs
@@ -0,0 +1,6 @@
+import Test.Cabal.Prelude
+
+-- All `autogen-modules` have to appear in `other-modules` or
+-- `exposed-modules` (benchmark).
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOtherBenchmark/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOtherBenchmark/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOtherBenchmark/pkg.cabal
@@ -0,0 +1,14 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+benchmark benchmark
+  main-is: Main.hs
+  default-language: Haskell2010
+  autogen-modules: AutoGenMod
+  type: exitcode-stdio-1.0
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOtherExe/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOtherExe/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOtherExe/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The package will not build sanely due to these errors:
+Warning: On executable 'exe' an 'autogen-module' is not on 'other-modules'
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOtherExe/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOtherExe/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOtherExe/cabal.test.hs
@@ -0,0 +1,6 @@
+import Test.Cabal.Prelude
+
+-- All `autogen-modules` have to appear in `other-modules` or
+-- `exposed-modules` (executables).
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOtherExe/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOtherExe/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOtherExe/pkg.cabal
@@ -0,0 +1,13 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+executable exe
+  main-is: Main.hs
+  default-language: Haskell2010
+  autogen-modules: AutoGenMod
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOtherTestsuite/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOtherTestsuite/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOtherTestsuite/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The package will not build sanely due to these errors:
+Warning: On test suite 'test' an 'autogen-module' is not on 'other-modules'
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOtherTestsuite/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOtherTestsuite/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOtherTestsuite/cabal.test.hs
@@ -0,0 +1,6 @@
+import Test.Cabal.Prelude
+
+-- All `autogen-modules` have to appear in `other-modules` or
+-- `exposed-modules` (testsuite).
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOtherTestsuite/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOtherTestsuite/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenExposedOtherTestsuite/pkg.cabal
@@ -0,0 +1,14 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+test-suite test
+  main-is: Main.hs
+  default-language: Haskell2010
+  autogen-modules: AutoGenMod
+  type: exitcode-stdio-1.0
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludes/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludes/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludes/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The package will not build sanely due to these errors:
+Warning: An include in 'autogen-includes' is neither in 'includes' or 'install-includes'.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludes/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludes/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludes/cabal.test.hs
@@ -0,0 +1,6 @@
+import Test.Cabal.Prelude
+
+-- All `autogen-includes` should appear in `install-includes` or
+-- `includes`.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludes/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludes/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludes/pkg.cabal
@@ -0,0 +1,13 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
+  autogen-includes: AutoGenInc
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludesBenchmark/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludesBenchmark/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludesBenchmark/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The package will not build sanely due to these errors:
+Warning: An include in 'autogen-includes' is not in 'includes'.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludesBenchmark/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludesBenchmark/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludesBenchmark/cabal.test.hs
@@ -0,0 +1,6 @@
+import Test.Cabal.Prelude
+
+-- All `autogen-includes` should appear in `install-includes` or
+-- `includes` (benchmark).
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludesBenchmark/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludesBenchmark/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludesBenchmark/pkg.cabal
@@ -0,0 +1,14 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+benchmark benchmark
+  main-is: Main.hs
+  autogen-includes: AutoGenInc
+  default-language: Haskell2010
+  type: exitcode-stdio-1.0
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludesExe/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludesExe/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludesExe/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The package will not build sanely due to these errors:
+Warning: An include in 'autogen-includes' is not in 'includes'.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludesExe/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludesExe/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludesExe/cabal.test.hs
@@ -0,0 +1,6 @@
+import Test.Cabal.Prelude
+
+-- All `autogen-includes` should appear in `install-includes` or
+-- `includes` (executable).
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludesExe/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludesExe/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludesExe/pkg.cabal
@@ -0,0 +1,13 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+executable exe
+  main-is: Main.hs
+  autogen-includes: AutoGenInc
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludesTestsuite/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludesTestsuite/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludesTestsuite/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The package will not build sanely due to these errors:
+Warning: An include in 'autogen-includes' is not in 'includes'.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludesTestsuite/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludesTestsuite/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludesTestsuite/cabal.test.hs
@@ -0,0 +1,6 @@
+import Test.Cabal.Prelude
+
+-- All `autogen-includes` should appear in `install-includes` or
+-- `includes` (testsuite).
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludesTestsuite/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludesTestsuite/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenIncludesTestsuite/pkg.cabal
@@ -0,0 +1,14 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+test-suite test
+  main-is: Main.hs
+  autogen-includes: AutoGenInc
+  default-language: Haskell2010
+  type: exitcode-stdio-1.0
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenVersion/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenVersion/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenVersion/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: To use the autogenerated module PackageInfo_* you need to specify `cabal-version: 3.12` or higher. This is not possible in `cabal 3.10`. To use this feature and be able to upload your package to Hackage, download `cabal 3.12`!
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenVersion/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenVersion/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenVersion/cabal.test.hs
@@ -0,0 +1,6 @@
+import Test.Cabal.Prelude
+
+-- #9331: PackageInfo functionality should be guarded by cabal-version.
+main = cabalTest $
+  fails $ cabal "check" []
+
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenVersion/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenVersion/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/AutogenVersion/pkg.cabal
@@ -0,0 +1,16 @@
+cabal-version: 2.4
+name: pkg
+version: 0
+license: GPL-3.0-or-later
+maintainer: Someone
+category: Example
+synopsis: Foo
+description: FooBar
+build-type: Simple
+
+library
+    default-language: Haskell2010
+    build-depends: base <5
+    autogen-modules: PackageInfo_pkg
+    exposed-modules: PackageInfo_pkg
+
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/CMainIsVersion/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/CMainIsVersion/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/CMainIsVersion/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/CMainIsVersion/Setup.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/CMainIsVersion/Setup.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/CMainIsVersion/Setup.hs
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/CMainIsVersion/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/CMainIsVersion/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/CMainIsVersion/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: The package uses a C/C++/obj-C source file for the 'main-is' field. To use this feature you need to specify 'cabal-version: 1.18' or higher.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/CMainIsVersion/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/CMainIsVersion/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/CMainIsVersion/cabal.test.hs
@@ -0,0 +1,6 @@
+import Test.Cabal.Prelude
+
+-- You need `cabal-version` ≥ 1.18 to use C/C++/obj-C source files
+-- in `main-is`.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/CMainIsVersion/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/CMainIsVersion/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/CMainIsVersion/pkg.cabal
@@ -0,0 +1,16 @@
+cabal-version: 1.12
+build-type: Custom
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3
+license-file: LICENSE
+
+custom-setup
+
+executable exe
+    main-is: main.c
+    default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/CMainIsVersionTestsuite/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/CMainIsVersionTestsuite/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/CMainIsVersionTestsuite/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/CMainIsVersionTestsuite/Setup.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/CMainIsVersionTestsuite/Setup.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/CMainIsVersionTestsuite/Setup.hs
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/CMainIsVersionTestsuite/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/CMainIsVersionTestsuite/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/CMainIsVersionTestsuite/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: The package uses a C/C++/obj-C source file for the 'main-is' field. To use this feature you need to specify 'cabal-version: 1.18' or higher.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/CMainIsVersionTestsuite/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/CMainIsVersionTestsuite/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/CMainIsVersionTestsuite/cabal.test.hs
@@ -0,0 +1,6 @@
+import Test.Cabal.Prelude
+
+-- You need `cabal-version` ≥ 1.18 to use C/C++/obj-C source files
+-- in `main-is`. (testsuite)
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/CMainIsVersionTestsuite/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/CMainIsVersionTestsuite/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/CMainIsVersionTestsuite/pkg.cabal
@@ -0,0 +1,17 @@
+cabal-version: 1.12
+build-type: Custom
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3
+license-file: LICENSE
+
+custom-setup
+
+test-suite test
+    main-is: main.c
+    default-language: Haskell2010
+    type: exitcode-stdio-1.0
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/MalformedMainIs/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/MalformedMainIs/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/MalformedMainIs/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The package will not build sanely due to these errors:
+Warning: The 'main-is' field must specify a '.hs' or '.lhs' file (even if it is generated by a preprocessor), or it may specify a C/C++/obj-C source file.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/MalformedMainIs/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/MalformedMainIs/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/MalformedMainIs/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- `main-is` has to be a `.hs` or `.lhs` file (or C* source file).
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/MalformedMainIs/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/MalformedMainIs/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/MalformedMainIs/pkg.cabal
@@ -0,0 +1,12 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+executable exe
+    main-is: Main
+    default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/MalformedMainIsBenchmark/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/MalformedMainIsBenchmark/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/MalformedMainIsBenchmark/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The package will not build sanely due to these errors:
+Warning: The 'main-is' field must specify a '.hs' or '.lhs' file (even if it is generated by a preprocessor).
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/MalformedMainIsBenchmark/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/MalformedMainIsBenchmark/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/MalformedMainIsBenchmark/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- `main-is` has to be a `.hs` or `.lhs` file (or C* source file) (benchmark).
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/MalformedMainIsBenchmark/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/MalformedMainIsBenchmark/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/MalformedMainIsBenchmark/pkg.cabal
@@ -0,0 +1,14 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+benchmark benchmark
+    Main-is: Main
+    type:    exitcode-stdio-1.0
+    default-language: Haskell2010
+
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/MalformedMainIsTestsuite/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/MalformedMainIsTestsuite/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/MalformedMainIsTestsuite/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The package will not build sanely due to these errors:
+Warning: The 'main-is' field must specify a '.hs' or '.lhs' file (even if it is generated by a preprocessor), or it may specify a C/C++/obj-C source file.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/MalformedMainIsTestsuite/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/MalformedMainIsTestsuite/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/MalformedMainIsTestsuite/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- `main-is` has to be a `.hs` or `.lhs` file (or C* source file) (testsuite).
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/MalformedMainIsTestsuite/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/MalformedMainIsTestsuite/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/MalformedMainIsTestsuite/pkg.cabal
@@ -0,0 +1,14 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+test-suite test
+    Main-is: Main
+    type:    exitcode-stdio-1.0
+    default-language: Haskell2010
+
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoBody/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoBody/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoBody/cabal.out
@@ -0,0 +1,6 @@
+# cabal check
+Warning: The package will not build sanely due to these errors:
+Warning: No executables, libraries, tests, or benchmarks found. Nothing to do.
+Warning: These warnings may cause trouble when distributing the package:
+Warning: pkg.cabal:0:0: A package using 'cabal-version: 2.2' must use section syntax. See the Cabal user guide for details.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoBody/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoBody/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoBody/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- No exec, library, test or benchmark.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoBody/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoBody/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoBody/pkg.cabal
@@ -0,0 +1,8 @@
+cabal-version: 2.2
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoDupNames/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoDupNames/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoDupNames/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: The package will not build sanely due to these errors:
+Warning: Duplicate sections: dup. The name of every library, executable, test suite, and benchmark section in the package must be unique.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoDupNames/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoDupNames/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoDupNames/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Duplicate section names.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoDupNames/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoDupNames/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoDupNames/pkg.cabal
@@ -0,0 +1,17 @@
+cabal-version: 2.2
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library dup
+  exposed-modules: Foo
+  default-language: Haskell2010
+
+test-suite dup
+  main-is: Main.hs
+  type: exitcode-stdio-1.0
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoExposedModules/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoExposedModules/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoExposedModules/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: library does not expose any modules
+
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoExposedModules/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoExposedModules/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoExposedModules/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- No exposed modules.
+main = cabalTest $
+  cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoExposedModules/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoExposedModules/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoExposedModules/pkg.cabal
@@ -0,0 +1,11 @@
+cabal-version: 2.2
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoInternalNameClash/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoInternalNameClash/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoInternalNameClash/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The package will not build sanely due to these errors:
+Warning: Illegal internal library name pkg. Internal libraries cannot have the same name as the package. Maybe you wanted a non-internal library? If so, rewrite the section stanza from 'library: 'pkg' to 'library'.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoInternalNameClash/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoInternalNameClash/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoInternalNameClash/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Internal library / package name clash.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoInternalNameClash/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoInternalNameClash/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoInternalNameClash/pkg.cabal
@@ -0,0 +1,12 @@
+cabal-version: 2.2
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library pkg
+  exposed-modules: Foo
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoMainIs/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoMainIs/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoMainIs/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The package will not build sanely due to these errors:
+Warning: No 'main-is' field found for executable exe
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoMainIs/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoMainIs/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoMainIs/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Missing `main-is`.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoMainIs/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoMainIs/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoMainIs/pkg.cabal
@@ -0,0 +1,11 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+executable exe
+    default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoName/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoName/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoName/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: pkg.cabal:0:0: "name" field missing
+Error: cabal: parse error
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoName/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoName/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoName/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- No package name.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoName/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoName/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoName/pkg.cabal
@@ -0,0 +1,11 @@
+cabal-version: 2.2
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoVersion/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoVersion/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoVersion/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: pkg.cabal:0:0: "version" field missing
+Error: cabal: parse error
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoVersion/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoVersion/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoVersion/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- No version.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoVersion/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoVersion/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/NoVersion/pkg.cabal
@@ -0,0 +1,11 @@
+cabal-version: 2.2
+name: pkg
+synopsis: synopsis
+description: description
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/OkDupNamesExe/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/OkDupNamesExe/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/OkDupNamesExe/cabal.out
@@ -0,0 +1,2 @@
+# cabal check
+No errors or warnings could be found in the package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/OkDupNamesExe/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/OkDupNamesExe/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/OkDupNamesExe/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- It is OK for executables to have the same name of the external library.
+main = cabalTest $
+  cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/OkDupNamesExe/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/OkDupNamesExe/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/OkDupNamesExe/pkg.cabal
@@ -0,0 +1,16 @@
+cabal-version: 2.2
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
+
+executable pkg
+  main-is: Main.hs
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/VersionSignatures/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/VersionSignatures/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/VersionSignatures/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/VersionSignatures/Setup.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/VersionSignatures/Setup.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/VersionSignatures/Setup.hs
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/VersionSignatures/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/VersionSignatures/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/VersionSignatures/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: pkg.cabal:17:3: The field "signatures" is available only since the Cabal specification version 2.0. This field will be ignored.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/VersionSignatures/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/VersionSignatures/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/VersionSignatures/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- `signatures` field used with cabal-version < 2.0
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/VersionSignatures/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/VersionSignatures/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Sanity/VersionSignatures/pkg.cabal
@@ -0,0 +1,17 @@
+cabal-version: 1.24
+build-type: Custom
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3
+license-file: LICENSE
+
+custom-setup
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
+  signatures: Str
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoGoodRelative/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoGoodRelative/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoGoodRelative/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: The 'subdir' field of a source-repository is not a good relative path: "empty path segment"
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoGoodRelative/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoGoodRelative/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoGoodRelative/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- `subdir` is not a good relative path.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoGoodRelative/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoGoodRelative/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoGoodRelative/pkg.cabal
@@ -0,0 +1,17 @@
+cabal-version: 3.0
+name: pkg
+version: 0
+category: example
+maintainer: none@example.com
+synopsis: synopsis
+description: description
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
+
+source-repository head
+  subdir: .//
+  type:     darcs
+  location: http://www.example.org
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoLocation/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoLocation/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoLocation/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: The source-repository 'location' is a required field.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoLocation/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoLocation/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoLocation/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- No `location`.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoLocation/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoLocation/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoLocation/pkg.cabal
@@ -0,0 +1,15 @@
+cabal-version: 3.0
+name: pkg
+version: 0
+category: example
+maintainer: none@example.com
+synopsis: synopsis
+description: description
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
+
+source-repository head
+  type:     darcs
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoModuleCVS/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoModuleCVS/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoModuleCVS/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: For a CVS source-repository, the 'module' is a required field.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoModuleCVS/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoModuleCVS/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoModuleCVS/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- No `module` (CVS only).
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoModuleCVS/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoModuleCVS/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoModuleCVS/pkg.cabal
@@ -0,0 +1,16 @@
+cabal-version: 3.0
+name: pkg
+version: 0
+category: example
+maintainer: none@example.com
+synopsis: synopsis
+description: description
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
+
+source-repository head
+  type:     CVS
+  location: http://www.example.org
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoType/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoType/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoType/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: The source-repository 'type' is a required field.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoType/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoType/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoType/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- No `type`.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoType/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoType/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NoType/pkg.cabal
@@ -0,0 +1,15 @@
+cabal-version: 3.0
+name: pkg
+version: 0
+category: example
+maintainer: none@example.com
+synopsis: synopsis
+description: description
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
+
+source-repository head
+  location: http://www.example.org
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NonRecognisedRepo/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NonRecognisedRepo/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NonRecognisedRepo/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: 'tail' is not a recognised kind of source-repository. The repo kind is usually 'head' or 'this'
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NonRecognisedRepo/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NonRecognisedRepo/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NonRecognisedRepo/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Non-regonised (head, this, etc.) repo.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NonRecognisedRepo/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NonRecognisedRepo/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/NonRecognisedRepo/pkg.cabal
@@ -0,0 +1,16 @@
+cabal-version: 3.0
+name: pkg
+version: 0
+category: example
+maintainer: none@example.com
+synopsis: synopsis
+description: description
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
+
+source-repository tail
+  type:     darcs
+  location: http://www.example.org
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/SubdirRelative/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/SubdirRelative/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/SubdirRelative/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: The 'subdir' field of a source-repository must be a relative path.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/SubdirRelative/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/SubdirRelative/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/SubdirRelative/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- `subdir` is not a relative path.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/SubdirRelative/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/SubdirRelative/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/SubdirRelative/pkg.cabal
@@ -0,0 +1,17 @@
+cabal-version: 3.0
+name: pkg
+version: 0
+category: example
+maintainer: none@example.com
+synopsis: synopsis
+description: description
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
+
+source-repository head
+  subdir: \\home
+  type:     darcs
+  location: http://www.example.org
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/ThisTag/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/ThisTag/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/ThisTag/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: For the 'this' kind of source-repository, the 'tag' is a required field. It should specify the tag corresponding to this version or release of the package.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/ThisTag/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/ThisTag/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/ThisTag/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- `tag` needed in `this` repos.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/ThisTag/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/ThisTag/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/ConfiguredPackage/SourceRepos/ThisTag/pkg.cabal
@@ -0,0 +1,16 @@
+cabal-version: 3.0
+name: pkg
+version: 0
+category: example
+maintainer: none@example.com
+synopsis: synopsis
+description: description
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
+
+source-repository this
+  type:     darcs
+  location: http://www.example.org
diff --git a/cabal/cabal-testsuite/PackageTests/Check/DifferentGhcOptions/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/DifferentGhcOptions/cabal.out
--- a/cabal/cabal-testsuite/PackageTests/Check/DifferentGhcOptions/cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/Check/DifferentGhcOptions/cabal.out
@@ -4,5 +4,5 @@
 Warning: The following errors will cause portability problems on other environments:
 Warning: 'ghc-options: -fasm' is unnecessary and will not work on CPU architectures other than x86, x86-64, ppc or sparc.
 Warning: 'ghc-prof-options: -fhpc' is not necessary. Use the configure flag  --enable-coverage instead.
-Warning: 'ghc-shared-options: -Wall -Werror' makes the package very easy to break with future GHC versions because new GHC versions often add new warnings. Use just 'ghc-shared-options: -Wall' instead. Alternatively, if you want to use this, make it conditional based on a Cabal configuration flag (with 'manual: True' and 'default: False') and enable that flag during development.
+Warning: 'ghc-shared-options: -Werror' makes the package easy to break with future GHC versions because new GHC versions often add new warnings. Alternatively, if you want to use this, make it conditional based on a Cabal configuration flag (with 'manual: True' and 'default: False') and enable that flag during development.
 Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/InvalidGlob/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/InvalidGlob/pkg.cabal
--- a/cabal/cabal-testsuite/PackageTests/Check/InvalidGlob/pkg.cabal
+++ b/cabal/cabal-testsuite/PackageTests/Check/InvalidGlob/pkg.cabal
@@ -10,4 +10,4 @@
 library
   exposed-modules: Foo
   default-language: Haskell2010
-  
+
diff --git a/cabal/cabal-testsuite/PackageTests/Check/MissingGlobDirectory/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/MissingGlobDirectory/pkg.cabal
--- a/cabal/cabal-testsuite/PackageTests/Check/MissingGlobDirectory/pkg.cabal
+++ b/cabal/cabal-testsuite/PackageTests/Check/MissingGlobDirectory/pkg.cabal
diff --git a/cabal/cabal-testsuite/PackageTests/Check/MissingGlobDirectory2/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/MissingGlobDirectory2/cabal.out
--- a/cabal/cabal-testsuite/PackageTests/Check/MissingGlobDirectory2/cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/Check/MissingGlobDirectory2/cabal.out
@@ -1,5 +1,5 @@
 # cabal check
 Warning: These warnings may cause trouble when distributing the package:
-Warning: In 'data-files': the pattern 'non-existent-directory/*.dat' attempts to match files in the directory 'non-existent-directory', but there is no directory by that name.
 Warning: In 'extra-source-files': the pattern 'dir/*.html' does not match any files.
 Warning: In 'extra-source-files': the pattern 'dir/*.html' does not match the file 'dir/foo.en.html' because the extensions do not exactly match (e.g., foo.en.html does not exactly match *.html). To enable looser suffix-only matching, set 'cabal-version: 2.4' or higher.
+Warning: In 'data-files': the pattern 'non-existent-directory/*.dat' attempts to match files in the directory 'non-existent-directory', but there is no directory by that name.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/Conditionals/UnknownArch/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/Conditionals/UnknownArch/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/Conditionals/UnknownArch/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: Unknown architecture name 'subleq'
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/Conditionals/UnknownArch/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/Conditionals/UnknownArch/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/Conditionals/UnknownArch/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Uknown arch name.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/Conditionals/UnknownArch/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/Conditionals/UnknownArch/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/Conditionals/UnknownArch/pkg.cabal
@@ -0,0 +1,15 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
+  if arch(subleq)
+    exposed-modules: Bar
+
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/Conditionals/UnknownCompiler/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/Conditionals/UnknownCompiler/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/Conditionals/UnknownCompiler/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: Unknown compiler name 'MHC'
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/Conditionals/UnknownCompiler/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/Conditionals/UnknownCompiler/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/Conditionals/UnknownCompiler/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Uknown compiler.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/Conditionals/UnknownCompiler/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/Conditionals/UnknownCompiler/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/Conditionals/UnknownCompiler/pkg.cabal
@@ -0,0 +1,15 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
+  if !impl(MHC)
+    exposed-modules: Bar
+
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/Conditionals/UnknownOS/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/Conditionals/UnknownOS/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/Conditionals/UnknownOS/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: Unknown operating system name 'plan9'
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/Conditionals/UnknownOS/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/Conditionals/UnknownOS/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/Conditionals/UnknownOS/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Uknown OS name.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/Conditionals/UnknownOS/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/Conditionals/UnknownOS/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/Conditionals/UnknownOS/pkg.cabal
@@ -0,0 +1,15 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
+  if os(plan9)
+    exposed-modules: Bar
+
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/DebugFlag/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/DebugFlag/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/DebugFlag/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: 'ghc-prof-options: -d*' debug flags are not appropriate for a distributed package. Alternatively, if you want to use this, make it conditional based on a Cabal configuration flag (with 'manual: True' and 'default: False') and enable that flag during development.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/DebugFlag/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/DebugFlag/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/DebugFlag/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Debug flags are inappropriate for release.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/DebugFlag/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/DebugFlag/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/DebugFlag/pkg.cabal
@@ -0,0 +1,14 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
+  ghc-prof-options: -ddump-asm
+
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/FDeferTypeErrors/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/FDeferTypeErrors/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/FDeferTypeErrors/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: 'ghc-options: -fdefer-type-errors' is fine during development but is not appropriate for a distributed package. Alternatively, if you want to use this, make it conditional based on a Cabal configuration flag (with 'manual: True' and 'default: False') and enable that flag during development.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/FDeferTypeErrors/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/FDeferTypeErrors/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/FDeferTypeErrors/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- -fdefer-type-errors
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/FDeferTypeErrors/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/FDeferTypeErrors/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/FDeferTypeErrors/pkg.cabal
@@ -0,0 +1,14 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
+  ghc-options: -fdefer-type-errors
+
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/Jn/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/Jn/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/Jn/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: 'ghc-shared-options: -j[N]' can make sense for specific user's setup, but it is not appropriate for a distributed package. Alternatively, if you want to use this, make it conditional based on a Cabal configuration flag (with 'manual: True' and 'default: False') and enable that flag during development.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/Jn/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/Jn/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/Jn/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- j[n].
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/Jn/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/Jn/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/Jn/pkg.cabal
@@ -0,0 +1,14 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
+  ghc-shared-options: -j4
+
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/Profiling/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/Profiling/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/Profiling/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: 'ghc-shared-options: -fprof*' profiling flags are typically not appropriate for a distributed library package. These flags are useful to profile this package, but when profiling other packages that use this one these flags clutter the profile output with excessive detail. If you think other packages really want to see cost centres from this package then use '-fprof-auto-exported' which puts cost centres only on exported functions. Alternatively, if you want to use this, make it conditional based on a Cabal configuration flag (with 'manual: True' and 'default: False') and enable that flag during development.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/Profiling/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/Profiling/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/Profiling/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Profiling flags unsuited for distribution.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/Profiling/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/Profiling/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/Profiling/pkg.cabal
@@ -0,0 +1,14 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
+  ghc-shared-options: -caf-all
+
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/WError/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/WError/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/WError/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: 'ghc-prof-options: -Werror' makes the package easy to break with future GHC versions because new GHC versions often add new warnings. Alternatively, if you want to use this, make it conditional based on a Cabal configuration flag (with 'manual: True' and 'default: False') and enable that flag during development.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/WError/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/WError/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/WError/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- WError without -W/-Wall.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/WError/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/WError/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DevOnlyFlags/WError/pkg.cabal
@@ -0,0 +1,14 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
+  ghc-prof-options: -Werror
+
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DuplicatedModules/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DuplicatedModules/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DuplicatedModules/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The package will not build sanely due to these errors:
+Warning: Duplicate modules in library: Foo
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DuplicatedModules/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DuplicatedModules/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DuplicatedModules/cabal.test.hs
@@ -0,0 +1,8 @@
+import Test.Cabal.Prelude
+
+-- Duplicated module.
+main = cabalTest $
+  fails $ cabal "check" []
+
+  -- TODO: note how conditional give a “potential duplicate”,
+  --       which is not true at all.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DuplicatedModules/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DuplicatedModules/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/DuplicatedModules/pkg.cabal
@@ -0,0 +1,19 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+    exposed-modules: Foo,
+                     Foo
+
+--   if os(linux)
+--     exposed-modules: Bar
+--   if !os(linux)
+--     exposed-modules: Bar
+
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/PackageVersions/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/PackageVersions/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/PackageVersions/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: The dependency 'build-depends: base' does not specify an upper bound on the version number. Each major release of the 'base' package changes the API in various ways and most packages will need some changes to compile with it. The recommended practice is to specify an upper bound on the version of the 'base' package. This ensures your package will continue to build when a new major version of the 'base' package is released. If you are not sure what upper bound to use then use the next  major version. For example if you have tested your package with 'base' version 4.5 and 4.6 then use 'build-depends: base >= 4.5 && < 4.7'.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/PackageVersions/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/PackageVersions/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/PackageVersions/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Unbounded (top) base.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/PackageVersions/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/PackageVersions/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/PackageVersions/pkg.cabal
@@ -0,0 +1,14 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
+  build-depends: base >= 3.10
+
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/PackageVersionsNoCheck/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/PackageVersionsNoCheck/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/PackageVersionsNoCheck/cabal.out
@@ -0,0 +1,2 @@
+# cabal check
+No errors or warnings could be found in the package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/PackageVersionsNoCheck/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/PackageVersionsNoCheck/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/PackageVersionsNoCheck/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Internal targets (tests, benchmarks) should not be checked.
+main = cabalTest $
+  cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/PackageVersionsNoCheck/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/PackageVersionsNoCheck/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/PackageVersionsNoCheck/pkg.cabal
@@ -0,0 +1,20 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
+  build-depends: base == 2.2.*
+
+test-suite test
+  type: exitcode-stdio-1.0
+  main-is: Test.hs
+  default-language: Haskell2010
+  build-depends: base == 2.2.*,
+                 criterion
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/PathsExtensions/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/PathsExtensions/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/PathsExtensions/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/PathsExtensions/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/PathsExtensions/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/PathsExtensions/cabal.out
@@ -0,0 +1,7 @@
+# cabal check
+Warning: The package will not build sanely due to these errors:
+Warning: Packages using RebindableSyntax with OverloadedStrings or OverloadedLists in default-extensions, in conjunction with the autogenerated module Paths_*, are known to cause compile failures with Cabal < 2.2. To use these default-extensions with a Paths_* autogen module, specify at least 'cabal-version: 2.2'.
+Warning: Packages using RebindableSyntax with OverloadedStrings or OverloadedLists in default-extensions, in conjunction with the autogenerated module PackageInfo_*, are known to cause compile failures with Cabal < 2.2. To use these default-extensions with a PackageInfo_* autogen module, specify at least 'cabal-version: 2.2'.
+Warning: The following errors will cause portability problems on other environments:
+Warning: To use the autogenerated module PackageInfo_* you need to specify `cabal-version: 3.12` or higher. This is not possible in `cabal 3.10`. To use this feature and be able to upload your package to Hackage, download `cabal 3.12`!
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/PathsExtensions/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/PathsExtensions/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/PathsExtensions/cabal.test.hs
@@ -0,0 +1,7 @@
+import Test.Cabal.Prelude
+
+-- cabal-version <2.2, Paths_pkg *and* `default extensions` w/
+-- RebindableSyntax plus OverloadedList or similar do not get well
+-- together.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/PathsExtensions/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/PathsExtensions/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/PathsExtensions/pkg.cabal
@@ -0,0 +1,22 @@
+cabal-version: 2.0
+build-type: Simple
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3
+license-file: LICENSE
+
+library
+  exposed-modules: Foo
+  autogen-modules:
+    PackageInfo_pkg
+    Paths_pkg
+  other-modules:
+    PackageInfo_pkg
+    Paths_pkg
+  default-language: Haskell2010
+  default-extensions: RebindableSyntax,
+                      OverloadedLists
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/SetupBounds/Setup.hs b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/SetupBounds/Setup.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/SetupBounds/Setup.hs
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/SetupBounds/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/SetupBounds/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/SetupBounds/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: The dependency 'setup-depends: 'base' does not specify an upper bound on the version number. Each major release of the 'base' package changes the API in various ways and most packages will need some changes to compile with it. If you are not sure what upper bound to use then use the next major version.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/SetupBounds/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/SetupBounds/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/SetupBounds/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- `custom-setup` bounds.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/SetupBounds/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/SetupBounds/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/SetupBounds/pkg.cabal
@@ -0,0 +1,17 @@
+cabal-version: 3.0
+build-type: Custom
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+custom-setup
+  setup-depends: base > 1
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
+
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/UnicodeCustomFields/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/UnicodeCustomFields/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/UnicodeCustomFields/cabal.test.hs
@@ -0,0 +1,9 @@
+import Test.Cabal.Prelude
+
+-- No unicode in custom fields.
+main = cabalTest . recordMode DoNotRecord $
+  fails $ cabal "check" []
+
+  -- You cannot check this against the output,
+  -- as the way to display “Wnknown unicode
+  -- char” wobbles between OSes.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/UnicodeCustomFields/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/UnicodeCustomFields/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/UnicodeCustomFields/pkg.cabal
@@ -0,0 +1,13 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+x-field-ä: content
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/UnusedFlags/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/UnusedFlags/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/UnusedFlags/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: Declared and used flag sets differ: test-flag /= . 
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/UnusedFlags/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/UnusedFlags/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/UnusedFlags/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Unused flag.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/UnusedFlags/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/UnusedFlags/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/NonConfCheck/UnusedFlags/pkg.cabal
@@ -0,0 +1,14 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+flag test-flag
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/BOM/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/BOM/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/BOM/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/BOM/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/BOM/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/BOM/cabal.out
@@ -0,0 +1,6 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: pkg.cabal:1:1: Byte-order mark found at the beginning of the file
+Warning: The following errors will cause portability problems on other environments:
+Warning: ./pkg.cabal starts with an Unicode byte order mark (BOM). This may cause problems with older cabal versions.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/BOM/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/BOM/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/BOM/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- BOM at top of .cabal file.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/BOM/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/BOM/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/BOM/pkg.cabal
@@ -0,0 +1,13 @@
+﻿cabal-version: >= 1.2
+build-type: Simple
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: BSD3
+license-file: LICENSE
+
+library
+  exposed-modules: Foo
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/ExtensionMatch/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/ExtensionMatch/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/ExtensionMatch/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/ExtensionMatch/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/ExtensionMatch/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/ExtensionMatch/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: In the 'extra-doc-files' field: invalid file glob '***.html'. Wildcards '*' may only totally replace the file's base name, not only parts of it.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/ExtensionMatch/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/ExtensionMatch/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/ExtensionMatch/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Partial extension match & <2.4.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/ExtensionMatch/doc.eo.html b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/ExtensionMatch/doc.eo.html
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/ExtensionMatch/doc.eo.html
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/ExtensionMatch/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/ExtensionMatch/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/ExtensionMatch/pkg.cabal
@@ -0,0 +1,15 @@
+cabal-version: 2.0
+build-type: Simple
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3
+extra-doc-files: ***.html
+license-file: LICENSE
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/FileName/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/FileName/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/FileName/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: The filename './pkg.cabal' does not match package name (expected: 'package.cabal')
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/FileName/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/FileName/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/FileName/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Mismatched package name/filename.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/FileName/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/FileName/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/FileName/pkg.cabal
@@ -0,0 +1,12 @@
+cabal-version: 3.0
+name: package
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/LocalPaths/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/LocalPaths/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/LocalPaths/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following warnings are likely to affect your build negatively:
+Warning: 'extra-lib-dirs: lib-folder' specifies a directory which does not exist.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/LocalPaths/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/LocalPaths/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/LocalPaths/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Invalid local paths.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/LocalPaths/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/LocalPaths/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/LocalPaths/pkg.cabal
@@ -0,0 +1,13 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
+  extra-lib-dirs: lib-folder
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/Missing/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/Missing/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/Missing/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Error: cabal: No cabal file found.
+Please create a package description file <pkgname>.cabal
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/Missing/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/Missing/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/Missing/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- No .cabal file.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotExisting/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotExisting/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotExisting/cabal.out
@@ -0,0 +1,2 @@
+# cabal check
+No errors or warnings could be found in the package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotExisting/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotExisting/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotExisting/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Omitting ChangeLog.md but not README in extra-doc-files
+main = cabalTest $ do
+  cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotExisting/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotExisting/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotExisting/pkg.cabal
@@ -0,0 +1,12 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/.gitignore b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/.gitignore
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/.gitignore
@@ -0,0 +1,2 @@
+# Needed for test, to ensure we test the file extension as well.
+!ChangeLog.md~
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/V1.12/ChangeLog.md b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/V1.12/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/V1.12/ChangeLog.md
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/V1.12/ChangeLog.md~ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/V1.12/ChangeLog.md~
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/V1.12/ChangeLog.md~
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/V1.12/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/V1.12/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/V1.12/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/V1.12/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/V1.12/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/V1.12/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: Please consider including the file './ChangeLog.md' in the 'extra-source-files' section of the .cabal file if it contains useful information for users of the package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/V1.12/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/V1.12/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/V1.12/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Omitting ChangeLog.md but not README in extra-doc-files
+main = cabalTest $ do
+  cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/V1.12/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/V1.12/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/V1.12/pkg.cabal
@@ -0,0 +1,14 @@
+cabal-version: 1.12
+build-type: Simple
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3
+license-file: LICENSE
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/V3.0/CHANGELOG.TXT b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/V3.0/CHANGELOG.TXT
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/V3.0/CHANGELOG.TXT
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/V3.0/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/V3.0/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/V3.0/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: Please consider including the file './CHANGELOG.TXT' in the 'extra-doc-files' section of the .cabal file if it contains useful information for users of the package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/V3.0/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/V3.0/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/V3.0/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Omitting ChangeLog.md but not README in extra-doc-files
+main = cabalTest $ do
+  cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/V3.0/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/V3.0/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/NotIncluded/V3.0/pkg.cabal
@@ -0,0 +1,12 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/WrongField/V1.12/ChangeLog.md b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/WrongField/V1.12/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/WrongField/V1.12/ChangeLog.md
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/WrongField/V1.12/LICENSE b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/WrongField/V1.12/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/WrongField/V1.12/LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/WrongField/V1.12/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/WrongField/V1.12/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/WrongField/V1.12/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: Please consider moving the file 'ChangeLog.md' from the 'data-files' section of the .cabal file to the section 'extra-source-files'.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/WrongField/V1.12/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/WrongField/V1.12/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/WrongField/V1.12/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Included ChangeLog.md but not in extra-doc-files
+main = cabalTest $ do
+  cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/WrongField/V1.12/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/WrongField/V1.12/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/WrongField/V1.12/pkg.cabal
@@ -0,0 +1,15 @@
+cabal-version: 1.12
+build-type: Simple
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3
+license-file: LICENSE
+data-files: ChangeLog.md
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/WrongField/V3.0/ChangeLog.md b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/WrongField/V3.0/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/WrongField/V3.0/ChangeLog.md
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/WrongField/V3.0/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/WrongField/V3.0/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/WrongField/V3.0/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: Please consider moving the file 'ChangeLog.md' from the 'extra-source-files' section of the .cabal file to the section 'extra-doc-files'.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/WrongField/V3.0/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/WrongField/V3.0/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/WrongField/V3.0/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Included ChangeLog.md but not in extra-doc-files
+main = cabalTest $ do
+  cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/WrongField/V3.0/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/WrongField/V3.0/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/MissingExpectedDocFiles/ChangeLog/WrongField/V3.0/pkg.cabal
@@ -0,0 +1,13 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+extra-source-files: ChangeLog.md
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/NoConfigureFile/Setup.hs b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/NoConfigureFile/Setup.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/NoConfigureFile/Setup.hs
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/NoConfigureFile/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/NoConfigureFile/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/NoConfigureFile/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following warnings are likely to affect your build negatively:
+Warning: The 'build-type' is 'Configure' but there is no 'configure' script. You probably need to run 'autoreconf -i' to generate it.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/NoConfigureFile/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/NoConfigureFile/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/NoConfigureFile/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- No `configure` script.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/NoConfigureFile/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/NoConfigureFile/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/NoConfigureFile/pkg.cabal
@@ -0,0 +1,13 @@
+cabal-version: 3.0
+build-type: Configure
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/NoLicenseFile/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/NoLicenseFile/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/NoLicenseFile/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following warnings are likely to affect your build negatively:
+Warning: The 'license-file' field refers to the file 'LICENSE' which does not exist.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/NoLicenseFile/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/NoLicenseFile/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/NoLicenseFile/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Missing license file.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/NoLicenseFile/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/NoLicenseFile/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/NoLicenseFile/pkg.cabal
@@ -0,0 +1,13 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+license-file: LICENSE
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/NoSetupFile/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/NoSetupFile/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/NoSetupFile/cabal.out
@@ -0,0 +1,4 @@
+# cabal check
+Warning: The following errors will cause portability problems on other environments:
+Warning: The package is missing a Setup.hs or Setup.lhs script.
+Warning: Hackage would reject this package.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/NoSetupFile/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/NoSetupFile/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/NoSetupFile/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- No Setup.hs/lhs.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/NoSetupFile/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/NoSetupFile/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/NoSetupFile/pkg.cabal
@@ -0,0 +1,15 @@
+cabal-version: 3.0
+build-type: Custom
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+custom-setup
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/VCSInfo/_darcs/.gitkeep b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/VCSInfo/_darcs/.gitkeep
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/VCSInfo/_darcs/.gitkeep
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/VCSInfo/cabal.out b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/VCSInfo/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/VCSInfo/cabal.out
@@ -0,0 +1,3 @@
+# cabal check
+Warning: These warnings may cause trouble when distributing the package:
+Warning: When distributing packages it is encouraged to specify source control information in the .cabal file using one or more 'source-repository' sections. See the Cabal user guide for details.
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/VCSInfo/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/VCSInfo/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/VCSInfo/cabal.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+-- Missing VCS info.
+main = cabalTest $
+  fails $ cabal "check" []
diff --git a/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/VCSInfo/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/VCSInfo/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Check/PackageFiles/VCSInfo/pkg.cabal
@@ -0,0 +1,12 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Foo
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Check/SynopsisLength/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Check/SynopsisLength/cabal.test.hs
--- a/cabal/cabal-testsuite/PackageTests/Check/SynopsisLength/cabal.test.hs
+++ b/cabal/cabal-testsuite/PackageTests/Check/SynopsisLength/cabal.test.hs
diff --git a/cabal/cabal-testsuite/PackageTests/Check/SynopsisLength/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Check/SynopsisLength/pkg.cabal
--- a/cabal/cabal-testsuite/PackageTests/Check/SynopsisLength/pkg.cabal
+++ b/cabal/cabal-testsuite/PackageTests/Check/SynopsisLength/pkg.cabal
@@ -3,7 +3,7 @@
 version: 0
 category: example
 maintainer: none@example.com
-synopsis: this is a preposterously big synopsis but don't worry because it is this big on 
+synopsis: this is a preposterously big synopsis but don't worry because it is this big on
 description: this is a preposterously filler description so warnings are not triggered but don
 license: BSD-3-Clause
 
diff --git a/cabal/cabal-testsuite/PackageTests/CmmSources/cmmexperiment.cabal b/cabal/cabal-testsuite/PackageTests/CmmSources/cmmexperiment.cabal
--- a/cabal/cabal-testsuite/PackageTests/CmmSources/cmmexperiment.cabal
+++ b/cabal/cabal-testsuite/PackageTests/CmmSources/cmmexperiment.cabal
@@ -8,7 +8,7 @@
 -- (and probably -2020 GHC Team)
 -- Under BSD-3-Clause
 
-library 
+library
   default-language: Haskell2010
   hs-source-dirs: src
   build-depends: base
diff --git a/cabal/cabal-testsuite/PackageTests/CmmSourcesDyn/cmmexperiment.cabal b/cabal/cabal-testsuite/PackageTests/CmmSourcesDyn/cmmexperiment.cabal
--- a/cabal/cabal-testsuite/PackageTests/CmmSourcesDyn/cmmexperiment.cabal
+++ b/cabal/cabal-testsuite/PackageTests/CmmSourcesDyn/cmmexperiment.cabal
@@ -8,7 +8,7 @@
 -- (and probably -2020 GHC Team)
 -- Under BSD-3-Clause
 
-library 
+library
   default-language: Haskell2010
   hs-source-dirs: src
   build-depends: base
diff --git a/cabal/cabal-testsuite/PackageTests/ConfigFile/T8487/cabal.out b/cabal/cabal-testsuite/PackageTests/ConfigFile/T8487/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/ConfigFile/T8487/cabal.out
@@ -0,0 +1,8 @@
+# cabal build
+Resolving dependencies...
+Build profile: -w ghc-<GHCVER> -O2
+In order, the following will be built:
+ - test-0.1.0.0 (lib) (first run)
+Configuring library for test-0.1.0.0..
+Preprocessing library for test-0.1.0.0..
+Building library for test-0.1.0.0..
diff --git a/cabal/cabal-testsuite/PackageTests/ConfigFile/T8487/cabal.project b/cabal/cabal-testsuite/PackageTests/ConfigFile/T8487/cabal.project
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/ConfigFile/T8487/cabal.project
@@ -0,0 +1,1 @@
+packages: .
diff --git a/cabal/cabal-testsuite/PackageTests/ConfigFile/T8487/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/ConfigFile/T8487/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/ConfigFile/T8487/cabal.test.hs
@@ -0,0 +1,7 @@
+-- 2022-09-20, issue #8487
+--
+
+import Test.Cabal.Prelude
+
+main = cabalTest $ do
+  cabalG [ "--config-file", "config.file" ] "build" [ "test" ]
diff --git a/cabal/cabal-testsuite/PackageTests/ConfigFile/T8487/config.file b/cabal/cabal-testsuite/PackageTests/ConfigFile/T8487/config.file
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/ConfigFile/T8487/config.file
@@ -0,0 +1,1 @@
+optimization: 2
diff --git a/cabal/cabal-testsuite/PackageTests/ConfigFile/T8487/src/MyLib.hs b/cabal/cabal-testsuite/PackageTests/ConfigFile/T8487/src/MyLib.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/ConfigFile/T8487/src/MyLib.hs
@@ -0,0 +1,4 @@
+module MyLib (someFunc) where
+
+someFunc :: IO ()
+someFunc = putStrLn "someFunc"
diff --git a/cabal/cabal-testsuite/PackageTests/ConfigFile/T8487/test.cabal b/cabal/cabal-testsuite/PackageTests/ConfigFile/T8487/test.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/ConfigFile/T8487/test.cabal
@@ -0,0 +1,13 @@
+cabal-version:   3.0
+name:            test
+version:         0.1.0.0
+license:         NONE
+author:          a.pelenitsyn@gmail.com
+maintainer:      Artem Pelenitsyn
+build-type:      Simple
+
+library
+    exposed-modules:  MyLib
+    build-depends:    base
+    hs-source-dirs:   src
+    default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Configure/cabal.out b/cabal/cabal-testsuite/PackageTests/Configure/cabal.out
--- a/cabal/cabal-testsuite/PackageTests/Configure/cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/Configure/cabal.out
@@ -4,5 +4,6 @@
 In order, the following will be built:
  - zlib-1.1 (lib:zlib) (first run)
 Configuring zlib-1.1...
+Warning: Flags 'con_flict', 'con-flict' all map to the same environment variable 'CABAL_FLAG_con_flict' causing a collision. The value first flag 'con_flict' will be used.
 Preprocessing library for zlib-1.1..
 Building library for zlib-1.1..
diff --git a/cabal/cabal-testsuite/PackageTests/Configure/configure.ac b/cabal/cabal-testsuite/PackageTests/Configure/configure.ac
--- a/cabal/cabal-testsuite/PackageTests/Configure/configure.ac
+++ b/cabal/cabal-testsuite/PackageTests/Configure/configure.ac
@@ -9,6 +9,21 @@
 # Check for zlib include
 AC_CHECK_HEADER(zlib.h, [ZLIB_HEADER=yes], [], [])
 
+# Check that flag assignment has been propagated correctly
+if test "$CABAL_FLAG_true_flag" != "1"; then
+    echo "true flag incorrectly set: got '$CABAL_FLAG_true_flag'"
+    exit 1
+fi
+if test "$CABAL_FLAG_false_flag" != "0"; then
+    echo "false flag incorrectly set: got '$CABAL_FLAG_false_flag'"
+    exit 1
+fi
+
+if test "$CABAL_FLAGS" != "+con-flict +con_flict -false-flag +true-flag"; then
+    echo "CABAL_FLAGS incorrectly set: got '$CABAL_FLAGS'"
+    exit 1
+fi
+
 # Build the package if we found X11 stuff
 if test "x$ZLIB_HEADER" = "x"
 then BUILD_PACKAGE_BOOL=False
diff --git a/cabal/cabal-testsuite/PackageTests/Configure/include/.gitkeep b/cabal/cabal-testsuite/PackageTests/Configure/include/.gitkeep
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Configure/include/.gitkeep
diff --git a/cabal/cabal-testsuite/PackageTests/Configure/include/HsZlibConfig.h.in b/cabal/cabal-testsuite/PackageTests/Configure/include/HsZlibConfig.h.in
deleted file mode 100644
--- a/cabal/cabal-testsuite/PackageTests/Configure/include/HsZlibConfig.h.in
+++ /dev/null
@@ -1,49 +0,0 @@
-/* include/HsZlibConfig.h.in.  Generated from configure.ac by autoheader.  */
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#undef HAVE_INTTYPES_H
-
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#undef HAVE_STDINT_H
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#undef HAVE_STDLIB_H
-
-/* Define to 1 if you have the <strings.h> header file. */
-#undef HAVE_STRINGS_H
-
-/* Define to 1 if you have the <string.h> header file. */
-#undef HAVE_STRING_H
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#undef HAVE_SYS_STAT_H
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#undef HAVE_SYS_TYPES_H
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#undef HAVE_UNISTD_H
-
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
-
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
-
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
-
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
-
-/* Define to the home page for this package. */
-#undef PACKAGE_URL
-
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
-
-/* Define to 1 if you have the ANSI C header files. */
-#undef STDC_HEADERS
diff --git a/cabal/cabal-testsuite/PackageTests/Configure/setup.cabal.out b/cabal/cabal-testsuite/PackageTests/Configure/setup.cabal.out
--- a/cabal/cabal-testsuite/PackageTests/Configure/setup.cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/Configure/setup.cabal.out
@@ -1,6 +1,7 @@
 # Setup configure
 Resolving dependencies...
 Configuring zlib-1.1...
+Warning: Flags 'con_flict', 'con-flict' all map to the same environment variable 'CABAL_FLAG_con_flict' causing a collision. The value first flag 'con_flict' will be used.
 # Setup build
 Preprocessing library for zlib-1.1..
 Building library for zlib-1.1..
diff --git a/cabal/cabal-testsuite/PackageTests/Configure/setup.out b/cabal/cabal-testsuite/PackageTests/Configure/setup.out
--- a/cabal/cabal-testsuite/PackageTests/Configure/setup.out
+++ b/cabal/cabal-testsuite/PackageTests/Configure/setup.out
@@ -1,5 +1,6 @@
 # Setup configure
 Configuring zlib-1.1...
+Warning: Flags 'con_flict', 'con-flict' all map to the same environment variable 'CABAL_FLAG_con_flict' causing a collision. The value first flag 'con_flict' will be used.
 # Setup build
 Preprocessing library for zlib-1.1..
 Building library for zlib-1.1..
diff --git a/cabal/cabal-testsuite/PackageTests/Configure/zlib.cabal b/cabal/cabal-testsuite/PackageTests/Configure/zlib.cabal
--- a/cabal/cabal-testsuite/PackageTests/Configure/zlib.cabal
+++ b/cabal/cabal-testsuite/PackageTests/Configure/zlib.cabal
@@ -6,6 +6,22 @@
 build-type:          Configure
 cabal-version:       >=1.10
 
+flag con-flict
+  description:       A flag that will share an env var
+  default:           True
+
+flag con_flict
+  description:       A flag that will share an env var
+  default:           True
+
+flag true-flag
+  description:       A flag to ensure that flags are correctly passed to @configure@
+  default:           True
+
+flag false-flag
+  description:       A flag to ensure that flags are correctly passed to @configure@
+  default:           False
+
 library
   exposed-modules:     A
   build-depends:       base
diff --git a/cabal/cabal-testsuite/PackageTests/CustomPreProcess/internal-preprocessor-test.cabal b/cabal/cabal-testsuite/PackageTests/CustomPreProcess/internal-preprocessor-test.cabal
--- a/cabal/cabal-testsuite/PackageTests/CustomPreProcess/internal-preprocessor-test.cabal
+++ b/cabal/cabal-testsuite/PackageTests/CustomPreProcess/internal-preprocessor-test.cabal
@@ -12,7 +12,7 @@
 custom-setup
   setup-depends: Cabal, base, process, filepath
 
--- Note that exe comes before the library. 
+-- Note that exe comes before the library.
 -- The reason is backwards compat: old versions of Cabal (< 1.18)
 -- don't have a proper component build graph, so components are
 -- built in declaration order.
diff --git a/cabal/cabal-testsuite/PackageTests/CustomWithoutCabal/cabal.out b/cabal/cabal-testsuite/PackageTests/CustomWithoutCabal/cabal.out
--- a/cabal/cabal-testsuite/PackageTests/CustomWithoutCabal/cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/CustomWithoutCabal/cabal.out
@@ -3,3 +3,4 @@
 Build profile: -w ghc-<GHCVER> -O1
 In order, the following will be built:
  - custom-setup-without-cabal-1.0 (lib:custom-setup-without-cabal) (first run)
+Error: cabal: Failed to build custom-setup-without-cabal-1.0-inplace. The failure occurred during the configure step.
diff --git a/cabal/cabal-testsuite/PackageTests/CustomWithoutCabalDefaultMain/cabal.out b/cabal/cabal-testsuite/PackageTests/CustomWithoutCabalDefaultMain/cabal.out
--- a/cabal/cabal-testsuite/PackageTests/CustomWithoutCabalDefaultMain/cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/CustomWithoutCabalDefaultMain/cabal.out
@@ -3,3 +3,4 @@
 Build profile: -w ghc-<GHCVER> -O1
 In order, the following will be built:
  - custom-setup-without-cabal-defaultMain-1.0 (lib:custom-setup-without-cabal-defaultMain) (first run)
+Error: cabal: Failed to build custom-setup-without-cabal-defaultMain-1.0-inplace. The failure occurred during the configure step.
diff --git a/cabal/cabal-testsuite/PackageTests/ExtraProgPath/MyLibrary.hs b/cabal/cabal-testsuite/PackageTests/ExtraProgPath/MyLibrary.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/ExtraProgPath/MyLibrary.hs
@@ -0,0 +1,1 @@
+module MyLibrary () where
diff --git a/cabal/cabal-testsuite/PackageTests/ExtraProgPath/cabal.project b/cabal/cabal-testsuite/PackageTests/ExtraProgPath/cabal.project
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/ExtraProgPath/cabal.project
@@ -0,0 +1,1 @@
+packages: *.cabal
diff --git a/cabal/cabal-testsuite/PackageTests/ExtraProgPath/my.cabal b/cabal/cabal-testsuite/PackageTests/ExtraProgPath/my.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/ExtraProgPath/my.cabal
@@ -0,0 +1,20 @@
+name: CheckExtraProgPath
+version: 0.1
+license: BSD3
+license-file: LICENSE
+author: Alexander Vershilov
+maintainer: Alexander Vershilov
+synopsis: Check Extra Prog Path
+category: PackageTests
+build-type: Simple
+cabal-version: 2.0
+
+description:
+    Check that Cabal recognizes an override of the prog path.
+
+Library
+    pkgconfig-depends: zlib
+    default-language: Haskell2010
+    build-depends: base <5.0
+    exposed-modules:
+        MyLibrary
diff --git a/cabal/cabal-testsuite/PackageTests/ExtraProgPath/pkg-config b/cabal/cabal-testsuite/PackageTests/ExtraProgPath/pkg-config
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/ExtraProgPath/pkg-config
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+exit 1;
diff --git a/cabal/cabal-testsuite/PackageTests/ExtraProgPath/setup.out b/cabal/cabal-testsuite/PackageTests/ExtraProgPath/setup.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/ExtraProgPath/setup.out
@@ -0,0 +1,11 @@
+# cabal v2-build
+Warning: cannot determine version of <ROOT>/./pkg-config :
+""
+Warning: cannot determine version of <ROOT>/./pkg-config :
+""
+Resolving dependencies...
+Error: cabal: Could not resolve dependencies:
+[__0] next goal: CheckExtraProgPath (user goal)
+[__0] rejecting: CheckExtraProgPath-0.1 (conflict: pkg-config package zlib-any, not found in the pkg-config database)
+[__0] fail (backjumping, conflict set: CheckExtraProgPath)
+After searching the rest of the dependency tree exhaustively, these were the goals I've had most trouble fulfilling: CheckExtraProgPath (2)
diff --git a/cabal/cabal-testsuite/PackageTests/ExtraProgPath/setup.test.hs b/cabal/cabal-testsuite/PackageTests/ExtraProgPath/setup.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/ExtraProgPath/setup.test.hs
@@ -0,0 +1,8 @@
+import Test.Cabal.Prelude
+
+-- Test that extra-prog-path overrides the path for pkg-config
+main = cabalTest $ do
+  -- skipped on windows because using a script to dummy up an executable doesn't work the same.
+  skipIfWindows
+  cdir <- testCurrentDir `fmap` getTestEnv
+  fails $ cabal "v2-build" ["--extra-prog-path="++cdir]
diff --git a/cabal/cabal-testsuite/PackageTests/ForeignLibs/UseLib.c b/cabal/cabal-testsuite/PackageTests/ForeignLibs/UseLib.c
--- a/cabal/cabal-testsuite/PackageTests/ForeignLibs/UseLib.c
+++ b/cabal/cabal-testsuite/PackageTests/ForeignLibs/UseLib.c
@@ -4,7 +4,7 @@
 /* Forward declarations */
 bool myForeignLibInit();
 void myForeignLibExit();
-void sayHi();
+extern void sayHi();
 
 int main()
 {
diff --git a/cabal/cabal-testsuite/PackageTests/ForeignLibs/setup.test.hs b/cabal/cabal-testsuite/PackageTests/ForeignLibs/setup.test.hs
--- a/cabal/cabal-testsuite/PackageTests/ForeignLibs/setup.test.hs
+++ b/cabal/cabal-testsuite/PackageTests/ForeignLibs/setup.test.hs
@@ -26,9 +26,9 @@
 main = setupAndCabalTest . recordMode DoNotRecord $ do
   -- Foreign libraries don't work with GHC 7.6 and earlier
   skipUnlessGhcVersion ">= 7.8"
-  osx <- isOSX
-  ghc80 <- isGhcVersion "== 8.0.2"
-  expectBrokenIf (osx && ghc80) 7989 $
+  win <- isWindows
+  ghc94 <- isGhcVersion "== 9.4.*"
+  expectBrokenIf (win && ghc94) 8451 $
     withPackageDb $ do
         setup_install []
         setup "copy" [] -- regression test #4156
diff --git a/cabal/cabal-testsuite/PackageTests/GenBounds/Issue6290/Main.hs b/cabal/cabal-testsuite/PackageTests/GenBounds/Issue6290/Main.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/GenBounds/Issue6290/Main.hs
@@ -0,0 +1,3 @@
+module Main where
+
+main = putStrLn "Issue 6290."
diff --git a/cabal/cabal-testsuite/PackageTests/GenBounds/Issue6290/cabal.out b/cabal/cabal-testsuite/PackageTests/GenBounds/Issue6290/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/GenBounds/Issue6290/cabal.out
@@ -0,0 +1,3 @@
+# cabal gen-bounds
+Resolving dependencies...
+Congratulations, all your dependencies have upper bounds!
diff --git a/cabal/cabal-testsuite/PackageTests/GenBounds/Issue6290/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/GenBounds/Issue6290/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/GenBounds/Issue6290/cabal.test.hs
@@ -0,0 +1,3 @@
+import Test.Cabal.Prelude
+
+main = cabalTest $ cabal "gen-bounds" []
diff --git a/cabal/cabal-testsuite/PackageTests/GenBounds/Issue6290/pkg.cabal b/cabal/cabal-testsuite/PackageTests/GenBounds/Issue6290/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/GenBounds/Issue6290/pkg.cabal
@@ -0,0 +1,11 @@
+cabal-version:       2.4
+name:                pkg
+version:             0.0.0.0
+
+library lib
+  build-depends:
+    base >= 4 && < 5
+
+executable exec
+  main-is:       Main.hs
+  build-depends: lib
diff --git a/cabal/cabal-testsuite/PackageTests/Get/OnlyDescription/cabal.out b/cabal/cabal-testsuite/PackageTests/Get/OnlyDescription/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Get/OnlyDescription/cabal.out
@@ -0,0 +1,6 @@
+# cabal v2-update
+Downloading the latest package list from test-local-repo
+# cabal update
+Downloading the latest package list from test-local-repo
+# cabal get
+Writing package description to criterion-1.1.4.0.cabal
diff --git a/cabal/cabal-testsuite/PackageTests/Get/OnlyDescription/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Get/OnlyDescription/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Get/OnlyDescription/cabal.test.hs
@@ -0,0 +1,11 @@
+-- 2022-07-03, issue #1954
+--
+-- Purpose of this test:
+-- Make sure that `cabal get --only-package-description` works
+
+import Test.Cabal.Prelude
+main = cabalTest $ withRepo "repo" $ do
+  cabal "update" []
+  cabal
+    "get"
+    [ "criterion", "--only-package-description" ]
diff --git a/cabal/cabal-testsuite/PackageTests/Get/OnlyDescription/repo/criterion-1.1.4.0/criterion.cabal b/cabal/cabal-testsuite/PackageTests/Get/OnlyDescription/repo/criterion-1.1.4.0/criterion.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Get/OnlyDescription/repo/criterion-1.1.4.0/criterion.cabal
@@ -0,0 +1,8 @@
+name: criterion
+version: 1.1.4.0
+build-type: Simple
+cabal-version: >= 1.10
+
+library
+    build-depends: base, ghc-prim
+    default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Haddock/setup.cabal.out b/cabal/cabal-testsuite/PackageTests/Haddock/setup.cabal.out
--- a/cabal/cabal-testsuite/PackageTests/Haddock/setup.cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/Haddock/setup.cabal.out
@@ -3,4 +3,4 @@
 # Setup haddock
 Preprocessing library for Haddock-0.1..
 Running Haddock on library for Haddock-0.1..
-Documentation created: setup.cabal.dist/work/dist/doc/html/Haddock/index.html
+Documentation created: setup.cabal.dist/work/dist/doc/html/Haddock/
diff --git a/cabal/cabal-testsuite/PackageTests/Haddock/setup.out b/cabal/cabal-testsuite/PackageTests/Haddock/setup.out
--- a/cabal/cabal-testsuite/PackageTests/Haddock/setup.out
+++ b/cabal/cabal-testsuite/PackageTests/Haddock/setup.out
@@ -3,4 +3,4 @@
 # Setup haddock
 Preprocessing library for Haddock-0.1..
 Running Haddock on library for Haddock-0.1..
-Documentation created: setup.dist/work/dist/doc/html/Haddock/index.html
+Documentation created: setup.dist/work/dist/doc/html/Haddock/
diff --git a/cabal/cabal-testsuite/PackageTests/HaddockArgs/quickjump.out b/cabal/cabal-testsuite/PackageTests/HaddockArgs/quickjump.out
--- a/cabal/cabal-testsuite/PackageTests/HaddockArgs/quickjump.out
+++ b/cabal/cabal-testsuite/PackageTests/HaddockArgs/quickjump.out
@@ -14,7 +14,7 @@
 Preprocessing library for sigs-0.1.0.0..
 Running Haddock on library instantiated with Data.Map = <Data.Map>
 for sigs-0.1.0.0..
-Documentation created: dist/doc/html/sigs/index.html
+Documentation created: dist/doc/html/sigs/
 Installing library in <PATH>
 Configuring library for indef-0.1.0.0..
 Preprocessing library for indef-0.1.0.0..
@@ -23,7 +23,7 @@
 Preprocessing library for indef-0.1.0.0..
 Running Haddock on library instantiated with Data.Map = <Data.Map>
 for indef-0.1.0.0..
-Documentation created: dist/doc/html/indef/index.html
+Documentation created: dist/doc/html/indef/
 Installing library in <PATH>
 Configuring library for example-1.0..
 Preprocessing library for example-1.0..
@@ -32,4 +32,4 @@
 Preprocessing library for example-1.0..
 Running Haddock on library instantiated with Data.Map = <Data.Map>
 for example-1.0..
-Documentation created: <ROOT>/quickjump.dist/work/dist/build/<ARCH>/ghc-<GHCVER>/example-1.0/doc/html/example/index.html
+Documentation created: <ROOT>/quickjump.dist/work/dist/build/<ARCH>/ghc-<GHCVER>/example-1.0/doc/html/example/
diff --git a/cabal/cabal-testsuite/PackageTests/HaddockNewline/HaddockNewline.cabal b/cabal/cabal-testsuite/PackageTests/HaddockNewline/HaddockNewline.cabal
--- a/cabal/cabal-testsuite/PackageTests/HaddockNewline/HaddockNewline.cabal
+++ b/cabal/cabal-testsuite/PackageTests/HaddockNewline/HaddockNewline.cabal
@@ -2,7 +2,7 @@
 version:             0.1.0.0
 synopsis:            This has a
                      newline yo.
--- description:         
+-- description:
 license:             BSD3
 license-file:        LICENSE
 author:              Edward Z. Yang
@@ -13,8 +13,8 @@
 
 library
   exposed-modules:     A
-  -- other-modules:       
-  -- other-extensions:    
+  -- other-modules:
+  -- other-extensions:
   build-depends:       base
-  -- hs-source-dirs:      
+  -- hs-source-dirs:
   default-language:    Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/HaddockNewline/setup.cabal.out b/cabal/cabal-testsuite/PackageTests/HaddockNewline/setup.cabal.out
--- a/cabal/cabal-testsuite/PackageTests/HaddockNewline/setup.cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/HaddockNewline/setup.cabal.out
@@ -3,4 +3,4 @@
 # Setup haddock
 Preprocessing library for HaddockNewline-0.1.0.0..
 Running Haddock on library for HaddockNewline-0.1.0.0..
-Documentation created: setup.cabal.dist/work/dist/doc/html/HaddockNewline/index.html
+Documentation created: setup.cabal.dist/work/dist/doc/html/HaddockNewline/
diff --git a/cabal/cabal-testsuite/PackageTests/HaddockNewline/setup.out b/cabal/cabal-testsuite/PackageTests/HaddockNewline/setup.out
--- a/cabal/cabal-testsuite/PackageTests/HaddockNewline/setup.out
+++ b/cabal/cabal-testsuite/PackageTests/HaddockNewline/setup.out
@@ -3,4 +3,4 @@
 # Setup haddock
 Preprocessing library for HaddockNewline-0.1.0.0..
 Running Haddock on library for HaddockNewline-0.1.0.0..
-Documentation created: setup.dist/work/dist/doc/html/HaddockNewline/index.html
+Documentation created: setup.dist/work/dist/doc/html/HaddockNewline/
diff --git a/cabal/cabal-testsuite/PackageTests/HaddockProject/a.cabal b/cabal/cabal-testsuite/PackageTests/HaddockProject/a.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/HaddockProject/a.cabal
@@ -0,0 +1,10 @@
+name: a
+version: 0.1.0.0
+build-type: Simple
+cabal-version: >= 1.10
+
+library
+    exposed-modules:  MyLib
+    build-depends:    base, async
+    hs-source-dirs:   src
+    default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/HaddockProject/cabal.project b/cabal/cabal-testsuite/PackageTests/HaddockProject/cabal.project
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/HaddockProject/cabal.project
@@ -0,0 +1,8 @@
+packages: .
+-- `jobs` is necessary to use `InternalMethod :: SetupMethod`.
+jobs: 1
+
+documentation: True
+
+package async
+  documentation: True
diff --git a/cabal/cabal-testsuite/PackageTests/HaddockProject/haddock-project.out b/cabal/cabal-testsuite/PackageTests/HaddockProject/haddock-project.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/HaddockProject/haddock-project.out
@@ -0,0 +1,25 @@
+# cabal v2-update
+Downloading the latest package list from test-local-repo
+# cabal haddock-project
+Warning: haddock-project command is experimental, it might break in the future
+Resolving dependencies...
+Build profile: -w ghc-<GHCVER> -O1
+In order, the following will be built:
+ - async-2.2.4 (lib) (requires build)
+ - a-0.1.0.0 (lib) (first run)
+Build profile: -w ghc-<GHCVER> -O1
+In order, the following will be built:
+ - async-2.2.4 (lib) (requires build)
+ - a-0.1.0.0 (lib) (configuration changed)
+Configuring library for async-2.2.4..
+Preprocessing library for async-2.2.4..
+Building library for async-2.2.4..
+Preprocessing library for async-2.2.4..
+Running Haddock on library for async-2.2.4..
+Documentation created: dist/doc/html/async/
+Installing library in <PATH>
+Configuring library for a-0.1.0.0..
+Preprocessing library for a-0.1.0.0..
+Running Haddock on library for a-0.1.0.0..
+Documentation created: <ROOT>/haddock-project.dist/source/dist-newstyle/build/<ARCH>/ghc-<GHCVER>/a-0.1.0.0/doc/html/a/
+Documentation created: haddocks/index.html
diff --git a/cabal/cabal-testsuite/PackageTests/HaddockProject/haddock-project.test.hs b/cabal/cabal-testsuite/PackageTests/HaddockProject/haddock-project.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/HaddockProject/haddock-project.test.hs
@@ -0,0 +1,13 @@
+import Test.Cabal.Prelude
+import System.Directory (doesFileExist, removeDirectory)
+
+main = cabalTest . withRepo "repo" . withSourceCopy $ do
+    skipUnlessGhcVersion ">= 9.4.0"
+    env <- getTestEnv
+    let testDir = testCurrentDir env
+
+    cabal "haddock-project" ["all"]
+    let asyncHaddocks = "haddocks" </> "async" </> "async.haddock"
+    liftIO (doesFileExist (testDir </> asyncHaddocks))
+      >>= assertBool ("'" ++ asyncHaddocks ++ "'" ++ "should exist")
+
diff --git a/cabal/cabal-testsuite/PackageTests/HaddockProject/repo/async-2.2.4/Control/Concurrent/Async.hs b/cabal/cabal-testsuite/PackageTests/HaddockProject/repo/async-2.2.4/Control/Concurrent/Async.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/HaddockProject/repo/async-2.2.4/Control/Concurrent/Async.hs
@@ -0,0 +1,25 @@
+module Control.Concurrent.Async (
+    Async,
+    async
+  ) where
+
+
+-- -----------------------------------------------------------------------------
+-- STM Async API
+
+
+-- | An asynchronous action spawned by 'async' or 'withAsync'.
+-- Asynchronous actions are executed in a separate thread, and
+-- operations are provided for waiting for asynchronous actions to
+-- complete and obtaining their results (see e.g. 'wait').
+--
+data Async a = Async
+
+-- | Spawn an asynchronous action in a separate thread.
+--
+-- Like for 'forkIO', the action may be left running unintentinally
+-- (see module-level documentation for details).
+--
+-- __Use 'withAsync' style functions wherever you can instead!__
+async :: IO a -> IO (Async a)
+async = undefined
diff --git a/cabal/cabal-testsuite/PackageTests/HaddockProject/repo/async-2.2.4/LICENSE b/cabal/cabal-testsuite/PackageTests/HaddockProject/repo/async-2.2.4/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/HaddockProject/repo/async-2.2.4/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2012, Simon Marlow
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Simon Marlow nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/cabal/cabal-testsuite/PackageTests/HaddockProject/repo/async-2.2.4/Setup.hs b/cabal/cabal-testsuite/PackageTests/HaddockProject/repo/async-2.2.4/Setup.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/HaddockProject/repo/async-2.2.4/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/cabal/cabal-testsuite/PackageTests/HaddockProject/repo/async-2.2.4/async.cabal b/cabal/cabal-testsuite/PackageTests/HaddockProject/repo/async-2.2.4/async.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/HaddockProject/repo/async-2.2.4/async.cabal
@@ -0,0 +1,22 @@
+name:                async
+version:             2.2.4
+synopsis:            Run IO operations asynchronously and wait for their results
+license:             BSD3
+license-file:        LICENSE
+author:              Simon Marlow
+maintainer:          Simon Marlow <marlowsd@gmail.com>
+copyright:           (c) Simon Marlow 2012
+category:            Concurrency
+build-type:          Simple
+cabal-version:       >=1.10
+homepage:            https://github.com/simonmar/async
+bug-reports:         https://github.com/simonmar/async/issues
+
+source-repository head
+    type: git
+    location: https://github.com/simonmar/async.git
+
+library
+    default-language:    Haskell2010
+    exposed-modules:     Control.Concurrent.Async
+    build-depends:       base
diff --git a/cabal/cabal-testsuite/PackageTests/HaddockProject/src/MyLib.hs b/cabal/cabal-testsuite/PackageTests/HaddockProject/src/MyLib.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/HaddockProject/src/MyLib.hs
@@ -0,0 +1,6 @@
+module MyLib (someFunc) where
+
+import Control.Concurrent.Async
+
+someFunc :: IO (Async ())
+someFunc = async (return ())
diff --git a/cabal/cabal-testsuite/PackageTests/Init/app/Main.hs b/cabal/cabal-testsuite/PackageTests/Init/app/Main.hs
--- a/cabal/cabal-testsuite/PackageTests/Init/app/Main.hs
+++ b/cabal/cabal-testsuite/PackageTests/Init/app/Main.hs
diff --git a/cabal/cabal-testsuite/PackageTests/InternalLibraries/Haddock/haddock.cabal.out b/cabal/cabal-testsuite/PackageTests/InternalLibraries/Haddock/haddock.cabal.out
--- a/cabal/cabal-testsuite/PackageTests/InternalLibraries/Haddock/haddock.cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/InternalLibraries/Haddock/haddock.cabal.out
@@ -18,10 +18,10 @@
 # Setup haddock
 Preprocessing library 'foo-internal-before' for foo-0.1.0.0..
 Running Haddock on library 'foo-internal-before' for foo-0.1.0.0..
-Documentation created: haddock.cabal.dist/work/dist/doc/html/foo/index.html
+Documentation created: haddock.cabal.dist/work/dist/doc/html/foo/
 Preprocessing library for foo-0.1.0.0..
 Running Haddock on library for foo-0.1.0.0..
-Documentation created: haddock.cabal.dist/work/dist/doc/html/foo/index.html
+Documentation created: haddock.cabal.dist/work/dist/doc/html/foo/
 Preprocessing library 'foo-internal-after' for foo-0.1.0.0..
 Running Haddock on library 'foo-internal-after' for foo-0.1.0.0..
-Documentation created: haddock.cabal.dist/work/dist/doc/html/foo/index.html
+Documentation created: haddock.cabal.dist/work/dist/doc/html/foo/
diff --git a/cabal/cabal-testsuite/PackageTests/InternalLibraries/Haddock/haddock.out b/cabal/cabal-testsuite/PackageTests/InternalLibraries/Haddock/haddock.out
--- a/cabal/cabal-testsuite/PackageTests/InternalLibraries/Haddock/haddock.out
+++ b/cabal/cabal-testsuite/PackageTests/InternalLibraries/Haddock/haddock.out
@@ -18,10 +18,10 @@
 # Setup haddock
 Preprocessing library 'foo-internal-before' for foo-0.1.0.0..
 Running Haddock on library 'foo-internal-before' for foo-0.1.0.0..
-Documentation created: haddock.dist/work/dist/doc/html/foo/index.html
+Documentation created: haddock.dist/work/dist/doc/html/foo/
 Preprocessing library for foo-0.1.0.0..
 Running Haddock on library for foo-0.1.0.0..
-Documentation created: haddock.dist/work/dist/doc/html/foo/index.html
+Documentation created: haddock.dist/work/dist/doc/html/foo/
 Preprocessing library 'foo-internal-after' for foo-0.1.0.0..
 Running Haddock on library 'foo-internal-after' for foo-0.1.0.0..
-Documentation created: haddock.dist/work/dist/doc/html/foo/index.html
+Documentation created: haddock.dist/work/dist/doc/html/foo/
diff --git a/cabal/cabal-testsuite/PackageTests/JS/JsSources/cabal.project b/cabal/cabal-testsuite/PackageTests/JS/JsSources/cabal.project
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/JS/JsSources/cabal.project
@@ -0,0 +1,1 @@
+packages: .
diff --git a/cabal/cabal-testsuite/PackageTests/JS/JsSources/demo/Main.hs b/cabal/cabal-testsuite/PackageTests/JS/JsSources/demo/Main.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/JS/JsSources/demo/Main.hs
@@ -0,0 +1,6 @@
+module Main where
+
+import Lib
+
+main :: IO ()
+main = foo
diff --git a/cabal/cabal-testsuite/PackageTests/JS/JsSources/js-arch.test.hs b/cabal/cabal-testsuite/PackageTests/JS/JsSources/js-arch.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/JS/JsSources/js-arch.test.hs
@@ -0,0 +1,9 @@
+import Test.Cabal.Prelude
+
+main = setupAndCabalTest $ do
+    skipUnlessGhcVersion ">= 9.6"
+    skipUnlessJavaScript
+    skipIfWindows
+
+    res <- cabal' "v2-run" ["demo"]
+    assertOutputContains "Hello JS!" res
diff --git a/cabal/cabal-testsuite/PackageTests/JS/JsSources/jsbits/lib.js b/cabal/cabal-testsuite/PackageTests/JS/JsSources/jsbits/lib.js
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/JS/JsSources/jsbits/lib.js
@@ -0,0 +1,3 @@
+function foo() {
+  console.log("Hello JS!");
+}
diff --git a/cabal/cabal-testsuite/PackageTests/JS/JsSources/jssources.cabal b/cabal/cabal-testsuite/PackageTests/JS/JsSources/jssources.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/JS/JsSources/jssources.cabal
@@ -0,0 +1,20 @@
+cabal-version: 3.0
+name: jssources
+version: 0
+build-type: Simple
+
+library
+  default-language: Haskell2010
+  js-sources: jsbits/lib.js
+  if arch(JavaScript)
+    hs-source-dirs: srcJS
+  else
+    hs-source-dirs: src
+  exposed-modules: Lib
+  build-depends: base
+
+executable demo
+  default-language: Haskell2010
+  main-is: Main.hs
+  hs-source-dirs: demo
+  build-depends: base, jssources
diff --git a/cabal/cabal-testsuite/PackageTests/JS/JsSources/other-arch.out b/cabal/cabal-testsuite/PackageTests/JS/JsSources/other-arch.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/JS/JsSources/other-arch.out
@@ -0,0 +1,12 @@
+# cabal v2-run
+Resolving dependencies...
+Build profile: -w ghc-<GHCVER> -O1
+In order, the following will be built:
+ - jssources-0 (lib) (first run)
+ - jssources-0 (exe:demo) (first run)
+Configuring library for jssources-0..
+Preprocessing library for jssources-0..
+Building library for jssources-0..
+Configuring executable 'demo' for jssources-0..
+Preprocessing executable 'demo' for jssources-0..
+Building executable 'demo' for jssources-0..
diff --git a/cabal/cabal-testsuite/PackageTests/JS/JsSources/other-arch.test.hs b/cabal/cabal-testsuite/PackageTests/JS/JsSources/other-arch.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/JS/JsSources/other-arch.test.hs
@@ -0,0 +1,7 @@
+import Test.Cabal.Prelude
+
+main = cabalTest $ do
+    skipIfJavaScript
+    -- Ensure the field `js-sources` does not raise issues
+    res <- cabal' "v2-run" ["demo"]
+    assertOutputContains "Hello Not JS!" res
diff --git a/cabal/cabal-testsuite/PackageTests/JS/JsSources/src/Lib.hs b/cabal/cabal-testsuite/PackageTests/JS/JsSources/src/Lib.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/JS/JsSources/src/Lib.hs
@@ -0,0 +1,4 @@
+module Lib where
+
+foo :: IO ()
+foo = putStrLn "Hello Not JS!"
diff --git a/cabal/cabal-testsuite/PackageTests/JS/JsSources/srcJS/Lib.hs b/cabal/cabal-testsuite/PackageTests/JS/JsSources/srcJS/Lib.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/JS/JsSources/srcJS/Lib.hs
@@ -0,0 +1,3 @@
+module Lib where
+
+foreign import javascript foo :: IO ()
diff --git a/cabal/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/basic/basic/Basic.hs b/cabal/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/basic/basic/Basic.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/basic/basic/Basic.hs
@@ -0,0 +1,10 @@
+module Basic where
+
+funcs :: (a -> b -> c) -> ((a -> b -> c) -> a -> b -> c) -> b -> a -> c
+funcs f g = \a b -> (g f) b a
+
+name :: String
+name = "Basic"
+
+number :: Integer
+number = 8
diff --git a/cabal/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/basic/basic/basic.cabal b/cabal/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/basic/basic/basic.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/basic/basic/basic.cabal
@@ -0,0 +1,10 @@
+cabal-version: >= 1.10
+name: basic
+version: 0.1
+build-type: Simple
+
+library
+  default-language: Haskell2010
+  build-depends: base
+  exposed-modules:
+    Basic
diff --git a/cabal/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/basic/cabal.project b/cabal/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/basic/cabal.project
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/basic/cabal.project
@@ -0,0 +1,1 @@
+packages: basic
diff --git a/cabal/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/cabal.out b/cabal/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/cabal.out
@@ -0,0 +1,26 @@
+# cabal v2-install
+Wrote tarball sdist to <ROOT>/cabal.dist/work/./basic/../dist/sdist/basic-0.1.tar.gz
+Resolving dependencies...
+Build profile: -w ghc-<GHCVER> -O1
+In order, the following will be built:
+ - basic-0.1 (lib) (requires build)
+Configuring library for basic-0.1..
+Preprocessing library for basic-0.1..
+Building library for basic-0.1..
+Installing library in <PATH>
+# cabal v2-install
+Wrote tarball sdist to <ROOT>/cabal.dist/work/./basic/../dist/sdist/basic-0.1.tar.gz
+Resolving dependencies...
+Build profile: -w ghc-<GHCVER> -O1
+In order, the following will be built:
+ - basic-0.1 (lib) (requires build)
+Configuring library for basic-0.1..
+Preprocessing library for basic-0.1..
+Building library for basic-0.1..
+Installing library in <PATH>
+# cabal v2-install
+Wrote tarball sdist to <ROOT>/cabal.dist/work/./basic/../dist/sdist/basic-0.1.tar.gz
+Resolving dependencies...
+# cabal v2-install
+Wrote tarball sdist to <ROOT>/cabal.dist/work/./basic/../dist/sdist/basic-0.1.tar.gz
+Resolving dependencies...
diff --git a/cabal/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/LinkerOptions/NonignoredConfigs/cabal.test.hs
@@ -0,0 +1,104 @@
+import Test.Cabal.Prelude
+
+-- This test ensures the following fix holds:
+-- > Fix project-local build flags being ignored.
+-- >
+-- > I noticed that running ‘cabal install’ with two separate sets of dynamic /
+-- > static build flags (e.g. one with none, and one with ‘--enable-shared
+-- > --enable-executable-dynamic --disable-library-vanilla’) produced packages with
+-- > the same hash, instead of different hashes.
+-- >
+-- > After debugging this issue I found that this command (with no explicit cabal
+-- > project file) was resulting in these build configuration flags being ignored,
+-- > because in ProjectPlanning.hs, the sdist was not considered a local package, so
+-- > the (non-shared) local-package-only configuration was being dropped.
+-- >
+-- > This fix ensures that these command-line arguments properly make it through to
+-- > where they belong in cases like this.
+--
+-- Basically, take a simple package, build it under two sets of build flags:
+-- > (nothing)
+-- > --enable-shared --enable-executable-dynamic --disable-library-vanilla
+--
+-- And ensure that whereas before they produced the same hash, now the package
+-- hashes produced are different.  (And also supplementarily ensure that
+-- re-running the same build with the same flags a second time produces a
+-- deterministic hash too; the hash should differ only when we change these
+-- flags.)
+--
+-- Based on the UniqueIPID test.
+
+import Control.Monad (forM, foldM_)
+import Data.List (isPrefixOf, tails)
+
+data Linking = Static | Dynamic deriving (Eq, Ord, Show)
+
+links :: [Linking]
+links = [Static, Dynamic]
+
+linkConfigFlags :: Linking -> [String]
+linkConfigFlags Static  =
+    [
+    ]
+linkConfigFlags Dynamic =
+    [
+        "--enable-shared",
+        "--enable-executable-dynamic",
+        "--disable-library-vanilla"
+    ]
+
+lrun :: [Linking]
+lrun = [Static, Dynamic, Static, Dynamic]
+
+main = cabalTest $ do
+    -- Skip if on Windows, since my default Chocolatey Windows setup (and the CI
+    -- server setup at the time, presumably) lacks support for dynamic builds
+    -- since the base package appears to be static only, lacking e.g. ‘.dyn_o’
+    -- files.  Normal Windows installations would need support for dynamic
+    -- builds, or else this test would fail when it tries to build with the
+    -- dynamic flags.
+    skipIfWindows
+
+    withPackageDb $ do
+        -- Phase 1: get 4 hashes according to config flags.
+        results <- forM (zip [0..] lrun) $ \(idx, linking) -> do
+            withDirectory "basic" $ do
+                withSourceCopyDir ("basic" ++ show idx) $ do
+                    -- (Now do ‘cd ..’, since withSourceCopyDir made our previous
+                    -- previous such withDirectories now accumulate to be
+                    -- relative to setup.dist/basic0, not testSourceDir
+                    -- (see 'testCurrentDir').)
+                    withDirectory ".." $ do
+                        packageEnv <- (</> ("basic" ++ show idx ++ ".env")) . testWorkDir <$> getTestEnv
+                        cabal "v2-install" $ ["--disable-deterministic", "--lib", "--package-env=" ++ packageEnv] ++ linkConfigFlags linking ++ ["basic"]
+                        let exIPID s = takeWhile (/= '\n') . head . filter (\t -> any (`isPrefixOf` t) ["basic-0.1-", "bsc-0.1-"]) $ tails s
+                        hashedIpid <- exIPID <$> liftIO (readFile packageEnv)
+                        return $ ((idx, linking), hashedIpid)
+        -- Phase 2: make sure we have different hashes iff we have different config flags.
+        -- In particular make sure the dynamic config flags weren't silently
+        -- dropped and ignored, since this is the bug that prompted this test.
+        (\step -> foldM_ step (const $ return ()) results) $ \acc x -> do
+            acc x
+            return $ \future -> acc future >> do
+                let
+                    ((thisIdx,   thisLinking),   thisHashedIpid)   = x
+                    ((futureIdx, futureLinking), futureHashedIpid) = future
+                when ((thisHashedIpid == futureHashedIpid) /= (thisLinking == futureLinking)) $ do
+                    assertFailure . unlines $
+                        if thisLinking /= futureLinking
+                            then
+                                -- What we are primarily concerned with testing
+                                -- here.
+                                [
+                                    "Error: static and dynamic config flags produced an IPID with the same hash; were the dynamic flags silently dropped?",
+                                    "\thashed IPID: " ++ thisHashedIpid
+                                ]
+                            else
+                                -- Help test our test can also make equal
+                                -- hashes.
+                                [
+                                    "Error: config flags were equal, yet a different IPID hash was produced.",
+                                    "\thashed IPID 1 : " ++ thisHashedIpid,
+                                    "\thashed IPID 2 : " ++ futureHashedIpid,
+                                    "\tlinking flags : " ++ show thisLinking
+                                ]
diff --git a/cabal/cabal-testsuite/PackageTests/LinkerOptions/T7339/T19350.script b/cabal/cabal-testsuite/PackageTests/LinkerOptions/T7339/T19350.script
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/LinkerOptions/T7339/T19350.script
@@ -0,0 +1,3 @@
+import Hello
+hello
+:q
diff --git a/cabal/cabal-testsuite/PackageTests/LinkerOptions/T7339/clib/lib.c b/cabal/cabal-testsuite/PackageTests/LinkerOptions/T7339/clib/lib.c
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/LinkerOptions/T7339/clib/lib.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+void hello_world(void) {
+  printf("hello world!");
+}
+
diff --git a/cabal/cabal-testsuite/PackageTests/LinkerOptions/T7339/lib/Hello.hs b/cabal/cabal-testsuite/PackageTests/LinkerOptions/T7339/lib/Hello.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/LinkerOptions/T7339/lib/Hello.hs
@@ -0,0 +1,3 @@
+module Hello (hello) where
+
+foreign import ccall "hello_world" hello :: IO ()
diff --git a/cabal/cabal-testsuite/PackageTests/LinkerOptions/T7339/lib/Setup.hs b/cabal/cabal-testsuite/PackageTests/LinkerOptions/T7339/lib/Setup.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/LinkerOptions/T7339/lib/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/cabal/cabal-testsuite/PackageTests/LinkerOptions/T7339/lib/T7339.cabal b/cabal/cabal-testsuite/PackageTests/LinkerOptions/T7339/lib/T7339.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/LinkerOptions/T7339/lib/T7339.cabal
@@ -0,0 +1,11 @@
+cabal-version: >=1.10
+name: T7339
+version: 1.0
+build-type: Simple
+
+library
+  build-depends: base
+  exposed-modules: Hello
+  default-language: Haskell2010
+  extra-libraries: hello
+
diff --git a/cabal/cabal-testsuite/PackageTests/LinkerOptions/T7339/setup.out b/cabal/cabal-testsuite/PackageTests/LinkerOptions/T7339/setup.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/LinkerOptions/T7339/setup.out
@@ -0,0 +1,6 @@
+# Setup configure
+# Setup build
+Preprocessing library for T7339-1.0..
+Building library for T7339-1.0..
+# Setup register
+Registering library for T7339-1.0..
diff --git a/cabal/cabal-testsuite/PackageTests/LinkerOptions/T7339/setup.test.hs b/cabal/cabal-testsuite/PackageTests/LinkerOptions/T7339/setup.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/LinkerOptions/T7339/setup.test.hs
@@ -0,0 +1,67 @@
+-- Test for #19350, #7339 originally by @bgamari
+-- =============================================
+--
+-- The plan
+-- ---------
+-- We build a C shared library (`libhello`, contained in ./clib) and then build
+-- a Haskell library (`T19350-lib`, in ./lib) which depends upon it via `foreign
+-- import`. We make sure that the libhello shared object can only be found via
+-- the extra-lib-dirs from the package database registration (which we do by
+-- moving libhello.so from its original place).
+--
+-- Finally, we enter GHCi, load the Haskell library, and try to use it to call
+-- into libhello.
+
+import System.Directory
+import Distribution.System
+import Test.Cabal.Prelude
+
+
+main = setupTest $ do
+
+  skipIfWindows
+  skipUnlessGhcVersion ">= 8.4"
+
+  withPackageDb $ do
+    cwd  <- takeDirectory . testCurrentDir <$> getTestEnv
+    plat <- testPlatform <$> getTestEnv
+    let libExt = case plat of
+          Platform _ OSX     -> "dylib"
+          Platform _ Windows -> "dll"
+          Platform _ _other  -> "so"
+
+
+    -- Link a C program against the library
+    _ <- runProgramM ghcProgram
+        [ "-fPIC", "-c", "clib/lib.c"
+        , "-o", "clib/lib.o" ]
+        Nothing
+    _ <- runProgramM ghcProgram
+        [ "-shared", "-no-hs-main", "clib/lib.o"
+        , "-o", "clib/libhello" <.> libExt ]
+        Nothing
+
+    withDirectory "lib" $ do
+      setup "configure" ["-v0"
+                        , "--extra-lib-dirs=" ++ (cwd </> "clib")
+                        , "--extra-lib-dirs=" ++ (cwd </> "clib-install")
+                        , "--disable-library-vanilla"
+                        , "--enable-shared"]
+      setup "build" []
+      setup "register" ["--inplace"]
+
+    -- Move libhello from its original place to ensure it isn't found via RPATH
+    liftIO $ do
+      createDirectoryIfMissing False (cwd </> "clib-install")
+      copyFile (cwd </> "clib/libhello" <.> libExt) ( cwd </> "clib-install/libhello" <.> libExt)
+      removeFile (cwd </> "clib/libhello" <.> libExt)
+
+    pkgDb <- testPackageDbDir <$> getTestEnv
+    ghciScript <- liftIO $ readFile (cwd </> "T19350.script")
+    _ <- runProgramM ghcProgram
+         [ "--interactive"
+         , "-package", "T7339"
+         , "-package-db", pkgDb
+         ] (Just ghciScript)
+
+    return ()
diff --git a/cabal/cabal-testsuite/PackageTests/ListBin/Script/cabal.out b/cabal/cabal-testsuite/PackageTests/ListBin/Script/cabal.out
--- a/cabal/cabal-testsuite/PackageTests/ListBin/Script/cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/ListBin/Script/cabal.out
@@ -2,4 +2,5 @@
 Resolving dependencies...
 Build profile: -w ghc-<GHCVER> -O1
 In order, the following will be built:
- - fake-package-0 (exe:cabal-script-script.hs) (first run)
+ - fake-package-0 (exe:script-script.hs) (first run)
+<ROOT>/cabal.dist/work/./dist/build/<ARCH>/ghc-<GHCVER>/fake-package-0/x/script-script.hs/bin/cabal-script-script.hs
diff --git a/cabal/cabal-testsuite/PackageTests/ListBin/SelectedComponent/cabal.out b/cabal/cabal-testsuite/PackageTests/ListBin/SelectedComponent/cabal.out
--- a/cabal/cabal-testsuite/PackageTests/ListBin/SelectedComponent/cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/ListBin/SelectedComponent/cabal.out
@@ -3,3 +3,4 @@
 Build profile: -w ghc-<GHCVER> -O1
 In order, the following will be built:
  - SelectedComponent-1.0.0 (exe:testexe) (first run)
+<ROOT>/cabal.dist/work/./dist/build/<ARCH>/ghc-<GHCVER>/SelectedComponent-1.0.0/build/testexe/testexe
diff --git a/cabal/cabal-testsuite/PackageTests/ListBin/SelectedComponent/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/ListBin/SelectedComponent/cabal.test.hs
--- a/cabal/cabal-testsuite/PackageTests/ListBin/SelectedComponent/cabal.test.hs
+++ b/cabal/cabal-testsuite/PackageTests/ListBin/SelectedComponent/cabal.test.hs
@@ -1,8 +1,12 @@
+import System.FilePath ( joinPath )
+
 import Test.Cabal.Prelude
 
 -- https://github.com/haskell/cabal/issues/7679
+-- https://github.com/haskell/cabal/issues/8400
+
 main = cabalTest . void $ do
     res <- cabal' "list-bin" ["exe:testexe"]
 
-    assertOutputContains "SelectedComponent-1.0.0" res
-    assertOutputContains "testexe" res
+    let path = joinPath ["SelectedComponent-1.0.0", "build", "testexe", "testexe"]
+    assertOutputContains path res
diff --git a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdBench/OptionsFlag/OptionsFlag.hs b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdBench/OptionsFlag/OptionsFlag.hs
--- a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdBench/OptionsFlag/OptionsFlag.hs
+++ b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdBench/OptionsFlag/OptionsFlag.hs
@@ -6,7 +6,6 @@
 main :: IO ()
 main = do
   args <- getArgs
-  let allArgs = unwords args
-  if allArgs == "1 2 3 4 5 6"
+  if args == ["1", "2 3", "4", "5 6"]
      then exitSuccess
-     else putStrLn ("Got: " ++ allArgs) >> exitFailure
+     else putStrLn ("Got: " ++ show args) >> exitFailure
diff --git a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdBuild/Script/cabal.out b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdBuild/Script/cabal.out
--- a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdBuild/Script/cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdBuild/Script/cabal.out
@@ -2,6 +2,6 @@
 Resolving dependencies...
 Build profile: -w ghc-<GHCVER> -O1
 In order, the following will be built:
- - fake-package-0 (exe:cabal-script-script.hs) (first run)
-Configuring executable 'cabal-script-script.hs' for fake-package-0..
-Building executable 'cabal-script-script.hs' for fake-package-0..
+ - fake-package-0 (exe:script-script.hs) (first run)
+Configuring executable 'script-script.hs' for fake-package-0..
+Building executable 'script-script.hs' for fake-package-0..
diff --git a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdBuild/ScriptBuildRepl/cabal.out b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdBuild/ScriptBuildRepl/cabal.out
--- a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdBuild/ScriptBuildRepl/cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdBuild/ScriptBuildRepl/cabal.out
@@ -2,10 +2,10 @@
 Resolving dependencies...
 Build profile: -w ghc-<GHCVER> -O1
 In order, the following will be built:
- - fake-package-0 (exe:cabal-script-script.hs) (first run)
-Configuring executable 'cabal-script-script.hs' for fake-package-0..
-Building executable 'cabal-script-script.hs' for fake-package-0..
+ - fake-package-0 (exe:script-script.hs) (first run)
+Configuring executable 'script-script.hs' for fake-package-0..
+Building executable 'script-script.hs' for fake-package-0..
 # cabal v2-repl
 Build profile: -w ghc-<GHCVER> -O1
 In order, the following will be built:
- - fake-package-0 (exe:cabal-script-script.hs) (ephemeral targets)
+ - fake-package-0 (exe:script-script.hs) (ephemeral targets)
diff --git a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdBuild/ScriptBuildRun/cabal.out b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdBuild/ScriptBuildRun/cabal.out
--- a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdBuild/ScriptBuildRun/cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdBuild/ScriptBuildRun/cabal.out
@@ -2,8 +2,7 @@
 Resolving dependencies...
 Build profile: -w ghc-<GHCVER> -O1
 In order, the following will be built:
- - fake-package-0 (exe:cabal-script-script.hs) (first run)
-Configuring executable 'cabal-script-script.hs' for fake-package-0..
-Building executable 'cabal-script-script.hs' for fake-package-0..
+ - fake-package-0 (exe:script-script.hs) (first run)
+Configuring executable 'script-script.hs' for fake-package-0..
+Building executable 'script-script.hs' for fake-package-0..
 # cabal v2-run
-Up to date
diff --git a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdBuild/ScriptRerun/cabal.out b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdBuild/ScriptRerun/cabal.out
--- a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdBuild/ScriptRerun/cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdBuild/ScriptRerun/cabal.out
@@ -2,8 +2,8 @@
 Resolving dependencies...
 Build profile: -w ghc-<GHCVER> -O1
 In order, the following will be built:
- - fake-package-0 (exe:cabal-script-script.hs) (first run)
-Configuring executable 'cabal-script-script.hs' for fake-package-0..
-Building executable 'cabal-script-script.hs' for fake-package-0..
+ - fake-package-0 (exe:script-script.hs) (first run)
+Configuring executable 'script-script.hs' for fake-package-0..
+Building executable 'script-script.hs' for fake-package-0..
 # cabal v2-build
 Up to date
diff --git a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdClean/Keep/cabal.out b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdClean/Keep/cabal.out
--- a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdClean/Keep/cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdClean/Keep/cabal.out
@@ -2,14 +2,14 @@
 Resolving dependencies...
 Build profile: -w ghc-<GHCVER> -O1
 In order, the following will be built:
- - fake-package-0 (exe:cabal-script-script.hs) (first run)
-Configuring executable 'cabal-script-script.hs' for fake-package-0..
-Building executable 'cabal-script-script.hs' for fake-package-0..
+ - fake-package-0 (exe:script-script.hs) (first run)
+Configuring executable 'script-script.hs' for fake-package-0..
+Building executable 'script-script.hs' for fake-package-0..
 # cabal v2-build
 Resolving dependencies...
 Build profile: -w ghc-<GHCVER> -O1
 In order, the following will be built:
- - fake-package-0 (exe:cabal-script-script2.hs) (first run)
-Configuring executable 'cabal-script-script2.hs' for fake-package-0..
-Building executable 'cabal-script-script2.hs' for fake-package-0..
+ - fake-package-0 (exe:script-script2.hs) (first run)
+Configuring executable 'script-script2.hs' for fake-package-0..
+Building executable 'script-script2.hs' for fake-package-0..
 # cabal v2-clean
diff --git a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdClean/Orphan/cabal.out b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdClean/Orphan/cabal.out
--- a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdClean/Orphan/cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdClean/Orphan/cabal.out
@@ -2,14 +2,14 @@
 Resolving dependencies...
 Build profile: -w ghc-<GHCVER> -O1
 In order, the following will be built:
- - fake-package-0 (exe:cabal-script-script.hs) (first run)
-Configuring executable 'cabal-script-script.hs' for fake-package-0..
-Building executable 'cabal-script-script.hs' for fake-package-0..
+ - fake-package-0 (exe:script-script.hs) (first run)
+Configuring executable 'script-script.hs' for fake-package-0..
+Building executable 'script-script.hs' for fake-package-0..
 # cabal v2-build
 Resolving dependencies...
 Build profile: -w ghc-<GHCVER> -O1
 In order, the following will be built:
- - fake-package-0 (exe:cabal-script-script2.hs) (first run)
-Configuring executable 'cabal-script-script2.hs' for fake-package-0..
-Building executable 'cabal-script-script2.hs' for fake-package-0..
+ - fake-package-0 (exe:script-script2.hs) (first run)
+Configuring executable 'script-script2.hs' for fake-package-0..
+Building executable 'script-script2.hs' for fake-package-0..
 # cabal v2-clean
diff --git a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdClean/Script/cabal.out b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdClean/Script/cabal.out
--- a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdClean/Script/cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdClean/Script/cabal.out
@@ -2,7 +2,7 @@
 Resolving dependencies...
 Build profile: -w ghc-<GHCVER> -O1
 In order, the following will be built:
- - fake-package-0 (exe:cabal-script-script.hs) (first run)
-Configuring executable 'cabal-script-script.hs' for fake-package-0..
-Building executable 'cabal-script-script.hs' for fake-package-0..
+ - fake-package-0 (exe:script-script.hs) (first run)
+Configuring executable 'script-script.hs' for fake-package-0..
+Building executable 'script-script.hs' for fake-package-0..
 # cabal v2-clean
diff --git a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRepl/Script/cabal.out b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRepl/Script/cabal.out
--- a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRepl/Script/cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRepl/Script/cabal.out
@@ -2,5 +2,5 @@
 Resolving dependencies...
 Build profile: -w ghc-<GHCVER> -O1
 In order, the following will be built:
- - fake-package-0 (exe:cabal-script-script.hs) (first run)
-Configuring executable 'cabal-script-script.hs' for fake-package-0..
+ - fake-package-0 (exe:script-script.hs) (first run)
+Configuring executable 'script-script.hs' for fake-package-0..
diff --git a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRepl/ScriptRerun/cabal.out b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRepl/ScriptRerun/cabal.out
--- a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRepl/ScriptRerun/cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRepl/ScriptRerun/cabal.out
@@ -2,9 +2,9 @@
 Resolving dependencies...
 Build profile: -w ghc-<GHCVER> -O1
 In order, the following will be built:
- - fake-package-0 (exe:cabal-script-script.hs) (first run)
-Configuring executable 'cabal-script-script.hs' for fake-package-0..
+ - fake-package-0 (exe:script-script.hs) (first run)
+Configuring executable 'script-script.hs' for fake-package-0..
 # cabal v2-repl
 Build profile: -w ghc-<GHCVER> -O1
 In order, the following will be built:
- - fake-package-0 (exe:cabal-script-script.hs) (first run)
+ - fake-package-0 (exe:script-script.hs) (first run)
diff --git a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/Datafiles/foo/foo.cabal b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/Datafiles/foo/foo.cabal
--- a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/Datafiles/foo/foo.cabal
+++ b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/Datafiles/foo/foo.cabal
@@ -12,8 +12,9 @@
 
 library
     exposed-modules: LibFoo
-    other-modules: Paths_foo
+    other-modules:
+        PackageInfo_foo
+        Paths_foo
     build-depends: base
     default-language: Haskell2010
-
 
diff --git a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/MultipleExes/cabal.out b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/MultipleExes/cabal.out
--- a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/MultipleExes/cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/MultipleExes/cabal.out
@@ -14,8 +14,10 @@
 Preprocessing executable 'bar' for MultipleExes-1.0..
 Building executable 'bar' for MultipleExes-1.0..
 # cabal v2-run
-Up to date
+
 # cabal v2-run
-Error: cabal: The run command is for running a single executable at once. The target '' refers to the package MultipleExes-1.0 which includes the executable 'foo' and the executable 'bar'.
+Error: cabal: The run command is for running a single executable at once. The target '' refers to the package MultipleExes-1.0 which includes 
+- executables: bar and foo
 # cabal v2-run
-Error: cabal: The run command is for running a single executable at once. The target 'MultipleExes' refers to the package MultipleExes-1.0 which includes the executable 'foo' and the executable 'bar'.
+Error: cabal: The run command is for running a single executable at once. The target 'MultipleExes' refers to the package MultipleExes-1.0 which includes 
+- executables: bar and foo
diff --git a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/MultiplePackages/cabal.out b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/MultiplePackages/cabal.out
--- a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/MultiplePackages/cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/MultiplePackages/cabal.out
@@ -7,7 +7,6 @@
 Preprocessing executable 'bar-exe' for bar-1.0..
 Building executable 'bar-exe' for bar-1.0..
 # cabal v2-run
-Up to date
 # cabal v2-run
 Build profile: -w ghc-<GHCVER> -O1
 In order, the following will be built:
@@ -25,7 +24,8 @@
 # cabal v2-run
 Error: cabal: No targets given and there is no package in the current directory. Specify packages or components by name or location. See 'cabal build --help' for more details on target options.
 # cabal v2-run
-Error: cabal: The run command is for running a single executable at once. The target 'bar' refers to the package bar-1.0 which includes the executable 'foo-exe' and the executable 'bar-exe'.
+Error: cabal: The run command is for running a single executable at once. The target 'bar' refers to the package bar-1.0 which includes 
+- executables: bar-exe and foo-exe
 # cabal v2-run
 Error: cabal: Ambiguous target 'foo-exe'. It could be:
     bar:foo-exe (component)
diff --git a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/Script/cabal.out b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/Script/cabal.out
--- a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/Script/cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/Script/cabal.out
@@ -2,6 +2,6 @@
 Resolving dependencies...
 Build profile: -w ghc-<GHCVER> -O1
 In order, the following will be built:
- - fake-package-0 (exe:cabal-script-script.hs) (first run)
-Configuring executable 'cabal-script-script.hs' for fake-package-0..
-Building executable 'cabal-script-script.hs' for fake-package-0..
+ - fake-package-0 (exe:script-script.hs) (first run)
+Configuring executable 'script-script.hs' for fake-package-0..
+Building executable 'script-script.hs' for fake-package-0..
diff --git a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/ScriptLiterate/cabal.out b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/ScriptLiterate/cabal.out
--- a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/ScriptLiterate/cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/ScriptLiterate/cabal.out
@@ -2,6 +2,6 @@
 Resolving dependencies...
 Build profile: -w ghc-<GHCVER> -O1
 In order, the following will be built:
- - fake-package-0 (exe:cabal-script-script.lhs) (first run)
-Configuring executable 'cabal-script-script.lhs' for fake-package-0..
-Building executable 'cabal-script-script.lhs' for fake-package-0..
+ - fake-package-0 (exe:script-script.lhs) (first run)
+Configuring executable 'script-script.lhs' for fake-package-0..
+Building executable 'script-script.lhs' for fake-package-0..
diff --git a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/ScriptNoExtension/cabal.out b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/ScriptNoExtension/cabal.out
--- a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/ScriptNoExtension/cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/ScriptNoExtension/cabal.out
@@ -2,6 +2,6 @@
 Resolving dependencies...
 Build profile: -w ghc-<GHCVER> -O1
 In order, the following will be built:
- - fake-package-0 (exe:cabal-script-with_sp) (first run)
-Configuring executable 'cabal-script-with_sp' for fake-package-0..
-Building executable 'cabal-script-with_sp' for fake-package-0..
+ - fake-package-0 (exe:script-with_sp) (first run)
+Configuring executable 'script-with_sp' for fake-package-0..
+Building executable 'script-with_sp' for fake-package-0..
diff --git a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/ScriptRerun/cabal.out b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/ScriptRerun/cabal.out
--- a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/ScriptRerun/cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/ScriptRerun/cabal.out
@@ -2,8 +2,7 @@
 Resolving dependencies...
 Build profile: -w ghc-<GHCVER> -O1
 In order, the following will be built:
- - fake-package-0 (exe:cabal-script-script.hs) (first run)
-Configuring executable 'cabal-script-script.hs' for fake-package-0..
-Building executable 'cabal-script-script.hs' for fake-package-0..
+ - fake-package-0 (exe:script-script.hs) (first run)
+Configuring executable 'script-script.hs' for fake-package-0..
+Building executable 'script-script.hs' for fake-package-0..
 # cabal v2-run
-Up to date
diff --git a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/ScriptWithProjectBlock/cabal.out b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/ScriptWithProjectBlock/cabal.out
--- a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/ScriptWithProjectBlock/cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/ScriptWithProjectBlock/cabal.out
@@ -2,6 +2,6 @@
 Resolving dependencies...
 Build profile: -w ghc-<GHCVER> -O2
 In order, the following will be built:
- - fake-package-0 (exe:cabal-script-s.hs) (first run)
-Configuring executable 'cabal-script-s.hs' for fake-package-0..
-Building executable 'cabal-script-s.hs' for fake-package-0..
+ - fake-package-0 (exe:script-s.hs) (first run)
+Configuring executable 'script-s.hs' for fake-package-0..
+Building executable 'script-s.hs' for fake-package-0..
diff --git a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/Single/cabal.out b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/Single/cabal.out
--- a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/Single/cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/Single/cabal.out
@@ -7,12 +7,8 @@
 Preprocessing executable 'foo' for Single-1.0..
 Building executable 'foo' for Single-1.0..
 # cabal v2-run
-Up to date
 # cabal v2-run
-Up to date
 # cabal v2-run
-Up to date
 # cabal v2-run
-Up to date
 # cabal v2-run
 Error: cabal: Cannot run the package bar, it is not in this project (either directly or indirectly). If you want to add it to the project then edit the cabal.project file.
diff --git a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/Terminate/Main.hs b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/Terminate/Main.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/Terminate/Main.hs
@@ -0,0 +1,22 @@
+import Control.Concurrent (killThread, threadDelay, myThreadId)
+import Control.Exception (finally)
+import qualified System.Posix.Signals as Signal
+import System.Exit (exitFailure)
+import qualified Data.Time.Clock as Time
+import qualified Data.Time.Format as Time
+
+main = do
+  -- timestamped logging to aid with #8416
+  let log msg = do
+        ts <- Time.getCurrentTime
+        let tsfmt = Time.formatTime Time.defaultTimeLocale "%H:%M:%S.%q" ts
+        putStrLn $ tsfmt <> " [exe       ] " <> msg
+  mainThreadId <- myThreadId
+  Signal.installHandler Signal.sigTERM (Signal.Catch $ killThread mainThreadId) Nothing
+  (do
+    log "about to write file"
+    writeFile "exe.run" "up and running"
+    log "about to sleep"
+    threadDelay 10000000 -- 10s
+    log "done sleeping")
+    `finally` log "exiting"
diff --git a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/Terminate/RunKill.cabal b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/Terminate/RunKill.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/Terminate/RunKill.cabal
@@ -0,0 +1,9 @@
+name: RunKill
+version: 1.0
+build-type: Simple
+cabal-version: >= 1.10
+
+executable exe
+  default-language: Haskell2010
+  build-depends: base, process, time, unix
+  main-is: Main.hs
diff --git a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/Terminate/cabal.project b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/Terminate/cabal.project
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/Terminate/cabal.project
@@ -0,0 +1,2 @@
+packages: .
+
diff --git a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/Terminate/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/Terminate/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdRun/Terminate/cabal.test.hs
@@ -0,0 +1,75 @@
+import Test.Cabal.Prelude
+import qualified System.Process as Process
+import Control.Concurrent (threadDelay)
+import System.Directory (removeFile)
+import Control.Exception (catch, throwIO)
+import System.IO.Error (isDoesNotExistError)
+import qualified Data.Time.Clock as Time
+import qualified Data.Time.Format as Time
+
+{-
+This test verifies that 'cabal run' terminates its
+child when it is killed. More generally, while we
+use the same code path for all child processes, this
+ensure that cabal-install cleans up after all children.
+(That might change if 'cabal run' is changed to exec(3)
+without forking in the future.)
+-}
+
+main :: IO ()
+main = cabalTest $ do
+  skipIfWindows -- test project relies on Posix
+
+  -- timestamped logging to aid with #8416
+  let logIO msg = do
+        ts <- Time.getCurrentTime
+        let tsfmt = Time.formatTime Time.defaultTimeLocale "%H:%M:%S.%q" ts
+        putStrLn $ tsfmt <> " [cabal.test] " <> msg
+      log = liftIO . logIO
+
+  dir <- fmap testCurrentDir getTestEnv
+  let runFile = dir </> "exe.run"
+  liftIO $ removeFile runFile `catchNoExist` return ()
+
+  log "about to v2-build"
+  cabal_raw_action ["v2-build", "exe"] (\_ -> return ())
+  log "about to v2-run"
+  r <- fails $ cabal_raw_action ["v2-run", "exe"] $ \cabalHandle -> do
+    -- wait for "cabal run" to have started "exe"
+    logIO "about to wait for file"
+    waitFile total runFile
+    -- then kill "cabal run"
+    logIO "about to terminate cabal"
+    Process.terminateProcess cabalHandle
+  log "v2-run done"
+
+  -- "exe" should exit, and should have been interrupted before
+  -- finishing its sleep
+  assertOutputContains "exiting" r
+  assertOutputDoesNotContain "done sleeping" r
+
+  where
+    catchNoExist action handle =
+      action `catch`
+        (\e -> if isDoesNotExistError e then handle else throwIO e)
+    waitFile totalWait f
+      | totalWait <= 0 = error "waitFile timed out"
+      | otherwise      = readFile f `catchNoExist` do
+                           threadDelay delta
+                           waitFile (totalWait - delta) f
+    delta = 50000 -- 0.05s
+    total = 10000000 -- 10s
+
+cabal_raw_action :: [String] -> (Process.ProcessHandle -> IO ()) -> TestM Result
+cabal_raw_action args action = do
+    configured_prog <- requireProgramM cabalProgram
+    env <- getTestEnv
+    r <- liftIO $ runAction (testVerbosity env)
+                 (Just (testCurrentDir env))
+                 (testEnvironment env)
+                 (programPath configured_prog)
+                 args
+                 Nothing
+                 action
+    recordLog r
+    requireSuccess r
diff --git a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdTest/OptionsFlag/OptionsFlag.hs b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdTest/OptionsFlag/OptionsFlag.hs
--- a/cabal/cabal-testsuite/PackageTests/NewBuild/CmdTest/OptionsFlag/OptionsFlag.hs
+++ b/cabal/cabal-testsuite/PackageTests/NewBuild/CmdTest/OptionsFlag/OptionsFlag.hs
@@ -6,7 +6,6 @@
 main :: IO ()
 main = do
   args <- getArgs
-  let allArgs = unwords args
-  if allArgs == "1 2 3 4 5 6"
+  if args == ["1", "2 3", "4", "5 6"]
      then exitSuccess
-     else putStrLn ("Got: " ++ allArgs) >> exitFailure
+     else putStrLn ("Got: " ++ show args) >> exitFailure
diff --git a/cabal/cabal-testsuite/PackageTests/NewBuild/MonitorCabalFiles/cabal.out b/cabal/cabal-testsuite/PackageTests/NewBuild/MonitorCabalFiles/cabal.out
--- a/cabal/cabal-testsuite/PackageTests/NewBuild/MonitorCabalFiles/cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/NewBuild/MonitorCabalFiles/cabal.out
@@ -6,6 +6,7 @@
 Configuring executable 'q' for q-0.1.0.0..
 Preprocessing executable 'q' for q-0.1.0.0..
 Building executable 'q' for q-0.1.0.0..
+Error: cabal: Failed to build q-0.1.0.0-inplace-q.
 # cabal v2-build
 Resolving dependencies...
 Build profile: -w ghc-<GHCVER> -O1
diff --git a/cabal/cabal-testsuite/PackageTests/NewBuild/T3460/T3460.cabal b/cabal/cabal-testsuite/PackageTests/NewBuild/T3460/T3460.cabal
--- a/cabal/cabal-testsuite/PackageTests/NewBuild/T3460/T3460.cabal
+++ b/cabal/cabal-testsuite/PackageTests/NewBuild/T3460/T3460.cabal
@@ -3,20 +3,20 @@
 
 name:                T3460
 version:             0.1.0.0
--- synopsis:            
--- description:         
+-- synopsis:
+-- description:
 license:             BSD3
 author:              Edward Z. Yang
 maintainer:          ezyang@cs.stanford.edu
--- copyright:           
--- category:            
+-- copyright:
+-- category:
 build-type:          Simple
 cabal-version:       >=1.10
 
 library
   exposed-modules:     C
-  -- other-modules:       
-  -- other-extensions:    
+  -- other-modules:
+  -- other-extensions:
   build-depends:       base, sub-package-A, sub-package-B
-  -- hs-source-dirs:      
+  -- hs-source-dirs:
   default-language:    Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/NewBuild/T3460/sub-package-A/sub-package-A.cabal b/cabal/cabal-testsuite/PackageTests/NewBuild/T3460/sub-package-A/sub-package-A.cabal
--- a/cabal/cabal-testsuite/PackageTests/NewBuild/T3460/sub-package-A/sub-package-A.cabal
+++ b/cabal/cabal-testsuite/PackageTests/NewBuild/T3460/sub-package-A/sub-package-A.cabal
@@ -1,22 +1,22 @@
--- Initial sub-package-A.cabal generated by cabal init.  For further 
+-- Initial sub-package-A.cabal generated by cabal init.  For further
 -- documentation, see http://haskell.org/cabal/users-guide/
 
 name:                sub-package-A
 version:             0.1.0.0
--- synopsis:            
--- description:         
+-- synopsis:
+-- description:
 license:             BSD3
 author:              Edward Z. Yang
 maintainer:          ezyang@cs.stanford.edu
--- copyright:           
--- category:            
+-- copyright:
+-- category:
 build-type:          Simple
 cabal-version:       >=1.10
 
 library
   exposed-modules:     A
-  -- other-modules:       
-  -- other-extensions:    
+  -- other-modules:
+  -- other-extensions:
   build-depends:       base
-  -- hs-source-dirs:      
+  -- hs-source-dirs:
   default-language:    Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/NewBuild/T3460/sub-package-B/sub-package-B.cabal b/cabal/cabal-testsuite/PackageTests/NewBuild/T3460/sub-package-B/sub-package-B.cabal
--- a/cabal/cabal-testsuite/PackageTests/NewBuild/T3460/sub-package-B/sub-package-B.cabal
+++ b/cabal/cabal-testsuite/PackageTests/NewBuild/T3460/sub-package-B/sub-package-B.cabal
@@ -1,22 +1,22 @@
--- Initial sub-package-B.cabal generated by cabal init.  For further 
+-- Initial sub-package-B.cabal generated by cabal init.  For further
 -- documentation, see http://haskell.org/cabal/users-guide/
 
 name:                sub-package-B
 version:             0.1.0.0
--- synopsis:            
--- description:         
+-- synopsis:
+-- description:
 license:             BSD3
 author:              Edward Z. Yang
 maintainer:          ezyang@cs.stanford.edu
--- copyright:           
--- category:            
+-- copyright:
+-- category:
 build-type:          Simple
 cabal-version:       >=1.10
 
 library
   exposed-modules:     B
-  -- other-modules:       
-  -- other-extensions:    
+  -- other-modules:
+  -- other-extensions:
   build-depends:       base
-  -- hs-source-dirs:      
+  -- hs-source-dirs:
   default-language:    Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/NewBuild/T5164/setup-lib/setup-lib.cabal b/cabal/cabal-testsuite/PackageTests/NewBuild/T5164/setup-lib/setup-lib.cabal
--- a/cabal/cabal-testsuite/PackageTests/NewBuild/T5164/setup-lib/setup-lib.cabal
+++ b/cabal/cabal-testsuite/PackageTests/NewBuild/T5164/setup-lib/setup-lib.cabal
@@ -6,6 +6,8 @@
 
 library
     exposed-modules: SetupLib
-    other-modules: Paths_setup_lib
+    other-modules:
+        PackageInfo_setup_lib
+        Paths_setup_lib
     build-depends: base
     default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/NewHaddock/DisableDoc/B/B.cabal b/cabal/cabal-testsuite/PackageTests/NewHaddock/DisableDoc/B/B.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/NewHaddock/DisableDoc/B/B.cabal
@@ -0,0 +1,12 @@
+cabal-version:      2.4
+name:               B
+version:            0.1.0.0
+author:             Artem Pelenitsyn
+maintainer:         a.pelenitsyn@gmail.com
+
+library
+    exposed-modules:  B
+    build-depends:    base
+                    , A
+    hs-source-dirs:   .
+    default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/NewHaddock/DisableDoc/B/B.hs b/cabal/cabal-testsuite/PackageTests/NewHaddock/DisableDoc/B/B.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/NewHaddock/DisableDoc/B/B.hs
@@ -0,0 +1,8 @@
+-- | Module using external dependency and mentioning it in haddocks
+module B (b) where
+
+import A
+
+-- | Use 'a'
+b :: Int
+b = a
diff --git a/cabal/cabal-testsuite/PackageTests/NewHaddock/DisableDoc/cabal.out b/cabal/cabal-testsuite/PackageTests/NewHaddock/DisableDoc/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/NewHaddock/DisableDoc/cabal.out
@@ -0,0 +1,16 @@
+# cabal v2-update
+Downloading the latest package list from test-local-repo
+# cabal haddock
+Resolving dependencies...
+Build profile: -w ghc-<GHCVER> -O1
+In order, the following will be built:
+ - A-0.1.0.0 (lib) (requires build)
+ - B-0.1.0.0 (lib) (first run)
+Configuring library for A-0.1.0.0..
+Preprocessing library for A-0.1.0.0..
+Building library for A-0.1.0.0..
+Installing library in <PATH>
+Configuring library for B-0.1.0.0..
+Preprocessing library for B-0.1.0.0..
+Running Haddock on library for B-0.1.0.0..
+Documentation created: <ROOT>/cabal.dist/work/dist/build/<ARCH>/ghc-<GHCVER>/B-0.1.0.0/doc/html/B/
diff --git a/cabal/cabal-testsuite/PackageTests/NewHaddock/DisableDoc/cabal.project b/cabal/cabal-testsuite/PackageTests/NewHaddock/DisableDoc/cabal.project
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/NewHaddock/DisableDoc/cabal.project
@@ -0,0 +1,1 @@
+packages: B
diff --git a/cabal/cabal-testsuite/PackageTests/NewHaddock/DisableDoc/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/NewHaddock/DisableDoc/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/NewHaddock/DisableDoc/cabal.test.hs
@@ -0,0 +1,6 @@
+import Test.Cabal.Prelude
+-- Test that `cabal haddock --disable-documention` works as expected and leads
+-- to a warning if a local package makes an outer reference.
+main = cabalTest . withRepo "repo" $ do
+    r <- cabal' "haddock" ["--disable-documentation", "B"]
+    assertOutputContains "Warning: B: could not find link destinations for" r
diff --git a/cabal/cabal-testsuite/PackageTests/NewHaddock/DisableDoc/repo/A-0.1.0.0/A.cabal b/cabal/cabal-testsuite/PackageTests/NewHaddock/DisableDoc/repo/A-0.1.0.0/A.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/NewHaddock/DisableDoc/repo/A-0.1.0.0/A.cabal
@@ -0,0 +1,11 @@
+cabal-version:      2.4
+name:               A
+version:            0.1.0.0
+author:             Artem Pelenitsyn
+maintainer:         a.pelenitsyn@gmail.com
+
+library
+    exposed-modules:  A
+    build-depends:    base
+    hs-source-dirs:   .
+    default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/NewHaddock/DisableDoc/repo/A-0.1.0.0/A.hs b/cabal/cabal-testsuite/PackageTests/NewHaddock/DisableDoc/repo/A-0.1.0.0/A.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/NewHaddock/DisableDoc/repo/A-0.1.0.0/A.hs
@@ -0,0 +1,4 @@
+module A (a) where
+
+a :: Int
+a = 42
diff --git a/cabal/cabal-testsuite/PackageTests/NewHaddock/Fails/cabal.out b/cabal/cabal-testsuite/PackageTests/NewHaddock/Fails/cabal.out
--- a/cabal/cabal-testsuite/PackageTests/NewHaddock/Fails/cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/NewHaddock/Fails/cabal.out
@@ -6,6 +6,7 @@
 Configuring library for example-1.0..
 Preprocessing library for example-1.0..
 Building library for example-1.0..
+Error: cabal: Failed to build example-1.0-inplace.
 # cabal v2-haddock
 Build profile: -w ghc-<GHCVER> -O1
 In order, the following will be built:
diff --git a/cabal/cabal-testsuite/PackageTests/NewHaddock/HaddockOutput/HaddockOutputCmd/cabal.out b/cabal/cabal-testsuite/PackageTests/NewHaddock/HaddockOutput/HaddockOutputCmd/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/NewHaddock/HaddockOutput/HaddockOutputCmd/cabal.out
@@ -0,0 +1,11 @@
+# cabal v2-update
+Downloading the latest package list from test-local-repo
+# cabal haddock
+Resolving dependencies...
+Build profile: -w ghc-<GHCVER> -O1
+In order, the following will be built:
+ - A-0.0.0 (lib) (first run)
+Configuring library for A-0.0.0...
+Preprocessing library for A-0.0.0...
+Running Haddock on library for A-0.0.0...
+Documentation created: <ROOT>/docs/
diff --git a/cabal/cabal-testsuite/PackageTests/NewHaddock/HaddockOutput/HaddockOutputConfig/cabal.out b/cabal/cabal-testsuite/PackageTests/NewHaddock/HaddockOutput/HaddockOutputConfig/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/NewHaddock/HaddockOutput/HaddockOutputConfig/cabal.out
@@ -0,0 +1,11 @@
+# cabal v2-update
+Downloading the latest package list from test-local-repo
+# cabal haddock
+Resolving dependencies...
+Build profile: -w ghc-<GHCVER> -O1
+In order, the following will be built:
+ - A-0.0.0 (lib) (first run)
+Configuring library for A-0.0.0...
+Preprocessing library for A-0.0.0...
+Running Haddock on library for A-0.0.0...
+Documentation created: <ROOT>/docs/
diff --git a/cabal/cabal-testsuite/PackageTests/NewHaddock/ImplyDependencies/B/B.cabal b/cabal/cabal-testsuite/PackageTests/NewHaddock/ImplyDependencies/B/B.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/NewHaddock/ImplyDependencies/B/B.cabal
@@ -0,0 +1,12 @@
+cabal-version:      2.4
+name:               B
+version:            0.1.0.0
+author:             Artem Pelenitsyn
+maintainer:         a.pelenitsyn@gmail.com
+
+library
+    exposed-modules:  B
+    build-depends:    base
+                    , A
+    hs-source-dirs:   .
+    default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/NewHaddock/ImplyDependencies/B/B.hs b/cabal/cabal-testsuite/PackageTests/NewHaddock/ImplyDependencies/B/B.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/NewHaddock/ImplyDependencies/B/B.hs
@@ -0,0 +1,8 @@
+-- | Module using external dependency and mentioning it in haddocks
+module B (b) where
+
+import A
+
+-- | Use 'a'
+b :: Int
+b = a
diff --git a/cabal/cabal-testsuite/PackageTests/NewHaddock/ImplyDependencies/cabal.out b/cabal/cabal-testsuite/PackageTests/NewHaddock/ImplyDependencies/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/NewHaddock/ImplyDependencies/cabal.out
@@ -0,0 +1,19 @@
+# cabal v2-update
+Downloading the latest package list from test-local-repo
+# cabal haddock
+Resolving dependencies...
+Build profile: -w ghc-<GHCVER> -O1
+In order, the following will be built:
+ - A-0.1.0.0 (lib) (requires build)
+ - B-0.1.0.0 (lib) (first run)
+Configuring library for A-0.1.0.0..
+Preprocessing library for A-0.1.0.0..
+Building library for A-0.1.0.0..
+Preprocessing library for A-0.1.0.0..
+Running Haddock on library for A-0.1.0.0..
+Documentation created: dist/doc/html/A/
+Installing library in <PATH>
+Configuring library for B-0.1.0.0..
+Preprocessing library for B-0.1.0.0..
+Running Haddock on library for B-0.1.0.0..
+Documentation created: <ROOT>/cabal.dist/work/dist/build/<ARCH>/ghc-<GHCVER>/B-0.1.0.0/doc/html/B/
diff --git a/cabal/cabal-testsuite/PackageTests/NewHaddock/ImplyDependencies/cabal.project b/cabal/cabal-testsuite/PackageTests/NewHaddock/ImplyDependencies/cabal.project
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/NewHaddock/ImplyDependencies/cabal.project
@@ -0,0 +1,1 @@
+packages: B
diff --git a/cabal/cabal-testsuite/PackageTests/NewHaddock/ImplyDependencies/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/NewHaddock/ImplyDependencies/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/NewHaddock/ImplyDependencies/cabal.test.hs
@@ -0,0 +1,6 @@
+import Test.Cabal.Prelude
+-- Test that `cabal haddock` doesn't require explicit
+-- `--enable-dependencies` to happily process links to external packages.
+-- In this example package B depends on an external package A.
+main = cabalTest . withRepo "repo" $
+    cabal "haddock" ["B"]
diff --git a/cabal/cabal-testsuite/PackageTests/NewHaddock/ImplyDependencies/repo/A-0.1.0.0/A.cabal b/cabal/cabal-testsuite/PackageTests/NewHaddock/ImplyDependencies/repo/A-0.1.0.0/A.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/NewHaddock/ImplyDependencies/repo/A-0.1.0.0/A.cabal
@@ -0,0 +1,11 @@
+cabal-version:      2.4
+name:               A
+version:            0.1.0.0
+author:             Artem Pelenitsyn
+maintainer:         a.pelenitsyn@gmail.com
+
+library
+    exposed-modules:  A
+    build-depends:    base
+    hs-source-dirs:   .
+    default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/NewHaddock/ImplyDependencies/repo/A-0.1.0.0/A.hs b/cabal/cabal-testsuite/PackageTests/NewHaddock/ImplyDependencies/repo/A-0.1.0.0/A.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/NewHaddock/ImplyDependencies/repo/A-0.1.0.0/A.hs
@@ -0,0 +1,4 @@
+module A (a) where
+
+a :: Int
+a = 42
diff --git a/cabal/cabal-testsuite/PackageTests/NewUpdate/UpdateIndexState/update-index-state.out b/cabal/cabal-testsuite/PackageTests/NewUpdate/UpdateIndexState/update-index-state.out
--- a/cabal/cabal-testsuite/PackageTests/NewUpdate/UpdateIndexState/update-index-state.out
+++ b/cabal/cabal-testsuite/PackageTests/NewUpdate/UpdateIndexState/update-index-state.out
@@ -1,10 +1,4 @@
 # cabal update
-Warning: Caught exception during _mirrors lookup:user error (res_query(3) failed)
-Warning: No mirrors found for http://localhost:8000/
-Downloading the latest package list from repository.localhost
-Package list of repository.localhost has been updated.
-The index-state is set to 2022-01-28T02:36:41Z.
-# cabal update
 Downloading the latest package list from repository.localhost
 Package list of repository.localhost is up to date.
 The index-state is set to 2016-09-24T17:47:48Z.
diff --git a/cabal/cabal-testsuite/PackageTests/NewUpdate/UpdateIndexState/update-index-state.test.hs b/cabal/cabal-testsuite/PackageTests/NewUpdate/UpdateIndexState/update-index-state.test.hs
--- a/cabal/cabal-testsuite/PackageTests/NewUpdate/UpdateIndexState/update-index-state.test.hs
+++ b/cabal/cabal-testsuite/PackageTests/NewUpdate/UpdateIndexState/update-index-state.test.hs
@@ -1,9 +1,12 @@
 import Test.Cabal.Prelude
 
 main = cabalTest $ withRemoteRepo "repo" $ do
-  -- This test causes a warning about missing mirrors, the warning is
-  -- included in the expected output to make the test pass but it's not
-  -- part of the test expectations.
-  cabal "update" ["repository.localhost,2022-01-28T02:36:41Z"]
+  -- The _first_ update call causes a warning about missing mirrors, the warning
+  -- is platform-dependent and it's not part of the test expectations, so we
+  -- check the output manually.
+  res <- recordMode DoNotRecord $
+           cabal' "update" ["repository.localhost,2022-01-28T02:36:41Z"]
+  assertOutputContains "The index-state is set to 2022-01-28T02:36:41Z" res
+  assertOutputDoesNotContain "revert" res
   cabal "update" ["repository.localhost,2016-09-24T17:47:48Z"]
   cabal "update" ["repository.localhost,2022-01-28T02:36:41Z"]
diff --git a/cabal/cabal-testsuite/PackageTests/PackageInfoModule/Executable/Main.hs b/cabal/cabal-testsuite/PackageTests/PackageInfoModule/Executable/Main.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/PackageInfoModule/Executable/Main.hs
@@ -0,0 +1,7 @@
+module Main where
+
+import PackageInfo_PackageInfoModule (version)
+
+main :: IO ()
+main = do
+  print version
diff --git a/cabal/cabal-testsuite/PackageTests/PackageInfoModule/Executable/my.cabal b/cabal/cabal-testsuite/PackageTests/PackageInfoModule/Executable/my.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/PackageInfoModule/Executable/my.cabal
@@ -0,0 +1,18 @@
+name: PackageInfoModule
+version: 0.1
+license: BSD3
+author: Gautier DI FOLCO
+stability: stable
+category: PackageTests
+build-type: Simple
+Cabal-version: >= 1.2
+
+description:
+    Check that the generated package info module compiles.
+
+Executable TestPackageInfoModule
+    main-is: Main.hs
+    other-modules:
+        PackageInfo_PackageInfoModule
+        Paths_PackageInfoModule
+    build-depends: base
diff --git a/cabal/cabal-testsuite/PackageTests/PackageInfoModule/Executable/setup.cabal.out b/cabal/cabal-testsuite/PackageTests/PackageInfoModule/Executable/setup.cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/PackageInfoModule/Executable/setup.cabal.out
@@ -0,0 +1,5 @@
+# Setup configure
+Configuring PackageInfoModule-0.1...
+# Setup build
+Preprocessing executable 'TestPackageInfoModule' for PackageInfoModule-0.1..
+Building executable 'TestPackageInfoModule' for PackageInfoModule-0.1..
diff --git a/cabal/cabal-testsuite/PackageTests/PackageInfoModule/Executable/setup.out b/cabal/cabal-testsuite/PackageTests/PackageInfoModule/Executable/setup.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/PackageInfoModule/Executable/setup.out
@@ -0,0 +1,5 @@
+# Setup configure
+Configuring PackageInfoModule-0.1...
+# Setup build
+Preprocessing executable 'TestPackageInfoModule' for PackageInfoModule-0.1..
+Building executable 'TestPackageInfoModule' for PackageInfoModule-0.1..
diff --git a/cabal/cabal-testsuite/PackageTests/PackageInfoModule/Executable/setup.test.hs b/cabal/cabal-testsuite/PackageTests/PackageInfoModule/Executable/setup.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/PackageInfoModule/Executable/setup.test.hs
@@ -0,0 +1,4 @@
+import Test.Cabal.Prelude
+-- Test that Paths module is generated and available for executables.
+main = setupAndCabalTest $ setup_build []
+
diff --git a/cabal/cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/Main.hs b/cabal/cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/Main.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/Main.hs
@@ -0,0 +1,4 @@
+module Main where
+
+main :: IO ()
+main = return ()
diff --git a/cabal/cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/my.cabal b/cabal/cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/my.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/my.cabal
@@ -0,0 +1,19 @@
+name: PackageInfoModule
+version: 0.1
+license: BSD3
+author: Gautier DI FOLCO
+category: PackageTests
+build-type: Simple
+Cabal-version: >= 1.2
+
+description:
+    Check that the generated package info module compiles.
+
+Executable TestPackageInfoModule
+    main-is: Main.hs
+    if impl(ghc >= 8.10.0)
+        ghc-options: -Werror -fwarn-prepositive-qualified-module
+    other-modules:
+        PackageInfo_PackageInfoModule
+        Paths_PackageInfoModule
+    build-depends: base
diff --git a/cabal/cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/setup.cabal.out b/cabal/cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/setup.cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/setup.cabal.out
@@ -0,0 +1,5 @@
+# Setup configure
+Configuring PackageInfoModule-0.1...
+# Setup build
+Preprocessing executable 'TestPackageInfoModule' for PackageInfoModule-0.1..
+Building executable 'TestPackageInfoModule' for PackageInfoModule-0.1..
diff --git a/cabal/cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/setup.out b/cabal/cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/setup.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/setup.out
@@ -0,0 +1,5 @@
+# Setup configure
+Configuring PackageInfoModule-0.1...
+# Setup build
+Preprocessing executable 'TestPackageInfoModule' for PackageInfoModule-0.1..
+Building executable 'TestPackageInfoModule' for PackageInfoModule-0.1..
diff --git a/cabal/cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/setup.test.hs b/cabal/cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/setup.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/setup.test.hs
@@ -0,0 +1,4 @@
+import Test.Cabal.Prelude
+-- Test that Paths module is generated and available for executables.
+main = setupAndCabalTest $ setup_build []
+
diff --git a/cabal/cabal-testsuite/PackageTests/PackageInfoModule/Library/my.cabal b/cabal/cabal-testsuite/PackageTests/PackageInfoModule/Library/my.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/PackageInfoModule/Library/my.cabal
@@ -0,0 +1,36 @@
+Cabal-version: 2.2
+name: PackageInfoModule
+version: 0.1
+license: BSD-3-Clause
+author: Gautier DI FOLCO
+stability: stable
+category: PackageTests
+build-type: Simple
+
+description:
+    Check that the generated package info module compiles.
+
+Library
+    exposed-modules:
+        PackageInfo_PackageInfoModule
+        Paths_PackageInfoModule
+    build-depends: base
+    default-language: Haskell2010
+    default-extensions:
+        -- This is a non-exhaustive list of extensions that can cause code to
+        -- not compile when it would if the extension was disabled. This ensures
+        -- that autogen modules are compatible with default extensions.
+        NoImplicitPrelude
+        CPP
+        TemplateHaskell
+        QuasiQuotes
+        Arrows
+        OverloadedStrings
+    if impl(ghc >= 6.12)
+       default-extensions: MonoLocalBinds
+    if impl(ghc >= 7.0.1)
+       default-extensions: RebindableSyntax
+    if impl(ghc >= 7.4.1)
+       default-extensions: NoTraditionalRecordSyntax
+    if impl(ghc >= 7.8.1)
+       default-extensions: OverloadedLists
diff --git a/cabal/cabal-testsuite/PackageTests/PackageInfoModule/Library/setup.cabal.out b/cabal/cabal-testsuite/PackageTests/PackageInfoModule/Library/setup.cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/PackageInfoModule/Library/setup.cabal.out
@@ -0,0 +1,5 @@
+# Setup configure
+Configuring PackageInfoModule-0.1...
+# Setup build
+Preprocessing library for PackageInfoModule-0.1..
+Building library for PackageInfoModule-0.1..
diff --git a/cabal/cabal-testsuite/PackageTests/PackageInfoModule/Library/setup.out b/cabal/cabal-testsuite/PackageTests/PackageInfoModule/Library/setup.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/PackageInfoModule/Library/setup.out
@@ -0,0 +1,5 @@
+# Setup configure
+Configuring PackageInfoModule-0.1...
+# Setup build
+Preprocessing library for PackageInfoModule-0.1..
+Building library for PackageInfoModule-0.1..
diff --git a/cabal/cabal-testsuite/PackageTests/PackageInfoModule/Library/setup.test.hs b/cabal/cabal-testsuite/PackageTests/PackageInfoModule/Library/setup.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/PackageInfoModule/Library/setup.test.hs
@@ -0,0 +1,3 @@
+import Test.Cabal.Prelude
+-- Test that Paths module is generated and available for libraries.
+main = setupAndCabalTest $ setup_build []
diff --git a/cabal/cabal-testsuite/PackageTests/PathsModule/Executable-Relocatable/Main.hs b/cabal/cabal-testsuite/PackageTests/PathsModule/Executable-Relocatable/Main.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/PathsModule/Executable-Relocatable/Main.hs
@@ -0,0 +1,8 @@
+module Main where
+
+import Paths_PathsModule (getBinDir)
+
+main :: IO ()
+main = do
+    _ <- getBinDir
+    return ()
diff --git a/cabal/cabal-testsuite/PackageTests/PathsModule/Executable-Relocatable/my.cabal b/cabal/cabal-testsuite/PackageTests/PathsModule/Executable-Relocatable/my.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/PathsModule/Executable-Relocatable/my.cabal
@@ -0,0 +1,18 @@
+name: PathsModule
+version: 0.1
+license: BSD3
+author: Johan Tibell
+stability: stable
+category: PackageTests
+build-type: Simple
+Cabal-version: >= 1.2
+
+description:
+    Check that the generated paths module compiles.
+
+Executable TestPathsModule
+    main-is: Main.hs
+    other-modules:
+        PackageInfo_PathsModule
+        Paths_PathsModule
+    build-depends: base
diff --git a/cabal/cabal-testsuite/PackageTests/PathsModule/Executable-Relocatable/setup.cabal.out b/cabal/cabal-testsuite/PackageTests/PathsModule/Executable-Relocatable/setup.cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/PathsModule/Executable-Relocatable/setup.cabal.out
@@ -0,0 +1,5 @@
+# Setup configure
+Configuring PathsModule-0.1...
+# Setup build
+Preprocessing executable 'TestPathsModule' for PathsModule-0.1..
+Building executable 'TestPathsModule' for PathsModule-0.1..
diff --git a/cabal/cabal-testsuite/PackageTests/PathsModule/Executable-Relocatable/setup.out b/cabal/cabal-testsuite/PackageTests/PathsModule/Executable-Relocatable/setup.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/PathsModule/Executable-Relocatable/setup.out
@@ -0,0 +1,5 @@
+# Setup configure
+Configuring PathsModule-0.1...
+# Setup build
+Preprocessing executable 'TestPathsModule' for PathsModule-0.1..
+Building executable 'TestPathsModule' for PathsModule-0.1..
diff --git a/cabal/cabal-testsuite/PackageTests/PathsModule/Executable-Relocatable/setup.test.hs b/cabal/cabal-testsuite/PackageTests/PathsModule/Executable-Relocatable/setup.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/PathsModule/Executable-Relocatable/setup.test.hs
@@ -0,0 +1,7 @@
+import Test.Cabal.Prelude
+-- Test that Paths module is generated and usable when relocatable is turned on.
+
+main = setupAndCabalTest $ do
+  skipIfWindows
+  skipUnlessGhcVersion ">= 8.0"
+  setup_build ["--enable-relocatable"]
diff --git a/cabal/cabal-testsuite/PackageTests/PathsModule/Executable/my.cabal b/cabal/cabal-testsuite/PackageTests/PathsModule/Executable/my.cabal
--- a/cabal/cabal-testsuite/PackageTests/PathsModule/Executable/my.cabal
+++ b/cabal/cabal-testsuite/PackageTests/PathsModule/Executable/my.cabal
@@ -12,5 +12,7 @@
 
 Executable TestPathsModule
     main-is: Main.hs
-    other-modules: Paths_PathsModule
+    other-modules:
+        PackageInfo_PathsModule
+        Paths_PathsModule
     build-depends: base
diff --git a/cabal/cabal-testsuite/PackageTests/PathsModule/ImportQualifiedPost/Main.hs b/cabal/cabal-testsuite/PackageTests/PathsModule/ImportQualifiedPost/Main.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/PathsModule/ImportQualifiedPost/Main.hs
@@ -0,0 +1,4 @@
+module Main where
+
+main :: IO ()
+main = return ()
diff --git a/cabal/cabal-testsuite/PackageTests/PathsModule/ImportQualifiedPost/my.cabal b/cabal/cabal-testsuite/PackageTests/PathsModule/ImportQualifiedPost/my.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/PathsModule/ImportQualifiedPost/my.cabal
@@ -0,0 +1,19 @@
+name: PathsModule
+version: 0.1
+license: BSD3
+author: Martijn Bastiaan
+category: PackageTests
+build-type: Simple
+Cabal-version: >= 1.2
+
+description:
+    Check that the generated paths module compiles.
+
+Executable TestPathsModule
+    main-is: Main.hs
+    if impl(ghc >= 8.10.0)
+        ghc-options: -Werror -fwarn-prepositive-qualified-module
+    other-modules:
+        PackageInfo_PathsModule
+        Paths_PathsModule
+    build-depends: base
diff --git a/cabal/cabal-testsuite/PackageTests/PathsModule/ImportQualifiedPost/setup.cabal.out b/cabal/cabal-testsuite/PackageTests/PathsModule/ImportQualifiedPost/setup.cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/PathsModule/ImportQualifiedPost/setup.cabal.out
@@ -0,0 +1,5 @@
+# Setup configure
+Configuring PathsModule-0.1...
+# Setup build
+Preprocessing executable 'TestPathsModule' for PathsModule-0.1..
+Building executable 'TestPathsModule' for PathsModule-0.1..
diff --git a/cabal/cabal-testsuite/PackageTests/PathsModule/ImportQualifiedPost/setup.out b/cabal/cabal-testsuite/PackageTests/PathsModule/ImportQualifiedPost/setup.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/PathsModule/ImportQualifiedPost/setup.out
@@ -0,0 +1,5 @@
+# Setup configure
+Configuring PathsModule-0.1...
+# Setup build
+Preprocessing executable 'TestPathsModule' for PathsModule-0.1..
+Building executable 'TestPathsModule' for PathsModule-0.1..
diff --git a/cabal/cabal-testsuite/PackageTests/PathsModule/ImportQualifiedPost/setup.test.hs b/cabal/cabal-testsuite/PackageTests/PathsModule/ImportQualifiedPost/setup.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/PathsModule/ImportQualifiedPost/setup.test.hs
@@ -0,0 +1,4 @@
+import Test.Cabal.Prelude
+-- Test that Paths module is generated and available for executables.
+main = setupAndCabalTest $ setup_build []
+
diff --git a/cabal/cabal-testsuite/PackageTests/PathsModule/Library/my.cabal b/cabal/cabal-testsuite/PackageTests/PathsModule/Library/my.cabal
--- a/cabal/cabal-testsuite/PackageTests/PathsModule/Library/my.cabal
+++ b/cabal/cabal-testsuite/PackageTests/PathsModule/Library/my.cabal
@@ -11,7 +11,9 @@
     Check that the generated paths module compiles.
 
 Library
-    exposed-modules: Paths_PathsModule
+    exposed-modules:
+        PackageInfo_PathsModule
+        Paths_PathsModule
     build-depends: base
     default-language: Haskell2010
     default-extensions:
diff --git a/cabal/cabal-testsuite/PackageTests/PathsModule/MissingSafeHaskellMode/my.cabal b/cabal/cabal-testsuite/PackageTests/PathsModule/MissingSafeHaskellMode/my.cabal
--- a/cabal/cabal-testsuite/PackageTests/PathsModule/MissingSafeHaskellMode/my.cabal
+++ b/cabal/cabal-testsuite/PackageTests/PathsModule/MissingSafeHaskellMode/my.cabal
@@ -11,7 +11,9 @@
     Check that the generated paths module compiles.
 
 Library
-    exposed-modules: Paths_PathsModule
+    exposed-modules:
+        PackageInfo_PathsModule
+        Paths_PathsModule
     build-depends: base
     default-language: Haskell2010
 
diff --git a/cabal/cabal-testsuite/PackageTests/PkgConfigParse/MyLibrary.hs b/cabal/cabal-testsuite/PackageTests/PkgConfigParse/MyLibrary.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/PkgConfigParse/MyLibrary.hs
@@ -0,0 +1,1 @@
+module MyLibrary () where
diff --git a/cabal/cabal-testsuite/PackageTests/PkgConfigParse/cabal.project b/cabal/cabal-testsuite/PackageTests/PkgConfigParse/cabal.project
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/PkgConfigParse/cabal.project
@@ -0,0 +1,1 @@
+packages: *.cabal
diff --git a/cabal/cabal-testsuite/PackageTests/PkgConfigParse/my.cabal b/cabal/cabal-testsuite/PackageTests/PkgConfigParse/my.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/PkgConfigParse/my.cabal
@@ -0,0 +1,19 @@
+name: PkgConfigParse
+version: 0.1
+license: BSD3
+author: Tom Smeding
+maintainer: Tom Smeding
+synopsis: Pkg Config Parse
+category: PackageTests
+build-type: Simple
+cabal-version: 2.0
+
+description:
+    Check that Cabal does not crash when pkg-config outputs invalid Unicode.
+
+Library
+    pkgconfig-depends: vpl
+    default-language: Haskell2010
+    build-depends: base <5.0
+    exposed-modules:
+        MyLibrary
diff --git a/cabal/cabal-testsuite/PackageTests/PkgConfigParse/pkg-config b/cabal/cabal-testsuite/PackageTests/PkgConfigParse/pkg-config
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/PkgConfigParse/pkg-config
@@ -0,0 +1,49 @@
+#!/bin/sh
+
+set -eu
+
+# ugly, but "good enough" for this test
+# This will need to be updated whenever cabal invokes pkg-config
+# in new ways
+case "$*" in
+  '--version')
+    echo 2.1.0  # whatever
+    ;;
+
+  '--variable pc_path pkg-config')
+    echo '.'
+    ;;
+
+  '--list-all')
+    printf 'zlib   zlib - zlib compression library\n'
+    # \256 = \xAE is the iso-8859-1 (latin-1) encoded version of U+00AE,
+    # i.e. the "registered sign": ®
+    # This resulted in problems, see #9608
+    printf 'vpl    Intel\256 Video Processing Library - Accelerated video decode, encode, and frame processing capabilities on Intel\256 GPUs\n'
+    # \360 = \xF0 is latin-1 for ð; this is orð, Icelandic for "word"/"words".
+    printf 'or\360   Icelandic characters\n'
+    ;;
+
+  '--modversion '*)
+    shift  # drop the --modversion
+    for arg; do
+      case "$arg" in
+        zlib) echo 1.3; ;;  # whatever
+        vpl) echo 2.10; ;;  # whatever
+        # No entry for orð here; let's not even try to match on that
+        *)
+          echo >&2 "Package $arg was not found in the pkg-config search path."
+          exit 1
+      esac
+    done
+    ;;
+
+  # Ignore some stuff we're not implementing
+  '--cflags '*) ;;
+  '--libs '*) ;;
+
+  *)
+    echo >&2 "pkg-config: unrecognised arguments $* (this is an incomplete shim)"
+    exit 1
+    ;;
+esac
diff --git a/cabal/cabal-testsuite/PackageTests/PkgConfigParse/setup.out b/cabal/cabal-testsuite/PackageTests/PkgConfigParse/setup.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/PkgConfigParse/setup.out
@@ -0,0 +1,1 @@
+# cabal v2-build
diff --git a/cabal/cabal-testsuite/PackageTests/PkgConfigParse/setup.test.hs b/cabal/cabal-testsuite/PackageTests/PkgConfigParse/setup.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/PkgConfigParse/setup.test.hs
@@ -0,0 +1,9 @@
+import Test.Cabal.Prelude
+
+-- Test that invalid unicode in pkg-config output doesn't trip up cabal very much
+main = cabalTest $ do
+  -- skipped on windows because using a script to dummy up an executable doesn't work the same.
+  skipIfWindows
+  cdir <- testCurrentDir `fmap` getTestEnv
+  res <- cabal' "v2-build" ["--extra-prog-path="++cdir, "-v2"]
+  assertOutputContains "Some pkg-config packages have names containing invalid unicode: or" res
diff --git a/cabal/cabal-testsuite/PackageTests/ProfLate/Exe.hs b/cabal/cabal-testsuite/PackageTests/ProfLate/Exe.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/ProfLate/Exe.hs
@@ -0,0 +1,6 @@
+module Main where
+
+{-# NOINLINE foo #-}
+foo = putStrLn "Hello World!"
+
+main = foo
diff --git a/cabal/cabal-testsuite/PackageTests/ProfLate/cabal.out b/cabal/cabal-testsuite/PackageTests/ProfLate/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/ProfLate/cabal.out
@@ -0,0 +1,2 @@
+# cabal clean
+# cabal build
diff --git a/cabal/cabal-testsuite/PackageTests/ProfLate/cabal.project b/cabal/cabal-testsuite/PackageTests/ProfLate/cabal.project
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/ProfLate/cabal.project
@@ -0,0 +1,1 @@
+packages: .
diff --git a/cabal/cabal-testsuite/PackageTests/ProfLate/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/ProfLate/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/ProfLate/cabal.test.hs
@@ -0,0 +1,9 @@
+import Test.Cabal.Prelude
+-- Test building with profiling detail "late"
+main = do
+    cabalTest $ do
+        skipUnlessGhcVersion ">= 9.4"
+        cabal' "clean" []
+        res <- cabal' "build" ["-v2", "profLate", "--enable-profiling", "--profiling-detail=late"]
+        assertOutputContains "-fprof-late" res
+
diff --git a/cabal/cabal-testsuite/PackageTests/ProfLate/profLate.cabal b/cabal/cabal-testsuite/PackageTests/ProfLate/profLate.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/ProfLate/profLate.cabal
@@ -0,0 +1,8 @@
+Cabal-Version: 3.8
+Name: profLate
+Version: 0.1
+Build-Type: Simple
+
+Executable main
+    Main-is: Exe.hs
+    Build-Depends: base
diff --git a/cabal/cabal-testsuite/PackageTests/ProfLate/setup.cabal.out b/cabal/cabal-testsuite/PackageTests/ProfLate/setup.cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/ProfLate/setup.cabal.out
@@ -0,0 +1,5 @@
+# Setup configure
+Configuring profLate-0.1...
+# Setup build
+Preprocessing executable 'main' for profLate-0.1..
+Building executable 'main' for profLate-0.1..
diff --git a/cabal/cabal-testsuite/PackageTests/ProfLate/setup.out b/cabal/cabal-testsuite/PackageTests/ProfLate/setup.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/ProfLate/setup.out
@@ -0,0 +1,5 @@
+# Setup configure
+Configuring profLate-0.1...
+# Setup build
+Preprocessing executable 'main' for profLate-0.1..
+Building executable 'main' for profLate-0.1..
diff --git a/cabal/cabal-testsuite/PackageTests/ProfLate/setup.test.hs b/cabal/cabal-testsuite/PackageTests/ProfLate/setup.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/ProfLate/setup.test.hs
@@ -0,0 +1,8 @@
+import Test.Cabal.Prelude
+-- Test building with profiling detail "late"
+main = do
+    setupAndCabalTest $ do
+        skipUnless "no profiling libs" =<< hasProfiledLibraries
+        setup_build ["--enable-profiling", "--profiling-detail=late"]
+        --  ["--enable-profiling", "--profiling-detail=late-toplevel"]
+
diff --git a/cabal/cabal-testsuite/PackageTests/Regression/T5213/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Regression/T5213/cabal.test.hs
--- a/cabal/cabal-testsuite/PackageTests/Regression/T5213/cabal.test.hs
+++ b/cabal/cabal-testsuite/PackageTests/Regression/T5213/cabal.test.hs
diff --git a/cabal/cabal-testsuite/PackageTests/Regression/T5213ExeCoverage/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Regression/T5213ExeCoverage/cabal.test.hs
--- a/cabal/cabal-testsuite/PackageTests/Regression/T5213ExeCoverage/cabal.test.hs
+++ b/cabal/cabal-testsuite/PackageTests/Regression/T5213ExeCoverage/cabal.test.hs
diff --git a/cabal/cabal-testsuite/PackageTests/Regression/T5309/T5309.cabal b/cabal/cabal-testsuite/PackageTests/Regression/T5309/T5309.cabal
--- a/cabal/cabal-testsuite/PackageTests/Regression/T5309/T5309.cabal
+++ b/cabal/cabal-testsuite/PackageTests/Regression/T5309/T5309.cabal
@@ -8,7 +8,7 @@
 author:             Alex Washburn
 maintainer:         github@recursion.ninja
 copyright:          2018 Alex Washburn (recursion.ninja)
-                    
+
 synopsis:           A binding to a C++ hashtable for thread-safe memoization.
 
 description:        This package is designed to provide a "minimal working example"
@@ -23,7 +23,7 @@
                     memoized-tcm/dynamicCharacterOperations.c
 
   cc-options:       --std=c11
-                     
+
   cxx-sources:      memoized-tcm/costMatrix.cpp
 
   cxx-options:      --std=c++11
@@ -46,12 +46,12 @@
 
   build-depends:    base       >=4.5.1
 --                  , lens
-       
+
   default-language: Haskell2010
 
   ghc-options:      -O2 -Wall
 
-                    
+
 common lib-build-info
 
   hs-source-dirs:   lib
@@ -61,7 +61,7 @@
                     Data.TCM.Memoized
                     Data.TCM.Memoized.FFI
 
-                    
+
 library
 
   import:           ffi-build-info
@@ -73,8 +73,8 @@
                     Data.TCM.Memoized.FFI
 
   hs-source-dirs:   lib
-                    
 
+
 executable exe-no-lib
 
   import:           ffi-build-info
@@ -106,10 +106,10 @@
   main-is:          Main.hs
 
   type:             exitcode-stdio-1.0
-                     
+
   hs-source-dirs:   app
 
- 
+
 benchmark bench-with-lib
 
   import:           language-spec
@@ -122,7 +122,7 @@
 
   hs-source-dirs:   app
 
- 
+
 test-suite test-no-lib
 
   import:           ffi-build-info
@@ -132,7 +132,7 @@
   main-is:          Main.hs
 
   type:             exitcode-stdio-1.0
-                     
+
   hs-source-dirs:   app
 
 
@@ -143,7 +143,7 @@
   main-is:          Main.hs
 
   type:             exitcode-stdio-1.0
-  
+
   build-depends:    T5309
-                     
+
   hs-source-dirs:   app
diff --git a/cabal/cabal-testsuite/PackageTests/Regression/T5309/lib/Bio/Character/Exportable/Class.hs b/cabal/cabal-testsuite/PackageTests/Regression/T5309/lib/Bio/Character/Exportable/Class.hs
--- a/cabal/cabal-testsuite/PackageTests/Regression/T5309/lib/Bio/Character/Exportable/Class.hs
+++ b/cabal/cabal-testsuite/PackageTests/Regression/T5309/lib/Bio/Character/Exportable/Class.hs
@@ -18,7 +18,7 @@
 module Bio.Character.Exportable.Class where
 
 
-import Foreign.C.Types 
+import Foreign.C.Types
 
 
 -- |
@@ -42,7 +42,7 @@
    { exportedElementCountSequence :: Int
    , exportedElementWidthSequence :: Int
    , exportedBufferChunks :: [CULong]
-   } deriving (Eq, Show)   
+   } deriving (Eq, Show)
 
 
 -- |
@@ -51,6 +51,6 @@
 data ExportableCharacterElements
    = ExportableCharacterElements
    { exportedElementCountElements :: Int
-   , exportedElementWidthElements :: Int 
+   , exportedElementWidthElements :: Int
    , exportedCharacterElements :: [CUInt]
-   } deriving (Eq, Show)   
+   } deriving (Eq, Show)
diff --git a/cabal/cabal-testsuite/PackageTests/Regression/T5782Diamond/issue5782/Main.hs b/cabal/cabal-testsuite/PackageTests/Regression/T5782Diamond/issue5782/Main.hs
--- a/cabal/cabal-testsuite/PackageTests/Regression/T5782Diamond/issue5782/Main.hs
+++ b/cabal/cabal-testsuite/PackageTests/Regression/T5782Diamond/issue5782/Main.hs
diff --git a/cabal/cabal-testsuite/PackageTests/Regression/T8507/Foo.hs b/cabal/cabal-testsuite/PackageTests/Regression/T8507/Foo.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Regression/T8507/Foo.hs
@@ -0,0 +1,4 @@
+module Foo where
+
+foo :: a
+foo = undefined
diff --git a/cabal/cabal-testsuite/PackageTests/Regression/T8507/cabal.out b/cabal/cabal-testsuite/PackageTests/Regression/T8507/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Regression/T8507/cabal.out
@@ -0,0 +1,8 @@
+# cabal v2-build
+Resolving dependencies...
+Build profile: -w ghc-<GHCVER> -O1
+In order, the following will be built:
+ - pkg-0 (lib) (first run)
+Configuring library for pkg-0..
+Preprocessing library for pkg-0..
+Building library for pkg-0..
diff --git a/cabal/cabal-testsuite/PackageTests/Regression/T8507/cabal.project b/cabal/cabal-testsuite/PackageTests/Regression/T8507/cabal.project
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Regression/T8507/cabal.project
@@ -0,0 +1,2 @@
+packages:
+  ./
diff --git a/cabal/cabal-testsuite/PackageTests/Regression/T8507/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Regression/T8507/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Regression/T8507/cabal.test.hs
@@ -0,0 +1,6 @@
+import Test.Cabal.Prelude
+
+-- Issue #8507: trailing space in `default-language` should not make
+-- `cabal build` complain.
+main = cabalTest $ cabal "v2-build" ["all"]
+
diff --git a/cabal/cabal-testsuite/PackageTests/Regression/T8507/pkg.cabal b/cabal/cabal-testsuite/PackageTests/Regression/T8507/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Regression/T8507/pkg.cabal
@@ -0,0 +1,14 @@
+cabal-version: 3.0
+name: pkg
+synopsis: synopsis
+description: description
+version: 0
+category: example
+maintainer: none@example.com
+license: GPL-3.0-or-later
+
+library
+  exposed-modules: Foo,
+  build-depends: base == 4.*
+  default-language: Haskell2010    
+    -- Note whitespace after “Haskell 2010”.
diff --git a/cabal/cabal-testsuite/PackageTests/Regression/T9122/p/p.cabal b/cabal/cabal-testsuite/PackageTests/Regression/T9122/p/p.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Regression/T9122/p/p.cabal
@@ -0,0 +1,6 @@
+cabal-version:      3.4
+name:               p
+Version:            2
+Build-Type:         Simple
+
+library
diff --git a/cabal/cabal-testsuite/PackageTests/Regression/T9122/q/q.cabal b/cabal/cabal-testsuite/PackageTests/Regression/T9122/q/q.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Regression/T9122/q/q.cabal
@@ -0,0 +1,10 @@
+cabal-version:      3.4
+name:               q
+Version:            1
+Build-Type:         Simple
+
+library
+  build-depends:        q:p
+
+library p
+  build-depends:        p:p == 2
diff --git a/cabal/cabal-testsuite/PackageTests/Regression/T9122/setup.cabal.out b/cabal/cabal-testsuite/PackageTests/Regression/T9122/setup.cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Regression/T9122/setup.cabal.out
@@ -0,0 +1,11 @@
+# Setup configure
+Configuring p-2...
+# Setup build
+Preprocessing library for p-2..
+Building library for p-2..
+# Setup copy
+Installing library in <PATH>
+# Setup register
+Registering library for p-2..
+# Setup configure
+Configuring q-1...
diff --git a/cabal/cabal-testsuite/PackageTests/Regression/T9122/setup.out b/cabal/cabal-testsuite/PackageTests/Regression/T9122/setup.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Regression/T9122/setup.out
@@ -0,0 +1,11 @@
+# Setup configure
+Configuring p-2...
+# Setup build
+Preprocessing library for p-2..
+Building library for p-2..
+# Setup copy
+Installing library in <PATH>
+# Setup register
+Registering library for p-2..
+# Setup configure
+Configuring q-1...
diff --git a/cabal/cabal-testsuite/PackageTests/Regression/T9122/setup.test.hs b/cabal/cabal-testsuite/PackageTests/Regression/T9122/setup.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Regression/T9122/setup.test.hs
@@ -0,0 +1,5 @@
+import Test.Cabal.Prelude
+
+main = setupAndCabalTest $ withPackageDb $ do
+  withDirectory "p" $ setup_install []
+  withDirectory "q" $ setup "configure" []
diff --git a/cabal/cabal-testsuite/PackageTests/Regression/T9756/OK.hs b/cabal/cabal-testsuite/PackageTests/Regression/T9756/OK.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Regression/T9756/OK.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE TemplateHaskell #-}
+module OK where
+
+import Data.List
+import System.Process
+import Language.Haskell.TH
+
+$(do
+    out <- runIO $ readProcess "mybuilder" [] ""
+    if "0.2.0.0" `isInfixOf` out then
+       [d| x = () |]
+    else
+      error ("Expecting Version 0.2.0.0, but got: " ++ out)
+ )
diff --git a/cabal/cabal-testsuite/PackageTests/Regression/T9756/cabal-bug-build-tool.cabal b/cabal/cabal-testsuite/PackageTests/Regression/T9756/cabal-bug-build-tool.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Regression/T9756/cabal-bug-build-tool.cabal
@@ -0,0 +1,10 @@
+cabal-version:  1.12
+name:           cabal-bug-build-tool
+version:        0
+build-type:     Simple
+
+library
+  exposed-modules:  OK
+  default-language: Haskell2010
+  build-depends:    base, template-haskell, process
+  build-tool-depends: mybuilder:mybuilder >=0.2.0.0
diff --git a/cabal/cabal-testsuite/PackageTests/Regression/T9756/cabal.out b/cabal/cabal-testsuite/PackageTests/Regression/T9756/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Regression/T9756/cabal.out
@@ -0,0 +1,27 @@
+# cabal v2-update
+Downloading the latest package list from test-local-repo
+# cabal v2-install
+Resolving dependencies...
+Build profile: -w ghc-<GHCVER> -O1
+In order, the following will be built:
+ - mybuilder-0.1.0.0 (exe:mybuilder) (requires build)
+Configuring executable 'mybuilder' for mybuilder-0.1.0.0..
+Preprocessing executable 'mybuilder' for mybuilder-0.1.0.0..
+Building executable 'mybuilder' for mybuilder-0.1.0.0..
+Installing executable mybuilder in <PATH>
+Warning: The directory <ROOT>/cabal.dist/home/.cabal/store/ghc-<GHCVER>/incoming/new-<RAND><ROOT>/cabal.dist/home/.cabal/store/ghc-<GHCVER>/<PACKAGE>-<HASH>/bin is not in the system search path.
+Symlinking 'mybuilder' to '<ROOT>/cabal.dist/install/mybuilder'
+# cabal v2-build
+Resolving dependencies...
+Build profile: -w ghc-<GHCVER> -O1
+In order, the following will be built:
+ - mybuilder-0.2.0.0 (exe:mybuilder) (requires build)
+ - cabal-bug-build-tool-0 (lib) (first run)
+Configuring executable 'mybuilder' for mybuilder-0.2.0.0..
+Preprocessing executable 'mybuilder' for mybuilder-0.2.0.0..
+Building executable 'mybuilder' for mybuilder-0.2.0.0..
+Installing executable mybuilder in <PATH>
+Warning: The directory <ROOT>/cabal.dist/home/.cabal/store/ghc-<GHCVER>/incoming/new-<RAND><ROOT>/cabal.dist/home/.cabal/store/ghc-<GHCVER>/<PACKAGE>-<HASH>/bin is not in the system search path.
+Configuring library for cabal-bug-build-tool-0..
+Preprocessing library for cabal-bug-build-tool-0..
+Building library for cabal-bug-build-tool-0..
diff --git a/cabal/cabal-testsuite/PackageTests/Regression/T9756/cabal.project b/cabal/cabal-testsuite/PackageTests/Regression/T9756/cabal.project
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Regression/T9756/cabal.project
@@ -0,0 +1,1 @@
+packages: .
diff --git a/cabal/cabal-testsuite/PackageTests/Regression/T9756/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/Regression/T9756/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Regression/T9756/cabal.test.hs
@@ -0,0 +1,13 @@
+import Test.Cabal.Prelude
+
+-- We are testing if the build-tools program is found in path before programs e.g. in extra-prog-path or the system path
+-- For that, we need
+--  * A repo with a build tool that is up to date
+--  * An older version of the build tool in the extra-prog-path
+--  * A project that requires the more up-to-date version of the build-tool
+
+main = cabalTest $ withRepo "repo" $ do
+  dir <- testWorkDir <$> getTestEnv
+  cabal "v2-install" ["mybuilder-0.1.0.0", "--installdir=" ++ dir ++ "/install", "--overwrite-policy=always"]
+  cabal "v2-build" ["cabal-bug-build-tool", "--extra-prog-path=" ++ dir ++ "/install"]
+
diff --git a/cabal/cabal-testsuite/PackageTests/Regression/T9756/repo/mybuilder-0.1.0.0/CHANGELOG.md b/cabal/cabal-testsuite/PackageTests/Regression/T9756/repo/mybuilder-0.1.0.0/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Regression/T9756/repo/mybuilder-0.1.0.0/CHANGELOG.md
@@ -0,0 +1,5 @@
+# Revision history for mybuilder0100
+
+## 0.1.0.0 -- YYYY-mm-dd
+
+* First version. Released on an unsuspecting world.
diff --git a/cabal/cabal-testsuite/PackageTests/Regression/T9756/repo/mybuilder-0.1.0.0/app/Main.hs b/cabal/cabal-testsuite/PackageTests/Regression/T9756/repo/mybuilder-0.1.0.0/app/Main.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Regression/T9756/repo/mybuilder-0.1.0.0/app/Main.hs
@@ -0,0 +1,4 @@
+module Main where
+
+main :: IO ()
+main = putStrLn "0.1.0.0"
diff --git a/cabal/cabal-testsuite/PackageTests/Regression/T9756/repo/mybuilder-0.1.0.0/mybuilder.cabal b/cabal/cabal-testsuite/PackageTests/Regression/T9756/repo/mybuilder-0.1.0.0/mybuilder.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Regression/T9756/repo/mybuilder-0.1.0.0/mybuilder.cabal
@@ -0,0 +1,18 @@
+cabal-version:   3.0
+name:            mybuilder
+version:         0.1.0.0
+license:         NONE
+author:          Rodrigo Mesquita
+maintainer:      rodrigo.m.mesquita@gmail.com
+build-type:      Simple
+extra-doc-files: CHANGELOG.md
+
+common warnings
+    ghc-options: -Wall
+
+executable mybuilder
+    import:           warnings
+    main-is:          Main.hs
+    build-depends:    base
+    hs-source-dirs:   app
+    default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/Regression/T9756/repo/mybuilder-0.2.0.0/CHANGELOG.md b/cabal/cabal-testsuite/PackageTests/Regression/T9756/repo/mybuilder-0.2.0.0/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Regression/T9756/repo/mybuilder-0.2.0.0/CHANGELOG.md
@@ -0,0 +1,5 @@
+# Revision history for mybuilder0100
+
+## 0.1.0.0 -- YYYY-mm-dd
+
+* First version. Released on an unsuspecting world.
diff --git a/cabal/cabal-testsuite/PackageTests/Regression/T9756/repo/mybuilder-0.2.0.0/app/Main.hs b/cabal/cabal-testsuite/PackageTests/Regression/T9756/repo/mybuilder-0.2.0.0/app/Main.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Regression/T9756/repo/mybuilder-0.2.0.0/app/Main.hs
@@ -0,0 +1,4 @@
+module Main where
+
+main :: IO ()
+main = putStrLn "0.2.0.0"
diff --git a/cabal/cabal-testsuite/PackageTests/Regression/T9756/repo/mybuilder-0.2.0.0/mybuilder.cabal b/cabal/cabal-testsuite/PackageTests/Regression/T9756/repo/mybuilder-0.2.0.0/mybuilder.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/Regression/T9756/repo/mybuilder-0.2.0.0/mybuilder.cabal
@@ -0,0 +1,18 @@
+cabal-version:   3.0
+name:            mybuilder
+version:         0.2.0.0
+license:         NONE
+author:          Rodrigo Mesquita
+maintainer:      rodrigo.m.mesquita@gmail.com
+build-type:      Simple
+extra-doc-files: CHANGELOG.md
+
+common warnings
+    ghc-options: -Wall
+
+executable mybuilder
+    import:           warnings
+    main-is:          Main.hs
+    build-depends:    base
+    hs-source-dirs:   app
+    default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/RelativePathProjectImports/Lib.hs b/cabal/cabal-testsuite/PackageTests/RelativePathProjectImports/Lib.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/RelativePathProjectImports/Lib.hs
@@ -0,0 +1,7 @@
+module Lib (foo) where
+
+import Dep (bar)
+import Dep2 (baz)
+
+foo :: Int
+foo = bar + baz
diff --git a/cabal/cabal-testsuite/PackageTests/RelativePathProjectImports/cabal.out b/cabal/cabal-testsuite/PackageTests/RelativePathProjectImports/cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/RelativePathProjectImports/cabal.out
@@ -0,0 +1,24 @@
+# cabal build
+Resolving dependencies...
+Build profile: -w ghc-<GHCVER> -O1
+In order, the following will be built:
+ - dep-0.1 (lib) (first run)
+ - dep2-0.1 (lib) (first run)
+ - main-0.1 (lib) (first run)
+Configuring library for dep-0.1..
+Preprocessing library for dep-0.1..
+Building library for dep-0.1..
+Configuring library for dep2-0.1..
+Preprocessing library for dep2-0.1..
+Building library for dep2-0.1..
+Configuring library for main-0.1..
+Preprocessing library for main-0.1..
+Building library for main-0.1..
+# cabal build
+Resolving dependencies...
+Build profile: -w ghc-<GHCVER> -O1
+In order, the following will be built:
+ - dep2-0.1 (lib) (first run)
+Configuring library for dep2-0.1..
+Preprocessing library for dep2-0.1..
+Building library for dep2-0.1..
diff --git a/cabal/cabal-testsuite/PackageTests/RelativePathProjectImports/cabal.project b/cabal/cabal-testsuite/PackageTests/RelativePathProjectImports/cabal.project
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/RelativePathProjectImports/cabal.project
@@ -0,0 +1,6 @@
+import: ./dep/cabal.project
+
+packages:
+  main.cabal
+  dep/dep.cabal
+  dep2/dep2.cabal
diff --git a/cabal/cabal-testsuite/PackageTests/RelativePathProjectImports/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/RelativePathProjectImports/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/RelativePathProjectImports/cabal.test.hs
@@ -0,0 +1,8 @@
+import Test.Cabal.Prelude
+
+main = cabalTest $ do
+  -- Build from toplevel.
+  cabal "build" []
+  withDirectory "dep2" $ do
+    -- Build from one of the subdirectories that uses toplevel cabal.project.
+    cabal "build" []
diff --git a/cabal/cabal-testsuite/PackageTests/RelativePathProjectImports/dep/Dep.hs b/cabal/cabal-testsuite/PackageTests/RelativePathProjectImports/dep/Dep.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/RelativePathProjectImports/dep/Dep.hs
@@ -0,0 +1,4 @@
+module Dep (bar) where
+
+bar :: Int
+bar = 1
diff --git a/cabal/cabal-testsuite/PackageTests/RelativePathProjectImports/dep/cabal.project b/cabal/cabal-testsuite/PackageTests/RelativePathProjectImports/dep/cabal.project
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/RelativePathProjectImports/dep/cabal.project
@@ -0,0 +1,2 @@
+package dep
+  ghc-options: -O2
diff --git a/cabal/cabal-testsuite/PackageTests/RelativePathProjectImports/dep/dep.cabal b/cabal/cabal-testsuite/PackageTests/RelativePathProjectImports/dep/dep.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/RelativePathProjectImports/dep/dep.cabal
@@ -0,0 +1,15 @@
+cabal-version: 3.0
+
+name: dep
+version: 0.1
+build-type: Simple
+category: Test
+maintainer: Joe
+synopsis: Test input
+description: Test input
+license: BSD-3-Clause
+
+library
+  exposed-modules: Dep
+  build-depends: base > 4
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/RelativePathProjectImports/dep2/Dep2.hs b/cabal/cabal-testsuite/PackageTests/RelativePathProjectImports/dep2/Dep2.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/RelativePathProjectImports/dep2/Dep2.hs
@@ -0,0 +1,4 @@
+module Dep2 (baz) where
+
+baz :: Int
+baz = 2
diff --git a/cabal/cabal-testsuite/PackageTests/RelativePathProjectImports/dep2/dep2.cabal b/cabal/cabal-testsuite/PackageTests/RelativePathProjectImports/dep2/dep2.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/RelativePathProjectImports/dep2/dep2.cabal
@@ -0,0 +1,15 @@
+cabal-version: 3.0
+
+name: dep2
+version: 0.1
+build-type: Simple
+category: Test
+maintainer: Joe
+synopsis: Test input
+description: Test input
+license: BSD-3-Clause
+
+library
+  exposed-modules: Dep2
+  build-depends: base > 4
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/RelativePathProjectImports/main.cabal b/cabal/cabal-testsuite/PackageTests/RelativePathProjectImports/main.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/RelativePathProjectImports/main.cabal
@@ -0,0 +1,15 @@
+cabal-version: 3.0
+
+name: main
+version: 0.1
+build-type: Simple
+category: Test
+maintainer: Joe
+synopsis: Test input
+description: Test input
+license: BSD-3-Clause
+
+library
+  exposed-modules: Lib
+  build-depends: base > 4, dep >= 0.1, dep2
+  default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/ReplBuildDepends/Foo.hs b/cabal/cabal-testsuite/PackageTests/ReplBuildDepends/Foo.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/ReplBuildDepends/Foo.hs
@@ -0,0 +1,4 @@
+module Foo where
+
+a :: Int
+a = 42
diff --git a/cabal/cabal-testsuite/PackageTests/ReplBuildDepends/cabal.allow-newer.out b/cabal/cabal-testsuite/PackageTests/ReplBuildDepends/cabal.allow-newer.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/ReplBuildDepends/cabal.allow-newer.out
@@ -0,0 +1,2 @@
+# cabal clean
+# cabal repl
diff --git a/cabal/cabal-testsuite/PackageTests/ReplBuildDepends/cabal.allow-older.out b/cabal/cabal-testsuite/PackageTests/ReplBuildDepends/cabal.allow-older.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/ReplBuildDepends/cabal.allow-older.out
@@ -0,0 +1,2 @@
+# cabal clean
+# cabal repl
diff --git a/cabal/cabal-testsuite/PackageTests/ReplBuildDepends/cabal.normal.out b/cabal/cabal-testsuite/PackageTests/ReplBuildDepends/cabal.normal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/ReplBuildDepends/cabal.normal.out
@@ -0,0 +1,2 @@
+# cabal clean
+# cabal repl
diff --git a/cabal/cabal-testsuite/PackageTests/ReplBuildDepends/cabal.project b/cabal/cabal-testsuite/PackageTests/ReplBuildDepends/cabal.project
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/ReplBuildDepends/cabal.project
@@ -0,0 +1,1 @@
+packages: .
diff --git a/cabal/cabal-testsuite/PackageTests/ReplBuildDepends/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/ReplBuildDepends/cabal.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/ReplBuildDepends/cabal.test.hs
@@ -0,0 +1,19 @@
+import Test.Cabal.Prelude
+
+-- Test “repl --build-depends”
+main = do
+  testWithByteString "normal" []
+  -- See https://github.com/haskell/cabal/issues/6859
+  testWithByteString "allow-newer" ["--allow-newer"]
+  -- See https://github.com/haskell/cabal/issues/6859
+  testWithByteString "allow-older" ["--allow-older"]
+  where
+  testWithByteString label extraArgs = cabalTest' label $ do
+    cabal' "clean" []
+    res <- cabalWithStdin
+        "repl"
+        ("-v2" : "--build-depends" : "bytestring" : extraArgs)
+        "import qualified Data.ByteString as BS"
+    assertOutputContains "Ok, one module loaded." res
+    -- Ensure we can load ‘bytestring’
+    assertOutputDoesNotContain "Could not load" res
diff --git a/cabal/cabal-testsuite/PackageTests/ReplBuildDepends/pkg.cabal b/cabal/cabal-testsuite/PackageTests/ReplBuildDepends/pkg.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/ReplBuildDepends/pkg.cabal
@@ -0,0 +1,7 @@
+cabal-version:      2.4
+name:               pkg
+version:            0.1.0.0
+library
+    exposed-modules:  Foo
+    build-depends:    base
+    default-language: Haskell2010
diff --git a/cabal/cabal-testsuite/PackageTests/RtsOptsClean/LICENSE b/cabal/cabal-testsuite/PackageTests/RtsOptsClean/LICENSE
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/RtsOptsClean/LICENSE
@@ -0,0 +1,1 @@
+LICENSE
diff --git a/cabal/cabal-testsuite/PackageTests/RtsOptsClean/Main.hs b/cabal/cabal-testsuite/PackageTests/RtsOptsClean/Main.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/RtsOptsClean/Main.hs
@@ -0,0 +1,4 @@
+module Main where
+
+main :: IO ()
+main = undefined
diff --git a/cabal/cabal-testsuite/PackageTests/RtsOptsClean/my.cabal b/cabal/cabal-testsuite/PackageTests/RtsOptsClean/my.cabal
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/RtsOptsClean/my.cabal
@@ -0,0 +1,19 @@
+name: RtsOptsClean
+version: 0.1
+author: Artem Pelenitsyn
+synopsis: Make sure -with-rtsopts do not produce spurious warnings (fix #4255)
+category: PackageTests
+build-type: Simple
+cabal-version: 2.0
+
+description:
+    Make sure -with-rtsopts do not produce spurious warnings
+
+Executable RtsOptsClean
+    default-language: Haskell2010
+    build-depends: base <5.0
+    main-is:
+        Main.hs
+    ghc-options:
+      -rtsopts
+      -with-rtsopts "-I0"
diff --git a/cabal/cabal-testsuite/PackageTests/RtsOptsClean/setup.cabal.out b/cabal/cabal-testsuite/PackageTests/RtsOptsClean/setup.cabal.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/RtsOptsClean/setup.cabal.out
@@ -0,0 +1,2 @@
+# Setup configure
+Configuring RtsOptsClean-0.1...
diff --git a/cabal/cabal-testsuite/PackageTests/RtsOptsClean/setup.out b/cabal/cabal-testsuite/PackageTests/RtsOptsClean/setup.out
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/RtsOptsClean/setup.out
@@ -0,0 +1,2 @@
+# Setup configure
+Configuring RtsOptsClean-0.1...
diff --git a/cabal/cabal-testsuite/PackageTests/RtsOptsClean/setup.test.hs b/cabal/cabal-testsuite/PackageTests/RtsOptsClean/setup.test.hs
new file mode 100644
--- /dev/null
+++ b/cabal/cabal-testsuite/PackageTests/RtsOptsClean/setup.test.hs
@@ -0,0 +1,6 @@
+import Test.Cabal.Prelude
+
+-- Test that setup shows all the 'autogen-modules' warnings.
+main = setupAndCabalTest $ do
+    setup' "configure" [] >>=
+         assertOutputDoesNotContain "Warning: Instead of 'ghc-options: -I0' use 'include-dirs: 0'"
diff --git a/cabal/cabal-testsuite/PackageTests/ShowBuildInfo/CompileFail/compile-fail.out b/cabal/cabal-testsuite/PackageTests/ShowBuildInfo/CompileFail/compile-fail.out
--- a/cabal/cabal-testsuite/PackageTests/ShowBuildInfo/CompileFail/compile-fail.out
+++ b/cabal/cabal-testsuite/PackageTests/ShowBuildInfo/CompileFail/compile-fail.out
@@ -10,6 +10,7 @@
 Configuring test suite 'CompileFail-test' for CompileFail-0.1.0.0..
 Preprocessing test suite 'CompileFail-test' for CompileFail-0.1.0.0..
 Building test suite 'CompileFail-test' for CompileFail-0.1.0.0..
+Error: cabal: Failed to build CompileFail-0.1.0.0-inplace-CompileFail-test.
 # cabal build
 Build profile: -w ghc-<GHCVER> -O1
 In order, the following will be built:
diff --git a/cabal/cabal-testsuite/PackageTests/ShowBuildInfo/Custom/custom.test.hs b/cabal/cabal-testsuite/PackageTests/ShowBuildInfo/Custom/custom.test.hs
--- a/cabal/cabal-testsuite/PackageTests/ShowBuildInfo/Custom/custom.test.hs
+++ b/cabal/cabal-testsuite/PackageTests/ShowBuildInfo/Custom/custom.test.hs
@@ -13,7 +13,7 @@
     buildInfo <- decodeBuildInfoFile buildInfoFp
     assertCommonBuildInfo buildInfo
     let [libBI, exeBI] = components buildInfo
-    
+
     assertComponentPure libBI defCompAssertion
       { modules = ["MyLib"]
       , compType = "lib"
diff --git a/cabal/cabal-testsuite/PackageTests/TestCodeGenerator/test-code-gen/LICENSE b/cabal/cabal-testsuite/PackageTests/TestCodeGenerator/test-code-gen/LICENSE
--- a/cabal/cabal-testsuite/PackageTests/TestCodeGenerator/test-code-gen/LICENSE
+++ b/cabal/cabal-testsuite/PackageTests/TestCodeGenerator/test-code-gen/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2022, 
+Copyright (c) 2022,
 
 All rights reserved.
 
diff --git a/cabal/cabal-testsuite/PackageTests/TestCodeGenerator/test-code-gen/app/Main.hs b/cabal/cabal-testsuite/PackageTests/TestCodeGenerator/test-code-gen/app/Main.hs
--- a/cabal/cabal-testsuite/PackageTests/TestCodeGenerator/test-code-gen/app/Main.hs
+++ b/cabal/cabal-testsuite/PackageTests/TestCodeGenerator/test-code-gen/app/Main.hs
@@ -7,7 +7,7 @@
   (tgt:rest) <- getArgs
   let (srcDirs, ghcArgs) = splitArgs rest
   let isGood = srcDirs == ["."] && "-outputdir" `elem` ghcArgs
-  if isGood 
+  if isGood
    then writeFile (tgt </> "Main.hs") $ "module Main where main = pure ()"
    else writeFile (tgt </> "Main.hs") $ "module Main where main = error \"failure\""
 
diff --git a/cabal/cabal-testsuite/PackageTests/UserConfig/cabal.out b/cabal/cabal-testsuite/PackageTests/UserConfig/cabal.out
--- a/cabal/cabal-testsuite/PackageTests/UserConfig/cabal.out
+++ b/cabal/cabal-testsuite/PackageTests/UserConfig/cabal.out
@@ -12,3 +12,6 @@
 # cabal user-config
 Renaming <ROOT>/cabal.dist/cabal-config to <ROOT>/cabal.dist/cabal-config.backup.
 Writing merged config to <ROOT>/cabal.dist/cabal-config.
+# cabal user-config
+Renaming <ROOT>/cabal.dist/cabal-config to <ROOT>/cabal.dist/cabal-config.backup.
+Writing merged config to <ROOT>/cabal.dist/cabal-config.
diff --git a/cabal/cabal-testsuite/PackageTests/UserConfig/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/UserConfig/cabal.test.hs
--- a/cabal/cabal-testsuite/PackageTests/UserConfig/cabal.test.hs
+++ b/cabal/cabal-testsuite/PackageTests/UserConfig/cabal.test.hs
@@ -15,3 +15,9 @@
     assertFileDoesContain conf "foo,bar"
     cabalG ["--config-file", conf] "user-config" ["update", "-f", "-a", "extra-prog-path: foo, bar"]
     assertFileDoesContain conf "foo,bar"
+
+    -- regression test for #6268 (password-command parsing)
+    cabalG ["--config-file", conf]
+        "user-config" ["update", "-f", "-a", "password-command: sh -c \"echo secret\""]
+    -- non-quoted tokens do get quoted when writing, but this is expected
+    assertFileDoesContain conf "password-command: \"sh\" \"-c\" \"echo secret\""
diff --git a/cabal/cabal-testsuite/PackageTests/postCheckoutCommand/cabal.test.hs b/cabal/cabal-testsuite/PackageTests/postCheckoutCommand/cabal.test.hs
--- a/cabal/cabal-testsuite/PackageTests/postCheckoutCommand/cabal.test.hs
+++ b/cabal/cabal-testsuite/PackageTests/postCheckoutCommand/cabal.test.hs
@@ -1,7 +1,7 @@
 import Test.Cabal.Prelude
 
 main = cabalTest $ do
-    skipIfWindows 
+    skipIfWindows
     withProjectFile "cabal.positive.project" $ do
         cabal "v2-build" ["-v0"]
     withProjectFile "cabal.negative.project" $ do
diff --git a/cabal/cabal-testsuite/README.md b/cabal/cabal-testsuite/README.md
--- a/cabal/cabal-testsuite/README.md
+++ b/cabal/cabal-testsuite/README.md
@@ -4,11 +4,12 @@
 How to run
 ----------
 
-1. Build `cabal-tests` (`cabal build cabal-tests`)
+1. Build `cabal-testsuite` (`cabal build cabal-testsuite:cabal-tests`)
 2. Run the `cabal-tests` executable. It will scan for all tests
    in your current directory and subdirectories and run them.
-   To run a specific set of tests, use `cabal-tests PATH ...`.  You can
-   control parallelism using the `-j` flag.
+   To run a specific set of tests, use `cabal-tests --with-cabal=CABALBIN PATH ...`.
+   (e.g. `cabal run cabal-testsuite:cabal-tests -- --with-cabal=cabal cabal-testsuite/PackageTests/TestOptions/setup.test.hs`)
+   You can control parallelism using the `-j` flag.
 
 There are a few useful flags:
 
@@ -24,6 +25,28 @@
   the autodetection doesn't work correctly (which may be the
   case for old versions of GHC.)
 
+doctests
+========
+
+You need to install the doctest tool. Make sure it's compiled with your current
+GHC, and don't forget to reinstall it every time you switch GHC version:
+
+``` shellsession
+cabal install doctest --overwrite-policy=always --ignore-project
+```
+
+After that you can run doctests for a component of your choice via the following command:
+
+``` shellsession
+cabal repl --with-ghc=doctest --build-depends=QuickCheck --build-depends=template-haskell --repl-options="-w" --project-file="cabal.project.validate" Cabal-syntax
+```
+
+In this example we have run doctests in `Cabal-syntax`. Notice, that some
+components have broken doctests
+([#8734](https://github.com/haskell/cabal/issues/8734));
+our CI currently checks that `Cabal-syntax` and `Cabal` doctests pass via
+`make doctest-install && make doctest` (you can use this make-based workflow too).
+
 How to write
 ------------
 
@@ -137,7 +160,7 @@
 `hasCabalShared`, `isGhcVersion`, `isWindows`, `isLinux`, `isOSX`
 and `hasCabalForGhc`.
 
-**I programatically modified a file in my test suite, but Cabal/GHC
+**I programmatically modified a file in my test suite, but Cabal/GHC
 doesn't seem to be picking it up.**  You need to sleep sufficiently
 long before editing a file, in order for file system timestamp
 resolution to pick it up.  Use `withDelay` and `delay` prior to
@@ -152,7 +175,7 @@
 --------------
 
 By default, we run tests directly on the source code that is checked into the
-source code repository.  However, some tests require programatically
+source code repository.  However, some tests require programmatically
 modifying source files, or interact with Cabal commands which are
 not hermetic (e.g., `cabal freeze`).  In this case, cabal-testsuite
 supports opting into a hermetic test, where we first make copy of all
diff --git a/cabal/cabal-testsuite/cabal-testsuite.cabal b/cabal/cabal-testsuite/cabal-testsuite.cabal
--- a/cabal/cabal-testsuite/cabal-testsuite.cabal
+++ b/cabal/cabal-testsuite/cabal-testsuite.cabal
@@ -1,7 +1,7 @@
 cabal-version: 2.2
 name:          cabal-testsuite
 version:       3
-copyright:     2003-2022, Cabal Development Team (see AUTHORS file)
+copyright:     2003-2023, Cabal Development Team (see AUTHORS file)
 license:       BSD-3-Clause
 license-file:  LICENSE
 author:        Cabal Development Team <cabal-devel@haskell.org>
@@ -26,10 +26,10 @@
   default-language: Haskell2010
 
   build-depends:
-    , base >= 4.6 && <4.18
+    , base >= 4.9 && <4.20
     -- this needs to match the in-tree lib:Cabal version
-    , Cabal ^>=3.8.0.0
-    , Cabal-syntax ^>=3.8.0.0
+    , Cabal ^>= 3.10.3.0
+    , Cabal-syntax ^>= 3.10.3.0
 
   ghc-options: -Wall -fwarn-tabs -fwarn-incomplete-uni-patterns
 
@@ -57,30 +57,30 @@
     Test.Cabal.ScriptEnv0
 
   build-depends:
-    , aeson                 ^>= 1.4.2.0 || ^>=1.5.0.0 || ^>= 2.0.0.0 || ^>= 2.1.0.0
+    , aeson                 ^>= 1.4.2.0 || ^>=1.5.0.0 || ^>= 2.0.0.0 || ^>= 2.1.0.0 || ^>= 2.2.1.0
     , async                 ^>= 2.2.1
     , attoparsec            ^>= 0.13.2.2 || ^>=0.14.1
-    , base16-bytestring     ^>= 0.1.1.6 || ^>= 1.0.0.0
-    , bytestring            ^>= 0.10.0.2 || ^>= 0.11.0.0
-    , containers            ^>= 0.5.0.0 || ^>= 0.6.0.1
+    , base16-bytestring     ^>= 0.1.1.5 || ^>= 1.0
+    , bytestring            ^>= 0.10.0.2 || ^>= 0.11.0.0 || ^>= 0.12.0.0
+    , containers            ^>= 0.5.0.0 || ^>= 0.6.0.1 || ^>= 0.7
     , cryptohash-sha256     ^>= 0.11.101.0
     , directory             ^>= 1.2.0.1 || ^>= 1.3.0.0
     , exceptions            ^>= 0.10.0
-    , filepath              ^>= 1.3.0.1 || ^>= 1.4.0.0
+    , filepath              ^>= 1.3.0.1 || ^>= 1.4.0.0 || ^>= 1.5.0.0
     , network-wait          ^>= 0.1.2.0 || ^>= 0.2.0.0
-    , optparse-applicative  ^>= 0.14.3.0 || ^>=0.15.1.0 || ^>=0.16.0.0 || ^>= 0.17.0.0
+    , optparse-applicative  ^>= 0.14.3.0 || ^>=0.15.1.0 || ^>=0.16.0.0 || ^>= 0.17.0.0 || ^>= 0.18.1.0
     , process               ^>= 1.2.1.0 || ^>= 1.4.2.0 || ^>= 1.6.1.0
     , regex-base            ^>= 0.94.0.1
     , regex-tdfa            ^>= 1.2.3.1 || ^>=1.3.1.0
     , retry                 ^>= 0.9.1.0
     , array                 ^>= 0.4.0.1 || ^>= 0.5.0.0
     , temporary             ^>= 1.3
-    , text                  ^>= 1.2.3.1 || ^>= 2.0.1
-    , transformers          ^>= 0.3.0.0 || ^>= 0.4.2.0 || ^>= 0.5.2.0
+    , text                  ^>= 1.2.3.1 || ^>= 2.0.1   || ^>= 2.1
+    , transformers          ^>= 0.3.0.0 || ^>= 0.4.2.0 || ^>= 0.5.2.0 || ^>= 0.6.0.2
 
   if !os(windows)
     build-depends:
-      , unix                ^>= 2.6.0.0 || ^>= 2.7.0.0
+      , unix                ^>= 2.6.0.0 || ^>= 2.7.0.0 || ^>= 2.8.0.0
   else
     build-depends:
       , Win32
@@ -103,6 +103,7 @@
     , clock                 ^>= 0.7.2 || ^>=0.8
 
   build-tool-depends: cabal-testsuite:setup
+  default-extensions: TypeOperators
 
 -- this executable is needed by lib:cabal-testsuite
 executable setup
@@ -112,7 +113,8 @@
 custom-setup
   -- we only depend on even stable releases of lib:Cabal
   -- and due to Custom complexity and ConstraintSetupCabalMaxVersion
-  -- it can't be the current version
-  setup-depends: Cabal == 3.8.*,
-                 Cabal-syntax == 3.8.*,
+  -- it has to be the latest release version plus
+  -- you have to use the latest cabal-install release
+  setup-depends: Cabal == 3.10.3.0,
+                 Cabal-syntax == 3.10.3.0,
                  base, filepath, directory
diff --git a/cabal/cabal-testsuite/main/cabal-tests.hs b/cabal/cabal-testsuite/main/cabal-tests.hs
--- a/cabal/cabal-testsuite/main/cabal-tests.hs
+++ b/cabal/cabal-testsuite/main/cabal-tests.hs
@@ -82,8 +82,8 @@
     -- https://github.com/appveyor/ci/issues/1364
     hSetBuffering stderr LineBuffering
 
-    -- Parse arguments
-    args <- execParser (info mainArgParser mempty)
+    -- Parse arguments.  N.B. 'helper' adds the option `--help`.
+    args <- execParser $ info (mainArgParser <**> helper) mempty
     let verbosity = if mainArgVerbose args then verbose else normal
 
     -- To run our test scripts, we need to be able to run Haskell code
@@ -214,10 +214,15 @@
             unexpected_passes <- takeMVar unexpected_passes_var
             skipped           <- takeMVar skipped_var
 
-            -- print skipped
-            logAll $ "SKIPPED " ++ show (length skipped) ++ " tests"
+            -- print summary
+            let sl = show . length
+                testSummary =
+                  sl all_tests ++ " tests, " ++ sl skipped ++ " skipped, "
+                    ++ sl unexpected_passes ++ " unexpected passes, "
+                    ++ sl unexpected_fails ++ " unexpected fails."
+            logAll testSummary
 
-            -- print failed or ook
+            -- print failed or unexpected ok
             if null (unexpected_fails ++ unexpected_passes)
             then logAll "OK"
             else do
diff --git a/cabal/cabal-testsuite/src/Test/Cabal/CheckArMetadata.hs b/cabal/cabal-testsuite/src/Test/Cabal/CheckArMetadata.hs
--- a/cabal/cabal-testsuite/src/Test/Cabal/CheckArMetadata.hs
+++ b/cabal/cabal-testsuite/src/Test/Cabal/CheckArMetadata.hs
@@ -20,10 +20,8 @@
 import Data.Char (isSpace)
 import System.IO
 
-import Distribution.Compiler              (CompilerFlavor(..), CompilerId(..))
 import Distribution.Package               (getHSLibraryName)
-import Distribution.Simple.Compiler       (compilerId)
-import Distribution.Simple.LocalBuildInfo (LocalBuildInfo, compiler, localUnitId)
+import Distribution.Simple.LocalBuildInfo (LocalBuildInfo, localUnitId)
 
 -- Almost a copypasta of Distribution.Simple.Program.Ar.wipeMetadata
 checkMetadata :: LocalBuildInfo -> FilePath -> IO ()
@@ -31,10 +29,6 @@
   hFileSize h >>= checkArchive h
   where
     path = dir </> "lib" ++ getHSLibraryName (localUnitId lbi) ++ ".a"
-
-    _ghc_7_10 = case compilerId (compiler lbi) of
-      CompilerId GHC version | version >= mkVersion [7, 10]  -> True
-      _                                                      -> False
 
     checkError msg = assertFailure (
         "PackageTests.DeterministicAr.checkMetadata: " ++ msg ++
diff --git a/cabal/cabal-testsuite/src/Test/Cabal/Monad.hs b/cabal/cabal-testsuite/src/Test/Cabal/Monad.hs
--- a/cabal/cabal-testsuite/src/Test/Cabal/Monad.hs
+++ b/cabal/cabal-testsuite/src/Test/Cabal/Monad.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 
 -- | The test monad
@@ -72,7 +73,10 @@
 import Distribution.Verbosity
 import Distribution.Version
 
-import Data.Monoid ((<>), mempty)
+#if !MIN_VERSION_base(4,11,0)
+import Data.Monoid ((<>))
+#endif
+import Data.Monoid (mempty)
 import qualified Control.Exception as E
 import Control.Monad
 import Control.Monad.Trans.Reader
@@ -100,8 +104,8 @@
 commonArgParser :: Parser CommonArgs
 commonArgParser = CommonArgs
     <$> optional (option str
-        ( help "Path to cabal-install executable to test"
-       Data.Monoid.<> long "with-cabal"
+        ( help "Path to cabal-install executable to test. If omitted, tests involving cabal-install are skipped!"
+       <> long "with-cabal"
        <> metavar "PATH"
         ))
     <*> optional (option str
diff --git a/cabal/cabal-testsuite/src/Test/Cabal/Prelude.hs b/cabal/cabal-testsuite/src/Test/Cabal/Prelude.hs
--- a/cabal/cabal-testsuite/src/Test/Cabal/Prelude.hs
+++ b/cabal/cabal-testsuite/src/Test/Cabal/Prelude.hs
@@ -28,7 +28,7 @@
 import Distribution.Simple.Program.Types
 import Distribution.Simple.Program.Db
 import Distribution.Simple.Program
-import Distribution.System (OS(Windows,Linux,OSX), buildOS)
+import Distribution.System (OS(Windows,Linux,OSX), Arch(JavaScript), buildOS, buildArch)
 import Distribution.Simple.Utils
     ( withFileContents, withTempDirectory, tryFindPackageDesc )
 import Distribution.Simple.Configure
@@ -170,7 +170,7 @@
     defaultRecordMode RecordMarked $ do
     recordHeader ["Setup", cmd]
 
-    -- We test `cabal act-act-setup` when running cabal-tests.
+    -- We test `cabal act-as-setup` when running cabal-tests.
     --
     -- `cabal` and `Setup.hs` do have different interface.
     --
@@ -258,9 +258,11 @@
 ------------------------------------------------------------------------
 -- * Running cabal
 
+-- cabal cmd args
 cabal :: String -> [String] -> TestM ()
 cabal cmd args = void (cabal' cmd args)
 
+-- cabal cmd args
 cabal' :: String -> [String] -> TestM Result
 cabal' = cabalG' []
 
@@ -287,9 +289,11 @@
               , "man"
               , "v1-freeze"
               , "check"
+              , "gen-bounds"
               , "get", "unpack"
               , "info"
               , "init"
+              , "haddock-project"
               ]
           = [ ]
 
@@ -838,7 +842,7 @@
 getScriptCacheDirectory script = do
     cabalDir <- testCabalDir `fmap` getTestEnv
     hashinput <- liftIO $ canonicalizePath script
-    let hash = C.unpack . Base16.encode . SHA256.hash . C.pack $ hashinput
+    let hash = C.unpack . Base16.encode . C.take 26 . SHA256.hash . C.pack $ hashinput
     return $ cabalDir </> "script-builds" </> hash
 
 ------------------------------------------------------------------------
@@ -886,8 +890,14 @@
 skipUnlessGhcVersion range = skipUnless ("needs ghc " ++ range) =<< isGhcVersion range
 
 skipIfGhcVersion :: String -> TestM ()
-skipIfGhcVersion range = skipUnless ("incompatible with ghc " ++ range) =<< isGhcVersion range
+skipIfGhcVersion range = skipIf ("incompatible with ghc " ++ range) =<< isGhcVersion range
 
+skipUnlessJavaScript :: TestM ()
+skipUnlessJavaScript = skipUnless "needs the JavaScript backend" =<< isJavaScript
+
+skipIfJavaScript :: TestM ()
+skipIfJavaScript = skipIf "incompatible with the JavaScript backend" =<< isJavaScript
+
 isWindows :: TestM Bool
 isWindows = return (buildOS == Windows)
 
@@ -896,6 +906,11 @@
 
 isLinux :: TestM Bool
 isLinux = return (buildOS == Linux)
+
+isJavaScript :: TestM Bool
+isJavaScript = return (buildArch == JavaScript)
+  -- should probably be `hostArch` but Cabal doesn't distinguish build platform
+  -- and host platform
 
 skipIfWindows :: TestM ()
 skipIfWindows = skipIf "Windows" =<< isWindows
diff --git a/cabal/cabal-testsuite/src/Test/Cabal/Run.hs b/cabal/cabal-testsuite/src/Test/Cabal/Run.hs
--- a/cabal/cabal-testsuite/src/Test/Cabal/Run.hs
+++ b/cabal/cabal-testsuite/src/Test/Cabal/Run.hs
@@ -2,6 +2,7 @@
 -- | A module for running commands in a chatty way.
 module Test.Cabal.Run (
     run,
+    runAction,
     Result(..)
 ) where
 
@@ -24,8 +25,14 @@
 
 -- | Run a command, streaming its output to stdout, and return a 'Result'
 -- with this information.
-run :: Verbosity -> Maybe FilePath -> [(String, Maybe String)] -> FilePath -> [String] -> Maybe String -> IO Result
-run _verbosity mb_cwd env_overrides path0 args input = do
+run :: Verbosity -> Maybe FilePath -> [(String, Maybe String)] -> FilePath -> [String]
+    -> Maybe String -> IO Result
+run verbosity mb_cwd env_overrides path0 args input =
+    runAction verbosity mb_cwd env_overrides path0 args input (\_ -> return ())
+
+runAction :: Verbosity -> Maybe FilePath -> [(String, Maybe String)] -> FilePath -> [String]
+    -> Maybe String -> (ProcessHandle -> IO ()) -> IO Result
+runAction _verbosity mb_cwd env_overrides path0 args input action = do
     -- In our test runner, we allow a path to be relative to the
     -- current directory using the same heuristic as shells:
     -- 'foo' refers to an executable in the PATH, but './foo'
@@ -71,6 +78,8 @@
           Just h -> hPutStr h x >> hClose h
           Nothing -> error "No stdin handle when input was specified!"
       Nothing -> return ()
+
+    action procHandle
 
     -- wait for the program to terminate
     exitcode <- waitForProcess procHandle
diff --git a/cabal/cabal-testsuite/src/Test/Cabal/Server.hs b/cabal/cabal-testsuite/src/Test/Cabal/Server.hs
--- a/cabal/cabal-testsuite/src/Test/Cabal/Server.hs
+++ b/cabal/cabal-testsuite/src/Test/Cabal/Server.hs
@@ -226,7 +226,6 @@
                         std_out = CreatePipe,
                         std_err = CreatePipe
                     }
-    -- printRawCommandAndArgsAndEnv (runnerVerbosity senv) (programPath prog) ghc_args Nothing
     when (verbosity >= verbose) $
         writeChan chan (ServerLogMsg AllServers (showCommandForUser (programPath prog) ghc_args))
     (Just hin, Just hout, Just herr, proch) <- createProcess proc_spec
diff --git a/cabal/cabal.project b/cabal/cabal.project
--- a/cabal/cabal.project
+++ b/cabal/cabal.project
@@ -13,44 +13,9 @@
 
 optional-packages: ./vendored/*/*.cabal
 
-allow-newer:
-  hackage-security:Cabal
-
 -- avoiding extra dependencies
 constraints: rere -rere-cfg
 constraints: these -assoc
 
--- Andreas, 2022-08-19, https://github.com/haskell/cabal/issues/8377
--- Force latest dependencies in the development version:
-constraints: text >= 2.0
-constraints: time >= 1.12
-
--- So us hackers get all the assertion failures early:
---
--- NOTE: currently commented out, see
--- https://github.com/haskell/cabal/issues/3911
--- as a workaround we specify it for each package individually:
---
--- program-options
---   ghc-options: -fno-ignore-asserts
---
-package Cabal
-  ghc-options: -fno-ignore-asserts
-
-package cabal-testsuite
-  ghc-options: -fno-ignore-asserts
-
-package Cabal-QuickCheck
-  ghc-options: -fno-ignore-asserts
-
-package Cabal-tree-diff
-  ghc-options: -fno-ignore-asserts
-
-package Cabal-described
-  ghc-options: -fno-ignore-asserts
-
-package cabal-install-solver
-  ghc-options: -fno-ignore-asserts
-
-package cabal-install
+program-options
   ghc-options: -fno-ignore-asserts
diff --git a/cabal/cabal.project.coverage b/cabal/cabal.project.coverage
--- a/cabal/cabal.project.coverage
+++ b/cabal/cabal.project.coverage
@@ -28,6 +28,9 @@
 constraints: rere -rere-cfg
 constraints: these
 
+program-options
+  ghc-options: -fno-ignore-asserts
+
 -- NOTE: for library coverage in multi-project builds,
 -- see:
 --
@@ -39,41 +42,33 @@
 -- the `cabal-install` library
 --
 package Cabal-syntax
-  ghc-options: -fno-ignore-asserts
   coverage: False
   library-coverage: False
 
 package Cabal
-  ghc-options: -fno-ignore-asserts
   coverage: False
   library-coverage: False
 
 package cabal-testsuite
-  ghc-options: -fno-ignore-asserts
   coverage: False
   library-coverage: False
 
 package Cabal-QuickCheck
-  ghc-options: -fno-ignore-asserts
   coverage: False
   library-coverage: False
 
 package Cabal-tree-diff
-  ghc-options: -fno-ignore-asserts
   coverage: False
   library-coverage: False
 
 package Cabal-described
-  ghc-options: -fno-ignore-asserts
   coverage: False
   library-coverage: False
 
 package cabal-install-solver
-  ghc-options: -fno-ignore-asserts
   coverage: False
   library-coverage: False
 
 package cabal-install
-  ghc-options: -fno-ignore-asserts
   coverage: True
   library-coverage: True
diff --git a/cabal/cabal.project.doctest b/cabal/cabal.project.doctest
new file mode 100644
--- /dev/null
+++ b/cabal/cabal.project.doctest
@@ -0,0 +1,24 @@
+packages: Cabal-syntax/
+packages: Cabal/
+packages: cabal-testsuite/
+packages: cabal-install/
+packages: solver-benchmarks/
+
+packages: cabal-install-solver/
+packages: Cabal-QuickCheck/
+packages: Cabal-tree-diff
+packages: Cabal-described
+packages: Cabal-tests
+packages: cabal-benchmarks
+
+tests: True
+
+-- avoiding extra dependencies
+constraints: rere -rere-cfg
+constraints: these -assoc
+
+write-ghc-environment-files: never
+
+program-options
+  ghc-options: -fno-ignore-asserts
+
diff --git a/cabal/cabal.project.libonly b/cabal/cabal.project.libonly
--- a/cabal/cabal.project.libonly
+++ b/cabal/cabal.project.libonly
@@ -11,17 +11,4 @@
 --optional-packages: */
 
 program-options
-  -- So us hackers get all the assertion failures early:
-  --
-  -- NOTE: currently commented out, see
-  -- https://github.com/haskell/cabal/issues/3911
-  --
-  -- ghc-options: -fno-ignore-asserts
-  --
-  -- as a workaround we specify it for each package individually:
-package Cabal-syntax
-  ghc-options: -fno-ignore-asserts
-package Cabal
-  ghc-options: -fno-ignore-asserts
-package cabal-testsuite
   ghc-options: -fno-ignore-asserts
diff --git a/cabal/cabal.project.release b/cabal/cabal.project.release
--- a/cabal/cabal.project.release
+++ b/cabal/cabal.project.release
@@ -5,3 +5,4 @@
 tests: False
 benchmarks: False
 optimization: True
+index-state: hackage.haskell.org 2024-03-19T15:03:08Z
diff --git a/cabal/cabal.project.validate b/cabal/cabal.project.validate
--- a/cabal/cabal.project.validate
+++ b/cabal/cabal.project.validate
@@ -19,11 +19,16 @@
 
 write-ghc-environment-files: never
 
+program-options
+  ghc-options: -fno-ignore-asserts
+
 package Cabal-syntax
-  ghc-options: -Werror -fno-ignore-asserts
+  ghc-options: -Werror
 package Cabal
-  ghc-options: -Werror -fno-ignore-asserts
+  ghc-options: -Werror
 package cabal-testsuite
-  ghc-options: -Werror -fno-ignore-asserts
+  ghc-options: -Werror
 package cabal-install
-  ghc-options: -Werror -fno-ignore-asserts
+  ghc-options: -Werror
+
+index-state: hackage.haskell.org 2024-03-19T15:03:08Z
diff --git a/cabal/cabal.project.validate.libonly b/cabal/cabal.project.validate.libonly
--- a/cabal/cabal.project.validate.libonly
+++ b/cabal/cabal.project.validate.libonly
@@ -14,12 +14,15 @@
 constraints: rere -rere-cfg
 constraints: these -assoc
 
+program-options
+  ghc-options: -fno-ignore-asserts
+
 package Cabal-syntax
-  ghc-options: -Werror -fno-ignore-asserts
+  ghc-options: -Werror
 package Cabal
-  ghc-options: -Werror -fno-ignore-asserts
+  ghc-options: -Werror
 package cabal-testsuite
-  ghc-options: -Werror -fno-ignore-asserts
+  ghc-options: -Werror
 
 -- https://github.com/haskell-hvr/cryptohash-sha256/issues/12
 allow-newer: cryptohash-sha256:base
diff --git a/cabal/changelog.d/issue-8351 b/cabal/changelog.d/issue-8351
deleted file mode 100644
--- a/cabal/changelog.d/issue-8351
+++ /dev/null
@@ -1,11 +0,0 @@
-synopsis: Expose BuildFlags and ClientHaddockFlags
-packages: cabal-install
-prs: #8353
-issues: #8351
-
-description: {
-
-Some types are present in public functions in cabal-install, but they are not exported.
-This PR fix it for BuildFlags and ClientHaddockFlags.
-
-}
diff --git a/cabal/changelog.d/pr-8261 b/cabal/changelog.d/pr-8261
deleted file mode 100644
--- a/cabal/changelog.d/pr-8261
+++ /dev/null
@@ -1,9 +0,0 @@
-synopsis: Implement --prefer-oldest
-packages: cabal-install
-prs: #8261
-
-description: {
-
-- Implement `--prefer-oldest` flag for Cabal solver, which tries to find a build plan with the oldest versions possible. This is useful to establish lower bounds.
-
-}
diff --git a/cabal/changelog.d/pr-8309 b/cabal/changelog.d/pr-8309
deleted file mode 100644
--- a/cabal/changelog.d/pr-8309
+++ /dev/null
@@ -1,4 +0,0 @@
-synopsis: Add documentation for cabal-install commands: user-config,
-report, list, init, fetch, info, upload, get.
-prs: #8309
-issues: #8308 #7884 #7978
diff --git a/cabal/changelog.d/pr-8414 b/cabal/changelog.d/pr-8414
deleted file mode 100644
--- a/cabal/changelog.d/pr-8414
+++ /dev/null
@@ -1,11 +0,0 @@
-synopsis: Pass some haddock flags to dependencies
-packages: cabal-install
-prs: #8414
-issues: #8104 #395
-
-description: {
-
-- Pass "--haddock-hoogle", "--haddock-html", "--haddock-internal", "--haddock-quickjump", "--haddock-hyperlinked-source"
-  to all the dependencies if they are specified as command line args
-
-}
diff --git a/cabal/changelog.d/pr-8496 b/cabal/changelog.d/pr-8496
deleted file mode 100644
--- a/cabal/changelog.d/pr-8496
+++ /dev/null
@@ -1,10 +0,0 @@
-synopsis: build pkgconfig db individually when bulk fails
-packages: cabal-install cabal-install-solver
-prs: #8496
-issues: #8494
-
-description: {
-
-- When pkg-config fails to get versions for all packages in bulk, falls back to querying one-by-one.
-
-}
diff --git a/cabal/changelog.d/pr-8561 b/cabal/changelog.d/pr-8561
deleted file mode 100644
--- a/cabal/changelog.d/pr-8561
+++ /dev/null
@@ -1,9 +0,0 @@
-synopsis: cabal init -i should sanitize package name guessed from the directory name
-packages: cabal-install
-prs: #8561
-issues: #8404
-description: {
-    If the current directory name has any non-alphanumeric symbol in its name, the symbol will be replaced with a dash. Also, will make sure that the resulting package name starts with a letter.
-
-    This worked for cabal init -n already, and this PR only moves code around so that cabal init -i also benefits from this logic.
-}
diff --git a/cabal/changelog.d/pr-9443 b/cabal/changelog.d/pr-9443
new file mode 100644
--- /dev/null
+++ b/cabal/changelog.d/pr-9443
@@ -0,0 +1,11 @@
+synopsis: Use linker capability detection to improve linker use
+packages: Cabal
+prs: #9443
+
+description: {
+
+- Previously the GHC version number and platform were used as a proxy for whether
+  the linker can generate relocatable objects.
+- Now, the ability of the linker to create relocatable objects is detected.
+
+}
diff --git a/cabal/doc/Makefile b/cabal/doc/Makefile
--- a/cabal/doc/Makefile
+++ b/cabal/doc/Makefile
@@ -23,6 +23,7 @@
 # See https://modelpredict.com/wht-requirements-txt-is-not-enough
 requirements.txt: requirements.in
 	. ../.python-sphinx-virtualenv/bin/activate \
+	  && pip install --upgrade pip \
 	  && pip install pip-tools \
 	  && pip-compile requirements.in
 
diff --git a/cabal/doc/README.md b/cabal/doc/README.md
--- a/cabal/doc/README.md
+++ b/cabal/doc/README.md
@@ -37,11 +37,11 @@
 So, you cannot have
 
 ```
-	Section heading
-	===============
+    Section heading
+    ===============
 
-	Some unimportant block
-	""""""""""""""""""""""
+    Some unimportant block
+    """"""""""""""""""""""
 ```
 
   instead you need to observe order and either promote your block:
diff --git a/cabal/doc/cabal-commands.rst b/cabal/doc/cabal-commands.rst
--- a/cabal/doc/cabal-commands.rst
+++ b/cabal/doc/cabal-commands.rst
@@ -33,938 +33,1058 @@
 
     freeze            Freeze dependencies.
     haddock           Build Haddock documentation.
-    exec              Give a command access to the store.
-    list-bin          List path to a single executable.
-
-    [new-style projects (forwards-compatible aliases)]
-    Since cabal-install-3.0.0.0, all 'v2-' prefixed names of commands are just aliases for the simple unprefixed names.
-    So v2-build is an alias for build, v2-install for install and so on.
-
-    [legacy command aliases]
-    No legacy commands are described.
-
-Common Arguments and Flags
---------------------------
-
-Arguments and flags common to some or all commands are:
-
-
-.. option:: --default-user-config=file
-
-    Allows a "default" ``cabal.config`` freeze file to be passed in
-    manually. This file will only be used if one does not exist in the
-    project directory already. Typically, this can be set from the
-    global cabal ``config`` file so as to provide a default set of
-    partial constraints to be used by projects, providing a way for
-    users to peg themselves to stable package collections.
-
-
-.. option:: --allow-newer[=pkgs], --allow-older[=pkgs]
-
-    Selectively relax upper or lower bounds in dependencies without
-    editing the package description respectively.
-
-    The following description focuses on upper bounds and the
-    :option:`--allow-newer` flag, but applies analogously to
-    :option:`--allow-older` and lower bounds. :option:`--allow-newer`
-    and :option:`--allow-older` can be used at the same time.
-
-    If you want to install a package A that depends on B >= 1.0 && <
-    2.0, but you have the version 2.0 of B installed, you can compile A
-    against B 2.0 by using ``cabal install --allow-newer=B A``. This
-    works for the whole package index: if A also depends on C that in
-    turn depends on B < 2.0, C's dependency on B will be also relaxed.
-
-    Example:
-
-    ::
-
-        $ cd foo
-        $ cabal configure
-        Resolving dependencies...
-        cabal: Could not resolve dependencies:
-        [...]
-        $ cabal configure --allow-newer
-        Resolving dependencies...
-        Configuring foo...
-
-    Additional examples:
-
-    ::
-
-        # Relax upper bounds in all dependencies.
-        $ cabal install --allow-newer foo
-
-        # Relax upper bounds only in dependencies on bar, baz and quux.
-        $ cabal install --allow-newer=bar,baz,quux foo
-
-        # Relax the upper bound on bar and force bar==2.1.
-        $ cabal install --allow-newer=bar --constraint="bar==2.1" foo
-
-    It's also possible to limit the scope of :option:`--allow-newer` to single
-    packages with the ``--allow-newer=scope:dep`` syntax. This means
-    that the dependency on ``dep`` will be relaxed only for the package
-    ``scope``.
-
-    Example:
-
-    ::
-
-        # Relax upper bound in foo's dependency on base; also relax upper bound in
-        # every package's dependency on lens.
-        $ cabal install --allow-newer=foo:base,lens
-
-        # Relax upper bounds in foo's dependency on base and bar's dependency
-        # on time; also relax the upper bound in the dependency on lens specified by
-        # any package.
-        $ cabal install --allow-newer=foo:base,lens --allow-newer=bar:time
-
-    Finally, one can enable :option:`--allow-newer` permanently by setting
-    ``allow-newer: True`` in the ``~/.cabal/config`` file. Enabling
-    'allow-newer' selectively is also supported in the config file
-    (``allow-newer: foo, bar, baz:base``).
-
-.. option:: --preference=preference
-
-    Specify a soft constraint on versions of a package. The solver will
-    attempt to satisfy these preferences on a "best-effort" basis.
-
-.. option:: --enable-build-info
-
-    Generate accurate build information for build components.
-
-    Information contains meta information, such as component type, compiler type, and
-    Cabal library version used during the build, but also fine grained information,
-    such as dependencies, what modules are part of the component, etc...
-
-    On build, a file ``build-info.json`` (in the ``json`` format) will be written to
-    the root of the build directory.
-
-    .. note::
-        The format and fields of the generated build information is currently
-        experimental. In the future we might add or remove fields, depending
-        on the needs of other tooling.
-
-    .. code-block:: json
-
-        {
-            "cabal-lib-version": "<cabal lib version>",
-            "compiler": {
-                "flavour": "<compiler name>",
-                "compiler-id": "<compiler id>",
-                "path": "<absolute path of the compiler>"
-            },
-            "components": [
-                {
-                "type": "<component type, e.g. lib | bench | exe | flib | test>",
-                "name": "<component name>",
-                "unit-id": "<unitid>",
-                "compiler-args": [
-                    "<compiler args necessary for compilation>"
-                ],
-                "modules": [
-                    "<modules in this component>"
-                ],
-                "src-files": [
-                    "<source files relative to hs-src-dirs>"
-                ],
-                "hs-src-dirs": [
-                    "<source directories of this component>"
-                ],
-                "src-dir": "<root directory of this component>",
-                "cabal-file": "<cabal file location>"
-                }
-            ]
-        }
-
-    .. jsonschema:: ./json-schemas/build-info.schema.json
-
-.. option:: --disable-build-info
-
-    (default) Do not generate detailed build information for built components.
-
-    Already generated `build-info.json` files will be removed since they would be stale otherwise.
-
-cabal init
-----------
-
-``cabal init [FLAGS]`` initialises a Cabal package, picking
-reasonable defaults. Run it in your project folder.
-
-.. option:: -i, --interactive
-
-    Enable interactive mode.
-
-.. option:: -m, --minimal
-
-    Generate a short .cabal file, without extra empty fields or
-    explanatory comments.
-
-See :ref:`init quickstart` for an overview on the command, and
-``cabal init --help`` for the complete list of options.
-
-cabal list-bin
---------------
-
-``cabal list-bin`` will either (a) display the path for a single executable or (b)
-complain that the target doesn't resolve to a single binary. In the latter case,
-it will name the binary products contained in the package. These products can
-be used to narrow the search and get an actual path to a particular executable.
-
-Example showing a failure to resolve to a single executable.
-
-::
-
-    $ cabal list-bin cabal-install
-    cabal: The list-bin command is for finding a single binary at once. The
-    target 'cabal-install' refers to the package cabal-install-#.#.#.# which
-    includes the executable 'cabal', the test suite 'unit-tests', the test suite
-    'mem-use-tests', the test suite 'long-tests' and the test suite
-    'integration-tests2'.
-
-For a scope that results in only one item we'll get a path.
-
-::
-
-    $ cabal list-bin cabal-install:exes
-    /.../dist-newstyle/build/.../cabal/cabal
-
-    $ cabal list-bin cabal-install:cabal
-    /.../dist-newstyle/build/.../cabal/cabal
-
-We can also scope to test suite targets as they produce binaries.
-
-::
-
-    $ cabal list-bin cabal-install:tests
-    cabal: The list-bin command is for finding a single binary at once. The
-    target 'cabal-install:tests' refers to the test suites in the package
-    cabal-install-#.#.#.# which includes the test suite 'unit-tests', the test
-    suite 'mem-use-tests', the test suite 'long-tests' and the test suite
-    'integration-tests2'.
-
-    $ cabal list-bin cabal-install:unit-tests
-    /.../dist-newstyle/.../unit-tests/unit-tests
-
-Note that ``cabal list-bin`` will print the executables' location, but
-will not make sure that these executables actually exist (i.e., have
-been successfully built).  In order to determine the correct location,
-it may invoke the configuration step (see ``cabal configure``).
-
-cabal configure
----------------
-
-``cabal configure`` takes a set of arguments and writes a
-``cabal.project.local`` file based on the flags passed to this command.
-``cabal configure FLAGS; cabal build`` is roughly equivalent to
-``cabal build FLAGS``, except that with ``configure`` the flags
-are persisted to all subsequent calls to ``build``.
-
-``cabal configure`` is intended to be a convenient way to write out
-a ``cabal.project.local`` for simple configurations; e.g.,
-``cabal configure -w ghc-7.8`` would ensure that all subsequent
-builds with ``cabal build`` are performed with the compiler
-``ghc-7.8``. For more complex configuration, we recommend writing the
-``cabal.project.local`` file directly (or placing it in
-``cabal.project``!)
-
-``cabal configure`` inherits options from ``Cabal``. semantics:
-
--  Any flag accepted by ``./Setup configure``.
-
--  Any flag accepted by ``cabal configure`` beyond
-   ``./Setup configure``, namely ``--cabal-lib-version``,
-   ``--constraint``, ``--preference`` and ``--solver.``
-
--  Any flag accepted by ``cabal install`` beyond ``./Setup configure``.
-
--  Any flag accepted by ``./Setup haddock``.
-
-The options of all of these flags apply only to *local* packages in a
-project; this behavior is different than that of ``cabal install``,
-which applies flags to every package that would be built. The motivation
-for this is to avoid an innocuous addition to the flags of a package
-resulting in a rebuild of every package in the store (which might need
-to happen if a flag actually applied to every transitive dependency). To
-apply options to an external package, use a ``package`` stanza in a
-``cabal.project`` file.
-
-There are two ways of modifying the ``cabal.project.local`` file through
-``cabal configure``, either by appending new configurations to it, or
-by simply overwriting it all. Overwriting is the default behaviour, as
-such, there's a flag ``--enable-append`` to append the new configurations
-instead. Since overwriting is rather destructive in nature, a backup system
-is in place, which moves the old configuration to a ``cabal.project.local~``
-file, this feature can also be disabled by using the ``--disable-backup``
-flag.
-
-
-cabal update
-------------
-
-``cabal update`` updates the state of the package index. If the
-project contains multiple remote package repositories it will update
-the index of all of them (e.g. when using overlays).
-
-Some examples:
-
-::
-
-    $ cabal update                  # update all remote repos
-    $ cabal update head.hackage     # update only head.hackage
-
-Target Forms
-------------
-
-A cabal command target can take any of the following forms:
-
--  A package target: ``package``, which specifies that all enabled
-   components of a package to be built. By default, test suites and
-   benchmarks are *not* enabled, unless they are explicitly requested
-   (e.g., via ``--enable-tests``.)
-
--  A component target: ``[package:][ctype:]component``, which specifies
-   a specific component (e.g., a library, executable, test suite or
-   benchmark) to be built.
-
--  All packages: ``all``, which specifies all packages within the project.
-
--  Components of a particular type: ``package:ctypes``, ``all:ctypes``:
-   which specifies all components of the given type. Where valid
-   ``ctypes`` are:
-
-     - ``libs``, ``libraries``,
-     - ``flibs``, ``foreign-libraries``,
-     - ``exes``, ``executables``,
-     - ``tests``,
-     - ``benches``, ``benchmarks``.
-
--  A module target: ``[package:][ctype:]module``, which specifies that the
-   component of which the given module is a part of will be built.
-
--  A filepath target: ``[package:][ctype:]filepath``, which specifies that the
-   component of which the given filepath is a part of will be built.
-
--  A script target: ``path/to/script``, which specifies the path to a script
-   file. This is supported by ``build``, ``repl``, ``run``, and ``clean``.
-   Script targets are not part of a package.
-
-cabal build
------------
-
-``cabal build`` takes a set of targets and builds them. It
-automatically handles building and installing any dependencies of these
-targets.
-
-In component targets, ``package:`` and ``ctype:`` (valid component types
-are ``lib``, ``flib``, ``exe``, ``test`` and ``bench``) can be used to
-disambiguate when multiple packages define the same component, or the
-same component name is used in a package (e.g., a package ``foo``
-defines both an executable and library named ``foo``). We always prefer
-interpreting a target as a package name rather than as a component name.
-
-Some example targets:
-
-::
-
-    $ cabal build lib:foo-pkg       # build the library named foo-pkg
-    $ cabal build foo-pkg:foo-tests # build foo-tests in foo-pkg
-    $ cabal build src/Lib.s         # build the library component to
-                                       # which "src/Lib.hs" belongs
-    $ cabal build app/Main.hs       # build the executable component of
-                                       # "app/Main.hs"
-    $ cabal build Lib               # build the library component to
-                                       # which the module "Lib" belongs
-    $ cabal build path/to/script    # build the script as an executable
-
-Beyond a list of targets, ``cabal build`` accepts all the flags that
-``cabal configure`` takes. Most of these flags are only taken into
-consideration when building local packages; however, some flags may
-cause extra store packages to be built (for example,
-``--enable-profiling`` will automatically make sure profiling libraries
-for all transitive dependencies are built and installed.)
-
-When building a script, the executable is cached under the cabal directory.
-See ``cabal run`` for more information on scripts.
-
-In addition ``cabal build`` accepts these flags:
-
-- ``--only-configure``: When given we will forego performing a full build and
-  abort after running the configure phase of each target package.
-
-
-cabal repl
-----------
-
-``cabal repl TARGET`` loads all of the modules of the target into
-GHCi as interpreted bytecode. In addition to ``cabal build``'s flags,
-it additionally takes the ``--repl-options`` and ``--repl-no-load`` flags.
-
-To avoid ``ghci`` specific flags from triggering unneeded global rebuilds these
-flags are now stripped from the internal configuration. 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 flag also works on ``cabal
-repl`` and ``Setup repl`` on sufficiently new versions of Cabal.)
-
-The ``repl-no-load`` flag disables the loading of target modules at startup.
-
-Currently, it is not supported to pass multiple targets to ``repl``
-(``repl`` will just successively open a separate GHCi session for
-each target.)
-
-It also provides a way to experiment with libraries without needing to download
-them manually or to install them globally.
-
-This command opens a REPL with the current default target loaded, and a version
-of the ``vector`` package matching that specification exposed.
-
-::
-
-    $ cabal repl --build-depends "vector >= 0.12 && < 0.13"
-
-Both of these commands do the same thing as the above, but only exposes ``base``,
-``vector``, and the ``vector`` package's transitive dependencies even if the user
-is in a project context.
-
-::
-
-    $ cabal repl --ignore-project --build-depends "vector >= 0.12 && < 0.13"
-    $ cabal repl --project='' --build-depends "vector >= 0.12 && < 0.13"
-
-This command would add ``vector``, but not (for example) ``primitive``, because
-it only includes the packages specified on the command line (and ``base``, which
-cannot be excluded for technical reasons).
-
-::
-
-    $ cabal repl --build-depends vector --no-transitive-deps
-
-``repl`` can open scripts by passing the path to the script as the target.
-
-::
-
-    $ cabal repl path/to/script
-
-The configuration information for the script is cached under the cabal directory
-and can be pre-built with ``cabal build path/to/script``.
-See ``cabal run`` for more information on scripts.
-
-cabal run
----------
-
-``cabal run [TARGET [ARGS]]`` runs the executable specified by the
-target, which can be a component, a package or can be left blank, as
-long as it can uniquely identify an executable within the project.
-Tests and benchmarks are also treated as executables.
-
-See `the build section <#cabal-build>`__ for the target syntax.
-
-When ``TARGET`` is one of the following:
-
-- A component target: execute the specified executable, benchmark or test suite.
-
-- A package target:
-   1. If the package has exactly one executable component, it will be selected.
-   2. If the package has multiple executable components, an error is raised.
-   3. If the package has exactly one test or benchmark component, it will be selected.
-   4. Otherwise an issue is raised.
-
-- The path to a script: execute the script at the path.
-
-- Empty target: Same as package target, implicitly using the package from the current
-  working directory.
-
-Except in the case of the empty target, the strings after it will be
-passed to the executable as arguments.
-
-If one of the arguments starts with ``-`` it will be interpreted as
-a cabal flag, so if you need to pass flags to the executable you
-have to separate them with ``--``.
-
-::
-
-    $ cabal run target -- -a -bcd --argument
-
-``run`` supports running script files that use a certain format.
-Scripts look like:
-
-::
-
-    #!/usr/bin/env cabal
-    {- cabal:
-    build-depends: base ^>= 4.14
-                , shelly ^>= 1.10
-    -}
-    {- project:
-    with-compiler: ghc-8.10.7
-    -}
-
-    main :: IO ()
-    main = do
-        ...
-
-Where there cabal metadata block is mandatory and contains fields from a
-package executable block, and the project metadata block is optional and
-contains fields that would be in the cabal.project file in a regular project.
-
-Only some fields are supported in the metadata blocks, and these fields are
-currently not validated. See
-`#8024 <https://github.com/haskell/cabal/issues/8024>`__ for details.
-
-A script can either be executed directly using `cabal` as an interpreter or
-with the command:
-
-::
-
-    $ cabal run path/to/script
-
-The executable is cached under the cabal directory, and can be pre-built with
-``cabal build path/to/script`` and the cache can be removed with
-``cabal clean path/to/script``.
-
-A note on targets: Whenever a command takes a script target and it matches the
-name of another target, the other target is preferred. To load the script
-instead pass it as an explicit path: ./script
-
-By default, scripts are run at silent verbosity (``--verbose=0``). To show the
-build output for a script either use the command
-
-::
-
-    $ cabal run --verbose=n path/to/script
-
-or the interpreter line
-
-::
-
-    #!/usr/bin/env -S cabal run --verbose=n
-
-For more information see :cfg-field:`verbose`
-
-cabal fetch
------------
-
-*☞ N.B.:* ``cabal fetch`` only works for legacy ``v1-`` commands and only
-for single package projects. If you are not maintaining an old project,
-`cabal build`_ with ``--only-download`` has similar effects to ``fetch``
-and benefits from compatibility with newer build methods.
-
-``cabal fetch [FLAGS] PACKAGES`` downloads packages for later installation.
-It fetches the project plus its dependencies, very useful when
-e.g. you plan to work on a project with unreliable or no internet access.
-
-.. option:: --no-dependencies
-
-    Ignore dependencies.
-
-.. option:: --disable-tests
-
-    Disable dependency checking and compilation
-    for test suites listed in the package
-    description file.
-
-.. option::  --disable-benchmarks
-
-    Disable dependency checking and compilation
-    for benchmarks listed in the package
-    description file.
-
-Check ``cabal fetch --help`` for a complete list of options.
-
-cabal list
-----------
-
-``cabal list [FLAGS] STRINGS`` lists all packages matching a search string.
-
-.. option::  --installed
-
-    Only output installed packages.
-
-.. option::  --simple-output
-
-    Print matching packages in a one-package-one-line format.
-
-.. option::  -i, --ignore-case
-
-.. option::  -I, --strict-case
-
-.. option:: --package-db=DB
-
-    Append the given package database to the list of used package
-    databases. See `cabal info`_ for a thorough explanation.
-
-.. option:: -w, --with-compiler=PATH
-
-    Path to specific compiler.
-
-cabal get
----------
-
-``cabal get [PACKAGES]`` (synonym: ``cabal unpack``) downloads and unpacks
-the source code of ``PACKAGES`` locally. By default the content of the
-packages is unpacked in the current working directory, in named subfolders
-(e.g.  ``./filepath-1.2.0.8/``), use ``--destdir=PATH`` to specify another
-folder. By default the latest version of the package is downloaded, you can
-ask for a spefic one by adding version numbers
-(``cabal get random-1.0.0.1``).
-
-.. option:: -s, --source-repository[=head|this|...]]
-
-    Clone the package's source repository (Darcs, Git, etc.) instead
-    of downloading the tarball. Only works if the package specifies
-    a ``source-repository``.
-
-.. option:: --index-state=STATE
-
-    Pin your request to a specific Hackage index state. Available
-    ``STATE`` formats: Unix timestamps (e.g. ``@1474732068``),
-    ISO8601 UTC timestamps (e.g. ``2016-09-24T17:47:48Z``), or ``HEAD``
-    (default).
-
-.. option:: --pristine
-
-    Unpacks the pristine tarball, i.e. disregarding any Hackage revision.
-
-cabal freeze
-------------
-
-``cabal freeze`` writes out a **freeze file** which records all of
-the versions and flags that are picked by the solver under the
-current index and flags.  Default name of this file is
-``cabal.project.freeze`` but in combination with a
-``--project-file=my.project`` flag (see :ref:`project-file
-<cmdoption-project-file>`)
-the name will be ``my.project.freeze``.
-A freeze file has the same syntax as ``cabal.project`` and looks
-something like this:
-
-.. highlight:: cabal
-
-::
-
-    constraints: HTTP ==4000.3.3,
-                 HTTP +warp-tests -warn-as-error -network23 +network-uri -mtl1 -conduit10,
-                 QuickCheck ==2.9.1,
-                 QuickCheck +templatehaskell,
-                 -- etc...
-
-
-For end-user executables, it is recommended that you distribute the
-``cabal.project.freeze`` file in your source repository so that all
-users see a consistent set of dependencies. For libraries, this is not
-recommended: users often need to build against different versions of
-libraries than what you developed against.
-
-cabal bench
------------
-
-``cabal bench [TARGETS] [OPTIONS]`` runs the specified benchmarks
-(all the benchmarks in the current package by default), first ensuring
-they are up to date.
-
-cabal test
-----------
-
-``cabal test [TARGETS] [OPTIONS]`` runs the specified test suites
-(all the test suites in the current package by default), first ensuring
-they are up to date.
-
-cabal haddock
--------------
-
-``cabal haddock [FLAGS] [TARGET]`` builds Haddock documentation for
-the specified packages within the project.
-
-If a target is not a library :cfg-field:`haddock-benchmarks`,
-:cfg-field:`haddock-executables`, :cfg-field:`haddock-internal`,
-:cfg-field:`haddock-tests` will be implied as necessary.
-
-cabal exec
-----------
-
-``cabal exec [FLAGS] [--] COMMAND [--] [ARGS]`` runs the specified command
-using the project's environment. That is, passing the right flags to compiler
-invocations and bringing the project's executables into scope.
-
-cabal install
--------------
-
-``cabal install [FLAGS] [TARGETS]`` builds the specified target packages and
-symlinks/copies their executables in ``installdir`` (usually ``~/.cabal/bin``).
-
-.. warning::
-
-  If not every package has an executable to install, use ``all:exes`` rather
-  than ``all`` as the target. To overwrite an installation, use
-  ``--overwrite-policy=always`` as the default policy is ``never``.
-
-For example this command will build the latest ``cabal-install`` and symlink
-its ``cabal`` executable:
-
-::
-
-    $ cabal install cabal-install
-
-In addition, it's possible to use ``cabal install`` to install components
-of a local project. For example, with an up-to-date Git clone of the Cabal
-repository, this command will build cabal-install HEAD and symlink the
-``cabal`` executable:
-
-::
-
-    $ cabal install exe:cabal
-
-Where symlinking is not possible (eg. on some Windows versions) the ``copy``
-method is used by default. You can specify the install method
-by using ``--install-method`` flag:
-
-::
-
-    $ cabal install exe:cabal --install-method=copy --installdir=$HOME/bin
-
-Note that copied executables are not self-contained, since they might use
-data-files from the store.
-
-.. _adding-libraries:
-
-Adding libraries to GHC package environments
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-It is also possible to "install" libraries using the ``--lib`` flag. For
-example, this command will build the latest Cabal library and install it:
-
-::
-
-    $ cabal install --lib Cabal
-
-This works by managing GHC package environment files. By default, it is writing
-to the global environment in ``~/.ghc/$ARCH-$OS-$GHCVER/environments/default``.
-``install`` provides the ``--package-env`` flag to control which of these
-environments is modified.
-
-This command will modify the environment file in the current directory:
-
-::
-
-    $ cabal install --lib Cabal --package-env .
-
-This command will modify the environment file in the ``~/foo`` directory:
-
-::
-
-    $ cabal install --lib Cabal --package-env foo/
-
-Do note that the results of the previous two commands will be overwritten by
-the use of other style commands, so it is not recommended to use them inside
-a project directory.
-
-This command will modify the environment in the ``local.env`` file in the
-current directory:
-
-::
-
-    $ cabal install --lib Cabal --package-env local.env
-
-This command will modify the ``myenv`` named global environment:
-
-::
-
-    $ cabal install --lib Cabal --package-env myenv
-
-If you wish to create a named environment file in the current directory where
-the name does not contain an extension, you must reference it as ``./myenv``.
-
-You can learn more about how to use these environments in `this section of the
-GHC manual <https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/packages.html#package-environments>`_.
-
-cabal clean
------------
-
-``cabal clean [FLAGS]`` cleans up the temporary files and build artifacts
-stored in the ``dist-newstyle`` folder.
-
-By default, it removes the entire folder, but it can also spare the configuration
-and caches if the ``--save-config`` option is given, in which case it only removes
-the build artefacts (``.hi``, ``.o`` along with any other temporary files generated
-by the compiler, along with the build output).
-
-``cabal clean [FLAGS] path/to/script`` cleans up the temporary files and build
-artifacts for the script, which are stored under the .cabal/script-builds directory.
-
-In addition when clean is invoked it will remove all script build artifacts for
-which the corresponding script no longer exists.
-
-cabal info
-----------
-
-``cabal info [FLAGS] PACKAGES`` displays useful informations about remote
-packages.
-
-.. option:: --package-db=DB
-
-    Append the given package database to the list of package databases
-    used (to satisfy dependencies and register into). May be a specific
-    file, ``global`` or ``user``. The initial list is ``['global'], ['global',
-    'user']``, depending on context. Use ``clear`` to reset the list to empty.
-
-cabal sdist
------------
-
-``cabal sdist [FLAGS] [TARGETS]`` takes the crucial files needed to build ``TARGETS``
-and puts them into an archive format ready for upload to Hackage. These archives are stable
-and two archives of the same format built from the same source will hash to the same value.
-
-``cabal sdist`` takes the following flags:
-
-- ``-l``, ``--list-only``: Rather than creating an archive, lists files that would be included.
-  Output is to ``stdout`` by default. The file paths are relative to the project's root
-  directory.
-
-- ``-o``, ``--output-directory``: Sets the output dir, if a non-default one is desired. The default is
-  ``dist-newstyle/sdist/``. ``--output-directory -`` will send output to ``stdout``
-  unless multiple archives are being created.
-
-- ``--null-sep``: Only used with ``--list-only``. Separates filenames with a NUL
-  byte instead of newlines.
-
-``sdist`` is inherently incompatible with sdist hooks (which were removed in `Cabal-3.0`),
-not due to implementation but due to fundamental core invariants
-(same source code should result in the same tarball, byte for byte)
-that must be satisfied for it to function correctly in the larger build ecosystem.
-``autogen-modules`` is able to replace uses of the hooks to add generated modules, along with
-the custom publishing of Haddock documentation to Hackage.
-
-cabal upload
-------------
-
-``cabal upload [FLAGS] TARFILES`` uploads source packages or documentation
-to Hackage.
-
-.. option:: --publish
-
-    Publish the package immediately instead of uploading it as a
-    `package candidate <https://hackage.haskell.org/upload#candidates>`__
-    (make sure everything is fine, you cannot delete published packages
-    on Hackage!).
-
-.. option:: -d, --documentation
-
-    Upload documentation instead of a source package. To upload
-    documentation for a published package (and not a candidate), add
-    ``--publish``.
-
-.. option:: -u, --username
-
-    Your Hackage username.
-
-.. option:: -p, --password
-
-    Your Hackage password.
-
-.. option:: -P, --password-command
-
-    Command to get your Hackage password.
-
-cabal report
-------------
-
-``cabal report [FLAGS]`` uploads build reports to Hackage.
-
-.. option:: -u, --username
-
-    Your Hackage username.
-
-.. option:: -p, --password
-
-    Your Hackage password.
-
-cabal gen-bounds
-----------------
-
-``cabal gen-bounds [FLAGS]`` generates bounds for all dependencies that do not
-currently have them.  Generated bounds are printed to stdout. You can then
-paste them into your .cabal file.
-
-See `the section on generating dependency version bounds <cabal-package.html#generating-dependency-version-bounds>`__ for more details and examples.
-
-cabal user-config
------------------
-
-``cabal user-config [init|diff|update]`` prints and updates user's global
-cabal preferences. It is very useful when you are e.g. first configuring
-``cabal`` on a new machine.
-
-- ``cabal user-config init`` creates a new configuration file.
-
-  .. option:: --config-file=PATH
-
-      Specify config file path. (default: ``~/.cabal/config``).
-
-  .. option:: -f, --force
-
-    Force configuration file overwriting if already exists.
-
-- ``cabal user-config diff`` prints a diff of the user's config file and the
-  default one.
-
-- ``cabal user-config update`` updates the user's config file with additional
-  lines.
-
-  .. option:: -a, --augment=CONFIGLINE
-
-      Pass additional configuration lines to be incorporated in the
-      config file. e.g.
-      ``cabal user-config update --augment "offline: True"``.
-
-      Note how ``--augment`` syntax follows ``cabal user-config diff``
-      output.
-
-cabal outdated
---------------
-
-``cabal outdated [FLAGS]`` checks for outdated dependencies in the package
-description file or freeze file.
-
-``cabal outdated`` supports the following flags:
-
-- ``--v1-freeze-file``: Read dependency version bounds from the freeze file
-  (``cabal.config``) instead of the package description file
-  (``$PACKAGENAME.cabal``).
-
-- ``--v2-freeze-file``:
-
-  :since: 2.4
-
-  Read dependency version bounds from the v2-style freeze file
-  (by default, ``cabal.project.freeze``) instead of the package
-  description file. ``--new-freeze-file`` is an alias for this flag
-  that can be used with pre-2.4 ``cabal``.
-
-- ``--project-file PROJECTFILE``:
-
-  :since: 2.4
-
-  Read dependendency version bounds from the v2-style freeze file
-  related to the named project file (i.e., ``$PROJECTFILE.freeze``)
-  instead of the package desctription file. If multiple ``--project-file``
-  flags are provided, only the final one is considered. This flag
-  must only be passed in when ``--new-freeze-file`` is present.
-
-- ``--simple-output``: Print only the names of outdated dependencies, one per line.
-
-- ``--exit-code``: Exit with a non-zero exit code when there are outdated dependencies.
-
-- ``-q, --quiet``: Don't print any output. Implies ``-v0`` and ``--exit-code``.
-
-- ``--ignore PACKAGENAMES``: Don't warn about outdated dependency version bounds for the packages in this list.
-
-- ``--minor [PACKAGENAMES]``: Ignore major version bumps for these packages.
-  E.g. if there's a version 2.0 of a package ``pkg`` on Hackage and the freeze
-  file specifies the constraint ``pkg == 1.9``, ``cabal outdated --freeze
-  --minor=pkg`` will only consider the ``pkg`` outdated when there's a version
-  of ``pkg`` on Hackage satisfying ``pkg > 1.9 && < 2.0``. ``--minor`` can also
-  be used without arguments, in that case major version bumps are ignored for
-  all packages.
-
-  See `the section on listing outdated dependency version bounds <cabal-package.html#listing-outdated-dependency-version-bounds>`__ for more details and examples.
+    haddock-project   Build Haddock documentation of local packages.
+    exec              Give a command access to the store.
+    list-bin          List path to a single executable.
+
+    [new-style projects (forwards-compatible aliases)]
+    Since cabal-install-3.0.0.0, all 'v2-' prefixed names of commands are just aliases for the simple unprefixed names.
+    So v2-build is an alias for build, v2-install for install and so on.
+
+    [legacy command aliases]
+    No legacy commands are described.
+
+Common Arguments and Flags
+--------------------------
+
+Arguments and flags common to some or all commands are:
+
+
+.. option:: --default-user-config=file
+
+    Allows a "default" ``cabal.config`` freeze file to be passed in
+    manually. This file will only be used if one does not exist in the
+    project directory already. Typically, this can be set from the
+    global cabal ``config`` file so as to provide a default set of
+    partial constraints to be used by projects, providing a way for
+    users to peg themselves to stable package collections.
+
+
+.. option:: --allow-newer[=pkgs], --allow-older[=pkgs]
+
+    Selectively relax upper or lower bounds in dependencies without
+    editing the package description respectively.
+
+    The following description focuses on upper bounds and the
+    :option:`--allow-newer` flag, but applies analogously to
+    :option:`--allow-older` and lower bounds. :option:`--allow-newer`
+    and :option:`--allow-older` can be used at the same time.
+
+    If you want to install a package A that depends on B >= 1.0 && <
+    2.0, but you have the version 2.0 of B installed, you can compile A
+    against B 2.0 by using ``cabal install --allow-newer=B A``. This
+    works for the whole package index: if A also depends on C that in
+    turn depends on B < 2.0, C's dependency on B will be also relaxed.
+
+    Example:
+
+    ::
+
+        $ cd foo
+        $ cabal configure
+        Resolving dependencies...
+        cabal: Could not resolve dependencies:
+        [...]
+        $ cabal configure --allow-newer
+        Resolving dependencies...
+        Configuring foo...
+
+    Additional examples:
+
+    ::
+
+        # Relax upper bounds in all dependencies.
+        $ cabal install --allow-newer foo
+
+        # Relax upper bounds only in dependencies on bar, baz and quux.
+        $ cabal install --allow-newer=bar,baz,quux foo
+
+        # Relax the upper bound on bar and force bar==2.1.
+        $ cabal install --allow-newer=bar --constraint="bar==2.1" foo
+
+    It's also possible to limit the scope of :option:`--allow-newer` to single
+    packages with the ``--allow-newer=scope:dep`` syntax. This means
+    that the dependency on ``dep`` will be relaxed only for the package
+    ``scope``.
+
+    Example:
+
+    ::
+
+        # Relax upper bound in foo's dependency on base; also relax upper bound in
+        # every package's dependency on lens.
+        $ cabal install --allow-newer=foo:base,lens
+
+        # Relax upper bounds in foo's dependency on base and bar's dependency
+        # on time; also relax the upper bound in the dependency on lens specified by
+        # any package.
+        $ cabal install --allow-newer=foo:base,lens --allow-newer=bar:time
+
+    Finally, one can enable :option:`--allow-newer` permanently by setting
+    ``allow-newer: True`` in the :ref:`config file <config-file-discovery>`. Enabling
+    'allow-newer' selectively is also supported in the config file
+    (``allow-newer: foo, bar, baz:base``).
+
+.. option:: --preference=preference
+
+    Specify a soft constraint on versions of a package. The solver will
+    attempt to satisfy these preferences on a "best-effort" basis.
+
+.. option:: --enable-build-info
+
+    Generate accurate build information for build components.
+
+    Information contains meta information, such as component type, compiler type, and
+    Cabal library version used during the build, but also fine grained information,
+    such as dependencies, what modules are part of the component, etc...
+
+    On build, a file ``build-info.json`` (in the ``json`` format) will be written to
+    the root of the build directory.
+
+    .. note::
+        The format and fields of the generated build information is currently
+        experimental. In the future we might add or remove fields, depending
+        on the needs of other tooling.
+
+    .. code-block:: json
+
+        {
+            "cabal-lib-version": "<cabal lib version>",
+            "compiler": {
+                "flavour": "<compiler name>",
+                "compiler-id": "<compiler id>",
+                "path": "<absolute path of the compiler>"
+            },
+            "components": [
+                {
+                "type": "<component type, e.g. lib | bench | exe | flib | test>",
+                "name": "<component name>",
+                "unit-id": "<unitid>",
+                "compiler-args": [
+                    "<compiler args necessary for compilation>"
+                ],
+                "modules": [
+                    "<modules in this component>"
+                ],
+                "src-files": [
+                    "<source files relative to hs-src-dirs>"
+                ],
+                "hs-src-dirs": [
+                    "<source directories of this component>"
+                ],
+                "src-dir": "<root directory of this component>",
+                "cabal-file": "<cabal file location>"
+                }
+            ]
+        }
+
+    .. jsonschema:: ./json-schemas/build-info.schema.json
+
+.. option:: --disable-build-info
+
+    (default) Do not generate detailed build information for built components.
+
+    Already generated `build-info.json` files will be removed since they would be stale otherwise.
+
+Target Forms
+------------
+
+A cabal command target can take any of the following forms:
+
+-  A package target: ``[pkg:]package``, which specifies that all enabled
+   components of a package to be built. By default, test suites and
+   benchmarks are *not* enabled, unless they are explicitly requested
+   (e.g., via ``--enable-tests``.)
+
+-  A component target: ``[package:][ctype:]component``, which specifies
+   a specific component (e.g., a library, executable, test suite or
+   benchmark) to be built.
+
+-  All packages: ``all``, which specifies all packages within the project.
+
+-  Components of a particular type: ``package:ctypes``, ``all:ctypes``:
+   which specifies all components of the given type. Where valid
+   ``ctypes`` are:
+
+     - ``libs``, ``libraries``,
+     - ``flibs``, ``foreign-libraries``,
+     - ``exes``, ``executables``,
+     - ``tests``,
+     - ``benches``, ``benchmarks``.
+
+-  A module target: ``[package:][ctype:]module``, which specifies that the
+   component of which the given module is a part of will be built.
+
+-  A filepath target: ``[package:][ctype:]filepath``, which specifies that the
+   component of which the given filepath is a part of will be built.
+
+-  A script target: ``path/to/script``, which specifies the path to a script
+   file. This is supported by ``build``, ``repl``, ``run``, and ``clean``.
+   Script targets are not part of a package.
+
+Global commands
+---------------
+
+cabal user-config
+^^^^^^^^^^^^^^^^^
+
+``cabal user-config [init|diff|update]`` prints and updates user's global
+cabal preferences. It is very useful when you are e.g. first configuring
+``cabal`` on a new machine.
+
+- ``cabal user-config init`` creates a new configuration file.
+
+  .. option:: --config-file=PATH
+
+      Specify config file path. (default: ``~/.cabal/config``).
+
+  .. option:: -f, --force
+
+    Force configuration file overwriting if already exists.
+
+- ``cabal user-config diff`` prints a diff of the user's config file and the
+  default one.
+
+- ``cabal user-config update`` updates the user's config file with additional
+  lines.
+
+  .. option:: -a, --augment=CONFIGLINE
+
+      Pass additional configuration lines to be incorporated in the
+      config file. e.g.
+      ``cabal user-config update --augment "offline: True"``.
+
+      Note how ``--augment`` syntax follows ``cabal user-config diff``
+      output.
+
+
+Package database commands
+-------------------------
+
+cabal update
+^^^^^^^^^^^^
+
+``cabal update`` updates the state of the package index. If the
+project contains multiple remote package repositories it will update
+the index of all of them (e.g. when using overlays).
+
+Some examples:
+
+::
+
+    $ cabal update                  # update all remote repos
+    $ cabal update head.hackage     # update only head.hackage
+
+cabal list
+^^^^^^^^^^
+
+``cabal list [FLAGS] STRINGS`` lists all packages matching a search string.
+
+.. option::  --installed
+
+    Only output installed packages.
+
+.. option::  --simple-output
+
+    Print matching packages in a one-package-one-line format.
+
+.. option::  -i, --ignore-case
+
+.. option::  -I, --strict-case
+
+.. option:: --package-db=DB
+
+    Append the given package database to the list of used package
+    databases. See `cabal info`_ for a thorough explanation.
+
+.. option:: -w, --with-compiler=PATH
+
+    Path to specific compiler.
+
+cabal info
+^^^^^^^^^^
+
+``cabal info [FLAGS] PACKAGES`` displays useful informations about remote
+packages.
+
+.. option:: --package-db=DB
+
+    Append the given package database to the list of package databases
+    used (to satisfy dependencies and register into). May be a specific
+    file, ``global`` or ``user``. The initial list is ``['global'], ['global',
+    'user']``, depending on context. Use ``clear`` to reset the list to empty.
+
+
+Initialization and download
+---------------------------
+
+cabal init
+^^^^^^^^^^
+
+``cabal init [FLAGS]`` initialises a Cabal package, picking
+reasonable defaults. Run it in your project folder.
+
+.. option:: -i, --interactive
+
+    Enable interactive mode.
+
+.. option:: -m, --minimal
+
+    Generate a short .cabal file, without extra empty fields or
+    explanatory comments.
+
+See :ref:`init quickstart` for an overview on the command, and
+``cabal init --help`` for the complete list of options.
+
+cabal fetch
+^^^^^^^^^^^
+
+*☞ N.B.:* ``cabal fetch`` only works for legacy ``v1-`` commands and only
+for single package projects. If you are not maintaining an old project,
+`cabal build`_ with ``--only-download`` has similar effects to ``fetch``
+and benefits from compatibility with newer build methods.
+
+``cabal fetch [FLAGS] PACKAGES`` downloads packages for later installation.
+It fetches the project plus its dependencies, very useful when
+e.g. you plan to work on a project with unreliable or no internet access.
+
+.. option:: --no-dependencies
+
+    Ignore dependencies.
+
+.. option:: --disable-tests
+
+    Disable dependency checking and compilation
+    for test suites listed in the package
+    description file.
+
+.. option::  --disable-benchmarks
+
+    Disable dependency checking and compilation
+    for benchmarks listed in the package
+    description file.
+
+Check ``cabal fetch --help`` for a complete list of options.
+
+cabal get
+^^^^^^^^^
+
+``cabal get [PACKAGES]`` (synonym: ``cabal unpack``) downloads and unpacks
+the source code of ``PACKAGES`` locally. By default the content of the
+packages is unpacked in the current working directory, in named subfolders
+(e.g.  ``./filepath-1.2.0.8/``), use ``--destdir=PATH`` to specify another
+folder. By default the latest version of the package is downloaded, you can
+ask for a spefic one by adding version numbers
+(``cabal get random-1.0.0.1``).
+
+.. option:: -s, --source-repository[=head|this|...]]
+
+    Clone the package's source repository (Darcs, Git, etc.) instead
+    of downloading the tarball. Only works if the package specifies
+    a ``source-repository``.
+
+.. option:: --index-state=STATE
+
+    Pin your request to a specific Hackage index state. Available
+    ``STATE`` formats: Unix timestamps (e.g. ``@1474732068``),
+    ISO8601 UTC timestamps (e.g. ``2016-09-24T17:47:48Z``), or ``HEAD``
+    (default).
+
+.. option:: --pristine
+
+    Unpacks the pristine tarball, i.e. disregarding any Hackage revision.
+
+Project configuration
+---------------------
+
+cabal configure
+^^^^^^^^^^^^^^^
+
+``cabal configure`` takes a set of arguments and writes a
+``cabal.project.local`` file based on the flags passed to this command.
+``cabal configure FLAGS; cabal build`` is roughly equivalent to
+``cabal build FLAGS``, except that with ``configure`` the flags
+are persisted to all subsequent calls to ``build``.
+
+``cabal configure`` is intended to be a convenient way to write out
+a ``cabal.project.local`` for simple configurations; e.g.,
+``cabal configure -w ghc-7.8`` would ensure that all subsequent
+builds with ``cabal build`` are performed with the compiler
+``ghc-7.8``. For more complex configuration, we recommend writing the
+``cabal.project.local`` file directly (or placing it in
+``cabal.project``!)
+
+``cabal configure`` inherits options from ``Cabal``. semantics:
+
+-  Any flag accepted by ``./Setup configure``.
+
+-  Any flag accepted by ``cabal configure`` beyond
+   ``./Setup configure``, namely ``--cabal-lib-version``,
+   ``--constraint``, ``--preference`` and ``--solver.``
+
+-  Any flag accepted by ``cabal install`` beyond ``./Setup configure``.
+
+-  Any flag accepted by ``./Setup haddock``.
+
+The options of all of these flags apply only to *local* packages in a
+project; this behavior is different than that of ``cabal install``,
+which applies flags to every package that would be built. The motivation
+for this is to avoid an innocuous addition to the flags of a package
+resulting in a rebuild of every package in the store (which might need
+to happen if a flag actually applied to every transitive dependency). To
+apply options to an external package, use a ``package`` stanza in a
+``cabal.project`` file.
+
+There are two ways of modifying the ``cabal.project.local`` file through
+``cabal configure``, either by appending new configurations to it, or
+by simply overwriting it all. Overwriting is the default behaviour, as
+such, there's a flag ``--enable-append`` to append the new configurations
+instead. Since overwriting is rather destructive in nature, a backup system
+is in place, which moves the old configuration to a ``cabal.project.local~``
+file, this feature can also be disabled by using the ``--disable-backup``
+flag.
+
+cabal freeze
+^^^^^^^^^^^^
+
+``cabal freeze`` writes out a **freeze file** which records all of
+the versions and flags that are picked by the solver under the
+current index and flags.  Default name of this file is
+``cabal.project.freeze`` but in combination with a
+``--project-file=my.project`` flag (see :ref:`project-file
+<cmdoption-project-file>`)
+the name will be ``my.project.freeze``.
+A freeze file has the same syntax as ``cabal.project`` and looks
+something like this:
+
+.. highlight:: cabal
+
+::
+
+    constraints: HTTP ==4000.3.3,
+                 HTTP +warp-tests -warn-as-error -network23 +network-uri -mtl1 -conduit10,
+                 QuickCheck ==2.9.1,
+                 QuickCheck +templatehaskell,
+                 -- etc...
+
+
+For end-user executables, it is recommended that you distribute the
+``cabal.project.freeze`` file in your source repository so that all
+users see a consistent set of dependencies. For libraries, this is not
+recommended: users often need to build against different versions of
+libraries than what you developed against.
+
+cabal gen-bounds
+^^^^^^^^^^^^^^^^
+
+``cabal gen-bounds [FLAGS]`` generates bounds for all dependencies that do not
+currently have them.  Generated bounds are printed to stdout. You can then
+paste them into your .cabal file.
+
+See `the section on generating dependency version bounds <cabal-package.html#generating-dependency-version-bounds>`__ for more details and examples.
+
+cabal outdated
+^^^^^^^^^^^^^^
+
+``cabal outdated [FLAGS]`` checks for outdated dependencies in the package
+description file or freeze file.
+
+``cabal outdated`` supports the following flags:
+
+.. option:: --v1-freeze-file
+
+    Read dependency version bounds from the freeze file.
+
+    (``cabal.config``) instead of the package description file
+    (``$PACKAGENAME.cabal``).
+
+.. option:: --v2-freeze-file
+
+    :since: 2.4
+
+    Read dependency version bounds from the v2-style freeze file
+    (by default, ``cabal.project.freeze``) instead of the package
+    description file. ``--new-freeze-file`` is an alias for this flag
+    that can be used with pre-2.4 ``cabal``.
+
+.. option:: --project-file PROJECTFILE
+
+    :since: 2.4
+
+    Read dependency version bounds from the v2-style freeze file
+    related to the named project file (i.e., ``$PROJECTFILE.freeze``)
+    instead of the package description file. If multiple ``--project-file``
+    flags are provided, only the final one is considered. This flag
+    must only be passed in when ``--new-freeze-file`` is present.
+
+.. option:: --simple-output
+
+    Print only the names of outdated dependencies, one per line.
+
+.. option:: --exit-code
+
+    Exit with a non-zero exit code when there are outdated dependencies.
+
+.. option:: -q, --quiet
+
+    Don't print any output. Implies ``-v0`` and ``--exit-code``.
+
+.. option:: --ignore PACKAGENAMES
+
+    Don't warn about outdated dependency version bounds for the packages in this list.
+
+.. option:: --minor [PACKAGENAMES]
+
+    Ignore major version bumps for these packages.
+
+    E.g. if there's a version 2.0 of a package ``pkg`` on Hackage and the freeze
+    file specifies the constraint ``pkg == 1.9``, ``cabal outdated --freeze
+    --minor=pkg`` will only consider the ``pkg`` outdated when there's a version
+    of ``pkg`` on Hackage satisfying ``pkg > 1.9 && < 2.0``. ``--minor`` can also
+    be used without arguments, in that case major version bumps are ignored for
+    all packages.
+
+    See `the section on listing outdated dependency version bounds <cabal-package.html#listing-outdated-dependency-version-bounds>`__ for more details and examples.
+
+Project building and installing
+-------------------------------
+
+cabal build
+^^^^^^^^^^^
+
+``cabal build`` takes a set of targets and builds them. It
+automatically handles building and installing any dependencies of these
+targets.
+
+In component targets, ``package:`` and ``ctype:`` (valid component types
+are ``lib``, ``flib``, ``exe``, ``test`` and ``bench``) can be used to
+disambiguate when multiple packages define the same component, or the
+same component name is used in a package (e.g., a package ``foo``
+defines both an executable and library named ``foo``). We always prefer
+interpreting a target as a package name rather than as a component name.
+
+Some example targets:
+
+::
+
+    $ cabal build lib:foo-pkg       # build the library named foo-pkg
+    $ cabal build foo-pkg:foo-tests # build foo-tests in foo-pkg
+    $ cabal build src/Lib.s         # build the library component to
+                                       # which "src/Lib.hs" belongs
+    $ cabal build app/Main.hs       # build the executable component of
+                                       # "app/Main.hs"
+    $ cabal build Lib               # build the library component to
+                                       # which the module "Lib" belongs
+    $ cabal build path/to/script    # build the script as an executable
+
+Beyond a list of targets, ``cabal build`` accepts all the flags that
+``cabal configure`` takes. Most of these flags are only taken into
+consideration when building local packages; however, some flags may
+cause extra store packages to be built (for example,
+``--enable-profiling`` will automatically make sure profiling libraries
+for all transitive dependencies are built and installed.)
+
+When building a script, the executable is cached under the cabal directory.
+See ``cabal run`` for more information on scripts.
+
+In addition ``cabal build`` accepts these flags:
+
+.. option:: --only-configure
+
+    When given we will forego performing a full build and abort after running
+    the configure phase of each target package.
+
+cabal install
+^^^^^^^^^^^^^
+
+``cabal install [FLAGS] [TARGETS]`` builds the specified target packages and
+symlinks/copies their executables in ``installdir`` (usually ``~/.local/bin``).
+
+.. warning::
+
+  If not every package has an executable to install, use ``all:exes`` rather
+  than ``all`` as the target. To overwrite an installation, use
+  ``--overwrite-policy=always`` as the default policy is ``never``.
+
+For example this command will build the latest ``cabal-install`` and symlink
+its ``cabal`` executable:
+
+::
+
+    $ cabal install cabal-install
+
+In addition, it's possible to use ``cabal install`` to install components
+of a local project. For example, with an up-to-date Git clone of the Cabal
+repository, this command will build cabal-install HEAD and symlink the
+``cabal`` executable:
+
+::
+
+    $ cabal install exe:cabal
+
+Where symlinking is not possible (eg. on some Windows versions) the ``copy``
+method is used by default. You can specify the install method
+by using ``--install-method`` flag:
+
+::
+
+    $ cabal install exe:cabal --install-method=copy --installdir=$HOME/bin
+
+Note that copied executables are not self-contained, since they might use
+data-files from the store.
+
+.. _adding-libraries:
+
+Adding libraries to GHC package environments
+""""""""""""""""""""""""""""""""""""""""""""
+
+It is also possible to "install" libraries using the ``--lib`` flag. For
+example, this command will build the latest Cabal library and install it:
+
+::
+
+    $ cabal install --lib Cabal
+
+This works by managing GHC package environment files. By default, it is writing
+to the global environment in ``~/.ghc/$ARCH-$OS-$GHCVER/environments/default``.
+``install`` provides the ``--package-env`` flag to control which of these
+environments is modified.
+
+This command will modify the environment file in the current directory:
+
+::
+
+    $ cabal install --lib Cabal --package-env .
+
+This command will modify the environment file in the ``~/foo`` directory:
+
+::
+
+    $ cabal install --lib Cabal --package-env foo/
+
+Do note that the results of the previous two commands will be overwritten by
+the use of other style commands, so it is not recommended to use them inside
+a project directory.
+
+This command will modify the environment in the ``local.env`` file in the
+current directory:
+
+::
+
+    $ cabal install --lib Cabal --package-env local.env
+
+This command will modify the ``myenv`` named global environment:
+
+::
+
+    $ cabal install --lib Cabal --package-env myenv
+
+If you wish to create a named environment file in the current directory where
+the name does not contain an extension, you must reference it as ``./myenv``.
+
+You can learn more about how to use these environments in `this section of the
+GHC manual <https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/packages.html#package-environments>`_.
+
+cabal haddock
+^^^^^^^^^^^^^
+
+``cabal haddock [FLAGS] [TARGET]`` builds Haddock documentation for
+the specified packages within the project.
+
+If a target is not a library :cfg-field:`haddock-benchmarks`,
+:cfg-field:`haddock-executables`, :cfg-field:`haddock-internal`,
+:cfg-field:`haddock-tests` will be implied as necessary.
+
+cabal haddock-project
+^^^^^^^^^^^^^^^^^^^^^
+
+``cabal haddock-project [FLAGS]`` builds Haddock documentation for all local
+packages specified in the project.
+
+By default the documentation will be put in ``./haddocks`` folder, this can be
+modified with the ``--output`` flag.
+
+This command supports two primary modes: building a self contained directory
+(which is the default mode) or documentation that links to hackage (with
+``--hackage`` flag).
+
+In both cases the html index as well as quickjump index will include all terms
+and types defined in any of the local packages, but not ones that are included
+in any of the dependencies.  But note that if you navigate to a dependency,
+you will have access to its quickjump index.
+
+The generated landing page will contain one tree of all modules per local
+package.
+
+cabal clean
+^^^^^^^^^^^
+
+``cabal clean [FLAGS]`` cleans up the temporary files and build artifacts
+stored in the ``dist-newstyle`` folder.
+
+By default, it removes the entire folder, but it can also spare the configuration
+and caches if the ``--save-config`` option is given, in which case it only removes
+the build artefacts (``.hi``, ``.o`` along with any other temporary files generated
+by the compiler, along with the build output).
+
+``cabal clean [FLAGS] path/to/script`` cleans up the temporary files and build
+artifacts for the script, which are stored under the .cabal/script-builds directory.
+
+In addition when clean is invoked it will remove all script build artifacts for
+which the corresponding script no longer exists.
+
+Running and testing
+-------------------
+
+cabal list-bin
+^^^^^^^^^^^^^^
+
+``cabal list-bin`` will either (a) display the path for a single executable or (b)
+complain that the target doesn't resolve to a single binary. In the latter case,
+it will name the binary products contained in the package. These products can
+be used to narrow the search and get an actual path to a particular executable.
+
+Example showing a failure to resolve to a single executable.
+
+::
+
+    $ cabal list-bin cabal-install
+    cabal: The list-bin command is for finding a single binary at once. The
+    target 'cabal-install' refers to the package cabal-install-#.#.#.# which
+    includes the executable 'cabal', the test suite 'unit-tests', the test suite
+    'mem-use-tests', the test suite 'long-tests' and the test suite
+    'integration-tests2'.
+
+For a scope that results in only one item we'll get a path.
+
+::
+
+    $ cabal list-bin cabal-install:exes
+    /.../dist-newstyle/build/.../cabal/cabal
+
+    $ cabal list-bin cabal-install:cabal
+    /.../dist-newstyle/build/.../cabal/cabal
+
+We can also scope to test suite targets as they produce binaries.
+
+::
+
+    $ cabal list-bin cabal-install:tests
+    cabal: The list-bin command is for finding a single binary at once. The
+    target 'cabal-install:tests' refers to the test suites in the package
+    cabal-install-#.#.#.# which includes the test suite 'unit-tests', the test
+    suite 'mem-use-tests', the test suite 'long-tests' and the test suite
+    'integration-tests2'.
+
+    $ cabal list-bin cabal-install:unit-tests
+    /.../dist-newstyle/.../unit-tests/unit-tests
+
+Note that ``cabal list-bin`` will print the executables' location, but
+will not make sure that these executables actually exist (i.e., have
+been successfully built).  In order to determine the correct location,
+it may invoke the configuration step (see ``cabal configure``).
+
+cabal repl
+^^^^^^^^^^
+
+``cabal repl TARGET [FLAGS]``
+opens an interactive session for the target component within the project and
+loads all of the modules of the target into GHCi as interpreted bytecode.
+The available targets are the same as for the ``build`` command: individual components
+within packages in the project, including libraries, executables, test-suites
+and benchmarks (see `the build section <#cabal-build>`__ for the target syntax).
+Local packages can also be specified, in which case the library
+component in the package will be used, or the (first listed) executable in the
+package if there is no library. Dependencies are built or rebuilt as necessary.
+
+Currently, it is not supported to pass multiple targets to ``repl``
+(``repl`` will just successively open a separate GHCi session for
+each target.)
+
+Examples:
+
+::
+
+    $ cabal repl                # default component in the package in the current directory
+    $ cabal repl pkgname        # default component in the package named 'pkgname'
+    $ cabal repl ./pkgfoo       # default component in the package in the ./pkgfoo directory
+    $ cabal repl cname          # component named 'cname'
+    $ cabal repl pkgname:cname  # component 'cname' in the package 'pkgname'
+
+Configuration flags can be specified on the command line and these extend the project
+configuration from the 'cabal.project', 'cabal.project.local' and other files.
+
+.. option:: --repl-options
+
+    To avoid ``ghci``-specific flags from triggering unneeded global rebuilds, these
+    flags are stripped from the internal configuration. As a result,
+    ``--ghc-options`` will no longer (reliably) work to pass flags to ``ghci`` (or
+    other REPLs). Instead, you should use the ``--repl-options`` flag to
+    specify these options to the invoked REPL.
+
+.. option:: --repl-no-load
+
+    Disables the loading of target modules at startup.
+
+.. option:: -b, --build-depends
+
+    A way to experiment with libraries without needing to download
+    them manually or to install them globally.
+
+    This command opens a REPL with the current default target loaded, and a version
+    of the ``vector`` package matching that specification exposed.
+
+    ::
+
+        $ cabal repl --build-depends "vector >= 0.12 && < 0.13"
+
+    Both of these commands do the same thing as the above, but only expose ``base``,
+    ``vector``, and the ``vector`` package's transitive dependencies even if the user
+    is in a project context.
+
+    ::
+
+        $ cabal repl --ignore-project --build-depends "vector >= 0.12 && < 0.13"
+        $ cabal repl --project='' --build-depends "vector >= 0.12 && < 0.13"
+
+    This command would add ``vector``, but not (for example) ``primitive``, because
+    it only includes the packages specified on the command line (and ``base``, which
+    cannot be excluded for technical reasons).
+
+    ::
+
+        $ cabal repl --build-depends vector --no-transitive-deps
+
+``cabal repl`` can open scripts by passing the path to the script as the target.
+
+::
+
+    $ cabal repl path/to/script
+
+The configuration information for the script is cached under the cabal directory
+and can be pre-built with ``cabal build path/to/script``.
+See ``cabal run`` for more information on scripts.
+
+.. _cabal run:
+
+cabal run
+^^^^^^^^^
+
+``cabal run [TARGET [ARGS]]`` runs the executable specified by the
+target, which can be a component, a package or can be left blank, as
+long as it can uniquely identify an executable within the project.
+Tests and benchmarks are also treated as executables.
+
+See `the build section <#cabal-build>`__ for the target syntax.
+
+When ``TARGET`` is one of the following:
+
+- A component target: execute the specified executable, benchmark or test suite.
+
+- A package target:
+   1. If the package has exactly one executable component, it will be selected.
+   2. If the package has multiple executable components, an error is raised.
+   3. If the package has exactly one test or benchmark component, it will be selected.
+   4. Otherwise an issue is raised.
+
+- The path to a script: execute the script at the path.
+
+- Empty target: Same as package target, implicitly using the package from the current
+  working directory.
+
+Except in the case of the empty target, the strings after it will be
+passed to the executable as arguments.
+
+If one of the arguments starts with ``-`` it will be interpreted as
+a cabal flag, so if you need to pass flags to the executable you
+have to separate them with ``--``.
+
+::
+
+    $ cabal run target -- -a -bcd --argument
+
+``run`` supports running script files that use a certain format.
+Scripts look like:
+
+::
+
+    #!/usr/bin/env cabal
+    {- cabal:
+    build-depends: base ^>= 4.14
+                , shelly ^>= 1.10
+    -}
+    {- project:
+    with-compiler: ghc-8.10.7
+    -}
+
+    main :: IO ()
+    main = do
+        ...
+
+Where there cabal metadata block is mandatory and contains fields from a
+package executable block, and the project metadata block is optional and
+contains fields that would be in the cabal.project file in a regular project.
+
+Only some fields are supported in the metadata blocks, and these fields are
+currently not validated. See
+`#8024 <https://github.com/haskell/cabal/issues/8024>`__ for details.
+
+A script can either be executed directly using `cabal` as an interpreter or
+with the command:
+
+::
+
+    $ cabal run path/to/script
+
+The executable is cached under the cabal directory, and can be pre-built with
+``cabal build path/to/script`` and the cache can be removed with
+``cabal clean path/to/script``.
+
+A note on targets: Whenever a command takes a script target and it matches the
+name of another target, the other target is preferred. To load the script
+instead pass it as an explicit path: ./script
+
+By default, scripts are run at silent verbosity (``--verbose=0``). To show the
+build output for a script either use the command
+
+::
+
+    $ cabal run --verbose=n path/to/script
+
+or the interpreter line
+
+::
+
+    #!/usr/bin/env -S cabal run --verbose=n
+
+For more information see :cfg-field:`verbose`
+
+cabal bench
+^^^^^^^^^^^
+
+``cabal bench [TARGETS] [OPTIONS]`` runs the specified benchmarks
+(all the benchmarks in the current package by default), first ensuring
+they are up to date.
+
+cabal test
+^^^^^^^^^^
+
+``cabal test [TARGETS] [OPTIONS]`` runs the specified test suites
+(all the test suites in the current package by default), first ensuring
+they are up to date.
+
+cabal exec
+^^^^^^^^^^
+
+``cabal exec [FLAGS] [--] COMMAND [--] [ARGS]`` runs the specified command
+using the project's environment. That is, passing the right flags to compiler
+invocations and bringing the project's executables into scope.
+
+Sanity checks and shipping
+--------------------------
+
+cabal check
+^^^^^^^^^^^
+
+``cabal check [FLAGS]`` checks the package for common mistakes (e.g.: if
+it is missing important fields like ``synopsis``, if it is using
+tricky GHC options, etc.).
+
+Run ``cabal check`` in the folder where your ``.cabal`` package file is.
+
+.. option:: -v, --verbose[=n]
+
+    Set verbosity level (0–3, default is 1).
+
+``cabal check`` mimics Hackage's requirements: if no error or warning
+is reported, Hackage should accept your package.
+
+cabal sdist
+^^^^^^^^^^^
+
+``cabal sdist [FLAGS] [TARGETS]`` takes the crucial files needed to build ``TARGETS``
+and puts them into an archive format ready for upload to Hackage. These archives are stable
+and two archives of the same format built from the same source will hash to the same value.
+
+``cabal sdist`` takes the following flags:
+
+.. option:: -l, --list-only
+
+    Rather than creating an archive, lists files that would be included.
+
+    Output is to ``stdout`` by default. The file paths are relative to the project's root
+    directory.
+
+.. option:: -o, --output-directory
+
+    Sets the output dir, if a non-default one is desired. The default is
+    ``dist-newstyle/sdist/``. ``--output-directory -`` will send output to ``stdout``
+    unless multiple archives are being created.
+
+.. option:: --null-sep
+
+    Only used with ``--list-only``. Separates filenames with a NUL
+    byte instead of newlines.
+
+``sdist`` is inherently incompatible with sdist hooks (which were removed in `Cabal-3.0`),
+not due to implementation but due to fundamental core invariants
+(same source code should result in the same tarball, byte for byte)
+that must be satisfied for it to function correctly in the larger build ecosystem.
+``autogen-modules`` is able to replace uses of the hooks to add generated modules, along with
+the custom publishing of Haddock documentation to Hackage.
+
+cabal upload
+^^^^^^^^^^^^
+
+``cabal upload [FLAGS] TARFILES`` uploads source packages or documentation
+to Hackage.
+
+.. option:: --publish
+
+    Publish the package immediately instead of uploading it as a
+    `package candidate <https://hackage.haskell.org/upload#candidates>`__
+    (make sure everything is fine, you cannot delete published packages
+    on Hackage!).
+
+.. option:: -d, --documentation
+
+    Upload documentation instead of a source package. To upload
+    documentation for a published package (and not a candidate), add
+    ``--publish``.
+
+.. option:: -u, --username
+
+    Your Hackage username.
+
+.. option:: -p, --password
+
+    Your Hackage password.
+
+.. option:: -P, --password-command
+
+    Command to get your Hackage password.  Arguments with whitespace
+    must be quoted (double-quotes only).  For example:
+
+    ::
+
+        --password-command 'sh -c "grep hackage ~/secrets | cut -d : -f 2"'
+
+    Or in the config file:
+
+    ::
+
+        password-command: sh -c "grep hackage ~/secrets | cut -d : -f 2"
+
+
+cabal report
+^^^^^^^^^^^^
+
+``cabal report [FLAGS]`` uploads build reports to Hackage.
+
+.. option:: -u, --username
+
+    Your Hackage username.
+
+.. option:: -p, --password
+
+    Your Hackage password.
diff --git a/cabal/doc/cabal-package.rst b/cabal/doc/cabal-package.rst
--- a/cabal/doc/cabal-package.rst
+++ b/cabal/doc/cabal-package.rst
@@ -763,7 +763,8 @@
     behaviour, put the files that wildcards will match against in
     their own folder.
 
-    ``**`` wildcards are available starting in Cabal 2.4.
+    ``**`` wildcards are available starting in Cabal 2.4
+    and `bug-free since Cabal 3.0 <https://github.com/haskell/cabal/issues/6125#issuecomment-1379878419>`_.
 
 .. pkg-field:: data-dir: directory
 
@@ -773,9 +774,9 @@
 
 .. pkg-field:: extra-source-files: filename list
 
-    A list of additional files to be included in source distributions
-    built with :ref:`setup-sdist`. As with :pkg-field:`data-files` it can use
-    a limited form of ``*`` wildcards in file names.
+    A list of additional files to be included in source distributions built with :ref:`setup-sdist`.
+    As with :pkg-field:`data-files` it can use a limited form of ``*`` wildcards in file names.
+    Files listed here are tracked by ``cabal build``; changes in these files cause (partial) rebuilds.
 
 .. pkg-field:: extra-doc-files: filename list
     :since: 1.18
@@ -999,6 +1000,11 @@
 
       default-language: Haskell2010
 
+.. note::
+    For packages using ``cabal-version: 3.4`` or higher, the syntax to
+    specify an internal library in a ``build-depends:`` section is
+    ``package-name:internal-library-name``.
+
 **Multiple public libraries**
 
 Cabal 3.0 and later support exposing multiple libraries from a single package
@@ -1250,6 +1256,25 @@
 
     The module exporting the ``tests`` symbol.
 
+.. pkg-field:: code-generators
+
+    An optional list of preprocessors which can generate new modules
+    for use in the test-suite.
+
+ A list of executabes (possibly brought into scope by
+ :pkg-field:`build-tool-depends`) that are run after all other
+ preprocessors. These executables are invoked as so: ``exe-name
+ TARGETDIR [SOURCEDIRS] -- [GHCOPTIONS]``. The arguments are, in order a target dir for
+ output, a sequence of all source directories with source files of
+ local lib components that the given test stanza dependens on, and
+ following a double dash, all options cabal would pass to ghc for a
+ build. They are expected to output a newline-seperated list of
+ generated modules which have been written to the targetdir
+ (excepting, if written, the main module). This can
+ be used for driving doctests and other discover-style tests generated
+ from source code.
+
+
 Example: Package using ``exitcode-stdio-1.0`` interface
 """""""""""""""""""""""""""""""""""""""""""""""""""""""
 
@@ -1574,7 +1599,7 @@
 is. Foreign libraries however don't get registered, which means that we'd have
 to have a way of finding out where a platform library got installed (other than by
 searching the ``lib/`` directory). Instead, we install foreign libraries in
-``~/.cabal/lib``, much like we install executables in ``~/.cabal/bin``.
+``~/.local/lib``.
 
 Build information
 ^^^^^^^^^^^^^^^^^
@@ -2901,6 +2926,9 @@
     ``2016-09-24T17:47:48Z``), or ``HEAD`` (default).
     This determines which package versions are available as well as which
     ``.cabal`` file revision is selected (unless ``--pristine`` is used).
+``--only-package-description``
+    Unpack only the package description file. A synonym,
+    ``--package-description-only``, is provided for convenience.
 ``--pristine``
     Unpack the original pristine tarball, rather than updating the
     ``.cabal`` file with the latest revision from the package archive.
@@ -3149,12 +3177,29 @@
 Accessing the package version
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-The aforementioned auto generated :file:`Paths_{pkgname}` module also
-exports the constant ``version ::``
-`Version <http://hackage.haskell.org/package/base/docs/Data-Version.html>`__
+The auto generated :file:`PackageInfo_{pkgname}` module exports the constant
+``version ::`` `Version <http://hackage.haskell.org/package/base/docs/Data-Version.html>`__
 which is defined as the version of your package as specified in the
 ``version`` field.
 
+Accessing package-related informations
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The auto generated :file:`PackageInfo_{pkgname}` module exports the following
+package-related constants:
+
+.. code-block:: haskell
+
+    name :: String
+    version :: Version
+    synopsis :: String
+    copyright :: String
+    homepage :: String
+
+Unlike :file:`Paths_{pkgname}` (see <#accessing-data-files-from-package-code>),
+:file:`PackageInfo_{pkgname}` is system- and path-independent. It aims to be
+easier to work with for hash-based tools such as Nix.
+
 .. _system-dependent parameters:
 
 System-dependent parameters
@@ -3192,6 +3237,20 @@
    given in the ``.cabal`` file. In particular, this file may be
    generated by the ``configure`` script mentioned above, allowing these
    settings to vary depending on the build environment.
+
+Note that the package's ``extra-source-files`` are available to the
+``configure`` script when it is executed. In typical ``autoconf`` fashion,
+``--host`` flag will be passed to the ``configure`` script to indicate the host
+platform when cross-compiling. Moreover, various bits of build configuration
+will be passed via environment variables:
+
+ - ``CC`` will reflect the path to the C compiler
+ - ``CFLAGS`` will reflect the path to the C compiler
+ - ``CABAL_FLAGS`` will contain the Cabal flag assignment of the current
+   package using traditional Cabal flag syntax (e.g. ``+flagA -flagB``)
+ - ``CABAL_FLAG_<flag>`` will be set to either ``0`` or ``1`` depending upon
+   whether flag ``<flag>`` is enabled. Note that any any non-alpha-numeric
+   characters in the flag name are replaced with ``_``.
 
 The build information file should have the following structure:
 
diff --git a/cabal/doc/cabal-project.rst b/cabal/doc/cabal-project.rst
--- a/cabal/doc/cabal-project.rst
+++ b/cabal/doc/cabal-project.rst
@@ -24,7 +24,7 @@
 following sources (later entries override earlier ones, except for appendable
 options):
 
-1. ``~/.cabal/config`` (the user-wide global configuration)
+1. :ref:`The user-wide global configuration <config-file-discovery>` (default: ``~/.config/cabal/config``)
 
 2. ``cabal.project`` (the project configuration)
 
@@ -63,6 +63,11 @@
 
     import: /absolutepath/some-project.project
 
+Using conditionals will force cabal to find a ghc to derive
+architecture and version information from, which will force some
+commands (update, sdist) to require ghc present where otherwise it
+would not be necessitated.
+
 Specifying the local packages
 -----------------------------
 
@@ -76,7 +81,7 @@
 
     .. warning::
 
-      The default value ``./*.cabal`` only takes effect if there is no explicit 
+      The default value ``./*.cabal`` only takes effect if there is no explicit
       ``cabal.project`` file.
       If you use such explicit file you *must* fill the field.
 
@@ -122,8 +127,10 @@
 .. cfg-field:: extra-packages: package list with version bounds (comma separated)
     :synopsis: Adds external packages as local
 
-    [STRIKEOUT:Specifies a list of external packages from Hackage which
-    should be considered local packages.] (Not implemented)
+    Specifies a list of external packages from Hackage, which
+    should be considered local packages. The motivation for
+    :cfg-field:`extra-packages` is making libraries that are not
+    dependencies of any package in the project available for use in ghci.
 
     There is no command line variant of this field.
 
@@ -301,8 +308,8 @@
 
     This option cannot be specified via a ``cabal.project`` file.
 
--- option:: --ignore-project
-    
+.. option:: --ignore-project
+
     Ignores the local ``cabal.project`` file and uses the default
     configuration with the local ``foo.cabal`` file. Note that
     if this flag is set while the ``--project-file`` flag is also
@@ -906,7 +913,7 @@
 
     :default: False
 
-    If the compiler (e.g., GHC 7.10 and later) supports outputing OS
+    If the compiler (e.g., GHC 7.10 and later) supports outputting OS
     native debug info (e.g., DWARF), setting ``debug-info: True`` will
     instruct it to do so. See the GHC wiki page on :ghc-wiki:`DWARF`
     for more information about this feature.
@@ -1000,7 +1007,7 @@
                --program-prefix=prefix
     :synopsis: Prepend prefix to program names.
 
-    [STRIKEOUT:Prepend *prefix* to installed program names.] (Currently
+    :strike:`Prepend *prefix* to installed program names.` (Currently
     implemented in a silly and not useful way. If you need this to work
     give us a shout.)
 
@@ -1014,7 +1021,7 @@
                --program-suffix=suffix
     :synopsis: Append refix to program names.
 
-    [STRIKEOUT:Append *suffix* to installed program names.] (Currently
+    :strike:`Append *suffix* to installed program names.` (Currently
     implemented in a silly and not useful way. If you need this to work
     give us a shout.)
 
@@ -1084,7 +1091,7 @@
 
     :default: False
 
-    [STRIKEOUT:Build a package which is relocatable.] (TODO: It is not
+    :strike:`Build a package which is relocatable.` (TODO: It is not
     clear what this actually does, or if it works at all.)
 
     The command line variant of this flag is ``--relocatable``.
@@ -1231,6 +1238,14 @@
         each module, whether top level or local. In GHC specifically,
         this is for non-inline toplevel or where-bound functions or
         values.  Corresponds to ``-fprof-auto``.
+    late-toplevel
+        Like top-level but costs will be assigned to top level definitions after
+        optimization. This lowers profiling overhead massively while giving similar
+        levels of detail as toplevle-functions. However it means functions introduced
+        by GHC during optimization will show up in profiles as well.
+        Corresponds to ``-fprof-late`` if supported and ``-fprof-auto-top`` otherwise.
+    late
+        Currently an alias for late-toplevel
 
     The command line variant of this flag is
     ``--profiling-detail=none``.
@@ -1330,11 +1345,12 @@
     :default: False
 
     Enables building of Haddock documentation.
+    Implied when calling ``cabal haddock``.
 
     The command line variant of this flag is ``--enable-documentation``
     and ``--disable-documentation``.
 
-    `documentation: true` does not imply
+    ``documentation: true`` does not imply
     :cfg-field:`haddock-all`,
     :cfg-field:`haddock-benchmarks`,
     :cfg-field:`haddock-executables`,
@@ -1567,8 +1583,8 @@
 
     :default: ``~/.cabal/packages``
 
-    [STRIKEOUT:The location where packages downloaded from remote
-    repositories will be cached.] Not implemented yet.
+    :strike:`The location where packages downloaded from remote
+    repositories will be cached.` Not implemented yet.
 
     The command line variant of this flag is
     ``--remote-repo-cache=DIR``.
@@ -1579,7 +1595,7 @@
 
     :default: ``~/.cabal/logs``
 
-    [STRIKEOUT:The location where build logs for packages are stored.]
+    :strike:`The location where build logs for packages are stored.`
     Not implemented yet.
 
     The command line variant of this flag is ``--logs-dir=DIR``.
@@ -1590,10 +1606,11 @@
 
     :default: ``~/.cabal/logs/build.log``
 
-    [STRIKEOUT:The file to save build summaries. Valid variables which
-    can be used in the path are ``$pkgid``, ``$compiler``, ``$os`` and
-    ``$arch``.] Not implemented yet.
+    :strike:`The file to save build summaries.` Not implemented yet.
 
+    Valid variables which can be used in the path are ``$pkgid``,
+    ``$compiler``, ``$os`` and ``$arch``.
+
     The command line variant of this flag is
     ``--build-summary=TEMPLATE``.
 
@@ -1659,7 +1676,7 @@
                --fine-grained-conflicts
                --no-fine-grained-conflicts
     :synopsis: Skip a version of a package if it does not resolve any conflicts
-	       encountered in the last version (solver optimization).
+               encountered in the last version (solver optimization).
 
     :default: True
 
@@ -1676,7 +1693,7 @@
                --minimize-conflict-set
                --no-minimize-conflict-set
     :synopsis: Try to improve the solver error message when there is no
-	       solution.
+               solution.
 
     :default: False
 
@@ -1730,7 +1747,7 @@
                --prefer-oldest
                --no-prefer-oldest
     :synopsis: Prefer the oldest versions of packages available.
-    :since:    3.8
+    :since:    3.10
 
     :default:  False
 
diff --git a/cabal/doc/conf.py b/cabal/doc/conf.py
--- a/cabal/doc/conf.py
+++ b/cabal/doc/conf.py
@@ -13,12 +13,13 @@
 sys.path.insert(0, os.path.abspath('.'))
 import cabaldomain
 
-version = "3.8.1.0"
+version = "3.10.3.0"
 
 extensions = [
     'sphinx.ext.extlinks',
     'sphinx.ext.todo',
-    'sphinx-jsonschema'
+    'sphinx-jsonschema',
+    'sphinxnotes.strike'
 ]
 
 templates_path = ['_templates']
@@ -28,17 +29,17 @@
 
 # extlinks -- see http://www.sphinx-doc.org/en/stable/ext/extlinks.html
 extlinks = {
-    'issue': ('https://github.com/haskell/cabal/issues/%s', '#'),
+    'issue': ('https://github.com/haskell/cabal/issues/%s', 'issue #%s'),
 
-    'ghc-wiki': ('https://gitlab.haskell.org/ghc/ghc/-/wikis/%s', ''),
-    'ghc-ticket': ('https://gitlab.haskell.org/ghc/ghc/-/issues/%s', 'GHC #'),
+    'ghc-wiki': ('https://gitlab.haskell.org/ghc/ghc/-/wikis/%s', '%s'),
+    'ghc-ticket': ('https://gitlab.haskell.org/ghc/ghc/-/issues/%s', 'GHC issue #%s'),
 
-    'hackage-pkg': ('http://hackage.haskell.org/package/%s', ''),
+    'hackage-pkg': ('http://hackage.haskell.org/package/%s', '%s'),
 }
 
 # General information about the project.
 project = u'Cabal'
-copyright = u'2003-2022, Cabal Team'
+copyright = u'2003-2023, Cabal Team'
 # N.B. version comes from ghc_config
 release = version  # The full version, including alpha/beta/rc tags.
 
@@ -57,9 +58,13 @@
 # on_rtd is whether we are on readthedocs.org, this line of code grabbed from docs.readthedocs.org
 on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
 
-if not on_rtd:  # only import and set the theme if we're building docs locally
+html_theme = 'sphinx_rtd_theme'
+# only import the theme if we're building docs locally
+if on_rtd:
+    html_style = None
+    using_rtd_theme = True
+else:
     import sphinx_rtd_theme
-    html_theme = 'sphinx_rtd_theme'
     html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
 
 # The name for this set of Sphinx documents.  If None, it defaults to
@@ -81,12 +86,15 @@
     "conf_py_path": "doc/",
     "source_suffix": '.rst',
 }
+html_theme_options = {
+    'collapse_navigation': False,
+}
 
 
 # If true, an OpenSearch description file will be output, and all pages will
 # contain a <link> tag referring to it.  The value of this option must be the
 # base URL from which the finished HTML is served.
-#html_use_opensearch = ''
+html_use_opensearch = 'https://cabal.readthedocs.io/en/stable'
 
 # This is the file name suffix for HTML files (e.g. ".xhtml").
 #html_file_suffix = None
diff --git a/cabal/doc/config.rst b/cabal/doc/config.rst
--- a/cabal/doc/config.rst
+++ b/cabal/doc/config.rst
@@ -7,7 +7,7 @@
 --------
 
 The global configuration file for ``cabal-install`` is by default
-``$HOME/.cabal/config``. If you do not have this file, ``cabal`` will create
+``$XDG_CONFIG_HOME/cabal/config``. If you do not have this file, ``cabal`` will create
 it for you on the first call to ``cabal update``
 (details see `configuration file discovery`_).
 Alternatively, you can explicitly ask ``cabal`` to create it for you using
@@ -18,7 +18,7 @@
 
 You can change the location of the global configuration file by specifying
 either ``--config-file=FILE`` on the command line or by setting the
-``CABAL_CONFIG`` environment variable.
+``CABAL_CONFIG`` or ``CABAL_DIR`` environment variable.
 
 Most of the options in this configuration file are also available as
 command line arguments, and the corresponding documentation can be used
@@ -51,16 +51,23 @@
    The variable to find global configuration file.
 
 ``CABAL_DIR``
-   Default content directory for ``cabal-install`` files.
-   Default value is ``getAppUserDataDirectory "cabal"``, which is
-   ``$HOME/.cabal`` on unix systems and ``%APPDATA%\cabal`` in Windows.
 
+   If set, *all* ``cabal-install`` content files will be stored as
+   subdirectories of this directory, including the configuration file
+   if ``CABAL_CONFIG`` is unset.  If ``CABAL_DIR`` is unset, Cabal
+   will store data files according to the XDG Base Directory
+   Specification (see `directories`_).
+
    .. note::
 
-       The CABAL_DIR might be dropped in the future, when
-       ``cabal-install`` starts to use XDG Directory specification.
+       For backwards compatibility, if the directory ``~/.cabal`` on
+       Unix or ``%APPDATA%\cabal`` on Windows exists, and
+       ``$XDG_CONFIG_HOME/cabal/config`` does not exist, and
+       ``CABAL_DIR`` is unset, ``cabal-install`` will behave as if
+       ``CABAL_DIR`` was set to point at this directory.
 
 ``CABAL_BUILDDIR``
+
     The override for default ``dist`` build directory.
     Note, the nix-style builds build directory (``dist-newstyle``)
     is not affected by this environment variable.
@@ -75,14 +82,44 @@
 1. If option ``--config-file`` is given, use it;
 2. otherwise, if ``$CABAL_CONFIG`` is set use it;
 3. otherwise, if ``$CABAL_DIR`` is set use ``$CABAL_DIR/config``;
-4. otherwise use ``config`` in ``getAppUserDirectory "cabal"``.
+4. otherwise use ``config`` in ``$XDG_CONFIG_HOME/cabal``, which
+   defaults to ``~/.config/cabal`` on Unix.
 
 If the configuration file does not exist, and it was not given
 explicitly via ``--config-file`` or ``$CABAL_CONFIG``, then
 ``cabal-install`` will generate the default one, with directories
-based on ``$CABAL_DIR`` (if set) or ``getAppUserDirectory "cabal"``
-prefix.
+based on ``$CABAL_DIR`` (if set) or according to the XDG Base
+Directory Specification, as listed below.
 
+.. _directories:
+
+Directories
+-----------
+
+Unless the ``CABAL_DIR`` environment variable is set or a ``~/.cabal``
+directory exists, Cabal will by default store data in directories
+according to the XDG Base Directory Specification.  The following
+directories are used unless otherwise specified in the configuration
+file:
+
+* ``$XDG_CONFIG_HOME/cabal`` for the main configuration file.
+  Defaults to ``~/.config/cabal`` on Unix, and ``%APPDATA%/cabal`` on
+  Windows.  Overridden by the ``CABAL_CONFIG`` environment variable if
+  set.
+
+* ``$XDG_CACHE_HOME/cabal`` for downloaded packages and script
+  executables.  Defaults to ``~/.cache/cabal`` on Unix, and
+  ``%LOCALAPPDATA%/cabal`` on Windows.  You can delete this directory
+  and expect that its contents will be reconstructed as needed.
+
+* ``$XDG_STATE_HOME/cabal`` for compiled libraries and other stateful
+  artifacts, including the Cabal store.  Defaults to
+  ``~/.local/state/cabal`` on Unix and ``%LOCALAPPDATA%/cabal`` on
+  Windows.  Deleting this directory might cause installed programs to
+  stop working.
+
+* ``~/.local/bin`` for executables installed with ``cabal install``.
+
 Repository specification
 ------------------------
 
@@ -97,7 +134,7 @@
 
 The name of the repository is given on the first line, and can be
 anything; packages downloaded from this repository will be cached under
-``~/.cabal/packages/hackage.haskell.org`` (or whatever name you specify;
+``$XDG_CACHE_HOME/cabal/packages/hackage.haskell.org`` (or whatever name you specify;
 you can change the prefix by changing the value of
 :cfg-field:`remote-repo-cache`). If you want, you can configure multiple
 repositories, and ``cabal`` will combine them and be able to download
@@ -214,7 +251,8 @@
 .. note::
     The ``preferred-versions`` file can be used to restrict the package set from Hackage, by preferring
     certain versions or marking a specific version as deprecated. To achieve this, add a
-    local no-index repository to your ``~/.cabal/config``, where the directory contains your custom
+    local no-index repository to your :ref:`configuration file <config-file-discovery>`,
+    where the directory contains your custom
     ``preferred-versions``. After running ``cabal update``, all ``cabal`` operations will honour the
     configuration.
 
diff --git a/cabal/doc/file-format-changelog.rst b/cabal/doc/file-format-changelog.rst
--- a/cabal/doc/file-format-changelog.rst
+++ b/cabal/doc/file-format-changelog.rst
@@ -70,8 +70,9 @@
 * License fields use identifiers from SPDX License List version
   ``3.9 2020-05-15``
 
-* Dependencies to sublibraries have to be specified explicitly,
+* Dependencies to sublibraries must be specified explicitly,
   even for current package.
+  For example: ``build-depends: mypackage:internal-lib``
   This way you can have an internal library with the same
   name as some external dependency.
 
@@ -160,6 +161,10 @@
     ``foo/**/bar.html`` are all invalid). As ``**`` was an error in
     globs before, this does not affect any existing ``.cabal`` files
     that previously worked.
+    (Caveat: Double-star wildcards in :pkg-field:`data-files` directories,
+    e.g. ``data-files: data/**/*.csv``,
+    `are only supported correctly from Cabal 3.0 <https://github.com/haskell/cabal/issues/6125#issuecomment-1379878419>`_.)
+
 
   * Wildcards now match when the pattern's extensions form a suffix of
     the candidate file's extension, rather than requiring strict
diff --git a/cabal/doc/getting-started.rst b/cabal/doc/getting-started.rst
--- a/cabal/doc/getting-started.rst
+++ b/cabal/doc/getting-started.rst
@@ -166,6 +166,44 @@
         /    /  /    /   \    \
        /____/  /____/     \____\
 
+Run a single-file Haskell script
+--------------------------------
+
+Cabal also enables us to run single-file Haskell scripts
+without creating a project directory or ``.cabal`` file.
+The cabal directives are placed in the file within a comment.
+
+.. code-block:: haskell
+
+    #!/usr/bin/env cabal
+    {- cabal:
+    build-depends: base, split
+    -}
+
+    import Data.List.Split (chunksOf)
+
+    main :: IO ()
+    main = getLine >>= print . chunksOf 3
+
+This can be run using ``cabal run myscript``.
+On Unix-like systems this can be run directly with execute permission.
+
+.. code-block:: console
+
+    $ cabal run myscript
+
+    $ chmod +x myscript
+    $ ./myscript
+
+Project metadata can also be included:
+
+.. code-block:: haskell
+
+    {- project:
+    with-compiler: ghc-8.10.7
+    -}
+
+See more in the documentation for :ref:`cabal run`.
 
 What Next?
 ----------
diff --git a/cabal/doc/nix-integration.rst b/cabal/doc/nix-integration.rst
--- a/cabal/doc/nix-integration.rst
+++ b/cabal/doc/nix-integration.rst
@@ -11,10 +11,8 @@
 Enabling Nix Integration
 ------------------------
 
-To enable Nix integration, simply pass the ``--enable-nix`` global
-option when you call ``cabal``. To use this option everywhere, edit
-your :ref:`global configuration file<config-file-discovery>`
-(default: ``$HOME/.cabal/config``) to include:
+To enable Nix integration, simply pass the ``--enable-nix`` global option when you call ``cabal`` (eg. ``cabal --enable-nix v1-build``).
+To use this option everywhere, edit your :ref:`global configuration file<config-file-discovery>` (default: ``~/.config/cabal/config``) to include:
 
 .. code-block:: cabal
 
@@ -22,16 +20,16 @@
 
 If the package (which must be locally unpacked) provides a ``shell.nix`` or ``default.nix`` file, this flag will cause ``cabal`` to run most commands through ``nix-shell``. If both expressions are present, ``shell.nix`` is preferred. The following commands are affected:
 
-- ``cabal configure``
-- ``cabal build``
-- ``cabal repl``
-- ``cabal install`` (only if installing into a sandbox)
-- ``cabal haddock``
-- ``cabal freeze``
-- ``cabal gen-bounds``
-- ``cabal run``
+- ``cabal v1-configure``
+- ``cabal v1-build``
+- ``cabal v1-repl``
+- ``cabal v1-install`` (only if installing into a sandbox)
+- ``cabal v1-haddock``
+- ``cabal v1-freeze``
+- ``cabal v1-gen-bounds``
+- ``cabal v1-run``
 
-If the package does not provide an expression, ``cabal`` runs normally.
+If the package does not provide a Nix expression, ``cabal`` runs normally.
 
 Creating Nix Expressions
 ------------------------
diff --git a/cabal/doc/nix-local-build.rst b/cabal/doc/nix-local-build.rst
--- a/cabal/doc/nix-local-build.rst
+++ b/cabal/doc/nix-local-build.rst
@@ -11,19 +11,19 @@
 
 ::
 
-    $ cabal v2-build
+    $ cabal build
 
 To open a GHCi shell with this package, use this command:
 
 ::
 
-    $ cabal v2-repl
+    $ cabal repl
 
 To run an executable defined in this package, use this command:
 
 ::
 
-    $ cabal v2-run <executable name> [executable args]
+    $ cabal run <executable name> [executable args]
 
 Developing multiple packages
 ----------------------------
@@ -51,29 +51,29 @@
 
 ::
 
-    $ cabal v2-build all
+    $ cabal build all
 
-To build a specific package, you can either run ``v2-build`` from the
+To build a specific package, you can either run ``build`` from the
 directory of the package in question:
 
 ::
 
     $ cd cabal-install
-    $ cabal v2-build
+    $ cabal build
 
 or you can pass the name of the package as an argument to
-``cabal v2-build`` (this works in any subdirectory of the project):
+``cabal build`` (this works in any subdirectory of the project):
 
 ::
 
-    $ cabal v2-build cabal-install
+    $ cabal build cabal-install
 
 You can also specify a specific component of the package to build. For
 example, to build a test suite named ``package-tests``, use the command:
 
 ::
 
-    $ cabal v2-build package-tests
+    $ cabal build package-tests
 
 Targets can be qualified with package names. So to request
 ``package-tests`` *from* the ``Cabal`` package, use
@@ -81,7 +81,7 @@
 
 Unlike sandboxes, there is no need to setup a sandbox or ``add-source``
 projects; just check in ``cabal.project`` to your repository and
-``v2-build`` will just work.
+``build`` will just work.
 
 Cookbook
 ========
@@ -94,14 +94,14 @@
 
     profiling: True
 
-Now, ``cabal v2-build`` will automatically build all libraries and
+Now, ``cabal build`` will automatically build all libraries and
 executables with profiling.  You can fine-tune the profiling settings
 for each package using :cfg-field:`profiling-detail`::
 
     package p
         profiling-detail: toplevel-functions
 
-Alternately, you can call ``cabal v2-build --enable-profiling`` to
+Alternately, you can call ``cabal build --enable-profiling`` to
 temporarily build with profiling.
 
 How can I have a reproducible set of versions for my dependencies?
@@ -146,11 +146,10 @@
 across projects. To be more precise:
 
 1. A **local package** is one that is listed explicitly in the
-   ``packages``, ``optional-packages`` or ``extra-packages`` field of a
-   project. Usually, these refer to packages whose source code lives
-   directly in a folder in your project. But you can list an
-   arbitrary Hackage package in :cfg-field:`packages`
-   to force it to be treated as local.
+   ``packages``, ``optional-packages`` or ``extra-packages`` fields of a
+   project. Packages in the former two fields will usually have their
+   source code stored in a folder in your project, while ``extra-packages`` lists
+   packages residing on Hackage that are treated as being local anyway.
 
 Local packages, as well as the external packages (below) which depend on
 them, are built **inplace**, meaning that they are always built
@@ -159,8 +158,8 @@
 suitable for packages which you want to edit and recompile.
 
 2. An **external package** is any package which is not listed in the
-   ``packages`` field. The source code for external packages is usually
-   retrieved from Hackage.
+   ``packages``, ``optional-packages`` and ``extra-packages`` fields.
+   The source code for external packages is usually retrieved from Hackage.
 
 When an external package does not depend on an inplace package, it can
 be built and installed to a **global** store, which can be shared across
@@ -174,13 +173,13 @@
 The global package store is ``~/.cabal/store`` (configurable via
 global `store-dir` option); if you need to clear your store for
 whatever reason (e.g., to reclaim disk space or because the global
-store is corrupted), deleting this directory is safe (``v2-build``
+store is corrupted), deleting this directory is safe (``build``
 will just rebuild everything it needs on its next invocation).
 
 This split motivates some of the UI choices for Nix-style local build
-commands. For example, flags passed to ``cabal v2-build`` are only
+commands. For example, flags passed to ``cabal build`` are only
 applied to *local* packages, so that adding a flag to
-``cabal v2-build`` doesn't necessitate a rebuild of *every* transitive
+``cabal build`` doesn't necessitate a rebuild of *every* transitive
 dependency in the global package store.
 
 In cabal-install 2.0 and above, Nix-style local builds also take advantage of a
@@ -195,10 +194,10 @@
 Where are my build products?
 ----------------------------
 
-A major deficiency in the current implementation of v2-build is that
+A major deficiency in the current implementation of ``cabal build`` is that
 there is no programmatic way to access the location of build products.
 The location of the build products is intended to be an internal
-implementation detail of v2-build, but we also understand that many
+implementation detail of ``cabal build``, but we also understand that many
 unimplemented features can only be reasonably worked around by
 accessing build products directly.
 
@@ -246,7 +245,7 @@
 ``cabal-install`` does caching are an implementation detail and may
 change in the future, knowing what gets cached is helpful for
 understanding the performance characteristics of invocations to
-``v2-build``. The cached intermediate results are stored in
+``build``. The cached intermediate results are stored in
 ``dist-newstyle/cache``; this folder can be safely deleted to clear the
 cache.
 
@@ -262,7 +261,7 @@
     already available in the store.)
 ``source-hashes`` (binary)
     The hashes of all local source files. When all local source files of
-    a local package are unchanged, ``cabal v2-build`` will skip
+    a local package are unchanged, ``cabal build`` will skip
     invoking ``setup build`` entirely (saving us from a possibly
     expensive call to ``ghc --make``). The full list of source files
     participating in compilation is determined using
diff --git a/cabal/doc/requirements.in b/cabal/doc/requirements.in
--- a/cabal/doc/requirements.in
+++ b/cabal/doc/requirements.in
@@ -1,5 +1,12 @@
-sphinx >= 3.1
-sphinx_rtd_theme
+sphinx == 5.3.0
+sphinx_rtd_theme >= 1.2
 sphinx-jsonschema
+sphinxnotes-strike
 # Pygments>=2.7.4 suggested by CVE-2021-20270 CVE-2021-27291
 Pygments >= 2.7.4
+# CVE-2023-37920
+certifi >= 2023.07.22
+# CVE-2023-45803
+urllib3 >= 2.0.7
+# CVE-2024-22195
+jinja2 == 3.1.3
diff --git a/cabal/doc/requirements.txt b/cabal/doc/requirements.txt
--- a/cabal/doc/requirements.txt
+++ b/cabal/doc/requirements.txt
@@ -1,6 +1,6 @@
 #
-# This file is autogenerated by pip-compile with python 3.9
-# To update, run:
+# This file is autogenerated by pip-compile with Python 3.10
+# by the following command:
 #
 #    pip-compile requirements.in
 #
@@ -8,36 +8,38 @@
     # via sphinx
 babel==2.9.1
     # via sphinx
-certifi==2021.10.8
-    # via requests
+certifi==2022.12.7
+    # via
+    #   -r requirements.in
+    #   requests
 charset-normalizer==2.0.7
     # via requests
-docutils==0.17.1
+docutils==0.18.1
     # via
     #   sphinx
     #   sphinx-jsonschema
     #   sphinx-rtd-theme
 idna==2.10
     # via requests
-imagesize==1.2.0
-    # via sphinx
-jinja2==2.11.3
+imagesize==1.4.1
     # via sphinx
-jsonpointer==2.1
+jinja2==3.1.3
+    # via
+    #   -r requirements.in
+    #   sphinx
+jsonpointer==2.3
     # via sphinx-jsonschema
-markupsafe==1.1.1
+markupsafe==2.1.2
     # via jinja2
-packaging==20.9
+packaging==23.0
     # via sphinx
-pygments==2.10.0
+pygments==2.14.0
     # via
     #   -r requirements.in
     #   sphinx
-pyparsing==2.4.7
-    # via packaging
 pytz==2021.3
     # via babel
-pyyaml==5.4.1
+pyyaml==6.0.1
     # via sphinx-jsonschema
 requests==2.26.0
     # via
@@ -45,13 +47,14 @@
     #   sphinx-jsonschema
 snowballstemmer==2.1.0
     # via sphinx
-sphinx==4.2.0
+sphinx==5.3.0
     # via
     #   -r requirements.in
     #   sphinx-rtd-theme
+    #   sphinxnotes-strike
 sphinx-jsonschema==1.16.11
     # via -r requirements.in
-sphinx-rtd-theme==1.0.0
+sphinx-rtd-theme==1.2.0
     # via -r requirements.in
 sphinxcontrib-applehelp==1.0.2
     # via sphinx
@@ -59,12 +62,16 @@
     # via sphinx
 sphinxcontrib-htmlhelp==2.0.0
     # via sphinx
+sphinxcontrib-jquery==2.0.0
+    # via sphinx-rtd-theme
 sphinxcontrib-jsmath==1.0.1
     # via sphinx
 sphinxcontrib-qthelp==1.0.3
     # via sphinx
 sphinxcontrib-serializinghtml==1.1.5
     # via sphinx
+sphinxnotes-strike==1.1
+    # via -r requirements.in
 urllib3==1.26.7
     # via requests
 
diff --git a/cabal/doc/setup-commands.rst b/cabal/doc/setup-commands.rst
--- a/cabal/doc/setup-commands.rst
+++ b/cabal/doc/setup-commands.rst
@@ -790,7 +790,7 @@
 
    Build a static library. This passes ``-staticlib`` to GHC (available
    for iOS, and with 8.4 more platforms).  The result is an archive ``.a``
-   containing all dependent haskell libararies combined.
+   containing all dependent haskell libraries combined.
 
 .. option:: --disable-static
 
@@ -880,37 +880,29 @@
 .. option:: --constraint=constraint
 
     Restrict solutions involving a package to given version
-    bounds, flag settings, and other properties. For example, to
-    consider only install plans that use version 2.1 of ``bar``
-    or do not use ``bar`` at all, write:
+    bounds, flag settings, and other properties.
 
+    The following considers only install plans where ``bar``,
+    if used, is restricted to version 2.1:
+
     ::
 
         $ cabal install --constraint="bar == 2.1"
 
-    Version bounds have the same syntax as :pkg-field:`build-depends`.
-    As a special case, the following prevents ``bar`` from being
-    used at all:
+    The following prevents ``bar`` from being used at all:
 
     ::
 
-        # Note: this is just syntax sugar for '> 1 && < 1', and is
-        # supported by build-depends.
-        $ cabal install --constraint="bar -none"
-
-    You can also specify flag assignments:
-
-    ::
+        $ cabal install --constraint="bar <0"
 
-        # Require bar to be installed with the foo flag turned on and
-        # the baz flag turned off.
-        $ cabal install --constraint="bar +foo -baz"
+    Version bounds have the same syntax as :pkg-field:`build-depends`.
+    Yet extra pseudo version bounds are available here in addition:
 
-    To specify multiple constraints, you may pass the
-    ``constraint`` option multiple times.
+      - ``installed`` to fix a package to the already installed version.
+        Often useful for GHC-supplied packages in combination with :cfg-field:`allow-newer`,
+        e.g., ``--allow-newer='*:base' --constraint='base installed'``.
 
-    There are also some more specialized constraints, which most people
-    don't generally need:
+      - ``source`` to fix a package to the local source copy.
 
     ::
 
@@ -924,9 +916,21 @@
         # specify this.)
         $ cabal install --constraint="bar source"
 
+    Further, we can specify flag assignments with ``+FLAG`` and ``-FLAG``
+    or enable test (``test``) and benchmark (``bench``) suites:
+
+    ::
+
+        # Require bar to be installed with the foo flag turned on and
+        # the baz flag turned off.
+        $ cabal install --constraint="bar +foo -baz"
+
         # Require that bar have test suites and benchmarks enabled.
         $ cabal install --constraint="bar test" --constraint="bar bench"
 
+    To specify multiple constraints, you may pass the
+    ``constraint`` option multiple times.
+
     By default, constraints only apply to build dependencies
     (:pkg-field:`build-depends`), build dependencies of build
     dependencies, and so on. Constraints normally do not apply to
@@ -934,8 +938,8 @@
     (:pkg-field:`custom-setup:setup-depends`) nor do they apply to build tools
     (:pkg-field:`build-tool-depends`) or the dependencies of build
     tools. To explicitly apply a constraint to a setup or build
-    tool dependency, you can add a qualifier to the constraint as
-    follows:
+    tool dependency, you can add a qualifier ``setup`` or ``any``
+    to the constraint as follows:
 
     ::
 
diff --git a/cabal/editors/vim/syntax/cabal.vim b/cabal/editors/vim/syntax/cabal.vim
--- a/cabal/editors/vim/syntax/cabal.vim
+++ b/cabal/editors/vim/syntax/cabal.vim
@@ -160,6 +160,7 @@
   \ DataKinds
   \ DatatypeContexts
   \ DefaultSignatures
+  \ DeepSubsumption
   \ DeriveAnyClass
   \ DeriveDataTypeable
   \ DeriveFoldable
@@ -207,6 +208,7 @@
   \ LexicalNegation
   \ LiberalTypeSynonyms
   \ LinearTypes
+  \ RequiredTypeArguments
   \ MagicHash
   \ MonadComprehensions
   \ MonadFailDesugaring
@@ -265,7 +267,9 @@
   \ TraditionalRecordSyntax
   \ TransformListComp
   \ TupleSections
+  \ TypeAbstractions
   \ TypeApplications
+  \ TypeData
   \ TypeFamilies
   \ TypeFamilyDependencies
   \ TypeInType
@@ -343,6 +347,7 @@
   \ NoLexicalNegation
   \ NoLiberalTypeSynonyms
   \ NoLinearTypes
+  \ NoRequiredTypeArguments
   \ NoMagicHash
   \ NoMonadComprehensions
   \ NoMonadFailDesugaring
@@ -401,6 +406,7 @@
   \ NoTraditionalRecordSyntax
   \ NoTransformListComp
   \ NoTupleSections
+  \ NoTypeAbstractions
   \ NoTypeApplications
   \ NoTypeFamilies
   \ NoTypeFamilyDependencies
diff --git a/cabal/fix-whitespace.yaml b/cabal/fix-whitespace.yaml
new file mode 100644
--- /dev/null
+++ b/cabal/fix-whitespace.yaml
@@ -0,0 +1,137 @@
+# This file contains the project-specific settings for `fix-whitespace` a tiny
+# but useful tool to
+#
+# * Removes trailing whitespace.
+# * Removes trailing lines containing nothing but whitespace.
+# * Ensures that the file ends in a newline character.
+#
+# By default, fix-whitespace checks every directory under the current working
+# directory but no files. This program should be placed under a text-based
+# project.
+#
+# For directories,
+#
+# 1) excluded-dirs is a black-list of directories,
+# 2) included-dirs is a white-list of excluded-dirs
+#
+# For files,
+#
+# 3) included-files is a white-list of files,
+# 4) excluded-files is a black-list of included-files.
+#
+# The extended glob pattern can be used to specify file/direcotory names.
+# For details, see http://hackage.haskell.org/package/filemanip-0.3.6.3/docs/System-FilePath-GlobPattern.html
+#
+included-dirs:
+    # Without this line the above path will be excluded.
+
+excluded-dirs:
+  - "**/dist*"   # matches every dist* in any directory
+  - _darcs
+  - .git
+  - .python-sphinx-virtualenv
+  - .stack-work
+  - .vscode
+
+# Every matched filename is included unless it is matched by excluded-files.
+included-files:
+  - .dockerignore
+  - .gitignore
+  - .gitattributes
+  - AUTHORS
+  - LICENSE
+  - "cabal.project.*"
+  - "*.ac"
+  - "*.bat"
+  - "*.bat_t"
+  - "*.c"
+  - "*.cabal"
+  - "*.cmm"
+  - "*.cobol"
+  - "*.conf"
+  - "*.config"
+  - "*.cfg"
+  - "*.cpp"
+  - "*.csh"
+  - "*.css"
+  - "*.css_t"
+  - "*.dhall"
+  - "*.dockerfile"
+  - "*.el"
+  - "*.h"
+  - "*.hs"
+  - "*.hs-boot"
+  - "*.hsc"
+  - "*.hsig"
+  - "*.html"
+  - "*.html_t"
+  - "*.in"
+  - "*.inc"
+  - "*.js"
+  - "*.js_t"
+  - "*.json"
+  - "*.lhs"
+  - "*.md"
+  - "*.py"
+  - "*.rst"
+  - "*.rst_t"
+  - "*.sh"
+  - "*.sty"
+  - "*.tex"
+  - "*.tex_t"
+  - "*.toml"
+  - "*.txt"
+  - "*.x"
+  - "*.y"
+  - "*.yaml"
+  - "*.yml"
+  - "*.zinza"
+
+excluded-files:
+# Exceptions
+  - Cabal-syntax/src/Distribution/Fields/Lexer.hs
+  - Cabal-tests/tests/ParserTests/warnings/tab.cabal
+  - Cabal-tests/tests/ParserTests/warnings/utf8.cabal
+  - cabal-testsuite/PackageTests/Regression/T8507/pkg.cabal
+
+  # These also contain tabs that affect the golden value:
+  # Could be removed from exceptions, but then the tab warning
+  # has to be removed from the corresponding .format file.
+  - Cabal-tests/tests/ParserTests/regressions/monad-param.cabal
+  - Cabal-tests/tests/ParserTests/regressions/th-lift-instances.cabal
+
+# Files that use tabs
+  - Makefile
+  - GNUmakefile
+  - "*.mk"
+  - .mailmap
+
+# Generated files
+  - TAGS
+  - "*.buildinfo"
+  - "*.check"
+  - "*.expr"
+  - "*.errors"
+  - "*.format"
+  - "*.freeze"
+  - "*.golden"
+  - "*.log"
+  - "*.out"
+
+# Binary files
+  - "*.a"
+  - "*.dylib"
+  - "*.dyn_hi"
+  - "*.dyn_hi-boot"
+  - "*.enc"
+  - "*.exe"
+  - "*.gif"
+  - "*.gz"
+  - "*.hi"
+  - "*.hi-boot"
+  - "*.o"
+  - "*.o-boot"
+  - "*.p_hi"
+  - "*.p_o"
+  - "*.png"
+  - "*.so"
diff --git a/cabal/generics-sop-lens.hs b/cabal/generics-sop-lens.hs
--- a/cabal/generics-sop-lens.hs
+++ b/cabal/generics-sop-lens.hs
@@ -33,7 +33,7 @@
 
 genericLenses
     :: forall a xs proxy. (GDatatypeInfo a, GCode a ~ '[xs], All Typeable xs)
-    => proxy a 
+    => proxy a
     -> String
 genericLenses p = case gdatatypeInfo p of
     Newtype _ _ _                   -> "-- newtype deriving not implemented"
@@ -52,7 +52,7 @@
 
 genericClassyLenses
     :: forall a xs proxy. (GDatatypeInfo a, GCode a ~ '[xs], All Typeable xs)
-    => proxy a 
+    => proxy a
     -> String
 genericClassyLenses p = case gdatatypeInfo p of
     Newtype _ _ _                   -> "-- newtype deriving not implemented"
diff --git a/cabal/license-list-data/exceptions-3.0.json b/cabal/license-list-data/exceptions-3.0.json
--- a/cabal/license-list-data/exceptions-3.0.json
+++ b/cabal/license-list-data/exceptions-3.0.json
diff --git a/cabal/license-list-data/exceptions-3.10.json b/cabal/license-list-data/exceptions-3.10.json
--- a/cabal/license-list-data/exceptions-3.10.json
+++ b/cabal/license-list-data/exceptions-3.10.json
diff --git a/cabal/license-list-data/exceptions-3.16.json b/cabal/license-list-data/exceptions-3.16.json
--- a/cabal/license-list-data/exceptions-3.16.json
+++ b/cabal/license-list-data/exceptions-3.16.json
diff --git a/cabal/license-list-data/exceptions-3.2.json b/cabal/license-list-data/exceptions-3.2.json
--- a/cabal/license-list-data/exceptions-3.2.json
+++ b/cabal/license-list-data/exceptions-3.2.json
diff --git a/cabal/license-list-data/exceptions-3.6.json b/cabal/license-list-data/exceptions-3.6.json
--- a/cabal/license-list-data/exceptions-3.6.json
+++ b/cabal/license-list-data/exceptions-3.6.json
diff --git a/cabal/license-list-data/exceptions-3.9.json b/cabal/license-list-data/exceptions-3.9.json
--- a/cabal/license-list-data/exceptions-3.9.json
+++ b/cabal/license-list-data/exceptions-3.9.json
diff --git a/cabal/license-list-data/licenses-3.0.json b/cabal/license-list-data/licenses-3.0.json
--- a/cabal/license-list-data/licenses-3.0.json
+++ b/cabal/license-list-data/licenses-3.0.json
diff --git a/cabal/license-list-data/licenses-3.10.json b/cabal/license-list-data/licenses-3.10.json
--- a/cabal/license-list-data/licenses-3.10.json
+++ b/cabal/license-list-data/licenses-3.10.json
diff --git a/cabal/license-list-data/licenses-3.16.json b/cabal/license-list-data/licenses-3.16.json
--- a/cabal/license-list-data/licenses-3.16.json
+++ b/cabal/license-list-data/licenses-3.16.json
diff --git a/cabal/license-list-data/licenses-3.2.json b/cabal/license-list-data/licenses-3.2.json
--- a/cabal/license-list-data/licenses-3.2.json
+++ b/cabal/license-list-data/licenses-3.2.json
diff --git a/cabal/license-list-data/licenses-3.6.json b/cabal/license-list-data/licenses-3.6.json
--- a/cabal/license-list-data/licenses-3.6.json
+++ b/cabal/license-list-data/licenses-3.6.json
diff --git a/cabal/license-list-data/licenses-3.9.json b/cabal/license-list-data/licenses-3.9.json
--- a/cabal/license-list-data/licenses-3.9.json
+++ b/cabal/license-list-data/licenses-3.9.json
diff --git a/cabal/release-notes/Cabal-3.10.1.0.md b/cabal/release-notes/Cabal-3.10.1.0.md
new file mode 100644
--- /dev/null
+++ b/cabal/release-notes/Cabal-3.10.1.0.md
@@ -0,0 +1,145 @@
+Cabal and Cabal-syntax 3.10.1.0 changelog and release notes
+---
+
+Release 3.10.1.0 of cabal now sets the `--enable-documentation` option by default
+when running `cabal haddock` (https://github.com/haskell/cabal/issues/7462).
+If the new default does not fit your workflow, pass an explicit `--disable-documentation`
+option or consider (helping to implement) the other workarounds proposed
+in https://github.com/haskell/cabal/issues/8725.
+
+This version of cabal introduces support for JS cross-compilation (https://github.com/haskell/cabal/pull/8636).
+We've seen related Windows segfaults on CI, so please kindly report if you can reproduce either
+cabal or GHC segfaults when cross-compiling for JS or compiling normally but with any files
+listed in the `js-sources` field of a .cabal file.
+
+This release of cabal also fixes a lot of bugs in cabal 3.8.1.0 and not all of the fixes
+are listed here.
+
+
+### Significant changes
+
+- Add support for the XDG Base Directory Specification [#680](https://github.com/haskell/cabal/issues/680) [#7386](https://github.com/haskell/cabal/pull/7386)
+
+  Cabal/cabal-install now uses the XDG Base Directory Specification to
+  store configuration, caches, and the store.  Specifically,
+  `$XDG_CONFIG_HOME/cabal` stores the configuration file,
+  `$XDG_CACHE_HOME/cabal` stores downloaded packages and similar, and
+  `$XDG_STATE_HOME/cabal` mainly contains the store of compiled
+  packages.  Further, `cabal install` will put executables in
+  `~/.local/bin` by default.
+
+  The `dist`/`dist-newstyle` directories are not affected.
+
+  On Windows, these XDG paths are mapped to other (hopefully)
+  appropriate locations.  See the Cabal User Guide for information.
+
+  If the `CABAL_DIR` environment variable is set, the indicated
+  directory will be used to store all Cabal-related files, as in
+  previous versions.
+
+  **Backwards compatibility**: If `~/.cabal` already exists, this will be
+  interpreted as `CABAL_DIR=~/.cabal`.  This means that upgrading on an
+  existing system already using cabal-install should not cause any
+  change in behaviour.  An existing system can be migrated by deleting
+  `~/.cabal` (possibly copying `~/.cabal/config` to
+  `~/.config/cabal/config` first).
+
+- Add `PackageInfo_` module [#8534](https://github.com/haskell/cabal/pull/8534)
+
+  - Add `PackageInfo_` module to embed portable package-related informations (issue #3909)
+
+- *Cabal-syntax* Add language extensions `DeepSubsumption` and `TypeData` [#8493](https://github.com/haskell/cabal/pull/8493)
+
+  - adds support for the `DeepSubsumption` language extension ([GHC proposal #511](https://github.com/ghc-proposals/ghc-proposals/pull/511))
+  - adds support for the `TypeData` language extension ([GHC proposal #106](https://github.com/ghc-proposals/ghc-proposals/pull/106))
+
+- Add support for GHC 9.4+ `-fprof-late` flag. [#8528](https://github.com/haskell/cabal/pull/8528)
+
+- This adds the new `late-toplevel` (and its alias `late`) profiling-detail option which enables `-fprof-late`-based automatic cost centre annotations for GHCs that support it ([earliest is GHC 9.4.1](https://downloads.haskell.org/ghc/9.4.1/docs/users_guide/profiling.html#ghc-flag--fprof-late)).
+
+
+### Other changes
+
+- Remove "'-main-is' is not portable" check [#8646](https://github.com/haskell/cabal/issues/8646) [#8651](https://github.com/haskell/cabal/pull/8651)
+
+  `cabal check` no longer complains about `-main-is` flag in `ghc-options`
+
+- Fix generation of Path_ modules with relocatable [#8219](https://github.com/haskell/cabal/issues/8219) [#8220](https://github.com/haskell/cabal/pull/8220)
+
+  The generation of the functions `minusFileName` and `splitFileName`
+  are now in the same conditional block as their call,
+  preventing generation of inconsistent Paths_ files
+  where those functions are used but not defined.
+
+- Remove warning on option -threaded when building libraries [#774](https://github.com/haskell/cabal/issues/774) [#8431](https://github.com/haskell/cabal/issues/8431) [#8432](https://github.com/haskell/cabal/pull/8432)
+
+  - Accompanied by option `-flink-rts`, option `-threaded` defines the flavour of
+    the ghc RTS library the built library will be linked against. Note that bare
+    ghc does not warn when option `-threaded` is used for building a library
+    either.
+  - Note that the changes require modification of the regression check for issue
+    #774 which can be regarded as a proper test for this PR.
+
+- Add warning about expensive globs [#5311](https://github.com/haskell/cabal/issues/5311) [#8441](https://github.com/haskell/cabal/pull/8441)
+
+  - Now cabal check will emit a warning when package uses
+  recursive globs starting at root of the project
+
+- Order `extra*` stanzas [#8458](https://github.com/haskell/cabal/issues/8458) [#8499](https://github.com/haskell/cabal/pull/8499)
+
+  Ensure that `extra-src-dirs`, extra sources, and extra other modules all are added using `ordNub` rather than incidentally alphabetized.
+
+- Prepend rather than append `extra-prog-path` [#6304](https://github.com/haskell/cabal/issues/6304) [#8506](https://github.com/haskell/cabal/pull/8506)
+
+  Prepends the `extra-prog-path` to the system path rather than appending, to allow binaries in the extra path to override defaults.
+
+- don't send non-extant `extra-lib-dirs` to GHC [#6492](https://github.com/haskell/cabal/issues/6492) [#8510](https://github.com/haskell/cabal/pull/8510)
+
+  If an extra-libs-dir does not exist, it does not get sent to ghc, which can error on windows.
+
+- Improve mutually recursive unit identifier error message [#8582](https://github.com/haskell/cabal/pull/8582)
+
+  Improves the error message in case of mutually recursive unit identifiers
+  by specifying the name of the identifier, the name of the signature, and a suggestion
+  to check the 'build-depends:' section.
+
+- Specify default exe extension on wasm32 to be .wasm [#8633](https://github.com/haskell/cabal/pull/8633)
+
+  Specify default exe extension on wasm32 to be .wasm, following the convention in other WebAssembly toolchains.
+
+- Support `js-sources` with GHC, not only with GHCJS [#8636](https://github.com/haskell/cabal/pull/8636)
+
+  - Take into account js-sources when building library components with GHC
+  - Missing support for js-sources in executable components is tracked in #8639
+
+- Tiny refactor of how Cabal handles configure scripts [#8648](https://github.com/haskell/cabal/pull/8648)
+
+  None of this is visible downstream
+
+  - Remove needless parameter on one private function.
+
+  - Move another internal function (and ones that only it uses from the same module) to new private module.
+
+- Warn if expected files are omitted from extra-doc-files [#3964](https://github.com/haskell/cabal/issues/3964) [#8657](https://github.com/haskell/cabal/pull/8657)
+
+  - Emit a warning if there exist a “changelog” file at the root of the
+    package which is not included in any field.
+  - Emit a warning if a “changelog” file at the root of the package is included
+    in a field different from “extra-doc-files” (Cabal spec >= 1.18) or
+    “extra-source-files” (spec < 1.18).
+
+- Disallow GHC <8.0 for  [#7531](https://github.com/haskell/cabal/issues/7531) [#8715](https://github.com/haskell/cabal/issues/8715) [#8794](https://github.com/haskell/cabal/pull/8794)
+
+  Disallow GHC <8.0 by restricting the version of base that can be used to at least 4.9
+
+- Avoid spurious warnings from -with-rtsopts [#4255](https://github.com/haskell/cabal/issues/4255) [#8183](https://github.com/haskell/cabal/pull/8183)
+
+- Do not print "up to date" for commands unless running "cabal build" [#4994](https://github.com/haskell/cabal/issues/4994) [#8569](https://github.com/haskell/cabal/pull/8569)
+
+- The `configure` script of `build-type: configure` packages now has access to the flag assignment of the package being built via the `CABAL_FLAGS` and `CABAL_FLAG_<flag>` environment variables [#8564](https://github.com/haskell/cabal/issues/8564) [#8565](https://github.com/haskell/cabal/pull/8565)
+
+- Export pretty printer `ppPackageCheck` from [#8311](https://github.com/haskell/cabal/pull/8311)
+
+- Add check for upper bound on any dependency in `cabal check` [#8291](https://github.com/haskell/cabal/issues/8291) [#8339](https://github.com/haskell/cabal/pull/8339)
+
+- *Cabal-syntax* Relax language selection parsing in `cabal init` [#8278](https://github.com/haskell/cabal/issues/8278) [#8281](https://github.com/haskell/cabal/pull/8281)
diff --git a/cabal/release-notes/Cabal-3.10.2.0.md b/cabal/release-notes/Cabal-3.10.2.0.md
new file mode 100644
--- /dev/null
+++ b/cabal/release-notes/Cabal-3.10.2.0.md
@@ -0,0 +1,26 @@
+Cabal and Cabal-syntax 3.10.2.0 changelog and release notes
+---
+
+## Release 3.10.2.0 is strictly a bug-fix release, with the fixes listed below
+
+- Shorten script-builds paths [#8841](https://github.com/haskell/cabal/issues/8841) [#8898](https://github.com/haskell/cabal/pull/8898)
+
+  - Use Base64 hash truncated to 26 chars for script-build cache directories.
+  - Use the cache directory as the dist directory.
+  - Use script-<your-sanitized-script-name> as the component name instead of cabal-script-<...>.
+  - Use cabal-script-<your-actual-script-name> for the executable name.
+  - This change is incompatible with previous cabal versions in terms of cache location,
+    you should manually remove your old caches once you no longer need them.
+
+- Do not always pass --quickjump to haddock #9049 [#9060](https://github.com/haskell/cabal/issues/9060) [#9049](https://github.com/haskell/cabal/pull/9049)
+
+  6d8adf13101 caused `cabal` to always pass the `--quickjump` flag to Haddock.
+  Not only does this waste memory for a service that user hasn't asked for,
+  but also leads to a failure with Haddocks shipped with GHC 9.0 and 9.2,
+  which had a separate bug (fixed in later versions but not backported) when
+  Haddock does not pass `--quickjump` recursively to the package dependencies.
+
+- Regenerate Lexer.hs to avoid out-of-bound array access due to a bug in Alex [#8892](https://github.com/haskell/cabal/issues/8892) [#8896](https://github.com/haskell/cabal/pull/8896)
+
+  - Regenerate Cabal-syntax's Lexer.hs with Alex 3.2.7.3 which includes a fix for
+    an out-of-bound array access (only noticeable with GHC's JavaScript backend).
diff --git a/cabal/release-notes/Cabal-3.10.2.1.md b/cabal/release-notes/Cabal-3.10.2.1.md
new file mode 100644
--- /dev/null
+++ b/cabal/release-notes/Cabal-3.10.2.1.md
@@ -0,0 +1,9 @@
+Cabal and Cabal-syntax 3.10.2.1 changelog and release notes
+---
+
+## Release 3.10.2.1 is strictly a bug-fix release, with the fixes listed below
+
+- Relax extension .c requirement for c-sources [#9285](https://github.com/haskell/cabal/pull/9285)
+
+We will be tightening the behaviour of Cabal in the future, when users list files ending with extensions other than `.c` in the `c-sources` field of their cabal file. These files were never processed properly.
+This PR displays more warnings and prepares the transition.
diff --git a/cabal/release-notes/Cabal-3.10.3.0.md b/cabal/release-notes/Cabal-3.10.3.0.md
new file mode 100644
--- /dev/null
+++ b/cabal/release-notes/Cabal-3.10.3.0.md
@@ -0,0 +1,15 @@
+Cabal and Cabal-syntax 3.10.3.0 changelog and release notes
+---
+
+## Release 3.10.3.0 is strictly a bug-fix release, with the fixes listed below
+
+- PkgConfig environment variables [#9134](https://github.com/haskell/cabal/pull/9134)
+  - `cabal` invokes `pkg-config` with `PKG_CONFIG_ALLOW_SYSTEM_CFLAGS` and `PKG_CONFIG_ALLOW_SYSTEM_LIBS` set
+
+- Support text-2.1 in Cabal and Cabal-syntax [#9242](https://github.com/haskell/cabal/pull/9242)
+
+- Fix extra-prog-path propagation [#7649](https://github.com/haskell/cabal/issues/7649) [#9519](https://github.com/haskell/cabal/issues/9519) [#9527](https://github.com/haskell/cabal/pull/9527)
+  - extra-prog-paths are now propagated to all commands. This in particular helps
+    when running a MinGW cabal in the PowerShell, where the MSYS2 paths are
+    usually not available in the PowerShell PATH. GHCup already sets them up for
+    us but they were sometimes lost on the way.
diff --git a/cabal/release-notes/Cabal-3.4.0.0.md b/cabal/release-notes/Cabal-3.4.0.0.md
--- a/cabal/release-notes/Cabal-3.4.0.0.md
+++ b/cabal/release-notes/Cabal-3.4.0.0.md
@@ -1,55 +1,55 @@
 ### Significant changes
 
 - Add cabal-version: 3.4 [!6663](https://github.com/haskell/cabal/pull/6663)
-  
+
   See various changes in https://cabal.readthedocs.io/en/latest/file-format-changelog.html#cabal-version-3-4
-  
+
 - Support GHC-9.0 [#6903](https://github.com/haskell/cabal/issues/6903) [#6904](https://github.com/haskell/cabal/issues/6904) [#6905](https://github.com/haskell/cabal/issues/6905) [!6545](https://github.com/haskell/cabal/pull/6545) [!6552](https://github.com/haskell/cabal/pull/6552) [!6553](https://github.com/haskell/cabal/pull/6553) [!6563](https://github.com/haskell/cabal/pull/6563) [!6735](https://github.com/haskell/cabal/pull/6735) [!6844](https://github.com/haskell/cabal/pull/6844) [!6848](https://github.com/haskell/cabal/pull/6848) [!6865](https://github.com/haskell/cabal/pull/6865) [!6908](https://github.com/haskell/cabal/pull/6908) [!6947](https://github.com/haskell/cabal/pull/6947)
-  
+
   - Support for `-this-package-key` deprecation
   - Use process `createPipe`
   - Add support for WINIO to Cabal
-  - Adopt to simplfied subsumption changes
-  
+  - Adopt to simplified subsumption changes
+
   There are no magical `IO = WithCallStack Prelude.IO` alias in Cabal,
   as it is hard to get working with GHC-9.0's simplified subsumption.
-  
+
 - Treat `pkg:sublib` dependency syntax as is in `cabal-version: 3.4` [#6083](https://github.com/haskell/cabal/issues/6083) [!6893](https://github.com/haskell/cabal/pull/6893) [!6907](https://github.com/haskell/cabal/pull/6907)
-  
+
   In `cabal-version: 3.4` cabal files the dependency definition
-  
+
   ```cabal
   build-depends: somesublib
   ```
-  
+
   does not use in-package sublibraries. You have to be explicit and write
-  
+
   ```cabal
   build-depends: thispkg:somesublib
   ```
-  
+
   This fixes an issue where it was impossible to refer to an external
   library if you had a sublibrary of the same name.
-  
+
 - Dependency type refactorings [#5570](https://github.com/haskell/cabal/issues/5570) [#6894](https://github.com/haskell/cabal/issues/6894) [!6768](https://github.com/haskell/cabal/pull/6768) [!6798](https://github.com/haskell/cabal/pull/6798) [!6895](https://github.com/haskell/cabal/pull/6895) [!6896](https://github.com/haskell/cabal/pull/6896) [!6897](https://github.com/haskell/cabal/pull/6897) [!6898](https://github.com/haskell/cabal/pull/6898)
-  
+
   With additions of (public) sublibraries, `Dependency` type use for multiple needs become painful.
   Therefore a new type `PackageVersionConstraint` was added to serve *constraint on package* use-case.
   `Dependency` type is *dependency on a library component*, i.e. representing `build-depends` entry.
-  
+
   - Use PackageVersionConstraint more
   - Add NonEmptySet and use it in Dependency
-  
+
 ### Other changes
 
 - Tests additions [#6409](https://github.com/haskell/cabal/issues/6409) [!6753](https://github.com/haskell/cabal/pull/6753) [!6759](https://github.com/haskell/cabal/pull/6759) [!6802](https://github.com/haskell/cabal/pull/6802) [!6842](https://github.com/haskell/cabal/pull/6842) [!6872](https://github.com/haskell/cabal/pull/6872)
-  
+
   - Add shrinker, so writing big non-generic product shrinkers is easier
   - Add `hs-source-dirs: NL .` test-case
   - Add public multilib test(s)
-  
+
 - Code organization [!6599](https://github.com/haskell/cabal/pull/6599) [!6642](https://github.com/haskell/cabal/pull/6642) [!6734](https://github.com/haskell/cabal/pull/6734) [!6745](https://github.com/haskell/cabal/pull/6745) [!6746](https://github.com/haskell/cabal/pull/6746) [!6817](https://github.com/haskell/cabal/pull/6817) [!6818](https://github.com/haskell/cabal/pull/6818) [!6821](https://github.com/haskell/cabal/pull/6821) [!6867](https://github.com/haskell/cabal/pull/6867)
-  
+
   - Split `Distribution.Client.Types` module
   - Move cabal-testsuite code into `src/`
   - Add `ProjectFlags`
@@ -59,45 +59,45 @@
   - Make cabal-install compilable with `NoImplicitPrelude`
   - Refactor shared `TargetProblem` data types into their own module.
   - Template `cabal-install.cabal` using zinza
-  
+
 - The grammar of most package description fields is formally documented [!6591](https://github.com/haskell/cabal/pull/6591) [!6593](https://github.com/haskell/cabal/pull/6593) [!6704](https://github.com/haskell/cabal/pull/6704) [!6766](https://github.com/haskell/cabal/pull/6766) [!6778](https://github.com/haskell/cabal/pull/6778) [!6780](https://github.com/haskell/cabal/pull/6780) [!6781](https://github.com/haskell/cabal/pull/6781) [!6791](https://github.com/haskell/cabal/pull/6791) [!6800](https://github.com/haskell/cabal/pull/6800)
-  
+
   See https://cabal.readthedocs.io/en/latest/buildinfo-fields-reference.html
-  
+
 - Fix ghci being launched before other sources are built. [!6923](https://github.com/haskell/cabal/pull/6923)
-  
+
   Related to foreign calls to C-sources.
-  
+
 - Remove `-any` and `-none` syntax for version ranges in cabal-version: 3.4 [#6589](https://github.com/haskell/cabal/issues/6589) [!6786](https://github.com/haskell/cabal/pull/6786)
-  
+
   Use `>=0` (or empty in dependencies) and `<0` respectively.
-  
+
 - Add pijul to known repository type [#6610](https://github.com/haskell/cabal/issues/6610) [!6684](https://github.com/haskell/cabal/pull/6684)
-  
+
   Pijul is now explicitly recognized version control system.
   However `cabal-install` isn't yet able to use it in
   `source-repository-package`.
-  
+
 - Rename Flag to CompilerFlag and PackageFlag [#6710](https://github.com/haskell/cabal/issues/6710) [!6725](https://github.com/haskell/cabal/pull/6725)
-  
+
   There was three Flag's. Now they are
-  
+
   - `Flag` (cli parsing)
   - `PackageFlag`
   - `CompilerFlag`
-  
+
   This allows wild-imports without `hiding (Flag)`.
-  
+
 - Accept "linux-androideabi" as an alias for Android for determining buildOS [!6301](https://github.com/haskell/cabal/pull/6301) [!6949](https://github.com/haskell/cabal/pull/6949)
-  
+
   `Cabal` will able to parse `linux-androideabi` from the value of `System.Info.os`.
-  
+
 - Refactor Distribution.PackageDescription module [!6855](https://github.com/haskell/cabal/pull/6855)
-  
+
   Now it re-exports a collection of modules, not individual symbols.
-  
+
 - Use process jobs when spawning subprocesses [!6529](https://github.com/haskell/cabal/pull/6529) [!6536](https://github.com/haskell/cabal/pull/6536)
-  
+
   Many toolchain tools written for POSIX systems rely on the exec system
   call. Unfortunately, it is not possible to implement exec in a
   POSIX-compliant manner on Windows. In particular, the semantics of the
@@ -105,21 +105,21 @@
   will cause process's waiting on the exec'ing process to incorrectly
   conclude that the process has successfully terminated when in fact it is
   still running in another process.
-  
+
   For this reason, the process library exposes the use_process_jobs
   flag to use a more strict (although still not POSIX-compliant) mechanism
   for tracking process completion.
   This is explained in [the Process.hs comment](https://github.com/haskell/process/blob/master/System/Process.hs#L399)
-  
+
   Unfortunately, job support in the process library is currently quite
   broken and was only recently fixed. Consequently, we only enable job
   object support for process releases >= 1.6.8.
-  
+
 - Remove `AnyVersion` and `WildcardVersion` constructors from `Version` [!6742](https://github.com/haskell/cabal/pull/6742)
-  
+
   This changes makes `Version` type less "syntactic",
   i.e. contains less constructors for semantically same version ranges.
-  
+
 - Cabal-QuickCheck package with `Arbitrary` instances [#6882](https://github.com/haskell/cabal/issues/6882) [!6557](https://github.com/haskell/cabal/pull/6557) [!6891](https://github.com/haskell/cabal/pull/6891)
 - Create Cabal-tree-diff package with `ToExpr` instances [!6789](https://github.com/haskell/cabal/pull/6789)
 - `Cabal.Distribution.Compiler`: add `Traversable` instance for `PerCompilerFlavor` [!6763](https://github.com/haskell/cabal/pull/6763)
@@ -131,7 +131,7 @@
 - default-language field is optional in cabal-version: 3.4 [#6288](https://github.com/haskell/cabal/issues/6288) [!6924](https://github.com/haskell/cabal/pull/6924) [!6926](https://github.com/haskell/cabal/pull/6926)
 - Split `KnownRepoType` out of `RepoType` [#6432](https://github.com/haskell/cabal/issues/6432) [!6612](https://github.com/haskell/cabal/pull/6612)
 - Include component name in unit-id [#6485](https://github.com/haskell/cabal/issues/6485) [!6547](https://github.com/haskell/cabal/pull/6547)
-- Change 'optional-packages' default to empty, when cabal.project is mising. [#4797](https://github.com/haskell/cabal/issues/4797) [#6739](https://github.com/haskell/cabal/issues/6739) [!6740](https://github.com/haskell/cabal/pull/6740)
+- Change 'optional-packages' default to empty, when cabal.project is missing. [#4797](https://github.com/haskell/cabal/issues/4797) [#6739](https://github.com/haskell/cabal/issues/6739) [!6740](https://github.com/haskell/cabal/pull/6740)
 - Fix rpmvercmp (trailing non-digit characters) [#6805](https://github.com/haskell/cabal/issues/6805) [!6808](https://github.com/haskell/cabal/pull/6808)
 - other changes [!6556](https://github.com/haskell/cabal/pull/6556) [!6598](https://github.com/haskell/cabal/pull/6598) [!6910](https://github.com/haskell/cabal/pull/6910)
 - Package description parser benchmark [!6594](https://github.com/haskell/cabal/pull/6594)
diff --git a/cabal/release-notes/Cabal-3.6.1.0.md b/cabal/release-notes/Cabal-3.6.1.0.md
--- a/cabal/release-notes/Cabal-3.6.1.0.md
+++ b/cabal/release-notes/Cabal-3.6.1.0.md
@@ -33,15 +33,15 @@
   As such, this patch provides a workaround for
   older, already existing GHC versions by first always
   following the symbolic link of the ghc binary (if it is one)
-  and prefering its target directory as the guess lookup
+  and preferring its target directory as the guess lookup
   location.
 
   Rationale
 
   The canonicalized path of the ghc binary usually points to the
   bin/ directory unpacked from a bindist, which is less likely to be
-  tampered with by distributions and tools. As such, prefering the
-  canoncialized path should get us more robust results.
+  tampered with by distributions and tools. As such, preferring the
+  canonicalized path should get us more robust results.
 
 - Fix `cabal test --enable-library-coverage` for other-modules [#5213](https://github.com/haskell/cabal/issues/5213) [#7493](https://github.com/haskell/cabal/pull/7493)
 
diff --git a/cabal/release-notes/Cabal-3.8.0.20220526.md b/cabal/release-notes/Cabal-3.8.0.20220526.md
--- a/cabal/release-notes/Cabal-3.8.0.20220526.md
+++ b/cabal/release-notes/Cabal-3.8.0.20220526.md
@@ -105,7 +105,7 @@
 
   - Make builds that use experimental Cabal language features less noisy. At -v1
     (normal) we show just first instance of use of experimental cabal language
-  features, along with count of further occurences in the same file.
+  features, along with count of further occurrences in the same file.
 
 - Fix Cabal not finding public sublibraries of installed packages [#7270](https://github.com/haskell/cabal/issues/7270) [#8089](https://github.com/haskell/cabal/pull/8089)
 
@@ -135,7 +135,7 @@
 - Add "prompt" strategy when symlinking binaries. [#5672](https://github.com/haskell/cabal/pull/5672)
 - Add fields extra-libraries-static and extra-lib-dirs-static [#6688](https://github.com/haskell/cabal/issues/6688) [#7399](https://github.com/haskell/cabal/issues/7399) [#7536](https://github.com/haskell/cabal/pull/7536)
 - Paths passed to GHC are now relative to the current working directory
-- Autoatically pipe auth from repo uris into curl transport. [#4743](https://github.com/haskell/cabal/issues/4743) [#7630](https://github.com/haskell/cabal/pull/7630)
+- Automatically pipe auth from repo uris into curl transport. [#4743](https://github.com/haskell/cabal/issues/4743) [#7630](https://github.com/haskell/cabal/pull/7630)
 - raise lower bound of process and remove compatibility shims [#7922](https://github.com/haskell/cabal/pull/7922)
 - changes the cabal check warning about long synopsis, so it warns only synopsis bigger than the set size [#7932](https://github.com/haskell/cabal/issues/7932) [#7933](https://github.com/haskell/cabal/pull/7933)
 - Remove bootstrapping plan files from version control, and simplify bootstrap update Makefile targets. [#7949](https://github.com/haskell/cabal/pull/7949)
diff --git a/cabal/release-notes/Cabal-3.8.1.0.md b/cabal/release-notes/Cabal-3.8.1.0.md
--- a/cabal/release-notes/Cabal-3.8.1.0.md
+++ b/cabal/release-notes/Cabal-3.8.1.0.md
@@ -78,7 +78,7 @@
 
   - Make builds that use experimental Cabal language features less noisy. At -v1
     (normal) we show just first instance of use of experimental cabal language
-  features, along with count of further occurences in the same file.
+  features, along with count of further occurrences in the same file.
 
 - Fix Cabal not finding public sublibraries of installed packages [#7270](https://github.com/haskell/cabal/issues/7270) [#8089](https://github.com/haskell/cabal/pull/8089)
 
diff --git a/cabal/release-notes/cabal-install-3.10.1.0.md b/cabal/release-notes/cabal-install-3.10.1.0.md
new file mode 100644
--- /dev/null
+++ b/cabal/release-notes/cabal-install-3.10.1.0.md
@@ -0,0 +1,213 @@
+cabal-install and cabal-install-solver 3.10.1.0 changelog and release notes
+---
+
+Release 3.10.1.0 of cabal now sets the `--enable-documentation` option by default
+when running `cabal haddock` (https://github.com/haskell/cabal/issues/7462).
+If the new default does not fit your workflow, pass an explicit `--disable-documentation`
+option or consider (helping to implement) the other workarounds proposed
+in https://github.com/haskell/cabal/issues/8725.
+
+This version of cabal introduces support for JS cross-compilation (https://github.com/haskell/cabal/pull/8636).
+We've seen related Windows segfaults on CI, so please kindly report if you can reproduce either
+cabal or GHC segfaults when cross-compiling for JS or compiling normally but with any files
+listed in the `js-sources` field of a .cabal file.
+
+This release of cabal also fixes a lot of bugs in cabal 3.8.1.0 and not all of the fixes
+are listed here.
+
+
+### Significant changes
+
+- `Cabal-3.10.1.0` is used, which brings [its own set of changes](./Cabal-3.10.1.0.md),
+  many of which are significant. The Cabal and Cabal-syntax changes that touch
+  the cabal-install or cabal-install-solver codebases are pasted here again in full.
+
+- Add support for the XDG Base Directory Specification [#680](https://github.com/haskell/cabal/issues/680) [#7386](https://github.com/haskell/cabal/pull/7386)
+
+  Cabal/cabal-install now uses the XDG Base Directory Specification to
+  store configuration, caches, and the store.  Specifically,
+  `$XDG_CONFIG_HOME/cabal` stores the configuration file,
+  `$XDG_CACHE_HOME/cabal` stores downloaded packages and similar, and
+  `$XDG_STATE_HOME/cabal` mainly contains the store of compiled
+  packages.  Further, `cabal install` will put executables in
+  `~/.local/bin` by default.
+
+  The `dist`/`dist-newstyle` directories are not affected.
+
+  On Windows, these XDG paths are mapped to other (hopefully)
+  appropriate locations.  See the Cabal User Guide for information.
+
+  If the `CABAL_DIR` environment variable is set, the indicated
+  directory will be used to store all Cabal-related files, as in
+  previous versions.
+
+  **Backwards compatibility**: If `~/.cabal` already exists, this will be
+  interpreted as `CABAL_DIR=~/.cabal`.  This means that upgrading on an
+  existing system already using cabal-install should not cause any
+  change in behaviour.  An existing system can be migrated by deleting
+  `~/.cabal` (possibly copying `~/.cabal/config` to
+  `~/.config/cabal/config` first).
+
+- Add `installDirs` (`datadir`, etc) to v2-build and remove them from v2-install [#8556](https://github.com/haskell/cabal/pull/8556)
+
+  - Passes through `--prefix`, `--datadir` and other `installdir`-arguments properly in v2-build, allowing its use in preparing somewhat more relocatable compilation targets (no worse than v1-build).
+  - Removes these flags (which never worked) from v2-install
+
+- No global packages auto written to environment files, allow `--force-reinstalls` [#5559](https://github.com/haskell/cabal/issues/5559) [#6165](https://github.com/haskell/cabal/issues/6165) [#8607](https://github.com/haskell/cabal/pull/8607)
+
+  - When v2-install runs on a library, it does not pin global packages in the env file, only those directly necessary for the library.
+
+- Add support for GHC 9.4+ `-fprof-late` flag [#8528](https://github.com/haskell/cabal/pull/8528)
+
+  - This adds the new `late-toplevel` (and its alias `late`) profiling-detail option which enables `-fprof-late`-based automatic cost centre annotations for GHCs that support it ([earliest is GHC 9.4.1](https://downloads.haskell.org/ghc/9.4.1/docs/users_guide/profiling.html#ghc-flag--fprof-late)).
+
+- Added `haddock-project` command [#7669](https://github.com/haskell/cabal/issues/7669) [#8162](https://github.com/haskell/cabal/pull/8162)
+
+  The `haddock-project` command can be used to build documentation of multiple
+  packages.  By passing `--local` option the directory will be self contained,
+  by passing `--hackage` links to dependencies will link to `hackage`.  Both
+  `--local` and `--hackage` options imply `--quickfix`, `--gen-index`,
+  `--gen-contents`, and `--hyperlinked-source`.
+
+  Building self contained directory is the default, unless `--hackage` or
+  `--html-location`.
+
+  The PR #8162 also fixes the `--with-haddock` option.
+
+
+### Other changes
+
+- Pretty-print run targets on failure [#8189](https://github.com/haskell/cabal/issues/8189) [#8234](https://github.com/haskell/cabal/pull/8234)
+
+  - Targets of the `run` command are pretty-printed when failing due to multiple targets.
+  - Duplicate targets are removed in the output.
+
+- Expose `BuildFlags` and `ClientHaddockFlags` [#8351](https://github.com/haskell/cabal/issues/8351) [#8353](https://github.com/haskell/cabal/pull/8353)
+
+  Some types are present in public functions in cabal-install, but they are not exported.
+  This PR fix it for BuildFlags and ClientHaddockFlags.
+
+- `cabal man` handles `$PAGER` containing arguments now [#8405](https://github.com/haskell/cabal/issues/8405) [#8353](https://github.com/haskell/cabal/pull/8353)
+
+  Things like `PAGER="less -FX" cabal man` work now.
+
+  There's a slight change in the default behavior. We still use `less -R` as the default,
+  but if the user passes `PAGER=less`, we won't add -R to that, unlike before. This is
+  reasonable, as the user should be able to set the variable as they see fit.
+
+- Fix issue with "nix" config option [#8452](https://github.com/haskell/cabal/issues/8452) [#8522](https://github.com/haskell/cabal/pull/8522)
+
+  Nix option in config file was broken with [#8054](https://github.com/haskell/cabal/pull/8054), this should fix it.
+
+- "Build profile" message now reflects optimization level set in global config [#8487](https://github.com/haskell/cabal/issues/8487) [#8488](https://github.com/haskell/cabal/pull/8488)
+
+  Imagine you have `optimization: 2` in your `~/.cabal/config`, and you call `cabal build`
+  in a project that doesn't have optimization level explicitly set in its project file.
+  You will still see 'Build profile: -w ghc-<VER> -O1'. This is incorrect and was fixed
+  in this patch: now you'll see '-O2'.
+
+- `ghc`, `ghc-boot`, `ghci` packages should be non-upgradable [#8489](https://github.com/haskell/cabal/issues/8489) [#8501](https://github.com/haskell/cabal/pull/8501)
+
+  - Changed both `Distribution.Client.Dependency`'s `dontUpgradeNonUpgradeablePackages`
+    and `Distribution.Solver.Modular.Solver`'s `nonInstallable` to be in sync.
+
+- Apply command line flags to install packages [#8637](https://github.com/haskell/cabal/issues/8637) [#8779](https://github.com/haskell/cabal/pull/8779)
+
+  - Command line flags usually only apply to "local" packages (packages specified
+    in the cabal.project). This change causes the v2-install command to ignore
+    that distinction to better match the expected behavior for packages specified
+    directly in the command.
+
+- Print a warning when assertions are enabled [#4377](https://github.com/haskell/cabal/issues/4377) [#8240](https://github.com/haskell/cabal/pull/8240)
+
+  - Now cabal-install executable will print a warning if assertions are enabled
+
+- Implement `--prefer-oldest` [#8261](https://github.com/haskell/cabal/pull/8261)
+
+  - The new flag makes Cabal solver try to find a build plan with the oldest versions possible. This is useful to establish lower bounds.
+
+- Update and sdist now only check for compiler when project file has conditionals [#8352](https://github.com/haskell/cabal/issues/8352) [#8550](https://github.com/haskell/cabal/issues/8550) [#8589](https://github.com/haskell/cabal/issues/8589) [#8358](https://github.com/haskell/cabal/pull/8358) [#8627](https://github.com/haskell/cabal/pull/8627)
+
+  - Cabal update and sdist will not require a ghc in path unless the project has conditionals that require it
+
+- Allow offline bootstrapping of cabal-install [#8368](https://github.com/haskell/cabal/pull/8368)
+
+  - The bootstrap script for cabal-install now supports fetching the sources of the dependencies in a separate step.
+    One can then copy over the resulting archive and perform offline bootstrapping of cabal-install.
+
+- Pass some haddock flags to dependencies [#395](https://github.com/haskell/cabal/issues/395) [#8104](https://github.com/haskell/cabal/issues/8104) [#8414](https://github.com/haskell/cabal/pull/8414)
+
+  - Pass `--haddock-hoogle`, `--haddock-html`, `--haddock-internal`, `--haddock-quickjump`, `--haddock-hyperlinked-source`
+    to all the dependencies if they are specified as command line args
+
+- build pkgconfig db individually when bulk fails [#8494](https://github.com/haskell/cabal/issues/8494) [#8496](https://github.com/haskell/cabal/pull/8496)
+
+  - When pkg-config fails to get versions for all packages in bulk, falls back to querying one-by-one.
+
+- improve install target handling logic regarding of project files [#8094](https://github.com/haskell/cabal/issues/8094) [#8352](https://github.com/haskell/cabal/issues/8352) [#8498](https://github.com/haskell/cabal/pull/8498)
+
+  - fixes an issue where `cabal install pkg-x.y.z` fails unless `--ignore-project` is given
+  - fixes an issue where `cabal install --ignore-project` crashes when a project file is present
+
+- Redownload packages when source hash verification fails [#7541](https://github.com/haskell/cabal/issues/7541) [#8500](https://github.com/haskell/cabal/pull/8500)
+
+  - Cabal-install will verify source hashes on cached downloads against the current index, and redownload on mismatch. (Which can occur with e.g. head.hackage)
+
+- `cabal init -i` should sanitize package name guessed from the directory name [#8404](https://github.com/haskell/cabal/issues/8404) [#8561](https://github.com/haskell/cabal/pull/8561)
+
+  If the current directory name has any non-alphanumeric symbols in its name, the symbols will be replaced with a dash. Also, will make sure that the resulting package name starts with a letter.
+
+  This worked for cabal init -n already, and this PR only moves code around so that cabal init -i also benefits from this logic.
+
+- Support `js-sources` with GHC, not only with GHCJS [#8636](https://github.com/haskell/cabal/pull/8636)
+
+  - Take into account `js-sources` when building library components with GHC
+  - Missing support for `js-sources` in executable components is tracked in #8639
+
+- Fix `extra-source-file` rebuild tracking when run in a multi-package project [#8632](https://github.com/haskell/cabal/issues/8632) [#8634](https://github.com/haskell/cabal/issues/8634) [#8640](https://github.com/haskell/cabal/pull/8640)
+
+  - Fixes an issue where glob expansion of `extra-source-files` for rebuild tracking purposes was not occurring correctly when run in a multi-package setting (i.e. when the globs needed to be expanded relative to something other than ".").
+
+- No up-front warning that assertions are on for special commands (help, version, numeric-version) [#8645](https://github.com/haskell/cabal/issues/8645) [#8647](https://github.com/haskell/cabal/pull/8647)
+
+  - When compiled with ghc option `-fno-ignore-assert`, `cabal-install` will issue a generic warning that assertions are on.
+    This warning will no longer be emitted for special modes of operation like `cabal --numeric-version`, `--version` and help,
+    and also not if `cabal` could not parse its command line.
+    Further, the warning now goes to `stderr` rather than `stdout`.
+
+- Fix and improve list parser for `cabal init` arguments [#8659](https://github.com/haskell/cabal/issues/8659) [#8663](https://github.com/haskell/cabal/pull/8663)
+
+  Occurrences of 'Flag [a]' seem to behave in an unexpected way. The monoid
+  instance of 'Flag' is right associative and discard the value on the
+  left, but we want to merge the contents of 'Flag'.
+
+  Permits:
+  - `cabal init -d base -d vector -d containers`
+
+  Fixes for all Flag '[a]' the cli parser in cabal init. Adds cli parser tests.
+
+  Adds the feature to specify a comma-separated list of dependencies:
+  - `cabal init -d base,vector,containers`
+
+- Fix resolution of imports by relative paths in cabal.project [#8686](https://github.com/haskell/cabal/pull/8686)
+
+  Fix bug where cabal tries to resolve imports by relative paths against
+  the directory cabal executable was invoked in rather than directory of
+  cabal.project file that does the import.
+
+- Fix `cabal repl` discarding `--build-depends` [#6859](https://github.com/haskell/cabal/issues/6859) [#7081](https://github.com/haskell/cabal/issues/7081) [#8732](https://github.com/haskell/cabal/pull/8732)
+
+  - Fix `repl` command discarding `--build-depends` argument when using
+    `allow-newer` or `allow-older`.
+
+- Add `cabal get --only-package-description` [#1954](https://github.com/haskell/cabal/issues/1954) [#1977](https://github.com/haskell/cabal/pull/1977) [#5162](https://github.com/haskell/cabal/pull/5162) [#8263](https://github.com/haskell/cabal/pull/8263)
+
+- `cabal haddock` now implies `--enable-documentation` [#7462](https://github.com/haskell/cabal/issues/7462) [#8259](https://github.com/haskell/cabal/pull/8259)
+
+- Include `extra-lib-dirs-static` into `PackageHash` [#6935](https://github.com/haskell/cabal/issues/6935) [#7794](https://github.com/haskell/cabal/pull/7794)
+
+- Document `cabal check` in the user guide [#8237](https://github.com/haskell/cabal/pull/8237)
+
+- Add documentation (or stubs) for cabal-install commands: `fetch`, `get`, `info`, `init`, `list`, `report`, `unpack`, `upload`, `user-config` [#7884](https://github.com/haskell/cabal/issues/7884) [#7978](https://github.com/haskell/cabal/issues/7978) [#8308](https://github.com/haskell/cabal/issues/8308) [#8309](https://github.com/haskell/cabal/pull/8309)
+
+- Add check for upper bound on any dependency in `cabal check` [#8291](https://github.com/haskell/cabal/issues/8291) [#8339](https://github.com/haskell/cabal/pull/8339)
diff --git a/cabal/release-notes/cabal-install-3.10.2.0.md b/cabal/release-notes/cabal-install-3.10.2.0.md
new file mode 100644
--- /dev/null
+++ b/cabal/release-notes/cabal-install-3.10.2.0.md
@@ -0,0 +1,60 @@
+cabal-install and cabal-install-solver 3.10.2.0 changelog and release notes
+---
+
+## Release 3.10.2.0 is strictly a bug-fix release, with the fixes listed below
+
+- Fix parsing of password-command option [#9002](https://github.com/haskell/cabal/pull/9002)
+
+  The password-command option did not parse its value correctly.
+  Quotes were ignored, making many kinds of commands impossible to
+  express (e.g.  `sh -c "foo | bar"`).  Also, `cabal user-config`
+  treated the argument list as a *list of option values*, rather than a
+  *value that is a list*.  As a consequence, `cabal user-config
+  update` corrupted the value in the config file.
+
+  Fixed these issues by parsing the command as a space separated list
+  of tokens (which may be enclosed in double quotes), and treating the
+  parsed list-of-token as one value (not multiple).
+
+- Existence of $XDG_CONFIG_HOME/cabal/config now overrides existence of $HOME/.cabal [#8577](https://github.com/haskell/cabal/issues/8577)
+
+  To avoid pre-XDG backwards compatibility from triggering due to other
+  tools accidentally creating a $HOME/.cabal directory, the presence of
+  $XDG_CONFIG_HOME/cabal/config now disables pre-XDG backwards
+  compatibility.  Presumably $XDG_CONFIG_HOME/cabal/config will never be
+  created by accident.
+
+- Shorten script-builds paths [#8841](https://github.com/haskell/cabal/issues/8841) [#8898](https://github.com/haskell/cabal/pull/8898)
+
+  - Use Base64 hash truncated to 26 chars for script-build cache directories.
+  - Use the cache directory as the dist directory.
+  - Use script-<your-sanitized-script-name> as the component name instead of cabal-script-<...>.
+  - Use cabal-script-<your-actual-script-name> for the executable name.
+  - This change is incompatible with previous cabal versions in terms of cache location,
+    you should manually remove your old caches once you no longer need them.
+
+- Don't add `extra-prog-path: ~/.local/bin` when initially creating `~/.config/cabal/config` [#8951](https://github.com/haskell/cabal/issues/8951)
+
+- Use compiler flags for caching project config [#8819](https://github.com/haskell/cabal/pull/8819)
+
+  This ensures that cached project configs with conditionals re-execute the conditional logic when the compiler changes.
+
+- Fix default Nix configuration option in generated ~/.cabal/config file [#8878](https://github.com/haskell/cabal/pull/8878)
+
+  Fixes the default for ~/.cabal/config file. The nix option should now be commented out by default.
+
+- add base to cabal install --lib default env file [#8903](https://github.com/haskell/cabal/pull/8903)
+
+  This adds base by default to the env file created by `cabal install --lib`. Further it ensures that packagedbs have been created before adding them to the env file.
+
+- Do not check PVP on internal targets [#8361](https://github.com/haskell/cabal/issues/8361) [#9004](https://github.com/haskell/cabal/pull/9004)
+
+  - `cabal check` will not check for dependencies upper bounds in internal
+    targets (i.e. test-suites and benchmarks)
+
+- Add new Hackage root keys to bootstrap set [#9068](https://github.com/haskell/cabal/pull/9068)
+
+  The two new [Hackage root keyholders](https://github.com/haskell-infra/hackage-root-keys/tree/master/root-keys) were added to the bootstrap set.
+
+  - Added Hackage root key for Joachim Breitner
+  - Added Hackage root key for Mathieu Boespflug
diff --git a/cabal/release-notes/cabal-install-3.10.2.1.md b/cabal/release-notes/cabal-install-3.10.2.1.md
new file mode 100644
--- /dev/null
+++ b/cabal/release-notes/cabal-install-3.10.2.1.md
@@ -0,0 +1,4 @@
+cabal-install and cabal-install-solver 3.10.2.1 changelog and release notes
+---
+
+## Release 3.10.2.1 is strictly a bounds bump release for GHC 9.8 compatibility
diff --git a/cabal/release-notes/cabal-install-3.10.3.0.md b/cabal/release-notes/cabal-install-3.10.3.0.md
new file mode 100644
--- /dev/null
+++ b/cabal/release-notes/cabal-install-3.10.3.0.md
@@ -0,0 +1,45 @@
+cabal-install and cabal-install-solver 3.10.3.0 changelog and release notes
+---
+
+## Release 3.10.3.0 is strictly a bug-fix release, with the fixes listed below
+
+- PkgConfig individual calls [#9134](https://github.com/haskell/cabal/pull/9134)
+
+  - `cabal` invokes `pkg-config` individually for each lib if querying for all doesn't return the expected result
+
+- Use compiler flags for caching project config [#8819](https://github.com/haskell/cabal/pull/8819)
+
+  This ensures that cached project configs with conditionals re-execute the conditional logic when the compiler changes.
+
+- Make `check` recognise `TypeAbstractions` [#9496](https://github.com/haskell/cabal/issues/9496) [#9503](https://github.com/haskell/cabal/pull/9503)
+
+  - `cabal check` will not complain about “Unknown extension” when
+    finding `TypeAbstractions`.
+
+- `check`: add PackageInfo warning [#9331](https://github.com/haskell/cabal/issues/9331) [#9525](https://github.com/haskell/cabal/pull/9525)
+
+  `cabal check` will warn about PackageInfo_* modules and provide an upgrade path to 3.12.
+
+- Fix extra-prog-path propagation [#7649](https://github.com/haskell/cabal/issues/7649) [#9519](https://github.com/haskell/cabal/issues/9519) [#9527](https://github.com/haskell/cabal/pull/9527)
+
+  - extra-prog-paths are now propagated to all commands. This in particular helps
+    when running a MinGW cabal in the PowerShell, where the MSYS2 paths are
+    usually not available in the PowerShell PATH. GHCup already sets them up for
+    us but they were sometimes lost on the way.
+
+- fix pkgconfig-depends for pkgconf-1.9 [#8923](https://github.com/haskell/cabal/issues/8923) [#9391](https://github.com/haskell/cabal/pull/9391)
+
+- Ignore invalid Unicode in pkg-config descriptions [#9608](https://github.com/haskell/cabal/issues/9608) [#9609](https://github.com/haskell/cabal/pull/9609)
+
+  Previously, cabal-install would crash when `pkg-config --list-all` contained
+  invalid Unicode. With this change, invalid unicode in package descriptions is
+  ignored, and unparseable package names are considered nonexistent.
+
+- Script cache dir is the base16 hash of the canonical path of the script. [#9459](https://github.com/haskell/cabal/pull/9459)
+
+  Script cache dir is the base16 hash of the canonical path of the script.
+
+- Fix run command environment [#8391](https://github.com/haskell/cabal/issues/8391) [#9341](https://github.com/haskell/cabal/pull/9341)
+
+  - The Run command will now add binary paths of dependencies
+    (build-tool-depends) to PATH, just like Exec and Test commands.
diff --git a/cabal/release-notes/cabal-install-3.4.0.0.md b/cabal/release-notes/cabal-install-3.4.0.0.md
--- a/cabal/release-notes/cabal-install-3.4.0.0.md
+++ b/cabal/release-notes/cabal-install-3.4.0.0.md
@@ -1,45 +1,45 @@
 ### Significant changes
 
 - Add cabal-version: 3.4 [!6663](https://github.com/haskell/cabal/pull/6663)
-  
+
   See various changes in https://cabal.readthedocs.io/en/latest/file-format-changelog.html#cabal-version-3-4
-  
+
 - Support GHC-8.12 [#6903](https://github.com/haskell/cabal/issues/6903) [#6904](https://github.com/haskell/cabal/issues/6904) [#6905](https://github.com/haskell/cabal/issues/6905) [!6545](https://github.com/haskell/cabal/pull/6545) [!6552](https://github.com/haskell/cabal/pull/6552) [!6553](https://github.com/haskell/cabal/pull/6553) [!6563](https://github.com/haskell/cabal/pull/6563) [!6735](https://github.com/haskell/cabal/pull/6735) [!6844](https://github.com/haskell/cabal/pull/6844) [!6848](https://github.com/haskell/cabal/pull/6848) [!6865](https://github.com/haskell/cabal/pull/6865) [!6908](https://github.com/haskell/cabal/pull/6908) [!6947](https://github.com/haskell/cabal/pull/6947)
-  
+
   - Support for `-this-package-key` deprecation
   - Use process `createPipe`
   - Add support for WINIO to Cabal
-  - Adopt to simplfied subsumption changes
-  
+  - Adopt to simplified subsumption changes
+
   There are no magical `IO = WithCallStack Prelude.IO` alias in Cabal,
   as it is hard to get working with GHC-8.12's simplified subsumption.
-  
+
 - Treat `pkg:sublib` dependency syntax as is in `cabal-version: 3.4` [#6083](https://github.com/haskell/cabal/issues/6083) [!6893](https://github.com/haskell/cabal/pull/6893) [!6907](https://github.com/haskell/cabal/pull/6907)
-  
+
   In `cabal-version: 3.4` cabal files the dependency definition
-  
+
   ```cabal
   build-depends: somesublib
   ```
-  
+
   is not using in-package sublibraries. You have to be explicit and write
-  
+
   ```cabal
   build-depends: thispkg:somesublib
   ```
-  
-  This fixes an issue, where it was impossible to refer to extenral
+
+  This fixes an issue, where it was impossible to refer to external
   library, if you had sublibrary of the same name.
-  
+
 - Add active-repositories configuration [#6819](https://github.com/haskell/cabal/issues/6819) [!6724](https://github.com/haskell/cabal/pull/6724) [!6868](https://github.com/haskell/cabal/pull/6868)
-  
+
   New `active-repositories` `cabal.project` fields allows
   specifying an order and ways various package repositories are combined.
-  
+
   The active `active-repositories` is saved in `cabal.project.freeze`.
-  
+
 - Various `cabal init` improvements [#6150](https://github.com/haskell/cabal/issues/6150) [#6675](https://github.com/haskell/cabal/issues/6675) [!6603](https://github.com/haskell/cabal/pull/6603) [!6607](https://github.com/haskell/cabal/pull/6607) [!6619](https://github.com/haskell/cabal/pull/6619) [!6632](https://github.com/haskell/cabal/pull/6632) [!6641](https://github.com/haskell/cabal/pull/6641) [!6650](https://github.com/haskell/cabal/pull/6650) [!6661](https://github.com/haskell/cabal/pull/6661) [!6676](https://github.com/haskell/cabal/pull/6676) [!6677](https://github.com/haskell/cabal/pull/6677) [!6678](https://github.com/haskell/cabal/pull/6678) [!6690](https://github.com/haskell/cabal/pull/6690) [!6705](https://github.com/haskell/cabal/pull/6705) [!6723](https://github.com/haskell/cabal/pull/6723)
-  
+
   - Default to `cabal-version: 2.4`
   - `cabal` doesn't force a default license choice anymore
   - Licenses are always asked using SPDX expression
@@ -49,57 +49,57 @@
   - Add `FileCreators.generateCabalFile` unit tests.
   - Default cabal init application-dir to `app`, and source-dir to `src`.
   - Default to SPDX.NONE license in cabal init interactive mode.
-  
+
 - Rework `v2-sdist` command [#2940](https://github.com/haskell/cabal/issues/2940) [#5813](https://github.com/haskell/cabal/issues/5813) [#6514](https://github.com/haskell/cabal/issues/6514) [#6611](https://github.com/haskell/cabal/issues/6611) [#6635](https://github.com/haskell/cabal/issues/6635) [!6454](https://github.com/haskell/cabal/pull/6454) [!6637](https://github.com/haskell/cabal/pull/6637) [!6640](https://github.com/haskell/cabal/pull/6640) [!6660](https://github.com/haskell/cabal/pull/6660) [!6666](https://github.com/haskell/cabal/pull/6666) [!6884](https://github.com/haskell/cabal/pull/6884) [!6916](https://github.com/haskell/cabal/pull/6916)
-  
+
   `v2-sdist` marks all files as readonly in resulting tarballs.
-  
+
   The #2940 "cabal sdist should touch preprocessed .hs files" issue
   is fixed by virtue of not doing any preprocessing anymore.
   It's responsibility of packager.
-  
+
   The #6611 "v2-sdist includes a file twice in the tarball " issue
   is fixed as we don't consider only one file list,
   not two separate executable and ordinary file lists.
-  
+
   The #6514 "unpack doesn't preserve (executable) permissions" issue
   is partially resolved,  as there shouldn't be executable permissions
   in the tar files.
-  
+
   The rationale for above simplification is simple. The only file
   Cabal machinery would run is `configure` script. These
   are run with explicit `sh` program. For package internal scripts,
   maintainers should also use interpreters explicitly as well.
   Scripts with shebangs are not executable on Windows.
-  
+
   The `v1-sdist` command is removed, as its functionality is completely
   superseded by `v2-sdist`.
-  
+
 - `source-repository-package` directories aren't local [#5586](https://github.com/haskell/cabal/issues/5586) [!6915](https://github.com/haskell/cabal/pull/6915) [!6917](https://github.com/haskell/cabal/pull/6917)
-  
+
   Concretely these means that compiled `source-repository-package` entries
   used in different projects are stored in the global nix-style store.
-  
+
 - Add list-bin command [#6807](https://github.com/haskell/cabal/issues/6807) [!6931](https://github.com/haskell/cabal/pull/6931)
-  
+
   `cabal list-bin executable-component` tells the path to the build artifact.
-  
+
 - Remove sandboxes [#6445](https://github.com/haskell/cabal/issues/6445) [!6747](https://github.com/haskell/cabal/pull/6747)
-  
+
   Sandbox functionality is remove in favour of now default nix-style builds.
-  
+
 - `cabal list` accepts regular expression [#4267](https://github.com/haskell/cabal/issues/4267) [#6683](https://github.com/haskell/cabal/issues/6683) [!6618](https://github.com/haskell/cabal/pull/6618) [!6806](https://github.com/haskell/cabal/pull/6806)
 - More rich `index-state` syntax. `v2-freeze` saves `index-state`. [#6728](https://github.com/haskell/cabal/issues/6728) [!6581](https://github.com/haskell/cabal/pull/6581) [!6591](https://github.com/haskell/cabal/pull/6591) [!6596](https://github.com/haskell/cabal/pull/6596) [!6597](https://github.com/haskell/cabal/pull/6597) [!6682](https://github.com/haskell/cabal/pull/6682) [!6733](https://github.com/haskell/cabal/pull/6733)
 ### Other changes
 
 - Tests additions [#6409](https://github.com/haskell/cabal/issues/6409) [!6753](https://github.com/haskell/cabal/pull/6753) [!6759](https://github.com/haskell/cabal/pull/6759) [!6802](https://github.com/haskell/cabal/pull/6802) [!6842](https://github.com/haskell/cabal/pull/6842) [!6872](https://github.com/haskell/cabal/pull/6872)
-  
+
   - Add shrinker, so writing big non-generic product shrinkers is easier
   - Add `hs-source-dirs: NL .` test-case
   - Add public multilib test(s)
-  
+
 - Code organization [!6599](https://github.com/haskell/cabal/pull/6599) [!6642](https://github.com/haskell/cabal/pull/6642) [!6734](https://github.com/haskell/cabal/pull/6734) [!6745](https://github.com/haskell/cabal/pull/6745) [!6746](https://github.com/haskell/cabal/pull/6746) [!6817](https://github.com/haskell/cabal/pull/6817) [!6818](https://github.com/haskell/cabal/pull/6818) [!6821](https://github.com/haskell/cabal/pull/6821) [!6867](https://github.com/haskell/cabal/pull/6867)
-  
+
   - Split `Distribution.Client.Types` module
   - Move cabal-testsuite code into `src/`
   - Add `ProjectFlags`
@@ -109,77 +109,77 @@
   - Make cabal-install compilable with `NoImplicitPrelude`
   - Refactor shared `TargetProblem` data types into their own module.
   - Template `cabal-install.cabal` using zinza
-  
+
 - The grammar of most package description fields is formally documented [!6591](https://github.com/haskell/cabal/pull/6591) [!6593](https://github.com/haskell/cabal/pull/6593) [!6704](https://github.com/haskell/cabal/pull/6704) [!6766](https://github.com/haskell/cabal/pull/6766) [!6778](https://github.com/haskell/cabal/pull/6778) [!6780](https://github.com/haskell/cabal/pull/6780) [!6781](https://github.com/haskell/cabal/pull/6781) [!6791](https://github.com/haskell/cabal/pull/6791) [!6800](https://github.com/haskell/cabal/pull/6800)
-  
+
   See https://cabal.readthedocs.io/en/latest/buildinfo-fields-reference.html
-  
+
 - Add -fexpose-all-unfoldings to parsec and Cabal in release project [!6708](https://github.com/haskell/cabal/pull/6708)
-  
+
   This makes parser faster with acceptable code-size increase.
-  
+
 - Fix ghci being launched before other sources are built. [!6923](https://github.com/haskell/cabal/pull/6923)
-  
+
   Related to foreign calls to C-sources.
-  
+
 - Use default install directory if not specified [#5973](https://github.com/haskell/cabal/issues/5973) [!6624](https://github.com/haskell/cabal/pull/6624)
-  
+
   Cabal 3.0.0.0 added the --installdir option to specify the location that
   binaries should be installed in. Running a cabal user-config update would
   populate the config file with the default value, but the cabal install program
   would error if it wasn't set. This change uses the default value that would be
   written to the config if its unset, and outputs a warning.
-  
+
 - Update GHC environment location [#6565](https://github.com/haskell/cabal/issues/6565) [!6822](https://github.com/haskell/cabal/pull/6822)
-  
+
   cabal-install currently assumes that the GHC environment files are always located in `$HOME/.ghc/`.
   However, GHC itself doesn't query the home directory directly.
   Instead, it uses `getAppUserDataDirectory "ghc"` which happens to coincide with `$HOME/.ghc`/ on UNIX systems.
   On Windows, however, GHC ends up looking in `%APPDATA%/ghc/`.
-  
+
 - Remove `-any` and `-none` syntax for version ranges in cabal-version: 3.4 [#6589](https://github.com/haskell/cabal/issues/6589) [!6786](https://github.com/haskell/cabal/pull/6786)
-  
+
   Use `>=0` (or empty in dependencies) and `<0` respectively.
-  
+
 - Add pijul to known repository type [#6610](https://github.com/haskell/cabal/issues/6610) [!6684](https://github.com/haskell/cabal/pull/6684)
-  
+
   Pijul is now explicitly recognized version control system.
   However `cabal-install` isn't yet able to use it in
   `source-repository-package`.
-  
+
 - Remove upgrade, uninstall and win32selfupgrade commands [#6691](https://github.com/haskell/cabal/issues/6691) [!6707](https://github.com/haskell/cabal/pull/6707)
-  
+
   This commands were not implemented or are special purpose.
   The removal of `win32selfupgrade` might break self upgrade on windows,
   when `cabal-install` tries to rewrite the binary of itself.
   This shouldn't be a problem when symlinking is used.
-  
+
 - Remove local-repo [#6729](https://github.com/haskell/cabal/issues/6729) [!6730](https://github.com/haskell/cabal/pull/6730)
-  
+
   This functionality was mainly used by removed sandboxes.
   `file+noindex` repositories are better variant for local package repositories.
-  
+
 - Add support for multiple public libraries to the solver [#6039](https://github.com/haskell/cabal/issues/6039) [!6047](https://github.com/haskell/cabal/pull/6047) [!6812](https://github.com/haskell/cabal/pull/6812) [!6836](https://github.com/haskell/cabal/pull/6836)
-  
+
   cabal-install can now take into account the presence and visibility of
   sublibraries when solving. This also means that, when using cabal-install,
   multiple public libraries support is extended to GHCs older than 8.8.
   The support is limited to source packages for now.
-  
+
 - Remove text type-class [!6764](https://github.com/haskell/cabal/pull/6764) [!6777](https://github.com/haskell/cabal/pull/6777) [!6784](https://github.com/haskell/cabal/pull/6784) [!6785](https://github.com/haskell/cabal/pull/6785) [!6793](https://github.com/haskell/cabal/pull/6793) [!6794](https://github.com/haskell/cabal/pull/6794)
-  
+
   `Text` type-class was removed from `Cabal`, but it still lived in `cabal-install`.
   Now it is finally removed.
   `cabal-install` is still using `ReadP` parsers for various things though.
-  
+
 - Windows install symlinks [!5684](https://github.com/haskell/cabal/pull/5684) [!6506](https://github.com/haskell/cabal/pull/6506) [!6519](https://github.com/haskell/cabal/pull/6519)
-  
+
   `cabal-install` will try to infer whether symlinking is supported on Windows,
   and make symlinks in `install`. Otherwise it will fallback to copying files.
   Either way can be forced with `--install-method`.
-  
+
 - Use process jobs when spawning subprocesses [!6529](https://github.com/haskell/cabal/pull/6529) [!6536](https://github.com/haskell/cabal/pull/6536)
-  
+
   Many toolchain tools written for POSIX systems rely on the exec system
   call. Unfortunately, it is not possible to implement exec in a
   POSIX-compliant manner on Windows. In particular, the semantics of the
@@ -187,16 +187,16 @@
   will cause process's waiting on the exec'ing process to incorrectly
   conclude that the process has successfully terminated when in fact it is
   still running in another process.
-  
+
   For this reason, the process library exposes the use_process_jobs
   flag to use a more strict (although still not POSIX-compliant) mechanism
   for tracking process completion.
   This is explained in [the Process.hs comment](https://github.com/haskell/process/blob/master/System/Process.hs#L399)
-  
+
   Unfortunately, job support in the process library is currently quite
   broken and was only recently fixed. Consequently, we only enable job
   object support for process releases >= 1.6.8.
-  
+
 - Change `BuildReports` parse/pretty to use FieldGrammar framework [!6783](https://github.com/haskell/cabal/pull/6783)
 - Tell users about `cabal.project.local~` in `cabal v2-configure` [!6877](https://github.com/haskell/cabal/pull/6877)
 - Improvements to cabal-testsuite framework [!6643](https://github.com/haskell/cabal/pull/6643)
@@ -218,7 +218,7 @@
 - Include component name in unit-id [#6485](https://github.com/haskell/cabal/issues/6485) [!6547](https://github.com/haskell/cabal/pull/6547)
 - cabal v2-install prints copy/symlink destination [#6575](https://github.com/haskell/cabal/issues/6575) [!6582](https://github.com/haskell/cabal/pull/6582) [!6890](https://github.com/haskell/cabal/pull/6890)
 - Prepend hs-source-dir to match-component, fixes `cabal repl file` [#6622](https://github.com/haskell/cabal/issues/6622) [!6623](https://github.com/haskell/cabal/pull/6623) [!6826](https://github.com/haskell/cabal/pull/6826) [!6875](https://github.com/haskell/cabal/pull/6875)
-- Change 'optional-packages' default to empty, when cabal.project is mising. [#4797](https://github.com/haskell/cabal/issues/4797) [#6739](https://github.com/haskell/cabal/issues/6739) [!6740](https://github.com/haskell/cabal/pull/6740)
+- Change 'optional-packages' default to empty, when cabal.project is missing. [#4797](https://github.com/haskell/cabal/issues/4797) [#6739](https://github.com/haskell/cabal/issues/6739) [!6740](https://github.com/haskell/cabal/pull/6740)
 - v2-update reports new index-state [#6804](https://github.com/haskell/cabal/issues/6804) [!6810](https://github.com/haskell/cabal/pull/6810)
 - Fix rpmvercmp (trailing non-digit characters) [#6805](https://github.com/haskell/cabal/issues/6805) [!6808](https://github.com/haskell/cabal/pull/6808)
 - Add `-z` / `--ignore-project` flag to `cabal v2-update` [#6809](https://github.com/haskell/cabal/issues/6809) [!6814](https://github.com/haskell/cabal/pull/6814)
diff --git a/cabal/release-notes/cabal-install-3.8.0.20220526.md b/cabal/release-notes/cabal-install-3.8.0.20220526.md
--- a/cabal/release-notes/cabal-install-3.8.0.20220526.md
+++ b/cabal/release-notes/cabal-install-3.8.0.20220526.md
@@ -201,7 +201,7 @@
 
 - Fix running GHCJS executables [#6175](https://github.com/haskell/cabal/issues/6175) [#6361](https://github.com/haskell/cabal/issues/6361) [#7575](https://github.com/haskell/cabal/pull/7575)
 
-- Support Git submodules in `source-package-respository` [#5536](https://github.com/haskell/cabal/issues/5536) [#7625](https://github.com/haskell/cabal/pull/7625)
+- Support Git submodules in `source-package-repository` [#5536](https://github.com/haskell/cabal/issues/5536) [#7625](https://github.com/haskell/cabal/pull/7625)
 
 - Add support for `--package-db` flags to v2 commands [#5773](https://github.com/haskell/cabal/issues/5773) [#7676](https://github.com/haskell/cabal/pull/7676)
 
diff --git a/cabal/release-notes/cabal-install-3.8.1.0.md b/cabal/release-notes/cabal-install-3.8.1.0.md
--- a/cabal/release-notes/cabal-install-3.8.1.0.md
+++ b/cabal/release-notes/cabal-install-3.8.1.0.md
@@ -195,7 +195,7 @@
 
 - Fix running GHCJS executables [#6175](https://github.com/haskell/cabal/issues/6175) [#6361](https://github.com/haskell/cabal/issues/6361) [#7575](https://github.com/haskell/cabal/pull/7575)
 
-- Support Git submodules in `source-package-respository` [#5536](https://github.com/haskell/cabal/issues/5536) [#7625](https://github.com/haskell/cabal/pull/7625)
+- Support Git submodules in `source-package-repository` [#5536](https://github.com/haskell/cabal/issues/5536) [#7625](https://github.com/haskell/cabal/pull/7625)
 
 - Add support for `--package-db` flags to v2 commands [#5773](https://github.com/haskell/cabal/issues/5773) [#7676](https://github.com/haskell/cabal/pull/7676)
 
diff --git a/cabal/scripts/release/create-release-metadata-for-ghcup.sh b/cabal/scripts/release/create-release-metadata-for-ghcup.sh
new file mode 100644
--- /dev/null
+++ b/cabal/scripts/release/create-release-metadata-for-ghcup.sh
@@ -0,0 +1,125 @@
+#!/usr/bin/env bash
+
+# This script, when passed the cabal release number as the first and only argument
+# generates the metadata in the correct format to be useable as is by GHCup
+# for eg:-
+# $ create-release-metadata-for-ghcup.sh 3.10.2.0 or "3.10.2.0"
+
+# Note:- Please run ./download-cabal-install-release-binaries.sh before running this script.
+set -eu
+set -o pipefail
+
+RELEASE=$1
+## FixMe:// What dir to use here?
+
+if [ -d "binary-downloads/cabal-install-${RELEASE}-binaries" ]; then
+    echo "binary downloads folder for release ${RELEASE} found, starting generating GHCup metadata..."
+else
+    echo "The binary downloads for release ${RELEASE} not found."
+    echo "Please run the script to download them first."
+fi
+
+cd "binary-downloads/cabal-install-${RELEASE}-binaries"
+
+cat <<EOF > /dev/stdout
+    $RELEASE:
+      viTags:
+        - Latest
+      viChangeLog: https://github.com/haskell/cabal/blob/master/release-notes/cabal-install-$RELEASE.md
+      viPostInstall: *cabal-${RELEASE//./}-post-install
+      viArch:
+        A_64:
+          Linux_UnknownLinux:
+            unknown_versioning: &cabal-${RELEASE//./}-64
+            dlUri: https://downloads.haskell.org/~cabal/cabal-install-$RELEASE/cabal-install-$RELEASE-x86_64-linux-alpine3_12.tar.xz
+            dlSubdir: cabal-install-$RELEASE
+            dlHash: $(sha256sum "cabal-install-$RELEASE-x86_64-linux-alpine3_12.tar.xz" | awk '{ print $1 }')
+          Linux_Alpine:
+            unknown_versioning: &cabal-${RELEASE//./}-64
+          Linux_CentOS:
+            unknown_versioning: &cabal-${RELEASE//./}-64-centos7
+            dlUri: https://downloads.haskell.org/~cabal/cabal-install-$RELEASE/cabal-install-$RELEASE-x86_64-linux-centos7.tar.xz
+            dlSubdir: cabal-install-$RELEASE
+            dlHash: $(sha256sum "cabal-install-$RELEASE-x86_64-linux-centos7.tar.xz" | awk '{ print $1 }')
+          Linux_Debian:
+            ' ( >= 9 && < 10)': &cabal-${RELEASE//./}-64-debian
+              dlUri: https://downloads.haskell.org/~cabal/cabal-install-$RELEASE/cabal-install-$RELEASE-x86_64-linux-deb9.tar.xz
+              dlSubdir: cabal-install-$RELEASE
+              dlHash: $(sha256sum "cabal-install-$RELEASE-x86_64-linux-deb9.tar.xz" | awk '{ print $1 }')
+            ' ( == 10 && < 11)':
+              dlUri: https://downloads.haskell.org/~cabal/cabal-install-$RELEASE/cabal-install-$RELEASE-x86_64-linux-deb10.tar.xz
+              dlSubdir: cabal-install-$RELEASE
+              dlHash: $(sha256sum "cabal-install-$RELEASE-x86_64-linux-deb10.tar.xz" | awk '{ print $1 }')
+            ' ( >= 11)':
+              dlUri: https://downloads.haskell.org/~cabal/cabal-install-$RELEASE/cabal-install-$RELEASE-x86_64-linux-deb11.tar.xz
+              dlSubdir: cabal-install-$RELEASE
+              dlHash: $(sha256sum "cabal-install-$RELEASE-x86_64-linux-deb11.tar.xz" | awk '{ print $1 }')
+            unknown_versioning: &cabal-${RELEASE//./}-64-debian
+          Linux_Fedora:
+            '>= 33':
+              dlUri: https://downloads.haskell.org/~cabal/cabal-install-$RELEASE/cabal-install-$RELEASE-x86_64-linux-fedora33.tar.xz
+              dlSubdir: cabal-install-$RELEASE
+              dlHash: $(sha256sum "cabal-install-$RELEASE-x86_64-linux-fedora33.tar.xz" | awk '{ print $1 }')
+            unknown_versioning: &cabal-${RELEASE//./}-64-centos7
+          Linux_Ubuntu:
+            '< 20': &cabal-${RELEASE//./}-64-ubuntu18
+              dlUri: https://downloads.haskell.org/~cabal/cabal-install-$RELEASE/cabal-install-$RELEASE-x86_64-linux-ubuntu18_04.tar.xz
+              dlSubdir: cabal-install-$RELEASE
+              dlHash: $(sha256sum "cabal-install-$RELEASE-x86_64-linux-ubuntu18_04.tar.xz" | awk '{ print $1 }')
+            '>= 20': &cabal-${RELEASE//./}-64-ubuntu20
+              dlUri: https://downloads.haskell.org/~cabal/cabal-install-$RELEASE/cabal-install-$RELEASE-x86_64-linux-ubuntu20_04.tar.xz
+              dlSubdir: cabal-install-$RELEASE
+              dlHash: $(sha256sum "cabal-install-$RELEASE-x86_64-linux-ubuntu20_04.tar.xz" | awk '{ print $1 }')
+            unknown_versioning: *cabal-${RELEASE//./}-64-ubuntu18
+          Linux_Mint:
+            '< 20': *cabal-${RELEASE//./}-64-ubuntu18
+            '>= 20': *cabal-${RELEASE//./}-64-ubuntu20
+            unknown_versioning: *cabal-${RELEASE//./}-64-ubuntu18
+          Darwin:
+            unknown_versioning:
+              dlUri: https://downloads.haskell.org/~cabal/cabal-install-$RELEASE/cabal-install-$RELEASE-x86_64-darwin.tar.xz
+              dlSubdir: cabal-install-$RELEASE
+              dlHash: $(sha256sum "cabal-install-$RELEASE-x86_64-darwin.tar.xz" | awk '{ print $1 }')
+          Windows:
+            unknown_versioning:
+              dlUri: https://downloads.haskell.org/~cabal/cabal-install-$RELEASE/cabal-install-$RELEASE-x86_64-windows.zip
+              dlSubdir: cabal-install-$RELEASE
+              dlHash: $(sha256sum "cabal-install-$RELEASE-x86_64-windows.zip" | awk '{ print $1 }')
+          FreeBSD:
+            unknown_versioning:
+              dlUri: https://downloads.haskell.org/~cabal/cabal-install-$RELEASE/cabal-install-$RELEASE-x86_64-freebsd.tar.xz
+              dlSubdir: cabal-install-$RELEASE
+              dlHash: $(sha256sum "cabal-install-$RELEASE-x86_64-freebsd.tar.xz" | awk '{ print $1 }')
+        A_32:
+          Linux_UnknownLinux:
+            unknown_versioning: &cabal-${RELEASE//./}-32
+              dlUri: https://downloads.haskell.org/~cabal/cabal-install-$RELEASE/cabal-install-$RELEASE-i386-linux-alpine3_12.tar.xz
+              dlSubdir: cabal-install-$RELEASE
+              dlHash: $(sha256sum "cabal-install-$RELEASE-i386-linux-alpine3_12.tar.xz" | awk '{ print $1 }')
+          Linux_Alpine:
+            unknown_versioning: *cabal-${RELEASE//./}-32
+          Linux_Debian:
+            '( >= 9 )':
+              dlUri: https://downloads.haskell.org/~cabal/cabal-install-$RELEASE/cabal-install-$RELEASE-i386-linux-deb9.tar.xz
+              dlSubdir: cabal-install-$RELEASE
+              dlHash: $(sha256sum "cabal-install-$RELEASE-i386-linux-deb9.tar.xz" | awk '{ print $1 }')
+            unknown_versioning: *cabal-${RELEASE//./}-32
+        A_ARM64:
+          Darwin:
+            unknown_versioning:
+              dlUri: https://downloads.haskell.org/~cabal/cabal-install-$RELEASE/cabal-install-$RELEASE-aarch64-darwin.tar.xz
+              dlSubdir: cabal-install-$RELEASE
+              dlHash: $(sha256sum "cabal-install-$RELEASE-aarch64-darwin.tar.xz" | awk '{ print $1 }')
+          Linux_Debian:
+            '( >= 10 && < 11)': &cabal-31020-arm64
+              dlUri: https://downloads.haskell.org/~cabal/cabal-install-$RELEASE/cabal-install-$RELEASE-aarch64-linux-deb10.tar.xz
+              dlSubdir: cabal-install-$RELEASE
+              dlHash: $(sha256sum "cabal-install-$RELEASE-aarch64-linux-deb10.tar.xz" | awk '{ print $1 }')
+            '( >= 11)':
+              dlUri: https://downloads.haskell.org/~cabal/cabal-install-$RELEASE/cabal-install-$RELEASE-aarch64-linux-deb11.tar.xz
+              dlSubdir: cabal-install-$RELEASE
+              dlHash: $(sha256sum "cabal-install-$RELEASE-aarch64-linux-deb11.tar.xz" | awk '{ print $1 }')
+            unknown_versioning: *cabal-${RELEASE//./}-arm64
+          Linux_UnknownLinux:
+            unknown_versioning: *cabal-${RELEASE//./}-arm64
+EOF
diff --git a/cabal/scripts/release/download-artifacts-from-pipeline.py b/cabal/scripts/release/download-artifacts-from-pipeline.py
new file mode 100644
--- /dev/null
+++ b/cabal/scripts/release/download-artifacts-from-pipeline.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python3
+
+from pathlib import Path
+import argparse
+import json
+import logging
+import subprocess
+import gitlab
+import os
+
+logging.basicConfig(level=logging.INFO)
+
+def strip_prefix(s, prefix):
+    if s.startswith(prefix):
+        return s[len(prefix):]
+    else:
+        return None
+
+def job_triple(job_name):
+    bindists = {
+            "build-linux-alpine: [i386, alpine3_12, 9.0.2]": "i386-linux-alpine3_12",
+            "build-linux-alpine: [x86_64, alpine3_12]": "x86_64-linux-alpine3_12",
+            "build-linux: [aarch64, aarch64-linux, deb10]": "aarch64-linux-deb10",
+            "build-linux: [aarch64, aarch64-linux, deb11]": "aarch64-linux-deb11",
+            "build-linux: [i386, x86_64-linux, deb9]": "i386-linux-deb9",
+            "build-linux: [x86_64, x86_64-linux, centos7]": "x86_64-linux-centos7",
+            "build-linux: [x86_64, x86_64-linux, deb10]": "x86_64-linux-deb10",
+            "build-linux: [x86_64, x86_64-linux, deb11]": "x86_64-linux-deb11",
+            "build-linux: [x86_64, x86_64-linux, deb9]": "x86_64-linux-deb9",
+            "build-linux: [x86_64, x86_64-linux, fedora33]": "x86_64-linux-fedora33",
+            "build-linux: [x86_64, x86_64-linux, rocky8]": "x86_64-linux-rocky8",
+            "build-linux: [x86_64, x86_64-linux, ubuntu18_04]": "x86_64-linux-ubuntu18_04",
+            "build-linux: [x86_64, x86_64-linux, ubuntu20_04]": "x86_64-linux-ubuntu20_04",
+            "build-x86_64-windows": "x86_64-windows",
+            "build-aarch64-darwin": "aarch64-darwin",
+            "build-x86_64-darwin": "x86_64-darwin",
+    }
+
+    if job_name in bindists:
+        return bindists[job_name]
+    else:
+        return None
+
+class UnhandledJobException(Exception):
+    # Raised when there is a release job in the pipeline but we don"t explicitly handle it.
+    def __init__(self, name):
+        self.message = f"{name} is a release job but not downloaded"
+        super().__init__(self.message)
+
+def fetch_artifacts(release: str, pipeline_id: int,
+                    dest_dir: Path, gl: gitlab.Gitlab):
+    dest_dir.mkdir(exist_ok=True)
+    # Write the pipeline id into output directory
+    with open(f"{dest_dir}/metadata.json", "w") as out: json.dump({ "pipeline_id": pipeline_id }, out)
+
+    proj = gl.projects.get("haskell/cabal")
+    pipeline = proj.pipelines.get(pipeline_id)
+    tmpdir = Path("fetch-gitlab")
+    tmpdir.mkdir(exist_ok=True)
+    for pipeline_job in pipeline.jobs.list(all=True):
+        if len(pipeline_job.artifacts) == 0:
+            logging.info(f"job {pipeline_job.name} ({pipeline_job.id}) has no artifacts")
+            continue
+
+        job = proj.jobs.get(pipeline_job.id)
+        triple = job_triple(job.name)
+        if triple is None:
+            if job.name.startswith("build"):
+                raise(UnhandledJobException(job.name))
+            logging.info(f"ignoring {job.name}")
+            continue
+
+        try:
+            destdir = tmpdir / job.name
+            zip_name = Path(f"{tmpdir}/{job.name}.zip")
+            if not zip_name.exists() or zip_name.stat().st_size == 0:
+                logging.info(f"downloading archive {zip_name} for job {job.name} (job {job.id})...")
+                with open(zip_name, "wb") as f:
+                    job.artifacts(streamed=True, action=f.write)
+
+            if zip_name.stat().st_size == 0:
+                logging.info(f"artifact archive for job {job.name} (job {job.id}) is empty")
+                continue
+
+            subprocess.run(["unzip", "-bo", zip_name, "-d", destdir])
+
+            if job.name == "build-x86_64-windows":
+                bindist_files = list(destdir.glob("out/cabal-install*.zip"))
+                bindist = bindist_files[0]
+                dest = dest_dir / bindist.name
+                final_destination = Path("../../release") / Path(bindist.name)
+                bindist.rename(final_destination)
+                logging.info(f"Extracted {job.name} to {final_destination}")
+            else:
+                bindist_files = list(destdir.glob("out/cabal-install*.tar.xz"))
+                logging.info(f"bindist_files: {bindist_files}")
+                bindist = bindist_files[0]
+                logging.info(f"Bindist: {bindist}")
+                dest = dest_dir / bindist.name
+                final_destination = Path("../../release") / Path(bindist.name)
+                bindist.rename(final_destination)
+
+        except Exception as e:
+            logging.error(f"Error fetching job {job.name}: \"{e}\"")
+            pass
+
+def main():
+    parser = argparse.ArgumentParser()
+    parser.add_argument("--pipeline", "-p", required=True, type=int, help="pipeline id")
+    parser.add_argument("--release", "-r", required=True, type=str, help="release name")
+    parser.add_argument("--output", "-o", type=Path, default=Path.cwd(), help="output directory")
+    parser.add_argument("--profile", "-P", default="haskell",
+                        help="python-gitlab.cfg profile name")
+    args = parser.parse_args()
+    gl = gitlab.Gitlab.from_config(args.profile)
+    fetch_artifacts(args.release, args.pipeline,
+                    dest_dir=args.output, gl=gl)
+
+if __name__ == "__main__":
+    main()
+
diff --git a/cabal/scripts/release/download-cabal-install-release-binaries.sh b/cabal/scripts/release/download-cabal-install-release-binaries.sh
new file mode 100644
--- /dev/null
+++ b/cabal/scripts/release/download-cabal-install-release-binaries.sh
@@ -0,0 +1,42 @@
+#!/usr/bin/env bash
+
+# A script to download the release binary files for a given cabal release
+# from upstream "downlods.haskell.org".
+# It accepts the first and only argument as the release number.
+#
+# useage:-
+#   $ download-cabal-install-release-binaries.sh "3.10.1.0"
+#
+# This was initally made to be used with ./create-release-metadata-for-ghcup.sh
+
+set -eu
+set -o pipefail
+
+RELEASE=$1
+
+echo "RELEASE: $RELEASE"
+
+for com in wget sha256sum ; do
+        command -V ${com} >/dev/null 2>&1
+done
+
+[ ! -d "binary-downloads/cabal-install-${RELEASE}-binaries" ]
+
+mkdir -p "binary-downloads/cabal-install-${RELEASE}-binaries"
+
+cd "binary-downloads/cabal-install-${RELEASE}-binaries"
+
+## Download release files
+echo "Downloading form: \"https://downloads.haskell.org/~cabal/cabal-install-${RELEASE}/\""
+wget --no-parent -r --reject "index.html*" --no-directories "https://downloads.haskell.org/~cabal/cabal-install-${RELEASE}/"
+
+## Verify that sha256 sums of downloaded files match the ones mentioned in the upstream SHA256SUMS file
+echo "verifying checksums for downloaded files..."
+
+if sha256sum --check ./SHA256SUMS; then
+    echo "All checksums match!"
+    echo "Successfully downloaded binaries for release: ${RELEASE}"
+else
+    echo "checksums of downloaded files do no match the ones listed in upstream SHA256SUMS file."
+    echo "please try deleting \"binary-downloads/cabal-install-${RELEASE}-binaries\" folder and downloading again."
+fi
diff --git a/cabal/solver-benchmarks/HackageBenchmark.hs b/cabal/solver-benchmarks/HackageBenchmark.hs
--- a/cabal/solver-benchmarks/HackageBenchmark.hs
+++ b/cabal/solver-benchmarks/HackageBenchmark.hs
@@ -213,14 +213,14 @@
   putStrLn $ "Cabal directory (for " ++ cabal ++ ") " ++ cabalDir
   createDirectoryIfMissing True cabalDir
 
-  -- shell enviroment
+  -- shell environment
   currEnv <- Map.fromList <$>  getEnvironment
   let thisEnv :: [(String, String)]
       thisEnv = Map.toList $ currEnv
           & Map.insert "CABAL_CONFIG" (cabalDir </> "config")
           & Map.insert "CABAL_DIR"     cabalDir
 
-  -- Run cabal update, 
+  -- Run cabal update,
   putStrLn $ "Running cabal update (using " ++ cabal ++ ") ..."
   (ec, uout, uerr) <- readCreateProcessWithExitCode (proc cabal ["update"])
       { cwd = Just cabalDir
diff --git a/cabal/solver-benchmarks/LICENSE b/cabal/solver-benchmarks/LICENSE
--- a/cabal/solver-benchmarks/LICENSE
+++ b/cabal/solver-benchmarks/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2003-2022, Cabal Development Team.
+Copyright (c) 2003-2023, Cabal Development Team.
 See the AUTHORS file for the full list of copyright holders.
 
 See */LICENSE for the copyright holders of the subcomponents.
diff --git a/cabal/solver-benchmarks/solver-benchmarks.cabal b/cabal/solver-benchmarks/solver-benchmarks.cabal
--- a/cabal/solver-benchmarks/solver-benchmarks.cabal
+++ b/cabal/solver-benchmarks/solver-benchmarks.cabal
@@ -1,7 +1,7 @@
 cabal-version:  2.2
 name:          solver-benchmarks
 version:       3
-copyright:     2003-2022, Cabal Development Team (see AUTHORS file)
+copyright:     2003-2023, Cabal Development Team (see AUTHORS file)
 license:       BSD-3-Clause
 license-file:  LICENSE
 author:        Cabal Development Team <cabal-devel@haskell.org>
@@ -31,13 +31,13 @@
     base,
     bytestring,
     containers,
-    Cabal-syntax ^>=3.8,
+    Cabal-syntax ^>= 3.10,
     directory,
     filepath,
     optparse-applicative,
     process,
     time,
-    statistics >= 0.14 && < 0.16,
+    statistics >= 0.14 && < 0.17,
     vector
   default-language: Haskell2010
 
@@ -58,7 +58,7 @@
   build-depends:
     base,
     solver-benchmarks,
-    statistics >= 0.14 && < 0.16,
+    statistics >= 0.14 && < 0.17,
     tasty,
     tasty-hunit
   default-language: Haskell2010
diff --git a/cabal/templates/Lexer.x b/cabal/templates/Lexer.x
--- a/cabal/templates/Lexer.x
+++ b/cabal/templates/Lexer.x
@@ -83,22 +83,22 @@
 tokens :-
 
 <0> {
-  @bom?  { \_ len _ -> do
-              when (len /= 0) $ addWarning LexWarningBOM
+  @bom?  { \pos len _ -> do
+              when (len /= 0) $ addWarningAt pos LexWarningBOM
               setStartCode bol_section
               lexToken
          }
 }
 
 <bol_section, bol_field_layout, bol_field_braces> {
-  @nbspspacetab* @nl         { \_pos len inp -> checkWhitespace len inp >> adjustPos retPos >> lexToken }
+  @nbspspacetab* @nl         { \pos len inp -> checkWhitespace pos len inp >> adjustPos retPos >> lexToken }
   -- no @nl here to allow for comments on last line of the file with no trailing \n
   $spacetab* "--" $comment*  ;  -- TODO: check the lack of @nl works here
                                 -- including counting line numbers
 }
 
 <bol_section> {
-  @nbspspacetab*   { \pos len inp -> checkLeadingWhitespace len inp >>
+  @nbspspacetab*   { \pos len inp -> checkLeadingWhitespace pos len inp >>
                                      if B.length inp == len
                                        then return (L pos EOF)
                                        else setStartCode in_section
@@ -123,7 +123,7 @@
 }
 
 <bol_field_layout> {
-  @nbspspacetab* { \pos len inp -> checkLeadingWhitespace len inp >>= \len' ->
+  @nbspspacetab* { \pos len inp -> checkLeadingWhitespace pos len inp >>= \len' ->
                                   if B.length inp == len
                                     then return (L pos EOF)
                                     else setStartCode in_field_layout
@@ -172,17 +172,17 @@
 tok :: Token -> Position -> Int -> ByteString -> Lex LToken
 tok  t pos _len _input = return $! L pos t
 
-checkLeadingWhitespace :: Int -> ByteString -> Lex Int
-checkLeadingWhitespace len bs
+checkLeadingWhitespace :: Position -> Int -> ByteString -> Lex Int
+checkLeadingWhitespace pos len bs
     | B.any (== 9) (B.take len bs) = do
-        addWarning LexWarningTab
-        checkWhitespace len bs
-    | otherwise = checkWhitespace len bs
+        addWarningAt pos LexWarningTab
+        checkWhitespace pos len bs
+    | otherwise = checkWhitespace pos len bs
 
-checkWhitespace :: Int -> ByteString -> Lex Int
-checkWhitespace len bs
+checkWhitespace :: Position -> Int -> ByteString -> Lex Int
+checkWhitespace pos len bs
     | B.any (== 194) (B.take len bs) = do
-        addWarning LexWarningNBSP
+        addWarningAt pos LexWarningNBSP
         return $ len - B.count 194 (B.take len bs)
     | otherwise = return len
 
diff --git a/cabal/templates/Paths_pkg.template.hs b/cabal/templates/Paths_pkg.template.hs
--- a/cabal/templates/Paths_pkg.template.hs
+++ b/cabal/templates/Paths_pkg.template.hs
@@ -7,6 +7,11 @@
 {% if not absolute %}
 {-# LANGUAGE ForeignFunctionInterface #-}
 {% endif %}
+{% if supportsCpp %}
+#if __GLASGOW_HASKELL__ >= 810
+{-# OPTIONS_GHC -Wno-prepositive-qualified-module #-}
+#endif
+{% endif %}
 {-# OPTIONS_GHC -fno-warn-missing-import-lists #-}
 {-# OPTIONS_GHC -w #-}
 module Paths_{{ manglePkgName packageName }} (
@@ -58,6 +63,28 @@
 
 getBinDir, getLibDir, getDynLibDir, getDataDir, getLibexecDir, getSysconfDir :: IO FilePath
 
+{% defblock function_defs %}
+minusFileName :: FilePath -> String -> FilePath
+minusFileName dir ""     = dir
+minusFileName dir "."    = dir
+minusFileName dir suffix =
+  minusFileName (fst (splitFileName dir)) (fst (splitFileName suffix))
+
+splitFileName :: FilePath -> (String, String)
+splitFileName p = (reverse (path2++drive), reverse fname)
+  where
+    (path,drive) = case p of
+      (c:':':p') -> (reverse p',[':',c])
+      _          -> (reverse p ,"")
+    (fname,path1) = break isPathSeparator path
+    path2 = case path1 of
+      []                           -> "."
+      [_]                          -> path1   -- don't remove the trailing slash if
+                                              -- there is only one character
+      (c:path') | isPathSeparator c -> path'
+      _                             -> path1
+{% endblock %}
+
 {# body #}
 {# ######################################################################### #}
 
@@ -76,6 +103,8 @@
 getLibexecDir = catchIO (getEnv "{{ manglePkgName packageName }}_libexecdir") (\_ -> getPrefixDirReloc $ {{ libexecdir }})
 getSysconfDir = catchIO (getEnv "{{ manglePkgName packageName }}_sysconfdir") (\_ -> getPrefixDirReloc $ {{ sysconfdir }})
 
+{% useblock function_defs %}
+
 {% elif absolute %}
 
 bindir, libdir, dynlibdir, datadir, libexecdir, sysconfdir :: FilePath
@@ -118,6 +147,8 @@
               return ((bindir `minusFileName` {{ bindir}}) `joinFileName` dirRel)
             | otherwise  -> try_size (size * 2)
 
+{% useblock function_defs %}
+
 {% if isI386 %}
 foreign import stdcall unsafe "windows.h GetModuleFileNameW"
   c_GetModuleFileName :: Ptr () -> CWString -> Int32 -> IO Int32
@@ -139,28 +170,6 @@
 
 {# filename stuff                                                            #}
 {# ######################################################################### #}
-
-{% if not absolute %}
-minusFileName :: FilePath -> String -> FilePath
-minusFileName dir ""     = dir
-minusFileName dir "."    = dir
-minusFileName dir suffix =
-  minusFileName (fst (splitFileName dir)) (fst (splitFileName suffix))
-
-splitFileName :: FilePath -> (String, String)
-splitFileName p = (reverse (path2++drive), reverse fname)
-  where
-    (path,drive) = case p of
-       (c:':':p') -> (reverse p',[':',c])
-       _          -> (reverse p ,"")
-    (fname,path1) = break isPathSeparator path
-    path2 = case path1 of
-      []                           -> "."
-      [_]                          -> path1   -- don't remove the trailing slash if
-                                              -- there is only one character
-      (c:path') | isPathSeparator c -> path'
-      _                             -> path1
-{% endif %}
 
 joinFileName :: String -> String -> FilePath
 joinFileName ""  fname = fname
diff --git a/cabal/templates/SPDX.LicenseExceptionId.template.hs b/cabal/templates/SPDX.LicenseExceptionId.template.hs
--- a/cabal/templates/SPDX.LicenseExceptionId.template.hs
+++ b/cabal/templates/SPDX.LicenseExceptionId.template.hs
@@ -28,7 +28,7 @@
 -- LicenseExceptionId
 -------------------------------------------------------------------------------
 
--- | SPDX License Exceptions identifiers list v3.16 
+-- | SPDX License Exceptions identifiers list v3.16
 data LicenseExceptionId
 {{ licenseIds }}
   deriving (Eq, Ord, Enum, Bounded, Show, Read, Typeable, Data, Generic)
diff --git a/cabal/templates/SPDX.LicenseId.template.hs b/cabal/templates/SPDX.LicenseId.template.hs
--- a/cabal/templates/SPDX.LicenseId.template.hs
+++ b/cabal/templates/SPDX.LicenseId.template.hs
@@ -31,7 +31,7 @@
 -- LicenseId
 -------------------------------------------------------------------------------
 
--- | SPDX License identifiers list v3.16 
+-- | SPDX License identifiers list v3.16
 data LicenseId
 {{ licenseIds }}
   deriving (Eq, Ord, Enum, Bounded, Show, Read, Typeable, Data)
diff --git a/cabal/tests/IntegrationTests2/config/default-config b/cabal/tests/IntegrationTests2/config/default-config
new file mode 100644
--- /dev/null
+++ b/cabal/tests/IntegrationTests2/config/default-config
@@ -0,0 +1,246 @@
+-- This is the configuration file for the 'cabal' command line tool.
+--
+-- The available configuration options are listed below.
+-- Some of them have default values listed.
+--
+-- Lines (like this one) beginning with '--' are comments.
+-- Be careful with spaces and indentation because they are
+-- used to indicate layout for nested sections.
+--
+-- This config file was generated using the following versions
+-- of Cabal and cabal-install:
+-- Cabal library version: 3.11.0.0
+-- cabal-install version: 3.11
+
+
+repository hackage.haskell.org
+  url: http://hackage.haskell.org/
+  -- secure: True
+  -- root-keys:
+  -- key-threshold: 3
+
+-- ignore-expiry: False
+-- http-transport:
+-- nix:
+-- store-dir:
+-- active-repositories:
+-- local-no-index-repo:
+remote-repo-cache: /home/colton/.cabal/packages
+-- logs-dir: /home/colton/.cabal/logs
+-- default-user-config:
+-- verbose: 1
+-- compiler: ghc
+-- cabal-file:
+-- with-compiler:
+-- with-hc-pkg:
+-- program-prefix: 
+-- program-suffix: 
+-- library-vanilla: True
+-- library-profiling:
+-- shared:
+-- static:
+-- executable-dynamic: False
+-- executable-static: False
+-- profiling:
+-- executable-profiling:
+-- profiling-detail:
+-- library-profiling-detail:
+-- optimization: True
+-- debug-info: False
+-- build-info:
+-- library-for-ghci:
+-- split-sections: False
+-- split-objs: False
+-- executable-stripping:
+-- library-stripping:
+-- configure-option:
+-- user-install: True
+-- package-db:
+-- flags:
+-- extra-include-dirs:
+-- deterministic:
+-- cid:
+-- extra-lib-dirs:
+-- extra-lib-dirs-static:
+-- extra-framework-dirs:
+extra-prog-path: /home/colton/.cabal/bin
+-- instantiate-with:
+-- tests: False
+-- coverage: False
+-- library-coverage:
+-- exact-configuration: False
+-- benchmarks: False
+-- relocatable: False
+-- response-files:
+-- allow-depending-on-private-libs:
+-- cabal-lib-version:
+-- append:
+-- backup:
+-- constraint:
+-- preference:
+-- solver: modular
+-- allow-older: False
+-- allow-newer: False
+-- write-ghc-environment-files:
+-- documentation: False
+-- doc-index-file: $datadir/doc/$arch-$os-$compiler/index.html
+-- only-download: False
+-- target-package-db:
+-- max-backjumps: 4000
+-- reorder-goals: False
+-- count-conflicts: True
+-- fine-grained-conflicts: True
+-- minimize-conflict-set: False
+-- independent-goals: False
+-- prefer-oldest: False
+-- shadow-installed-packages: False
+-- strong-flags: False
+-- allow-boot-library-installs: False
+-- reject-unconstrained-dependencies: none
+-- reinstall: False
+-- avoid-reinstalls: False
+-- force-reinstalls: False
+-- upgrade-dependencies: False
+-- index-state:
+-- root-cmd:
+-- symlink-bindir:
+build-summary: /home/colton/.cabal/logs/build.log
+-- build-log:
+remote-build-reporting: none
+-- report-planning-failure: False
+-- per-component: True
+-- run-tests:
+jobs: $ncpus
+-- keep-going: False
+-- offline: False
+-- lib: False
+-- package-env:
+-- overwrite-policy:
+-- install-method:
+installdir: /home/colton/.cabal/bin
+-- username:
+-- password:
+-- password-command:
+-- builddir:
+
+haddock
+  -- keep-temp-files: False
+  -- hoogle: False
+  -- html: False
+  -- html-location:
+  -- executables: False
+  -- tests: False
+  -- benchmarks: False
+  -- foreign-libraries: False
+  -- all:
+  -- internal: False
+  -- css:
+  -- hyperlink-source: False
+  -- quickjump: False
+  -- hscolour-css:
+  -- contents-location:
+  -- index-location:
+  -- base-url:
+  -- lib:
+  -- output-dir:
+
+init
+  -- interactive: False
+  -- quiet: False
+  -- no-comments: False
+  -- minimal: False
+  -- cabal-version: 3.0
+  -- license:
+  -- extra-doc-file:
+  -- tests:
+  -- test-dir:
+  -- simple: False
+  -- language: Haskell2010
+  -- application-dir: app
+  -- source-dir: src
+
+install-dirs user
+  -- prefix: /home/colton/.cabal
+  -- bindir: $prefix/bin
+  -- libdir: $prefix/lib
+  -- libsubdir: $abi/$libname
+  -- dynlibdir: $libdir/$abi
+  -- libexecdir: $prefix/libexec
+  -- libexecsubdir: $abi/$pkgid
+  -- datadir: $prefix/share
+  -- datasubdir: $abi/$pkgid
+  -- docdir: $datadir/doc/$abi/$pkgid
+  -- htmldir: $docdir/html
+  -- haddockdir: $htmldir
+  -- sysconfdir: $prefix/etc
+
+install-dirs global
+  -- prefix: /usr/local
+  -- bindir: $prefix/bin
+  -- libdir: $prefix/lib
+  -- libsubdir: $abi/$libname
+  -- dynlibdir: $libdir/$abi
+  -- libexecdir: $prefix/libexec
+  -- libexecsubdir: $abi/$pkgid
+  -- datadir: $prefix/share
+  -- datasubdir: $abi/$pkgid
+  -- docdir: $datadir/doc/$abi/$pkgid
+  -- htmldir: $docdir/html
+  -- haddockdir: $htmldir
+  -- sysconfdir: $prefix/etc
+
+program-locations
+  -- alex-location:
+  -- ar-location:
+  -- c2hs-location:
+  -- cpphs-location:
+  -- doctest-location:
+  -- gcc-location:
+  -- ghc-location:
+  -- ghc-pkg-location:
+  -- ghcjs-location:
+  -- ghcjs-pkg-location:
+  -- greencard-location:
+  -- haddock-location:
+  -- happy-location:
+  -- haskell-suite-location:
+  -- haskell-suite-pkg-location:
+  -- hmake-location:
+  -- hpc-location:
+  -- hsc2hs-location:
+  -- hscolour-location:
+  -- jhc-location:
+  -- ld-location:
+  -- pkg-config-location:
+  -- runghc-location:
+  -- strip-location:
+  -- tar-location:
+  -- uhc-location:
+
+program-default-options
+  -- alex-options:
+  -- ar-options:
+  -- c2hs-options:
+  -- cpphs-options:
+  -- doctest-options:
+  -- gcc-options:
+  -- ghc-options:
+  -- ghc-pkg-options:
+  -- ghcjs-options:
+  -- ghcjs-pkg-options:
+  -- greencard-options:
+  -- haddock-options:
+  -- happy-options:
+  -- haskell-suite-options:
+  -- haskell-suite-pkg-options:
+  -- hmake-options:
+  -- hpc-options:
+  -- hsc2hs-options:
+  -- hscolour-options:
+  -- jhc-options:
+  -- ld-options:
+  -- pkg-config-options:
+  -- runghc-options:
+  -- strip-options:
+  -- tar-options:
+  -- uhc-options:
diff --git a/cabal/tests/IntegrationTests2/nix-config/default-config b/cabal/tests/IntegrationTests2/nix-config/default-config
new file mode 100644
--- /dev/null
+++ b/cabal/tests/IntegrationTests2/nix-config/default-config
@@ -0,0 +1,246 @@
+-- This is the configuration file for the 'cabal' command line tool.
+--
+-- The available configuration options are listed below.
+-- Some of them have default values listed.
+--
+-- Lines (like this one) beginning with '--' are comments.
+-- Be careful with spaces and indentation because they are
+-- used to indicate layout for nested sections.
+--
+-- This config file was generated using the following versions
+-- of Cabal and cabal-install:
+-- Cabal library version: 3.11.0.0
+-- cabal-install version: 3.11
+
+
+repository hackage.haskell.org
+  url: http://hackage.haskell.org/
+  -- secure: True
+  -- root-keys:
+  -- key-threshold: 3
+
+-- ignore-expiry: False
+-- http-transport:
+-- nix:
+-- store-dir:
+-- active-repositories:
+-- local-no-index-repo:
+remote-repo-cache: /home/colton/.cabal/packages
+-- logs-dir: /home/colton/.cabal/logs
+-- default-user-config:
+-- verbose: 1
+-- compiler: ghc
+-- cabal-file:
+-- with-compiler:
+-- with-hc-pkg:
+-- program-prefix: 
+-- program-suffix: 
+-- library-vanilla: True
+-- library-profiling:
+-- shared:
+-- static:
+-- executable-dynamic: False
+-- executable-static: False
+-- profiling:
+-- executable-profiling:
+-- profiling-detail:
+-- library-profiling-detail:
+-- optimization: True
+-- debug-info: False
+-- build-info:
+-- library-for-ghci:
+-- split-sections: False
+-- split-objs: False
+-- executable-stripping:
+-- library-stripping:
+-- configure-option:
+-- user-install: True
+-- package-db:
+-- flags:
+-- extra-include-dirs:
+-- deterministic:
+-- cid:
+-- extra-lib-dirs:
+-- extra-lib-dirs-static:
+-- extra-framework-dirs:
+extra-prog-path: /home/colton/.cabal/bin
+-- instantiate-with:
+-- tests: False
+-- coverage: False
+-- library-coverage:
+-- exact-configuration: False
+-- benchmarks: False
+-- relocatable: False
+-- response-files:
+-- allow-depending-on-private-libs:
+-- cabal-lib-version:
+-- append:
+-- backup:
+-- constraint:
+-- preference:
+-- solver: modular
+-- allow-older: False
+-- allow-newer: False
+-- write-ghc-environment-files:
+-- documentation: False
+-- doc-index-file: $datadir/doc/$arch-$os-$compiler/index.html
+-- only-download: False
+-- target-package-db:
+-- max-backjumps: 4000
+-- reorder-goals: False
+-- count-conflicts: True
+-- fine-grained-conflicts: True
+-- minimize-conflict-set: False
+-- independent-goals: False
+-- prefer-oldest: False
+-- shadow-installed-packages: False
+-- strong-flags: False
+-- allow-boot-library-installs: False
+-- reject-unconstrained-dependencies: none
+-- reinstall: False
+-- avoid-reinstalls: False
+-- force-reinstalls: False
+-- upgrade-dependencies: False
+-- index-state:
+-- root-cmd:
+-- symlink-bindir:
+build-summary: /home/colton/.cabal/logs/build.log
+-- build-log:
+remote-build-reporting: none
+-- report-planning-failure: False
+-- per-component: True
+-- run-tests:
+jobs: $ncpus
+-- keep-going: False
+-- offline: False
+-- lib: False
+-- package-env:
+-- overwrite-policy:
+-- install-method:
+installdir: /home/colton/.cabal/bin
+-- username:
+-- password:
+-- password-command:
+-- builddir:
+
+haddock
+  -- keep-temp-files: False
+  -- hoogle: False
+  -- html: False
+  -- html-location:
+  -- executables: False
+  -- tests: False
+  -- benchmarks: False
+  -- foreign-libraries: False
+  -- all:
+  -- internal: False
+  -- css:
+  -- hyperlink-source: False
+  -- quickjump: False
+  -- hscolour-css:
+  -- contents-location:
+  -- index-location:
+  -- base-url:
+  -- lib:
+  -- output-dir:
+
+init
+  -- interactive: False
+  -- quiet: False
+  -- no-comments: False
+  -- minimal: False
+  -- cabal-version: 3.0
+  -- license:
+  -- extra-doc-file:
+  -- tests:
+  -- test-dir:
+  -- simple: False
+  -- language: Haskell2010
+  -- application-dir: app
+  -- source-dir: src
+
+install-dirs user
+  -- prefix: /home/colton/.cabal
+  -- bindir: $prefix/bin
+  -- libdir: $prefix/lib
+  -- libsubdir: $abi/$libname
+  -- dynlibdir: $libdir/$abi
+  -- libexecdir: $prefix/libexec
+  -- libexecsubdir: $abi/$pkgid
+  -- datadir: $prefix/share
+  -- datasubdir: $abi/$pkgid
+  -- docdir: $datadir/doc/$abi/$pkgid
+  -- htmldir: $docdir/html
+  -- haddockdir: $htmldir
+  -- sysconfdir: $prefix/etc
+
+install-dirs global
+  -- prefix: /usr/local
+  -- bindir: $prefix/bin
+  -- libdir: $prefix/lib
+  -- libsubdir: $abi/$libname
+  -- dynlibdir: $libdir/$abi
+  -- libexecdir: $prefix/libexec
+  -- libexecsubdir: $abi/$pkgid
+  -- datadir: $prefix/share
+  -- datasubdir: $abi/$pkgid
+  -- docdir: $datadir/doc/$abi/$pkgid
+  -- htmldir: $docdir/html
+  -- haddockdir: $htmldir
+  -- sysconfdir: $prefix/etc
+
+program-locations
+  -- alex-location:
+  -- ar-location:
+  -- c2hs-location:
+  -- cpphs-location:
+  -- doctest-location:
+  -- gcc-location:
+  -- ghc-location:
+  -- ghc-pkg-location:
+  -- ghcjs-location:
+  -- ghcjs-pkg-location:
+  -- greencard-location:
+  -- haddock-location:
+  -- happy-location:
+  -- haskell-suite-location:
+  -- haskell-suite-pkg-location:
+  -- hmake-location:
+  -- hpc-location:
+  -- hsc2hs-location:
+  -- hscolour-location:
+  -- jhc-location:
+  -- ld-location:
+  -- pkg-config-location:
+  -- runghc-location:
+  -- strip-location:
+  -- tar-location:
+  -- uhc-location:
+
+program-default-options
+  -- alex-options:
+  -- ar-options:
+  -- c2hs-options:
+  -- cpphs-options:
+  -- doctest-options:
+  -- gcc-options:
+  -- ghc-options:
+  -- ghc-pkg-options:
+  -- ghcjs-options:
+  -- ghcjs-pkg-options:
+  -- greencard-options:
+  -- haddock-options:
+  -- happy-options:
+  -- haskell-suite-options:
+  -- haskell-suite-pkg-options:
+  -- hmake-options:
+  -- hpc-options:
+  -- hsc2hs-options:
+  -- hscolour-options:
+  -- jhc-options:
+  -- ld-options:
+  -- pkg-config-options:
+  -- runghc-options:
+  -- strip-options:
+  -- tar-options:
+  -- uhc-options:
diff --git a/cabal/validate.sh b/cabal/validate.sh
--- a/cabal/validate.sh
+++ b/cabal/validate.sh
@@ -369,6 +369,7 @@
 step_build() {
 print_header "build"
 timed $CABALNEWBUILD $TARGETS --dry-run || exit 1
+$CABALPLAN topo --builddir=$BUILDDIR || exit 1
 timed $CABALNEWBUILD $TARGETS || exit 1
 }
 
diff --git a/hackport.cabal b/hackport.cabal
--- a/hackport.cabal
+++ b/hackport.cabal
@@ -1,6 +1,6 @@
 cabal-version: 3.0
 name:          hackport
-version:       0.8.5.2
+version:       0.9.0.0
 license:       GPL-3.0-or-later
 license-file:  LICENSE
 author:        Henning Günther, Duncan Coutts, Lennart Kolmodin
@@ -25,6 +25,7 @@
   , GHC == 9.4.8
   , GHC == 9.6.6
   , GHC == 9.8.2
+  , GHC == 9.10.1
 
 source-repository head
   type:     git
@@ -87,7 +88,7 @@
   hs-source-dirs:   cabal/Cabal-syntax/src
   build-depends:
     , array         >=0.4.0.1
-    , base          >=4.6      && <5
+    , base          >=4.9     && <5
     , binary        >=0.7
     , bytestring    >=0.10.0.0
     , containers    >=0.5.0.0
@@ -276,7 +277,7 @@
   build-depends:
     , hackport-external-libs-Cabal-syntax
     , array         >=0.4.0.1
-    , base          >=4.6      && <5
+    , base          >=4.9      && <5
     , bytestring    >=0.10.0.0
     , containers    >=0.5.0.0
     , deepseq       >=1.3.0.1
@@ -301,6 +302,9 @@
     Distribution.Backpack.ModSubst
     Distribution.Backpack.ModuleShape
     Distribution.Backpack.PreModuleShape
+    Distribution.Utils.IOData
+    Distribution.Utils.LogProgress
+    Distribution.Utils.MapAccum
 --     Distribution.Compat.CreatePipe
     Distribution.Compat.Directory
     Distribution.Compat.Environment
@@ -318,6 +322,7 @@
     Distribution.Simple.Bench
     Distribution.Simple.Build
     Distribution.Simple.Build.Macros
+    Distribution.Simple.Build.PackageInfoModule
     Distribution.Simple.Build.PathsModule
     Distribution.Simple.BuildPaths
     Distribution.Simple.BuildTarget
@@ -326,6 +331,7 @@
     Distribution.Simple.Command
     Distribution.Simple.Compiler
     Distribution.Simple.Configure
+    Distribution.Simple.ConfigureScript
     Distribution.Simple.Flag
     Distribution.Simple.GHC
     Distribution.Simple.GHCJS
@@ -376,10 +382,7 @@
     Distribution.Types.LocalBuildInfo
     Distribution.Types.PackageName.Magic
     Distribution.Types.TargetInfo
-    Distribution.Utils.IOData
     Distribution.Utils.Json
-    Distribution.Utils.LogProgress
-    Distribution.Utils.MapAccum
     Distribution.Utils.NubList
     Distribution.Utils.Progress
     Distribution.Verbosity
@@ -399,6 +402,7 @@
     Distribution.GetOpt
     Distribution.Lex
     Distribution.Simple.Build.Macros.Z
+    Distribution.Simple.Build.PackageInfoModule.Z
     Distribution.Simple.Build.PathsModule.Z
     Distribution.Simple.GHC.EnvironmentParser
     Distribution.Simple.GHC.Internal
@@ -560,6 +564,7 @@
     , filepath      >=1.4.0.0
     , mtl           >=2.0
     , pretty        >=1.1
+    , text          >=1.2.3.0
     , transformers  >=0.4.2.0
 
   exposed-modules:
@@ -632,7 +637,7 @@
     , containers                               >=0.5.6.2
     , cryptohash-sha256                        >=0.11
     , deepseq                                  >=1.4.1.1
-    , directory                                >=1.2.2.0
+    , directory                                >=1.3.7.0
     , echo                                     >=0.1.3
     , edit-distance                            >=0.2.2
     , exceptions                               >=0.10.4
@@ -654,6 +659,7 @@
     , tar                                      >=0.5.0.3
     , text                                     >=1.2.3
     , time                                     >=1.5.0.1
+    , unix                                     >=2.5
     , zlib                                     >=0.5.3
 
   exposed-modules:
@@ -661,76 +667,77 @@
     Distribution.Client.BuildReports.Lens
     Distribution.Client.BuildReports.Storage
     Distribution.Client.BuildReports.Types
---     Distribution.Client.BuildReports.Upload
---     Distribution.Client.Check
---     Distribution.Client.CmdBench
---     Distribution.Client.CmdBuild
---     Distribution.Client.CmdClean
---     Distribution.Client.CmdConfigure
---     Distribution.Client.CmdErrorMessages
---     Distribution.Client.CmdExec
---     Distribution.Client.CmdFreeze
---     Distribution.Client.CmdHaddock
---     Distribution.Client.CmdInstall
+    Distribution.Client.BuildReports.Upload
+    Distribution.Client.Check
+    Distribution.Client.CmdBench
+    Distribution.Client.CmdBuild
+    Distribution.Client.CmdClean
+    Distribution.Client.CmdConfigure
+    Distribution.Client.CmdErrorMessages
+    Distribution.Client.CmdExec
+    Distribution.Client.CmdFreeze
+    Distribution.Client.CmdHaddock
+    Distribution.Client.CmdHaddockProject
+    Distribution.Client.CmdInstall
     Distribution.Client.CmdInstall.ClientInstallFlags
---     Distribution.Client.CmdInstall.ClientInstallTargetSelector
---     Distribution.Client.CmdLegacy
---     Distribution.Client.CmdListBin
---     Distribution.Client.CmdOutdated
---     Distribution.Client.CmdRepl
---     Distribution.Client.CmdRun
---     Distribution.Client.CmdSdist
---     Distribution.Client.CmdTest
+    Distribution.Client.CmdInstall.ClientInstallTargetSelector
+    Distribution.Client.CmdLegacy
+    Distribution.Client.CmdListBin
+    Distribution.Client.CmdOutdated
+    Distribution.Client.CmdRepl
+    Distribution.Client.CmdRun
+    Distribution.Client.CmdSdist
+    Distribution.Client.CmdTest
     Distribution.Client.CmdUpdate
     Distribution.Client.Compat.Directory
     Distribution.Client.Compat.ExecutablePath
     Distribution.Client.Compat.Orphans
     Distribution.Client.Compat.Prelude
---     Distribution.Client.Compat.Process
     Distribution.Client.Compat.Semaphore
     Distribution.Client.Compat.Tar
     Distribution.Client.Config
---     Distribution.Client.Configure
+    Distribution.Client.Configure
     Distribution.Client.Dependency
     Distribution.Client.Dependency.Types
     Distribution.Client.DistDirLayout
---     Distribution.Client.Fetch
+    Distribution.Client.Fetch
     Distribution.Client.FetchUtils
     Distribution.Client.FileMonitor
---     Distribution.Client.Freeze
+    Distribution.Client.Freeze
     Distribution.Client.GZipUtils
---     Distribution.Client.GenBounds
---     Distribution.Client.Get
+    Distribution.Client.GenBounds
+    Distribution.Client.Get
     Distribution.Client.Glob
     Distribution.Client.GlobalFlags
---     Distribution.Client.Haddock
+    Distribution.Client.Haddock
     Distribution.Client.HashValue
     Distribution.Client.HttpUtils
     Distribution.Client.IndexUtils
     Distribution.Client.IndexUtils.ActiveRepos
     Distribution.Client.IndexUtils.IndexState
     Distribution.Client.IndexUtils.Timestamp
---     Distribution.Client.Init
+    Distribution.Client.Init
     Distribution.Client.Init.Defaults
---     Distribution.Client.Init.FileCreators
---     Distribution.Client.Init.FlagExtractors
---     Distribution.Client.Init.Format
---     Distribution.Client.Init.Interactive.Command
---     Distribution.Client.Init.Licenses
---     Distribution.Client.Init.NonInteractive.Command
---     Distribution.Client.Init.NonInteractive.Heuristics
---     Distribution.Client.Init.Prompt
---     Distribution.Client.Init.Simple
+    Distribution.Client.Init.FileCreators
+    Distribution.Client.Init.FlagExtractors
+    Distribution.Client.Init.Format
+    Distribution.Client.Init.Interactive.Command
+    Distribution.Client.Init.Licenses
+    Distribution.Client.Init.NonInteractive.Command
+    Distribution.Client.Init.NonInteractive.Heuristics
+    Distribution.Client.Init.Prompt
+    Distribution.Client.Init.Simple
     Distribution.Client.Init.Types
---     Distribution.Client.Init.Utils
---     Distribution.Client.Install
+    Distribution.Client.Init.Utils
+    Distribution.Client.Install
     Distribution.Client.InstallPlan
---     Distribution.Client.InstallSymlink
+    Distribution.Client.InstallSymlink
     Distribution.Client.JobControl
---     Distribution.Client.List
---     Distribution.Client.Manpage
+    Distribution.Client.List
+    Distribution.Client.Main
+    Distribution.Client.Manpage
     Distribution.Client.ManpageFlags
---     Distribution.Client.Nix
+    Distribution.Client.Nix
     Distribution.Client.NixStyleOptions
     Distribution.Client.PackageHash
     Distribution.Client.ParseUtils
@@ -745,16 +752,17 @@
     Distribution.Client.ProjectPlanning
     Distribution.Client.ProjectPlanning.Types
     Distribution.Client.RebuildMonad
---     Distribution.Client.Reconfigure
---     Distribution.Client.Run
---     Distribution.Client.Sandbox
---     Distribution.Client.Sandbox.PackageEnvironment
---     Distribution.Client.SavedFlags
---     Distribution.Client.ScriptUtils
+    Distribution.Client.Reconfigure
+    Distribution.Client.Run
+    Distribution.Client.Sandbox
+    Distribution.Client.Sandbox.PackageEnvironment
+    Distribution.Client.SavedFlags
+    Distribution.Client.ScriptUtils
     Distribution.Client.Security.DNS
     Distribution.Client.Security.HTTP
     Distribution.Client.Setup
     Distribution.Client.SetupWrapper
+    Distribution.Client.Signal
     Distribution.Client.SolverInstallPlan
     Distribution.Client.SourceFiles
     Distribution.Client.SrcDist
@@ -779,16 +787,19 @@
     Distribution.Client.Types.SourcePackageDb
     Distribution.Client.Types.SourceRepo
     Distribution.Client.Types.WriteGhcEnvironmentFilesPolicy
---     Distribution.Client.Upload
+    Distribution.Client.Upload
     Distribution.Client.Utils
     Distribution.Client.Utils.Json
     Distribution.Client.Utils.Parsec
     Distribution.Client.VCS
     Distribution.Client.Version
---     Distribution.Client.Win32SelfUpgrade
+    Distribution.Client.Win32SelfUpgrade
     Distribution.Deprecated.ParseUtils
     Distribution.Deprecated.ReadP
     Distribution.Deprecated.ViewAsFieldDescr
+
+  default-extensions:
+    TypeOperators
 
 library hackport-internal
   import:             warnings
