2017-11-19 34 views
0

python setup.py bdist_wheel 또는 이와 동등한 명령을 사용하여 Cython 모듈을 빌드 한 후에 특정 명령을 실행해야합니다. 이것이 가능한가?파이썬 패키지를 배포 할 때 dylib 다루기

여기에 상황이 특히 있습니다 : 나는 osx를위한 Cython 프로그램을 만들고 있습니다. 그것은 내 홈 디렉토리 및 구축 할 수있는 프로그램을 얻을하는 특정 .dylib 파일에 대한 링크, 당신은 (혼전 인)

export DYLD_LIBRARY_PATH=/path/to/parent/dir 

을 실행하거나

install_name_tool -change @executable_path/my.dylib /path/to/my.dylib 
을 실행하는 setup.py의 지시자를 포함 하나

이것은 기본적으로 바이너리에게 어디에서 dylib을 찾을 지 알려주는 것입니다. 어느 옵션도 이상적이지 않지만 후자는 약간 더 이식성이 있습니다. 지금 난 그냥 setup.py의 바닥이 지침을 추가,하지만 여전히 휴대용되지 않습니다 : 나는 문서 및 몇 가지 튜토리얼을 읽고, 이제

python setup.py sdist # I think this collects source files into a .tar 
python setup.py bdist_wheel # I think this builds a binary. This is where I assume the post-compilation stuff should happen. 
twine upload dist/* # This puts stuff up on PyPi. 

:의 내가 패키지 말을 다음과 같이 내 패키지를 업로드 할 수 그리고 나는 아직도이 명령들이하는 것을 100 % 확신하지 못하고있다. 보인다 솔루션은

ImportError: dlopen(/path/to/my/module.cpython-36m-darwin.so, 2): 
Library not loaded: @executable_path/my.dylib 
    Referenced from: /path/to/my/module.cpython-36m-darwin.so 
    Reason: image not found 

자동 후 컴파일 방향의 어떤 종류를 추가 :하지만 이후 경우, 다른 프로젝트에, 내가

pip install mypackage 

가 dylib 문제가 그 추한 머리를 앞발 실행할 것을 알고있다 setup.py를 사용하여 install_name_tool 작업을 수행해야 함을 나타냅니다. 이것이 가능하다면, 어떻게하면 될까요? 이상적으로는 기성품 인 Cython.Build.cythonizesetuptools.Extension을 사용하고 싶지만 더 맞춤화 된 것을해야 할 수도 있습니다. 귀하의 제안에 감사드립니다! 대니가 제대로 install_name_tool를 실행하는 휴대용 솔루션 대신 dylib가 어떻게 든 패키지에 포함될 필요가 있음을 지적

솔루션. delocate은 작업을위한 도구이지만, 내가 처음 발견 된 문제는 delocate@executable_path 작동하지 않음을했다 :

❯ delocate-wheel -w fixed_wheels -v dist/*.whl 
Fixing: dist/my-package-1.0.9-cp36-cp36m-macosx_10_12_x86_64.whl 
/Users/ethan/virtualenvs/my-package/lib/python3.6/site-packages/delocate/delocating.py:71: UserWarning: Not processing required path @executable_path/my.dylib because it begins with @ 
    'begins with @'.format(required)) 

, 나는 my.dylibid@executable_path을 사용하는지 확인 할 수 있었다 otool 사용 :

❯ install_name_tool -id my.dylib my.dylib 
:

@executable_path을 제거하려면

❯ otool -L my.dylib 
my.dylib: 
    @executable_path/my.dylib (compatibility version 0.0.0, current version 0.0.0) 
    /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.1.0) 
    /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0) 
    /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0) 
    /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1258.1.0) 
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1) 
나는 다음을 실행 일반적으로

❯ otool -L my.dylib 
my.dylib: 
    my.dylib (compatibility version 0.0.0, current version 0.0.0) 
    /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.1.0) 
    /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0) 
    /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0) 
    /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1258.1.0) 
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1) 

는, 이것은 dylib를 위해 사용하는 것이 id 아니라, delocate-wheel 함께 작업하는 것이 충분하다 :

지금 otool -L의 출력 봐.나는 다시 내 .whl :

python setup.py bdist_wheel 

그리고 지금은 delocate_wheel을 실행할 때 :

delocatemy.dylib을 찾을 것으로 예상하는 곳은 분명 우리에게
❯ delocate-wheel -w fixed_wheels -v dist/*.whl 
Fixing: dist/my.whl 
Traceback (most recent call last): 
...  
delocate.delocating.DelocationError: library "/Users/ethan/my-package/my.dylib" does not exist 

. 그래서 /Users/ethan/my-package/my.dylibmy.dylib를 복사하고 명령 reran :

❯ delocate-wheel -w fixed_wheels -v dist/*.whl 
Fixing: dist/my.whl 
Copied to package .dylibs directory: 
    /Users/ethan/my-package/my.dylib 

성공! 이 .dylibs 디렉토리 란 무엇입니까? 당신이 볼 수 있듯이

❯ tree -a fixed_wheels/my-package 
fixed_wheels/my-package 
├── .dylibs 
│   └── my.dylib 
├── __init__.py 
└── package.cpython-36m-darwin.so 

가의 my.dylibmy.whl 패키지로 가져옵니다 .dylibs/ 디렉토리에 복사되었습니다 나는 바퀴를 풀고 그 내용을 검토 tar -xvf my.whl을 달렸다. my.whl을 pypi에 업로드 한 후 코드를 다운로드하여 실행할 수있었습니다.

답변

0

delocate 및 해당 Linux auditwheel을 살펴보십시오.

delocate 도구는 런타임에 링크 로더 경로를 변경하지 않고 제 3 자 라이브러리를 휠에 포함시키고 그에 따라로드 시간 경로를 조정합니다.

결과는 모든 종속 라이브러리가 올바르게 포함 된 배포 가능 바이너리 휠입니다.

런타임로드 경로 설정은 이식 가능하지 않으며 파이썬 버전 또는 시스템 아키텍처에서 작동하지 않습니다. 바퀴가 python setup.py bdist_wheel 실행에 의해 생성 된 후 위의 예를 들어

: 고정 된 휠 파일이 fixed_wheels 디렉토리에 배치됩니다

delocate-wheel -w fixed_wheels <wheel file>

. -v으로 실행하면 포함 된 라이브러리를 확인할 수 있습니다.