Page MenuHome GnuPG

libgpg-error: build failure without threads
Closed, ResolvedPublic

Description

Cross-compilation of libgpg-error fails on toolchain without threads since commit 988211d3d4c1f3d5cfa6b460210f65ab636763b5, 9ee011259f819a3cf50fe7019fa4366dbc437e0e and 50e62b36ea01ed25d12c443088b85d4f41a2b3e1

Indeed, since that time, libgpg-error assumes that pthread.h is always available resulting in the following error at configure time:

checking for arm-unknown-linux-gnueabi-objdump... (cached) /tmp/instance-1/output-1/host/bin/arm-linux-objdump
conftest.c:1:10: fatal error: pthread.h: No such file or directory
    1 | #include <pthread.h>
      |          ^~~~~~~~~~~
compilation terminated.
configure: generated src/lock-obj-pub.native.h using arm-unknown-linux-gnueabi-objdump and gawk
checking whether to enable log_clock... no

This error will in turn result in a build failure because "Can't determine mutex size" is echoed by gen-lock-obj.sh:

In file included from strsource-sym.c:27:
./gpg-error.h:1115:4: warning: missing terminating ' character
 1115 | Can't determine mutex size
      |    ^

I would advise to update configure.ac to set force_use_syscfg to yes when threads are not available.

Full build log: http://autobuild.buildroot.org/results/334/3344c96e5627a9327b0eabe0b27f34490bbabc0d/build-end.log

Event Timeline

werner triaged this task as Normal priority.Feb 12 2021, 12:01 PM
werner added a project: gpgrt.
werner added a subscriber: werner.

How does it come that you have a Linux kernel without threads? Or maybe the better question is why does libc not support threads?

Because, threads are optional on uclibc as threads are not supported by all embedded targets.
libgpg-error was building perfectly fine without threads until version 1.40 as all pthread calls were protected by USE_POSIX_THREADS.
Should I understand from your answer that threads are now mandatory?

They are mandatory for gnupg but not for Libgcrypt and Libgpg-error. I guess we can fix that.

Thank you for the report. I had expected *-*-linux* matches only to GNU/Linux (Linux kernel with GNU C library).

I think that the fix would be:

diff --git a/configure.ac b/configure.ac
index b9a2a3e..2031666 100644
--- a/configure.ac
+++ b/configure.ac
@@ -597,7 +597,7 @@ if test "$have_w32_system" = yes; then
 fi
 if test x$cross_compiling = xyes; then
   case $host in
-    *-*-linux*)
+    *-*-linux-gnu*)
     AC_CHECK_TOOL(OBJDUMP, [objdump])
     if test -n "$OBJDUMP"; then
       lock_obj_h_generated=yes

For GNU/Linux, I think that it should fail when pthread is not available for building (for now).
We could still support libgpg-error with no thread support on GNU/Linux by more changes, but ABI name should be different in that case.

This won't work in the context of buildroot as we're passing --host="arm-unknown-linux-gnueabi" to avoid the following build failure:

if test -f lock-obj-pub.native.h; then rm lock-obj-pub.native.h; fi
./mkheader --cross       \
                   arm-buildroot-linux-uclibcgnueabihf  ./gpg-error.h.in \
                   ../config.h 1.41-unknown 0x012900 >gpg-error.h
./gpg-error.h.in:508: error including `./syscfg/lock-obj-pub.linux-uclibcgnueabihf.h': No such file or directory

You can find attached a patch that should fix the build failure by checking if the user didn't provided --disable-threads.
Tell me if you have any comments on it.

I would understand your workaorund of using artifical --host intentionally.

For the fix in the upstream:

if test -f lock-obj-pub.native.h; then rm lock-obj-pub.native.h; fi
./mkheader --cross       \
                   arm-buildroot-linux-uclibcgnueabihf  ./gpg-error.h.in \
                   ../config.h 1.41-unknown 0x012900 >gpg-error.h
./gpg-error.h.in:508: error including `./syscfg/lock-obj-pub.linux-uclibcgnueabihf.h': No such file or directory

This error is relevant because there is no syscfg/lock-obj-pub.linux-uclibcgnueabihf.h in libgpg-error.
Correct fix is put
syscfg/lock-obj-pub.linux-uclibcgnueabihf.h in libgpg-error.

