在CMake中使用串行HDF5 C ++

时间:2018-07-27 15:23:38

标签: c++ cmake hdf5

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

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

在升级集群(HPC)之前,此方法一直有效。 现在在链接过程中出现错误:

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不会自动告诉我/这样做。

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

我做了一些检查:

    两个hdf5库上的
  • ldd显示libmpi
  • 我的应用程序在两个系统上都没有-lmpi
  • 两者均使用HDF5 1.10.1,两者均针对具有GCC 6.4.0的OpenMPI 2.1.2构建
  • mpicxx -show显示了不同的输出:新的包含-lmpi_cxx,旧的不包含。
  • h5c++ -show似乎是相同的(当然还有其他一些路径)

1 个答案:

答案 0 :(得分:0)

TL&DR:当HDF_IS_PARALLEL为true时,即使不使用MPI,也需要链接到MPI。
HDF5编译器包装器调用MPI编译器包装器,该包装器将自动添加该包装器,但CMake模块不遵循此路径。进一步阅读我如何发现可能会解决类似问题的信息。

我找到了解决方案,方法是将调用的编译器命令隔离到最低限度。使用grep,我已经在cpp源文件的目标文件中找到对MPI_*的引用。这样就消除了与链接的库建立关系的可能性,因此仅包含中的差异是可能的。我将新旧HDF5包含目录与diff -qr进行了比较,发现它们是相同的。
确保是标题,我检查了预处理的文件(g++ -E)。经过一些额外的步骤,我将新旧版本与vimdiff进行了比较(替换后的标头包括从旧系统更改为新系统的路径,以使混乱降至最低)。搜索mpi时,我发现唯一的区别在于包含在mpi_cxx中。这是通过mpi.h完成的,它也可以从预处理输出中轻松看到。
检查两个系统上的MPI安装是否已确认,是否已建立了新的mpi_cxx支持(在MPI2中添加了MPI的C ++绑定,在MPI3中删除了MPI,但看起来仍然可选),而旧版本则没有。

由于C头仅具有声明,因此引用不位于源中,但是C ++绑定具有定义。这导致引用降落在目标文件中,并且以后在链接期间无法解析。

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

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