2014-04-30 4 views
6

Cython으로 바꾸거나 변환하려고하는 C++ 프로그램이 있습니다. 그것은 어떤 이유로 든 가져 오기를 위해 작동하는 모듈을 만들지 않을 특별한 라이브러리를 사용합니다. 그런데 C++ 프로그램이 있습니다. 여기에 setup.py가 있습니다 :정의되지 않은 기호로 인한 Cython 빌드

ext_modules = [ 
Extension(
    name="libnmfpy", 
    sources=["interface/nmf_lib.pyx"], 
    include_dirs = ["../src/", numpy.get_include()], 
    libraries=["nmf","mpi_cxx","mpi","m"], 
    library_dirs=["../build/Linux/bin.release","/usr/local/lib/","/usr/lib"], 
    language="c++",) 
] 

setup(
name = 'libnmfpy', 
cmdclass = {'build_ext': build_ext}, 
ext_modules = ext_modules, 
) 

나는 그것이 문제를 일으키는 것으로 보이는 libnmf입니다. libnmf의 첫 번째 빌드는이 오류를 생성하는 스크립트를 일으킬 것입니다 : 내가 -fPIC으로 libnmf 다시 때

/usr/bin/ld: ../build/Linux/bin.release/libnmf.a(nmf.o): relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC 
../build/Linux/bin.release/libnmf.a: could not read symbols: Bad value 
collect2: error: ld returned 1 exit status 

이 설정은 libnmfpy.so 생성을,하지만 난 다른 스크립트에 있음을 가져올 때, 나는 전술을 얻을 것 정의되지 않은 심볼 :

nm libnmfpy.so | grep _ZN4elem6lapack3SVDEiiPdiS1_ 
      U _ZN4elem6lapack3SVDEiiPdiS1_ 

nm ../build/Linux/bin.release/libnmf.a | grep _ZN4elem6lapack3SVDEiiPdiS1_ 
      U _ZN4elem6lapack3SVDEiiPdiS1_ 

나는 오류의 원인을 추측 무엇 어떤 :

Traceback (most recent call last): 
File "test.py", line 1, in <module> 
    import libnmfpy 
ImportError: $path/cython/libnmfpy.so: undefined symbol: _ZN4elem6lapack3SVDEiiPdiS1_ 

이 도움이 될 경우, 여기 내 검색 제안 뭔가입니다.

nm $another_path/lib/libelemental.a | grep _ZN4elem6lapack3SVDEiiPdiS1_ 
0000000000005290 T _ZN4elem6lapack3SVDEiiPdiS1_ 

나는 아직 라이브러리와 링커 너무 익숙하지 않다, 그래서 어떤 도움을 주시면 감사하겠습니다 : 나는 내가 생각하기에 내장되어 libnmf 잘못된 라이브러리가 보면. 감사합니다

편집 : 약간 파고 나 뭔가를 깨닫게했다. Mac OS X과 Linux 사이에 차이점이 있습니까? 내가 일하는 사람들이 원래 이런 오류를보고하지 않았다.

+0

문제를 해결 했습니까? MacOSX/Linux의 차이점에 대해 10.9 OSX 컴파일러는 [libstdC++] 대신에'libC++'로 기본 설정되어 있기 때문에 [here] (https://support.enthought.com/entries/26184115-GCC-Clang-and- Cython-in-OS-X-10-9- 매버릭스) 내가 일하고있는 프로젝트에서 C++ 코드를 하나의 라이브러리에 연결하고 cython 코드를 다른 라이브러리에 연결하려고했습니다. 이로 인해 정의되지 않은 기호 오류가 발생합니다. – gg349

답변

1

글쎄, 나는 당신의 설정을 다시 만든 다음 소스가 없기 때문에 운동을하고 설정에 대한 해결책을 찾을 수 없다. 필자가 fpic을 사용하여 libnmf를 다시 컴파일 할 때 정적 링크가 사용되기 전에 동적 링크로 다시 컴파일되었다고 생각됩니다. 내 추측이 맞다면

, 다음 중 하나를 시도 할 수 있습니다 :

  1. -fPIC, 그리고 -static 다시 libnmf 컴파일.
  2. setup.py - "elemental"libraries 목록에 추가하면 링커가 해당 lib도 가져옵니다.

# 1 방법은 일반적으로 덜 바람직한 것으로 간주되지만, 원래는 어쨌든 그렇게 컴파일 된 것일 수 있습니다. 그러나 다른 라이브러리가 필요하다면 # 2를 찾아서 추가해야하기 때문에 # 2는 더 많은 작업을 수행 할 수 있습니다.

+0

1) 왜'-fPIC'와'-static' 둘 다요? '정적'의 역할은 무엇입니까? 2) '원소'란 무엇인가? – gg349

+0

나는 2를 추측 할 수있다. elemental은 선형 대수 라이브러리 - http://libelemental.org/이다. 그리고 정적 라이브러리로 컴파일되었지만이 cython 통합 외부에 정적이 필요하지 않았기 때문에 기본적으로 – Ben

+0

에 대해 알지 못합니다. -fPIC은 라이브러리가 내부에서 재배치 될 수있는 방식으로 컴파일된다는 것을 의미합니다 프로세스 메모리 -static은 독립형 라이브러리를 만들기 위해 모든 종속성을 수집한다는 것을 의미합니다. 이 경우에는 libnmf가 libelemental을 필요로합니다. without -static 이것은 단지 연기되고 나중에 동적 링커는 그냥 찾을 수 없습니다. – itai

3

심볼을 분리하려면 nm -C을 사용해야합니다. 또한 일반적으로 좋은 생각이 아닌 정적 및 공유 라이브러리를 혼합하는 것처럼 보입니다. 또한 gcc의 링커는 라이브러리 플래그의 순서가 중요하다는 것을 의미하는 원 패스 링커입니다. 역방향 순서로 라이브러리를 나열하려고합니다. 즉, a가 b에 의존하면 b는 링커 플래그 앞에 a를 표시해야합니다.

+1

"정적 및 공유 라이브러리를 혼합하는 것처럼 보입니다." 더 자세하게 얘기해 주 시겠어요? – gg349

+0

-C 플래그가 무엇을 설명 할 수 있습니까? 명령에 추가하려고 시도했지만 아무 것도 보여주지 않습니다. – Ben

+0

-C는 [GNU nm] (http://sourceware.org/binutils/docs/binutils/nm.html)의 --demangle을 줄입니다. Mac에서는 [C++ filt] (http://stackoverflow.com/questions/2424576/unmangling-c-names-on-mac-10-5)를 사용해야합니다. – b4hand