You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于MPI::MPI_C别名的使用及参数设置疑问

关于CMake中MPI::MPI_C目标的疑问与解答

背景

我使用CMake 3.20.1构建ScaLAPACK(提交哈希:7e4e07070a489686287c36ab473d21cf29a54bdd),通过find_package(MPI)工具获取MPI编译所需的库、包含目录及编译选项。

两种链接方式出现不同结果:

  1. 使用MPI::MPI_C导入目标链接:
target_link_libraries(scalapack ${LAPACK_LIBRARIES} ${BLAS_LIBRARIES} MPI::MPI_C)

构建并安装的共享库(DSO)带有RUNPATH条目:

$ readelf -d ~/opt/scalapack/lib/libscalapack.so | grep RUNPATH
0x000000000000001d (RUNPATH)            Library runpath: [/opt/apps/resif/aion/2020b/epyc/software/UCX/1.9.0-GCCcore-10.2.0/lib64:/usr/lib64:/opt/apps/resif/aion/2020b/epyc/software/OpenMPI/4.0.5-GCC-10.2.0/lib]
  1. 使用MPI_C_LIBRARIES变量链接:
target_link_libraries(scalapack ${LAPACK_LIBRARIES} ${BLAS_LIBRARIES} ${MPI_C_LIBRARIES})

安装后的DSO无RUNPATH条目。对比CMake生成的Makefile,发现使用MPI::MPI_C时会添加额外的系统选项。

问题

  1. MPI::MPI_C是什么,应如何使用?
  2. 为何该目标会设置大量参数,而非仅配置链接ScaLAPACK DSO与MPI所需的变量?

解答

1. MPI::MPI_C是什么,如何使用?

MPI::MPI_C是CMake通过find_package(MPI)生成的导入目标(Imported Target),属于CMake现代目标导向构建体系的一部分,不是简单的别名。

使用方式非常简洁:直接在target_link_libraries中引用该目标即可,不需要手动处理MPI_C_INCLUDE_DIRS、MPI_C_COMPILE_FLAGS这类零散变量——CMake会自动将该目标关联的包含目录、编译选项、链接库、链接选项等全部传递给你的目标(比如这里的scalapack)。

标准使用流程示例:

find_package(MPI REQUIRED)
add_library(scalapack ...)
# 无需手动添加include目录,链接时自动处理
target_link_libraries(scalapack PRIVATE ${LAPACK_LIBRARIES} ${BLAS_LIBRARIES} MPI::MPI_C)

2. 为何MPI::MPI_C会设置大量参数?

这是因为导入目标MPI::MPI_C封装了MPI库的完整依赖链和构建配置,不止是单纯的链接库:

  • 包含MPI的头文件目录,会自动添加到目标的编译包含路径中;
  • 携带MPI编译所需的预定义宏、编译标志(比如针对特定MPI实现的专属编译选项);
  • 包含MPI库的间接依赖(比如你看到的UCX库路径,这是OpenMPI依赖的底层通信库);
  • 自动处理共享库的运行时路径(RPATH/RUNPATH):CMake会确保你的库在运行时能找到MPI及其依赖库,这就是使用MPI::MPI_C时生成的库带有RUNPATH的原因。而MPI_C_LIBRARIES只是单纯的库文件路径列表,不会传递RPATH相关配置,所以不会生成RUNPATH。

CMake默认在构建阶段会设置RPATH,安装时通常会清理,但部分MPI实现的导入目标会强制保留RUNPATH,或者CMake在处理导入目标的依赖时自动添加了这些路径,以保证运行时的依赖查找正常。

内容的提问来源于stack exchange,提问作者gkaf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 02:52:36