python setuptools 编译 Fortran 代码并创建一个入口点
python setuptools compile fortran code and make an entry points
这是我的目录结构,
├── test
│ ├── test.f90
│ ├── __init__.py
│ └── test.py
现在我想用命令行工具从中制作一个包 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',
],
}
)
如果我尝试使用它,它会抛出这个错误
error: unknown file type '.f90' (from 'test/test.f90')
所以,我猜 setuptools 不支持 fortran 文件?那么,如何编译 Fortran 代码、创建包并为其创建入口点?
首先在 src/ 文件夹下创建一个名为 test 的文件夹,例如
src
-- <package>
-- test
--- ***
然后添加一个MANIFEST.in并添加
recursive-include src/<package_name>/test *
将这两行包含在您的 setup.py
中
from setuptools import setup, find_packages
package_dir={'': 'src'},
packages=find_packages('src'),
对于您的控制台脚本,执行
entry_points={
'console_scripts': [
'hello=<package>.test:main',
],
},
这实际上是一个非常简单的技巧。只需在从 numpy.distutils.core
导入 setup
之前导入 setuptools
就可以了。对此的解释是 numpy.distutils
不仅仅是普通的 distutils
有一些特定于包的调整。特别是,numpy.distutils
检查 setuptools
是否可用,如果可用,则尽可能在后台使用它。如果你有兴趣,look at the module's source code,注意have_setuptools
标志的用法。
像往常一样,Minimal, Complete, and Verifiable example:
so-55352409/
├── spam
│ ├── __init__.py
│ ├── cli.py
│ └── libfib.f90
└── setup.py
setup.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',
],
}
)
spam/cli.py
:
from spam.libfib import fib
def main():
print(fib(10))
spam/libfib.f90
:
C FILE: LIBFIB.F90
SUBROUTINE FIB(A,N)
C
C CALCULATE FIRST N FIBONACCI NUMBERS
C
INTEGER N
REAL*8 A(N)
Cf2py intent(in) n
Cf2py intent(out) a
Cf2py depend(n) a
DO I=1,N
IF (I.EQ.1) THEN
A(I) = 0.0D0
ELSEIF (I.EQ.2) THEN
A(I) = 1.0D0
ELSE
A(I) = A(I-1) + A(I-2)
ENDIF
ENDDO
END
C END FILE LIBFIB.F90
构建并安装包:
$ 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.]
这是我的目录结构,
├── test
│ ├── test.f90
│ ├── __init__.py
│ └── test.py
现在我想用命令行工具从中制作一个包 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',
],
}
)
如果我尝试使用它,它会抛出这个错误
error: unknown file type '.f90' (from 'test/test.f90')
所以,我猜 setuptools 不支持 fortran 文件?那么,如何编译 Fortran 代码、创建包并为其创建入口点?
首先在 src/ 文件夹下创建一个名为 test 的文件夹,例如
src
-- <package>
-- test
--- ***
然后添加一个MANIFEST.in并添加
recursive-include src/<package_name>/test *
将这两行包含在您的 setup.py
中from setuptools import setup, find_packages
package_dir={'': 'src'},
packages=find_packages('src'),
对于您的控制台脚本,执行
entry_points={
'console_scripts': [
'hello=<package>.test:main',
],
},
这实际上是一个非常简单的技巧。只需在从 numpy.distutils.core
导入 setup
之前导入 setuptools
就可以了。对此的解释是 numpy.distutils
不仅仅是普通的 distutils
有一些特定于包的调整。特别是,numpy.distutils
检查 setuptools
是否可用,如果可用,则尽可能在后台使用它。如果你有兴趣,look at the module's source code,注意have_setuptools
标志的用法。
像往常一样,Minimal, Complete, and Verifiable example:
so-55352409/
├── spam
│ ├── __init__.py
│ ├── cli.py
│ └── libfib.f90
└── setup.py
setup.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',
],
}
)
spam/cli.py
:
from spam.libfib import fib
def main():
print(fib(10))
spam/libfib.f90
:
C FILE: LIBFIB.F90
SUBROUTINE FIB(A,N)
C
C CALCULATE FIRST N FIBONACCI NUMBERS
C
INTEGER N
REAL*8 A(N)
Cf2py intent(in) n
Cf2py intent(out) a
Cf2py depend(n) a
DO I=1,N
IF (I.EQ.1) THEN
A(I) = 0.0D0
ELSEIF (I.EQ.2) THEN
A(I) = 1.0D0
ELSE
A(I) = A(I-1) + A(I-2)
ENDIF
ENDDO
END
C END FILE LIBFIB.F90
构建并安装包:
$ 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.]