我在我使用autotools构建的Linux应用程序中添加了一些pthreads代码。我收到一个关于不在libpthreads中链接的错误。所以我想在autotools中指定pthreads依赖项和编译器/链接器标志。
我发现some references表示使用ACX_PTHREAD
macro。 GNU提供AX_PTHREAD
macro。两者在概念上非常相似。但我已尝试过(在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也有一个package libpthread-stubs0-dev
。但我不确定它的用途。
在自动工具中使用pthreads的“正确方法”是什么?
答案 0 :(得分:3)
感谢Peter Simons在autoconf邮件列表中提问,我们有点official answer:
编译器标志和链接器标志不是互斥集,不是 至少是因为链接通常是通过编译器前端(cc)完成的 而不是直接调用链接器(ld)。你能做的任何旗帜 在编译步骤中使用(例如-O2,-DFOO,-I / tmp / include)将 通常在链接步骤中被接受,即使它不适用 然后。 (反之亦然,例如-lfoo。)
鉴于此,使用PTHREAD_CFLAGS(和。)的错误要少得多 其他CFLAGS变量)在链接时,而不是重复 适用的标志到PTHREAD_LIBS / LDFLAGS /等。变量而不是 然后使用任何CFLAGS变量。
所以也可以使用PTHREAD_CFLAGS作为链接器。
答案 1 :(得分:1)
当我将第一个C ++源代码添加到另一个正在运行的C项目(共享库)时,我遇到了同样的问题。添加此C ++文件导致libtool从使用gcc链接切换到使用g ++链接。似乎用gcc链接'-pthread'足以将动态依赖添加到libpthread,但是当与g ++链接时,它不是。
我尝试使用上面的补丁到本地ax_pthread.m4,但这没有帮助。将'-lpthread'传递给g ++可以解决问题。
编辑:由于某种原因,即使AC_LANG设置为C ++,ax_pthread.m4也会强制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
答案 2 :(得分: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"
我想我应该把它提交给宏观作者。
答案 3 :(得分: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]
答案 4 :(得分: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)