The Cabal file of the Win32
package has a c-sources
which includes cbits/errors.c
which provides a C function getErrorMessage
; Win32
uses it to create a Haskell function with the same name.
I created a package which copied that C function (verbatim). However, when I compiled a second package that depended on both Win32
and my new package, the GHC runtime linker complained about a fatal error: it found a duplicate definition for symbol getErrorMessage
while processing an object file for my new package and said it was previously defined in an object file for the Win32
package. (This resulted in a āpanic! (the āimpossibleā happened)ā and a suggestion it be reported as a GHC bug.)
My question is this: why does the C function result in a symbol in the GHC object file for the package? I had assumed - probably wrongly - that the C function would be somehow āinternalā to the package. Is it possible to specify that the C function is only āinternalā? If not, does that mean that C functions used in c-sources
need to be named in a way that makes name clashes unlikely?
Perhaps what I experienced was genuinely a GHC 9.2.7 bug; I canāt reproduce something similar with a minimal reproducible example.
There is no name spacing for C functions. If you copy the file youāll have to rename the functions to prevent duplicate symbols.
The alternative is: if you depend on Win32 anyway, to just not define the c functions at all and rely on the Win32 library to bring in the definitions.
1 Like
When compiling C files with GHC, all GHC does is add some defines and c compiler flags and then invoked the c compiler. This will produce an object file (.o), which is then together with the object files for the haskell modules, linked into a shared library/executable (and/or archived into an .a archive on object files aka static library).
From the linkers perspective there is just a bunch of symbols (function names and data references), where and how they came about, it doesnāt know. It does however require them to be unique.
This if you link two libraries that contain the same name, the linker will complain.
Option one: prefix the function names in C, Iād you want the duplicates to survive.
Option two: just assume the symbols to exist without implementing them, because you know they come in from a dependency at link time anyway and this will be found. M
1 Like
I now have a minimal reproducible example, following this 2012 GHC issue: #6107: GHCi runtime linker cannot link with duplicate common symbols Ā· Issues Ā· Glasgow Haskell Compiler / GHC Ā· GitLab. A Template Haskell splice triggers the problem; without the splice, GHC does not seem to be bothered by the object files containing the same symbol.
Iāll have a look. GHCs in-memory linker is fairly basic. Iām a bit confused as to why this would not happen with the final link product, but maybe the linker ca see that something is not used or itās not passed as a dependency to the linker.
1 Like
For anyone reading this, @RyanGlScott and others left some comments on the gitlab ticket. Iāve also left an analysis as promised.
1 Like
Many thanks for your and @RyanGlScottās thorough analysis at the GitLab tickets - I found that very helpful.
What I take from this is the following: if you are using C functions etc in c-sources
it is a good idea to choose names for them that other packages are unlikely to duplicate.
Yes. Use some library/package specific prefix to prevent name clashes.
ret_type <pkg>_<function>(argsā¦) { ā¦ }