Numpy: [ОШИБКА] f2py не удалось скомпилировать модуль расширения, если сначала были созданы исходные коды C

Созданный на 22 нояб. 2019  ·  7Комментарии  ·  Источник: numpy/numpy

Следуя документации / Руководству пользователя от f2py, если кто-то хочет создать файл .c с модулем расширения, необходимо сделать

$ f2py -m fib1 fib1.f

для создания файла fib1module.c . Это работает. Однако следующим шагом для создания модуля расширения для импорта в Python, согласно документации, является

$ f2py -c fib1module.c

Однако у меня это не получается со следующими сообщениями:

$ f2py -c fib1module.c --verbose
running build
running config_cc
unifing config_cc, config, build_clib, build_ext, build commands --compiler options
running config_fc
unifing config_fc, config, build_clib, build_ext, build commands --fcompiler options
running build_src
build_src
building extension "untitled" sources
build_src: building npy-pkg config files
running build_ext
new_compiler returns <class 'distutils.unixccompiler.UnixCCompiler'>
customize UnixCCompiler
customize UnixCCompiler using build_ext
********************************************************************************
<class 'distutils.unixccompiler.UnixCCompiler'>
preprocessor  = ['gcc', '-pthread', '-B', '/opt/miniconda/envs/numpy-dev/compiler_compat', '-Wl,--sysroot=/', '-E']
compiler      = ['gcc', '-pthread', '-B', '/opt/miniconda/envs/numpy-dev/compiler_compat', '-Wl,--sysroot=/', '-Wsign-compare', '-DNDEBUG', '-g', '-fwrapv', '-O3', '-Wall', '-Wstrict-prototypes', '-std=c99']
compiler_so   = ['gcc', '-pthread', '-B', '/opt/miniconda/envs/numpy-dev/compiler_compat', '-Wl,--sysroot=/', '-Wsign-compare', '-DNDEBUG', '-g', '-fwrapv', '-O3', '-Wall', '-Wstrict-prototypes', '-fPIC', '-std=c99']
compiler_cxx  = ['g++', '-pthread', '-B', '/opt/miniconda/envs/numpy-dev/compiler_compat', '-Wl,--sysroot=/']
linker_so     = ['gcc', '-pthread', '-shared', '-B', '/opt/miniconda/envs/numpy-dev/compiler_compat', '-L/opt/miniconda/envs/numpy-dev/lib', '-Wl,-rpath=/opt/miniconda/envs/numpy-dev/lib', '-Wl,--no-as-needed', '-Wl,--sysroot=/']
linker_exe    = ['gcc', '-pthread', '-B', '/opt/miniconda/envs/numpy-dev/compiler_compat', '-Wl,--sysroot=/']
archiver      = ['ar', 'rc']
ranlib        = None
libraries     = []
library_dirs  = []
include_dirs  = ['/opt/miniconda/envs/numpy-dev/include/python3.6m']
********************************************************************************
building 'untitled' extension
compiling C sources
C compiler: gcc -pthread -B /opt/miniconda/envs/numpy-dev/compiler_compat -Wl,--sysroot=/ -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -std=c99

compile options: '-I/home/melissa/projects/numpy/numpy/core/include -I/opt/miniconda/envs/numpy-dev/include/python3.6m -c'
gcc: fib1module.c
fib1module.c:16:10: fatal error: fortranobject.h: Arquivo ou diretório inexistente
   16 | #include "fortranobject.h"
      |          ^~~~~~~~~~~~~~~~~
compilation terminated.
error: Command "gcc -pthread -B /opt/miniconda/envs/numpy-dev/compiler_compat -Wl,--sysroot=/ -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -std=c99 -I/home/melissa/projects/numpy/numpy/core/include -I/opt/miniconda/envs/numpy-dev/include/python3.6m -c fib1module.c -o /tmp/tmpyjgu4iq5/fib1module.o -MMD -MF /tmp/tmpyjgu4iq5/fib1module.o.d" failed with exit status 1

Делать

$ f2py -c fib1module.c -I/home/melissa/projects/numpy/numpy/f2py/src -m fib1module

похоже, работает (это расположение моего файла fortranobject.h ), но тогда модуль не импортируется:

>>> import fib1module
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: /home/melissa/projects/numpy/doc/source/f2py/fib1module.cpython-36m-x86_64-linux-gnu.so: undefined symbol: PyFortran_Type

TL; ДР: Это ошибка или что-то, что мы не должны делать (сгенерировать .c sources, а затем на отдельном этапе создать модуль расширения)?

>>> import sys, numpy; print(numpy.__version__, sys.version)
1.18.0.dev0+8d217b0 3.6.7 | packaged by conda-forge | (default, Jul  2 2019, 02:18:42) 
[GCC 7.3.0]
00 - Bug numpy.f2py

Самый полезный комментарий

Я не уверен, в каких документах говорится об этом, но следующее неверно:

$ f2py -c fib1module.c

