c++ - scripts - setup script
Los distutils de Python no incluyen el módulo SWIG generado. (3)
El problema es que build_py
(que copia las fuentes de Python al directorio de compilación) viene antes de build_ext
, que ejecuta SWIG.
Puede subclasificar fácilmente el comando de compilación e intercambiar el orden, de modo que build_ext
produce module1.py
antes de que build_py
intente copiarlo.
from distutils.command.build import build
class CustomBuild(build):
sub_commands = [
(''build_ext'', build.has_ext_modules),
(''build_py'', build.has_pure_modules),
(''build_clib'', build.has_c_libraries),
(''build_scripts'', build.has_scripts),
]
module1 = Extension(''_module1'', etc...)
setup(
cmdclass={''build'': CustomBuild},
py_modules=[''module1''],
ext_modules=[module1]
)
Sin embargo, hay un problema con esto: si está utilizando setuptools, en lugar de solo los distritos simples, ejecutar python setup.py install
no ejecutará el comando de compilación personalizado. Esto se debe a que el comando de instalación setuptools realmente no ejecuta el comando de compilación primero, ejecuta egg_info, luego install_lib, que ejecuta build_py y luego build_ext directamente.
Así que, posiblemente, una mejor solución sea crear una subclase tanto del comando de compilación como de instalación, y asegurarse de que build_ext se ejecute al inicio de ambos.
from distutils.command.build import build
from setuptools.command.install import install
class CustomBuild(build):
def run(self):
self.run_command(''build_ext'')
build.run(self)
class CustomInstall(install):
def run(self):
self.run_command(''build_ext'')
self.do_egg_install()
setup(
cmdclass={''build'': CustomBuild, ''install'': CustomInstall},
py_modules=[''module1''],
ext_modules=[module1]
)
No parece que deba preocuparse por que build_ext se ejecute dos veces.
Estoy usando distutils para crear un rpm de mi proyecto. Tengo este árbol de directorios:
project/
my_module/
data/file.dat
my_module1.py
my_module2.py
src/
header1.h
header2.h
ext_module1.cpp
ext_module2.cpp
swig_module.i
setup.py
MANIFEST.in
MANIFEST
mi setup.py
:
from distutils.core import setup, Extension
module1 = Extension(''my_module._module'',
sources=[''src/ext_module1.cpp'',
''src/ext_module2.cpp'',
''src/swig_module.i''],
swig_opts=[''-c++'', ''-py3''],
include_dirs=[...],
runtime_library_dirs=[...],
libraries=[...],
extra_compile_args=[''-Wno-write-strings''])
setup( name = ''my_module'',
version = ''0.6'',
author = ''microo8'',
author_email = ''[email protected]'',
description = '''',
license = ''GPLv3'',
url = '''',
platforms = [''x86_64''],
ext_modules = [module1],
packages = [''my_module''],
package_dir = {''my_module'': ''my_module''},
package_data = {''my_module'': [''data/*.dat'']} )
mi archivo MANIFEST.in
:
include src/header1.h
include src/header2.h
El archivo MANIFEST
es generado automáticamente por python3 setup.py sdist
. Y cuando ejecuto python3 setup.py bdist_rpm
compila y crea los paquetes rpm correctos. Pero el problema es que cuando estoy ejecutando SWIG en una fuente C ++, crea un archivo module.py
que envuelve el archivo binario _module.cpython32-mu.so
, se crea con el archivo module_wrap.cpp
y no se copia en el archivo. directorio my_module
.
¿Qué debo escribir en el archivo setup.py
para copiar automáticamente los módulos de Python generados por SWIG?
Y también tengo otra pregunta: cuando instalo el paquete rpm, quiero que se cree un archivo ejecutable, en /usr/bin
, para ejecutar la aplicación (por ejemplo, si my_module/my_module1.py
es el script de inicio de la aplicación entonces puedo ejecutar en bash: $ my_module1
).
No es una respuesta completa, porque no tengo la solución completa. La razón por la que el módulo no se copia en el directorio de instalación es porque no estaba presente cuando el proceso de instalación intentó copiarlo. La secuencia de eventos es:
running install
running build
running build_py
file my_module.py (for module my_module) not found
file vcanmapper.py (for module vcanmapper) not found
running build_ext
Si ejecuta python setup.py install
segunda vez, hará lo que quiera en primer lugar. La documentación oficial de SWIG para Python propone que ejecute primero swig
para generar el archivo de setup.py install
, y luego ejecute setup.py install
para realizar la instalación real.
Parece que tienes que agregar una opción py_modules
, por ejemplo:
setup(...,
ext_modules=[Extension(''_foo'', [''foo.i''],
swig_opts=[''-modern'', ''-I../include''])],
py_modules=[''foo''],
)
Al utilizar rpm para instalar scripts del sistema en Linux , tendrá que modificar su archivo de especificaciones. La sección %files
le dice a rpm
dónde colocar los archivos, que puede mover o vincular en %post
, pero esto se puede definir en setup.py
usando:
options = {''bdist_rpm'':{''post_install'':''post_install'', ''post_uninstall'':''post_uninstall''}},
La ejecución de scripts de Python en Bash se puede hacer con la primera línea habitual como #!/usr/bin/python
y bit ejecutable en el archivo utilizando chmod +x filename
.