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

Reply via email to