2017-09-19 16 views
1

Cython 코드를 컴파일하여 Python 모듈로 사용하려고합니다. 나는 Cython's basic tutorial을 따라 갔다.distutils를 사용하여 Cython 코드를 컴파일하는 중 문제가 발생했습니다.

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 

그러나 불행히도 오류가 발생했습니다 : 나는 파일 hellowolrd.pyx했습니다

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 

pyth에 만족하지 않는 것으로 보입니다. on3.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 

그리고 그것은 효과가있었습니다. 알다시피 저는 파이썬 인터프리터에서 helloworld를 가져올 수 있습니다. 그러나 나는 distutils로 컴파일 된 Cython 코드를 만드는 법을 알 수 없다. extra_compile_args를 사용하여 같은 플래그를 전달하려고했지만 작동하지 않았습니다.

UPD : gcc가 파이썬의 64 비트 라이브러리를 찾을 수 없으므로 라이브러리 디렉토리를 명시 적으로 표시하려고 시도합니다. 그래서 난 (동일한 출력

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 
에게 여전히

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

+0

문제가 링크 (두 번째'gcc -pthread..')이고 컴파일하지 않습니다 (컴파일하지 않는 명령 행에서 링크하지 않음). 잘못된 유형의 라이브러리 (32 비트, 잘못된 아키텍처)가있는 것 같습니다. – ead

+0

@ead, oh my, 나는 이것을 체크했다고 생각했지만, 나는 오해했다.내 시스템에는 32 비트 아키텍처와 64 비트 아키텍처를위한 두 개의 파이썬 라이브러리가있는 것 같습니다. 그리고 기본적으로 32 비트 라이브러리를 검사합니다. 나는 distutils에서 lib 로의 경로를 바꾸려고 노력할 것이다. 감사! – Zhu

+0

@ead. 64 비트 libarary에 대한 경로가 있지만 링커는 출력에 대해 아무 것도 말하지 않습니다. – Zhu

답변

0

일반적으로, 이름 libXXX.so와 라이브러리에 대한 링커 검색하지 libXXX.so.1.0을있는 setup.py 변경 한 경우 성공하지, 다음 이름을 가진 라이브러리 libXXX.a). 보통 libXXX.so은 실제 라이브러리 인 libXXX.so.Y.0에 대한 심볼릭 링크입니다.

당신은 -Wl,--verbose로 링크 명령을 호출하여 작업 링커를 볼 수 있습니다 예 :

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

그래서 두 가지 옵션이 있습니다를

A : 시스템에 심볼릭 링크 /usr/lib64/libpython3.5m.so을 소개하십시오.

또는 덜 침입 B :

extensions = [ 
     Extension("helloworld", ["helloworld.pyx"], 
     library_dirs = ['/usr/lib64']), 
     libraries=[':libpython3.5m.so.1.0'] 
     ] 

이제 명령을 연결하는 다른 조금 보일 것입니다 :

gcc ... -L/usr/lib64 -l:libpython3.5m.so.1.0 ... 

을 그리고 링커가 libpython3.5m.so.1.0하고 찾고있을 것입니다 확장의 당신의 정의에 libraries=[':libpython3.5m.so.1.0']를 추가 distutils가 제공하는 libpython3.5m.so 일뿐만 아니라.

+0

예! 그게 도움이 됐어! Thnaks! – Zhu