validation: post-split cabal re-pin + stage-qualified host-only (DO NOT MERGE — pins WIP cabal#378) - #189
Draft
angerman wants to merge 142 commits into
Draft
validation: post-split cabal re-pin + stage-qualified host-only (DO NOT MERGE — pins WIP cabal#378)#189angerman wants to merge 142 commits into
angerman wants to merge 142 commits into
Conversation
This change reverts part of !14544, which forces the bootstrap compiler to have ghc-internal. As such it breaks booting with ghc 9.8.4. A better solution would be to make this conditional on the ghc version in the cabal file!
…ernal If the boot compiler doesn't have ghc-internal use "<unavailble>" as the `cGhcInternalUnitId`. This allows booting with older compilers. The subsequent stage2 compilers will have the proper ghc-internal id from their stage1 compiler, that boots them.
Make the first simple optimization pass after desugaring a real CoreToDo pass. This allows CorePlugins to decide whether they want to be executed before or after this pass.
It's more user-friendly to directly print the right thing instead of requiring the user to retry with the additional `-dppr-debug` flag.
mermaid is a common diagram format that can be inlined in markdown files, and e.g. github will even render it. This change adds support for mermaid diagram output to ghc-pkg.
This adds support to ghc-pkg to infer a package-db from a target name.
Add a new optional unitDataDir field to GhcPkg.InstalledPackageInfo and populate it in ghc-pkg's convertPackageInfoToCacheFormat. This is needed by the WASM linker to locate per-package data files (specifically WasmGlobalRegs.S) via GHC.Unit.Database.unitDataDir at link time, without requiring a file-system search.
By mistake we tried to use deriveConstant without passing `--gcc-flag -fcommon` (which Hadrian does) and it failed. This patch adds deriveConstant support for constants stored in the .bss section so that deriveConstant works without passing `-fcommon` to the C compiler.
Apple's LLVM toolchain uses `arm64` as the canonical architecture name for AArch64 on Apple platforms, while GNU config.sub normalises to `aarch64`. This mismatch causes `--target=aarch64-apple-darwin` to be passed to clang, which conflicts with toolchain wrappers (e.g. nix cc-wrapper) that expect `arm64-apple-darwin`. The result is thousands of test failures on aarch64-darwin because the cc-wrapper warning pollutes compiler output and the target flag interaction breaks compilation. Fix by adding normaliseLlvmTarget that rewrites `aarch64-apple-*` to `arm64-apple-*` for the LLVM target triple, matching Apple conventions and the existing llvm-targets file which already uses arm64-apple-darwin.
Add AC_ARG_WITH([compiler]) to allow specifying the Haskell compiler via the --with-compiler flag, consistent with standard autoconf practices for tool configuration. This provides an alternative to setting the GHC environment variable, making the build system more flexible and consistent with other configure scripts that accept --with-* options for tools.
Add entries to prevent AI agent config files from being accidentally committed. These files contain project-specific instructions for various AI coding assistants and should remain local. Covers: Claude Code, GitHub Copilot, Cursor, Gemini CLI/Jules, OpenAI Codex, and JetBrains Junie. See: https://agents.md/ for the AGENTS.md standard
Fixes #26434 In detail, this does a number of things: * Makes GHC aware of 'extra-libraries-static' (this changes the package database format). * Adds a switch '-static-external' that will honour 'extra-libraries-static' to link external system dependencies statically. * Adds a new field to settings/targets: "ld supports verbatim namespace". This field is used by '-static-external' to conditionally use '-l:foo.a' syntax during linking, which is more robust than trying to find the absolute path to an archive on our own. * Adds a switch '-fully-static' that is meant as a high-level interface for e.g. cabal. This also honours 'extra-libraries-static'. This also attempts to clean up the confusion around library search directories. At the moment, we have 3 types of directories in the package database format: * library-dirs * library-dirs-static * dynamic-library-dirs However, we only have two types of linking: dynamic or static. Given the existing logic in 'mungeDynLibFields', this patch assumes that 'library-dirs' is really just nothing but a fallback and always prefers the more specific variants if they exist and are non-empty. Conceptually, we should be ok with even just one search dirs variant. Haskell libraries are named differently depending on whether they're static or dynamic, so GHC can conveniently pick the right one depending on the linking needs. That means we don't really need to play tricks with search paths to convince the compiler to do linking as we want it. For system C libraries, the convention has been anyway to place static and dynamic libs next to each other, so we need to deal with that issue anyway and it is outside of our control. But this is out of the scope of this patch. This patch is backwards compatible with cabal. Cabal should however be patched to use the new '-fully-static' switch.
"Executable" seems more appropriate.
This patch teaches GHC how to build the external interpreter program when it is missing. As long as we have the `ghci` library, doing this is trivial so most of this patch is refactoring for doing it sanely. (cherry picked from commit 55eab80)
The comment still referenced the old `linkBinary` name after the rename to `linkExecutable` in 55ff022.
GHC and ghc-iserv load Haskell shared libraries dynamically for Template Haskell and GHCi. These libraries reference RTS symbols (e.g., stg_INTLIKE_closure) that are linked into the executable. Without special linker flags, those symbols aren't visible to dlopen'd libraries. This commit adds platform-specific linker flags to export these symbols: - Linux/FreeBSD: -rdynamic (passes --export-dynamic to ld) - macOS: -flat_namespace (makes all symbols visible across namespaces) - Windows: Cannot use --export-all-symbols due to 65535 symbol limit See Note [ghc-iserv and dynamic symbol export] in ghc-iserv.cabal.in for detailed explanation of the approach and alternatives considered.
Replace legacy __sync_fetch_and_* builtins with their modern __atomic_fetch_*
equivalents. This simplifies the code significantly, particularly for the nand
operation which previously required extensive workarounds for compiler
compatibility issues.
Changes:
- Replace __sync_fetch_and_{add,sub,and,or,xor} with __atomic_fetch_*
- Replace __sync_fetch_and_nand with __atomic_fetch_nand
- Remove CAS-based fallback for nand operations
- Remove compiler-specific warning suppressions for -Wsync-nand
- Remove volatile qualifiers (not needed with __atomic builtins)
- Update comments to reflect modern atomics usage
All operations maintain __ATOMIC_SEQ_CST memory ordering for sequential
consistency, matching the original behavior.
Co-authored-by: Andrea Bedini <andrea@andreabedini.com>
The T21651 concurrency stress test times out on aarch64-darwin CI runners. Mark it fragile since it's a CI environment issue, not a code regression.
ss_conv was emitting raw SBFM for all MO_SS_Conv cases. For widening conversions (e.g. W32->W64), emit the canonical SXTB/SXTH/SXTW instructions instead, with the correct source register width (Wn not Xn). Also fix signExtendReg to use source register width for the source operand of SXTW/SXTH/SXTB instructions (latent bug: source always used destination width).
FP_VISIBILITY_HIDDEN was called in rts/configure.ac but the macro definition was removed in an earlier commit. Remove the orphaned call to fix autoconf warnings.
The macOS-13 GitHub Actions runner now ships with Homebrew llvm@18, whose libunwind triggers a linker warning on every invocation: ld: warning: reexported library with install name '/usr/local/opt/llvm@18/lib/libunwind.1.dylib' ... couldn't be matched with any parent library and will be linked directly This causes ~190 spurious test failures (bad stderr / stderr mismatch) on the Mac x86_64 CI. Filter the warning in both normalise_errmsg and normalise_output, alongside the existing macOS ld warning patterns.
Recent macOS and Windows CI runner images set CC to include flags (e.g. "/usr/bin/cc -std=gnu23"). The --gcc-program argument was passed directly to rawSystem which treats the entire string as an executable path, causing: deriveConstants: /usr/bin/cc -std=gnu23: rawSystem: posix_spawnp: does not exist (No such file or directory) Split the --gcc-program value on whitespace: the first word becomes the program path, remaining words are prepended to the gcc flags.
On Windows (MSYS2/CLANG64), the _utime function expects a struct _utimbuf pointer. The CUtimbuf CTYPE was declared as "struct utimbuf" which worked when clang treated them as compatible, but with -std=gnu23 (now the default on updated CI runner images) clang errors on the type mismatch: incompatible pointer types passing 'struct utimbuf *' to parameter of type 'struct _utimbuf *' Use the correct Windows type name in the CTYPE pragma.
Point all stage cabal.project files at stable-haskell/cabal wip/angerman/compile-less (44817477ff6d22de4bfa4307e061df58f319d3b6), which is based on Andrea Bedini's wip/andrea/compile-less and includes: - Cross-compilation support (Stage/Toolchain architecture) - Local store (replaces in-place builds) - Recompilation avoidance (file monitor tracking for installed packages) - hasufell's "Stop stealing the vowels" and "Fix caching of remote source tarballs" - TOCTOU race fix for BuildInplaceOnly tarball extraction
wip/angerman/compile-less has been renamed to stable-haskell/master
…split Cabal 3.17 (commit edb808a0b8b, "allow setting the logging handle") split the old Verbosity type into VerbosityFlags (the CLI-passable part) plus VerbosityHandles. configVerbosity now yields a Flag VerbosityFlags, which must be wrapped back into a Verbosity via mkVerbosity before being passed to Cabal library functions such as requireProgram, getProgramOutput and info. Add a CPP-guarded configVerbosity' helper to both Setup.hs files, and in compiler/Setup.hs replace the bare 'normal' literal (now a VerbosityFlags) with the in-scope 'verbosity' parameter. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
It's required since cabal commit 6867dd5da57194337bab0079bbe2f1c21e11662f
It's required since cabal commit 6867dd5da57194337bab0079bbe2f1c21e11662f
Statically-linked executables link only system libraries (libc/libm) and load nothing from ../lib, so they need no rpath. patchelf also cannot rewrite the large statically-linked ghc/haddock/ghc-iserv binaries (it fails with "virtual address space underrun"). Gate the dist binary rpath loop under DYNAMIC=1, matching the existing gating of the shared-library rpath step.
The hackage-security package is only ever used in stage0 to build cabal-install.
…igure
Replace the configure-driven static/dynamic selection for stage2 with
explicit cabal project files.
Previously a `--enable-dynamic` autoconf toggle, together with the
`m4/accumulate.m4` helper macros, generated cabal.project.stage2.settings
from a .in template, while the Makefile separately appended
--enable-dynamic to GHC_CONFIGURE_ARGS when DYNAMIC=1. Keeping these two
mechanisms in sync was fragile.
Now the stage2 configuration is split into a shared
cabal.project.stage2.common plus two thin variants that import it:
- cabal.project.stage2.static (default; shared: False)
- cabal.project.stage2.dynamic (shared: True, executable-dynamic: True,
rts +dynamic)
The Makefile selects the project file directly through DYNAMIC_SUFFIX and
the new CABAL_PROJECT_FILE variable, so DYNAMIC=1 picks the dynamic file
without any configure round-trip.
Removed as no longer needed:
- the --enable-dynamic configure option and its substitution logic
- cabal.project.stage2.settings(.in) template
- m4/accumulate.m4
The hosted Windows runner's make changed from MSYS2 (MAKE_HOST=x86_64-pc-msys) to Cygwin (x86_64-pc-cygwin). Both `ifeq ($(MAKE_HOST),x86_64-pc-msys)` guards then fell through, dropping the Windows CC/CXX/LD overrides so CC/CXX defaulted to cc/g++ and ghc-toolchain failed stage1 settings generation with "g++ not found". Match all Windows make-host triples (msys, cygwin, mingw32) via $(filter ...).
release.yml was broken at the root by the Cabal source-repo pin
`tag: stable-haskell/master`, which cabal could not resolve at stage0 (every
platform died building cabal-install). Pin an explicit, resolvable SHA on the
feature/wasm-cross-ghcup-stack branch (aa57a49) which carries the fixes the
build needs:
* host-only `package *` handling, so cabal.project.stage2.dynamic's
`shared: True` no longer builds the build-stage packages shared (those
failed to link against the bootstrap GHC on ~every platform:
"ld: cannot find -lHSbytestring-...-ghc9.8.4");
* #361 target-prefix-aware companion-tool guess (cross ghc-pkg);
* a self ($ORIGIN/@loader_path) rpath entry so an instantiated Backpack
unit finds its signature implementation under musl (testsuite T14304 on
Alpine; glibc masked it via the runtime LD_LIBRARY_PATH GHC sets before
dlopen, which musl ignores).
Adapt the tree to this Cabal:
* cabal.project.stage0: drop the `hooks-exe` subdir (absent on this branch);
* compiler/Setup.hs, libraries/ghc-boot/Setup.hs: revert the Cabal-3.17
Verbosity/VerbosityHandles-split adaptation (this branch predates it);
* cabal.project.stage{1,2.common}: compile out libffi's deprecated (Java)
raw API with -optc-DFFI_NO_RAW_API=1, which RockyLinux 8 gcc treats as a
hard error (GHC does not use that API).
The FreeBSD self-hosted runner has no JS toolchain (llc/opt/emscripten), so it cannot build the javascript-unknown-ghcjs cross target. Drop both the JS bindist and haskell-toolchain.tar.gz (which depends on stage3-javascript-unknown-ghcjs) from the FreeBSD build; ship only the native ghc/cabal/tests bindists.
Replace the pre-split aa57a49 pin (feature/wasm-cross-ghcup-stack) with
feat/wasm-cross-ghcup-stack-next (ee3b55e6): stable-haskell/cabal's
wip/andrea/stage-qualified-options (#378, Host-only `package *` handling)
+ target-prefixed ghc-pkg guess (#361) + absolute-rpath relativization
(#368) + the $ORIGIN/@loader_path self-rpath (#385, musl T14304).
Being post-split, the next branch carries the Cabal-3.17 VerbosityHandles
API and the hooks-exe sub-dir, so two adaptations the aa57a49 pin forced
are no longer needed and are reverted here:
* compiler/Setup.hs, libraries/ghc-boot/Setup.hs: restore the upstream
`#if MIN_VERSION_Cabal(3,17,0)` VerbosityHandles form (un-revert).
* cabal.project.stage0: restore the hooks-exe sub-dir.
The libffi-clib FFI_NO_RAW_API workaround (Rocky gcc-8) is unrelated to
the pin and is kept. Tracked by stable-haskell/cabal#384; re-pin to
`master` once #378 lands there.
The post-split Cabal (#378, `package <stage>:*`) does not treat an unqualified
`package *` as host-only the way the pre-split aa57a49 pin did, so a bare
`package * { shared: True }` here also built the BUILD-stage tools shared and
they failed to link the bootstrap GHC's static-only libs
("ld: library not found for -lHSbytestring-...-ghc9.8.4", on build:os-string).
Split it per #378's own fixture: `package host:*` carries shared/dynamic,
`package build:*` forces the build tools static. Validated locally:
stage0+stage1+stage2 (DYNAMIC=1) build green on aarch64-darwin and stage2 ghc
is dynamically linked (@rpath/libHSghc-9.14-ghc9.14.dylib).
Consolidates the cabal.project changes for the post-split Cabal pin: - stage1 hermetic build: `active-repositories: :none` + pin happy/alex/ happy-lib/hpc so stage1 build-tools don't float to Hackage's newest (a floated happy produces parser code mismatching the pinned template -> genprimopcode/GHC-44432). stage2/stage3 already did this. (stable-haskell/ cabal#384) - stage1 `time-1.14` as source: the post-split host Cabal-3.17.0.1 pulls in `time`; the bootstrap's installed time-1.12.2 is bound to installed Win32-2.13.4.0 and conflicts with the pinned source Win32-2.14.2.1 on Windows. time-1.14 is the newest release satisfying hpc-0.7.0.2's `time >=1.2 && <1.15` (1.15 backjumps on host:hpc/host:time). - re-pin Cabal ee3b55e6 -> f2e0a89 (stage0/1/2.common/3): f2e0a89 fixes cross build-stage `ar` archiving — it derives -L/@-file support from the actual ar program (its --version) instead of the host/target compiler's claim, with a non-throwing probe so Apple cctools `ar` (no --version) falls back to the conservative path. Without it, build-stage happy-lib failed to archive on RockyLinux 8 (GNU ar, -qL) and macOS x86_64 (cctools ar, @-file).
The post-split Cabal-syntax now knows ExplicitLevelImports and ImplicitStagePersistence, so T4437 no longer reports them as "GHC-only" extensions; the two stale lines are removed from the golden.
angerman
force-pushed
the
feat/cabal-pin-postsplit
branch
from
June 18, 2026 00:55
25d5e45 to
13636ca
Compare
angerman
force-pushed
the
stable-ghc-9.14
branch
2 times, most recently
from
August 30, 2026 01:45
8bdf55f to
93c3dc1
Compare
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Validation only — DO NOT MERGE. This pins the WIP cabal branch
feat/wasm-cross-ghcup-stack-next(stable-haskell/cabal #378 host-only +#361 + #368 + #385
$ORIGIN), to validate the eventual post-split re-pinacross the full release matrix. It cannot merge until cabal #378 lands.
Replaces the pre-split
aa57a49pin and drops both pre-split hacks:compiler/Setup.hs+ghc-boot/Setup.hsrestored to the upstream#if MIN_VERSION_Cabal(3,17,0)VerbosityHandlesform.cabal.project.stage0hooks-exesub-dir restored.Plus the one adaptation the post-split host-only model needs:
cabal.project.stage2.dynamicstage-qualifies
shared/executable-dynamictohost:*(withbuild:*forcedstatic), because an unqualified
package *no longer scopes host-only on #378.Validated locally on aarch64-darwin: stage0 + stage1 + stage2 (DYNAMIC=1)
green, stage2 ghc dynamically linked. This run exercises the breadth
(DYNAMIC=0, Linux/Windows/FreeBSD/musl, cross). See stable-haskell/cabal#384.