使用 cmake 构建错误:找不到 -lpthreads

Building error using cmake: cannot find -lpthreads

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

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

Determining if the function pthread_create exists in the pthreads failed with the following output: ... /usr/bin/ld: cannot find -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)

我将不胜感激一些帮助,因为我已经缺乏下一步尝试的想法。

编辑 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 

编辑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

如果这不起作用,您可能需要 libc6-dev 中的 pthread 的开发版本。您可以在 http://packages.ubuntu.com/.

中搜索 libpthread.so 的包裹内容

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

编辑 2

使用以下内容和 运行 cmake.

创建一个简单的 CMakeLists.txt
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 

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

在您的 CMakeLists.txt 文件中查找 "thread" 并暂时将其删除。

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

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

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

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

在 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:找不到 -lpthreads”

在 ubuntu 18.04 我解决如下。

$ sudo apt-get install libboost-all-dev

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

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

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

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

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

解决方案:从top开始查看日志,找出配置检查的部分,找到 last configure check 在 CMake 识别故障并转储其日志的位置之前。您也可以尝试搜索文本“Configuring incomplete, errors occurred!

通常您会在那里找到非常准确的实际错误消息,或者至少您会找到最后调用的宏或函数的名称/路径,这使您可以查明实​​际出错的地方。

我发现是什么导致了我的问题。我最初是用 cmake2 做的,但项目需要 cmake3。我将它更改为 cmake3,但它没有进行干净的构建,所以一些剩余的垃圾把一切都搞砸了。当我清理所有内容并使用 cmake3 时,它起作用了。

我也遇到了这个问题。完全相同的情况:在 /lib/x86... 下有 pthread 库,但是 find_package() 总是给出“找不到 lpthread 错误”。 经过我的朋友的检查和咨询,我们发现在我的情况下,我从源代码构建 cmake 并让 cmake link 搜索路径是错误的。因此,我们通过添加 apt 源并使用 apt get install 以“正确”的方式卸载 self-buid 版本并重新安装 cmake。那解决了我的问题。希望对遇到同样情况的小伙伴们有所帮助。