¿Cómo forzar una rueda de python para que sea específica de plataforma al construirla?

Estoy trabajando en un paquete python2 en el que setup.py contiene algunos comandos de instalación personalizados. Estos comandos en realidad crean un código Rust y .dylib algunos archivos .dylib que se mueven al paquete python.

Un punto importante es que el código Rust está fuera del paquete python.

Se supone que setuptools detecta automáticamente si el paquete de python es python puro o específico de la plataforma (si contiene algunas extensiones de C, por ejemplo). En mi caso, cuando ejecuto python setup.py bdist_wheel , la rueda generada se etiqueta como una rueda de python pura: --py2-none-any.whl . Esto es problemático porque necesito ejecutar este código en diferentes plataformas y, por lo tanto, necesito generar una rueda por plataforma.

¿Hay alguna forma, cuando se construye una rueda, forzar la construcción para que sea específica de la plataforma?

Aquí está el código que suelo mirar desde uwsgi

El enfoque básico es:

setup.py

 # ... try: from wheel.bdist_wheel import bdist_wheel as _bdist_wheel class bdist_wheel(_bdist_wheel): def finalize_options(self): _bdist_wheel.finalize_options(self) self.root_is_pure = False except ImportError: bdist_wheel = None setup( # ... cmdclass={'bdist_wheel': bdist_wheel}, ) 

El bit root_is_pure le dice a la maquinaria de la rueda que construya una rueda no purelib ( pyX-none-any ). También puede ser más elegante diciendo que hay componentes binarios específicos de la plataforma pero no componentes específicos de cpython abi .

Los módulos setuptools , distutils y wheel deciden si una distribución de python es pura al verificar si tiene ext_modules .

Si crea un módulo externo por su cuenta, aún puede ext_modules en ext_modules para que las herramientas de construcción sepan que existe. El truco es proporcionar una lista vacía de fonts para que setuptools y distutils no intenten construirla. Por ejemplo,

 setup( ..., ext_modules=[ setuptools.Extension( name='your.external.module', sources=[] ) ] ) 

Esta solución funcionó mejor para mí que parchear el comando bdist_wheel . El motivo es que bdist_wheel llama al comando de install internamente y ese comando verifica nuevamente la existencia de ext_modules para decidir entre la instalación de purelib o platlib . Si no enumera el módulo externo, terminará con la purelib instalada en una subcarpeta dentro de la rueda. Eso causa problemas al usar la auditwheel repair , que se queja de que las extensiones se están instalando en una carpeta de purelib .