2015-07-13 14 views
18

Sto costruendo un pacchetto python usando una libreria C con i tipi. Voglio rendere portatile il mio pacchetto (Windows, Mac e Linux).Come evitare di costruire la libreria C con il mio pacchetto python?

Ho trovato una strategia, utilizzando build_ext con pip per creare la libreria durante l'installazione del pacchetto. Crea libfoo.dll o libfoo.dylib o libfoo.so a seconda della piattaforma di destinazione.

Il problema con questo è che il mio utente ha bisogno di CMake installato.

Esiste un'altra strategia per evitare la creazione durante l'installazione? Devo raggruppare librerie incorporate nel mio pacchetto?

Voglio mantenere i miei utenti facendo pip install mylib.

Edit: grazie a @Dawid commento, sto cercando di fare un python wheel con il comando python setup.py bdist_wheel senza alcun successo.

Come posso creare la mia ruota di pitone per la piattaforma diversa con la libreria incorporata?

Edit 2: sto usando Python 3.4 e di lavoro su Mac OS X, ma non ho accesso al computer Windows, e il computer Linux

+0

sì, è necessario creare pacchetti di ruote (compilati in formato binario) per piattaforme specifiche, 'pip install wheel 'e quindi creare per le piattaforme richieste – Dawid

+0

@Dawid grazie, ho provato a creare una ruota python, ma penso di essere Manca qualcosa –

+0

Penso che sia necessario includere informazioni su quella lib in 'setup.py' in modo da costruirlo. Qualcosa lungo https://docs.python.org/3.4/extending/building.html in questo modo eseguendo 'python setup.py bdist_wheel' su ogni piattaforma creerà un pacchetto whl per quella piattaforma con una libreria compilata. Quindi gli utenti su linux installeranno il pacchetto per linux, su windows per windows e su mac per mac. Almeno quello che vorrei fare per creare un pacchetto binario per quei sistemi. – Dawid

risposta

8

Stai certamente scendere la strada giusta secondo la mia ricerca ... Come dice Daniel, l'unica opzione che avete è quello di costruire e distribuire i binari stessi.

In generale, il metodo consigliato per installare i pacchetti è coperto bene nel packaging user guide. Non ripeterò consigli lì come l'hai già già trovato. Tuttavia, il punto chiave è che la comunità Python, in particolare PyPA, sta tentando di standardizzare sull'uso di platform wheels per il pacchetto di estensioni binarie. Purtroppo, ci sono alcuni problemi a questo punto:

  1. Non è possibile creare distribuzioni per tutte le varianti di Linux, ma è possibile creare ruote per un sottoinsieme compatibile. Vedi https://www.python.org/dev/peps/pep-0513/ per i dettagli.
  2. Il advice on building extensions è piuttosto incompleto, riflettendo la mancanza di una soluzione completa per le distribuzioni binarie.
  3. Le persone tentano quindi di creare la propria libreria e distribuirla come file di dati, il che confonde setuptools.

penso che si sta colpendo questo ultimo problema. A workaround è forzare la distribuzione a costruire una ruota della piattaforma eseguendo l'override di is_pure() per restituire sempre False. Comunque potresti semplicemente mantenere le tue istruzioni di build originali e bdist_wheel dovrebbe gestirle.

Una volta che hai costruito la ruota, però, è ancora necessario per distribuire e forse altri pacchetti binari che utilizza o usarlo.A questo punto, probabilmente dovrai utilizzare uno dei conda come recommended tools o un proxy PyPI come devpi per servire le tue ruote.

EDIT: Per rispondere alla domanda in più su cross-compilazione

Come coperto here Python 2.6 e versioni successive consente il cross-compilazione per Windows 32/64-bit costruisce. Non esiste un supporto formale per altri pacchetti su altre piattaforme e le persone hanno avuto limited success cercando di farlo. Stai davvero meglio costruendo in modo nativo su ciascuno dei tuoi ambienti Linux/Mac/Windows.

+2

"non puoi caricare ruote Linux su PyPI" Perché no? – endolith

+0

