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

将f2py Python模块从numpy.distutils迁移到scikit-build-core遇阻

Tsyganenko模块迁移至scikit-build-core后导入失败问题解决

原numpy.distutils配置(setup.py)

from numpy.distutils.core import Extension, setup

ext = Extension('geopack',
                sources=['src/tsyganenko/geopack_py.pyf',
                         'src/tsyganenko/geopack_py.f',
                         'src/tsyganenko/T96.f',
                         'src/tsyganenko/T02.f'])

with open("README.md", "r", encoding="utf-8") as f:
    long_description = f.read()

setup(author="John Coxon and Sebastien de Larquier",
      author_email="work@johncoxon.co.uk",
      classifiers=[
          "Development Status :: 4 - Beta",
          "Intended Audience :: Science/Research",
          "Natural Language :: English",
          "Programming Language :: Python/Fortran"
      ],
      description="A wrapper to call GEOPACK routines in Python.",
      ext_modules=[ext],
      install_requires=[
          "numpy",
          "matplotlib",
          "pandas"
      ],
      keywords=['Scientific/Space'],
      long_description=long_description,
      long_description_content_type="text/markdown",
      name="Tsyganenko",
      package_dir={"": "src"},
      packages=setuptools.find_packages(where="src"),
      python_requires=">=3.9",
      url="https://github.com/johncoxon/tsyganenko",
      version="2020.1",
      )

迁移后的scikit-build-core配置

pyproject.toml

[build-system]
requires = ["scikit-build-core", "numpy"]
build-backend = "scikit_build_core.build"

[project]
name = "Tsyganenko"
version = "2020.2"
dependencies = ["numpy"]

[tool.scikit-build]
ninja.version = ">=1.10"
cmake.version = ">=3.17.2"

[tool.setuptools.packages.find]
where = ["src"]

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)

# 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)

add_custom_command(
  OUTPUT geopack_pymodule.c geopack_py-f2pywrappers.f
  DEPENDS src/tsyganenko/geopack_py.f
  VERBATIM
  COMMAND "${Python_EXECUTABLE}" -m numpy.f2py
          "${CMAKE_CURRENT_SOURCE_DIR}/src/tsyganenko/geopack_py.f" -m geopack_py --lower)

python_add_library(
  geopack_py MODULE "${CMAKE_CURRENT_BINARY_DIR}/geopack_pymodule.c"
  "${CMAKE_CURRENT_BINARY_DIR}/geopack_py-f2pywrappers.f"
  "${CMAKE_CURRENT_SOURCE_DIR}/src/tsyganenko/geopack_py.f" WITH_SOABI)
target_link_libraries(geopack_py PRIVATE fortranobject)

install(TARGETS geopack_py DESTINATION .)

导入错误信息

In [1]: import geopack_py
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
Cell In[1], line 1
----> 1 import geopack_py

ImportError: dlopen(/opt/homebrew/Caskroom/mambaforge/base/envs/test/lib/python3.12/site-packages/geopack_py.cpython-312-darwin.so, 0x0002): symbol not found in flat namespace '_t01_01_'

问题原因

错误提示的_t01_01_符号来自T02.f文件,但当前CMake配置未将T96.f和T02.f纳入编译流程,同时未正确使用原setup.py中的geopack_py.pyf接口定义文件,导致F2PY生成的wrapper无法找到依赖的Fortran子程序。

解决方案

1. 修正CMakeLists.txt,纳入所有Fortran源文件并使用pyf接口

修改add_custom_command和python_add_library部分,确保包含geopack_py.pyf、T96.f和T02.f:

# 替换原有add_custom_command
add_custom_command(
  OUTPUT geopack_pymodule.c geopack_py-f2pywrappers.f
  DEPENDS src/tsyganenko/geopack_py.pyf
          src/tsyganenko/geopack_py.f
          src/tsyganenko/T96.f
          src/tsyganenko/T02.f
  VERBATIM
  COMMAND "${Python_EXECUTABLE}" -m numpy.f2py
          "${CMAKE_CURRENT_SOURCE_DIR}/src/tsyganenko/geopack_py.pyf"
          "${CMAKE_CURRENT_SOURCE_DIR}/src/tsyganenko/geopack_py.f"
          "${CMAKE_CURRENT_SOURCE_DIR}/src/tsyganenko/T96.f"
          "${CMAKE_CURRENT_SOURCE_DIR}/src/tsyganenko/T02.f"
          -m geopack_py --lower)

# 替换原有python_add_library
python_add_library(
  geopack_py MODULE 
  "${CMAKE_CURRENT_BINARY_DIR}/geopack_pymodule.c"
  "${CMAKE_CURRENT_BINARY_DIR}/geopack_py-f2pywrappers.f"
  "${CMAKE_CURRENT_SOURCE_DIR}/src/tsyganenko/geopack_py.f"
  "${CMAKE_CURRENT_SOURCE_DIR}/src/tsyganenko/T96.f"
  "${CMAKE_CURRENT_SOURCE_DIR}/src/tsyganenko/T02.f"
  WITH_SOABI)
target_link_libraries(geopack_py PRIVATE fortranobject)

2. 补全pyproject.toml中的项目配置

原setup.py中的依赖、作者、分类器等信息需要同步到pyproject.toml:

[project]
name = "Tsyganenko"
version = "2020.2"
authors = [
  { name = "John Coxon and Sebastien de Larquier", email = "work@johncoxon.co.uk" }
]
description = "A wrapper to call GEOPACK routines in Python."
readme = "README.md"
requires-python = ">=3.9"
classifiers = [
  "Development Status :: 4 - Beta",
  "Intended Audience :: Science/Research",
  "Natural Language :: English",
  "Programming Language :: Python",
  "Programming Language :: Fortran"
]
keywords = ["Scientific", "Space"]
dependencies = ["numpy", "matplotlib", "pandas"]

3. 验证安装

重新执行安装命令:

pip install . --no-build-isolation

安装完成后即可正常导入geopack_py模块。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 20:22:31