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

使用CMake+make从Fortran构建Python模块无报错但导入失败

解决方案

针对你遇到的f2py wrapper文件无法提前作为CMake源文件的问题,以下是几个可行的解决思路,核心是让CMake识别到wrapper文件是构建阶段生成的,并自动处理生成与编译的依赖顺序:

方法1:自定义生成命令+标记生成文件

通过add_custom_command指定wrapper文件的生成逻辑,同时用set_source_files_properties标记该文件为构建时生成,避免CMake在配置阶段检查文件是否存在。

示例CMake代码:

# 定义原始Fortran源文件
set(FORTRAN_SOURCES foo.f90)
# 定义生成的wrapper文件名
set(GENERATED_WRAPPER foo-f2pywrappers2.f90)

# 标记wrapper文件为GENERATED,告知CMake该文件由构建过程生成
set_source_files_properties(${GENERATED_WRAPPER} PROPERTIES GENERATED TRUE)

# 自定义命令:调用f2py生成wrapper文件,依赖原始Fortran文件
add_custom_command(
  OUTPUT ${GENERATED_WRAPPER}
  # 先生成签名文件,再编译生成wrapper(可根据f2py实际行为调整命令)
  COMMAND ${Python_EXECUTABLE} -m numpy.f2py -m foo --f90exec=${CMAKE_Fortran_COMPILER} ${FORTRAN_SOURCES} -h foo.pyf --overwrite-signature
  COMMAND ${Python_EXECUTABLE} -m numpy.f2py --f90exec=${CMAKE_Fortran_COMPILER} -c foo.pyf ${FORTRAN_SOURCES}
  DEPENDS ${FORTRAN_SOURCES}
  # 指定工作目录为构建目录,避免污染源码目录
  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)

# 构建Python模块,包含原始文件和生成的wrapper
python_add_library(foo MODULE
  ${FORTRAN_SOURCES}
  ${GENERATED_WRAPPER}
  WITH_SOABI
)

# 链接NumPy依赖
target_link_libraries(foo PRIVATE NumPy::NumPy)

方法2:直接让f2py生成完整编译所需文件并关联目标

如果不想手动拆分f2py命令,可以调整调用方式,让f2py生成所有必要的wrapper文件,并通过CMake的依赖机制确保这些文件在编译前生成:

set(FORTRAN_SOURCES foo.f90)
set(MODULE_NAME foo)

# 自定义命令生成所有f2py相关文件(包括wrapper)
add_custom_command(
  OUTPUT ${MODULE_NAME}${PYTHON_EXTENSION_SUFFIX}
  COMMAND ${Python_EXECUTABLE} -m numpy.f2py -m ${MODULE_NAME} -c ${FORTRAN_SOURCES} --f90exec=${CMAKE_Fortran_COMPILER}
  DEPENDS ${FORTRAN_SOURCES}
  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)

# 添加自定义目标来触发生成
add_custom_target(foo_module ALL DEPENDS ${MODULE_NAME}${PYTHON_EXTENSION_SUFFIX})

这种方式直接让f2py生成最终的.so模块,CMake负责触发这个生成过程,适合简单场景。

关键注意事项

  • 确保Python_EXECUTABLE和NumPy::NumPy在CMake中正确找到,可通过find_package(Python REQUIRED COMPONENTS Interpreter Development)和find_package(NumPy REQUIRED)来配置。
  • 工作目录尽量指定为CMAKE_CURRENT_BINARY_DIR,避免在源码目录生成临时文件,保持源码干净。
  • 如果需要指定Fortran编译器选项,可在--f90exec后添加--f90flags="-O2"这类参数调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 19:32:43