【问题标题】:Building error using cmake: cannot find -lpthreads使用 cmake 构建错误:找不到 -lpthreads
【发布时间】:2015-11-04 01:51:05
【问题描述】:

我有一个在给定机器上顺利运行的 c++ 项目,现在我正尝试在另一台具有相同操作系统(Xubuntu 14.04)的机器上编译它。

我已经安装了所有依赖项,并且正在使用 cmake 构建项目,尽管它因以下错误而停止:

确定函数 pthread_create 是否存在于 pthread 中失败,输出如下: ... /usr/bin/ld: 找不到 -lpthreads

包含编译器标志的 cmakelists.txt 行如下:

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -lpthread -DNDEBUG -DEIGEN_MPL2_ONLY")
set(CMAKE_C_FLAGS_DEBUG "-g -O0 -Wall -lpthread -DEIGEN_MPL2_ONLY")
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -O3 -lpthread -I/usr/include/freetype2 -DNDEBUG -DEIGEN_MPL2_ONLY")
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -Wall -lpthread -I/usr/include/freetype2 -DEIGEN_MPL2_ONLY")

我已经做了一些研究,并且已经尝试了以下方法:

- 使用 -pthread/-threads/-thread/-lpthreads 而不是 -lpthread,这并不能解决问题,并且会在没有找到以下包的情况下停止构建: find_package (Threads)

  • 在上面的 cmakelists 行中更改了 -lpthread 的顺序,这给出了相同的错误
  • 使用了不同的 gcc/g++ 版本:尝试了 4.4、4.6 和 4.8,没有任何变化
  • 在 /usr/lib/ 中创建了指向 libpthread.so 的符号链接,没有任何更改

我希望能得到一些帮助,因为我已经不知道下一步该尝试什么了。

编辑 1

图书馆应该在哪里:

$ find /lib -name "*pthread*"
/lib/x86_64-linux-gnu/libpthread-2.19.so
/lib/x86_64-linux-gnu/libpthread.so.0

pthread_create 也找到了:

$ nm /lib/x86_64-linux-gnu/libpthread.so.0 | grep "pthread_create"
0000000000008430 t __pthread_create_2_1
00000000000081430 T pthread_create@@GLIBC_2.2.5

我还验证了 libpthread-stubs0libc6-dev 都存在。

编辑 2

这是 FindThreads.cmake 文件内容的一部分,位于 /usr/share/cmake-2.8/Modules/:

if(CMAKE_HAVE_SPROC_H AND NOT CMAKE_THREAD_PREFER_PTHREAD)
  # We have sproc
  set(CMAKE_USE_SPROC_INIT 1)
