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.
@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.
@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.