将串行 HDF5 C++ 与 CMake 结合使用
Using serial HDF5 C++ with CMake
我想在使用 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) 升级之前一直有效。
现在我在 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 的版本没有改变,但新版本似乎需要 linking 反对 CMake 不会自动告诉 me/does 的 MPI。
我错过了什么吗? CMake FindHDF5 模块是否存在缺陷,或者我是否需要在设置 HDF5_IS_PARALLEL
时手动针对 MPI link?怎么可能,我现在需要 link MY 针对 mpi 的应用程序?
我做了一些检查:
- 两个 hdf5 库上的 ldd 显示 libmpi
- 我的应用程序在两个系统上都没有
-lmpi
- 两者均使用 HDF5 1.10.1,均基于 OpenMPI 2.1.2 和 GCC 6.4.0
mpicxx -show
显示不同的输出:新的包含 -lmpi_cxx
,旧的不包含
h5c++ -show
好像是一样的(当然还有一些其他的路径)
TL&DR:当 HDF_IS_PARALLEL
为真时,即使不使用它,也需要 link 对抗 MPI。
HDF5 编译器包装器调用 MPI 编译器包装器,它会自动添加该包装器,但 CMake 模块不遵循此路径。进一步阅读我如何发现可能有助于解决类似问题的内容。
我通过将调用的编译器命令隔离到最低限度找到了解决方案。使用 grep
我在 cpp 源文件的 object 文件中找到了对 MPI_*
的引用。这消除了与库 linked 相关的可能性,因此只有包含的差异是可能的。我将新旧 HDF5 包含目录与 diff -qr
进行了比较,发现它们是相同的。
确定它是 headers 我检查了预处理文件 (g++ -E
)。经过一些额外的步骤后,我将新旧系统与 vimdiff
进行了比较(替换的 header 包括从旧系统更改为新系统以将混乱降至最低的路径)搜索 mpi
我发现唯一的区别是包含 mpi_cxx。这是由 mpi.h
完成的,从预处理的输出中也很容易看到。
检查两个系统上的 MPI 安装确认,新的是用 mpi_cxx 支持构建的(MPI 的 C++ 绑定在 MPI2 中添加并在 MPI3 中删除,但看起来仍然可选)和旧的没有。
由于 C headers 只有声明,源代码中没有引用,但 C++ 绑定有定义。这导致引用落在 object 文件中,后来在 linking 期间无法解析。
四处搜索,我发现 "Parallel HDF5 IO requires MPI" 但与 CMake 无关。 https://www.hdfgroup.org/HDF5/release/cmakebuild.html 对此也很少提及,没有提及 HDF5_IS_PARALLEL
(他们确实提到他们不提供该查找模块)。
鉴于此,我最终添加了一个接口目标,从 hdf5 设置包含和库,检查 HDF_IS_PARALLEL
并将 mpi 包含和库添加到该目标。
我想在使用 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) 升级之前一直有效。 现在我在 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 的版本没有改变,但新版本似乎需要 linking 反对 CMake 不会自动告诉 me/does 的 MPI。
我错过了什么吗? CMake FindHDF5 模块是否存在缺陷,或者我是否需要在设置 HDF5_IS_PARALLEL
时手动针对 MPI link?怎么可能,我现在需要 link MY 针对 mpi 的应用程序?
我做了一些检查:
- 两个 hdf5 库上的 ldd 显示 libmpi
- 我的应用程序在两个系统上都没有
-lmpi
- 两者均使用 HDF5 1.10.1,均基于 OpenMPI 2.1.2 和 GCC 6.4.0
mpicxx -show
显示不同的输出:新的包含-lmpi_cxx
,旧的不包含h5c++ -show
好像是一样的(当然还有一些其他的路径)
TL&DR:当 HDF_IS_PARALLEL
为真时,即使不使用它,也需要 link 对抗 MPI。
HDF5 编译器包装器调用 MPI 编译器包装器,它会自动添加该包装器,但 CMake 模块不遵循此路径。进一步阅读我如何发现可能有助于解决类似问题的内容。
我通过将调用的编译器命令隔离到最低限度找到了解决方案。使用 grep
我在 cpp 源文件的 object 文件中找到了对 MPI_*
的引用。这消除了与库 linked 相关的可能性,因此只有包含的差异是可能的。我将新旧 HDF5 包含目录与 diff -qr
进行了比较,发现它们是相同的。
确定它是 headers 我检查了预处理文件 (g++ -E
)。经过一些额外的步骤后,我将新旧系统与 vimdiff
进行了比较(替换的 header 包括从旧系统更改为新系统以将混乱降至最低的路径)搜索 mpi
我发现唯一的区别是包含 mpi_cxx。这是由 mpi.h
完成的,从预处理的输出中也很容易看到。
检查两个系统上的 MPI 安装确认,新的是用 mpi_cxx 支持构建的(MPI 的 C++ 绑定在 MPI2 中添加并在 MPI3 中删除,但看起来仍然可选)和旧的没有。
由于 C headers 只有声明,源代码中没有引用,但 C++ 绑定有定义。这导致引用落在 object 文件中,后来在 linking 期间无法解析。
四处搜索,我发现 "Parallel HDF5 IO requires MPI" 但与 CMake 无关。 https://www.hdfgroup.org/HDF5/release/cmakebuild.html 对此也很少提及,没有提及 HDF5_IS_PARALLEL
(他们确实提到他们不提供该查找模块)。
鉴于此,我最终添加了一个接口目标,从 hdf5 设置包含和库,检查 HDF_IS_PARALLEL
并将 mpi 包含和库添加到该目标。