python setuptools 编译fortran代码并创建入口点

Eul*_*lar 6 python numpy setuptools setup.py python-packaging

这是我的目录结构,

??? test
?   ??? test.f90
?   ??? __init__.py
?   ??? test.py
Run Code Online (Sandbox Code Playgroud)

现在我想用命令行工具制作一个包test。现在我有两个选择,1. numpy distutils 和 2. setuptools。

问题distutils在于它不支持入口点,现在也不推荐使用。但它确实完美地编译了 fortran 代码。现在对于 setuptools 我正在尝试使用此代码,

mod = Extension(name = 'foo.adt', sources = ['test/test.f90'])
setup(
  name = 'foo',
  packages = ['foo'],
  package_dir = {'foo':'test'},
  ext_modules = [mod],
  entry_points={
    'console_scripts': [
        'hello = foo.test:main',
    ],
  }
)
Run Code Online (Sandbox Code Playgroud)

如果我尝试使用它,则会抛出此错误

error: unknown file type '.f90' (from 'test/test.f90')
Run Code Online (Sandbox Code Playgroud)

所以,我猜 setuptools 不支持 fortran 文件?那么,如何编译 fortran 代码、创建包并为其创建入口点?

hoe*_*ing 6

这实际上是一个非常简单的技巧。只需导入setuptools在导入前setupnumpy.distutils.core和你去好。对此的解释是,这numpy.distutils不仅仅是distutils具有一些特定于包的调整的香草。特别是,numpy.distutils检查是否setuptools可用,如果可用,则在可能的情况下使用它。有兴趣可以看一下模块的源码,注意have_setuptoolsflag的用法。

像往常一样,一个最小的、完整的和可验证的例子

so-55352409/
??? spam
?   ??? __init__.py
?   ??? cli.py
?   ??? libfib.f90
??? setup.py
Run Code Online (Sandbox Code Playgroud)

setup.py

so-55352409/
??? spam
?   ??? __init__.py
?   ??? cli.py
?   ??? libfib.f90
??? setup.py
Run Code Online (Sandbox Code Playgroud)

spam/cli.py

import setuptools  # this is the "magic" import
from numpy.distutils.core import setup, Extension


lib = Extension(name='spam.libfib', sources=['spam/libfib.f90'])

setup(
    name = 'spamlib',
    packages = ['spam'],
    ext_modules = [lib],
    entry_points={
        'console_scripts': [
            'hello = spam.cli:main',
        ],
    }
)
Run Code Online (Sandbox Code Playgroud)

spam/libfib.f90

from spam.libfib import fib


def main():
    print(fib(10))
Run Code Online (Sandbox Code Playgroud)

构建并安装包:

$ cd so-55352409
$ python setup.py bdist_wheel
...
$ pip install dist/spamlib-0.0.0-cp36-cp36m-linux_x86_64.whl
...
$ hello
[ 0.  1.  1.  2.  3.  5.  8. 13. 21. 34.]
Run Code Online (Sandbox Code Playgroud)