CMake:手动设置MPI标头和二进制文件的路径

时间:2016-03-18 18:16:36

标签: c++ cmake mpi

我正在开发一个MPI应用程序,它需要运行MPI的特定实现(让我们称之为MPIvA)。在我的工作站上,安装了MPI的另一个实现(让它称之为MPIvB)。

我的应用程序是使用CMake构建的,find_library(MPI)显然指向MPIvB。它编译和运行没有麻烦。

我在工作站上编译了MPIvA。如何让CMake使用这些标题和二进制文件?

5 个答案:

答案 0 :(得分:5)

CMake附带一个FindMPI模块,可以为您完成所有繁重的工作。

在您的CMakeLists.txt中,请使用find_library(MPI),而不是调用find_package

#### MPI
find_package(MPI REQUIRED)
if (MPI_FOUND)
    include_directories(SYSTEM ${MPI_INCLUDE_PATH})
else (MPI_FOUND)
    message(SEND_ERROR "This application cannot compile without MPI")
endif (MPI_FOUND)

然后,无论您将应用程序链接到哪里,都会链接到${MPI_LIBRARIES}

target_link_libraries(example-app ${MPI_LIBRARIES})

现在,cmake将自动在您的系统中找到 MPI实现。如果您有多个不同的MPI版本,并且想要指定要编译的版本,可以将MPI_C_COMPILERMPI_CXX_COMPILER变量设置为相应的mpiccmpicxx编译器包装器。然后,CMake模块将使用它们来确定所有必需的编译器和链接器标志本身。

示例:

cmake -DMPI_C_COMPILER=/usr/share/mvapich/bin/mpicc your-project-dir

要确保cmake使用正确的MPI,请从新的空构建目录开始。

有关FindMPI模块的更多信息,请访问:https://cmake.org/cmake/help/v3.0/module/FindMPI.html

答案 1 :(得分:1)

为了在工作站上针对MPIvA进行编译,您需要先使用CMake查找这些标头和二进制文件。以下链接介绍了CMake的find_library搜索顺序的工作原理:https://cmake.org/cmake/help/v3.0/command/find_library.html

我建议将MPIvA添加到CMAKE_LIBRARY_PATH。有关示例,请参阅以下问题的最佳答案: How do I instruct CMake to look for libraries installed by MacPorts?

答案 2 :(得分:0)

内置的cmake会经常干扰你想要的库,特别是如果你使用不同的集群,因为通常默认的编译器不是你可能需要的最新版本,解决这个问题的方法是拥有你自己的FindMYMPI.cmake并采取控制。 否则,命令行选项或使用ccmake GUI更改它也是上述答案中提供的可能性。

答案 3 :(得分:0)

在这种情况下,我成功使用了以下环境变量:

export MPI_HOME=/your/path/to/prefix

请使用cmake在之前进行设置,或清空构建目录。

答案 4 :(得分:0)

好吧,这不是新文章,但将来可能对其他人有用。

即使前面的答案也可以,但我认为更好的方法是使用 CMAKE_PREFIX_PATH 选项,例如

CMAKE_PREFIX_PATH=~/my-libs-install-path ccmake ..

现在,其他一些评论:

  1. 所有MPI库都应该可互换,即使用MPI规范的代码应编译并与任何MPI实现一起运行(例如,我假设是intelmpi,openmpi或mpich的MPIvA和MPIvB)。

  2. 关于这个答案(我的名声不允许我发表评论,所以我在这里回复):

find_package(MPI REQUIRED)
if (MPI_FOUND)
    include_directories(SYSTEM ${MPI_INCLUDE_PATH})
else (MPI_FOUND)
    message(SEND_ERROR "This application cannot compile without MPI")
endif (MPI_FOUND)

即使该功能大部分与预期的一样,但以下功能等效:

find_package(MPI REQUIRED)
include_directories(SYSTEM ${MPI_INCLUDE_PATH})

findpackage(需要MPI)命令中的 REQUIRED 部分将导致该命令在未找到MPI的情况下失败,因此 if(MPI_FOUND)< / strong>部分没有用,else子句实际上永远不会执行。

  1. 最后,关于 include_directories 命令,如果您使用目标(例如

    ),则在我的测试中不需要

    target_link_libraries(my_app PUBLIC MPI :: C)

足够了。