Support statically linking executables properly
## Context
* https://github.com/haskell/cabal/issues/11224
I originally thought this is purely a cabal issue, but it turns out that it's actually GHC that's at fault.
## Reproducer
https://github.com/hasufell/cabal-extra-libraries
## Problem description
The problem is described in the cabal issue. Basically: Cabal+GHC misbehave when requesting a fully statically linked binary, only considering `extra-libraries-static` from the current component, but ignoring it from dependencies:
```
+ executable A
- extra-libraries-static <- respected
- extra-libraries <- respected
+ library dependency B
- extra-libraries-static <- ignored
- extra-libraries <- respected
```
GHC is responsible for collecting the link flags from "library dependency B" at the moment.
In more detail:
* cabal passes `-static` (affects Haskell libs only) and `-optl-static` (affects system libs) to GHC and additionally consults `extra-libraries-static` and `library-dirs-static` to pass further flags to GHC:
- https://github.com/haskell/cabal/blob/1e3c355eeab89fa8894ce9c6e4e649903e58d6b3/Cabal/src/Distribution/Simple/GHC/Build/Link.hs#L119-L142
* `extra-libraries-static` and `library-dirs-static` are only considered from the **current component**
* cabal also passes the dependent package IDs to GHC
* GHC then gets additional linker flags from the package id's that have been passed in by cabal:
- https://github.com/ghc/ghc/blob/867c26755e8855c6df949e65df0c2aebc9da64c3/compiler/GHC/Linker/Static.hs#L168-L172
- https://github.com/ghc/ghc/blob/867c26755e8855c6df949e65df0c2aebc9da64c3/compiler/GHC/Linker/Unit.hs#L36-L48
* we can see that in `collectLinkOpts` we only consider `unitExtDepLibsSys`, which corresponds to the `extra-libraries` from a package `.conf` file
* GHC is entirely unaware of `extra-libraries-static`, so when we statically link an executable... it will just collect the libraries from `extra-libraries` and fail to link
## Discussion
I'm not entirely sure what the correct fix is.
We have to remember we have two different notions of static linking:
1. link Haskell libraries statically: `-static`
2. link system libraries statically: `-optl-static`
Cabal switches both on when using `--enable-exectuable-static`. But GHC internally only has a good understanding of dynamic vs static when it comes to Haskell libraries... which is reflected via `WayDyn :: Way`. To understand if we want a fully static binary, we'd have to examine `toolSettings_opt_l`. This seems like a rather questionable mechanism when dealing with linking intentions.
The current situation is definitely a bug. It wouldn't be hard to hack into GHC:
* make it aware of `extra-libraries-static`
* use them for linking if we find `-optl-static` in `toolSettings_opt_l`
But it's possible we have to re-think:
* the boundaries of linking (Cabal and GHC are awkwardly intertwined)
* what type of control the end user needs when requesting linking
issue