使用 distutils 编译 Cython 代码时出现问题
Issue while compiling Cython code with distutils
我正在尝试编译 Cython 代码并将其用作 Python 模块。我关注了Cython's basic tutorial。我制作了文件 hellowolrd.pyx:
print "Hello World"
我做了setup.py:
from distutils.core import setup
from Cython.Build import cythonize
setup(
ext_modules = cythonize("helloworld.pyx")
)
和运行:
python setup.py build_ext --inplace
但不幸的是发生了一个错误:
running build_ext
building 'helloworld' extension
gcc -pthread -Wno-unused-result -Wsign-compare -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -g -pipe -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fstack-protector --param=ssp-buffer-size=4 -g -O2 -g -pipe -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fstack-protector --param=ssp-buffer-size=4 -I/usr/include/ncursesw -fPIC -I/usr/include/python3.5m -c helloworld.c -o build/temp.linux-x86_64-3.5/helloworld.o
gcc -pthread -shared -Wl,--as-needed -Wl,-z,relro -Wl,-O1 -Wl,--build-id -Wl,--enable-new-dtags build/temp.linux-x86_64-3.5/helloworld.o -L/usr/lib64 -lpython3.5m -o /home/dima/Projects/AntennaModeling/test/helloworld.cpython-35m-x86_64-linux-gnu.so
/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-mageia-linux-gnu/5.4.0/../../../libpython3.5m.so when searching for -lpython3.5m
/bin/ld: skipping incompatible /lib/libpython3.5m.so when searching for -lpython3.5m
/bin/ld: skipping incompatible /usr/lib/libpython3.5m.so when searching for -lpython3.5m
/bin/ld: cannot find -lpython3.5m
collect2: error: command ld failed with exit status 1
error: command 'gcc' failed with exit status 1
似乎 gcc 对 python3.5 库不满意。我尝试使用以下命令在没有 distutils 的情况下进行编译:
cython -a helloworld.pyx
gcc -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing -I/usr/include/python3.5m -o helloworld.so helloworld.c
它奏效了。据了解,我可以从 Python 解释器导入 helloworld。但我不知道如何使用 distutils 编译 Cython 代码。我尝试使用 extra_compile_args 传递相同的标志,但没有成功。
更新:
它发现 gcc 找不到 python 的 64 位库,因此尝试显式显示库目录。所以我改变了setup.py
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
extensions = [
Extension("helloworld", ["helloworld.pyx"],
library_dirs = ['/usr/lib64']),
]
setup(
name = 'Hello world app',
ext_modules = cythonize(extensions),
)
仍然是相同的输出
running build_ext
building 'helloworld' extension
gcc -pthread -Wno-unused-result -Wsign-compare -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -g -pipe -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fstack-protector --param=ssp-buffer-size=4 -g -O2 -g -pipe -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fstack-protector --param=ssp-buffer-size=4 -I/usr/include/ncursesw -fPIC -I/usr/include/python3.5m -c helloworld.c -o build/temp.linux-x86_64-3.5/helloworld.o
gcc -pthread -shared -Wl,--as-needed -Wl,-z,relro -Wl,-O1 -Wl,--build-id -Wl,--enable-new-dtags build/temp.linux-x86_64-3.5/helloworld.o -L/usr/lib64 -L/usr/lib64 -lpython3.5m -o /home/dima/Projects/AntennaModeling/test/helloworld.cpython-35m-x86_64-linux-gnu.so
/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-mageia-linux-gnu/5.4.0/../../../libpython3.5m.so when searching for -lpython3.5m
/bin/ld: skipping incompatible /lib/libpython3.5m.so when searching for -lpython3.5m
/bin/ld: skipping incompatible /usr/lib/libpython3.5m.so when searching for -lpython3.5m
/bin/ld: cannot find -lpython3.5m
collect2: error: command ld failed with exit status 1
error: command 'gcc' failed with exit status 1
通常,linker 搜索名称为 libXXX.so
而不是 libXXX.so.1.0
的库(如果不成功,则搜索名称为 libXXX.a
的库)。通常 libXXX.so
是 link 到 libXXX.so.Y.0
的符号 libXXX.so.Y.0
是真正的库。
您可以通过使用 -Wl,--verbose
调用 link 命令来观看 linker 的工作,例如:
gcc -Wl,--verbose -pthread -shared -Wl,--as-needed -Wl,-z,relro -Wl,-O1 -Wl,--build-id -Wl,--enable-new-dtags build/temp.linux-x86_64-3.5/helloworld.o -L/usr/lib64 -lpython3.5m -o /home/dima/Projects/AntennaModeling/test/helloworld.cpython-35m-x86_64-linux-gnu.so
你会看到如下内容:
...
attempt to open /usr/lib64/libpython3.5m.so failed
...
所以有两种选择:
答:在你的系统上引入symlink /usr/lib64/libpython3.5m.so
。
或较少干扰 B:将 libraries=[':libpython3.5m.so.1.0']
添加到您的扩展定义中:
extensions = [
Extension("helloworld", ["helloworld.pyx"],
library_dirs = ['/usr/lib64']),
libraries=[':libpython3.5m.so.1.0']
]
现在 linking 命令应该看起来有点不同:
gcc ... -L/usr/lib64 -l:libpython3.5m.so.1.0 ...
并且 link 用户将寻找 libpython3.5m.so.1.0
而不仅仅是 libpython3.5m.so
,它仍然由 distutils 提供。
我正在尝试编译 Cython 代码并将其用作 Python 模块。我关注了Cython's basic tutorial。我制作了文件 hellowolrd.pyx:
print "Hello World"
我做了setup.py:
from distutils.core import setup
from Cython.Build import cythonize
setup(
ext_modules = cythonize("helloworld.pyx")
)
和运行:
python setup.py build_ext --inplace
但不幸的是发生了一个错误:
running build_ext
building 'helloworld' extension
gcc -pthread -Wno-unused-result -Wsign-compare -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -g -pipe -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fstack-protector --param=ssp-buffer-size=4 -g -O2 -g -pipe -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fstack-protector --param=ssp-buffer-size=4 -I/usr/include/ncursesw -fPIC -I/usr/include/python3.5m -c helloworld.c -o build/temp.linux-x86_64-3.5/helloworld.o
gcc -pthread -shared -Wl,--as-needed -Wl,-z,relro -Wl,-O1 -Wl,--build-id -Wl,--enable-new-dtags build/temp.linux-x86_64-3.5/helloworld.o -L/usr/lib64 -lpython3.5m -o /home/dima/Projects/AntennaModeling/test/helloworld.cpython-35m-x86_64-linux-gnu.so
/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-mageia-linux-gnu/5.4.0/../../../libpython3.5m.so when searching for -lpython3.5m
/bin/ld: skipping incompatible /lib/libpython3.5m.so when searching for -lpython3.5m
/bin/ld: skipping incompatible /usr/lib/libpython3.5m.so when searching for -lpython3.5m
/bin/ld: cannot find -lpython3.5m
collect2: error: command ld failed with exit status 1
error: command 'gcc' failed with exit status 1
似乎 gcc 对 python3.5 库不满意。我尝试使用以下命令在没有 distutils 的情况下进行编译:
cython -a helloworld.pyx
gcc -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing -I/usr/include/python3.5m -o helloworld.so helloworld.c
它奏效了。据了解,我可以从 Python 解释器导入 helloworld。但我不知道如何使用 distutils 编译 Cython 代码。我尝试使用 extra_compile_args 传递相同的标志,但没有成功。
更新: 它发现 gcc 找不到 python 的 64 位库,因此尝试显式显示库目录。所以我改变了setup.py
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
extensions = [
Extension("helloworld", ["helloworld.pyx"],
library_dirs = ['/usr/lib64']),
]
setup(
name = 'Hello world app',
ext_modules = cythonize(extensions),
)
仍然是相同的输出
running build_ext
building 'helloworld' extension
gcc -pthread -Wno-unused-result -Wsign-compare -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -g -pipe -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fstack-protector --param=ssp-buffer-size=4 -g -O2 -g -pipe -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fstack-protector --param=ssp-buffer-size=4 -I/usr/include/ncursesw -fPIC -I/usr/include/python3.5m -c helloworld.c -o build/temp.linux-x86_64-3.5/helloworld.o
gcc -pthread -shared -Wl,--as-needed -Wl,-z,relro -Wl,-O1 -Wl,--build-id -Wl,--enable-new-dtags build/temp.linux-x86_64-3.5/helloworld.o -L/usr/lib64 -L/usr/lib64 -lpython3.5m -o /home/dima/Projects/AntennaModeling/test/helloworld.cpython-35m-x86_64-linux-gnu.so
/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-mageia-linux-gnu/5.4.0/../../../libpython3.5m.so when searching for -lpython3.5m
/bin/ld: skipping incompatible /lib/libpython3.5m.so when searching for -lpython3.5m
/bin/ld: skipping incompatible /usr/lib/libpython3.5m.so when searching for -lpython3.5m
/bin/ld: cannot find -lpython3.5m
collect2: error: command ld failed with exit status 1
error: command 'gcc' failed with exit status 1
通常,linker 搜索名称为 libXXX.so
而不是 libXXX.so.1.0
的库(如果不成功,则搜索名称为 libXXX.a
的库)。通常 libXXX.so
是 link 到 libXXX.so.Y.0
的符号 libXXX.so.Y.0
是真正的库。
您可以通过使用 -Wl,--verbose
调用 link 命令来观看 linker 的工作,例如:
gcc -Wl,--verbose -pthread -shared -Wl,--as-needed -Wl,-z,relro -Wl,-O1 -Wl,--build-id -Wl,--enable-new-dtags build/temp.linux-x86_64-3.5/helloworld.o -L/usr/lib64 -lpython3.5m -o /home/dima/Projects/AntennaModeling/test/helloworld.cpython-35m-x86_64-linux-gnu.so
你会看到如下内容:
...
attempt to open /usr/lib64/libpython3.5m.so failed
...
所以有两种选择:
答:在你的系统上引入symlink /usr/lib64/libpython3.5m.so
。
或较少干扰 B:将 libraries=[':libpython3.5m.so.1.0']
添加到您的扩展定义中:
extensions = [
Extension("helloworld", ["helloworld.pyx"],
library_dirs = ['/usr/lib64']),
libraries=[':libpython3.5m.so.1.0']
]
现在 linking 命令应该看起来有点不同:
gcc ... -L/usr/lib64 -l:libpython3.5m.so.1.0 ...
并且 link 用户将寻找 libpython3.5m.so.1.0
而不仅仅是 libpython3.5m.so
,它仍然由 distutils 提供。