From 16821252c504071f5c2012e415e59cbf5fb79820 Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Thu, 2 Jan 2025 13:35:48 +0200 Subject: [PATCH] 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. --- CMakeLists.txt | 29 +++++++++++++++++++++ configure.ac | 29 +++++++++++++++++++++ src/common/tuklib_gettext.h | 51 ------------------------------------- 3 files changed, 58 insertions(+), 51 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e273c54d..767cc064 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 + #include + + #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 " diff --git a/configure.ac b/configure.ac index abc84fc2..c3447b2e 100644 --- a/configure.ac +++ b/configure.ac @@ -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 + #include + + #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. diff --git a/src/common/tuklib_gettext.h b/src/common/tuklib_gettext.h index fd4a156c..e5ad5e6f 100644 --- a/src/common/tuklib_gettext.h +++ b/src/common/tuklib_gettext.h @@ -24,57 +24,6 @@ #endif #if TUKLIB_GETTEXT -# if defined(_WIN32) && !defined(__CYGWIN__) - // 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 - // in addition to ). - // - // This macro is checked by 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 # define tuklib_gettext_init(package, localedir) \ do { \