Cython и фортран - как скомпилировать вместе без f2py

ЗАКЛЮЧИТЕЛЬНОЕ ОБНОВЛЕНИЕ

Этот вопрос о том, как написатьsetup.py это скомпилирует модуль Cython, который напрямую обращается к коду FORTRAN, как C. Это было довольно долгое и трудное путешествие к решению, но полный контекст включен ниже для контекста.

ОРИГИНАЛЬНЫЙ ВОПРОС

У меня есть расширение, которое представляет собой файл Cython, который устанавливает некоторую кучу памяти и передает ее в код Fortran, и файл Fortran, который является почтенным старым модулем, который яЯ бы хотел избежать повторной реализации, если смогу.

.pyx файл прекрасно компилируется в C, но компилятор Cython душит.f90 файл со следующей ошибкой:

$ python setup.py build_ext --inplace
running build_ext
cythoning delaunay/__init__.pyx to delaunay/__init__.c
building 'delaunay' extension
error: unknown file type '.f90' (from 'delaunay/stripack.f90')

Вот's (верхняя половина) моего установочного файла:

from distutils.core import setup, Extension
from Cython.Distutils import build_ext

ext_modules = [
  Extension("delaunay",
    sources=["delaunay/__init__.pyx",
             "delaunay/stripack.f90"])
]

setup(
  cmdclass = {'build_ext': build_ext},
  ext_modules = ext_modules,
  ...
)

ПРИМЕЧАНИЕ: у меня изначально был файл с ФортраномНеправильно указано местоположение (без префикса каталога), но после того, как я это исправил, это происходит точно так же.

Вещи, которые я пробовал:

я нашелэтоти попытался передать имя компилятора фортрана (т.е. gfortran) следующим образом:

