6

I am adding some pthreads code into my Linux application that I'm building with autotools. I was getting an error about not linking in libpthreads. So I want to specify the pthreads dependency and compiler/linker flags in autotools.

I found some references that say use an ACX_PTHREAD macro. GNU provides an AX_PTHREAD macro. Both are very similar in concept. But I've tried both (on Ubuntu 13.04 64-bit), and found that they set -pthread in $PTHREAD_CFLAGS, but for some reason they don't set the -lpthread linker flag in $PTHREAD_LIBS.

The build fails. When I run make, I get:

...
/bin/sh ../libtool --tag=CXX   --mode=link g++  -g -O2   -o myapp main.o ... -lconfuse   -llog4cpp -lnsl   -lpopt   -lfuse    -L/usr/local/lib -lrt 
libtool: link: g++ -g -O2 -o .libs/myapp main.o ...  -lconfuse -llog4cpp -lnsl /usr/lib/x86_64-linux-gnu/libpopt.so -lfuse -L/usr/local/lib -lrt
/usr/bin/ld: app-fuse.o: undefined reference to symbol 'pthread_kill@@GLIBC_2.2.5'
/usr/bin/ld: note: 'pthread_kill@@GLIBC_2.2.5' is defined in DSO /lib/x86_64-linux-gnu/libpthread.so.0 so try adding it to the linker command line
/lib/x86_64-linux-gnu/libpthread.so.0: could not read symbols: Invalid operation
collect2: error: ld returned 1 exit status
...

In this case, the ./configure step shows:

...
checking for the pthreads library -lpthreads... no
checking whether pthreads work without any flags... no
checking whether pthreads work with -Kthread... no
checking whether pthreads work with -kthread... no
checking for the pthreads library -llthread... no
checking whether pthreads work with -pthread... yes
checking for joinable pthread attribute... PTHREAD_CREATE_JOINABLE
checking if more special flags are required for pthreads... no
checking for PTHREAD_PRIO_INHERIT... yes
...

I notice it checks for -lpthreads, but shouldn't it be checking for -lpthread?

I've found that I can use:

AC_CHECK_LIB(pthread, pthread_create, [PTHREAD_LIBS+=-lpthread])

and then the build succeeds. But I assume this isn't the best way to make it work on the widest variety of platforms.

I see Ubuntu also has a package libpthread-stubs0-dev. But I'm not sure what it's for.

What is the "right way" to use pthreads with autotools?

Craig McQueen
  • 41,871
  • 30
  • 130
  • 181

5 Answers5

4

Thanks to Peter Simons who asked on the autoconf mailing list, we have a somewhat official answer:

Compiler flags and linker flags are not mutually-exclusive sets, not least because linking is typically done via the compiler frontend (cc) and not by invoking the linker (ld) directly. Any flags that you can use in the compile step (e.g. -O2, -DFOO, -I/tmp/include) will generally be accepted in the linking step, even if it's not applicable then. (The reverse may not be true, e.g. -lfoo.)

Given that, it's a lot less error-prone to use PTHREAD_CFLAGS (and other CFLAGS variables) when linking, rather than duplicating the applicable flags into PTHREAD_LIBS/LDFLAGS/etc. variables and not using any CFLAGS variables then.

So just use PTHREAD_CFLAGS for your linker, too.

usr1234567
  • 21,601
  • 16
  • 108
  • 128
  • 1
    *"So just use `PTHREAD_CFLAGS`..."* - This is a C++ library; he should not be using `CFLAGS`. He should be usign `CXXFLAGS` instead. – jww Nov 03 '17 at 20:50
1

I bumped into this same issue when I added a first C++ source to an otherwise working C project (a shared library). Adding this C++ file caused libtool to switch from linking with gcc to linking with g++. Seems that linking with gcc a '-pthread' is enough to add the dynamic dependency to libpthread, but when linking with g++, it is not.

I tried with the above patch to a local ax_pthread.m4, but this didn't help. Passing '-lpthread' to g++ would fix the issue.

Edit: for some reason, ax_pthread.m4 forces C as the test language even if the AC_LANG is set as C++. This patch makes things work for me:

--- m4/ax_pthread.m4_orig   2013-06-15 20:03:36.000000000 +0300
+++ m4/ax_pthread.m4    2013-06-15 20:03:51.000000000 +0300
@@ -87,7 +87,6 @@
 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
 AC_DEFUN([AX_PTHREAD], [
 AC_REQUIRE([AC_CANONICAL_HOST])
-AC_LANG_PUSH([C])
 ax_pthread_ok=no

 # We used to check for pthread.h first, but this fails if pthread.h
@@ -313,5 +312,4 @@
         ax_pthread_ok=no
         $2
fi
-AC_LANG_POP
 ])dnl AX_PTHREAD
user2365669
  • 145
  • 1
  • 5
  • *"Edit: for some reason, ax_pthread.m4 forces C as the test language even if the AC_LANG is set as C++...."* - I hope you filed a bug. Dealing with Autotools and its penchant for ignoring our C++ settings is getting old rather quickly. – jww Nov 03 '17 at 21:04
0

It seems that the AX_PTHREAD macro is finding the -pthread compiler flag, and using that. But it looks as though for that particular flag, it should be specified to the linker as well (it apparently does the equivalent of -lpthread in the linker). I modified the macro as follows, so that the -pthread flag is specified as a linker flag too:

diff --git a/m4/ax_pthread.m4 b/m4/ax_pthread.m4
index 6d400ed..f426654 100644
--- a/m4/ax_pthread.m4
+++ b/m4/ax_pthread.m4
@@ -172,6 +172,12 @@ for flag in $ax_pthread_flags; do
                 AC_MSG_CHECKING([whether pthreads work without any flags])
                 ;;

+                -pthread)
+                AC_MSG_CHECKING([whether pthreads work with $flag])
+                PTHREAD_CFLAGS="$flag"
+                PTHREAD_LIBS="$flag"
+                ;;
+
                 -*)
                 AC_MSG_CHECKING([whether pthreads work with $flag])
                 PTHREAD_CFLAGS="$flag"

I guess I should submit this to the macro authors.

Craig McQueen
  • 41,871
  • 30
  • 130
  • 181
0

Expanding on a suggestion above (https://stackoverflow.com/a/20253318/221802) with exact script, this error went away for me after updating my PKbuild.sh script with pthread args:

./bootstrap && \
    CPPFLAGS=" -g3 -Wall -pthread "\
    CFLAGS=" -pthread -g3 -Wall "\
    LDFLAGS=" -lpthread "\
    ./configure --enable-maintainer-mode \
        --enable-debug \
        --prefix=/usr \
        --mandir=/usr/share/man \
        --enable-pie           \
    --prefix=/usr          \
    --enable-library       \
    --enable-test          \
    ......... [and so on]
Community
  • 1
  • 1
peter karasev
  • 2,578
  • 1
  • 28
  • 38
0

I used the advice from another post: autoconf with -pthread

Here they mentioned you could download this file:

http://svn.sleuthkit.org/repos/sleuthkit/trunk/configure.ac

Place it into your m4 directory.

Then include this in your configure.ac:

ACX_PTHREAD

Finally, add this to your Makefile.am:

bin_PROGRAMS = main

main_SOURCES = main.c
main_CFLAGS = $(PTHREAD_CFLAGS)
main_LDADD = $(PTHREAD_LIBS)