[GHC] #11223: Dynamic linker on Windows is unable to link against libmingwex

GHC ghc-devs at haskell.org
Tue Dec 15 15:15:40 UTC 2015


#11223: Dynamic linker on Windows is unable to link against libmingwex
-------------------------------------+-------------------------------------
        Reporter:  Phyx-             |                Owner:  Phyx-
            Type:  task              |               Status:  new
        Priority:  normal            |            Milestone:  8.2.1
       Component:  Runtime System    |              Version:  7.10.3
  (Linker)                           |
      Resolution:                    |             Keywords:
Operating System:  Windows           |         Architecture:
 Type of failure:  Compile-time      |  Unknown/Multiple
  crash                              |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:  #10726            |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------
Description changed by bgamari:

Old description:

> 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:
>
> 1. I tried removing the symbols from the export list and adding
> `libmingwex` to the rts's `package.conf`and have it just link against it.
> But turns out the `rts`'s `package.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.
>
> 2. 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 file):
>
> {{{#!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'
> }}}

New description:

 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:

 1. I tried removing the symbols from the export list and adding
 `libmingwex` to the rts's `package.conf`and have it just link against it.
 But turns out the `rts`'s `package.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.

 2. 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 ===

 {{{#!hs
 -- 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'
 }}}

--

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/11223#comment:2>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list