Windows: Make NLS require UCRT and gettext-runtime >= 0.23.1

Also remove the recently-added workaround from tuklib_gettext.h.
Requiring a new enough gettext-runtime is cleaner. I guess it's
mostly MSYS2 where xz is built with translation support, so once
MSYS2 has Gettext >= 0.23.1, this requirement shouldn't be a problem
in practice.
This commit is contained in:
Lasse Collin 2025-01-02 13:35:48 +02:00
parent aa1807ed94
commit 16821252c5
No known key found for this signature in database
GPG Key ID: 38EE757D69184620
3 changed files with 58 additions and 51 deletions

View File

@ -360,6 +360,35 @@ if(XZ_NLS)
"Install gettext tools or set XZ_NLS=OFF.")
endif()
if(WIN32)
# The command line tools use UTF-8 on native Windows.
# Non-ASCII characters display correctly only when
# using UCRT and gettext-runtime >= 0.23.1.
check_c_source_compiles(
"#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <libintl.h>
#ifndef _UCRT
#error \"Not UCRT\"
#endif
#if LIBINTL_VERSION < 0x001701
#error \"gettext-runtime < 0.23.1\"
#endif
int main(void) { return 0; }
"
USING_UCRT_AND_RECENT_GETTEXT)
if(NOT USING_UCRT_AND_RECENT_GETTEXT)
message(FATAL_ERROR "Native language support (NLS) was enabled "
"but it requires UCRT and "
"gettext-runtime >= 0.23.1. To build with "
"MSVCRT or old gettext-runtime, "
"set XZ_NLS=OFF.")
endif()
endif()
# Warn if translated man pages are missing.
if(UNIX AND NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/po4a/man")
message(WARNING "Native language support (NLS) was enabled "

View File

@ -826,6 +826,35 @@ AM_GNU_GETTEXT_REQUIRE_VERSION([0.19.6])
AM_GNU_GETTEXT_VERSION([0.19.6])
AM_GNU_GETTEXT([external])
# The command line tools use UTF-8 on native Windows. Non-ASCII characters
# display correctly only when using UCRT and gettext-runtime >= 0.23.1.
AS_CASE([$USE_NLS-$host_os],
[yes-mingw*], [
AC_MSG_CHECKING([for UCRT and gettext-runtime >= 0.23.1])
AC_PREPROC_IFELSE([AC_LANG_SOURCE([[
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <libintl.h>
#ifndef _UCRT
#error "Not UCRT"
#endif
#if LIBINTL_VERSION < 0x001701
#error "gettext-runtime < 0.23.1"
#endif
]])], [
AC_MSG_RESULT([yes])
], [
AC_MSG_RESULT([no])
AC_MSG_ERROR([
Translation support (--enable-nls) on native Windows requires
UCRT and gettext-runtime >= 0.23.1. Use --disable-nls to build
with MSVCRT or old gettext-runtime.])
])
]
)
###############################################################################
# Checks for header files.

View File

@ -24,57 +24,6 @@
#endif
#if TUKLIB_GETTEXT
# if defined(_WIN32) && !defined(__CYGWIN__)
// <libintl.h> from gettext-runtime redirects setlocale()
// to libintl_setlocale(). As of gettext 0.22.5 (and probably
// 0.23), libintl_setlocale(LC_ALL, "") doesn't set the locale
// to UTF-8 if UTF-8 code page has been set in the application
// manifest. For example, one may get "fi_FI" when native
// setlocale() would result in "Finnish_Finland.utf8". The
// lack of ".utf8" (or equivalent) suffix results in garbled
// non-ASCII chars in translatated messages and also affects
// functions like mbrtowc() which depend on LC_CTYPE.
//
// Workaround the problem by not using libintl_setlocale()
// for now. Notes:
//
// (1) libintl_setlocale() reads LC_* environment variables
// but native setlocale() doesn't. The loss of this
// feature doesn't matter too much because, on Windows,
// libintl still reads the env vars LANGUAGE, LC_ALL,
// LC_MESSAGES, and LANG when translating messages in
// the LC_MESSAGES category (other categories are very
// rarely used for translations). As of Gettext commit
// e18edc579 and Gnulib commit 9e301775ff:
//
// libintl_gettext()
// `-- libintl_dcgettext()
// `-- libintl_dcigettext()
// `-- guess_category_value()
// |-- gl_locale_name_posix()
// | `-- gl_locale_name_posix_unsafe()
// | `-- gl_locale_name_environ()
// | |-- getenv("LC_ALL")
// | |-- getenv("LC_MESSAGES")
// | `-- getenv("LANG")
// `-- getenv("LANGUAGE")
//
// (2) If locale is changed, libintl_setlocale() marks cached
// translations as invalid. bindtextdomain(), which we
// call immediately after setlocale(), does the same
// invalidation too. Thus it doesn't matter in the
// tuklib_gettext_init() macro. It could matter if the
// application calls setlocale() elsewhere though (but
// then it's not guaranteed that such code even includes
// <libint.h> in addition to <locale.h>).
//
// This macro is checked by <libintl.h> since Gettext 0.18.2
// (2012-12-08). When this is defined, setlocale() isn't
// overridden.
//
// FIXME: Remove this hack when it's no longer needed.
# define GNULIB_defined_setlocale 1
# endif
# include <libintl.h>
# define tuklib_gettext_init(package, localedir) \
do { \