Python setuptools компилирует код Fortran и делает точки входа - PullRequest
2 голосов
/ 26 марта 2019

Вот моя структура каталогов,

├── test
│   ├── test.f90
│   ├── __init__.py
│   └── test.py

Теперь я хочу сделать из этого пакет с помощью инструмента командной строки test. Теперь у меня есть два варианта: 1. numpy distutils и 2. setuptools.

Проблема с distutils заключается в том, что он не поддерживает точки входа, и сейчас он также не рекомендуется. Но он прекрасно компилирует фортран-код. Теперь, что касается 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? Итак, как мне скомпилировать код на фортране, создать пакет и создать точку входа для этого?

Ответы [ 2 ]

1 голос
/ 26 марта 2019

Это на самом деле довольно простой трюк. Просто импортируйте setuptools перед импортом setup из numpy.distutils.core и все готово. Объяснение этому заключается в том, что numpy.distutils - это гораздо больше, чем просто ваниль distutils с некоторыми настройками для конкретного пакета. В частности, numpy.distutils проверяет, доступен ли setuptools, и, если да, использует его, где это возможно, под капотом. Если вам интересно, посмотрите на исходный код модуля , обращая внимание на использование флага have_setuptools.

Как обычно, пример Минимальный, Полный и Проверяемый :

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.]
0 голосов
/ 26 марта 2019

Начните с создания папки с именем test в src / folder, например.

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',
                ],
        },
...