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

scikit-build-core构建Python模块时未正确识别.pyf文件导致Fortran接口输出参数异常的问题排查与解决请求

scikit-build-core构建Python模块时未正确识别.pyf文件导致Fortran接口输出参数异常的问题排查与解决请求

大家好,我正在维护一个Python模块,最近打算从旧的numpy distutils切换到scikit-build-core(工作在change-setup分支),但构建过程遇到了问题,想请社区的朋友们帮忙看看怎么调整我的CMakeLists.txt,让构建能正确识别.pyf文件里的接口定义。

问题详情

我执行以下命令看似能成功安装模块,site-packages目录里也生成了geopack_tsyganenko.cpython-313-darwin.so文件:

git clone https://github.com/johncoxon/tsyganenko
cd tsyganenko
git checkout change-setup
pip install .

但在IPython里导入模块后,发现函数的参数签名不符合预期:

In [1]: import geopack_tsyganenko
In [2]: geopack_tsyganenko.igrf_gsw_08?
Signature: geopack_tsyganenko.igrf_gsw_08(*args, **kwargs)
Type: fortran
String form: <fortran function igrf_gsw_08>
Docstring:
igrf_gsw_08(xgsw,ygsw,zgsw,hxgsw,hygsw,hzgsw)
Wrapper for ``igrf_gsw_08``.

Parameters
----------
xgsw : input float
ygsw : input float
zgsw : input float
hxgsw : input float
hygsw : input float
hzgsw : input float

我的geopack.pyf文件里明明定义了hxgsw、hygsw和hzgsw是输出参数,但现在它们被当成了输入参数,这说明构建过程没有正确读取.pyf的配置。

对比验证(手动f2py命令能正常工作)

如果我手动进入src/tsyganenko目录执行f2py命令:

cd src/tsyganenko
python -m numpy.f2py -c --f77flags="-w" geopack.pyf geopack.f T96.f T02.f -m geopack_tsyganenko --lower

生成.so文件后手动复制到site-packages,再导入模块时,函数签名就完全正确了:

In [1]: import geopack_tsyganenko
In [2]: geopack_tsyganenko.igrf_gsw_08?
Signature: geopack_tsyganenko.igrf_gsw_08(*args, **kwargs)
Type: fortran
String form: <fortran function igrf_gsw_08>
Docstring:
hxgsw,hygsw,hzgsw = igrf_gsw_08(xgsw,ygsw,zgsw)
Wrapper for ``igrf_gsw_08``.

Parameters
----------
xgsw : input float
ygsw : input float
zgsw : input float

Returns
-------
hxgsw : float
hygsw : float
hzgsw : float

当前的CMakeLists.txt内容

我现在使用的CMakeLists.txt如下:

cmake_minimum_required(VERSION 3.17.2...3.29)
project(${SKBUILD_PROJECT_NAME} LANGUAGES C Fortran)

find_package( Python COMPONENTS Interpreter Development.Module NumPy REQUIRED)

set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_Fortran_FLAGS "-w")

# F2PY headers
execute_process(
    COMMAND "${PYTHON_EXECUTABLE}" -c "import numpy.f2py; print(numpy.f2py.get_include())"
    OUTPUT_VARIABLE F2PY_INCLUDE_DIR
    OUTPUT_STRIP_TRAILING_WHITESPACE)

add_library(fortranobject OBJECT "${F2PY_INCLUDE_DIR}/fortranobject.c")
target_link_libraries(fortranobject PUBLIC Python::NumPy)
target_include_directories(fortranobject PUBLIC "${F2PY_INCLUDE_DIR}")
set_property(TARGET fortranobject PROPERTY POSITION_INDEPENDENT_CODE ON)

# Define variables
set(FORTRAN_PYF_FILE ${CMAKE_CURRENT_SOURCE_DIR}/src/tsyganenko/geopack.pyf)
set(FORTRAN_SRC_FILE ${CMAKE_CURRENT_SOURCE_DIR}/src/tsyganenko/geopack.f)
set(FORTRAN_T96_FILE ${CMAKE_CURRENT_SOURCE_DIR}/src/tsyganenko/T96.f)
set(FORTRAN_T02_FILE ${CMAKE_CURRENT_SOURCE_DIR}/src/tsyganenko/T02.f)

set(MODULE_NAME geopack_tsyganenko)
set(F2PY_MODULE ${CMAKE_CURRENT_BINARY_DIR}/${MODULE_NAME}module.c)
set(F2PY_WRAPPERS ${CMAKE_CURRENT_BINARY_DIR}/${MODULE_NAME}-f2pywrappers.f)

add_custom_command(
    OUTPUT ${F2PY_MODULE} ${F2PY_WRAPPERS}
    DEPENDS ${FORTRAN_PYF_FILE} ${FORTRAN_SRC_FILE} ${FORTRAN_T96_FILE} ${FORTRAN_T02_FILE}
    VERBATIM
    COMMAND "${PYTHON_EXECUTABLE}" -m numpy.f2py "${FORTRAN_PYF_FILE}" "${FORTRAN_SRC_FILE}" "${FORTRAN_T96_FILE}" "${FORTRAN_T02_FILE}" -m ${MODULE_NAME} --lower
)

python_add_library(
    geopack_tsyganenko MODULE
    "${F2PY_MODULE}" "${F2PY_WRAPPERS}"
    "${FORTRAN_PYF_FILE}" "${FORTRAN_SRC_FILE}" "${FORTRAN_T96_FILE}" "${FORTRAN_T02_FILE}"
    WITH_SOABI)

target_link_libraries(${MODULE_NAME} PRIVATE fortranobject)

install(TARGETS ${MODULE_NAME} DESTINATION .)

请问我需要修改CMakeLists.txt中的哪部分内容,才能让scikit-build-core的构建过程正确识别geopack.pyf里的输出参数定义,生成和手动执行f2py命令一样正确的Python模块?

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 07:28:03