I think the only way to go is via an interpreter. That interpreter should be written in C, or some language trivially bootstrapped from C (that rules out C++, unfortunately, which has its own bootstrapping problems).
The interpreter could target a much simpler version of Haskell and it could be slow as hell, as it would be used only once.
That is how P-Code was born for Pascal, its original purpose was only to help porting Pascal compilers not to become a widespread target format for environments like UCSD Pascal.
An interpreter omits the target architecture/format question and thus is more portable than a compiler.
Of course, you could compile to a higher-level language, for instance directly to C. But that's usually still a complication that only gives you performance. And performance is something you probably don't need during bootstrapping.
Another point about bootstrapping an ancient version of GHC first and using that to build more modern versions: you need to run the generated x86 code (that also targets an old OS version) to do that, and it’s increasingly not a given that you can do so natively.
If you click through the link on that page (and click on Compiler), there are a series of articles on the development process - step by step bootstrapping stages and some further development past that point.
This project[0] is a fork of Ben Lynn’s compiler that can be bootstrapped from a binary less than 1 KB in size. The dialect of Haskell it accepts is impressive for its size and GHC-compatible too.