Distutils 将F2PY编译步骤转换为setup.py
我继承了一个Fortran 77代码,它实现了几个子程序,这些子程序通过程序块运行,每次程序运行时都需要大量用户通过交互式命令提示符输入。因为我想自动运行代码,所以我将所有子例程移动到一个模块中,并通过F2PY编写了一个包装器代码。经过两步编译后,一切正常:Distutils 将F2PY编译步骤转换为setup.py,distutils,gfortran,f2py,Distutils,Gfortran,F2py,我继承了一个Fortran 77代码,它实现了几个子程序,这些子程序通过程序块运行,每次程序运行时都需要大量用户通过交互式命令提示符输入。因为我想自动运行代码,所以我将所有子例程移动到一个模块中,并通过F2PY编写了一个包装器代码。经过两步编译后,一切正常: gfortran -c my_module.f90 -o my_module.o -ffixed-form f2py -c my_module.o -m my_wrapper my_wrapper.f90 这最终创建了三个文件:my_mo
gfortran -c my_module.f90 -o my_module.o -ffixed-form
f2py -c my_module.o -m my_wrapper my_wrapper.f90
这最终创建了三个文件:my_module.o
,my_wrapper.o
,my_module.mod
,以及my_wrapper.so
。my_wrapper.so
是我导入Python以访问传统Fortran代码的模块
我的目标是将此代码包含在一个更大的科学代码包中,该包已经有一个setup.py
使用distutils
构建Cython模块。暂时完全忽略Cython代码,如何将两步构建转换为setup.py
中的扩展?我能算出的结果如下:
from numpy.distutils.core import setup, Extension
wrapper = Extension('my_wrapper', ['my_wrapper.f90', ])
setup(
libraries = [('my_module', dict(sources=['my_module.f90']],
extra_f90_compile_args=["-ffixed-form", ])))],
ext_modules = [wrapper, ]
)
但这不管用。我的编译器在My_module.f90
上抛出许多警告,但它仍然编译(如果我使用上面的编译器调用,它不会抛出任何警告)。但是,当它试图编译包装器时,它无法找到my_module.mod
,即使它已成功创建
有什么想法吗?我有一种感觉,我遗漏了一些琐碎的东西,但文档似乎不够充实,无法指出它可能是什么。可能有点晚了,但您的问题是,在构建
我的包装器时,您没有链接到我的模块
:
wrapper = Extension('my_wrapper', sources=['my_wrapper.f90'], libraries=['my_module'])
setup(
libraries = [('my_module', dict(sources=['my_module.f90'],
extra_f90_compile_args=["-ffixed-form"]))],
ext_modules = [wrapper]
)
如果my\u模块
仅用于my\u包装
,则只需将其添加到my\u包装
的源中即可:
wrapper = Extension('my_wrapper', sources=['my_wrapper.f90', 'my_module.f90'],
extra_f90_compile_args=["-ffixed-form"])
setup(
ext_modules = [wrapper]
)
请注意,这还将把my_module
中的所有内容导出到Python,这可能是您不想要的
我正在处理Python之外的这种两层库结构,使用cmake
作为顶级构建系统。我对它进行了设置,以便makepython
调用distutils来构建python包装器。setup.py
s可以安全地假定所有外部库都已构建和安装。如果您希望在系统范围内安装通用库,然后为不同的应用程序打包,例如Python
,Matlab
,Octave
,IDL
,…,这些应用程序都有不同的方法来构建扩展,那么这种策略是非常有利的。感谢Stefan,这似乎起到了作用。我早就迁移到了cmake
,但我很感谢您的帮助!