【问题标题】:autotools for pthreads not setting correct linker flagspthreads 的自动工具未设置正确的链接器标志
【发布时间】:2013-06-07 23:05:31
【问题描述】:

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

我发现some references 说使用ACX_PTHREAD macro。 GNU 提供了一个AX_PTHREAD macro。两者在概念上非常相似。但我都试过了(在 Ubuntu 13.04 64 位上),发现他们在$PTHREAD_CFLAGS 中设置了-pthread,但由于某种原因,他们没有在$PTHREAD_LIBS 中设置-lpthread 链接器标志。

构建失败。当我运行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。但我不确定它是干什么用的。

在 autotools 中使用 pthread 的“正确方法”是什么?

【问题讨论】:

  • ACX_ 宏于 2009 年 8 月 6 日在 GNU Autoconf 存档中重命名为 AX_
  • 我发现 ACX_PTHREAD 在我的系统上使用 -lpthreads 正确的库名称是 -lpthread 没有 S。检查您的 config.log 中的 /usr/bin/ld: 找不到 -lpthreads
  • ax_pthread.m4 文件做对了

标签: pthreads autotools


【解决方案1】:

感谢在 autoconf 邮件列表中提问的 Peter Simons,我们有一个 official answer

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

鉴于此,使用 PTHREAD_CFLAGS(和 其他 CFLAGS 变量)链接时,而不是复制 适用的标志到 PTHREAD_LIBS/LDFLAGS/等。变量而不是 然后使用任何 CFLAGS 变量。

所以也只需将 PTHREAD_CFLAGS 用于您的链接器。

【讨论】:

  • "所以只要使用PTHREAD_CFLAGS..." - 这是一个 C++ 库;他不应该使用CFLAGS。他应该改用CXXFLAGS
【解决方案2】:

当我将第一个 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

【讨论】:

  • “编辑:出于某种原因,ax_pthread.m4 强制 C 作为测试语言,即使 AC_LANG 设置为 C++....” - 我希望你提交了一个漏洞。处理 Autotools 及其忽略我们的 C++ 设置的习惯很快就会过时。
【解决方案3】:

似乎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"

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

【讨论】:

    【解决方案4】:

    使用确切的脚本扩展上述建议 (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]
    

    【讨论】:

      【解决方案5】:

      我使用了另一个帖子的建议: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)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-03-04
        • 2016-02-25
        • 1970-01-01
        • 2017-08-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-03
        相关资源
        最近更新 更多