$ python setup.py config --fcompiler=gfortran build_ext --inplace
usage: setup.py [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
   or: setup.py --help [cmd1 cmd2 ...]
   or: setup.py --help-commands
   or: setup.py cmd --help

error: option --fcompiler not recognized

И я'мы также пытались удалить--inplaceв случае, если это было проблемой (это не былот, так же, как верхнее сообщение об ошибке).

Итак, как мне собрать этот фортран? Могу ли я взломать его в.o себя и сойти с рук, связав это? Или жеэто ошибка в Cython, что заставит меня переопределить distutils или взломать препроцессором?

ОБНОВИТЬ

Итак, проверивnumpy.distutils пакеты, я понимаю проблему немного больше. Кажется, ты должен

Используйте cython для преобразования файлов .pyx в файлы cpython .c,Затем используйте /Extensionsetup() комбинация, которая поддерживает Фортран, как 'numpys.

Попробовав это, мойsetup.py теперь выглядит так:

from numpy.distutils.core import setup
from Cython.Build import cythonize
from numpy.distutils.extension import Extension

cy_modules = cythonize('delaunay/sphere.pyx')
e = cy_modules[0]

ext_modules = [
  Extension("delaunay.sphere",
      sources=e.sources + ['delaunay/stripack.f90'])
]

setup(
  ext_modules = ext_modules,
  name="delaunay",
  ...
)

(обратите внимание, что яМы также немного перестроили модуль, так как__init__.pyx запрещено ...)

Теперь все становится глючным и зависит от платформы. У меня есть две системы тестирования - одна Mac OS X 10.6 (Snow Leopard), использующая Macports Python 2.7, и одна Mac OS X 10.7 (Lion), использующая системный python 2.7.

На Snow Leopard действует следующее:

Это означает, что модуль компилируется (ура!) (Хотянет нет--inplace кажется, что для numpy мне пришлось установить модуль тестирования в масштабе всей системы: /) но я все равно получаю сбойimport следующее:

  >>> import delaunay
  Traceback (most recent call last):
    File "", line 1, in 
    File "site-packages/delaunay/__init__.py", line 1, in 
      from sphere import delaunay_mesh
  ImportError: dlopen(site-packages/delaunay/sphere.so, 2): no suitable image found.  Did find:
    site-packages/delaunay/sphere.so: mach-o, but wrong architecture

и на Lion я получаю ошибку компиляции после довольно запутанной строки компиляции:

gfortran:f77: build/src.macosx-10.7-intel-2.7/delaunay/sphere-f2pywrappers.f
/usr/local/bin/gfortran -Wall -arch i686 -arch x86_64 -Wall -undefined dynamic_lookup -bundle build/temp.macosx-10.7-intel-2.7/delaunay/sphere.o build/temp.macosx-10.7-intel-2.7/build/src.macosx-10.7-intel-2.7/delaunay/spheremodule.o build/temp.macosx-10.7-intel-2.7/build/src.macosx-10.7-intel-2.7/fortranobject.o build/temp.macosx-10.7-intel-2.7/delaunay/stripack.o build/temp.macosx-10.7-intel-2.7/build/src.macosx-10.7-intel-2.7/delaunay/sphere-f2pywrappers.o -lgfortran -o build/lib.macosx-10.7-intel-2.7/delaunay/sphere.so
ld: duplicate symbol _initsphere in build/temp.macosx-10.7-intel-2.7/build/src.macosx-10.7-intel-2.7/delaunay/spheremodule.o ldand :build /temp.macosx-10.7-intelduplicate- 2.7symbol/ delaunay/sphere.o _initsphere in forbuild architecture /i386
temp.macosx-10.7-intel-2.7/build/src.macosx-10.7-intel-2.7/delaunay/spheremodule.o and build/temp.macosx-10.7-intel-2.7/delaunay/sphere.o for architecture x86_64

Теперь давайтеПросто сделайте шаг назад, прежде чем мы рассмотрим детали здесь. Во-первых, я знаю, что в 64-битной Mac OS X возникают проблемы с конфликтами архитектуры; Мне пришлось очень усердно работать, чтобы заставить Macports Python работать на компьютере Snow Leopard (просто для обновления с системного Python 2.6). Я также знаю, что когда вы видитеgfortran -arch i686 -arch x86_64 вы отправляете смешанные сообщения вашему компилятору. Там спрятаны всевозможные специфичные для платформы проблемы, которые мы нене нужно беспокоиться в контексте этого вопроса.

Но давайпросто посмотрите на эту строку:gfortran:f77: build/src.macosx-10.7-intel-2.7/delaunay/sphere-f2pywrappers.f

что делает NumPy ?! Я нев этой сборке не нужны никакие функции f2py! Я на самом деле написал модуль Cythonчтобы избежать имеем дело с f2py 'Безумие (мне нужно иметь 4 или 5 выходных переменных, а также ни аргументы «ни в, ни вне» - ни один из которых не поддерживается в f2py.) Я просто хочу, чтобы он компилировался ->.c .oи ->.f90 .o и связать их. Я мог бы написать эту строку компилятора сам, если бы знал, как включить все соответствующие заголовки.

Пожалуйста, скажи мне, что я нене нужно писать свой собственный make-файл для этого ... или что тамЭто способ перевести Fortran в (совместимый с выходом) C, так что я могу избежать того, чтобы python когда-либо видел расширение .f90 (которое исправляет всю проблему). Обратите внимание, чтоf2c не подходит для этого, так как он работает только на F77, и это более современный диалект (следовательно,.f90 расширение файла).

ОБНОВЛЕНИЕ 2 Следующий скрипт bash успешно скомпилирует и свяжет код на месте:

PYTHON_H_LOCATION="/opt/local/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7/"

cython sphere.pyx

gcc -arch x86_64 -c sphere.c -I$PYTHON_H_LOCATION
gfortran -arch x86_64 -c stripack.f90
gfortran -arch x86_64 -bundle -undefined dynamic_lookup -L/opt/local/lib *.o -o sphere.so

Любой совет о том, как сделать этот вид взлома совместимым с setup.py? Я неКто-нибудь, кто устанавливает этот модуль, должен найтиPython.h вручную...

Ответы на вопрос(3)

Ваш ответ на вопрос