Numpy: [BUG] f2py tidak dapat mengkompilasi modul ekstensi jika sumber C dibuat terlebih dahulu

Dibuat pada 22 Nov 2019  ·  7Komentar  ·  Sumber: numpy/numpy

Mengikuti dokumen / Panduan Pengguna dari f2py, jika seseorang ingin membuat file .c dengan modul ekstensi yang harus dilakukan

$ f2py -m fib1 fib1.f

untuk menghasilkan file fib1module.c . Ini bekerja. Namun, langkah selanjutnya untuk membangun modul ekstensi agar dapat diimpor dengan Python, menurut dokumen, adalah

$ f2py -c fib1module.c

Namun, ini gagal untuk saya dengan pesan berikut:

$ 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

Perbuatan

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

tampaknya berfungsi (ini adalah lokasi file fortranobject.h ), tetapi modul tidak dapat diimpor:

>>> 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; DR: Apakah ini bug, atau sesuatu yang tidak seharusnya kami lakukan (buat .c sources dan kemudian buat modul ekstensi dalam langkah terpisah)?

>>> 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

Komentar yang paling membantu

Saya tidak yakin dokumen mana yang mengatakan ini tetapi yang berikut ini salah:

$ f2py -c fib1module.c

f2py -c ... harus diterapkan ke file .pyf (ditambah file sumber / objek / pustaka) atau seseorang harus menentukan opsi -m <modulename> (ditambah file sumber / objek / pustaka) . f2py -c tidak dimaksudkan untuk mengkompilasi modul ekstensi C / API yang dihasilkan secara langsung (meskipun kemungkinan besar dapat melakukannya dengan flag direktori include yang tepat dan input file sumber / objek).

Gunakan salah satu opsi berikut:

f2py -c -m fib1 fib1.f

atau

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

Contoh-contoh ini minimal dalam arti bahwa jika ada sesuatu yang dilewati dalam baris perintah f2py di atas maka akan terjadi kegagalan.

Semua 7 komentar

Terima kasih atas laporannya @melissawm. Kita sedang membicarakan halaman ini kan: https://numpy.org/devdocs/f2py/getting-started.html?

Saya dapat mengonfirmasi apa yang Anda lihat:

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

Namun, halaman dokumen menghasilkan $ f2py -c -m fib1 fib1.f sebagai gantinya (menghasilkan kode dan mengkompilasinya sekaligus), dan itu berfungsi seperti yang diharapkan untuk saya. Saya tidak yakin apakah memisahkan -m dan -c pernah didukung. Seharusnya mungkin untuk membuat -c -hanya berfungsi, dengan menambahkan jalur penyertaan yang benar secara otomatis - mungkin tidak sulit, tetapi tidak yakin apakah itu diperlukan.

@pearu ada pemikiran?

Saya tidak yakin dokumen mana yang mengatakan ini tetapi yang berikut ini salah:

$ f2py -c fib1module.c

f2py -c ... harus diterapkan ke file .pyf (ditambah file sumber / objek / pustaka) atau seseorang harus menentukan opsi -m <modulename> (ditambah file sumber / objek / pustaka) . f2py -c tidak dimaksudkan untuk mengkompilasi modul ekstensi C / API yang dihasilkan secara langsung (meskipun kemungkinan besar dapat melakukannya dengan flag direktori include yang tepat dan input file sumber / objek).

Gunakan salah satu opsi berikut:

f2py -c -m fib1 fib1.f

atau

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

Contoh-contoh ini minimal dalam arti bahwa jika ada sesuatu yang dilewati dalam baris perintah f2py di atas maka akan terjadi kegagalan.

Sebenarnya, saya berbicara tentang halaman ini: https://numpy.org/devdocs/f2py/usage.html

Di sana, di item 2 dan 3, kami memiliki yang berikut: Item 2 menjalankan f2py tanpa opsi -m atau -c , yang tampaknya tidak berfungsi. Item 3 mengatakan

Untuk membangun modul ekstensi, gunakan

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

Jika <fortran files> berisi file tanda tangan, maka sumber untuk modul ekstensi dibuat,
semua sumber Fortran dan C dikompilasi, dan akhirnya semua file objek dan library ditautkan ke file
modul ekstensi <modulename>.so yang disimpan ke direktori saat ini.

Jika <fortran files> tidak berisi berkas tanda tangan, maka modul ekstensi dibuat oleh
memindai semua kode sumber Fortran untuk tanda tangan rutin.

Dari apa yang Anda katakan, saya mengerti bahwa kita tidak seharusnya menggunakan .c sources secara langsung, bukan? Jika kita membuat file .c , apakah nanti tidak bisa digunakan?

Terima kasih atas masukannya!

Sebenarnya, saya berbicara tentang halaman ini: https://numpy.org/devdocs/f2py/usage.html

Halaman ini menjelaskan f2py opsi baris perintah dan mode yang berbeda. Diasumsikan bahwa seseorang memahami bagaimana modul ekstensi Python dapat dibangun, lihat misalnya https://docs.python.org/3.8/extending/index.html

Meskipun f2py dapat digunakan untuk membuat modul ekstensi yang membungkus juga fungsi C (terdapat dalam file .c ) dan oleh karena itu pernyataan "kami tidak seharusnya menggunakan sumber .c secara langsung" tidak akurat.

Seseorang harus membedakan file .c yang dihasilkan f2py dan file .c yang berisi implementasi fungsi C. File .c yang dihasilkan f2py hanya berguna ketika seseorang perlu memiliki kendali penuh tentang bagaimana modul ekstensi dibuat atau untuk men-debug f2py. Dalam semua kasus lainnya, modul ekstensi tidak perlu dibuat karena akan dibuat secara otomatis dalam proses build.

Saya menambahkan penjelasan dari @pearu di atas ke dokumen, jika Anda memiliki ide lain, beri tahu saya. Terima kasih atas komentar Anda!

Jangan ragu untuk menutup masalah (atau haruskah saya melakukannya hanya setelah PR diterima?)

Saya menyarankan penutupan ketika PR yang menangani masalah ini diterima.

Saya menyarankan penutupan ketika PR yang menangani masalah ini diterima.

+1

@melissawm Anda juga dapat menambahkan closes gh-14960 ke salah satu pesan komit Anda, lalu masalah ditutup otomatis saat PR digabungkan.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat