Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Static .lib required for compiling library is also required for library users?

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?

like image 594
Tom Savage Avatar asked Jul 02 '13 22:07

Tom Savage


1 Answers

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.

like image 76
Yuras Avatar answered Oct 19 '22 09:10

Yuras