Estoy trabajando en el envasado de una interfaz de Python para una biblioteca C. La biblioteca C viene como un tarball distribución binaria con las cabeceras y la biblioteca compilado. Quiero hacer un bdist_wheel
fuera de él, junto con mis extensiones de Python construido, y las cabeceras.
He escrito un par de comandos distutils para extraer e instalar la biblioteca de este modo:
from distutils.core import Command
from distutils.command.build import build
import os
import tarfile
class ExtractLibraryCommand(Command):
description = 'extract library from binary distribution'
def initialize_options(self):
self.build_lib = None
self.build_temp = None
self.library_dist = os.environ.get('LIBRARY_DIST')
def finalize_options(self):
self.set_undefined_options('build',
('build_lib', 'build_lib'),
('build_temp', 'build_temp'))
assert os.path.exists(self.library_dist), 'Library dist {} does not exist'.format(self.library_dist)
def run(self):
with tarfile.open(self.library_dist, 'r') as tf:
tf.extractall(path=self.build_temp)
class InstallLibraryCommand(Command):
description = 'install library from extracted distribution'
def initialize_options(self):
self.build_lib = None
self.build_temp = None
def finalize_options(self):
self.set_undefined_options('build',
('build_lib', 'build_lib'),
('build_temp', 'build_temp'))
def run(self):
self.copy_tree(
os.path.join(os.path.join(build_temp, 'my_library')),
os.path.join(self.build_lib, os.path.join('my_package', 'my_library'))
)
Entonces puedo reemplazar el build
paso de incluir mis nuevos comandos.
class BuildCommand(build):
def run(self):
self.run_command('extract_library')
self.run_command('install_library')
build.run(self)
El problema es, no estoy seguro de cómo obtener la ruta a las cabeceras de la biblioteca para construir mis extensiones, a medida que se instalan en un directorio especificado por distutils.
from setuptools import setup, find_packages
from setuptools.extension import Extension
from Cython.Build import cythonize
extensions = [
Extension(
'package.library.*',
['package/library/*.pyx'],
include_dirs=???,
),
]
setup(
packages=find_packages(),
...
ext_modules=cythonize(extensions),
)
EDIT: Para aclarar, esto es un script setup.py.
Puede modificar las extensiones en el InstallLibraryCommand
, después de que la biblioteca esté disponible. Me muevo probablemente también el código de extracción / instalación en finalize_options
lugar de run
como instalar la biblioteca en la construcción de etapa es un poco tarde en mi opinión (hace que el disponible de la biblioteca en la etapa de configuración). Ejemplo:
class InstallLibraryCommand(Command):
def finalize_options(self):
...
with tarfile.open(self.library_dist, 'r') as tf:
tf.extractall(path=self.build_temp)
include_path = os.path.join(self.build_lib, os.path.join('my_package', 'my_library'))
self.copy_tree(
os.path.join(os.path.join(build_temp, 'my_library')),
include_path
)
for ext in self.distribution.ext_modules:
ext.include_dirs.append(include_path)