linux - CMakeLists 无法找到新安装的 HDF5?

标签 linux boost makefile cmake

我正在开发一个在另一台计算机(第一台)上运行的程序,并试图让它在我的新计算机(第三台)上运行。当我转到 build 并键入 ccmake .. 时,出现此错误:

CMake Error at build/share/cmake/hdf5/hdf5-targets.cmake:67 (message):
   The imported target "hdf5" references the file


 "/home/myname/Desktop/MyProject/build/lib/libhdf5.a"

   but this file does not exist.  Possible reasons include:

   * The file was deleted, renamed, or moved to another location.

   * An install or uninstall procedure did not complete successfully.

   * The installation package was faulty and contained


 "/home/myname/Desktop/MyProject/build/share/cmake/hdf5/h
df5-targets.cmake"

   but not all the files it references.

 Call Stack (most recent call first):
   build/share/cmake/hdf5/hdf5-config.cmake:70 (INCLUDE)
   build/share/cmake/hdf5/FindHDF5.cmake:85 (INCLUDE)
   src/Thing/CMakeLists.txt:66 (find_package)

即使我随后使用 sudo apt-get 安装 hdf5,我也遇到了同样的错误

我不得不删除那个 lib 目录,因为它包含过时的 boost 文件并导致了大量错误,这可能是因为我在 usr/中新安装了 boost 文件后发生了冲突libusr/include 在这台新计算机上。通过简单地删除 lib 目录

,我让这个程序在第二台计算机上运行

解决这个问题的方法是更改​​CMakeLists.txt,使其指向新安装的hdf5的目录吗? CMakeLists.txt 看起来像:

CMAKE_MINIMUM_REQUIRED (VERSION 2.6)
PROJECT (Projectname)


# CMake Modules
SET(CMAKE_MODULE_PATH
  ${PROJECT_BINARY_DIR}/share/cmake/hdf5
  ${CMAKE_SOURCE_DIR}/CMake
  ${CMAKE_MODULE_PATH})

SET(ENV{HDF5_ROOT_DIR_HINT} ${PROJECT_BINARY_DIR})

# Build output 
set(LIBRARY_OUTPUT_PATH "${CMAKE_BINARY_DIR}/lib")
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/bin")
mark_as_advanced(LIBRARY_OUTPUT_PATH EXECUTABLE_OUTPUT_PATH)


#other stuff I excluded to keep this brief

此外,即使我删除了 home/myname/Desktop/MyProject/build/liblib 目录中的所有文件,除了 libhdf5.a ,我得到了一堆 boost 错误。这是一个很长的输出,我认为这是因为 makelib 中创建了新的 boost 文件,这些文件最初来自 home/myname/Desktop/MyProject/build/lib,而不是引用 usr/libusr/include

中新安装的 boost 文件

如果有帮助,src/Thing/CMakeLists.txt 的第 66 行看起来像find_package(HDF5 COMPONENTS C CXX)

如有必要,我还可以发布 hdf5-config.cmakeFindHDF5.cmake 的内容

编辑:dpkg -l | greap hdf5 给出

ii  hdf5-helpers                                  1.8.15-patch1+docs-4                       amd64        Hierarchical Data Format 5 (HDF5) - Helper tools
ii  hdf5-tools                                    1.8.15-patch1+docs-4                       amd64        Hierarchical Data Format 5 (HDF5) - Runtime tools
ii  libhdf5-10:amd64                              1.8.15-patch1+docs-4                       amd64        Hierarchical Data Format 5 (HDF5) - runtime files - serial version
ii  libhdf5-cpp-10:amd64                          1.8.15-patch1+docs-4                       amd64        Hierarchical Data Format 5 (HDF5) - C++ libraries
ii  libhdf5-dev                                   1.8.15-patch1+docs-4                       amd64        Hierarchical Data Format 5 (HDF5) - development files - serial version
ii  libhdf5-openmpi-10:amd64                      1.8.15-patch1+docs-4                       amd64        Hierarchical Data Format 5 (HDF5) - runtime files - OpenMPI version
ii  libhdf5-openmpi-dev                           1.8.15-patch1+docs-4                       amd64        Hierarchical Data Format 5 (HDF5) - development files - OpenMPI version
ii  libhdf5-serial-dev                            1.8.15-patch1+docs-4                       all          transitional dummy package

最佳答案

关于在 Linux 上链接第三方库的简短介绍:

一般你应该决定2个方面。

第一个是关于“系统 vs 自定义库”

  1. 您可以将您的应用程序链接到从系统包安装的库(在 Debian 中使用 apt-get)。这是在 Linux 上编译程序的首选方式,除非您有某些理由反对(见下文)。这通常也是最简单的方法,因为所有构建工具都配置为在某些“众所周知”的地方查找库组件。
  2. 链接到库的自定义构建。如果您需要库的一些自定义构建选项,或者需要存储库中不可用的特定版本的库等,请使用此方法。

第二步是在静态库和动态库之间进行选择。

  1. 通常在 Linux 中应用程序链接到动态加载的库 (.so)。这减少了应用程序的大小,可能减少了内存消耗和应用程序加载时间(因为给定应用程序的库已经在内存中),有时还简化了安全修复等小更新 - 只需更新一个库而不是所有使用这个易受攻击的库的应用程序

  2. 但也有缺点 :) 如果您打算将与动态库链接的应用程序分发到其他计算机,您需要确保所需版本的库位于给定的目标计算机。每个库又可以与其他库链接等等。最后,您必须分发操作系统的完整副本,例如Steam for Linux 确实如此:在内部它承载了 Ubuntu 的很大一部分。因此,有时链接到一个静态库并将所需的一切都包含到您的应用程序中可能更明智。

回到实际问题。由于您已经安装了带有 libhdf5 开发文件 (libhdf5-dev) 的系统包,我建议您使用“系统库”(p1.1)。

在这种情况下,您应该从构建树中完全删除库的所有其他副本,并在 CMakeLists.txt 中使用以下代码块:

find_package(HDF5 REQUIRED)
...
include_directories(${HDF5_INCLUDE_DIRS})
...
target_link_libraries(yourapp ${HDF5_LIBRARIES} <other required libs>)

如果您的应用程序是 C++ 应用程序,您可以使用 ${HDF5_CXX_LIBRARIES} 而不是 ${HDF5_LIBRARIES}

如果您决定链接到一个静态库,那么您需要定义一个特殊变量 HDF5_USE_STATIC_LIBRARIES before calling find_package( HDF5...):

 set(HDF5_USE_STATIC_LIBRARIES ON)
 find_package(HDF5 REQUIRED)
 ...

如果您仍然希望使用库的自定义构建,那么您应该 “解释”到 find_package 在哪里寻找库组件。您可以在 HDF5 构建树 中运行 make DESTDIR=/some/path install,然后使用该 /some/path 作为 HDF5_ROOT 在应用程序构建树中运行 cmake 时的环境变量:

  HDF5_ROOT=/some/path cmake .

在这种情况下,CMake 将尝试在该目录中找到 HDF5 组件。我会在此操作之前删除系统包 libhdf5-dev(以防万一)使用 apt-get remove libhdf5-dev

但我再次相信您应该有充分的理由不使用系统 libhdf5 包。

关于linux - CMakeLists 无法找到新安装的 HDF5?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34573387/

相关文章:

c++ - 我怎样才能让 boost::function 不那么宽松?

c++ - boost::shared_array<char> 到 std::string

c++ - sleep boost::thread 无限期地从另一个线程唤醒?

java - java makefile 基础知识

c - utf-8 字符串的最佳哈希是什么

c++ - ubuntu Linux 中的数组复制实际上不起作用

Linux 文件系统自动由磁盘支持但完全托管在内存中?

python - 如何使用 os.posix_fadvise 防止 Linux 上的文件缓存?

makefile - 避免重复 GNU Make 规则

c++ - C++ 项目中的 undefined reference