使用f2py与scikit-build-core构建时出现Undefined reference错误
解决scikit-build-core + f2py链接
_npy_f2py_ARRAY_API未定义错误 问题概述
带有Fortran 90扩展的Python包,原基于distutils+f2py构建,因distutils弃用转用scikit-build+cmake+f2py。近期因setuptools弃用切换至无setuptools依赖的scikit-build-core后,出现链接错误:
undefined reference to '_npy_f2py_ARRAY_API'
该符号属于f2py的fortranobject库,使用numpy 1.23虽能编译,但导入模块时仍报相同错误;移除target_link_libraries命令可完成编译,但运行时会因缺失依赖报错。
解决方案
1. 显式获取f2py的库与包含路径
在CMakeLists.txt中,直接调用numpy.f2py的接口获取必要路径,避免自动检测的偏差:
find_package(Python REQUIRED COMPONENTS Interpreter Development) find_package(Numpy REQUIRED) # 获取f2py的包含目录和库目录 execute_process( COMMAND ${Python_EXECUTABLE} -c "import numpy.f2py; print(numpy.f2py.get_include())" OUTPUT_VARIABLE F2PY_INCLUDE_DIR OUTPUT_STRIP_TRAILING_WHITESPACE ) execute_process( COMMAND ${Python_EXECUTABLE} -c "import numpy.f2py; print(numpy.f2py.get_lib_dir())" OUTPUT_VARIABLE F2PY_LIB_DIR OUTPUT_STRIP_TRAILING_WHITESPACE ) # 添加包含目录 include_directories(${F2PY_INCLUDE_DIR} ${NumPy_INCLUDE_DIRS}) # 添加库搜索路径 link_directories(${F2PY_LIB_DIR})
2. 正确链接fortranobject库
在定义扩展目标后,显式链接fortranobject库和numpy:
add_library(your_module MODULE your_module_wrapper.c your_fortran_code.f90) target_link_libraries(your_module PRIVATE fortranobject ${NumPy_LIBRARIES}) set_target_properties(your_module PROPERTIES PREFIX "")
3. 适配numpy版本差异
针对numpy 1.24+的API变化,添加版本判断调整链接策略:
if (NumPy_VERSION VERSION_GREATER_EQUAL "1.24") target_link_libraries(your_module PRIVATE fortranobject ${NumPy_LIBRARIES}) else() target_link_libraries(your_module PRIVATE ${NumPy_LIBRARIES}) endif()
4. 修正pyproject.toml配置
确保scikit-build-core的构建配置正确,指定numpy依赖范围:
[build-system] requires = ["scikit-build-core>=0.7", "numpy>=1.23"] build-backend = "scikit_build_core.build" [project] name = "your-package" requires-python = ">=3.8" dependencies = ["numpy>=1.23"]
验证步骤
- 删除
build/、_skbuild/等缓存目录,清理旧构建产物 - 执行
pip install .重新构建安装 - 运行
python -c "import your_module"验证模块可正常导入
内容的提问来源于stack exchange,提问作者Adam Lanman
相关产品推荐
相关产品推荐

