We're not yet done with strnul. It broke the libunistring build:

/usr/bin/ld: .libs/libunistring_la-string.o: in function `libunistring_memeq':
/builds/gnu-libunistring/ci-distcheck/build/libunistring/lib/./string.h:970: 
multiple definition of `libunistring_memeq'; 
.libs/libunistring_la-string.o:/builds/gnu-libunistring/ci-distcheck/build/libunistring/lib/./string.h:970:
 first defined here
/usr/bin/ld: .libs/libunistring_la-string.o: in function `libunistring_streq':
/builds/gnu-libunistring/ci-distcheck/build/libunistring/lib/./string.h:1355: 
multiple definition of `libunistring_streq'; 
.libs/libunistring_la-string.o:/builds/gnu-libunistring/ci-distcheck/build/libunistring/lib/./string.h:1355:
 first defined here
/usr/bin/ld: .libs/libunistring_la-string.o: in function 
`libunistring_gl_strnul':
/builds/gnu-libunistring/ci-distcheck/build/libunistring/lib/./string.h:1797: 
multiple definition of `libunistring_gl_strnul'; 
.libs/libunistring_la-string.o:/builds/gnu-libunistring/ci-distcheck/build/libunistring/lib/./string.h:1797:
 first defined here
collect2: error: ld returned 1 exit status
make[3]: *** [Makefile:5886: libunistring.la] Error 1
make[3]: Leaving directory 
'/builds/gnu-libunistring/ci-distcheck/build/libunistring/lib'

The cause of this error is that the Makefile passing the object file
libunistring_la-string.lo twice in the link command line. And this is
because it is listed in two different modules:

  modules/strnul:lib_SOURCES += string.c
  modules/stringeq:lib_SOURCES += string.c

A possible way to avoid listing the same .lo file twice in the link is
to use AC_LIBOBJ. But AC_LIBOBJ has problems too; the better way is to
use different object files for different functions. There's no reason
why gl_strnul() should be defined in the same object file as streq() and
memeq().


2026-02-28  Bruno Haible  <[email protected]>

        strnul: Fix link-time error.
        * lib/string.in.h (_GL_STRNUL_INLINE): New macro.
        (gl_strnul): Use it instead of _GL_STRING_INLINE.
        * lib/strnul.c: New file.
        * lib/string.c: Update comment.
        * modules/strnul (Files): Add strnul.c. Remove string.c.
        (Makefile.am): Update accordingly.

diff --git a/lib/string.c b/lib/string.c
index b8f079aa78..610da9f12e 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -1,4 +1,4 @@
-/* streq, memeq, gl_strnul functions.
+/* streq, memeq functions.
    Copyright (C) 2025-2026 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/lib/string.in.h b/lib/string.in.h
index a98552b8f5..c930ecc4e0 100644
--- a/lib/string.in.h
+++ b/lib/string.in.h
@@ -81,10 +81,12 @@
 #endif
 
 _GL_INLINE_HEADER_BEGIN
-
 #ifndef _GL_STRING_INLINE
 # define _GL_STRING_INLINE _GL_INLINE
 #endif
+#ifndef _GL_STRNUL_INLINE
+# define _GL_STRNUL_INLINE _GL_INLINE
+#endif
 
 /* _GL_ATTRIBUTE_DEALLOC (F, I) declares that the function returns pointers
    that can be freed by passing them as the Ith argument to the
@@ -1243,10 +1245,10 @@ _GL_WARN_ON_USE (strtok_r, "strtok_r is unportable - "
 # ifdef __cplusplus
 extern "C" {
 # endif
-_GL_STRING_INLINE const char *gl_strnul (const char *string)
+_GL_STRNUL_INLINE const char *gl_strnul (const char *string)
      _GL_ATTRIBUTE_PURE
      _GL_ARG_NONNULL ((1));
-_GL_STRING_INLINE const char *gl_strnul (const char *string)
+_GL_STRNUL_INLINE const char *gl_strnul (const char *string)
 {
   /* In gcc >= 7 or clang >= 4, we could use the expression
        strchr (string, '\0')
diff --git a/lib/strnul.c b/lib/strnul.c
new file mode 100644
index 0000000000..a567f0722e
--- /dev/null
+++ b/lib/strnul.c
@@ -0,0 +1,19 @@
+/* gl_strnul function.
+   Copyright (C) 2025-2026 Free Software Foundation, Inc.
+
+   This file is free software: you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   This file is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#define _GL_STRNUL_INLINE _GL_EXTERN_INLINE
+#include <config.h>
+#include <string.h>
diff --git a/modules/strnul b/modules/strnul
index 52d6729c8c..7accd5fb0f 100644
--- a/modules/strnul
+++ b/modules/strnul
@@ -2,7 +2,7 @@ Description:
 strnul() function: return pointer to terminating NUL byte.
 
 Files:
-lib/string.c
+lib/strnul.c
 
 Depends-on:
 string-h
@@ -11,7 +11,7 @@ configure.ac:
 gl_STRING_MODULE_INDICATOR([strnul])
 
 Makefile.am:
-lib_SOURCES += string.c
+lib_SOURCES += strnul.c
 
 Include:
 <string.h>




  • strnul: Fix link-time error Bruno Haible via Gnulib discussion list

Reply via email to