Please note that the result with --host="arm-unknown-linux-gnueabi" for linux-uclibcgnueabih machine is different to the one of correctly generated version by gen-posix-lock-obj.c with USE_POSIX_THREADS undefined on the host.

I was not the author of the host "hacking" which has been committed to buildroot in 2016 by https://git.buildroot.net/buildroot/commit/package/?id=2f89476ad98b82ea9f914337b0050c4808082c82 so I can't really comment on it.
You can find more information here: https://patchwork.ozlabs.org/project/buildroot/patch/1451762923-15985-1-git-send-email-joerg.krause@embedded.rocks/
Especially, it seems that Jörg Krause started a discussion about this issue and proposed a patch to fix the architecture depends but it was never applied. Unfortunately, I wasn't able to find more information as it seems that links on comments.gmane.org are broken ...

Independently of the host "issue", do you think that my patch is acceptable and could be merged?

Thank you for more information.

Independently of the host "issue", do you think that my patch is acceptable and could be merged?

You can use the patch as local patch of your project, for a while. I think that it's better to proceed to better solution.

We identified the issue of uClibc (no POSIX thread) support. In this tickets, there are two sub-issues to fix:
(1) uClibc machine misidentified as GNU/Linux
(2) Supporting uClibc machine without fake host of GNU/Linux

I'd like to proceed to fix the issue of (2).

Sorry, I was assuming uClibc were not supporting POSIX threads.

Tell us the architecture(s) which doesn't support POSIX threads by uClibc.
Adding support for such an architecture would be the best.

When building with no threads support, I think that generating same lock-obj-pub-$host.h is just possible by this change.

diff --git a/configure.ac b/configure.ac
index b9a2a3e..7ec21b6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -595,9 +595,15 @@ if test "$have_w32_system" = yes; then
     fi
     force_use_syscfg=yes
 fi
-if test x$cross_compiling = xyes; then
+if test x"$gl_use_threads" = xno; then
+  lock_obj_h_generated=yes
+  if test ! -d src; then mkdir src; fi
+  host=$host $srcdir/src/gen-lock-obj.sh --disable-threads \
+    >src/lock-obj-pub.native.h
+  AC_MSG_NOTICE([generated src/lock-obj-pub.native.h for $host])
+elif test x$cross_compiling = xyes; then
   case $host in
-    *-*-linux*)
+    *-*-linux-gnu*)
     AC_CHECK_TOOL(OBJDUMP, [objdump])
     if test -n "$OBJDUMP"; then
       lock_obj_h_generated=yes
diff --git a/src/gen-lock-obj.sh b/src/gen-lock-obj.sh
index 8536aed..a710f0c 100755
--- a/src/gen-lock-obj.sh
+++ b/src/gen-lock-obj.sh
@@ -2,7 +2,7 @@
 #
 # gen-lock-obj.sh - Build tool to construct the lock object.
 #
-# Copyright (C) 2020 g10 Code GmbH
+# Copyright (C) 2020, 2021  g10 Code GmbH
 #
 # This file is part of libgpg-error.
 #
@@ -46,6 +46,21 @@ else
     ECHO_N='-n'
 fi
 
+if test "$1" = --disable-threads; then
+    cat <<EOF
+## lock-obj-pub.$host.h - NO LOCK SUPPORT
+## File created by gen-lock-obj.sh - DO NOT EDIT
+## To be included by mkheader into gpg-error.h
+
+/* Dummy object - no locking available.  */
+typedef struct
+{
+  long _vers;
+} gpgrt_lock_t;
+
+#define GPGRT_LOCK_INITIALIZER {-1}
+EOF
+else
 AWK_VERSION_OUTPUT=$($AWK 'BEGIN { print PROCINFO["version"] }')
 if test -n "$AWK_VERSION_OUTPUT"; then
     # It's GNU awk, which supports PROCINFO.
@@ -106,6 +121,7 @@ while test "$i" -lt $ac_mtx_size; do
     fi
     i=$(( i + 1 ))
 done
+fi
 
 cat <<'EOF'
 }}}
gniibe changed the task status from Open to Testing.Feb 18 2021, 2:24 AM

Pushed the change. Please test.