Skip to content

Commit

Permalink
dev-lang/ghc: patch (by upstream) fix linker errors
Browse files Browse the repository at this point in the history
Fixes linker errors building app-portage/hackport and dev-haskell/cabal-install

Signed-off-by: Mark Wright <[email protected]>
  • Loading branch information
markwright committed Jun 2, 2024
1 parent 2de3861 commit 104c8ef
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
From b1a052168497a7510aa6dbad85da65e7f2f23ae0 Mon Sep 17 00:00:00 2001
From: Cheng Shao <[email protected]>
Date: Tue, 26 Mar 2024 22:06:22 +0000
Subject: [PATCH] driver: force merge objects when building dynamic objects

This patch forces the driver to always merge objects when building
dynamic objects even when ar -L is supported. It is an oversight of
!8887: original rationale of that patch is favoring the relatively
cheap ar -L operation over object merging when ar -L is supported,
which makes sense but only if we are building static objects! Omitting
check for whether we are building dynamic objects will result in
broken .so files with undefined reference errors at executable link
time when building GHC with llvm-ar. Fixes #22210.
---
compiler/GHC/Driver/Pipeline/Execute.hs | 26 +++++++++++++++++--------
1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/compiler/GHC/Driver/Pipeline/Execute.hs b/compiler/GHC/Driver/Pipeline/Execute.hs
index ca3bd9067f6..908422f5478 100644
--- a/compiler/GHC/Driver/Pipeline/Execute.hs
+++ b/compiler/GHC/Driver/Pipeline/Execute.hs
@@ -1040,13 +1040,22 @@ this is accomplished with the `ld -r` command. We rely on this for two ends:
The command used for object linking is set using the -pgmlm and -optlm
command-line options.