else()
  # Do we have pthreads?
  CHECK_INCLUDE_FILES("pthread.h" CMAKE_HAVE_PTHREAD_H)
  if(CMAKE_HAVE_PTHREAD_H)

    #
    # We have pthread.h
    # Let's check for the library now.
    #
    set(CMAKE_HAVE_THREADS_LIBRARY)
    if(NOT THREADS_HAVE_PTHREAD_ARG)
      # Check if pthread functions are in normal C library
      CHECK_SYMBOL_EXISTS(pthread_create pthread.h CMAKE_HAVE_LIBC_CREATE)
      if(CMAKE_HAVE_LIBC_CREATE)
        set(CMAKE_THREAD_LIBS_INIT "")
        set(CMAKE_HAVE_THREADS_LIBRARY 1)
        set(Threads_FOUND TRUE)
      endif()

      if(NOT CMAKE_HAVE_THREADS_LIBRARY)
        # Do we have -lpthreads
        CHECK_LIBRARY_EXISTS(pthreads pthread_create "" CMAKE_HAVE_PTHREADS_CREATE)
        if(CMAKE_HAVE_PTHREADS_CREATE)
          set(CMAKE_THREAD_LIBS_INIT "-lpthreads")
          set(CMAKE_HAVE_THREADS_LIBRARY 1)
          set(Threads_FOUND TRUE)
        endif()

        # Ok, how about -lpthread
        CHECK_LIBRARY_EXISTS(pthread pthread_create "" CMAKE_HAVE_PTHREAD_CREATE)
        if(CMAKE_HAVE_PTHREAD_CREATE)
          set(CMAKE_THREAD_LIBS_INIT "-lpthread")
          set(CMAKE_HAVE_THREADS_LIBRARY 1)
          set(Threads_FOUND TRUE)
        endif()

        if(CMAKE_SYSTEM MATCHES "SunOS.*")
          # On sun also check for -lthread
          CHECK_LIBRARY_EXISTS(thread thr_create "" CMAKE_HAVE_THR_CREATE)
          if(CMAKE_HAVE_THR_CREATE)
            set(CMAKE_THREAD_LIBS_INIT "-lthread")
            set(CMAKE_HAVE_THREADS_LIBRARY 1)
            set(Threads_FOUND TRUE)
          endif()
        endif()
      endif()
    endif()

    if(NOT CMAKE_HAVE_THREADS_LIBRARY)
      # If we did not found -lpthread, -lpthread, or -lthread, look for -pthread
      if("THREADS_HAVE_PTHREAD_ARG" MATCHES "^THREADS_HAVE_PTHREAD_ARG")
        message(STATUS "Check if compiler accepts -pthread")
        try_run(THREADS_PTHREAD_ARG THREADS_HAVE_PTHREAD_ARG
          ${CMAKE_BINARY_DIR}
          ${CMAKE_ROOT}/Modules/CheckForPthreads.c
          CMAKE_FLAGS -DLINK_LIBRARIES:STRING=-pthread
          COMPILE_OUTPUT_VARIABLE OUTPUT)

        if(THREADS_HAVE_PTHREAD_ARG)
          if(THREADS_PTHREAD_ARG STREQUAL "2")
            set(Threads_FOUND TRUE)
            message(STATUS "Check if compiler accepts -pthread - yes")
          else()
            message(STATUS "Check if compiler accepts -pthread - no")
            file(APPEND
              ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
              "Determining if compiler accepts -pthread returned ${THREADS_PTHREAD_ARG} instead of 2. The compiler had the following output:\n${OUTPUT}\n\n")
          endif()
        else()
          message(STATUS "Check if compiler accepts -pthread - no")
          file(APPEND
            ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
            "Determining if compiler accepts -pthread failed with the following output:\n${OUTPUT}\n\n")
        endif()

      endif()

      if(THREADS_HAVE_PTHREAD_ARG)
        set(Threads_FOUND TRUE)
        set(CMAKE_THREAD_LIBS_INIT "-pthread")
      endif()

    endif()
  endif()
endif()

编辑 3

使用了一个最小的 Cmakelists.txt 如下:

cmake_minimum_required (VERSION 2.4)
find_package(Threads)

产生以下输出:

-- Looking for include file pthread.h
-- Looking for include file pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - not found.
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE 

【问题讨论】:

  • 可能不相关但不要使用-lpthread。使用-pthread,用于编译和链接。
  • 使用 -pthread 也不能解决问题。
  • 那么,您是否设法以某种方式克服了这个问题?我现在正在面对它......
  • @einpoklum 他做到了,请参阅答案下方的 cmets。遗憾的是,Sapiens 没有提及哪个软件包版本不匹配。
  • 为什么使用-lpthreads而不是-lpthread

标签: c++ linux cmake pthreads


【解决方案1】:

运行 cmake 时出现问题。但是,在这种情况下,cmake 不是问题,错误是无声的,并且 -lpthreads 相关的错误/警告是唯一写入 cmake 错误日志文件的内容,尽管这不会导致任何问题。 我已经完成了 cmakelists.txt 的最小版本并开始逐行测试它,直到找到导致它停止的包:最后我发现它是版本不匹配...

提示:搜索实际的错误信息

通常您会查找最后一条错误消息。但是,在这种情况下,这种(通常有用的)策略会导致误入歧途。

您正在查看的是CMakeCache.txtCMakeOutput.logCMakeError.log为什么会这样? 当配置阶段的某些宏或测试失败时,CMake 会“有帮助地”将这些文件转储到输出中。不幸的是,这些文件可能有数千行长,并且通常包含大量“*** Error: xyz"”条目,用于各种配置检查。“-lpthreads”的那个恰好是日志中的最后一个...

