On 2026-03-29 13:27, Bruno Haible wrote:
what is the problem? The .c files are only compiled when needed.
OK, but the tarball is significantly larger than it needs to be, and a
lot of those .c files are not really needed even when they are compiled.
Some of the problem is longstanding: the printf-posix and fprintf-posix
bring in a lot of floating-point and multibyte stuff that gzip doesn't
need. It's the usual problem that getting printf exactly right means a
lot of code - but gzip doesn't need printf to be exactly right.
But some of the problem is new: there's more multibyte and multithread
stuff now, none of which gzip needs.
From the Gnulib point of view, perhaps tuning gzip's use of Gnulib is a
waste of time or even counterproductive, because it's yet another
combination of modules that needs testing (by gzip). But from gzip's
point of view, Gnulib's bloat is becoming a bigger and bigger problem:
there are many more files, they all do something maybe, but probably
not, and it's increasing the confusion level.
In any case, you can use gnulib-tool to determine the reason why a
file is included:
I find gnulib-tool hard to use for this sort of thing. If I see a file
m4/xyz.m4 that I don't know why it's there, it's not easy for me to see
the path from m4/xyz.m4 to the Gnulib modules that bootstrap.conf
specifies. It'd be nice if gnulib-tool had an option to do that.
Looking at the starting points in gzip/bootstrap.conf, I can see at least
this dependency chain:
yesno → rpmatch → regex → wctype → iswxdigit
Unfortunately that example underscores the need for the gnulib-tool
option, as that dependency chain does not exist for gzip. gzip is
bootstrapped by passing '--avoid rpmatch' to gnulib-tool; see gzip's
bootstrap.conf.
I attempted to put gzip on a diet by installing the attached Gnulib
patches to remove some unnecessary dependencies, and then adding
"--avoid lock" to gzip's bootstrap.conf while also removing printf-posix
and fprintf-posix from gzip's bootstrap.conf. This shrank the gzip
tarball's files by 36%, and so should make the gzip build process easier
to understand.
It might be helpful to add more options like
GNULIB_MBRTOWC_SINGLE_THREAD as a better way of doing things for code
that is single-threaded and/or single-locale, compared to using "--avoid
lock" and omitting f?printf-posix, but I didn't explore that possibility.From 91150bc6e2ee5297046e15345b5e8cef01d7f25a Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email protected]>
Date: Tue, 31 Mar 2026 16:38:47 -0700
Subject: [PATCH 1/3] =?UTF-8?q?gettext-h:=20don=E2=80=99t=20depend=20on=20?=
=?UTF-8?q?locale-h?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This is useful for apps like gzip.h that stay in the C locale
and don’t need all the the locale-h machinery.
* lib/gettext.h: Include <locale.h> only if !ENABLE_NLS && __sun.
(pgettext, dpgettext, npgettext, dnpgettext, pgettext_expr)
(npgettext_expr): Use _GL_LC_MESSAGES, not LC_MESSAGES.
* m4/gettext_h.m4 (gl_GETTEXT_H): Define _GL_LC_MESSAGES.
* modules/gettext-h (Depends-on): Remove locale-h.
---
ChangeLog | 11 +++++++++++
lib/gettext.h | 27 +++++++++++++++------------
m4/gettext_h.m4 | 11 ++++++++++-
modules/gettext-h | 1 -
4 files changed, 36 insertions(+), 14 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index b431a150e2..c2beb296ef 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2026-03-31 Paul Eggert <[email protected]>
+
+ gettext-h: don’t depend on locale-h
+ This is useful for apps like gzip.h that stay in the C locale
+ and don’t need all the the locale-h machinery.
+ * lib/gettext.h: Include <locale.h> only if !ENABLE_NLS && __sun.
+ (pgettext, dpgettext, npgettext, dnpgettext, pgettext_expr)
+ (npgettext_expr): Use _GL_LC_MESSAGES, not LC_MESSAGES.
+ * m4/gettext_h.m4 (gl_GETTEXT_H): Define _GL_LC_MESSAGES.
+ * modules/gettext-h (Depends-on): Remove locale-h.
+
2026-03-30 Bruno Haible <[email protected]>
fenv-exceptions-trapping: Work around mingw 14.0.0 bug.
diff --git a/lib/gettext.h b/lib/gettext.h
index 0291cf09c5..ffe303f568 100644
--- a/lib/gettext.h
+++ b/lib/gettext.h
@@ -177,28 +177,31 @@ dcgettext (const char *domain, const char *msgid, int category)
short and rarely need to change.
The letter 'p' stands for 'particular' or 'special'. */
-#include <locale.h> /* for LC_MESSAGES */
-
#ifdef DEFAULT_TEXT_DOMAIN
# define pgettext(Msgctxt, Msgid) \
- pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
+ pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, \
+ Msgid, _GL_LC_MESSAGES)
#else
# define pgettext(Msgctxt, Msgid) \
- pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
+ pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, _GL_LC_MESSAGES)
#endif
#define dpgettext(Domainname, Msgctxt, Msgid) \
- pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
+ pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, \
+ Msgid, _GL_LC_MESSAGES)
#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \
pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category)
#ifdef DEFAULT_TEXT_DOMAIN
# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
- npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
+ npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, \
+ Msgid, MsgidPlural, N, _GL_LC_MESSAGES)
#else
# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
- npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
+ npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, \
+ Msgid, MsgidPlural, N, _GL_LC_MESSAGES)
#endif
#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
- npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
+ npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, \
+ Msgid, MsgidPlural, N, _GL_LC_MESSAGES)
#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)
@@ -268,9 +271,9 @@ npgettext_aux (const char *domain,
#endif
#define pgettext_expr(Msgctxt, Msgid) \
- dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES)
+ dcpgettext_expr (NULL, Msgctxt, Msgid, _GL_LC_MESSAGES)
#define dpgettext_expr(Domainname, Msgctxt, Msgid) \
- dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES)
+ dcpgettext_expr (Domainname, Msgctxt, Msgid, _GL_LC_MESSAGES)
#if defined __GNUC__ || defined __clang__
__inline
@@ -314,9 +317,9 @@ dcpgettext_expr (const char *domain,
}
#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
- dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
+ dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, _GL_LC_MESSAGES)
#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
- dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
+ dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, _GL_LC_MESSAGES)
#if defined __GNUC__ || defined __clang__
__inline
diff --git a/m4/gettext_h.m4 b/m4/gettext_h.m4
index 7ef89541b9..26546bef5d 100644
--- a/m4/gettext_h.m4
+++ b/m4/gettext_h.m4
@@ -1,5 +1,5 @@
# gettext_h.m4
-# serial 1
+# serial 2
dnl Copyright (C) 2025-2026 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -10,6 +10,15 @@ AC_DEFUN_ONCE([gl_GETTEXT_H],
[
AC_SUBST([LIBINTL])
AC_SUBST([LTLIBINTL])
+ AC_CACHE_CHECK([for LC_MESSAGES value], [gl_cv_val_LC_MESSAGES],
+ [AC_COMPUTE_INT([gl_cv_val_LC_MESSAGES],
+ [LC_MESSAGES],
+ [#include <locale.h>
+ ],
+ [# The value Gnulib uses when <locale.h> does not define LC_MESSAGES.
+ gl_cv_LC_MESSAGES=1729])])
+ AC_DEFINE_UNQUOTED([_GL_LC_MESSAGES], [$gl_cv_val_LC_MESSAGES],
+ [The value of LC_MESSAGES, or 1729 on hosts that lack it.])
AH_BOTTOM([
/* The text domainname for Gnulib messages. Ordinarily this is "gnulib",
but packages that do their own translations of Gnulib can use something
diff --git a/modules/gettext-h b/modules/gettext-h
index ffcc7e163a..2eef0caa2c 100644
--- a/modules/gettext-h
+++ b/modules/gettext-h
@@ -6,7 +6,6 @@ lib/gettext.h
m4/gettext_h.m4
Depends-on:
-locale-h
vararrays
configure.ac:
--
2.51.0
From 250881c4f839e18737a1d6d807337a76015cc722 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email protected]>
Date: Tue, 31 Mar 2026 19:51:36 -0700
Subject: [PATCH 2/3] thread: lessen glthread namespace pollution
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In lib/glthread/*.h, avoid including files if it’s easy, and if
the files are not needed in the .h file to implement the module.
* lib/glthread/cond.h: Include glthread/lock.h only if needed.
* lib/glthread/lock.c, lib/glthread/once.c: Include <errno.h> here ...
* lib/glthread/lock.h, lib/glthread/once.h: ... instead of here.
* lib/glthread/lock.h: Include glthread/once.h only if needed.
* lib/glthread/yield.h: Don’t include <errno.h>.
---
ChangeLog | 9 +++++++++
lib/glthread/cond.h | 5 ++++-
lib/glthread/lock.c | 2 ++
lib/glthread/lock.h | 7 ++++---
lib/glthread/once.c | 2 ++
lib/glthread/once.h | 1 -
lib/glthread/yield.h | 2 --
7 files changed, 21 insertions(+), 7 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index c2beb296ef..6a05bbea00 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
2026-03-31 Paul Eggert <[email protected]>
+ thread: lessen glthread namespace pollution
+ In lib/glthread/*.h, avoid including files if it’s easy, and if
+ the files are not needed in the .h file to implement the module.
+ * lib/glthread/cond.h: Include glthread/lock.h only if needed.
+ * lib/glthread/lock.c, lib/glthread/once.c: Include <errno.h> here ...
+ * lib/glthread/lock.h, lib/glthread/once.h: ... instead of here.
+ * lib/glthread/lock.h: Include glthread/once.h only if needed.
+ * lib/glthread/yield.h: Don’t include <errno.h>.
+
gettext-h: don’t depend on locale-h
This is useful for apps like gzip.h that stay in the C locale
and don’t need all the the locale-h machinery.
diff --git a/lib/glthread/cond.h b/lib/glthread/cond.h
index 6f93c71fa1..bbc253e574 100644
--- a/lib/glthread/cond.h
+++ b/lib/glthread/cond.h
@@ -57,7 +57,10 @@
#include <stdlib.h>
#include <time.h>
-#include "glthread/lock.h"
+#if (USE_ISOC_THREADS || USE_POSIX_THREADS || USE_ISOC_AND_POSIX_THREADS \
+ || USE_WINDOWS_THREADS)
+# include "glthread/lock.h"
+#endif
#if !defined c11_threads_in_use
# if HAVE_THREADS_H && USE_POSIX_THREADS_FROM_LIBC
diff --git a/lib/glthread/lock.c b/lib/glthread/lock.c
index cfb9393c43..52086c8426 100644
--- a/lib/glthread/lock.c
+++ b/lib/glthread/lock.c
@@ -21,6 +21,8 @@
#include "glthread/lock.h"
+#include <errno.h>
+
/* ========================================================================= */
#if USE_ISOC_THREADS || USE_ISOC_AND_POSIX_THREADS
diff --git a/lib/glthread/lock.h b/lib/glthread/lock.h
index d8190b6c81..b9fb907ead 100644
--- a/lib/glthread/lock.h
+++ b/lib/glthread/lock.h
@@ -78,12 +78,13 @@
#error "Please include config.h first."
#endif
-#include <errno.h>
#include <stdlib.h>
-#include "glthread/once.h"
-
+#if (USE_ISOC_THREADS || USE_POSIX_THREADS || USE_ISOC_AND_POSIX_THREADS \
+ || USE_WINDOWS_THREADS)
+# include "glthread/once.h"
/* c11_threads_in_use() is defined in glthread/once.h. */
+#endif
/* ========================================================================= */
diff --git a/lib/glthread/once.c b/lib/glthread/once.c
index b72a4a202a..1d04925e62 100644
--- a/lib/glthread/once.c
+++ b/lib/glthread/once.c
@@ -21,6 +21,8 @@
#include "glthread/once.h"
+#include <errno.h>
+
/* ========================================================================= */
#if USE_ISOC_THREADS || USE_ISOC_AND_POSIX_THREADS
diff --git a/lib/glthread/once.h b/lib/glthread/once.h
index b6d9ab404c..ac20b64cca 100644
--- a/lib/glthread/once.h
+++ b/lib/glthread/once.h
@@ -39,7 +39,6 @@
#error "Please include config.h first."
#endif
-#include <errno.h>
#include <stdlib.h>
#if !defined c11_threads_in_use
diff --git a/lib/glthread/yield.h b/lib/glthread/yield.h
index 99515d31fb..783421f92b 100644
--- a/lib/glthread/yield.h
+++ b/lib/glthread/yield.h
@@ -21,8 +21,6 @@
#ifndef _GLTHREAD_YIELD_H
#define _GLTHREAD_YIELD_H
-#include <errno.h>
-
/* ========================================================================= */
#if USE_ISOC_THREADS || USE_ISOC_AND_POSIX_THREADS
--
2.51.0
From 4726af921c9aa82cf0992871484108b7053cc81c Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email protected]>
Date: Tue, 31 Mar 2026 19:54:46 -0700
Subject: [PATCH 3/3] sigprocmask: allow --avoid=lock
* modules/sigprocmask (Files): Add lib/glthread/lock.h,
so that this module works even if the lock module is avoided.
This is useful for gzip, which does not use multithreading.
---
ChangeLog | 5 +++++
modules/sigprocmask | 1 +
2 files changed, 6 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index 6a05bbea00..0302110aef 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
2026-03-31 Paul Eggert <[email protected]>
+ sigprocmask: allow --avoid=lock
+ * modules/sigprocmask (Files): Add lib/glthread/lock.h,
+ so that this module works even if the lock module is avoided.
+ This is useful for gzip, which does not use multithreading.
+
thread: lessen glthread namespace pollution
In lib/glthread/*.h, avoid including files if it’s easy, and if
the files are not needed in the .h file to implement the module.
diff --git a/modules/sigprocmask b/modules/sigprocmask
index 79e7c7302f..ea706bab65 100644
--- a/modules/sigprocmask
+++ b/modules/sigprocmask
@@ -2,6 +2,7 @@ Description:
POSIX compatible signal blocking.
Files:
+lib/glthread/lock.h
lib/sigprocmask.c
m4/signalblocking.m4
--
2.51.0