Koka / gettext-rs

GNU Gettext FFI binding for Rust
51 stars 25 forks source link

fix-wbindtextdomain-call-on-mingw: Replace the reference to a "wbindtextdomain" symbol by a reference to a "libintl_wbindtextdomain" symbol, as "wbindtextdomain" is not present in the compiled libintl .DLL under the MinGW platform (conversely to Cygwin) #79

Closed marin-m closed 2 years ago

marin-m commented 2 years ago

This pull requests fixes a regression that likely prevents gettext-rs/gettext-sys to link with libintl.dll on the MinGW platform when using the gettext-system feature since pull request #41.

Indeed, when and only when compiling for the MinGW target of libintl, the wbindtextdomain symbol is not linked into the final .DLL, as due to a conditional definition in libintl.h, only a libintl_wbindtextsymbol is linked into the final .DLL file, and wbindtextsymbol is only defined as an inline function in an header file. See:

$ find /opt/gtkwin -iname '*libintl'*
/opt/gtkwin/usr/x86_64-w64-mingw32/sys-root/mingw/bin/libintl-8.dll
/opt/gtkwin/usr/x86_64-w64-mingw32/sys-root/mingw/lib/libintl.dll.a
/opt/gtkwin/usr/x86_64-w64-mingw32/sys-root/mingw/include/libintl.h

$ objdump -x /opt/gtkwin/usr/x86_64-w64-mingw32/sys-root/mingw/bin/libintl-8.dll | grep wbindtextdomain
    [  84] libintl_wbindtextdomain
[ 12](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000000008b0 libintl_wbindtextdomain

$ objdump -x /opt/gtkwin/usr/x86_64-w64-mingw32/sys-root/mingw/lib/libintl.dll.a | grep wbindtextdomain
[  5](sec  1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000000000 libintl_wbindtextdomain
[  6](sec  3)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000000000 __imp_libintl_wbindtextdomain

See:

$ cat /opt/gtkwin/usr/x86_64-w64-mingw32/sys-root/mingw/include/libintl.h
[...]
#if defined _WIN32 && !defined __CYGWIN__
/* Specify that the DOMAINNAME message catalog will be found
   in WDIRNAME rather than in the system locale data base.  */
#ifdef _INTL_REDIRECT_INLINE
extern wchar_t *libintl_wbindtextdomain (const char *__domainname,
                                         const wchar_t *__wdirname);
static inline wchar_t *wbindtextdomain (const char *__domainname,
                                        const wchar_t *__wdirname)
{
  return libintl_wbindtextdomain (__domainname, __wdirname);
}
#else
#ifdef _INTL_REDIRECT_MACROS
# define wbindtextdomain libintl_wbindtextdomain
#endif
extern wchar_t *wbindtextdomain (const char *__domainname,
                                 const wchar_t *__wdirname)
       _INTL_ASM (libintl_wbindtextdomain);
#endif
#endif
[...]

So, anyone who tried to link gettext-rs/gettext-sys 0.6.0 (since the integration of pull request #41) is likely to having obtained an error like this, while it worked correctly with version 0.5.0:

  = note: /usr/bin/x86_64-w64-mingw32-ld: /home/marin/gettext-rs/target/x86_64-pc-windows-gnu/release/deps/integration-a05475ff9a420f43.integration.d8pps1pk-cgu.1.rcgu.o:integration.d8pps1:(.text+0x7b3): undefined reference to `wbindtextdomain'
          /usr/bin/x86_64-w64-mingw32-ld: /home/marin/gettext-rs/target/x86_64-pc-windows-gnu/release/deps/integration-a05475ff9a420f43.integration.d8pps1pk-cgu.5.rcgu.o:integration.d8pps1:(.text+0xc4): undefined reference to `wbindtextdomain'
          /usr/bin/x86_64-w64-mingw32-ld: /home/marin/gettext-rs/target/x86_64-pc-windows-gnu/release/deps/libgettextrs-1913c68f0c1ca1db.rlib(gettextrs-1913c68f0c1ca1db.gettextrs.6yz7mjh2-cgu.2.rcgu.o):gettextrs.6yz7mjh2:(.text+0x383): undefined reference to `wbindtextdomain'
          collect2: error: ld returned 1 exit status

This pull request should solve the issue.