6

我正在使用 autotools 构建的 Linux 应用程序中添加一些 pthreads 代码。我收到关于未在 libpthreads 中链接的错误。所以我想在 autotools 中指定 pthreads 依赖项和编译器/链接器标志。

我发现一些引用说使用ACX_PTHREAD。GNU 提供了一个AX_PTHREAD. 两者在概念上非常相似。但我都尝试过(在 Ubuntu 13.04 64 位上),发现它们设置-pthread$PTHREAD_CFLAGS,但由于某种原因,他们没有-lpthread$PTHREAD_LIBS.

构建失败。当我运行时make,我得到:

...
/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
...

在这种情况下,./configure步骤显示:

...
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
...

我注意到它会检查-lpthreads,但它不应该检查-lpthread吗?

我发现我可以使用:

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

然后构建成功。但我认为这不是让它在最广泛的平台上工作的最佳方式。

我看到 Ubuntu 也有一个libpthread-stubs0-dev。但我不确定它的用途。

将 pthread 与 autotools 一起使用的“正确方法”是什么?

4

5 回答 5

4

感谢在 autoconf 邮件列表中提问的 Peter Simons,我们得到了一个有点官方的回答

编译器标志和链接器标志不是互斥的集合,尤其是因为链接通常是通过编译器前端 (cc) 而不是通过直接调用链接器 (ld) 来完成的。您可以在编译步骤中使用的任何标志(例如 -O2、-DFOO、-I/tmp/include)通常会在链接步骤中被接受,即使它当时不适用。(反之亦然,例如 -lfoo。)

鉴于此,在链接时使用 PTHREAD_CFLAGS(和其他 CFLAGS 变量)比将适用的标志复制到 PTHREAD_LIBS/LDFLAGS/等中更不容易出错。变量,然后不使用任何 CFLAGS 变量。

因此,也只需将 PTHREAD_CFLAGS 用于您的链接器。

于 2013-11-27T21:22:40.280 回答
1

当我将第一个 C++ 源代码添加到其他工作的 C 项目(共享库)时,我遇到了同样的问题。添加此 C++ 文件导致 libtool 从与 gcc 链接切换到与 g++ 链接。似乎与 gcc 链接一个“-pthread”足以将动态依赖项添加到 libpthread,但是当与 g++ 链接时,它不是。

我尝试将上述补丁安装到本地 ax_pthread.m4,但这没有帮助。将“-lpthread”传递给 g++ 可以解决问题。

编辑:出于某种原因, ax_pthread.m4 强制 C 作为测试语言,即使 AC_LANG 设置为 C++。这个补丁使事情对我有用:

--- 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
于 2013-06-13T19:57:57.100 回答
0

似乎AX_PTHREAD宏正在查找-pthread编译器标志并使用它。但它看起来好像对于那个特定的标志,它也应该被指定给链接器(它显然-lpthread在链接器中相当于)。我将宏修改如下,以便将该-pthread标志也指定为链接器标志:

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"

我想我应该将此提交给宏作者。

于 2013-06-12T02:14:24.467 回答
0

使用确切的脚本扩展上面的建议(https://stackoverflow.com/a/20253318/221802),在使用 pthread args 更新我的 PKbuild.sh 脚本后,这个错误对我来说消失了:

./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]
于 2015-09-11T15:52:39.207 回答
0

我使用了另一篇文章的建议:autoconf with -pthread

他们在这里提到您可以下载此文件:

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

将其放入您的 m4 目录中。

然后将其包含在您的 configure.ac 中:

ACX_PTHREAD

最后,将其添加到您的 Makefile.am 中:

bin_PROGRAMS = main

main_SOURCES = main.c
main_CFLAGS = $(PTHREAD_CFLAGS)
main_LDADD = $(PTHREAD_LIBS)
于 2017-11-02T20:54:22.607 回答