2014-06-05 4 views
12

나는 C로 구현되는 주요 기능 (속도가 중요 함)을 라이브러리에 작성했으며, 그 주위에는 희미한 파이썬 레이어가있어서 ctypes nastiness를 처리했다.C 공유 라이브러리가 포함 된 Python 라이브러리를 패키지하는 가장 좋은 방법은 무엇입니까?

나는 그것을 꾸러미에 넣을거야. 그리고 내가 어떻게 이것에 대해 가장 잘 갈지 궁금해. 인터페이스해야하는 코드는 공유 라이브러리입니다. C 코드를 빌드하고 .so 파일을 만드는 Makefile을 가지고 있지만 distutils를 통해 컴파일하는 방법을 모르겠습니다. 난 그냥 install 명령을 재정 의하여 subprocessmake를 호출해야 (그렇다면은,이에 대한 장소 install, 또는 더 적절한 build입니까?)

업데이트 :이 하지이므로주의 할 파이썬 확장. 즉, C 라이브러리에는 Python 런타임과 상호 작용하는 코드가 없습니다. 파이썬은 스트레이트 C 공유 라이브러리에 대한 외부 함수 호출을하고있다.

+0

문제에 대한 해결책이 있습니까? 나는 똑같은 질문에 빠지며 대답을 필사적으로한다.) – MrLeeh

+0

이것은 아주 오래전이지만 'make'로 포격하여 해결했다. 이 라이브러리의 setup.py는 다음과 같습니다 : https://gist.github.com/obeattie/3d491ec4c29b1d4b46387b285c91ca89 – obeattie

+0

이 요지에서했던 것을 시도해 보았습니다. 어떻게'.so'를 얻었습니까? 파이썬/ld가 그것을 찾을 것입니다 어떤 위치에 설치되어 줄 지어? – wvxvw

답변

2

create Python extensions in C에 대한 지침을 따른다면 this documentation과 같은 확장 모듈을 등록해야합니다.
그래서 라이브러리의 setup.py 스크립트는 다음과 같아야합니다

from distutils.core import setup, Extension 
setup(
    name='your_python_library', 
    version='1.0', 
    ext_modules=[Extension('your_c_extension', ['your_c_extension.c'])], 
) 

distutils은 넣어 위치를 또한 C 공유 라이브러리로 확장을 컴파일하는 방법을 알고있다.

물론 라이브러리에 대한 추가 정보가 없으므로 더 많은 인수를 setup(...) 호출에 추가하려고합니다.

+0

@ElmoVanKielvo, distutils2에서 어떻게하는지 알고 있습니까? – Mansueli

+1

같은데 ... http://pythonhosted.org/Distutils2/distutils/setupscript.html#describing-extension-modules ... 정확하게 동일 :) – ElmoVanKielmo

+5

이것은 파이썬 확장이 아닙니다. 이것은 순수한 C 라이브러리 (Python 런타임과 상호 작용할 코드 자체가 포함되어 있지 않음)이지만 Python은 ['ctypes'] (https://docs.python.org/2/library/ctypes.html)를 통해 호출합니다). 파이썬 확장 모듈에서 C 공유 라이브러리를 래핑하는 것이 가능할 수도 있지만, 현재'ctypes' 접근 방식을 유지하고 싶습니다. – obeattie

1

일반 공유 라이브러리 빌드의 하위 프로젝트로 파이썬 모듈을 빌드하는 것이 좋습니다. automake, autoconf 또는 이와 비슷한 것을 사용하여 공유 라이브러리를 만들고 setup.py와 python 모듈로 python_bindings 디렉토리를 만듭니다.

1

나는 비슷한 대답이 도움이 발견 : Python setup.py call makefile don't include binaries.

나는 배포판의 src 디렉토리에 ANSI C 라이브러리가 있습니다. src 디렉토리에 내 패키지 디렉토리 (lsd)에 liblsd.so이라는 파일을 빌드하는 Makefile이 있습니다. setup.py에서 이것을 호출 한 다음, 설치 프로그램에 package_data 인수를 사용하여 라이브러리 파일을 포함하도록 지시합니다.

import os.path 
import subprocess 

from setuptools import setup 

with open(os.path.join(os.path.dirname(__file__), 'README.rst')) as f: 
    readme = f.read() 

subprocess.call(['make', '-C', 'src']) 

setup(name='LSD', 
    version='0.0.1', 
    description='Python bindings for the LSD line segment detector.', 
    long_description=readme, 
    author='Geoff Hing', 
    author_email='[email protected]', 
    url='https://github.com/ghing/python-lsd', 
    packages=['lsd'], 
    package_data={'lsd': ['liblsd.so']}, 
    include_package_data=True, 
    classifiers=[ 
     'Development Status :: 1 - Planning', 
     'Intended Audience :: Developers', 
     'License :: OSI Approved :: MIT License', 
     'Operating System :: OS Independent', 
     'Programming Language :: Python', 
     'Programming Language :: C', 
     ], 
) 
+1

최소한'distutils.command.build'라는 클래스를 서브 클래스 화하고'run' 메소드를 오버라이드해야합니다. 그렇지 않으면 make.py는 라이브러리를 다시 컴파일하기를 원하지 않는 모든 유형의 호출 (예 : 'check '또는'업로드 ') –