2015-08-29 2 views
5

Я нахожусь в OSX, пытаясь скомпилировать общую библиотеку на C с setup.py distutils (для использования в python с использованием ctypes). Я новичок в distutils, но у меня возникают проблемы, когда разделяемая библиотека, которую я хочу скомпилировать (libreboundx.so), зависит от другой общей библиотеки (librebound.so). Явный, в modify_orbits_direct.c У меня естьКомпиляция C совместно используемой библиотеки с setup.py distutils, когда библиотека зависит от второй общей библиотеки

#include "rebound.h" 

rebound.h находится в каталоге/Users/дт/Отскок/ЦСИ /, и все функции rebound.h находятся в общей библиотеке librebound.so, которая in/Пользователи/dt/отскок /.

Ссылка на cc будет выглядеть.

cc -fPIC -shared reboundx.o -L/Users/dt/rebound -lrebound -o libreboundx.so 

UPDATE: Эта ситуация выглядит точно так же, как, например, в конце гл. 3 - https://docs.python.org/2/extending/building.html. Я обновил мой setup.py, чтобы имитировать, что один:

libreboundxmodule = Extension('libreboundx', 
       sources = [ 'src/reboundx.c', 
          'src/modify_orbits_direct.c'], 
       include_dirs = ['src', '/Users/dt/rebound/src'], 
       extra_compile_args=['-fstrict-aliasing', '-O3','-std=c99','-march=native', '-D_GNU_SOURCE', '-fPIC'], 
       library_dirs=['/Users/dt/rebound'], 
       libraries=['rebound'], 
           ) 

Это устанавливает штраф, когда я бегу

pip install -e ./ 

выход Сложение:

You are using pip version 7.0.3, however version 7.1.2 is available. 
You should consider upgrading via the 'pip install --upgrade pip' command. 
Obtaining file:///Users/dtamayo/Documents/workspace/reboundx 
Installing collected packages: reboundx 
Running setup.py develop for reboundx 
Successfully installed reboundx-1.0 

, но когда я пытаюсь

import reboundx 

в Python, я получаю OSError: dlopen (lib reboundx.so, 10): Символ не найден: _reb_boundary_particle_is_in_box, который является функцией в другой библиотеке (librebound.so), которая даже не вызывается в коде для libreboundx.so.

Если я связываю общую библиотеку с приведенной выше командой cc, все работает, и я могу использовать общую библиотеку libreboundx.so отлично в C. Если я попытаюсь взять тот же libreboundx.so, я скомпилирую команду cc и придерживаться его, где setup.py бы поставить его, а затем попытаться импортировать reboundx в Python, я вместо того, чтобы получить

OSError: dlopen(/Users/dtamayo/Documents/workspace/reboundx/reboundx/../libreboundx.so, 10): Library not loaded: librebound.so 

Реферировано от: /Users/dtamayo/Documents/workspace/reboundx/libreboundx.so Причина: изображение не найден

Может ли это быть проблемой rpath, где во время выполнения libreboundx.so не знает, где искать l ibrebound.so?

+1

'libraries = ['librebound']' выглядит подозрительно. Это не должно содержать префикс 'lib', но только« отскок ». Вы не связываетесь с '-llibrebound', но' -lrebound'. Помимо этого, можете ли вы предоставить сборку? – deets

+0

Я добавил его в вопрос. Я получаю то же самое поведение/вывод с «librebound» или «отскок» в библиотеках (что предполагает, что что-то не так!). Кроме того, я попытался добавить «отскок» в install_requires внизу. Это дает «Требование уже выполнено (используйте --upgrade to upgrade): отскок в/Пользователи/dtamayo/Documents/workspace/rebound (from reboundx == 1.0)», но та же ошибка при импорте в Python. – Dan

+2

В OS X, 'otool -D' показывает' install_name' lib, а 'install_name_tool -id' изменит его. Если вам нужен путь относительно модуля загрузки, используйте токен '@ loader_path'. Зависимости списков, используя 'otool -L', и измените их с помощью' install_name_tool -change'. Вы также можете установить путь поиска зависимостей '-rpath'; это может использовать '@ loader_path' для относительного пути. Класс 'Extension' имеет параметр' rpath', но этот класс действительно не подходит для создания общего общего модуля (особенно в Windows, если это имеет значение). Вы можете вызвать 'ccompiler.new_compiler', чтобы выполнить gcc напрямую. – eryksun

ответ

1

Спасибо за все предложения. Я должен был указать в вопросе, что в конце концов я хочу решение, которое я мог бы упаковать для загрузки в PyPy, чтобы пользователи могли установить одну команду. Он также должен работать как на OSX, так и на Linux, поэтому я предпочел решения, не связанные с install_name_tool.

Я не был в состоянии проверить это, но я думаю, что добавление

runtime_library_dirs=['/Users/dt/rebound'], 

рядом с library_dirs должны решить эту проблему на Linux. По-видимому, это не работает на Mac, но вместо этого вы можете использовать extra_link_args. Добавление этого ниже определения libreboundxmodule, вышеописанного,

исправлено решение проблемы.Я нашел ответ здесь: Python runtime_library_dirs doesn't work on Mac

+1

Это действительно не сработает, если загрузить в PyPI. Если пользователь не будет вызван dtamayo и работает из рабочего пространства в разделе «Документы»;) вам нужно будет связать библиотеку с вашим пакетом, и вам нужно будет использовать относительный путь rpath, например. '@ executable_path' или аналогичные псевдонимы. – deets

+0

Правильно. Я хотел попытаться разделить места, где была найдена библиотека отскока, что казалось возможным, поскольку установка python setup.py перечисляет ее как часть своего вывода. Я просто не мог заставить его работать, даже когда знал путь – Dan

+1

. Что я хотел бы предложить для экспериментов: во-первых, ручной инструмент, который вы хотите. Например. скопируйте librebound.dylib, кроме libreboundx.dylib, и попробуйте и импортируйте пакет. Если это не удается, используйте install_name_tool, чтобы изменить rpath libreboundx так, чтобы он * был найден (очевидно, используя относительный путь с помощью @ -aliases). Как только вы достигнете этого, попробуйте массировать файл setup.py, пока он не построит/не выполнит этот результат. – deets

Смежные вопросы