2013-02-11 77 views
3

我已经继承了一个Fortran 77代码,该代码实现了几个子程序,它们通过一个程序块运行,每次程序运行时都需要通过交互式命令提示符输入大量的用户输入。由于我想自动运行代码,因此我将所有子例程移动到模块中,并通过F2PY编写了包装代码。一切两步编译后工作正常:翻译F2PY编译步骤到setup.py

gfortran -c my_module.f90 -o my_module.o -ffixed-form 
f2py -c my_module.o -m my_wrapper my_wrapper.f90 

这最终创建三个文件:my_module.omy_wrapper.omy_module.modmy_wrapper.somy_wrapper.so是我导入Python以访问旧版Fortran代码的模块。

我的目标是将此代码添加到更大的科学代码包中,该代码已使用distutils构建一个Cython模块,其中已有setup.py。完全忽略了当前的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,即使它已成功创建。

有什么想法?我有一种感觉我错过了一些微不足道的东西,但是这些文档似乎并没有充分表明它可能是什么。

回答

3

这可能是有点晚了,但你的问题是,建设my_wrapper时,你是不是在my_module链接:

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来源:

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作为顶级构建系统。我已经设置好make python调用distutils来构建Python包装。 setup.py可以安全地假定所有的外部库已经被构建和安装。如果想要具有系统级安装的通用库,然后将其包装为不同的应用程序(如Python,Matlab,OctaveIDL,...),这些应用程序都有不同的构建扩展的方法,则此策略是有利的。

+0

谢谢斯蒂芬,这似乎是伎俩。我早已迁移到'cmake',但我非常感谢帮助! – 2013-05-27 13:34:50