Установить только заголовочную библиотеку с Python
У меня есть библиотека C++ только для заголовков, которую я использую в своих расширениях Python. Я хотел бы иметь возможность установить их по пути включения Python, так что я могу очень легко скомпилировать расширения с python3 setup.py build
, Я частично могу, но есть две вещи, которые я не могу заставить работать (см. Ниже):
Как я могу использовать
python3 setup.py install
установить заголовочные файлы? В настоящее время я получаю только некоторые*.egg
файл, но не заголовки установлены.Как я могу сохранить файловую структуру модуля? В настоящее время файловая структура ошибочно сглажена.
Что работает
Со следующим setup.py
from setuptools import setup
setup(
name = 'so',
description = 'Example',
headers = [
'so.h',
],
)
Я могу загрузить модуль в PyPi:
python3 setup.py bdist_wheel --universal
twine upload dist/*
а затем установите его с помощью pip:
pip3 install so
На моей системе, тогда я нахожу заголовок здесь
/usr/local/include/python3.6m/so/so.h
который доступен, когда я компилирую расширения с помощью Python.
Как я могу использовать 'python3 setup.py install'?
Используя эту стратегию, я не могу просто запустить
python3 setup.py install
В этом случае некоторые so*.egg
установлен, но заголовки не хранятся где-то там, где они доступны для компилятора.
Как сохранить файловую структуру?
Когда модуль немного сложнее и существует некоторая иерархия каталогов, я также сталкиваюсь с проблемами. Для следующих setup.py
from setuptools import setup
setup(
name = 'so',
description = 'Example',
headers = [
'so.h',
'so/implementation.h',
],
)
Проблема в том, что заголовки установлены в
/usr/local/include/python3.6m/so/so.h
/usr/local/include/python3.6m/so/implementation.h
тем самым сглаживая исходную файловую структуру.
Как я могу исправить обе проблемы?
1 ответ
Как я могу использовать
python3 setup.py install
установить заголовочные файлы?
К сожалению, вы не можете так долго, как вы используете setuptools
, Что происходит под капотом при звонке setuptools.setup()
? Инсталлятор яйца строится (bdist_egg
команда) и установлена (через easy_install
) и ни bdist_egg
ни easy_install
поддержка в том числе / установка заголовков. Хотя distribution
объект несет информацию заголовков, он никогда не запрашивается во время install
команда. Это старая хорошо известная проблема, которая никогда не решалась, потому что, очевидно, установка заголовочных файлов не вписывается в процедуру сборки / установки egg.
Таким образом, у вас есть три варианта (или, по крайней мере, три варианта, которые я знаю). Два из них (оба вызывают переключение на distutils
) не рекомендуются и предоставляются только для полноты:
голый distutils
установить (не рекомендуется)
$ sed 's/from setuptools import setup/from distutils.core import setup/' setup.py
Таким образом, старый добрый distutils
позаботится об установке при выполнении python setup.py install
инсталлятор для яиц не будет построен и install_headers
будет вызван. Однако это также включает отказ от всех функций setuptools
включая дополнительные ключевые слова в setup()
и все остальные хорошие вещи, само собой разумеется, что пакеты, установленные через distutils
не может быть удален с pip
,
old-and-unmanageable
установить (не рекомендуется)
Запустите установку с
$ python setup.py install --old-and-unmanageable
Это переключатель setuptools
обеспечивает, если вы явно хотите запустить distutils
установить. Установщик яиц не построен, вместо этого distutils.command.install.install
вызывается. Таким образом, установка такая же, как с голым distutils
установить.
Недостатки этого подхода: так же, как с голым distutils
установить плюс: setuptools
осуждает использование коммутатора; Если вы забудете предоставить его, вы закончите установку яиц и вам придется повторить установку.
замещать python setup.py install
с pip install
(рекомендуемые)
pip
способен устанавливать пакеты из исходных каталогов; просто выпустить
$ pip install dir/
при условии, dir
содержит setup.py
, Таким образом, файл колеса создается из источников (так же, как в bdist_wheel
; на самом деле, эта команда запускается первой) и устанавливается, управляя установкой заголовочных файлов просто отлично.
Как я могу сохранить файловую структуру модуля?
Вам придется настроить install_headers
команда немного:
import os
from distutils.command.install_headers import install_headers as install_headers_orig
from setuptools import setup
class install_headers(install_headers_orig):
def run(self):
headers = self.distribution.headers or []
for header in headers:
dst = os.path.join(self.install_dir, os.path.dirname(header))
self.mkpath(dst)
(out, _) = self.copy_file(header, dst)
self.outfiles.append(out)
setup(
name='so',
headers=['h1.h', 'subtree/h2.h'],
cmdclass={'install_headers': install_headers},
...
)
Что здесь важно, так это линия
dst = os.path.join(self.install_dir, os.path.dirname(header))
Ваниль install_headers
копирует заголовочные файлы непосредственно вinstall_dir
; вышеуказанная строка в перегруженном install_headers
Команда дополнительно заботится о возможных подкаталогах в именах заголовков. При установке пакета, подкаталоги должны быть сохранены:
$ pip show -f so | grep include
../../../include/site/python3.6/so/h1.h
../../../include/site/python3.6/so/subtree/h2.h