Declaration of _gpgrt_functions_w32_pollable in src/gpgrt-int.h should be extern
Closed, ResolvedPublic

Description

libgpg-error-1.35.tar.bz2's libgpg-error-1.35/src/gpgrt-int.h contains

#if HAVE_W32_SYSTEM
/* Prototypes for w32-estream.c.  */
struct cookie_io_functions_s _gpgrt_functions_w32_pollable;
int _gpgrt_w32_pollable_create (void *_GPGRT__RESTRICT *_GPGRT__RESTRICT cookie,
                                unsigned int modeflags,
                                struct cookie_io_functions_s next_functions,
                                void *next_cookie);
int _gpgrt_w32_poll (gpgrt_poll_t *fds, size_t nfds, int timeout);
#endif /*HAVE_W32_SYSTEM*/

Not sure how MSVC manages to not make this an ODR violation, where _gpgrt_functions_w32_pollable is defined in every translation unit including gpgrt-int.h. But compiling with clang-cl (which I happen to do when libgpg-error is built as part of building LibreOffice; the libgpg-error version used there is 1.27, but the issue appears to be still the same with latest 1.35) fails with

libgpg_error_la-visibility.obj : warning LNK4006: _gpgrt_functions_w32_pollable already defined in libgpg_error_la-b64dec.obj; second definition ignored
libgpg_error_la-estream-printf.obj : warning LNK4006: _gpgrt_functions_w32_pollable already defined in libgpg_error_la-b64dec.obj; second definition ignored
libgpg_error_la-estream.obj : warning LNK4006: _gpgrt_functions_w32_pollable already defined in libgpg_error_la-b64dec.obj; second definition ignored
libgpg_error_la-init.obj : warning LNK4006: _gpgrt_functions_w32_pollable already defined in libgpg_error_la-b64dec.obj; second definition ignored
libgpg_error_la-w32-estream.obj : warning LNK4006: _gpgrt_functions_w32_pollable already defined in libgpg_error_la-b64dec.obj; second definition ignored
libgpg_error_la-w32-iconv.obj : warning LNK4006: _gpgrt_functions_w32_pollable already defined in libgpg_error_la-b64dec.obj; second definition ignored
libtool: link: ( cd ".libs" && rm -f "libgpg-error.la" && ln -s "../libgpg-error.la" "libgpg-error.la" )
libtool: link: C:/lo-clang/core/workdir/LinkTarget/Executable/gcc-wrapper.exe -g -o gen-w32-lock-obj.exe gen-w32-lock-obj.obj
libtool: link: C:/lo-clang/core/workdir/LinkTarget/Executable/gcc-wrapper.exe -g -o gpg-error.exe gpg_error-strsource-sym.obj gpg_error-strerror-sym.obj gpg_error-gpg-error.obj  ./.libs/libgpg-error.lib
libgpg-error.lib(libgpg_error_la-init.obj) : error LNK2005: _gpgrt_functions_w32_pollable already defined in libgpg-error.lib(libgpg_error_la-visibility.obj)
libgpg-error.lib(libgpg_error_la-estream.obj) : error LNK2005: _gpgrt_functions_w32_pollable already defined in libgpg-error.lib(libgpg_error_la-visibility.obj)
libgpg-error.lib(libgpg_error_la-estream-printf.obj) : error LNK2005: _gpgrt_functions_w32_pollable already defined in libgpg-error.lib(libgpg_error_la-visibility.obj)
libgpg-error.lib(libgpg_error_la-b64dec.obj) : error LNK2005: _gpgrt_functions_w32_pollable already defined in libgpg-error.lib(libgpg_error_la-visibility.obj)
libgpg-error.lib(libgpg_error_la-w32-estream.obj) : error LNK2005: _gpgrt_functions_w32_pollable already defined in libgpg-error.lib(libgpg_error_la-visibility.obj)
gpg-error.exe : fatal error LNK1169: one or more multiply defined symbols found
clang: error: linker command failed with exit code 1169 (use -v to see invocation)

Adding "extern" to the declaration of _gpgrt_functions_w32_pollable in src/gpgrt-int.h fixes that.

Details

Commits
rE21dd885eecde: build: Fix for Microsoft MSVC.
Version
libgpg-error 1.35
sberg created this task.Fri, Feb 1, 3:52 PM
werner added a subscriber: werner.

This function is not exported on purposes. Even the name of the header file indicates that tis is internal. External, that is public functions of the API, are defined gpgrt.h and only made externally visible by including them in the .def file. This has not been done and so I don't understand your bug report.

In case you are linking statically (which is a not so good design decision), you may indeed the see this function but the underscore should be enough of a hint that this is an internal function. Linbking to different versions of a library is of course asking for trouble.

What is your use case?

sberg added a comment.Mon, Feb 4, 8:35 AM

This is not about a function, but about the variable _gpgrt_functions_w32_pollable. And this is not about exporting the variable from the library, but about declaring it as extern in gpgrt-int.h, so that gpgrt-int.h can be included in multiple translation units without defining the variable in each.

Okay, I see the problem. The microsoft toolchain is more picky about de-facto standard use patterns with common blocks and the author of that code was not ware of this. Thanks for reporting, will be fixed in the next release.

werner closed this task as Resolved.Mon, Feb 4, 5:46 PM
werner claimed this task.