haskell/zlib

Name clash with other foreign libraries

ndmitchell opened this issue · 7 comments

Combining Haskell code that uses the Haskell zlib library with code that uses the grpc C++ library from Google causes a link error because the names in adler32.o are duplicated between both libraries. Is it possible to rename the vendored sources function names so this library can stand alone and not clash with anything else?

This will only hit on Windows, since that's the only place you use the vendored in code. If you're happy to add some suitable prefix I'll make a PR.

hvr commented

@ndmitchell Ideally (that is, even more ideally we wouldn't have to ship zlib c source at all...), we'd name-mangle all visible names in the internally bundled zlib C lib which can't be declared static... a quick survey of the ABI-exposed symbols says that we'd need to name mangle the following symbols:

adler32
adler32_combine
adler32_combine64
compress
compress2
compressBound
crc32
crc32_combine
crc32_combine64
get_crc_table
deflate
deflateBound
deflateCopy
deflateEnd
deflateInit_
deflateInit2_
deflateParams
deflatePending
deflatePrime
deflateReset
deflateResetKeep
deflateSetDictionary
deflateSetHeader
deflateTune
inflateBack
inflateBackEnd
inflateBackInit_
inflate_fast
inflate
inflateCopy
inflateEnd
inflateGetDictionary
inflateGetHeader
inflateInit_
inflateInit2_
inflateMark
inflatePrime
inflateReset
inflateReset2
inflateResetKeep
inflateSetDictionary
inflateSync
inflateSyncPoint
inflateUndermine
inflate_table
_tr_align
_tr_flush_bits
_tr_flush_block
_tr_init
_tr_stored_block
_tr_tally
uncompress
zcalloc
zcfree
zError
zlibCompileFlags
zlibVersion

We could also try to reduce the amount of exposed surface by compiling zlib as a single compilation unit, and then only expose the bare minimum needed by the foreign imports....

Sounds great. I'm up for making a patch if your happy with that approach.

hvr commented

@ndmitchell I'd definitely support hidding the internal zlib impl a bit better (and I hope @dcoutts agrees :) ); packages depending on zlib shouldn't have any business assuming they can access the FFI C names of a zlib impl... on the other hand, we do have

install-includes: zlib.h zconf.h

which means that on windows, zlib also provides a C impl... :-/

So, if we want to keep this up, the name-mangling ought to work at the CPP level so that consumers that #include <zlib.h> properly, and pick up zlib's bundled zlib will be routed to the proper C ABI names. That would also preclude the approach I suggested with reducing the amount of exported C symbols...
(fwiw, one could also factor out the zlib C impl like I did in http://hackage.haskell.org/package/lzma-clib but that's somewhat orthogonal here)

So, I guess this all comes down to make a decision whether zlib shall continue to also provide a C API for the configuration where pkg-config is not used (i.e. there's a manual flag currently to force the use of pkg-config, which disables the internal zlib C impl even on windows) and os(windows) is true. And this is something I don't feel comfortable deciding without involving Duncan... :-/

Appreciate it needs Duncan's opinion too, but what's your view? My feeling is that providing a Haskell library and a C library on windows with one config flag is odd - I'd rather than C library wasn't there, or the packages only purpose was a C library.

I've no problem in principle with adjusting the namespace, though I fear it may make updating to new versions of zlib awkward. It'd be even better if we could make the C symbols private to the Haskell shared library.

I believe this is fixed in HEAD now, mostly by not forcing bundled C library onto Windows users.