In accordo con [Python Packaging Authority] (https://python-packaging-user-guide.readthedocs.io/distributing/#platform-wheels): "Attualmente, la specifica del tag wheel (PEP 425) non gestisce la variazione che può esistere attraverso distro di Linux ". –

+0

Non più: le ruote di Linux ora sono supportate su PyPI. Aggiornato di conseguenza la risposta. –

0

Se non si desidera che l'utente di costruire durante l'installazione , devi fornire un pacchetto binario pre-costruito, non credo che sia possibile alcuna altra strategia. Ho sentito cose positive su py2exe, ma non uso Windows così IDK. Ho avuto esperienze positive con miniconda, ma richiede un po 'di lavoro aggiuntivo su build binary packages from pypi.

+0

grazie, ma preferisco il mio utente installare cygwin/mingw32 o cmake e fare un 'pip install mylib' invece di creare un programma di installazione per questo. Voglio solo andare oltre e cercare di evitare l'installazione di cmake. –

1

Preferisco il mio utente installare cygwin/mingw32 o cmake e fare un pip install mylib [...]. Voglio solo andare oltre e provare a evitare l'installazione di CMake.

Per quanto riguarda il confezionamento di moduli python precompilati, consultare la risposta completa di @Peter Brittain.

Ora, supponendo che l'utente abbia effettivamente installato un compilatore C (sia che sia cygwin, conda su Windows o il sistema su Linux), e tutto ciò che si vuole è evitare l'installazione di CMake, che non ha alcuna relazione. .

La domanda è allora quanto la funzionalità di CMake che si sta utilizzando e se la stessa cosa può essere realizzato con più facile da gestire alternative, vedi relative domande (1), (2), ecc

Edit: In particolare, Stavo pensando qualcosa sulla falsariga di SCons che fornisce un sistema di compilazione completo, ma scritto in Python quindi è più facile da installare in un ambiente Python di CMake, vedi full comparison here. Un'ipotesi selvaggia (non l'ho mai usata io stesso), ma dal momento che si tratta di un modulo Python puro, potresti probabilmente impostare SCons come dipendenza nel tuo setup.py, e automatizzare completamente la generazione del tuo codice C lì, in modo che pip install mylib faccia tutto ciò che è necessario. Vedi anche, pacchetto CMake2SCons che potrebbe essere utile.

+1

Per ora ho visto molti pacchetti hacking Extension() per soddisfare le loro esigenze, rilevare il compilatore e modificare i parametri del compilatore. Cmake gestisce questa complessità per me. Ho creato alcune librerie (.dll e .dylib) che funzionano su piattaforme diverse. Sto cercando di trovare una soluzione semplice da implementare ma anche semplice da installare per il mio utente. –

3

@rth e @PeterBrittain mi aiutano molto. Ecco la soluzione che uso:

cartella struttura:

setup.py 
python_package/ 
    lib/ 
     libfoo.dylib 
     libfoo.dll 
    __init__.py 
    main.py 

setup.py:

from setuptools import setup, dist 


class BinaryDistribution(dist.Distribution): 
    def is_pure(self): 
     return False 


setup(
    name='python_package', 
    package_data={'python_package': ['lib/libfoo.dylib','lib/libfoo.dll']}, 
    include_package_data=True, 
    distclass=BinaryDistribution, 
    packages=['python_package'], 
) 

main.py:

#!/usr/bin/env python 
import platform 
from ctypes import CDLL, c_char_p 

import pkg_resources 

sysname = platform.system() 

if sysname == 'Darwin': 
    lib_name = "libfoo.dylib" 
elif sysname == 'Windows': 
    lib_name = "libfoo.dll" 
else: 
    lib_name = "libfoo.so" 
lib_path = pkg_resources.resource_filename('python_package', 'lib/{}'.format(lib_name)) 
foo = CDLL(lib_path) 

bar = foo.bar 
bar.restype = c_char_p 
bar.argtypes = [c_char_p] 

print(bar('hello')) 

ruota costruzione:

python setup.py bdist_wheel 

Si crea una specifica ruota plateform rtfdoc-0.0.1-cp34-cp34m-macosx_10_10_x86_64.whl e gli utenti Mac possono fare una semplice pip install rtfdoc-0.0.1-cp34-cp34m-macosx_10_10_x86_64.whl

Questa soluzione non è del tutto soddisfacente:

  • Penso che ancora bisogno di creare un Extension o guardare SCons per utenti linux.
  • Aggiornamento mio pacchetto sarà difficile a causa della produzione del lib
  • non so come gestire DLL per 32 bit e 64 bit

Grazie, ho imparato molto, e Capisco perché setup.py in Pillow o Psycopg2 sono enormi

2

Puoi usare cibuildwheel per costruire ruote su Travis CI e/o Appveyor per tutti i tipi di piattaforme e versioni di Python. Questo strumento può anche distribuire le tue ruote su PyPI o altrove.

Problemi correlati