f2py -c ... необходимо применить либо к существующему файлу .pyf (плюс файлы источника / объекта / библиотеки), либо необходимо указать параметр -m <modulename> (плюс файлы источников / объекта / библиотеки) . f2py -c не предназначен для непосредственной компиляции сгенерированных модулей расширения C / API (хотя он, вероятно, сможет сделать это с правильными флагами каталога включения и входными данными исходного / объектного файла).

Используйте один из следующих вариантов:

f2py -c -m fib1 fib1.f

или же

f2py -m fib1 fib1.f -h fib1.pyf
f2py -c fib1.pyf fib1.f

Эти примеры минимальны в том смысле, что если что-то пропущено в приведенных выше командных строках f2py, ожидается сбой.

Все 7 Комментарий

Спасибо за отчет @melissawm. Мы правильно говорим об этой странице: https://numpy.org/devdocs/f2py/getting-started.html?

Я могу подтвердить то, что вы видите:

$ f2py -m fib1 fib1.f
$ f2py -c fib1module.c
...
fib1module.c:16:10: fatal error: 'fortranobject.h' file not found
#include "fortranobject.h"

Однако страница документа вместо этого выполняет $ f2py -c -m fib1 fib1.f (генерирует код и компилирует его за один раз), и это работает для меня, как и ожидалось. Я не уверен, поддерживалось ли когда-либо разделение -m и -c . Должна быть возможность сделать так, чтобы -c -only работал, автоматически добавив правильный путь включения - вероятно, не сложно, но не уверен, нужен ли он.

@pearu есть мысли?

Я не уверен, в каких документах говорится об этом, но следующее неверно:

$ f2py -c fib1module.c

f2py -c ... необходимо применить либо к существующему файлу .pyf (плюс файлы источника / объекта / библиотеки), либо необходимо указать параметр -m <modulename> (плюс файлы источников / объекта / библиотеки) . f2py -c не предназначен для непосредственной компиляции сгенерированных модулей расширения C / API (хотя он, вероятно, сможет сделать это с правильными флагами каталога включения и входными данными исходного / объектного файла).

Используйте один из следующих вариантов:

f2py -c -m fib1 fib1.f

или же

f2py -m fib1 fib1.f -h fib1.pyf
f2py -c fib1.pyf fib1.f

Эти примеры минимальны в том смысле, что если что-то пропущено в приведенных выше командных строках f2py, ожидается сбой.

Собственно, я говорю об этой странице: https://numpy.org/devdocs/f2py/usage.html

Там, в пунктах 2 и 3, мы имеем следующее: Пункт 2 - запустить f2py без параметров -m или -c , что, по-видимому, не работает. Пункт 3 говорит

Чтобы создать модуль расширения, используйте

f2py -c <options> <fortran files>       \
  [[ only: <fortran functions>  : ]     \
   [ skip: <fortran functions>  : ]]... \
  [ <fortran/c source files> ] [ <.o, .a, .so files> ]

Если <fortran files> содержит файл подписи, то создается источник для модуля расширения,
все исходники Fortran и C скомпилированы, и, наконец, все файлы объектов и библиотек связаны с
модуль расширения <modulename>.so который сохраняется в текущем каталоге.

Если <fortran files> не содержит файла подписи, то модуль расширения создается
сканирование всех исходных кодов Fortran на предмет рутинных подписей.

Из того, что вы сказали, я понимаю, что мы не должны использовать источники .c напрямую, верно? Если мы сгенерируем файл .c , он станет непригодным для дальнейшего использования?

Спасибо за вклад!

Собственно, я говорю об этой странице: https://numpy.org/devdocs/f2py/usage.html

На этой странице описаны параметры командной строки f2py и различные режимы. Предполагается, что кто-то понимает, как можно создавать модули расширения Python, см., Например, https://docs.python.org/3.8/exnding/index.html

Хотя f2py можно использовать для создания модулей расширения, которые включают также функции C (содержащиеся в файлах .c ), и, следовательно, утверждение «мы не должны использовать источники .c напрямую» неточно.

Следует различать файлы .c которые генерирует f2py, и файлы .c , содержащие пользовательские реализации функций C. Файл .c который генерирует f2py, полезен только тогда, когда нужно иметь полный контроль над созданием модуля расширения или для отладки f2py. Во всех остальных случаях нет необходимости создавать модуль расширения, поскольку он будет сгенерирован автоматически в процессе сборки.

Я добавляю объяснение из @pearu выше в документы, если у вас есть другие идеи, дайте мне знать. Спасибо всем за комментарии!

Не стесняйтесь закрыть вопрос (или я должен сделать это только после того, как PR будет принят?)

Я предлагаю закрыть, когда будет принят PR, который занимается этой проблемой.

Я предлагаю закрыть, когда будет принят PR, который занимается этой проблемой.

+1

@melissawm вы также можете добавить closes gh-14960 в одно из ваших сообщений о фиксации, тогда проблема будет автоматически закрыта при объединении PR.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги