Skip to content
Snippets Groups Projects

driver: force merge objects when building dynamic objects

Closed Cheng Shao requested to merge type-dance/ghc:fix-llvm-ar into master
1 file
+ 18
8
Compare changes
  • Side-by-side
  • Inline
@@ -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))
Loading