解决方案:从 top 开始浏览日志,确定配置检查的部分,找到最后的配置检查点,CMake 识别故障并转储其日志。您也可以尝试搜索文本“Configuring incomplete, errors occurred!

通常,您会在那里找到非常精确的实际错误消息,或者至少找到最后调用的宏或函数的名称/路径,这样您就可以查明实​​际出了什么问题。

【讨论】:

  • 什么版本?cmake?
  • 这是正确的答案,整个“pthreads”是一条红鲱鱼!我已经扩展了答案并解释了在哪里查找实际错误消息。
  • 这种情况实际上很常见,在处理复杂的构建时。有时,树内宏写得不好,或者试图做一些疯狂的事情来“修复”构建,比如从 github 拉取一个较新的库版本,而不是仅仅通过错误消息彻底失败构建
  • 啊,我明白了,所以它给你一个配置错误,然后告诉你查看日志,这给了一个编译错误。我很困惑为什么会那样做。不过谢谢。
  • 我看不出这个答案如何解决问题。 “通常你会在那里找到一个非常精确的实际错误消息,......”即使可能有几个可能的原因,它也没有描述什么是“非常精确的实际错误消息”以及它是如何解决问题的特殊情况。
【解决方案2】:

在 Ubuntu 18.04.1 LTS 上,此安装为我提供了所需的所有文件:

apt -y install libboost-tools-dev libboost-thread1.62-dev magics++

/usr/lib/x86_64-linux-gnu/libpthread.a
/usr/lib/x86_64-linux-gnu/libpthread.so
/usr/lib/x86_64-linux-gnu/libpthread_nonshared.a

之后没有更多错误“/usr/bin/ld: cannot find -lpthreads”

【讨论】:

  • 在 19.04 编译 aom 时工作。谢谢!
  • 哎哟。这看起来像是一个巧合,而不是实际的问题解决方案。指示的错误消息源于配置检查。 CMake 运行了几十个,这里的失败不是构建失败的原因。在您的情况下,很可能是安装 libboost-threads 改变了一些 CMake 配置检查过程的方式,因此只是 掩盖 问题。
  • 另外请注意,您的推理即使在表面上也是错误的。原始问题中引用的错误消息是“/usr/bin/ld: cannot find -lpthreads”。注意后面的“s”!您无法通过安装libpthread.so 来修复该错误消息。你需要安装一个libpthreads.so !!
  • lchthyo 你当然是对的,这不是推理或实际解决问题的方法,只是 apt -y 的一种方法,可以使用 Ubuntu 完成工作。
【解决方案3】:

编辑1:

以下所有参考资料均适用于 Ubuntu。

名为 libpthread-stubs0 的包可能只是一个存根,因此不会有 pthread_create 函数。

你有这个吗?

$ find /lib -name "*pthread*"
/lib/x86_64-linux-gnu/libpthread-2.15.so
/lib/x86_64-linux-gnu/libpthread.so.0

检查应该存在的符号pthread_create

$ nm /lib/x86_64-linux-gnu/libpthread.so.0 | grep "pthread_create"
0000000000008140 t __pthread_create_2_1
0000000000008140 T pthread_create@@GLIBC_2.2.5

如果这不起作用,您可能需要pthread 的开发版本,它位于libc6-dev 中。您可以在http://packages.ubuntu.com/中搜索包含libpthread.so的包内容。

注意:另外,它在 -lpthreads 上失败。应该改为-lpthread(没有s)吗?

编辑 2

使用以下内容创建一个简单的CMakeLists.txt 并运行cmake

cmake_minimum_required (VERSION 2.8.7)
find_package(Threads)

输出是什么?找到pthread了吗?

我的输出是:

-- Looking for include file pthread.h
-- Looking for include file pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - not found.
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE 