-Sadly, the LLD linker that we use on Windows does not support the `-r` flag
-needed to support object merging (see #21068). For this reason on Windows we do
-not support GHCi objects. To deal with foreign stubs we build a static archive
-of all of a module's object files instead merging them. Consequently, we can
-end up producing `.o` files which are in fact static archives. However,
-toolchains generally don't have a problem with this as they use file headers,
-not the filename, to determine the nature of inputs.
+However, `ld -r` is broken in some cases:
+
+ * The LLD linker that we use on Windows does not support the `-r`
+ flag needed to support object merging (see #21068). For this reason
+ on Windows we do not support GHCi objects.
+ * `wasm-ld -r` is prohibitively slow, especially when handling large
+ input objects (e.g. profiled objects).
+
+In these cases, we bundle a module's own object file with its foreign
+stub's object file, instead of merging them. Consequently, we can end
+up producing `.o` files which are in fact static archives. This can
+only work if `ar -L` is supported, so the archive `.o` files can be
+properly added to the final static library. We must also take care not
+to produce archive `.dyn_o` when building dynamic objects, otherwise
+we end up with broken `.so` files when GHC is built with `llvm-ar`
+(#22210).

Note that this has somewhat non-obvious consequences when producing
initializers and finalizers. See Note [Initializers and finalizers in Cmm]
@@ -1072,7 +1081,7 @@ via gcc.
-- | See Note [Object merging].
joinObjectFiles :: HscEnv -> [FilePath] -> FilePath -> IO ()
joinObjectFiles hsc_env o_files output_fn
- | can_merge_objs && not dashLSupported = do
+ | can_merge_objs && (not dashLSupported || is_dyn) = do
let toolSettings' = toolSettings dflags
ldIsGnuLd = toolSettings_ldIsGnuLd toolSettings'
ld_r args = GHC.SysTools.runMergeObjects (hsc_logger hsc_env) (hsc_tmpfs hsc_env) (hsc_dflags hsc_env) (
@@ -1100,6 +1109,7 @@ joinObjectFiles hsc_env o_files output_fn
withAtomicRename output_fn $ \tmp_ar ->
liftIO $ runAr logger dflags Nothing $ map Option $ ["qc" ++ dashL, tmp_ar] ++ o_files
where
+ is_dyn = ways dflags `hasWay` WayDyn
dashLSupported = sArSupportsDashL (settings dflags)
dashL = if dashLSupported then "L" else ""
can_merge_objs = isJust (pgm_lm (hsc_dflags hsc_env))
20 changes: 11 additions & 9 deletions dev-lang/ghc/ghc-9.8.2.ebuild
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 1999-2023 Gentoo Authors
# Copyright 1999-2024 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

EAPI=8
Expand Down Expand Up @@ -454,14 +454,14 @@ src_prepare() {

if ! use ghcbootstrap && ! upstream_binary; then
# Make GHC's settings file comply with user's settings
GHC_SETTINGS="${WORKDIR}/usr/$(get_libdir)/${PN}-${BIN_PV}/lib/settings"
sed -i "s/,(\"C compiler command\", \".*\")/,(\"C compiler command\", \"$(tc-getCC)\")/" "${GHC_SETTINGS}" || die
sed -i "s/,(\"C++ compiler command\", \".*\")/,(\"C++ compiler command\", \"$(tc-getCXX)\")/" "${GHC_SETTINGS}" || die
sed -i "s/,(\"Haskell CPP command\", \".*\")/,(\"Haskell CPP command\", \"$(tc-getCC)\")/" "${GHC_SETTINGS}" || die
sed -i "s/,(\"ld command\", \".*\")/,(\"ld command\", \"$(tc-getLD)\")/" "${GHC_SETTINGS}" || die
sed -i "s/,(\"Merge objects command\", \".*\")/,(\"Merge objects command\", \"$(tc-getLD)\")/" "${GHC_SETTINGS}" || die
sed -i "s/,(\"ar command\", \".*\")/,(\"ar command\", \"$(tc-getAR)\")/" "${GHC_SETTINGS}" || die
sed -i "s/,(\"ranlib command\", \".*\")/,(\"ranlib command\", \"$(tc-getRANLIB)\")/" "${GHC_SETTINGS}" || die
GHC_SETTINGS="${WORKDIR}/usr/$(get_libdir)/${PN}-${BIN_PV}/lib/settings"
sed -i "s/,(\"C compiler command\", \".*\")/,(\"C compiler command\", \"$(tc-getCC)\")/" "${GHC_SETTINGS}" || die
sed -i "s/,(\"C++ compiler command\", \".*\")/,(\"C++ compiler command\", \"$(tc-getCXX)\")/" "${GHC_SETTINGS}" || die
sed -i "s/,(\"Haskell CPP command\", \".*\")/,(\"Haskell CPP command\", \"$(tc-getCC)\")/" "${GHC_SETTINGS}" || die
sed -i "s/,(\"ld command\", \".*\")/,(\"ld command\", \"$(tc-getLD)\")/" "${GHC_SETTINGS}" || die
sed -i "s/,(\"Merge objects command\", \".*\")/,(\"Merge objects command\", \"$(tc-getLD)\")/" "${GHC_SETTINGS}" || die
sed -i "s/,(\"ar command\", \".*\")/,(\"ar command\", \"$(tc-getAR)\")/" "${GHC_SETTINGS}" || die
sed -i "s/,(\"ranlib command\", \".*\")/,(\"ranlib command\", \"$(tc-getRANLIB)\")/" "${GHC_SETTINGS}" || die
fi
use llvm && ! use ghcbootstrap && llvmize "$(ghc_bin_path)"

Expand Down Expand Up @@ -538,6 +538,8 @@ src_prepare() {
eapply "${FILESDIR}"/${PN}-8.2.1_rc1-win32-cross-2-hack.patch # bad workaround
popd

eapply "${FILESDIR}"/${PN}-9.8.2-force-merge-objects-when-building-dynamic-objects.patch

bump_libs

eapply_user
Expand Down

0 comments on commit 104c8ef

Please sign in to comment.