Runtime linker performs eager loading of all object files
The runtime linker seems to be re-exporting some of the symbols of libmingwex
from the rts archive (using SymI_HasProto
). Only a very small subset of symbols are re-exporting.
If a symbol is needed that isn't re-exported (e.g. log1p
) then this code can't be run in GHCi because it will result in a duplicate symbols error.
A workaround
The rts
seems to be a special case again. The linker seems to ignore the extra-libraries
from the package.conf
, which explains why you can put anything you want in there and it'll still compile.
128 emptyPLS :: DynFlags -> PersistentLinkerState
129 emptyPLS _ = PersistentLinkerState {
130 closure_env = emptyNameEnv,
131 itbl_env = emptyNameEnv,
132 pkgs_loaded = init_pkgs,
133 bcos_loaded = [],
134 objs_loaded = [],
135 temp_sos = [] }
136
137 -- Packages that don't need loading, because the compiler
138 -- shares them with the interpreted program.
139 --
140 -- The linker's symbol table is populated with RTS symbols using an
141 -- explicit list. See rts/Linker.c for details.
142 where init_pkgs = [rtsUnitId]
I've tried 2 approaches which haven't worked completely:
- I tried removing the symbols from the export list and adding
libmingwex
to the rts'spackage.conf
and have it just link against it. But turns out therts
'spackage.conf
is ignored on all platforms. I didn't want to have to make an exception for Windows here and I don't know why the other platforms also ignore it so I abandoned this approach. - I tried marking the symbols we're re-exporting as weak symbols, so there wouldn't be a change to existing code and would allow you to link against
libmingwex
. But unfortunately because of when the other libraries specified by-l
are linked in, some of the symbols have already been used and thus aren't weak anymore. So I still get duplicate link errors.
What I want to try now is leaving them as weak symbols, but loading libmingwex.a
at rts
initialization time. Much like how kernel32
is loaded. This is hopefully early enough that the symbols haven't been used yet.
Example
-- LogFloat.hs
module Main (main) where
import Data.Number.LogFloat (log1p)
main :: IO ()
main = print $ log1p 1.0
runGhc LogFloat.hs
will fail:
Loading package logfloat-0.13.3.3 ...
linking ...
LogFloat.hs: ...\x86_64-windows-ghc-7.11.20151123\logfloat-0.13.3.3-4JZYNCXKwghOD60rvMUAcn\HSlogfloat-0.13.3.3-4JZYNCXKwghOD60rvMUAcn.o: unknown symbol `log1p'
LogFloat.hs: LogFloat.hs: unable to load package `logfloat-0.13.3.3'