【讨论】:

  • 我将不得不稍后检查 libpthread-stubs0-dev 是否是我安装的确切软件包。虽然你提到的 .a.so 文件已经在我的系统上,在那个确切的位置。为了以防万一,我创建了 .so 到 usr/lib/ 的符号链接,但它没有任何区别。
  • 你能分享 find_package(Threads) 的 CMake 脚本吗?应该有一个 FindThreads.cmake 抛出该错误。
  • CMake 正在寻找 pthread,这意味着 CMake 没有产生错误“确定 pthreads 中是否存在函数 pthread_create 失败,输出如下:... /usr/bin/ld: 找不到 - lpthreads”。是什么产生了错误?请分享试图链接到pthreads 导致错误的CMake 文件。另一种问法是……你在运行cmake或执行make时是否收到错误?
  • 运行 cmake 时出现问题。我已经弄清楚了,该错误是无声的,并且与 -lpthreads 相关的错误是唯一写入 cmake 错误日志文件的内容,尽管这不会导致任何问题。我已经完成了 cmakelists.txt 的最小版本并开始逐行测试它,直到我发现哪个包导致它停止:这是版本不匹配。
  • 在您的“注释”之一上:在 gcc 上是 -pthread,在 clang 上是 -pthreads
【解决方案4】:

这似乎是一个长期存在的 CMake 错误。出现了其他问题,CMake 感到困惑,并报告了这个虚假问题而不是真正的错误。

在您的 CMakeLists.txt 文件中查找“线程”并暂时将其删除。

在我的例子中,这立即确定了一个缺少的库(或者更确切地说,它的开发包)。安装它,将其添加到debian/controlBuild-Depends: 部分,重新​​编译,一切正常。

【讨论】:

  • 不,在我见过的很多情况下,这不是错误。 CMake 确实报告了正确的错误。但不幸的是,它转储了 CMakeError.log,其中还包含所有配置检查。因此:从输出顶部开始搜索,直到找到第一个相关错误
  • 到目前为止,我已经看到三个绝对没有发生的案例。是的,我第二次保存输出并搜索编辑CMakeLists.txt 后出现的错误消息。猜猜在任何地方都找不到什么。
【解决方案5】:

在 ubuntu 18.04 上我解决了如下问题。

$ sudo apt-get install libboost-all-dev

【讨论】:

  • 对我不起作用。 Pthreads 在那里,但我还是得到了这个错误。
【解决方案6】:

我遇到了完全相同的问题,最小的 Cmakelists.txt 给了我相同的输出。 要解决这个问题,只需将 cmake 升级到 lastest version(在我的情况下为 3.15)

【讨论】:

  • 嗯。这是一个相当无用的建议,例如“关闭所有窗口,重新启动,而不是升级系统”。 ;-) 在处理复杂的 cmake 构建时,我经常遇到类似的情况;正确的建议是努力找到实际的错误消息——通常情况下,它就在那里,隐藏在 1000 多行不那么有用的其他输出之间
  • 我的 cmake 是最新版本,这不是我的问题。
【解决方案7】:

我发现了导致我的问题的原因。我最初是用 cmake2 做的,但项目需要 cmake3。我把它改成了 cmake3,但它没有做一个干净的构建,所以一些剩余的垃圾把一切都搞砸了。当我清理所有东西并使用 cmake3 时,它起作用了。

【讨论】:

    【解决方案8】:

    我也遇到了这个问题。完全相同的情况:在 /lib/x86... 下有 pthread lib,但 find_package() 总是给出“找不到 lpthread 错误”。 经过和朋友的一番检查和咨询,我们发现在我的案例中,我是从源代码构建 cmake 并让 cmake 链接搜索路径错误。所以我们卸载自建版本并通过添加apt源并使用apt get install以“正确”的方式重新安装cmake。这解决了我的问题。希望这可以帮助处于相同情况的人。

    【讨论】:

      【解决方案9】:

      请尝试安装一个依赖glibc-static

      在 Ubuntu 上你可以试试apt-get install build-essential

      在其他 linux 上,您可以安装类似于 glibc-static 的软件包。

      【讨论】:

      • 投反对票。这是严重误导和潜在有害的建议。如果某些 CMake 构建确实需要特定的 glibc(如静态)或 pthread,通常会明确指出。然而,在手头的实际案例中,原因是完全不同的,-lpthreads 只是一个红鲱鱼。 请努力找出实际的错误信息
      • 这正是我所需要的,虽然上面的评论者听起来很聪明,但事实证明对于静态构建有不同的包。
      猜你喜欢
      • 1970-01-01
      • 2022-08-07
      • 1970-01-01
      • 1970-01-01
      • 2022-12-04
      • 2015-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多