GHC(1)
💖 GHC(1) — Glasgow Haskell Compiler 💖
okay bestie, welcome to the ghc manual page. This is the Glasgow Haskell Compiler, and we're gonna keep every single flag intact while making the vibe immaculate. ✨
🌸 NAME 🌸
ghc — the Glasgow Haskell Compiler.
🦋 SYNOPSIS 🦋
ghc [option|filename]
ghci [option|filename]
✨ DESCRIPTION ✨
This manual page documents briefly the ghc and ghci commands. Yes, briefly — it's a whole vibe. 💅
🫶 heads up, bestie: ghci is not yet available on all architectures.
Extensive documentation is available in various other formats including PDF https://downloads.haskell.org/ghc/latest/docs/users_guide.pdf and HTML https://downloads.haskell.org/ghc/latest/docs/html/.
Each of GHC's command line options is classified as either static or dynamic. A static flag may only be specified on the command line, whereas a dynamic flag may also be given in an OPTIONS pragma in a source file or set from the GHCi command-line with :set.
As a rule of thumb, all the language options are dynamic, as are the warning options and the debugging options.
The rest are static, with the notable exceptions of -v, -cpp, -fasm, -fvia-C, -fllvm, and -#include. The OPTIONS sections lists the status of each flag. That's the official word, no cap.
Common suffixes of file names for Haskell are:
.hs— Haskell source code; preprocess, compile.lhs— literate Haskell source; unlit, preprocess, compile.hi— Interface file; contains information about exported symbols.hc— intermediate C files.⟨way⟩_o— object files for "way"⟨way⟩; common ways are:dyn— dynamically-linkedp— built with profiling
.⟨way⟩_hi— interface files for "way"⟨way⟩; common ways are:
🌈 OPTIONS 🌈
Flag wall time, bestie. Every option below is kept exactly as written — no renaming, no merging, no invented nonsense. 🎀
⚙️ Code generation ⚙️
-dynamic-too -fasm -fllvm -fbyte-code -fbyte-code-and-object-code
-fexpose-internal-symbols -fexternal-dynamic-refs -fllvm -fasm
-fno-code -fobject-code -fPIC -fPIE -fprefer-byte-code
-fwrite-if-simplified-core -fwrite-interface
🐛 Debugging the compiler 🐛
-dasm-lint -dcmm-lint -dcore-lint -ddisable-js-c-sources
-ddisable-js-minifier -ddump-asm -ddump-asm-conflicts
-ddump-asm-liveness -ddump-asm-native -ddump-asm-regalloc
-ddump-asm-regalloc-stages -ddump-asm-stats -ddump-bcos
-ddump-c-backend -ddump-call-arity -ddump-cfg-weights -ddump-cmm
-ddump-cmm-caf -ddump-cmm-cbe -ddump-cmm-cfg -ddump-cmm-cps
-ddump-cmm-from-stg -ddump-cmm-info -ddump-cmm-opt
-ddump-cmm-proc -ddump-cmm-procmap -ddump-cmm-raw -ddump-cmm-sink
-ddump-cmm-sp -ddump-cmm-split -ddump-cmm-switch
-ddump-cmm-thread-sanitizer -ddump-cmm-verbose
-ddump-cmm-verbose-by-proc -ddump-core-stats
-ddump-cpr-signatures -ddump-cpranal -ddump-cs-trace -ddump-cse
-ddump-debug -ddump-deriv -ddump-dmd-signatures -ddump-dmdanal
-ddump-ds -ddump-ds-preopt -ddump-ec-trace -ddump-exitify
-ddump-faststrings -ddump-file-prefix=⟨str⟩ -ddump-float-in
-ddump-foreign -ddump-full-laziness -ddump-float-out -ddump-hie
-ddump-hpc -ddump-if-trace -ddump-inlinings -ddump-js -ddump-json
-ddump-late-cc -ddump-liberate-case -ddump-llvm -ddump-mod-map
-ddump-occur-anal -ddump-opt-cmm -ddump-parsed -ddump-parsed-ast
-ddump-prep -ddump-rn -ddump-rn-ast -ddump-rn-stats
-ddump-rn-trace -ddump-rtti -ddump-rule-firings
-ddump-rule-rewrites -ddump-rules -ddump-simpl
-ddump-simpl-iterations -ddump-simpl-stats -ddump-simpl-trace
-ddump-spec -ddump-spec-constr -ddump-splices
-ddump-static-argument-transformation -ddump-stg -ddump-stg-cg
-ddump-stg-final -ddump-stg-from-core -ddump-stg-tags
-ddump-stg-unarised -ddump-str-signatures -ddump-stranal
-ddump-tc -ddump-tc-ast -ddump-tc-trace -ddump-ticked
-ddump-timings -ddump-to-file -ddump-types
-ddump-verbose-inlinings -ddump-view-pattern-commoning
-ddump-worker-wrapper -dfaststring-stats -dhex-word-literals
-dinitial-unique=⟨s⟩ -dinline-check=⟨str⟩ -dipe-stats
-dkeep-comments -dlinear-core-lint -dlint -dno-debug-output
-ddebug-output -dno-typeable-binds -dppr-case-as-let
-dppr-cols=⟨n⟩ -dppr-debug -dppr-user-length -drule-check=⟨str⟩
-dshow-passes -dstg-lint -dsuppress-all -dsuppress-coercion-types
-dsuppress-coercions -dsuppress-core-sizes -dsuppress-idinfo
-dsuppress-module-prefixes -dsuppress-stg-free-vars
-dsuppress-stg-reps -dsuppress-ticks -dsuppress-timestamps
-dsuppress-type-applications -dsuppress-type-signatures
-dsuppress-unfoldings -dsuppress-uniques -dsuppress-var-kinds
-dtag-inference-checks -dth-dec-file -dunique-increment=⟨i⟩
-dverbose-core2core -dverbose-stg2stg -fadd-bco-name
-fno-add-bco-name -falignment-sanitisation
-fcatch-nonexhaustive-cases -fcheck-prim-bounds
-fcmm-thread-sanitizer -fdistinct-constructor-tables
-fdump-with-ways -finfo-table-map -finfo-table-map-with-fallback
-fno-info-table-map-with-fallback -finfo-table-map-with-stack
-fno-info-table-map-with-stack -fllvm-fill-undef-with-garbage
-fno-info-table-map-with-fallback -finfo-table-map-with-fallback
-fno-info-table-map-with-stack -finfo-table-map-with-stack
-forig-thunk-info -fproc-alignment
-funoptimized-core-for-interpreter
-fno-unoptimized-core-for-interpreter -g -g⟨n⟩
🧪 C pre-processor 🧪
-cpp -D⟨symbol⟩[=⟨value⟩] -U⟨symbol⟩ -I⟨dir⟩ -U⟨symbol⟩
🔎 Finding imports 🔎
-i -i⟨dir⟩[:⟨dir⟩]*
💬 Interactive mode 💬
-fbreak-on-error -fno-break-on-error -fbreak-on-exception
-fno-break-on-exception -fbreak-points -fno-break-points
-fghci-hist-size=⟨n⟩ -fghci-leak-check -fno-ghci-leak-check
-fimplicit-import-qualified -fno-implicit-import-qualified
-flocal-ghci-history -fno-local-ghci-history -fno-it -fno-no-it
-fprint-bind-result -fno-print-bind-result -fprint-evld-with-show
-fshow-loaded-modules -ghci-script -ignore-dot-ghci
-no-ignore-dot-ghci -interactive-print ⟨name⟩
🗂️ Interface files 🗂️
--show-iface ⟨file⟩ -ddump-hi -ddump-hi-diffs
-ddump-minimal-imports
🧹 Keeping intermediate files 🧹
-keep-hc-file -keep-hc-files -keep-hi-files -no-keep-hi-files
-keep-hscpp-file -keep-hscpp-files -keep-llvm-file
-keep-llvm-files -keep-o-files -no-keep-o-files -keep-s-file
-keep-s-files -keep-tmp-files
🗣️ Language options 🗣️
The big -X wall. Every single one is here, bestie — no skipping. 💅
-XAllowAmbiguousTypes -XApplicativeDo -XArrows -XBangPatterns
-XBinaryLiterals -XBlockArguments -XCApiFFI
-XConstrainedClassMethods -XConstraintKinds -XCPP -XCUSKs
-XDataKinds -XDatatypeContexts -XDeepSubsumption
-XDefaultSignatures -XDeriveAnyClass -XDeriveDataTypeable
-XDeriveFoldable -XDeriveFunctor -XDeriveGeneric -XDeriveLift
-XDeriveTraversable -XDerivingStrategies -XDerivingVia
-XDisambiguateRecordFields -XDuplicateRecordFields -XEmptyCase
-XEmptyDataDecls -XEmptyDataDeriving -XExistentialQuantification
-XExplicitForAll -XExplicitNamespaces -XExtendedDefaultRules
-XExtendedLiterals -XFieldSelectors -XFlexibleContexts
-XFlexibleInstances -XForeignFunctionInterface
-XFunctionalDependencies -XGADTs -XGADTSyntax
-XGeneralisedNewtypeDeriving -XGeneralizedNewtypeDeriving
-XGHC2021 -XGHC2024 -XGHCForeignImportPrim -XHaskell2010
-XHaskell98 -XHexFloatLiterals -XImplicitParams -XImplicitPrelude
-XImportQualifiedPost -XImpredicativeTypes -XIncoherentInstances
-XInstanceSigs -XInterruptibleFFI -XKindSignatures -XLambdaCase
-XLexicalNegation -XLiberalTypeSynonyms -XLinearTypes
-XListTuplePuns -XMagicHash -XMonadComprehensions
-XMonoLocalBinds -XMonomorphismRestriction -XMultilineStrings
-XMultiParamTypeClasses -XMultiWayIf -XNamedDefaults
-XNamedFieldPuns -XNamedWildCards -XNegativeLiterals
-XNondecreasingIndentation -XNPlusKPatterns -XNullaryTypeClasses
-XNumDecimals -XNumericUnderscores -XOrPatterns
-XOverlappingInstances -XOverloadedLabels -XOverloadedLists
-XOverloadedRecordDot -XOverloadedRecordUpdate
-XOverloadedStrings -XPackageImports -XParallelListComp
-XPartialTypeSignatures -XPatternGuards -XPatternSynonyms
-XPolyKinds -XPostfixOperators -XQualifiedDo
-XQuantifiedConstraints -XQuasiQuotes -XRank2Types -XRankNTypes
-XRebindableSyntax -XRecordWildCards -XRecursiveDo
-XRequiredTypeArguments -XRoleAnnotations -XSafe
-XScopedTypeVariables -XStandaloneDeriving
-XStandaloneKindSignatures -XStarIsType -XStaticPointers -XStrict
-XStrictData -XTemplateHaskell -XTemplateHaskellQuotes
-XTraditionalRecordSyntax -XTransformListComp -XTrustworthy
-XTupleSections -XTypeAbstractions -XTypeApplications -XTypeData
-XTypeFamilies -XTypeFamilyDependencies -XTypeInType
-XTypeOperators -XTypeSynonymInstances -XUnboxedSums
-XUnboxedTuples -XUndecidableInstances -XUndecidableSuperClasses
-XUnicodeSyntax -XUnliftedDatatypes -XUnliftedFFITypes
-XUnliftedNewtypes -XUnsafe -XViewPatterns
🔗 Linking options 🔗
-c -debug -dylib-install-name ⟨path⟩ -dynamic -dynload -eventlog
-fcompact-unwind -fkeep-cafs -flink-rts -fno-embed-manifest
-fno-gen-manifest -fno-shared-implib -framework ⟨name⟩
-framework-path ⟨dir⟩ -fsplit-sections -split-sections
-fno-split-sections -fuse-rpaths -fwhole-archive-hs-libs -L ⟨dir⟩
-l ⟨lib⟩ -main-is ⟨thing⟩ -no-hs-main -no-pie -pie
-no-rtsopts-suggestions -package ⟨name⟩ -pie -no-pie -rdynamic
-rtsopts[=⟨none|some|all|ignore|ignoreAll⟩] -shared
-single-threaded -threaded -static -staticlib -threaded
-single-threaded -with-rtsopts=⟨opts⟩
🎲 Miscellaneous options 🎲
-ddump-mod-cycles -fdefer-out-of-scope-variables
-fno-defer-out-of-scope-variables -fdefer-type-errors
-fno-defer-type-errors -fdefer-typed-holes -fno-defer-typed-holes
-fexternal-interpreter -ffamily-application-cache
-fno-family-application-cache -fglasgow-exts -fno-glasgow-exts
-fno-safe-haskell -ghcversion-file ⟨path to ghcversion.h⟩ -H
⟨size⟩ -hidden-module ⟨module name⟩ -j[⟨n⟩] -jsem
-reexported-module ⟨reexport-spec⟩ -this-package-name ⟨unit-id⟩
-unit @⟨filename⟩ -working-dir ⟨dir⟩
💅 Modes of operation 💅
ok bestie, this first block is the big one — it's literally "what do you want GHC to do today". One of these is your whole vibe. Pick your main character moment 🎀
--frontend ⟨module⟩— you're telling GHC to use that module as its frontend. name the module, that's the deal.--help,-?— the classic. it prints help. that's the whole bit. slay.--info— prints info. yes that's it. she's simple, she's iconic.--interactive— interactive mode, so GHC talks back to you 💬--make— make mode. the compiler pretends to be a build system, and honestly? she ate.--numeric-version— the version, but numbers only, no extra chatter.--print-booter-version— prints the booter version.--print-build-platform— prints the build platform.--print-c-compiler-flags— prints the C compiler flags.--print-c-compiler-link-flags— prints the C compiler link flags. yes, different from the other one.--print-debug-on— prints debug-on.--print-global-package-db— prints the global package db.--print-have-interpreter— prints whether there's an interpreter. lowkey nosy but go off.--print-have-native-code-generator— prints whether there's a native code generator.--print-host-platform— prints the host platform.--print-ld-flags— prints the ld flags.--print-leading-underscore— prints the leading underscore situation.--print-libdir— prints the libdir. very "where do the libs live" of her 🏠--print-object-splitting-supported— prints whether object splitting is supported.--print-project-git-commit-id— prints the project git commit id 🔖--print-project-version— prints the project version.--print-rts-ways— prints the RTS ways.--print-stage— prints the stage.--print-support-smp— prints whether SMP is supported.--print-tables-next-to-code— prints the tables-next-to-code situation.--print-target-platform— prints the target platform.--print-unregisterised— prints the unregisterised situation.--run ⟨file⟩— run that file. give her a file, she runs it 🏃♀️--show-iface ⟨file⟩— show the interface for that file.--show-options— shows you the options. meta, honestly. obsessed.--supported-extensions— lists the supported extensions.--supported-languages— lists the supported languages.--version,-V— version time 💫-e ⟨expr⟩— evaluate expr right there on the spot.-M— the M mode. capital M. she's mysterious, she's iconic.-shared— shared. yes queen, share it with the group 🫶
🔥 Individual optimizations 🔥
bestie. sit down. this is the big list — every single little optimisation knob GHC has, and there are like a hundred of them 🙈
quick vibe check before we go: almost every one of these comes as a pair, and the -fno- version is the "turn it off" twin. the ones with =⟨n⟩ want a number from you. that's the pattern, now go wild:
-fasm-shortcutting,-fno-asm-shortcutting— asm shortcutting: on, or off. simple as.-fbinary-blob-threshold=⟨n⟩— takes a number. binary blob threshold, you know the one.-fblock-layout-cfg,-fno-block-layout-cfg— block layout cfg, on/off 💅-fblock-layout-weightless,-fno-block-layout-weightless— the weightless version. iconique.-fblock-layout-weights— and here's the one with weights. no-fno-twin for this one, she stands alone.-fcall-arity,-fno-call-arity— call arity toggle 🎚️-fcase-folding,-fno-case-folding— case folding, yes/no.-fcase-merge,-fno-case-merge— case merge, yes/no.-fcmm-control-flow,-fno-cmm-control-flow— cmm control flow.-fcmm-elim-common-blocks,-fno-cmm-elim-common-blocks— cmm elim common blocks.-fcmm-sink,-fno-cmm-sink— cmm sink. she sinks. it's fine.-fcmm-static-pred,-fno-cmm-static-pred— cmm static pred.-fcore-constant-folding,-fno-core-constant-folding— core constant folding, the OG.-fcpr-anal,-fno-cpr-anal— cpr anal 💀-fcross-module-specialise,-fno-cross-module-specialise— cross module specialise.-fcse,-fno-cse— cse my beloved.-fdicts-cheap,-fno-dicts-cheap— dicts cheap. budget dictionaries fr fr.-fdicts-strict,-fno-dicts-strict— dicts strict.-fdmd-tx-dict-sel,-fno-dmd-tx-dict-sel— dmd tx dict sel (yes, really).-fdmd-unbox-width=⟨n⟩— takes a number. dmd unbox width.-fdo-clever-arg-eta-expansion,-fno-do-clever-arg-eta-expansion— the clever arg eta expansion. she's clever, it's in the name ✨-fdo-eta-reduction,-fno-do-eta-reduction— eta reduction.-fdo-lambda-eta-expansion,-fno-do-lambda-eta-expansion— lambda eta expansion.-feager-blackholing— eager blackholing. no off switch listed. she's just eager 🖤-fenable-rewrite-rules,-fno-enable-rewrite-rules— rewrite rules: enabled or not.-fexcess-precision,-fno-excess-precision— excess precision.-fexitification,-fno-exitification— exitification 🚪-fexpose-all-unfoldings,-fno-expose-all-unfoldings— expose all the unfoldings. no secrets, no privacy, we're all exposed 💅-fexpose-overloaded-unfoldings,-fno-expose-overloaded-unfoldings— the overloaded ones this time.-ffloat-in,-fno-float-in— float in.-ffull-laziness,-fno-full-laziness— full laziness. lazy girlie rights 😴-ffun-to-thunk,-fno-fun-to-thunk— fun to thunk. cute.-fignore-asserts,-fno-ignore-asserts— ignore asserts, or don't.-fignore-interface-pragmas,-fno-ignore-interface-pragmas— ignore interface pragmas.-finline-generics,-fno-inline-generics— inline generics.-finline-generics-aggressively,-fno-inline-generics-aggressively— inline generics but make it aggressive 🔥-finter-module-far-jumps,-fno-inter-module-far-jumps— inter module far jumps. far. jumps.-fkeep-auto-rules,-fno-keep-auto-rules— keep auto rules, or toss 'em.-flate-dmd-anal,-fno-late-dmd-anal— late dmd anal. fashionably late ⏰-flate-specialise,-fno-late-specialise— late specialise.-fliberate-case,-fno-liberate-case— liberate case 🕊️-fliberate-case-threshold=⟨n⟩,-fno-liberate-case-threshold— the numeric threshold version, plus its off switch.-fllvm-pass-vectors-in-regs— llvm pass vectors in regs. no off twin here.-flocal-float-out,-fno-local-float-out— local float out.-flocal-float-out-top-level,-fno-local-float-out-top-level— same but top level 👑-floopification,-fno-loopification— loopification, obviously.-fmax-forced-spec-args=⟨n⟩— takes a number. max forced spec args.-fmax-inline-alloc-size=⟨n⟩— takes a number. max inline alloc size.-fmax-inline-memcpy-insns=⟨n⟩— takes a number. max inline memcpy insns.-fmax-inline-memset-insns=⟨n⟩— takes a number. max inline memset insns.-fmax-simplifier-iterations=⟨n⟩— takes a number. max simplifier iterations.-fmax-uncovered-patterns=⟨n⟩— takes a number. max uncovered patterns.-fmax-worker-args=⟨n⟩— takes a number. max worker args.-fno-opt-coercion— opt coercion, but off. no on version listed here.-fno-pre-inlining— pre inlining, off.-fno-state-hack— the state hack, off. (only the off listed, bestie, don't @ me)-fobject-determinism,-fno-object-determinism— object determinism.-fomit-interface-pragmas,-fno-omit-interface-pragmas— omit interface pragmas.-fomit-yields,-fno-omit-yields— omit yields.-foptimal-applicative-do,-fno-optimal-applicative-do— optimal applicative do ✨-fpedantic-bottoms,-fno-pedantic-bottoms— pedantic bottoms 🙈-fpolymorphic-specialisation,-fno-polymorphic-specialisation— polymorphic specialisation.-fregs-graph,-fno-regs-graph— regs graph.-fregs-iterative,-fno-regs-iterative— regs iterative.-fsimpl-tick-factor=⟨n⟩— takes a number. simpl tick factor.-fsimplifier-phases=⟨n⟩— takes a number. simplifier phases.-fsolve-constant-dicts,-fno-solve-constant-dicts— solve constant dicts.-fspec-constr,-fno-spec-constr— spec constr.-fspec-constr-count=⟨n⟩,-fno-spec-constr-count— the numeric one plus its off switch.-fspec-constr-keen,-fno-spec-constr-keen— spec constr but keen 🫡-fspec-constr-threshold=⟨n⟩,-fno-spec-constr-threshold— threshold version + off switch.-fspec-eval,-fno-spec-eval— spec eval.-fspec-eval-dictfun,-fno-spec-eval-dictfun— spec eval dictfun.-fspecialise,-fno-specialise— specialise.-fspecialise-aggressively,-fno-specialise-aggressively— aggressive specialise, she's not playing 🔥-fspecialise-incoherents,-fno-specialise-incoherents— specialise incoherents 💀-fstatic-argument-transformation,-fno-static-argument-transformation— static argument transformation.-fstg-cse,-fno-stg-cse— stg cse.-fstg-lift-lams,-fno-stg-lift-lams— stg lift lams.-fstg-lift-lams-known,-fno-stg-lift-lams-known— stg lift lams, known variant.-fstg-lift-lams-non-rec-args— stg lift lams non rec args. no off twin.-fstg-lift-lams-non-rec-args-any— and the-anyversion of that one.-fstg-lift-lams-rec-args— stg lift lams rec args.-fstg-lift-lams-rec-args-any— the-anyversion of that one.-fstrictness,-fno-strictness— strictness.-fstrictness-before=⟨n⟩— takes a number. strictness, but before.-funbox-small-strict-fields,-fno-unbox-small-strict-fields— box/unbox the small strict fields (yes, the off one is spelledunbox, keep your eyes peeled 👀)-funbox-strict-fields,-fno-unbox-strict-fields— same energy, without "small".-funfolding-case-scaling=⟨n⟩— takes a number. unfolding case scaling.-funfolding-case-threshold=⟨n⟩— takes a number. unfolding case threshold.-funfolding-creation-threshold=⟨n⟩— takes a number. unfolding creation threshold.-funfolding-dict-discount=⟨n⟩— takes a number. unfolding dict discount 🏷️-funfolding-fun-discount=⟨n⟩— takes a number. unfolding fun discount.-funfolding-keeness-factor=⟨n⟩— takes a number. (spelledkeeness, that's canon, don't fix it 💅)-funfolding-use-threshold=⟨n⟩— takes a number. unfolding use threshold.-fworker-wrapper— worker wrapper 🫶-fworker-wrapper-cbv— worker wrapper, cbv flavour.-fwrite-if-compression=⟨n⟩— takes a number. write if compression.
like… that's the whole list. ngl I need a minute 😭
⚡ Optimization levels ⚡
the fast-food menu of optimisation: pick a level, any level 🍟
-O -O1 -O0 -O0 -O2 -O0 -O⟨n⟩ -O0
-O— the plain one.-O1— level one.-O0— level zero. she appears several times in this list, and bestie I'm not the one who wrote it, I'm just reporting it faithfully 🫡-O0— yep. again.-O2— level two, the spicy one.-O0— third time's the charm 💀-O⟨n⟩— your number, your level. pick a number, any number 🔢-O0— and one more for the road.
📦 Package options 📦
package management hours, bestie — this is how you tell GHC which packages exist, which ones you trust, and which ones you're side-eyeing 🧐
-clear-package-db— clears the package db. poof, gone.-distrust ⟨pkg⟩— you do NOT trust pkg. she's on thin ice 🙅♀️-distrust-all-packages— trust issues, but make it global 💀-fpackage-trust— enables package trust behaviour.-global-package-db— the global package db.-hide-all-packages— hide every single one. nobody's invited.-hide-package ⟨pkg⟩— hide just pkg. targeted.-ignore-package ⟨pkg⟩— ignore pkg entirely.-no-auto-link-packages— no auto link packages.-no-global-package-db— no global package db.-no-user-package-db— no user package db.-package ⟨pkg⟩— invite pkg to the party 🎉-package-db ⟨file⟩— point at file as your package db.-package-env ⟨file⟩|⟨name⟩— package env, by file or by name. both valid, choose your fighter.-package-id ⟨unit-id⟩— package id, by unit-id.-this-unit-id ⟨unit-id⟩— this unit id, by unit-id.-trust ⟨pkg⟩— ok fine, you trust pkg. character development 🫶-user-package-db— the user package db.
🧚 Phases of compilation 🧚
where in the pipeline do you wanna stop? pick a phase, she'll do the rest ✨
--merge-objs— merge objs.-C— the-Cphase.-c— the lowercase-cphase. yes, case matters, bestie, always.-E— the-Ephase.-F— the-Fphase.-S— the-Sphase.-x ⟨suffix⟩— specify a suffix 🏷️
🌸 Overriding external programs 🌸
sometimes you're like "no, I have my OWN C compiler" and GHC is like "ok bestie, noted" — that's this whole section. every one of these takes a ⟨cmd⟩ 💅
-pgma ⟨cmd⟩— override theaprogram with cmd.-pgmc ⟨cmd⟩— override the C compiler with cmd.-pgmCmmP ⟨cmd⟩— override the CmmP program with cmd.-pgmcxx ⟨cmd⟩— override the C++ compiler with cmd.-pgmF ⟨cmd⟩— override theFprogram with cmd.-pgmi ⟨cmd⟩— override theiprogram with cmd.-pgminstall_name_tool ⟨cmd⟩— overrideinstall_name_toolwith cmd. that's the literal name, underscores and all, don't touch it.-pgmJSP ⟨cmd⟩— override the JSP program with cmd.-pgmL ⟨cmd⟩— override uppercaseLwith cmd.-pgml ⟨cmd⟩— override lowercaselwith cmd. (yes, both, they're different, iykyk)-pgmlas ⟨cmd⟩— overridelaswith cmd.-pgmlc ⟨cmd⟩— overridelcwith cmd.-pgmlm ⟨cmd⟩— overridelmwith cmd.-pgmlo ⟨cmd⟩— overridelowith cmd.-pgmotool ⟨cmd⟩— overrideotoolwith cmd.-pgmP ⟨cmd⟩— override thePprogram with cmd.-pgms ⟨cmd⟩— override thesprogram with cmd.-pgmwindres ⟨cmd⟩— overridewindreswith cmd.
🎀 Phase-specific options 🎀
same energy as above but you're not swapping the program — you're slipping an extra ⟨option⟩ to a specific phase 🫶
-opta ⟨option⟩— pass option to theaphase.-optc ⟨option⟩— pass option to the C phase.-optCmmP ⟨option⟩— pass option to the CmmP phase.-optcxx ⟨option⟩— pass option to the C++ phase.-optF ⟨option⟩— pass option to theFphase.-opti ⟨option⟩— pass option to theiphase.-optJSP ⟨option⟩— pass option to the JSP phase.-optL ⟨option⟩— pass option to uppercaseL.-optl ⟨option⟩— pass option to lowercasel.-optlas ⟨option⟩— pass option tolas.-optlc ⟨option⟩— pass option tolc.-optlm ⟨option⟩— pass option tolm.-optlo ⟨option⟩— pass option tolo.-optP ⟨option⟩— pass option to thePphase.-optwindres ⟨option⟩— pass option towindres.-pgmc-supports-no-pie— flags that the C compiler supports no-pie.-pgml-supports-no-pie— same, but for thelprogram.
💜 Platform-specific options 💜
CPU feature flags, aka "please emit the fancy instructions, my machine can handle it" 💅
-mavx— avx ✨-mavx2— avx2 ✨-mavx512cd— avx512cd-mavx512er— avx512er-mavx512f— avx512f-mavx512pf— avx512pf-mbmi— bmi-mbmi2— bmi2-mfma— fma-msse— sse-msse2— sse2-msse3— sse3-msse4— sse4-msse4.2— sse4.2 (dot and all, keep it exact 🎯)
🦋 Compiler plugins 🦋
letting other code into the compiler's brain. very "group project but the group is a plugin system" energy 🧠
-fclear-plugins— clears all the plugins. clean slate, fresh start ✨-fplugin-library=⟨file-path⟩;⟨unit-id⟩;⟨module⟩;⟨args⟩— load a plugin from a library. four semicolon-separated pieces, in that exact order: file path, unit id, module, args. don't lose the semicolons, bestie 🫶-fplugin-opt=⟨module⟩:⟨args⟩— pass args to the plugin module. note the colon.-fplugin-trustworthy— declare the plugin trustworthy. big trust fall energy.-fplugin=⟨module⟩— load the plugin from module.-hide-all-plugin-packages— hide all plugin packages.-plugin-package ⟨pkg⟩— make pkg available as a plugin package.-plugin-package-id ⟨pkg-id⟩— same but by pkg-id.
👑 Profiling 👑
time to find out where your program is spending all its time. she's nosy and honestly? we love that for her 🔍
-auto— auto.-auto-all— auto, but all.-caf-all— caf all.-fno-prof-count-entries,-fprof-count-entries— prof count entries: off, or on.-fprof-auto,-fno-prof-auto— prof auto.-fprof-auto-calls,-fno-prof-auto— prof auto calls, with the shared-fno-prof-autooff switch.-fprof-auto-exported,-fno-prof-auto— prof auto exported, same off switch again.-fprof-auto-top,-fno-prof-auto— prof auto top, same off switch. (the page really does list-fno-prof-autofour times, she's thorough 💀)-fprof-cafs,-fno-prof-cafs— prof cafs.-fprof-callers=⟨name⟩— takes a name. prof callers.-fprof-late,-fno-prof-late— prof late.-fprof-late-inline,-fno-prof-late-inline— prof late inline.-fprof-late-overloaded,-fno-prof-late-overloaded— prof late overloaded.-fprof-late-overloaded-calls,-fno-prof-late-overloaded-calls— prof late overloaded calls.-fprof-manual,-fno-prof-manual— prof manual.-no-auto— no auto.-no-auto-all— no auto all.-no-caf-all— no caf all.-prof— the big one: prof.-ticky— ticky 📊-ticky-allocd— ticky, allocd.-ticky-ap-thunk— ticky ap thunk.-ticky-dyn-thunk— ticky dyn thunk.-ticky-LNE— ticky LNE (caps, keep 'em).-ticky-tag-checks— ticky tag checks.
🍓 Program coverage 🍓
did your tests actually run that line? now we know 🌈
-fhpc— hpc mode on.-hpcdir⟨dir⟩— the hpc dir. heads up: no space before the⟨dir⟩here, that's how it's written, so write it like that 🫶
⭐ Recompilation checking ⭐
GHC's "do I really have to rebuild this?" instincts. she's efficient, she's got places to be 💅
-exclude-module=⟨file⟩— exclude file from the recompilation party.-fforce-recomp,-fno-force-recomp— force recompilation, or don't.-fignore-hpc-changes,-fno-ignore-hpc-changes— ignore hpc changes, or don't.-fignore-optim-changes,-fno-ignore-optim-changes— ignore optim changes, or don't.-include-cpp-deps— include cpp deps.-include-pkg-deps— include pkg deps.
🌈 Redirecting output 🌈
where do the files GO? this is the "everything has a place and I have opinions about it" section 🗂️
-dep-makefile ⟨file⟩— dep makefile goes to file.-dep-suffix ⟨suffix⟩— dep suffix is suffix.-dumpdir ⟨dir⟩— dump stuff into dir.-dynhisuf ⟨suffix⟩— dynhi suffix.-dyno ⟨file⟩— dyno output goes to file.-dynohi ⟨file⟩— dynohi output goes to file.-dynosuf ⟨suffix⟩— dyno suffix.-hcsuf ⟨suffix⟩— hc suffix.-hidir ⟨dir⟩— hi files into dir.-hiedir ⟨dir⟩— hie files into dir.-hiesuf ⟨suffix⟩— hie suffix.-hisuf ⟨suffix⟩— hi suffix.-o ⟨file⟩— the classic-o. output goes to file 🎯-odir ⟨dir⟩— object files into dir.-ohi ⟨file⟩— hi file goes to file.-osuf ⟨suffix⟩— object suffix.-outputdir ⟨dir⟩— the general output dir.-stubdir ⟨dir⟩— stub files into dir.
🧊 Temporary files 🧊
one (1) option. she's lowkey but essential.
-tmpdir ⟨dir⟩— put temporary files in dir. give the girl a home 🏠
💀 Verbosity options 💀
ok this is the diagnostics-and-vibes section — error messages, hole fits, colour, timing, all of it. deep breath, bestie, we're going in 🔥
-fabstract-refinement-hole-fits,-fno-abstract-refinement-hole-fits— abstract refinement hole fits.-fdefer-diagnostics— defer diagnostics. procrastination, but for the compiler.-fdiagnostics-as-json— diagnostics as json. for the machines 🤖-fdiagnostics-color=⟨always|auto|never⟩— colour, and you choose from exactlyalways,auto, ornever. three options, no more, don't get creative 🎨-fdiagnostics-show-caret,-fno-diagnostics-show-caret— show the caret, or don't ^-ferror-spans— error spans.-fhide-source-paths— hide source paths.-fkeep-going— keep going. she's not giving up on you fr fr 💪-fmax-refinement-hole-fits=⟨n⟩,-fno-max-refinement-hole-fits— numeric max, or off.-fmax-relevant-binds=⟨n⟩,-fno-max-relevant-binds— numeric max, or off.-fmax-valid-hole-fits=⟨n⟩,-fno-max-valid-hole-fits— numeric max, or off.-fno-show-valid-hole-fits— show valid hole fits, off. (only the off listed here 👀)-fno-sort-valid-hole-fits,-fsort-valid-hole-fits— sorting, off then on.-fprint-axiom-incomps,-fno-print-axiom-incomps— print axiom incomps.-fprint-equality-relations,-fno-print-equality-relations— print equality relations.-fprint-error-index-links=⟨always|auto|never⟩— error index links,always,auto, ornever. same three, every time 🎚️-fprint-expanded-synonyms,-fno-print-expanded-synonyms— print expanded synonyms.-fprint-explicit-coercions,-fno-print-explicit-coercions— print explicit coercions.-fprint-explicit-foralls,-fno-print-explicit-foralls— print explicit foralls.-fprint-explicit-kinds,-fno-print-explicit-kinds— print explicit kinds.-fprint-explicit-runtime-reps,-fno-print-explicit-runtime-reps— print explicit runtime reps.-fprint-potential-instances,-fno-print-potential-instances— print potential instances.-fprint-redundant-promotion-ticks,-fno-print-redundant-promotion-ticks— print redundant promotion ticks.-fprint-typechecker-elaboration,-fno-print-typechecker-elaboration— print typechecker elaboration.-fprint-unicode-syntax,-fno-print-unicode-syntax— print unicode syntax 🌸-frefinement-level-hole-fits=⟨n⟩,-fno-refinement-level-hole-fits— numeric level, or off.-freverse-errors,-fno-reverse-errors— reverse errors.-fshow-docs-of-hole-fits,-fno-show-docs-of-hole-fits— show docs of hole fits.-fshow-error-context,-fno-show-error-context— show error context.-fshow-hole-constraints— show hole constraints. no off twin here.-fshow-hole-matches-of-hole-fits,-fno-show-hole-matches-of-hole-fits— show hole matches of hole fits.-fshow-provenance-of-hole-fits,-fno-show-provenance-of-hole-fits— show provenance of hole fits.-fshow-type-app-of-hole-fits,-fno-show-type-app-of-hole-fits— show type app of hole fits.-fshow-type-app-vars-of-hole-fits,-fno-show-type-app-vars-of-hole-fits— show type app vars of hole fits.-fshow-type-of-hole-fits,-fno-show-type-of-hole-fits— show type of hole fits.-fsort-by-size-hole-fits,-fno-sort-by-size-hole-fits— sort by size.-fsort-by-subsumption-hole-fits,-fno-sort-by-subsumption-hole-fits— sort by subsumption.-funclutter-valid-hole-fits— unclutter valid hole fits ✨ she's doing her best to tidy up.-Rghc-timing— report ghc timing ⏱️-v— verbose. she's talking now.-v⟨n⟩— verbose with a number, because sometimes you need more talking 🔢
and that's where this part lands, bestie — more chaos incoming, don't go anywhere 💖
⚠️ Warnings ⚠️
okay bestie, deep breath 💖 this next bit is the warning-flag motherload — it's a wall of -W flags and honestly it's giving "shouted the entire dictionary at me". Every single one is listed below, in the exact order they show up, because we do not skip entries in this house 💅 the -W version turns the warning on, the -Wno- version turns it back off. iykyk 🦋
-fenable-th-splice-warnings,-fno-enable-th-splice-warnings-fhelpful-errors,-fno-helpful-errors-fmax-pmcheck-models=⟨n⟩-fshow-warning-groups,-fno-show-warning-groups-fvia-C-W,-Wno-extra-w-Wall,-Wno-all-Wall-missed-specialisations,-Wno-all-missed-specialisations-Wall-missed-specializations,-Wno-all-missed-specializations-Wambiguous-fields-Wauto-orphans-Wbadly-staged-types,-Wno-badly-staged-types-Wcompat,-Wno-compat-Wcompat-unqualified-imports,-Wno-compat-unqualified-imports-Wcpp-undef-Wdata-kinds-tc,-Wno-data-kinds-tc-Wdefault,-Wno-default-Wdefaulted-exception-context,-Wnop-defaulted-exception-context-Wdeferred-out-of-scope-variables,-Wno-deferred-out-of-scope-variables-Wdeferred-type-errors,-Wno-deferred-type-errors-Wdeprecated-flags,-Wno-deprecated-flags-Wdeprecated-type-abstractions,-Wno-deprecated-type-abstractions-Wdeprecations,-Wno-deprecations-Wderiving-defaults,-Wno-deriving-defaults-Wderiving-typeable,-Wno-deriving-typeable-Wdodgy-exports,-Wno-dodgy-exports-Wdodgy-foreign-imports,-Wno-dodgy-foreign-imports-Wdodgy-imports,-Wno-dodgy-imports-Wduplicate-constraints,-Wno-duplicate-constraints-Wduplicate-exports,-Wno-duplicate-exports-Wempty-enumerations,-Wno-empty-enumerations-Werror,-Wwarn-Weverything-w-Wextended-warnings,-Wno-extended-warnings-Wextra,-Wno-extra-Wforall-identifier-Wgadt-mono-local-binds,-Wno-gadt-mono-local-binds-Whi-shadowing,-Wno-hi-shadowing-Widentities,-Wno-identities-Wimplicit-kind-vars,-Wno-implicit-kind-vars-Wimplicit-lift,-Wno-implicit-lift-Wimplicit-prelude,-Wno-implicit-prelude-Wimplicit-rhs-quantification,-Wno-implicit-rhs-quantification-Winaccessible-code,-Wno-inaccessible-code-Wincomplete-export-warnings,-Wno-incomplete-export-warnings-Wincomplete-patterns,-Wno-incomplete-patterns-Wincomplete-record-selectors,-Wno-incomplete-record-selectors-Wincomplete-record-updates,-Wno-incomplete-record-updates-Wincomplete-uni-patterns,-Wno-incomplete-uni-patterns-Winconsistent-flags,-Wno-inconsistent-flags-Winferred-safe-imports,-Wno-inferred-safe-imports-Winline-rule-shadowing,-Wno-inline-rule-shadowing-Winvalid-haddock,-Wno-invalid-haddock-Wloopy-superclass-solve,-Wno-loopy-superclass-solve-Wmisplaced-pragmas,-Wno-misplaced-pragmas-Wmissed-extra-shared-lib,-Wno-missed-extra-shared-lib-Wmissed-specialisations,-Wno-missed-specialisations-Wmissed-specializations,-Wno-missed-specializations-Wmissing-deriving-strategies,-Wno-missing-deriving-strategies-Wmissing-export-lists,-Wno-missing-export-lists-Wmissing-exported-pattern-synonym-signatures,-Wno-missing-exported-pattern-synonym-signatures-Wmissing-exported-signatures,-Wno-missing-exported-signatures-Wmissing-exported-sigs,-Wno-missing-exported-sigs-Wmissing-fields,-Wno-missing-fields-Wmissing-home-modules,-Wno-missing-home-modules-Wmissing-import-lists,-Wno-missing-import-lists-Wmissing-kind-signatures,-Wno-missing-kind-signatures-Wmissing-local-signatures,-Wno-missing-local-signatures-Wmissing-local-sigs,-Wno-missing-local-sigs-Wmissing-methods,-Wno-missing-methods-Wmissing-monadfail-instances,-Wno-missing-monadfail-instances-Wmissing-pattern-synonym-signatures,-Wno-missing-pattern-synonym-signatures-Wmissing-poly-kind-signatures,-Wno-missing-poly-kind-signatures-Wmissing-role-annotations,-Wno-role-annotations-signatures-Wmissing-safe-haskell-mode,-Wno-missing-safe-haskell-mode-Wmissing-signatures,-Wno-missing-signatures-Wmissing-space-after-bang-Wmonomorphism-restriction,-Wno-monomorphism-restriction-Wname-shadowing,-Wno-name-shadowing-Wnoncanonical-monad-instances,-Wno-noncanonical-monad-instances-Wnoncanonical-monadfail-instances,-Wno-noncanonical-monadfail-instances-Wnoncanonical-monoid-instances,-Wno-noncanonical-monoid-instances-Wnot-Woperator-whitespace,-Wno-operator-whitespace-Woperator-whitespace-ext-conflict,-Wno-operator-whitespace-ext-conflict-Worphans,-Wno-orphans-Woverflowed-literals,-Wno-overflowed-literals-Woverlapping-patterns,-Wno-overlapping-patterns-Wpartial-fields,-Wno-partial-fields-Wpartial-type-signatures,-Wno-partial-type-signatures-Wprepositive-qualified-module,-Wno-prepositive-qualified-module-Wredundant-bang-patterns,-Wno-redundant-bang-patterns-Wredundant-constraints,-Wno-redundant-constraints-Wredundant-record-wildcards,-Wno-redundant-record-wildcards-Wredundant-strictness-flags,-Wno-redundant-strictness-flags-Wsafe,-Wno-safe-Wsemigroup,-Wno-semigroup-Wsimplifiable-class-constraints,-Wno-simplifiable-class-constraints-Wstar-binder,-Wno-star-binder-Wstar-is-type,-Wno-star-is-type-Wtabs,-Wno-tabs-Wterm-variable-capture-Wtrustworthy-safe,-Wno-safe-Wtype-defaults,-Wno-type-defaults-Wtype-equality-out-of-scope,-Wno-type-equality-out-of-scope-Wtype-equality-requires-operators,-Wno-type-equality-requires-operators-Wtyped-holes,-Wno-typed-holes-Wunbanged-strict-patterns,-Wno-unbanged-strict-patterns-Wunicode-bidirectional-format-characters-Wunrecognised-pragmas,-Wno-unrecognised-pragmas-Wunrecognised-warning-flags,-Wno-unrecognised-warning-flags-Wunsafe,-Wno-unsafe-Wunsupported-calling-conventions,-Wno-unsupported-calling-conventions-Wunsupported-llvm-version,-Wno-unsupported-llvm-version-Wunticked-promoted-constructors,-Wno-unticked-promoted-constructors-Wunused-binds,-Wno-unused-binds-Wunused-do-bind,-Wno-unused-do-bind-Wunused-foralls,-Wno-unused-foralls-Wunused-imports,-Wno-unused-imports-Wunused-local-binds,-Wno-unused-local-binds-Wunused-matches,-Wno-unused-matches-Wunused-packages,-Wno-unused-packages-Wunused-pattern-binds,-Wno-unused-pattern-binds-Wunused-record-wildcards,-Wno-unused-record-wildcards-Wunused-top-binds,-Wno-unused-top-binds-Wunused-type-patterns,-Wno-unused-type-patterns-Wview-pattern-signatures,-Wno-view-pattern-signatures-Wwarn,-Werror-Wwarnings-deprecations,-Wno-warnings-deprecations-Wwrong-do-bind,-Wno-wrong-do-bind-Wx-⟨category⟩,-Wno-x-⟨category⟩
and THAT'S the whole list, no cap 🫶 if you made it here, you're literally built different 👑
🛠️ Code generation 🛠️
this is the part where GHC decides what kind of output it's actually making — object files, byte-code, LLVM, whatever ✨ it's giving "choose your fighter" and honestly every option is iconic in its own way 💅
-dynamic-too— build the dynamic object files and the static object files while it's compiling. both. at once. multitalented king behaviour 👑-fasm— use the native code generator 🔥-fbyte-code— generate byte-code 🦋-fbyte-code-and-object-code— generate object code and byte-code. why choose 🎀-fexpose-internal-symbols— produce symbols for all functions, including the internal ones. nothing to hide, main character energy 💫-fexternal-dynamic-refs— generate code for linking against dynamic libraries-fllvm— compile using the LLVM code generator 🧚-fno-code— omit code generation entirely. we're just vibing, no output 💀-fobject-code— generate object code-fPIC— generate position-independent code (where available)-fPIE— generate code for a position-independent executable (where available)-fprefer-byte-code— use byte-code if it's available for evaluating TH splices-fwrite-if-simplified-core— write an interface file containing the simplified core of the module 📝-fwrite-interface— always write interface files. always always 🌸
🔬 Debugging the compiler 🔬
okay so this section is for when you're down bad for GHC's internals 😭 it's basically all the -d flags — sanity checks on one side, and a whole buffet of -ddump- flags that dump out every intermediate stage you could possibly want to stare at. it's giving "behind the scenes" and honestly? obsessed 🍓
sanity checking & misc
-dasm-lint— ASM pass sanity checking-dcmm-lint—C--pass sanity checking-dcore-lint— turn on internal sanity checking 🔍-ddisable-js-c-sources— disable the link with C sources compiled to JavaScript-ddisable-js-minifier— generate pretty-printed JavaScript code instead of minified (compacted) code ✨
dumping the assembly pipeline
-ddump-asm— dump final assembly-ddump-asm-conflicts— dump register conflicts from the register allocator 👀-ddump-asm-liveness— dump assembly augmented with register liveness-ddump-asm-native— dump initial assembly-ddump-asm-regalloc— dump the result of register allocation-ddump-asm-regalloc-stages— dump the build/spill stages of the-fregs-graphregister allocator-ddump-asm-stats— dump statistics from the register allocator 📊
dumping everything else in the back end
-ddump-bcos— dump interpreter byte code-ddump-c-backend— dump C code produced by the C (unregisterised) backend-ddump-call-arity— dump output of the call arity analysis pass-ddump-cfg-weights— dump the assumed weights of the CFG-ddump-cmm— dump the finalC--output-ddump-cmm-caf— dump the results of theC--CAF analysis pass-ddump-cmm-cbe— dump the results of common block elimination-ddump-cmm-cfg— dump the results of theC--control flow optimisation pass-ddump-cmm-cps— dump the results of the CPS pass-ddump-cmm-from-stg— dump STG-to-C--output-ddump-cmm-info— dump the results of theC--info table augmentation pass-ddump-cmm-opt— dump the results ofC--toC--optimising passes-ddump-cmm-proc— dump the results of proc-point analysis-ddump-cmm-procmap— dump the results of theC--proc-point map pass-ddump-cmm-raw— dump rawC---ddump-cmm-sink— dump the results of theC--sinking pass-ddump-cmm-sp— dump the results of theC--stack layout pass-ddump-cmm-split— dump the results of theC--proc-point splitting pass-ddump-cmm-switch— dump the results of switch lowering passes-ddump-cmm-thread-sanitizer— dump the results of theC--ThreadSanitizer elaboration pass-ddump-cmm-verbose— write output from mainC--pipeline passes to files 📁-ddump-cmm-verbose-by-proc— show output from mainC--pipeline passes (grouped by proc)
core & analysis dumps
-ddump-core-stats— print a one-line summary of the size of the Core program at the end of the optimisation pipeline 📏-ddump-cpr-signatures— dump CPR signatures-ddump-cpranal— dump CPR analysis output-ddump-cs-trace— trace constraint solver-ddump-cse— dump CSE output-ddump-debug— spills out the generated DWARF debug information 🐛 like it's showing you the receipts of your own binary, bestie.-ddump-deriv— dumps the whole deriving output, so you can see exactly what the compiler manifested for you ✨.-ddump-dmd-signatures— dumps the top-level demand signatures. very serious analysis energy, ngl.-ddump-dmdanal— dumps the demand analysis output 💅 the compiler's little "who actually needs what, and when" report.-ddump-ds— dumps the desugarer output, periodt. that's the core after all the syntactic sugar got dissolved.-ddump-ec-trace— traces the exhaustiveness checker 🔍 so you can watch it check whether your patterns cover everything.-ddump-exitify— dumps output of the exitification pass. yes that's the real name, iconic.-ddump-faststrings— dumps the whole FastString table when it's all finished 🫶 the entire vibe, archived.- *
-ddump-file-prefix=str* — sets the prefix of the filenames used for debugging output 📁 so your dumps get cute little name tags. -ddump-float-in— dumps float in output. floating, literally.-ddump-foreign— dumps foreign export stubs 🌍 for when your Haskell is talking to the outside world.-ddump-full-laziness— dumps full laziness pass output. being lazy but make it productive ✨.-ddump-hie— dumps the hie file syntax tree 🌳 the whole tree-shaped truth.-ddump-hpc— an alias for-ddump-ticked🎀 (yes, it's giving "same energy, different name").-ddump-if-trace— traces interface files, iykyk. every step of the interface-file saga, on display.-ddump-inlinings— dumps the inlinings performed by the simplifier 💫 so you can see what got folded in where.-ddump-js— dumps the final JavaScript code, bestie. full backend reveal 🦋.-ddump-json— deprecated, so use-fdiagnostics-as-jsoninstead 💀 no cap, the old one's on its way out.-ddump-late-cc— dumps core with late cost centres added, so your profiling instrumentation is right there in the middle of the core 🔥.-ddump-liberate-case— dumps liberate case output. freeing the case expressions, main character energy.-ddump-llvm— dumps LLVM intermediate code 👑 for when you're going through the LLVM backend.-ddump-mod-map— dumps the state of the module mapping database 🗂️ a little snapshot of who maps to what.-ddump-occur-anal— dumps occurrence analysis output ✨ the analysis where the compiler clocks who shows up and how often.-ddump-opt-cmm— dumps the results ofC--toC--optimising passes 💅 C-- stays winning.-ddump-parsed— dumps the parse tree 🌳 pure syntax-tree realness, before anything else has touched it.-ddump-parsed-ast— dumps parser output as a syntax tree ✨ the AST version of the same vibe.-ddump-prep— dumps prepared core, which is core in its prepped era 🎀.-ddump-rn— dumps renamer output. the renamer said what it said.-ddump-rn-ast— dumps renamer output as a syntax tree 🌳.-ddump-rn-stats— renamer stats 📊 numbers about the renaming, slay.-ddump-rn-trace— traces the renamer 🔍.-ddump-rtti— traces runtime type inference 💫 types, inferred, at runtime.-ddump-rule-firings— dumps rule firing info 🔥 literally the rules going off.-ddump-rule-rewrites— dumps detailed rule firing info 🔥🔥 extra detailed, because you deserve the full story.-ddump-rules— dumps rewrite rules. the rulebook, unedited 💅.-ddump-simpl— dumps the final simplifier output ✨ the simplifier's final form, iconic.-ddump-simpl-iterations— dumps output from each simplifier iteration 🔁 one dump per round, no skipping.-ddump-simpl-stats— dumps simplifier stats 📊.-ddump-simpl-trace— dumps trace messages in the simplifier 🔍.-ddump-spec— dumps specialiser output ✨ the specialiser's greatest hits.-ddump-spec-constr— dumps specialiser output from SpecConstr 🎀 constructor-flavoured specialization.-ddump-splices— dumps TH spliced expressions, and what they evaluate to 💫 template Haskell showing off its handiwork.-ddump-static-argument-transformation— dumps static argument transformation output. SAT, but the compiler kind, not the vibe-killer exam.-ddump-stg— deprecated, it's an alias for-ddump-stg-from-core💀.-ddump-stg-cg— shows output after Stg2Stg 🌸 the post-pass glow-up.-ddump-stg-final— shows output of the last STG pass 👑 the final form.-ddump-stg-from-core— shows CoreToStg output, the moment core becomes STG 🦋.-ddump-stg-tags— shows output of the tag inference pass 🏷️ tagged and thriving.-ddump-stg-unarised— shows unarised STG. yes, unarised is the word, bestie.-ddump-str-signatures— deprecated, alias for-ddump-dmd-signatures💀.-ddump-stranal— deprecated, alias for-ddump-dmdanal💀.-ddump-tc— dumps typechecker output 🌈 the typechecker checked, and now you get to see it.-ddump-tc-ast— dumps typechecker output as a syntax tree 🌳.-ddump-tc-trace— traces the typechecker 🔍 every single typechecking moment, exposed.-ddump-ticked— dumps the code instrumented by HPC (Observing Code Coverage) 🎯 coverage ticks and all.-ddump-timings— dumps per-pass timing and allocation statistics ⏱️ so you know exactly which pass is eating your build time.-ddump-to-file— dumps to files instead of stdout 📁 which, honestly, is the move when the dump is huge.-ddump-types— dumps type signatures 🖊️ the types, in writing.-ddump-verbose-inlinings— dumps all considered inlinings 💅 not just the ones that won, but every candidate.-ddump-view-pattern-commoning— dumps commoned view patterns ✨.-ddump-worker-wrapper— dumps worker-wrapper output 🔧 the classic worker/wrapper transformation, on display.-dfaststring-stats— shows statistics for fast string usage when finished 📊.-dhex-word-literals— prints values of typeWord#in hexadecimal 🧮 hex girl summer.- *
-dinitial-unique=s* — starts UniqSupply allocation from s 🎀 pick your starting point. - *
-dinline-check=str* — dumps information about inlining decisions 🔍 so you can see why the inliner did what it did. -dipe-stats— shows statistics about IPE information 📊.-dkeep-comments— includes comments in the parser 🫶 useful in combination with-ddump-parsed-ast, so keep that in mind.-dlinear-core-lint— turns on internal sanity checking 🧠 not a vibe check, an actual sanity check.-dlint— enables several common internal sanity checkers ✅ the all-in-one sanity bundle.-dno-debug-output— suppresses unsolicited debugging output 🙈 the compiler stops oversharing.-dno-typeable-binds— doesn't generate bindings forTypeablemethods 🚫.-dppr-case-as-let— prints single alternative case expressions as strict lets 💅 a formatting choice, and honestly a look.- *
-dppr-cols=n* — sets the width of debugging output 📏 for example-dppr-cols200. -dppr-debug— turns on debug printing, which is more verbose 🔍 so much more verbose.-dppr-user-length— sets the depth for printing expressions in error msgs 🎀 so your errors stay readable.- *
-drule-check=str* — dumps information about potential rule application 🔍 the almost-fired rules. -dshow-passes— prints out each pass name as it happens 📢 live commentary from the compiler.-dstg-lint— STG pass sanity checking 🧠.-dsuppress-all— in dumps, suppresses everything (except for uniques) that is suppressible 🙈 maximum minimalism.-dsuppress-coercion-types— suppresses the printing of coercion types in Core dumps to make them shorter ✂️ shorter dumps, less scrolling.-dsuppress-coercions— suppresses the printing of coercions in Core dumps to make them shorter ✂️.-dsuppress-core-sizes— suppresses the printing of core size stats per binding (since 9.4) 📉.-dsuppress-idinfo— suppresses extended information about identifiers where they are bound 🙈.-dsuppress-module-prefixes— suppresses the printing of module qualification prefixes 🚫 so no moreM.everywhere.-dsuppress-stg-free-vars— suppresses the printing of closure free variable lists in STG output ✂️.-dsuppress-stg-reps— suppresses rep annotations on STG args 💅.-dsuppress-ticks— suppresses "ticks" in the pretty-printer output 🎀.-dsuppress-timestamps— suppresses timestamps in dumps ⏱️ which is lowkey essential for clean diffs.-dsuppress-type-applications— suppresses type applications 🚫.-dsuppress-type-signatures— suppresses type signatures 🚫.-dsuppress-unfoldings— suppresses the printing of the stable unfolding of a variable at its binding site ✂️.-dsuppress-uniques— suppresses the printing of uniques in debug output (easier to use diff) 🫶 genuinely so helpful for diffing.-dsuppress-var-kinds— suppresses the printing of variable kinds 🚫.-dtag-inference-checks— affirms tag inference results are correct at runtime ✅ runtime confirmation, no cap.-dth-dec-file— dumps evaluated TH declarations into*.th.hsfiles 📁.- *
-dunique-increment=i* — sets the increment for the generated Unique's to i 🎀. -dverbose-core2core— shows output from each core-to-core pass 🔁 every pass, out loud.-dverbose-stg2stg— shows output from each STG-to-STG pass 🔁.-fadd-bco-name— addsBCO_NAMEinstructions in generated bytecode 🏷️.-falignment-sanitisation— compiles with alignment checks for all info table dereferences 🛡️.-fcatch-nonexhaustive-cases— adds a default error alternative to case expressions without a default alternative 🚨 so a non-exhaustive case becomes a runtime error instead of undefined chaos.-fcheck-prim-bounds— instruments array primops with bounds checks 🚧 safety first, bestie.-fcmm-thread-sanitizer— enables ThreadSanitizer instrumentation of memory accesses 🧵 catching the races.-fdistinct-constructor-tables— generates a fresh info table for each usage of a data constructor 🎀 every single one gets its own table.-fdump-with-ways— includes the tag of the enabled ways in the extension of dump files 🏷️.-finfo-table-map— embeds a lookup table in the generated binary which maps the address of an info table to the source position the closure originated from 🗺️ the ultimate "where did this come from" map.-finfo-table-map-with-fallback— includes info tables with no source location information in the info table map 🫶.-finfo-table-map-with-stack— includes info tables forSTACKclosures in the info table map 🥞.-fllvm-fill-undef-with-garbage— instructs LLVM to fill dead STG registers with garbage 🗑️ (yes, deliberately garbage, it's on purpose).-fno-info-table-map-with-fallback— omits info tables with no source location information from the info table map 🚫.-fno-info-table-map-with-stack— omits info tables forSTACKclosures from the info table map 🚫.-forig-thunk-info— generatesstg_orig_thunk_infostack frames on thunk entry 🧵.-fproc-alignment— aligns functions at given boundary 📐.-funoptimized-core-for-interpreter— disables optimizations with the interpreter 🐢 unoptimized but interpretable.-g— produces DWARF debug information in compiled object files 🐛 n can be0,1, or2, with higher numbers producing richer output. If n is omitted, level2is assumed ✨.
🎀 C pre-processor 🎀
-cpp— runs the C pre-processor on Haskell source files 🏃♀️ yes, on Haskell files, that's the whole bit.-D<symbol>[=<value>]— defines a symbol in the C pre-processor 🏷️.-I<dir> — adds dir to the directory search list for#includefiles 📁.-U<symbol> — undefines a symbol in the C pre-processor 🚫.
🧚 Finding imports 🧚
-i— empties the import directory list 🧹 a clean slate, bestie.-i<dir>[:<dir>]*— adds dir, dir2, etc. to the import path 🛤️ one or many, colon-separated.
💅 Interactive mode 💅
-fbreak-on-error— breaks on uncaught exceptions and errors 🛑.-fbreak-on-exception— breaks on any exception thrown 💥.-fbreak-points— inserts breakpoints in the GHCi debugger 🎯 debugging era.- *
-fghci-hist-size=n* — sets the number of entries GHCi keeps for:history📜 see The GHCi Debugger. -fghci-leak-check— (debugging only) checks for space leaks when loading new modules in GHCi 🫧 leak hunting, but only for debugging.-fimplicit-import-qualified— puts in scope qualified identifiers for every loaded module 🌈.-flocal-ghci-history— uses current directory for the GHCi command history file.ghci-history📁 keeping it local, keeping it cute.-fno-it— no longer sets the special variableit🚫 that variable's era is over.-fprint-bind-result— turns on printing of binding results in GHCi 🖨️.-fprint-evld-with-show— instructs:printto useShowinstances where possible 💅.-fshow-loaded-modules— shows the names of modules that GHCi loaded after a:loadcommand 📋.-ghci-script— reads additional.ghcifiles 📜 more scripts, more power.-ignore-dot-ghci— disables reading of.ghcifiles 🙈.-interactive-printname — selects the function to use for printing evaluated expressions in GHCi 🖨️ you pick the printer, you're the main character.
🫶 Interface files 🫶
--show-ifacefile — see Modes of operation 👀.-ddump-hi— dumps the new interface to stdout 📤 the interface, right there in your terminal.-ddump-hi-diffs— shows you the diff between the new interface and the old one 🫶 like a glow-up reveal for your.hifiles.-ddump-minimal-imports— dumps out the most minimal set of imports that would still make your module work. iykyk, it's giving "declutter your room" energy 🎀
🧚 Keeping intermediate files 🧚
okay so normally GHC cleans up after itself like a good roommate, but if you want to keep the mess around for inspection, these are your girls ✨
-keep-hc-file— keeps the intermediate.hcfiles around 💅-keep-hi-files— keeps the intermediate.hifiles. lowkey this one is already the default, no cap.-keep-hscpp-file— keeps the intermediate.hscppfiles, for when you gotta see the post-preprocessor tea ☕-keep-llvm-file— keeps the intermediate LLVM.llfiles. heads up bestie: this one implies-fllvm🔥-keep-o-files— keeps the intermediate.ofiles. also the default already, so it's giving "yes queen we know" 💀-keep-s-file— keeps the intermediate.sfiles, assembly girlies rise 🌸-keep-tmp-files— keeps all the intermediate temporary files. every last one. no crumbs left behind 🙈
✨ Language options ✨
this is the section that goes on forever and honestly? iconic. every -X flag you could ever want, one per bullet, all facts intact 💖
-XAllowAmbiguousTypes— lets you write ambiguous types, and lets the type inference engine infer them too ✨-XApplicativeDo— letsdo-notation statements desugar viaApplicativeinstead of onlyMonad. slay.-XArrows— allows arrow notation, e.g.proc🏹-XBangPatterns— allows bang pattern syntax.!goes brr.-XBinaryLiterals— allows binary literal syntax.0b1010bestie 💅-XBlockArguments— allowsdoblocks and other constructs to be passed as function arguments 🫶-XCApiFFI— allows foreign imports to be declared with thecapicalling convention.-XConstrainedClassMethods— allows class methods to have non-empty contexts 👑-XConstraintKinds— allows constraints to be used as types of kindConstraint.-XCPP— resolves C preprocessor directives. yes the preprocessor is crashing the function party 🎉-XCUSKs— detects complete user-supplied kind signatures. (yes, CUSKs. that's the real acronym. we love her.)-XDataKinds— allows use of data constructors in types 🌈-XDatatypeContexts— allows contexts on data types.-XDeepSubsumption— uses GHC's deep subsumption checking.-XDefaultSignatures— allows default signatures for typeclass methods 💜-XDeriveAnyClass— allows deriving syntax to be used for any class. any. periodt.-XDeriveDataTypeable— allows deriving for theDataclass.-XDeriveFoldable— allows deriving for theFoldableclass.-XDeriveFunctor— allows deriving for theFunctorclass.-XDeriveGeneric— allows deriving ofGenericinstances.-XDeriveLift— allows deriving for theLiftclass.-XDeriveTraversable— allows deriving for theTraversableclass.-XDerivingStrategies— allows use of instance deriving strategies 🎀-XDerivingVia— allows deriving instances via types of the same runtime representation. it's giving "same vibe, different wrapper" ✨-XDisambiguateRecordFields— automatically disambiguates some record field references. so thoughtful of her.-XDuplicateRecordFields— allows definition of record types with identically-named fields. literally two fields, one name, zero drama 💅-XEmptyCase— allowscaseexpressions with no alternatives. empty but make it fashion 💀-XEmptyDataDecls— allows definition of empty data types.-XEmptyDataDeriving— allows deriving instances of standard type classes for empty data types 🫶-XExistentialQuantification— allows existentially quantified type variables in types.-XExplicitForAll— allows explicit universal quantification.forallsaid out loud 🗣️-XExplicitNamespaces— allows use of the keywordtypeto specify the namespace of entries in imports and exports.-XExtendedDefaultRules— uses GHCi's extended default rules in a normal module. GHCi behaviour, main character energy 👑-XExtendedLiterals— allows numeric literal postfix syntax for unboxed integers.-XFieldSelectors— makes record field selector functions visible in expressions 👀-XFlexibleContexts— removes some restrictions on class contexts.-XFlexibleInstances— allows instance heads to mention arbitrary nested types 🌸-XForeignFunctionInterface— allows foreign function interface syntax. hello C, nice to meet you 🤝-XFunctionalDependencies— allows functional dependencies to be given on typeclass declarations.-XGADTs— allows definition of generalised algebraic data types ✨-XGADTSyntax— allows generalised algebraic data type syntax.-XGeneralisedNewtypeDeriving— allows instances to be derived via newtype deriving. (the British spelling, we stan 🇬🇧)-XGeneralizedNewtypeDeriving— allows instances to be derived via newtype deriving. (the American spelling, equally valid 🦅)-XGHC2021— uses GHC's set of default language extensions from 2021. vintage but not that vintage 💅-XGHC2024— uses GHC's set of default language extensions from 2024. fresh out the oven 🔥-XGHCForeignImportPrim— allows theprimcalling convention. intended for internal use only bestie, so like… stay out of there 🙈-XHaskell2010— uses the Haskell 2010 language edition.-XHaskell98— uses the Haskell 98 language edition. ancient, respect her 🏛️-XHexFloatLiterals— allows hexadecimal floating-point literal syntax.-XImplicitParams— allows implicit parameter constraints.-XImplicitPrelude— implicitly importsPrelude. the default of defaults.-XImportQualifiedPost— allows the syntaximport M qualified.-XImpredicativeTypes— allows impredicative types. don't ask, just know she's powerful 😭-XIncoherentInstances— allows definitions of instances that may result in incoherence. chaotic, but on purpose 💀-XInstanceSigs— allows type signatures to be written for instance methods ✨-XInterruptibleFFI— allows interruptible FFI imports.-XKindSignatures— allows kind signatures to be given for types 🎀-XLambdaCase— allows\caseexpressions. so much cleaner, obsessed.-XLexicalNegation— uses whitespace to determine whether the minus sign stands for negation or subtraction. whitespace is doing work here 👑-XLiberalTypeSynonyms— relaxes many of Haskell 98's rules on type synonym definitions.-XLinearTypes— allows writing of linear arrow types. impliesMonoLocalBinds🫶-XListTuplePuns— enables punning for list, tuple and sum types.-XMagicHash— allows#as a postfix modifier on identifiers. magic by name, magic by nature 🔮-XMonadComprehensions— allows list comprehension syntax to be used at monads other thanList.-XMonoLocalBinds— does not generalise types of local bindings. no generalising, we stay specific 💅-XMonomorphismRestriction— applies the Haskell 2010 monomorphism restriction.-XMultilineStrings— enables multiline string literals. finally, room to breathe 📝-XMultiParamTypeClasses— enables multi-parameter type classes.-XMultiWayIf— allows multi-way if-expressions.-XNamedDefaults— enables default declarations with explicitly named class, extendingTypeclass defaulting ✨-XNamedFieldPuns— allows record field punning syntax.-XNamedWildCards— allows named wildcards in types.-XNegativeLiterals— allows negative numeric literal syntax. minus signs, but make it literal.-XNondecreasingIndentation— allows nested contexts to be at the same indentation level as its enclosing context 🌸-XNPlusKPatterns— allows use of n+k patterns.-XNullaryTypeClasses— deprecated, does nothing. nullary type classes are now enabled usingMultiParamTypeClasses. so like… retire her 💀-XNumDecimals— allows use of scientific notation syntax for integer literals.-XNumericUnderscores— allows underscores in numeric literals.1_000_000my beloved 🥰-XOrPatterns— enables or-patterns.-XOverlappingInstances— allows definition of overlapping instances.-XOverloadedLabels— allows overloaded label syntax.-XOverloadedLists— desugars list syntax via theIsListclass.-XOverloadedRecordDot— allows.to be used for record field access. dot notation girlies we are SO back 💅-XOverloadedRecordUpdate— allows.syntax in record updates.-XOverloadedStrings— desugars string literals via theIsStringclass.-XPackageImports— allows package-qualified import syntax.-XParallelListComp— allows parallel list comprehension syntax ⚡-XPartialTypeSignatures— allows type signatures to contain wildcards 🎀-XPatternGuards— allows pattern guards syntax.-XPatternSynonyms— allows definition of pattern synonyms.-XPolyKinds— allows kind polymorphism 🌈-XPostfixOperators— allows the use of postfix operators.-XQualifiedDo— allows qualified do-notation desugaring.-XQuantifiedConstraints— allowsforallquantifiers in constraints 👑-XQuasiQuotes— allows quasiquotation syntax.-XRank2Types— enables rank-2 types.-XRankNTypes— allows types of rank greater than one.-XRebindableSyntax— allows rebinding of builtin syntax. yes you can change the builtins, no I'm not scared 😭-XRecordWildCards— allows use of record wildcard syntax.-XRecursiveDo— allows recursive do (e.g.mdo) notation.-XRequiredTypeArguments— allows use of required type argument syntax in terms.-XRoleAnnotations— allows role annotation syntax.-XSafe— enables the Safe Haskell Safe mode 🛡️-XScopedTypeVariables— lexically scopes explicitly-introduced type variables.-XStandaloneDeriving— allows standalone instance deriving declarations.-XStandaloneKindSignatures— allows standalone kind signature declarations ✨-XStarIsType— treats*asData.Kind.Type.-XStaticPointers— allows static syntax.-XStrict— makes bindings in the current module strict by default. no laziness in this house 🫶-XStrictData— treats datatype fields as strict by default.-XTemplateHaskell— allows Template Haskell's splice and quotation syntax.-XTemplateHaskellQuotes— allows Template Haskell's quotation syntax. (quotes only, not the splices, okurrr)-XTraditionalRecordSyntax— allows traditional record syntax (e.g.C {f = x}).-XTransformListComp— allows generalised list comprehension syntax.-XTrustworthy— enables the Safe Haskell Trustworthy mode 🤝-XTupleSections— allows use of tuple section syntax.-XTypeAbstractions— allows type abstraction syntax in patterns and type variable binders.-XTypeApplications— allows type application syntax in terms and types 🌸-XTypeData— allows type data declarations.-XTypeFamilies— allows definition of type families. found family but make it types 💖-XTypeFamilyDependencies— allows injectivity annotations on type families.-XTypeInType— deprecated. enables kind polymorphism and datatype promotion. she's retired bestie, move on 💀-XTypeOperators— allows type constructors to be given operator names.-XTypeSynonymInstances— allows type synonyms to be mentioned in instance heads.-XUnboxedSums— allows the use of unboxed sum syntax.-XUnboxedTuples— allows the use of unboxed tuple syntax.-XUndecidableInstances— allows definition of instances which may make solving undecidable. highkey risky, but she's iconic for it 🔥-XUndecidableSuperClasses— lets you have literally all the superclass constraints, even the ones that might make the typechecker spin forever. non-termination? she's allowed 💅-XUnicodeSyntax— unicode syntax ON, bestie ✨-XUnliftedDatatypes— lets you define unlifted data types 🦋-XUnliftedFFITypes— lets foreign imports have certain unlifted types in their signatures 🔥-XUnliftedNewtypes— lets you define unlifted newtypes. iconic 💜-XUnsafe— turns on Safe Haskell Unsafe mode 🚨-XViewPatterns— allows view pattern syntax 👑
🔗 Linking options 🫶
-c— stop after generating the object (.o) file, that's it, we're done here ✋-debug— use the debugging runtime 🐛-dylib-install-name ⟨path⟩— sets the install name (it's passed to Apple's linker as-install_name), and you give it the full install path of the library file. Any libraries or executables that link with it later will pick up that path as their runtime search location for it. Darwin/OS X only 🍎-dynamic— build dynamically-linked object files and executables 💫-dynload— picks one of a number of modes for finding shared libraries at runtime 🔍-eventlog— enable runtime event tracing 📊-fcompact-unwind— tells the linker to produce a__compact_unwindsection 🌀-fkeep-cafs— do not garbage-collect CAFs (top-level expressions) at runtime, they stay 🫶-flink-rts— link the runtime when generating a shared or static library 🔗-fno-embed-manifest— don't embed the manifest in the executable (Windows only) 🪟-fno-gen-manifest— don't generate a manifest file (Windows only) 🪟-fno-shared-implib— don't generate an import library for a DLL (Windows only) 🪟-framework ⟨name⟩— Darwin/OS X/iOS only: link in the framework ⟨name⟩. This option corresponds to the-frameworkoption for Apple's Linker 🍏-framework-path ⟨dir⟩— Darwin/OS X/iOS only: add ⟨dir⟩ to the list of directories searched for frameworks. This one corresponds to the-Foption for Apple's Linker 🍏-fsplit-sections— split sections so link-time dead-code stripping can do its thing ✂️-fuse-rpaths— set the rpath based on-Lflags 🛤️-fwhole-archive-hs-libs— when linking a binary executable, this inserts the flag-Wl,--whole-archivebefore any-lflags for Haskell libraries, and-Wl,--no-whole-archiveafter them 📦-L ⟨dir⟩— add ⟨dir⟩ to the list of directories searched for libraries 📁-l ⟨lib⟩— link in library ⟨lib⟩ 🔗-main-is ⟨thing⟩— set the main module and function 🎯-no-hs-main— don't assume this program containsmain🙈-no-pie— don't instruct the linker to produce a position-independent executable 🚫-no-rtsopts-suggestions— don't print RTS suggestions about linking with-rtsopts[=⟨none|some|all|ignore|ignoreAll⟩]🤫-package ⟨name⟩— expose package ⟨pkg⟩ 📦-pie— instruct the linker to produce a position-independent executable ✨-rdynamic— tells the linker to add all symbols to the dynamic symbol table, not just the used ones. Currently Linux and Windows/MinGW32 only. It's equivalent to using-optl -rdynamicon Linux, and-optl -export-all-symbolson Windows 🔥-rtsopts[=⟨none|some|all|ignore|ignoreAll⟩]— controls whether the RTS behaviour can be tweaked via command-line flags and theGHCRTSenvironment variable. Let's break it down, bestie:nonemeans no RTS flags can be given at allsomemeans only a minimum of safe options can be given (this is the default, if-rtsoptsis not passed)allmeans all RTS flags are permitted (this is the default, if-rtsoptsis passed with no argument)ignoremeans RTS flags can be given, but they're treated as regular arguments and passed to the Haskell program as argumentsignoreAllis the same asignore, butGHCRTSis also ignored
ngl this one's important:-rtsoptsdoes not affect-with-rtsoptsbehavior. Flags passed via-with-rtsoptsare used regardless of-rtsopts💀
-shared— generate a shared library (as opposed to an executable) 📚-single-threaded— use the single-threaded runtime 1️⃣-static— use static Haskell libraries 🗿-staticlib— generate a standalone static library (as opposed to an executable). This is useful when cross compiling. The library, together with all its dependencies, ends up in a single static library that you can link against 🧱-threaded— use the threaded runtime 🧵-with-rtsopts=⟨opts⟩— set the default RTS options to ⟨opts⟩ ⚙️
🧩 Miscellaneous options 🍓
-ddump-mod-cycles— dump module cycles 🔄-fdefer-out-of-scope-variables— converts "variable out of scope" errors into warnings. It's implied by-fdefer-type-errors. See also-Wdeferred-out-of-scope-variables🙈-fdefer-type-errors— turns type errors into warnings, deferring the error until runtime. Implies-fdefer-typed-holesand-fdefer-out-of-scope-variables. See also-Wdeferred-type-errors😭-fdefer-typed-holes— converts typed hole errors into warnings, deferring the error until runtime. Implied by-fdefer-type-errors. See also-Wtyped-holes🕳️-fexternal-interpreter— run interpreted code in a separate process 🧚-ffamily-application-cache— use a cache when reducing type family applications 🗄️-fglasgow-exts— deprecated ⚠️ enables most language extensions; see Controlling editions and extensions for exactly which ones-fno-safe-haskell— disable Safe Haskell 🛑-ghcversion-file ⟨path to ghcversion.h⟩— (GHC as a C compiler only) use thisghcversion.hfile 📄-H ⟨size⟩— set the minimum size of the heap to ⟨size⟩ 📏-hidden-module ⟨module name⟩— a module which should not be visible outside its unit 🙈-j[⟨n⟩]— when compiling with--make, compile ⟨n⟩ modules in parallel ⚡-jsem— when compiling with--make, coordinate with other processes through the semaphore ⟨sem⟩ to compile modules in parallel 🤝-reexported-module ⟨reexport-spec⟩— a module which should be reexported from this unit 🔁-this-package-name ⟨unit-id⟩— the name of the package which this module would be part of when installed 📦-unit @⟨filename⟩— specify the options to build a specific unit 🧱-working-dir ⟨dir⟩— specify the directory a unit is expected to be compiled in 📁
🎛️ Modes of operation 👑
--frontend ⟨module⟩— run GHC with the given frontend plugin; see Frontend plugins for the deets 🔌--help— display help 🆘--info— display information about the compiler ℹ️--interactive— interactive mode — normally used by just runningghci; see Using GHCi for details 💬--make— build a multi-module Haskell program, automatically figuring out dependencies. Likely to be much easier, and faster, than usingmake; see Using ghc --make for details 🏗️--numeric-version— display GHC version (numeric only) 🔢--print-booter-version— display bootstrap compiler version 🥾--print-build-platform— display platform on which GHC was built 🏭--print-c-compiler-flags— C compiler flags used to build GHC 🅲--print-c-compiler-link-flags— C linker flags used to build GHC 🔗--print-debug-on— print whether GHC was built with-DDEBUG🐛--print-global-package-db— display GHC's global package database directory 📚--print-have-interpreter— display whether GHC was built with interactive support 💬--print-have-native-code-generator— display whether target platform has NCG support ⚙️--print-host-platform— display host platform of GHC 🖥️--print-ld-flags— display linker flags used to compile GHC 🔧--print-leading-underscore— display use of leading underscores on symbol names_--print-libdir— display GHC library directory 📁--print-object-splitting-supported— display whether GHC supports object splitting ✂️--print-project-git-commit-id— display Git commit id GHC is built from 🔖--print-project-version— display GHC version 🏷️--print-rts-ways— display which way RTS was built 🛠️--print-stage— display stage number of GHC 🪜--print-support-smp— display whether GHC was compiled with SMP support 🧵--print-tables-next-to-code— display whether GHC was compiled with--enable-tables-next-to-code📊--print-target-platform— display target platform of GHC 🎯--print-unregisterised— display whether this GHC was built in unregisterised mode 🗿--run ⟨file⟩— run a Haskell program 🏃--show-iface ⟨file⟩— display the contents of an interface file 📄--show-options— display the supported command line options 📋--supported-extensions— display the supported language extensions 🧩--version— display GHC version 🏷️-e ⟨expr⟩— evaluateexpr; see Expression evaluation mode for details 🧮-M— generate dependency information suitable for use in aMakefile; see Dependency generation for details 📝-shared— create a shared object 📚
⚡ Individual optimizations 🔥
-fasm-shortcutting— enable shortcutting on assembly. Implied by-O2✂️-fbinary-blob-threshold=⟨n⟩— default:500K. tweak the assembly generator for binary blobs 🧱-fblock-layout-cfg— use the new cfg based block layout algorithm. Implied by-O🗺️-fblock-layout-weightless— ignore cfg weights for code layout ⚖️-fblock-layout-weights— sets edge weights used by the new code layout algorithm 🏋️-fcall-arity— enable call-arity optimisation. Implied by-O📞-fcase-folding— enable constant folding in case expressions. Implied by-O🧊-fcase-merge— enable case-merging. Implied by-O🔀-fcmm-control-flow— enable control flow optimisation in the Cmm backend. Implied by-O🌊-fcmm-elim-common-blocks— enable Cmm common block elimination. Implied by-O🧹-fcmm-sink— enable Cmm sinking. Implied by-O🕳️-fcmm-static-pred— enable static control flow prediction. Implied by-O🔮-fcore-constant-folding— enable constant folding in Core. Implied by-O🧊-fcpr-anal— turn on Constructed Product Result analysis. Implied by-O🎀-fcross-module-specialise— turns on specialisation of overloaded functions imported from other modules. Implied by-O. no cap ✨-fcse— enables common sub-expression elimination. Implied by-O. slay 💅-fdicts-cheap— makes dictionary-valued expressions seem cheap to the optimiser. lowkey bribing the optimiser 🎀-fdicts-strict— makes dictionaries strict. Implied by-O2. 🦋-fdmd-tx-dict-sel— (deprecated) use a special demand transformer for dictionary selectors. 💀-fdmd-unbox-width=⟨n⟩— default: 3. Boxity analysis pretends that returned records with this many fields can be unboxed. 🌸-fdo-clever-arg-eta-expansion— enables sophisticated argument eta-expansion. Implied by-O2. 🧚-fdo-eta-reduction— enables eta-reduction. Always enabled by default. ⭐-fdo-lambda-eta-expansion— enables lambda eta-expansion. Always enabled by default. 🌈-feager-blackholing— turns on eager blackholing. 🔥-fenable-rewrite-rules— switches on all rewrite rules (including rules generated by automatic specialisation of overloaded functions). Implied by-O. 💅-fexcess-precision— enables excess intermediate precision. 🎀-fexitification— enables exitification optimisation. Implied by-O. ✨-fexpose-all-unfoldings— exposes all unfoldings, even for very large or recursive functions. 👑-fexpose-overloaded-unfoldings— exposes unfoldings carrying constraints, even for very large or recursive functions. 🦋-ffloat-in— turns on the float-in transformation. Implied by-O. 🌸-ffull-laziness— turns on full laziness (floating bindings outwards). Implied by-O. 🧚-ffun-to-thunk— (deprecated) superseded by-ffull-laziness. 💀-fignore-asserts— ignores assertions in the source. Implied by-O. 🙈-fignore-interface-pragmas— ignores pragmas in interface files. Implied by-O0only. 🫠-finline-generics— annotates methods of derivedGenericandGeneric1instances withINLINE[1]pragmas based on heuristics. Implied by-O. ✨-finline-generics-aggressively— annotates methods of all derivedGenericandGeneric1instances withINLINE[1]pragmas. 🔥-finter-module-far-jumps— assumes code sections can be very large. 🦋-fkeep-auto-rules— keeps all"auto"rules, generated by specialisation. 🎀-flate-dmd-anal— runs demand analysis again, at the end of the simplification pipeline. 🌀-flate-specialise— runs a late specialisation pass. ✨-fliberate-case— turns on the liberate-case transformation. Implied by-O2. 💅-fliberate-case-threshold=⟨n⟩— default: 2000. Sets the size threshold for the liberate-case transformation to⟨n⟩. 🌸-fllvm-pass-vectors-in-regs— (deprecated) does nothing. 💀-flocal-float-out— enables local floating definitions out of let-binds. 🦋-flocal-float-out-top-level— enables local floating to float top-level bindings. 🧚-floopification— turns saturated self-recursive tail-calls into local jumps in the generated assembly. Implied by-O. 🔥-fmax-forced-spec-args=⟨n⟩— default: 333. Maximum number of value arguments for forced SpecConstr specializations. 👑-fmax-inline-alloc-size=⟨n⟩— default: 128. Sets the maximum size of inline array allocations to⟨n⟩bytes (default: 128). 🎀-fmax-inline-memcpy-insns=⟨n⟩— default: 32. Inlinememcpycalls if they would generate no more than⟨n⟩pseudo instructions. 🌸-fmax-inline-memset-insns=⟨n⟩— default: 32. Inlinememsetcalls if they would generate no more than⟨n⟩pseudo instructions. 🦋-fmax-simplifier-iterations=⟨n⟩— default: 4. Sets the max iterations for the simplifier. 🌀-fmax-uncovered-patterns=⟨n⟩— default: 4. Sets the maximum number of patterns to display in warnings about non-exhaustive ones. 👀-fmax-worker-args=⟨n⟩— default: 10. Maximum number of value arguments for a worker. 💪-fno-opt-coercion— turns off the coercion optimiser. 🚫-fno-pre-inlining— turns off pre-inlining. 🚫-fno-state-hack— turns off the state hack — the thing where any lambda with a real-world state token as argument is considered to be single-entry. Hence it’s OK to inline things inside it. 🫶-fobject-determinism— produces fully deterministic object code. 🎯-fomit-interface-pragmas— doesn’t generate interface pragmas. Implied by-O0only. 🙈-fomit-yields— omits heap checks when no allocation is being performed. 💅-foptimal-applicative-do— uses a slower but better algorithm forApplicativeDo. 🐢✨-fpedantic-bottoms— makes GHC more precise about its treatment of bottom (but see also-fno-state-hack). In particular, GHC will not eta-expand through a case expression. 🧐-fpolymorphic-specialisation— allows specialisation to abstract over free type variables. 🌈-fregs-graph— uses the graph colouring register allocator for register allocation in the native code generator. 🎨-fregs-iterative— uses the iterative coalescing graph colouring register allocator in the native code generator. 🌀-fsimpl-tick-factor=⟨n⟩— default: 100. Sets the percentage factor for simplifier ticks. ⏱️-fsimplifier-phases=⟨n⟩— default: 2. Sets the number of phases for the simplifier. Ignored with-O0. 🌸-fsolve-constant-dicts— when solving constraints, tries to eagerly solve super classes using available dictionaries. Implied by-O. 🧠-fspec-constr— turns on the SpecConstr transformation. Implied by-O2. 🔥-fspec-constr-count=⟨n⟩— default:3.*Sets to⟨n⟩the maximum number of specialisations that will be created for any one function by the SpecConstr transformation. ⭐-fspec-constr-keen— specializes a call with an explicit constructor argument, even if the argument is not scrutinised in the body of the function. 🔍-fspec-constr-threshold=⟨n⟩— default: 2000. Sets the size threshold for the SpecConstr transformation to⟨n⟩. 🎀-fspec-eval— enables speculative evaluation. ✨-fspec-eval-dictfun— enables speculative evaluation of dictionary functions. 🦋-fspecialise— turns on specialisation of overloaded functions. Implied by-O. 💅-fspecialise-aggressively— turns on specialisation of overloaded functions regardless of size, if unfolding is available. 💥-fspecialise-incoherents— enables specialisation on incoherent instances. 🌀-fstatic-argument-transformation— turns on the static argument transformation. 🎀-fstg-cse— enables common sub-expression elimination on the STG intermediate language. Implied by-O. 🌸-fstg-lift-lams— enables late lambda lifting on the STG intermediate language. Implied by-O2. 🦋-fstg-lift-lams-known— allows turning known into unknown calls while performing late lambda lifting. 👀-fstg-lift-lams-non-rec-args— creates top-level non-recursive functions with at mostat most <n> parameterswhile performing late lambda lifting. 🧚-fstg-lift-lams-rec-args— creates top-level recursive functions with at mostat most <n> parameterswhile performing late lambda lifting. 🌀-fstrictness— turns on demand analysis. Implied by-O. Implies-fworker-wrapper— the way that worker/wrapper gets pulled in, iykyk. 💪-fstrictness-before=⟨n⟩— runs an additional demand analysis before simplifier phase⟨n⟩. ⏱️-funbox-small-strict-fields— flattens strict constructor fields with a pointer-sized representation. Implied by-O. 🎁-funbox-strict-fields— flattens strict constructor fields. 📦-funfolding-case-scaling=⟨n⟩— default: 30. Applies a penalty of(inlining_cost * 1/n)for each level of case nesting. 🌸-funfolding-case-threshold=⟨n⟩— default: 2. Reduces inlining for cases nested deeper thann. 🌀-funfolding-creation-threshold=⟨n⟩— default: 750. Tweaks unfolding settings. 🎀-funfolding-dict-discount=⟨n⟩— default: 30. Tweaks unfolding settings. 🦋-funfolding-fun-discount=⟨n⟩— default: 60. Tweaks unfolding settings. ✨-funfolding-keeness-factor=⟨n⟩— this has been deprecated in GHC 9.0.1. 💀-funfolding-use-threshold=⟨n⟩— default: 90. Tweaks unfolding settings. 💅-fworker-wrapper— enables the worker/wrapper transformation. Implied by-Oand by-fstrictness. 🫶-fworker-wrapper-cbv— enables w/w splits for wrappers whose sole purpose is evaluating arguments. 💪-fwrite-if-compression=⟨n⟩— default: 2. Tweaks the level of interface file compression. 🎀
🚀 Optimization levels 🚀
-O— enable level 1 optimisations. 🔥-O0— disable optimisations (default). 💤-O2— enable level 2 optimisations. 🔥🔥-O⟨n⟩— any-Onwheren > 2is the same as-O2. periodt 💅
🎁 Package options 🎁
-clear-package-db— clears the package db stack. 🧹-distrust ⟨pkg⟩— exposes package⟨pkg⟩and sets it to be distrusted. See Safe Haskell. 🕵️-distrust-all-packages— distrusts all packages by default. See Safe Haskell. 🚨-fpackage-trust— enables Safe Haskell trusted package requirement for trustworthy modules. 🔐-global-package-db— adds the global package db to the stack. 🌍-hide-all-packages— hides all packages by default. 🙈-hide-package ⟨pkg⟩— hides package⟨pkg⟩. 🫣-ignore-package ⟨pkg⟩— ignores package⟨pkg⟩. 🚫-no-auto-link-packages— doesn’t automatically link in thebaseandrtspackages. 🔗-no-global-package-db— removes the global package db from the stack. 🌍-no-user-package-db— removes the user’s package db from the stack. 👤-package ⟨pkg⟩— exposes package⟨pkg⟩. 📦-package-db ⟨file⟩— adds⟨file⟩to the package db stack. 🗂️-package-env ⟨file⟩|⟨name⟩— uses the specified package environment. 🌱-package-id ⟨unit-id⟩— exposes package by id⟨unit-id⟩. 🆔-this-unit-id ⟨unit-id⟩— compiles to be part of unit (i.e. package)⟨unit-id⟩. 🧩-trust ⟨pkg⟩— exposes package⟨pkg⟩and sets it to be trusted. See Safe Haskell. 🛡️-user-package-db— adds the user’s package db to the stack. 👤
🛠️ Phases of compilation 🛠️
--merge-objs— merges a set of objects into aGHCilibrary. 🧱-C— stops after generating C (.hcfile). 🇨-c— stops after generating object (.o) file. 🔧-E— stop right after preprocessing, so you're left with a.hsppfile and vibes ✨-F— turn on a pre-processor, which you pick with-pgmF ⟨cmd⟩🎀-S— stop after generating assembly, giving you a.sfile 🔥-x ⟨suffix⟩— override the default behaviour for source files, iykyk
🌈 Overriding external programs 🌈
okay so this whole lil family is literally "hey GHC, use this program instead of the one you'd normally grab" — one flag per tool, no cap 💅
-pgma ⟨cmd⟩— use⟨cmd⟩as the assembler-pgmc ⟨cmd⟩— use⟨cmd⟩as the C compiler-pgmCmmP ⟨cmd⟩— use⟨cmd⟩as the C-- C pre-processor-pgmcxx ⟨cmd⟩— use⟨cmd⟩as the C++ compiler-pgmF ⟨cmd⟩— use⟨cmd⟩as the pre-processor (with-Fonly!)-pgmi ⟨cmd⟩— use⟨cmd⟩as the external interpreter command-pgminstall_name_tool ⟨cmd⟩— use⟨cmd⟩as the program that injects runpath into mach-o dylibs on macOS 🍎-pgmJSP ⟨cmd⟩— use⟨cmd⟩as the JavaScript C pre-processor (only for javascript-backend)-pgmL ⟨cmd⟩— use⟨cmd⟩as the literate pre-processor-pgml ⟨cmd⟩— use⟨cmd⟩as the linker-pgmlas ⟨cmd⟩— use⟨cmd⟩as the LLVM assembler-pgmlc ⟨cmd⟩— use⟨cmd⟩as the LLVM compiler-pgmlm ⟨cmd⟩— use⟨cmd⟩as the linker when merging object files-pgmlo ⟨cmd⟩— use⟨cmd⟩as the LLVM optimiser-pgmotool ⟨cmd⟩— use⟨cmd⟩as the program to inspect mach-o dylibs on macOS 🍎-pgmP ⟨cmd⟩— use⟨cmd⟩as the C pre-processor (with-cpponly)-pgms ⟨cmd⟩— use⟨cmd⟩as the splitter-pgmwindres ⟨cmd⟩— use⟨cmd⟩as the program for embedding manifests on Windows 🪟
note the lowercase/uppercase chaos bestie:-pgml= linker,-pgmL= literate pre-processor. yes really. the case matters, do not come for me 😭
🦋 Phase-specific options 🦋
same energy, opposite direction: instead of naming a whole program, you pass one single option straight through to a tool 👑
-opta ⟨option⟩— pass⟨option⟩to the assembler-optc ⟨option⟩— pass⟨option⟩to the C compiler-optCmmP ⟨option⟩— pass⟨option⟩to the C-- C pre-processor-optcxx ⟨option⟩— pass⟨option⟩to the C++ compiler-optF ⟨option⟩— pass⟨option⟩to the custom pre-processor-opti ⟨option⟩— pass⟨option⟩to the interpreter sub-process-optJSP ⟨option⟩— pass⟨option⟩to JavaScript C pre-processor (only for javascript-backend)-optL ⟨option⟩— pass⟨option⟩to the literate pre-processor-optl ⟨option⟩— pass⟨option⟩to the linker-optlas ⟨option⟩— pass⟨option⟩to the LLVM assembler-optlc ⟨option⟩— pass⟨option⟩to the LLVM compiler-optlm ⟨option⟩— pass⟨option⟩to the linker when merging object files-optlo ⟨option⟩— pass⟨option⟩to the LLVM optimiser-optP ⟨option⟩— pass⟨option⟩to cpp (with-cpponly)-optwindres ⟨option⟩— pass⟨option⟩to windres-pgmc-supports-no-pie— (deprecated 👴) indicate that the linker supports-no-pie-pgml-supports-no-pie— indicate that the linker supports-no-pie
🌸 Platform-specific options 🌸
SIMD era 💅 these are basically you telling GHC "bestie the CPU can do this, go off". Several of them are x86 only, and I've flagged each one fr fr.
-mavx— (x86 only) enable support for AVX SIMD extensions-mavx2— (x86 only) enable support for AVX2 SIMD extensions-mavx512cd— (x86 only) enable support for AVX512-CD SIMD extensions-mavx512er— (x86 only) enable support for AVX512-ER SIMD extensions-mavx512f— (x86 only) enable support for AVX512-F SIMD extensions-mavx512pf— (x86 only) enable support for AVX512-PF SIMD extensions-mbmi— (x86 only) use BMI1 for bit manipulation operations-mbmi2— (x86 only) use BMI2 for bit manipulation operations-mfma— use native FMA instructions for fused multiply-add floating-point operations ✨ (no x86-only note on this one, that's just how it is)-msse— (x86 only) use SSE for floating-point operations-msse2— (x86 only) use SSE2 for floating-point operations-msse3— (x86 only) use SSE3 for floating-point operations-msse4— (x86 only) use SSE4 for floating-point operations-msse4.2— (x86 only) use SSE4.2 for floating-point operations
🧚 Compiler plugins 🧚
the plugin girlies are so real for this one 🫶
-fclear-plugins— clear the list of active plugins, poof 🪄-fplugin-library=⟨file-path⟩;⟨unit-id⟩;⟨module⟩;⟨args⟩— load a pre-compiled static plugin from an external library-fplugin-opt=⟨module⟩:⟨args⟩— give arguments to a plugin module; the module must be specified with-fplugin=⟨module⟩-fplugin-trustworthy— trust the used plugins and no longer mark the compiled module as unsafe 😌-fplugin=⟨module⟩— load a plugin exported by a given module-hide-all-plugin-packages— hide all packages for plugins by default-plugin-package ⟨pkg⟩— expose⟨pkg⟩for plugins-plugin-package-id ⟨pkg-id⟩— expose⟨pkg-id⟩for plugins
💜 Profiling 💜
the "why is my program slow" section, aka main character energy for performance girlies 🔥
-auto— (deprecated 👴) alias for-fprof-auto-exported-auto-all— (deprecated 👴) alias for-fprof-auto-caf-all— (deprecated 👴) alias for-fprof-cafs-fno-prof-count-entries— do not collect entry counts-fprof-auto— auto-addSCCs to all bindings not markedINLINE-fprof-auto-calls— auto-addSCCs to all call sites-fprof-auto-exported— auto-addSCCs to all exported bindings not markedINLINE-fprof-auto-top— auto-addSCCs to all top-level bindings not markedINLINE-fprof-cafs— auto-addSCCs to all CAFs-fprof-callers=⟨name⟩— auto-addSCCs to all call-sites of the named function-fprof-late— auto-addSCCs to all top level bindings after the core pipeline has run-fprof-late-inline— auto-addSCCs to all top level bindings after the optimizer has run and retain them when inlining-fprof-late-overloaded— auto-addSCCs to all top level overloaded bindings after the core pipeline has run-fprof-late-overloaded-calls— auto-addSCCs to all call sites that include dictionary arguments after the core pipeline has run-fprof-manual— process manualSCCannotations-no-auto— (deprecated 👴) alias for-fno-prof-auto-no-auto-all— (deprecated 👴) alias for-fno-prof-auto-no-caf-all— (deprecated 👴) alias for-fno-prof-cafs-prof— turn on profiling 📈-ticky— turn on ticky-ticky profiling-ticky-allocd— track the number of times each closure type is allocated-ticky-ap-thunk— don't use standard AP thunks on order to get more reliable entry counters (yes, "on order" — that's the manpage's own typo, I'm just the messenger 🙈)-ticky-dyn-thunk— track allocations of dynamic thunks-ticky-LNE— treat join point binders similar to thunks/functions-ticky-tag-checks— emit dummy ticky counters to record how many tag-inference checks tag inference avoided
⭐ Program coverage ⭐
-fhpc— turn on Haskell program coverage instrumentation ✨-hpcdir⟨dir⟩— set the directory where GHC places.mixfiles (no space before⟨dir⟩, that's exactly how it's written 💅)
🎀 Recompilation checking 🎀
the art of not rebuilding the entire world every time you sneeze 🌍
-exclude-module=⟨file⟩— regard⟨file⟩as "stable"; i.e., exclude it from having dependencies on it-fforce-recomp— turn off recompilation checking. this is implied by any-ddump-Xoption when compiling a single file (i.e. when using-c)-fignore-hpc-changes— do not recompile modules just to match changes to HPC flags. this is especially useful for avoiding recompilation when using GHCi, and is enabled by default for GHCi 😌-fignore-optim-changes— do not recompile modules just to match changes to optimisation flags. this is especially useful for avoiding recompilation when using GHCi, and is enabled by default for GHCi-include-cpp-deps— include preprocessor dependencies-include-pkg-deps— regard modules imported from packages as unstable
🍓 Redirecting output 🍓
you're the director now bestie, you pick where the files go 🎬
-dep-makefile ⟨file⟩— use⟨file⟩as the makefile-dep-suffix ⟨suffix⟩— make dependencies that declare that files with suffix.⟨suf⟩⟨osuf⟩depend on interface files with suffix.⟨suf⟩hi-dumpdir ⟨dir⟩— redirect dump files-dynhisuf ⟨suffix⟩— set the suffix to use for dynamic interface files-dyno ⟨file⟩— set dynamic output filename-dynohi ⟨file⟩— set the filename in which to put the dynamic interface-dynosuf ⟨suffix⟩— set the dynamic output file suffix-hcsuf ⟨suffix⟩— set the suffix to use for intermediate C files-hidir ⟨dir⟩— set directory for interface files-hiedir ⟨dir⟩— set directory for extended interface files-hiesuf ⟨suffix⟩— set the suffix to use for extended interface files-hisuf ⟨suffix⟩— set the suffix to use for interface files-o ⟨file⟩— set output filename-odir ⟨dir⟩— set directory for object files-ohi ⟨file⟩— set the filename in which to put the interface-osuf ⟨suffix⟩— set the output file suffix-outputdir ⟨dir⟩— set output directory-stubdir ⟨dir⟩— redirect FFI stub files
🧹 Temporary files 🧹
-tmpdir ⟨dir⟩— set the directory for temporary files
💀 Verbosity options 💀
how much GHC talks to you. the diagnostics girlies live here 🙈
-fabstract-refinement-hole-fits— default: off. toggles whether refinements where one or more of the holes are abstract are reported-fdefer-diagnostics— defer and group diagnostic messages by severity-fdiagnostics-as-json— output diagnostics in Json format specified by JSON schema-fdiagnostics-color=⟨always|auto|never⟩— use colors in error messages 🌈-fdiagnostics-show-caret— whether to show snippets of original source code-ferror-spans— output full span in error messages-fhide-source-paths— hide module source and object paths-fkeep-going— continue compilation as far as possible on errors 🫡-fmax-refinement-hole-fits=⟨n⟩— default: 6. set the maximum number of refinement hole fits for typed holes to display in type error messages-fmax-relevant-binds=⟨n⟩— default: 6. set the maximum number of bindings to display in type error messages-fmax-valid-hole-fits=⟨n⟩— default: 6. set the maximum number of valid hole fits for typed holes to display in type error messages-fno-show-valid-hole-fits— disables showing a list of valid hole fits for typed holes in type error messages-fno-sort-valid-hole-fits— turns off the sorting of the list of valid hole fits for typed holes in type error messages 💅 like, the suggestions still show up, they're just not ranked for you anymore-fprint-axiom-incomps— shows you the equation incompatibilities in closed type families ✨ messy family drama, but make it type-level-fprint-equality-relations— distinguishes between equality relations when printing 🎀 so you can actually tell which equality is which (iykyk)-fprint-error-index-links=⟨always|auto|never⟩ — decides whether your diagnostic codes get emitted as ANSI hyperlinks to the Haskell Error Index 🔗 like, do you want the cute clickable link or not-fprint-expanded-synonyms— in type errors, also prints type-synonym-expanded types 🌸 because sometimes the synonym is hiding the real tea-fprint-explicit-coercions— prints coercions in types 💅 no more mystery coercion erasure, we're showing everything-fprint-explicit-foralls— prints explicit forall quantification in types ✨ see alsoExplicitForAll-fprint-explicit-kinds— prints explicit kind foralls and kind arguments in types 👑 see alsoKindSignatures-fprint-explicit-runtime-reps— printsRuntimeRepandLevityvariables in types which are runtime-representation polymorphic 🌀 the full lore, no cap-fprint-potential-instances— displays all available instances in type error messages 🫶 it's giving "here are literally all your options, bestie"-fprint-redundant-promotion-ticks— prints redundantDataKindspromotion ticks 🎀 the ticks that didn't need to be there, exposed-fprint-typechecker-elaboration— prints extra information from typechecker 🔍 the behind-the-scenes commentary track-fprint-unicode-syntax— uses unicode syntax when printing expressions, types and kinds 🌈 see alsoUnicodeSyntax-frefinement-level-hole-fits=⟨n⟩ — default: off. Sets the level of refinement of the refinement hole fits, where level n means that hole fits of up to n holes will be considered 🦋 so dial in how adventurous the suggestions get-freverse-errors— outputs errors in reverse order 🙈 chronological order is cancelled, apparently-fshow-docs-of-hole-fits— toggles whether to show the documentation of the valid hole fits in the output 📚 educational slay-fshow-error-context— whether to show textual information about error context 🧐 the where and why, not just the what-fshow-hole-constraints— shows constraints when reporting typed holes ✨ the fine print, included-fshow-hole-matches-of-hole-fits— toggles whether to show the type of the additional holes in refinement hole fits 💅 more info about the extra holes-fshow-provenance-of-hole-fits— toggles whether to show the provenance of the valid hole fits in the output 🔎 where each suggestion came from-fshow-type-app-of-hole-fits— toggles whether to show the type application of the valid hole fits in the output 🎀-fshow-type-app-vars-of-hole-fits— toggles whether to show what type each quantified variable takes in a valid hole fit 🦋-fshow-type-of-hole-fits— toggles whether to show the type of the valid hole fits in the output 👑-fsort-by-size-hole-fits— sorts valid hole fits by size 📏 lil suggestions first, big chonky ones later-fsort-by-subsumption-hole-fits— sorts valid hole fits by subsumption 🌀-funclutter-valid-hole-fits— unclutters the list of valid hole fits by not showing provenance nor type applications of suggestions ✨ minimal aesthetic, less noise-Rghc-timing— summarises timing stats for GHC (same as+RTS -tstderr) ⏱️ receipts on where the time went-v— verbose mode (equivalent to-v3) 💬-v⟨n⟩ — sets verbosity level 🔊 pick your level of yapping
✨ Warnings ✨
-fenable-th-splice-warnings— generates warnings for Template Haskell splices 🔮 TH but it warns you now-fhelpful-errors— makes suggestions for mis-spelled names 💖 it's giving "did you mean…?" and honestly, we love her-fmax-pmcheck-models=⟨n⟩ — soft limit on the number of parallel models the pattern match checker should check a pattern match clause against 🧠 a soft limit, so don't stress-fshow-warning-groups— shows which group an emitted warning belongs to 🏷️-fvia-C— uses the C code generator 💀 old-school route-W— enables normal warnings ✅-w— disables all warnings 🤫 silence, but at what cost-Wall— enables almost all warnings (details in Warnings and sanity-checking) 🌈 the "I want to know everything" button-Wall-missed-specialisations— warns when specialisation of any overloaded function fails 😭-Wall-missed-specializations— alias for-Wall-missed-specialisations🪞 same thing, different spelling-Wambiguous-fields— warns about ambiguous field selectors or updates 🌀-Wauto-orphans— (deprecated) Does nothing 💀 literally nothing, she's retired-Wbadly-staged-types— warns when a type binding is used at the wrong TH stage 🎭 wrong stage, wrong vibe-Wcompat— enables future compatibility warnings (details in Warnings and sanity-checking) 🔮 future-proofing, bestie-Wcompat-unqualified-imports— (deprecated) reports unqualified imports of core libraries which are expected to cause compatibility problems in future releases ⚠️-Wcpp-undef— warns on uses of the#ifdirective on undefined identifiers 🧵-Wdata-kinds-tc— warns when an illegal use of a type or kind withoutDataKindsis caught by the typechecker 🚨-Wdefault— enables default flags 🎀-Wdefaulted-exception-context— warns when aControl.Exception.Context.ExceptionContextimplicit parameter is defaulted toControl.Exception.Context.emptyExceptionContext🫠 it got defaulted, and we're telling you-Wdeferred-out-of-scope-variables— reports warnings when variable out-of-scope errors are deferred until runtime 😬 see-fdefer-out-of-scope-variables-Wdeferred-type-errors— reports warnings when deferred type errors are enabled. This option is enabled by default. See-fdefer-type-errors✨-Wdeprecated-flags— warns about uses of commandline flags that are deprecated 👵-Wdeprecated-type-abstractions— warns when type abstractions in constructor patterns are used without enablingTypeApplications💅-Wdeprecations— warns about uses of functions & types that haveDEPRECATEDpragmas, orWARNINGpragmas with the deprecated category ⚠️-Wderiving-defaults— warns about default deriving when using bothDeriveAnyClassandGeneralizedNewtypeDeriving😵💫 yes the conflict is real-Wderiving-typeable— warns whenTypeableis derived 🌀-Wdodgy-exports— warns about dodgy exports 🚩-Wdodgy-foreign-imports— warns about dodgy foreign imports 🚩-Wdodgy-imports— warns about dodgy imports 🚩-Wduplicate-constraints— warns when a constraint appears duplicated in a type signature 👯-Wduplicate-exports— warns when an entity is exported multiple times 🔁-Wempty-enumerations— warns about enumerations that are empty 🫙-Werror— makes warnings fatal 💀🔪 no cap, your warnings now stop the build-Weverything— enables all warnings supported by GHC 🌈👑 the maximalist option-Wextended-warnings— warns about uses of functions & types that haveWARNINGorDEPRECATEDpragmas, across all categories 📢-Wextra— alias for-W🪞-Wforall-identifier— (deprecated) Does nothing 💀 retired icon-Wgadt-mono-local-binds— warns when pattern matching on a GADT withoutMonoLocalBinds🧩-Whi-shadowing— (deprecated) warns when a.hifile in the current directory shadows a library 👻-Widentities— warns about uses of Prelude numeric conversions that are probably the identity (and hence could be omitted) 🪞✨-Wimplicit-kind-vars— (deprecated) warns when kind variables are implicitly quantified over 🌀-Wimplicit-lift— warns about implicit lift in Template Haskell quotes 🔮-Wimplicit-prelude— warns when the Prelude is implicitly imported 📦-Wimplicit-rhs-quantification— warns when type variables on the RHS of a type synonym are implicitly quantified 🤫-Winaccessible-code— warns about inaccessible code 🚪-Wincomplete-export-warnings— warns when some but not all of exports for a name are warned about 🧮-Wincomplete-patterns— warns when a pattern match could fail 😬 the classic-Wincomplete-record-selectors— warns when a record selector application could fail 🎯-Wincomplete-record-updates— warns when a record update could fail 🎯-Wincomplete-uni-patterns— warns when a pattern match in a lambda expression, pattern binding or a lazy pattern could fail 🌪️-Winconsistent-flags— warns when command line options are inconsistent in some way 🚩 bestie, pick a lane-Winferred-safe-imports— warns when an explicitly Safe Haskell module imports a Safe-Inferred one 🛡️-Winline-rule-shadowing— warns if a rewriteRULEmight fail to fire because the function might be inlined before the rule has a chance to fire 🔥 see How rules interact with INLINE/NOINLINE pragmas-Winvalid-haddock— warns when a Haddock comment occurs in an invalid position 📝-Wloopy-superclass-solve— (deprecated) warns when creating potentially-loopy superclass constraint evidence 🌀-Wmisplaced-pragmas— warns about uses of file header pragmas in the module body 🏷️-Wmissed-extra-shared-lib— warns when GHCi can't load a shared lib 😭-Wmissed-specialisations— warns when specialisation of an imported, overloaded function fails 💔-Wmissed-specializations— alias for-Wmissed-specialisations🪞-Wmissing-deriving-strategies— warns when deriving without mentioning a deriving strategy 🎀-Wmissing-export-lists— warns when a module declaration does not explicitly list all exports 📋-Wmissing-exported-pattern-synonym-signatures— warns about pattern synonyms without signatures, only if they are exported 📤-Wmissing-exported-signatures— warns about top-level functions without signatures, only if they are exported 📤-Wmissing-exported-sigs— (deprecated) warns about top-level functions without signatures, only if they are exported. takes precedence over-Wmissing-signatures👑-Wmissing-fields— warns when fields of a record are uninitialised 🕳️-Wmissing-home-modules— warns when encountering a home module imported, but not listed on the command line. Useful for cabal to ensure GHC won't pick up modules, not listed neither inexposed-modules, nor inother-modules📦-Wmissing-import-lists— warns when an import declaration does not explicitly list all the names brought into scope 📋-Wmissing-kind-signatures— warns when type declarations don't have kind signatures nor CUSKs 🧬-Wmissing-local-signatures— warns about polymorphic local bindings without signatures 🪧-Wmissing-local-sigs— (deprecated) warns about polymorphic local bindings without signatures 🪧-Wmissing-methods— warns when class methods are undefined 🫥-Wmissing-monadfail-instances— (deprecated) warns when a failable pattern is used in a do-block that does not have aMonadFailinstance 💀-Wmissing-pattern-synonym-signatures— warns when pattern synonyms do not have type signatures ✍️-Wmissing-poly-kind-signatures— warns when an inferred polykinded type or class declaration doesn't have kind signatures nor CUSKs. give those kinds a home bestie 😭-Wmissing-role-annotations— warns when type declarations don't have role annotations. roles matter, we love a well-defined role 💅-Wmissing-safe-haskell-mode— warns when the Safe Haskell mode is not explicitly specified. say it with your chest ✨-Wmissing-signatures— warns about top-level functions without signatures. like what even are you, girl 🫶-Wmissing-space-after-bang— (deprecated) literally does nothing. a ghost. a vibe with no substance 👻-Wmonomorphism-restriction— warns when the Monomorphism Restriction is applied.-Wname-shadowing— warns when names are shadowed. not the shadowing 😭-Wnoncanonical-monad-instances— warns whenApplicativeorMonadinstances have noncanonical definitions ofreturn,pure,(>>), or(*>). See flag description in Warnings and sanity-checking for more details. 🔥-Wnoncanonical-monadfail-instances— (deprecated) warns whenMonadorMonadFailinstances have noncanonical definitions offail.-Wnoncanonical-monoid-instances— warns whenSemigrouporMonoidinstances have noncanonical definitions of(<>)ormappend. See flag description in Warnings and sanity-checking for more details. 🎀-Wnot— (deprecated) Alias for-w. that's it, that's the whole thing 💀-Woperator-whitespace— warns on prefix, suffix, and tight infix uses of infix operators. spacing is a love language fr fr-Woperator-whitespace-ext-conflict— warns on uses of infix operators that would be parsed differently were a particular GHC extension enabled. sneaky parse-flip energy, we're watching 👀-Worphans— warns when the module contains orphan instance declarations or rewrite rules. no parents? we're judging (lovingly) 🧚-Woverflowed-literals— warns about literals that will overflow their type. too much for that type to hold, honestly relatable 😭-Woverlapping-patterns— warns about overlapping patterns.-Wpartial-fields— warns when defining a partial record field.-Wpartial-type-signatures— warns about holes in partial type signatures whenPartialTypeSignaturesis enabled. Not applicable whenPartialTypeSignaturesis not enabled, in which case errors are generated for such holes. so like — either a warning or a full-on error, pick your fighter 💅-Wprepositive-qualified-module— Report imports with a leading/prepositive"qualified".-Wredundant-bang-patterns— Warns about redundant bang patterns.!but make it unnecessary 🫠-Wredundant-constraints— Have the compiler warn about redundant constraints in type signatures.-Wredundant-record-wildcards— Warns about record wildcard matches when the wildcard binds no patterns. wildcard that does nothing? embarrassing for it 🎀-Wredundant-strictness-flags— Warns about redundant strictness flags.-Wsafe— warn if the module being compiled is regarded to be safe. goody-two-shoes module alert 🫶-Wsemigroup— (deprecated) Warns when aMonoidis notSemigroup, and on non-Semigroupdefinitions of(<>)"— iykyk, it's giving legacy flag energy-Wsimplifiable-class-constraints— Warns about class constraints in a type signature that can be simplified using a top-level instance declaration. bestie that constraint is whole extra, pls simplify ✨-Wstar-binder— warns about binding the(*)type operator despiteStarIsType. tricky tricky ⭐-Wstar-is-type— warns when*is used to meanData.Kind.Type. stars in their type era 🌟-Wtabs— warn if there are tabs in the source file. tabs vs spaces discourse, but make it a compiler warning 💀-Wterm-variable-capture— warns when an implicitly quantified type variable captures a term's name. the way it just takes the name 😭-Wtrustworthy-safe— warn if the module being compiled is marked asTrustworthybut it could instead be marked asSafe, a more informative bound. glow-up suggestion 🦋-Wtype-defaults— warns when defaulting happens.-Wtype-equality-out-of-scope— warns when type equalitya ~ bis used despite being out of scope.-Wtype-equality-requires-operators— warns when type equalitya ~ bis used despite being out of scope. yes it's the same sentence as the one above, no we're not editing the manpage, we simply report 🫡-Wtyped-holes— Report warnings when typed hole errors are deferred until runtime. See-fdefer-typed-holes. holes at runtime, living dangerously 🙈-Wunbanged-strict-patterns— warns on pattern bind of unlifted variable that is neither bare nor banged. neither bare nor banged, the worst of both worlds 😔-Wunicode-bidirectional-format-characters— warns about the usage of unicode bidirectional layout override characters. sneaky text-invisible characters, we see u 👀-Wunrecognised-pragmas— warns about uses of pragmas that GHC doesn't recognise.{-# ??? #-}bestie no 😭-Wunrecognised-warning-flags— throws a warning when an unrecognised-W...flag is encountered on the command line. yes, it warns you about your warnings. iconic recursive behaviour tbh 👑-Wunsafe— warn if the module being compiled is regarded to be unsafe. See Safe Haskell. bad-boy module detected 💀-Wunsupported-calling-conventions— warns about use of an unsupported calling convention.-Wunsupported-llvm-version— Warns when using-fllvmwith an unsupported version of LLVM.-Wunticked-promoted-constructors— warns if promoted constructors are not ticked. give that constructor its lil'tick ✨-Wunused-binds— warns about bindings that are unused. Alias for-Wunused-top-binds,-Wunused-local-bindsand-Wunused-pattern-binds. a three-for-one, we love efficiency 🎀-Wunused-do-bind— warns aboutdobindings that appear to throw away values of types other than(). girl you dropped that value 😭-Wunused-foralls— warns about type variables in user-writtenforalls that are unused. all those quantifiers and for what 🙈-Wunused-imports— warns about unnecessary imports. clean it up bestie 🧹-Wunused-local-binds— warns about local bindings that are unused.-Wunused-matches— warns about variables in patterns that aren't used.-Wunused-packages— warns when package is requested on command line, but not needed. you asked for it and didn't even use it 💀-Wunused-pattern-binds— warns about pattern match bindings that are unused.-Wunused-record-wildcards— Warns about record wildcard matches when none of the bound variables are used.-Wunused-top-binds— warns about top-level bindings that are unused.-Wunused-type-patterns— warns about unused type variables which arise from patterns in in type family and data family instances. (that double "in in" is theirs, not ours, we keep the receipts 🧾)-Wview-pattern-signatures— warns when a view pattern is used with type signature without explicit parens. parens are load-bearing, wrap it up 🎁-Wwarn— make warnings non-fatal. they're just little guys, let 'em live 🫶-Wwarnings-deprecations— warns about uses of functions & types that haveDEPRECATEDpragmas, orWARNINGpragmas with the deprecated category. Alias for-Wdeprecations.-Wwrong-do-bind— warns aboutdobindings that appear to throw away monadic values that you should have bound instead. bestie you were supposed to keep that 😭-Wx-⟨category⟩— warns about uses of functions & types that haveWARNINGpragmas with the given category. custom categories, custom chaos 💅
🎀 COPYRIGHT 🎀
Copyright 2015. The University Court of the University of Glasgow. All rights reserved.
🌈 SEE ALSO 🌈
https://www.haskell.org/ghc— the GHC homepage
💖 AUTHOR 💖
The GHC Team
👑 COPYRIGHT 👑
2026, GHC Team
and that's the whole page, bestie — no cap, you read all of it 💅✨ this manual is version 9.12.4, dated Mar 28, 2026, straight from the GHC Team, and honestly? she ate. go compile something iconic now 🔥🦋🍓
📦 where this page comes from
- epel 10: ghc9.12-compiler 9.12.4-17.el10_3 · BSD-3-Clause
- 💖 girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms