Question

I've been working on a Haskell library package which requires a custom .dll and .lib on Windows to talk to some OS APIs. The .lib is linked into the library with the extra-libraries field and the DLL is installed in the cabal package directory with data-files.

For some reason (I'm not an expert on linking by any means, but this seems weird) if I create a test executable which uses my package (in the build-depends field), it wants to link in the same .lib used to compile the library - even though it's just calling library functions, not anything the .lib exposes. Obviously it needs access to the .dll at runtime but that is to be expected. Needing the .lib as well seems odd.

I would expect that the .lib would already be linked into the .a file generated by Cabal/GHC for my library when it's installed. Is this not the case? And if it is, can someone explain why it's that way?

Was it helpful?

Solution

Looks like you want partial linking (see --relocatable flag in ld manual page). As I can see from the sources, cabal uses partial linking only libraries, compiled for ghci. From Distribution.Simple.GHC (buildLib function):

whenVanillaLib False $ do
  (arProg, _) <- requireProgram verbosity arProgram (withPrograms lbi)
  Ar.createArLibArchive verbosity arProg
    vanillaLibFilePath staticObjectFiles

whenProfLib $ do
  (arProg, _) <- requireProgram verbosity arProgram (withPrograms lbi)
  Ar.createArLibArchive verbosity arProg
    profileLibFilePath profObjectFiles

whenGHCiLib $ do
  (ldProg, _) <- requireProgram verbosity ldProgram (withPrograms lbi)
  Ld.combineObjectFiles verbosity ldProg
    ghciLibFilePath ghciObjFiles

whenSharedLib False $
  runGhcProg ghcSharedLinkArgs

You can see, that for vanilla and profiling libraries, cabal just calls ar utility (see createArLibArchive). For ghci it calls ld with -r flag (which is a shortcut for --relocatable) (see combineObjectFiles).

So, cabal doesn't actually do any linking for vanilla libraries, it just combines object files. Actually cabal can't know, whether final application will use any symbol from your extra-lib, so the behavior seems reasonable.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top