将F2PY编译步骤转换为setup.py [英] Translate F2PY compile steps into setup.py
问题描述
我继承了一个Fortran 77代码,该代码实现了几个子例程,这些子例程通过程序块运行,每次运行该程序时,都需要通过交互式命令提示符输入大量的用户输入。由于我想自动运行代码,因此我将所有子例程移至一个模块中,并通过F2PY编写了包装器代码。经过两步编译后,一切正常:
I've inherited a Fortran 77 code which implements several subroutines which are run through a program block which requires a significant amount of user-input via an interactive command prompt every time the program is run. Since I'd like to automate running the code, I moved all the subroutines into a module and wrote a wrapper code through F2PY. Everything works fine after a 2-step compilation:
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代码的模块。
This ultimately creates three files: my_module.o
, my_wrapper.o
, my_module.mod
, and my_wrapper.so
. The my_wrapper.so
is the module which I import into Python to access the legacy Fortran code.
我的目标是将此代码包括在更大的科学代码包中,该代码包已经具有 setup.py
,其中使用 distutils
构建一个Cython模块。暂时完全忽略Cython代码,我应该如何将两步构建转换为 setup.py
中的扩展?我能够确定的关闭次数如下:
My goal is to include this code to use in a larger package of scientific codes, which already has a setup.py
using distutils
to build a Cython module. Totally ignoring the Cython code for the moment, how am I supposed to translate the 2-step build into an extension in the setup.py
? The closes I've been able to figure out looks like:
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
也没找到。
This doesn't work, though. My compiler throws many warnings on the my_module.f90
, but it still compiles (it throws no warnings if I use the compiler invocation above). When it tries to compile the wrapper though, it fails to find the my_module.mod
, even though it is successfully created.
有什么想法吗?我感觉自己缺少一些琐碎的东西,但是文档似乎还不够充实,无法表明可能是什么。
Any thoughts? I have a feeling I'm missing something trivial, but the documentation just doesn't seem fleshed out enough to indicate what it might be.
推荐答案
可能要晚一点,但是您的问题是,构建 my_wrapper
my_module >:
It might be a little late, but your problem is that you are not linking in my_module
when building my_wrapper
:
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_module
的使用是 my_wrapper
的,您只需将其添加到 my_wrapper
:
If your only use of my_module
is for my_wrapper
, you could simply add it to the sources of my_wrapper
:
wrapper = Extension('my_wrapper', sources=['my_wrapper.f90', 'my_module.f90'],
extra_f90_compile_args=["-ffixed-form"])
setup(
ext_modules = [wrapper]
)
请注意,这还会将 my_module
中的所有内容导出到您可能不希望的Python。
Note that this will also export everything in my_module
to Python, which you probably don't want.
我正在处理Python之外的这种两层库结构,使用 cmake
作为顶层构建系统。我进行了设置,以便 make python
调用distutils来构建Python包装器。 setup.py
可以安全地假定所有外部库均已构建并安装。如果要在系统范围内安装通用库,然后将其包装为不同的应用程序(例如 Python
, Matlab),则此策略很有用
, Octave
, IDL
,...,它们都有不同的扩展方式
I am dealing with such a two-layer library structure outside of Python, using cmake
as the top level build system. I have it setup so that make python
calls distutils to build the Python wrappers. The setup.py
s can safely assume that all external libraries are already built and installed. This strategy is advantageous if one wants to have general-purpose libraries that are installed system-wide, and then wrapped for different applications such as Python
, Matlab
, Octave
, IDL
,..., which all have different ways to build extensions.
这篇关于将F2PY编译步骤转换为setup.py的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!