Numpy: [BUG]如果首先生成C源代码,则f2py无法编译扩展模块

创建于 2019-11-22  ·  7评论  ·  资料来源: numpy/numpy

遵循f2py的docs / User Guide,如果要使用扩展模块生成.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扩展模块(尽管很可能可以通过适当的include目录标志和源/目标文件输入来做到这一点)。

使用以下其中一个选项:

f2py -c -m fib1 fib1.f

要么

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

从上面的f2py命令行中跳过任何内容的意义上来说,这些示例是最小的。

所有7条评论

感谢您的报告@melissawm。 我们正在正确地谈论此页面: https :

我可以确认您所看到的:

$ 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分开。 通过自动添加正确的include路径,应该有可能使-c只能工作-可能并不难,但不确定是否需要。

@pearu有什么想法吗?

我不确定哪个文档这么说,但是以下错误:

$ f2py -c fib1module.c

f2py -c ...必须应用于现有的.pyf文件(加上源/对象/库文件),或者必须指定-m <modulename>选项(加上源/对象/库文件) 。 f2py -c并不意味着直接编译生成的C / API扩展模块(尽管很可能可以通过适当的include目录标志和源/目标文件输入来做到这一点)。

使用以下其中一个选项:

f2py -c -m fib1 fib1.f

要么

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

从上面的f2py命令行中跳过任何内容的意义上来说,这些示例是最小的。

实际上,我在谈论此页面: https :

在那里,在第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 :

本页介绍f2py命令行选项和不同的模式。 假定您了解如何构建Python扩展模块,请参见例如https://docs.python.org/3.8/extending/index.html

尽管f2py可用于创建包含C函数的扩展模块(包含在.c文件中),因此“我们不应该直接使用.c源”声明是不准确的。

应该区分.c该f2py生成和文件.c包含的C函数用户实现文件。 f2py生成的.c文件仅在需要完全控制扩展模块的构建方式或调试f2py时才有用。 在所有其他情况下,不需要生成扩展模块,因为它将在构建过程中自动生成。

如果您有其他想法要告诉我,我会在文档中添加@pearu的解释。 谢谢大家的留言!

随时解决问题(或者应该仅在该PR被接受后才做?)

我建议在解决该问题的PR接受后关闭。

我建议在解决该问题的PR接受后关闭。

+1

@melissawm,您还可以在提交消息之一中添加closes gh-14960 ,然后在PR合并后自动关闭该问题。

此页面是否有帮助?
0 / 5 - 0 等级