将串行HDF5 C ++与CMake一起使用 [英] Using serial HDF5 C++ with CMake

查看:229
本文介绍了将串行HDF5 C ++与CMake一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在带有CMake的项目中使用HDF5 C ++绑定。所以我照常做:

I want to use the HDF5 C++ bindings in a project build with CMake. So I do the usual:

find_package (HDF5 REQUIRED COMPONENTS CXX)
target_link_libraries(foo PUBLIC ${HDF5_LIBRARIES})
target_include_directories(foo PUBLIC ${HDF5_INCLUDE_DIRS})

过去一直工作到集群( HPC)已升级。
现在在链接过程中出现错误:

This used to work till our cluster (HPC) was upgraded. Now I get errors during linking:

function MPI::Win::Set_name(char const*): error: undefined reference to 'MPI_Win_set_name'
function MPI::Win::Set_attr(int, void const*): error: undefined reference to 'MPI_Win_set_attr'

尽管HDF5的版本没有更改,但新版本似乎需要链接到MPI,而CMake不会自动告诉我/不会。

Although the versions of HDF5 did not change, the new one seems to require linking against MPI which CMake does not tell me/does automatically.

我错过了什么吗?设置 HDF5_IS_PARALLEL 时,CMake FindHDF5模块是否存在缺陷或需要我手动链接到MPI?我现在怎么可能需要将 MY 应用程序与MPI链接?

Am I missing anything? Is the CMake FindHDF5 module flawed or am I required to link against MPI manually when HDF5_IS_PARALLEL was set? How is it possible, that I now need to link MY application against mpi?

我做了一些检查:


  • ldd显示libmpi

  • 没有 -lmpi 在我的应用程序的任一系统上

  • 两者均使用HDF5 1.10.1,两者均针对具有GCC 6.4.0的OpenMPI 2.1.2构建

  • mpicxx -show 显示不同的输出:新的包含 -lmpi_cxx ,旧的不包含。

  • h5c ++ -show 似乎是相同的(当然还有其他路径)

  • ldd on both hdf5 libraries shows libmpi
  • there is no -lmpi on either system for my app
  • HDF5 1.10.1 is used on both, both build against OpenMPI 2.1.2 with GCC 6.4.0
  • mpicxx -show shows different output: The new one includes -lmpi_cxx, the old not.
  • h5c++ -show seems to be the same (some other paths of course)

推荐答案

TL& DR:当 HDF_IS_PARALLEL 为true时,即使不使用MPI,也需要链接到MPI。

HDF5编译器包装器调用MPI编译器包装器,该包装器将自动添加该包装器,但CMake模块不遵循此路径。进一步阅读以了解如何发现可能有助于解决类似问题的方法。

TL&DR: When HDF_IS_PARALLEL is true, one needs to link against MPI even when not using it.
The HDF5 compiler wrapper calls the MPI compiler wrapper which would add that automatically but the CMake module does not follow this path. Read further for how I found that which might help for similar issues.

我通过将调用的编译器命令隔离到最低限度来找到解决方案。使用 grep ,我已经在cpp源文件的目标文件中找到对 MPI _ * 的引用。这样就消除了与链接的库建立关系的可能性,因此仅包含中的差异是可能的。我将新旧HDF5包含目录与 diff -qr 进行了比较,发现它们是相同的。

确保这是我检查过的标头预处理文件( g ++ -E )。经过一些额外的步骤(替换标头包含从旧系统更改为新系统的路径,以使混乱降至最低),我将新旧版本与 vimdiff 进行了比较c $ c> mpi 我发现唯一的区别是包含了mpi_cxx。这是通过 mpi.h 完成的,在预处理输出中也很容易看到。

检查两个系统上的MPI安装是否已确认,使用mpi_cxx支持(在MPI2中添加了MPI的C ++绑定,并在MPI3中删除了MPI,但似乎仍然可以选择使用),而旧版本则没有。

I found the solution by isolating the compiler commands invoked to the bare minimum. Using grep I found references to MPI_* already in the object file of the cpp source file. This eliminated the possibility of a relation to the libraries linked, so only differences in includes were possible. I compared the new and old HDF5 include directories with diff -qr and found them to be the same.
Being sure it was the headers I examined the preprocessed files (g++ -E). I compared the new vs old one with vimdiff after some extra steps (replaced header include paths that changed from old to new system to keep the clutter to a minimum) Searching for mpi I found the only difference to be the inclusion of mpi_cxx. This is done by mpi.h which was also easily visible from the preprocessed output.
Checking the MPI installation on both systems confirmed, that new one was build with mpi_cxx support (C++ bindings for MPI added in MPI2 and removed in MPI3, but still optionally available as it seems) and the old one without.

作为C标头只有声明没有引用,但C ++绑定具有定义。这导致引用降落在目标文件中,并在链接期间随后无法解析。

As the C headers only have declarations no references land in the sources but the C++ bindings have definitions. This caused the references to land in the object file and later failed to resolve during linking.

搜索所有我发现的内容是并行HDF5 IO需要MPI,但与CMake。 https://www.hdfgroup.org/HDF5/release/cmakebuild.html对此也很稀疏,没有提到 HDF5_IS_PARALLEL (他们提到他们没有提供该find模块)。

Searching around all I found was "Parallel HDF5 IO requires MPI" but nothing related to CMake. https://www.hdfgroup.org/HDF5/release/cmakebuild.html is also pretty sparse about this and does not mention HDF5_IS_PARALLEL (they do mention that they don't provide that find module).

鉴于此,我最终添加了一个接口目标,从hdf5设置了include和库,检查 HDF_IS_PARALLEL 并将mpi include和库添加到该目标

Given that, I ended up adding an interface target, set the includes and libraries from hdf5, check for HDF_IS_PARALLEL and add the mpi includes and libraries to that target.

这篇关于将串行HDF5 C ++与CMake一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