<div dir="auto">Tamar,</div><div dir="auto"><br></div><div dir="auto">thanks so much for the backstory and the tickets. I’ll go dig down this path a bit more.</div><div dir="auto"><br></div><div dir="auto">Cheers,</div><div dir="auto"> Moritz</div><div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, 11 Feb 2021 at 5:31 PM, Phyx <<a href="mailto:lonetiger@gmail.com">lonetiger@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Hi, Just leaving my two cents feel free to ignore..</div><div><br></div><div>> 
I almost suggested that this had to be the reason for the back-compat design <br></div><div><br></div><div>You're right, but not for backwards compat of Hadrian vs Make, but for compat with RTS versions.</div><div>I could be wrong, but my understanding is the current design in Make is just an artifact of getting something that works on all OSes without much pain, but has proven to be suboptimal in a very important use case (slight detour time):</div><div><br></div><div>You have to make a choice of which RTS to use at compile time.  Which is quite bad.  Because it means that you can't swap between two RTS flavors with the same ABI. It also means building presents a problem, you want your compiler at the end of stage1 to use your new rts, not the one of the stage0 compiler.</div><div><br></div><div>You can't have multiple versions of the RTS in one library, but if you have the full name as a dependency the dynamic loader happily loads you multiple copies.</div><div><br></div><div>To solve this issue the design was made to not declare the RTS as a dependency on any haskell library. i.e. there's not DT_NEEDED entry for it on ELF operating systems.  Which means before you load a Haskell produced dynamic library on Linux you need to LD_PRELOAD an rts. It's clunky, but it works, it allows you to switch between debug and non-debug rts at initialization time.</div><div><br></div><div>On Windows, this problem was punted, because everything is statically linked.  But the problem exists that you can have multiple DLLs with different RTS and ABIs.  This is fine as long as the DLLs have no dependencies on each other. Once they do... you have a big problem.  This is one of the primary blockers of shared library support on Windows.</div><div><br></div><div>I.. don't know whatever wacky solution MacOS uses so can't comment there.</div><div><br></div><div>Now back to the original question about version 1.0, this has nothing to do with Make at all. Make based system only implemented the scheme that was wanted. It's not like any Make system design issues forced this scheme. Now over the years, assumptions that the RTS is always version 1.0 could have krept into the build system.  But I don't believe this to have been design, just convenience. Right now, the design only requires you to know the GHC version, which is available in all makefiles.  Knowing the RTS version would be difficult, but the point is that in a proper design you don't need to know the version.</div><div> <br></div><div>Almost half a decade ago a plan was made to replace this scheme with one that would work on all OSes and would allow us to solve these issues. The design was made and debated here <a href="https://gitlab.haskell.org/ghc/ghc/-/issues/10352" target="_blank">https://gitlab.haskell.org/ghc/ghc/-/issues/10352</a></div><div><br></div><div>The actual solution isn't as simple as just adding the rts version to the library name or add it only to the build system, in fact this would be the wrong approach as it makes it impossible to observe backwards compatibility between GHC releases.</div><div>i.e. without it, you'd need to have GHC 9.0.1 installed to run GHC 9.0.1 programs, you can't run using GHC 9.2.x rts if the version changed.</div><div><br></div><div>Typically ELF based platforms solve this by a combination of SONAME and symbol versioning.  Windows solves this by a combination of SxS Assembly versioning or mingw style SONAME.</div><div><br></div><div>All of which require you to have the same filename for the libraries, but use a different path to disambiguate:</div><div>
<p dir="auto">lib/ghc-${ver}/rts-1.0/libHSrts-ghc${ver}.so</p>
<p dir="auto">lib/ghc-${ver}/rts-1.0/thr/libHSrts-ghc${ver}.so</p>
<p dir="auto">lib/ghc-${ver}/rts-1.0/debug/libHSrts-ghc${ver}.so</p>
<p dir="auto">lib/ghc-${ver}/rts-1.0/l/libHSrts-ghc${ver}.so</p>
<p dir="auto">lib/ghc-${ver}/rts-1.0/thr_l/libHSrts-ghc${ver}.so</p><p>for each RTS with the same ABI. profiling libs for instance have a different ABI and can't use this scheme.</p><p>So what has taken so long to implement this? Well.. time. As it turns out, getting this scheme to work required a lot of foundational work in GHC (Particularly on Windows where dynamic linking design wasn't optimal, but both GHC and the dynamic linker are happy now).</p><p>On Linux it took a while to get SONAME support in cabal <a href="https://github.com/haskell/cabal/issues/4052" target="_blank">https://github.com/haskell/cabal/issues/4052</a> so we don't have to hack around in the build system.<br></p><p>But anyway this is why the current scheme exists, and why just adding an rts version isn't really sufficient, especially if the name propagates to the shared lib.<br></p><p>TL;DR;</p><p>If we are going to change the build system, we should do it properly.</p><p>The current scheme exists because GHC does not observe any mechanism to support multiple runtimes with the same ABI and does not really have a backwards compatibility story. <br></p><p>Kind Regards,</p><p>Tamar<br></p>

</div><br><div class="gmail_quote"></div></div><div dir="ltr"><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Feb 10, 2021 at 11:00 PM Richard Eisenberg <<a href="mailto:rae@richarde.dev" target="_blank">rae@richarde.dev</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><br><div><br><blockquote type="cite"><div>On Feb 10, 2021, at 8:50 AM, Simon Peyton Jones <<a href="mailto:simonpj@microsoft.com" target="_blank">simonpj@microsoft.com</a>> wrote:</div><br><div><span style="font-family:Calibri,sans-serif;font-size:14.6667px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration:none;float:none;display:inline">build with hadrian, and then continue using make with the artifacts (partially) built by Hadrian</span></div></blockquote></div><br><div>I almost suggested that this had to be the reason for the back-compat design, but I assumed I had to be wrong. I also agree this is a non-goal; I'm quite happy to be forced to pick one or the other and stick with that choice until blasting away all build products.</div><div><br></div><div>Richard</div></div>_______________________________________________<br>
ghc-devs mailing list<br>
<a href="mailto:ghc-devs@haskell.org" target="_blank">ghc-devs@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs</a><br>
</blockquote></div></div>
_______________________________________________<br>
ghc-devs mailing list<br>
<a href="mailto:ghc-devs@haskell.org" target="_blank">ghc-devs@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs</a><br>
</blockquote></div></div>