Numpy: [BUG] يتعذر على f2py تجميع وحدة التمديد إذا تم إنشاء مصادر C أولاً

تم إنشاؤها على ٢٢ نوفمبر ٢٠١٩  ·  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 ؛ DR: هل هذا خطأ ، أو شيء لا يفترض بنا القيام به (إنشاء مصادر .c ثم إنشاء وحدة الامتداد في خطوة منفصلة)؟

>>> 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 يعمل فقط ، عن طريق إضافة مسار التضمين الصحيح تلقائيًا - ربما ليس صعبًا ، لكن لست متأكدًا من الحاجة إليه.

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/extending/index.html

بينما يمكن استخدام f2py لإنشاء وحدات امتدادات تلتف أيضًا وظائف C (الموجودة في ملفات .c ) وبالتالي فإن العبارة "ليس من المفترض أن نستخدم مصادر .c مباشرة" غير دقيقة.

يجب على المرء التمييز بين ملفات .c التي ينشئها f2py والملفات .c التي تحتوي على تطبيقات المستخدم لوظائف C. يكون الملف .c الذي ينشئه f2py مفيدًا فقط عندما يحتاج المرء إلى التحكم الكامل في كيفية إنشاء وحدة الامتداد أو لتصحيح أخطاء f2py. في جميع الحالات الأخرى ، لا يحتاج المرء إلى إنشاء وحدة الامتداد حيث سيتم إنشاؤها تلقائيًا في عملية الإنشاء.

أقوم بإضافة الشرح من pearu أعلاه إلى المستندات ، إذا كان لديك أي أفكار أخرى ،

لا تتردد في إغلاق المشكلة (أم يجب أن أفعل ذلك فقط بعد قبول العلاقات العامة؟)

أقترح الإغلاق عند قبول العلاقات العامة التي تعالج هذه المشكلة.

أقترح الإغلاق عند قبول العلاقات العامة التي تعالج هذه المشكلة.

+1

melissawm ، يمكنك أيضًا إضافة closes gh-14960 إلى إحدى رسائل الالتزام ، ثم يتم إغلاق المشكلة تلقائيًا عند دمج العلاقات العامة.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات