python/python3: globalize *.pyc files compilation
Currently, each python package (be it the python interpreter package itself or external python modules) is responsible for compiling its .py into .pyc files. Unfortunately, this is not ideal as some packages only install .py files without compiling them into .pyc files. In this case, if the Buildroot configuration specifies to keep only the .pyc files, the .py files are removed and lost. To address this, this commit changes the logic by making the compilation of .pyc files a global operation: the python interpreter packages register a target finalize hook that is in charge of compiling all installed .py files. The *.pyc generation on a per package basis is disabled in the python-package infrastructure by passing the "--no-compile" option to setup.py. The *.pyc generation for the Python interpreter internal modules is disabled through --disable-pyc-build configure option. A small helper script is used to perform the compilation, the purpose of this script is to abort the compilation process if one of the .py file cannot be compiled. It has been provided by Samuel Martin and integrated into this commit. Signed-off-by: Yegor Yefremov <yegorslists@googlemail.com> Cc: Samuel Martin <s.martin49@gmail.com> [Thomas: - rework for python 3.5 - integrate Samuel proposal that allows to detect compilation failures.] Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> Reviewed-by: Samuel Martin <s.martin49@gmail.com> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
This commit is contained in:
parent
4cf16166c0
commit
549bbba67f
@ -253,7 +253,7 @@ ifndef $(2)_INSTALL_TARGET_CMDS
|
|||||||
define $(2)_INSTALL_TARGET_CMDS
|
define $(2)_INSTALL_TARGET_CMDS
|
||||||
(cd $$($$(PKG)_BUILDDIR)/; \
|
(cd $$($$(PKG)_BUILDDIR)/; \
|
||||||
$$($$(PKG)_BASE_ENV) $$($$(PKG)_ENV) \
|
$$($$(PKG)_BASE_ENV) $$($$(PKG)_ENV) \
|
||||||
$$($(2)_PYTHON_INTERPRETER) setup.py install \
|
$$($(2)_PYTHON_INTERPRETER) setup.py install --no-compile \
|
||||||
$$($$(PKG)_BASE_INSTALL_TARGET_OPTS) \
|
$$($$(PKG)_BASE_INSTALL_TARGET_OPTS) \
|
||||||
$$($$(PKG)_INSTALL_TARGET_OPTS))
|
$$($$(PKG)_INSTALL_TARGET_OPTS))
|
||||||
endef
|
endef
|
||||||
|
@ -143,7 +143,8 @@ PYTHON_CONF_OPTS += \
|
|||||||
--disable-tk \
|
--disable-tk \
|
||||||
--disable-nis \
|
--disable-nis \
|
||||||
--disable-dbm \
|
--disable-dbm \
|
||||||
--disable-pyo-build
|
--disable-pyo-build \
|
||||||
|
--disable-pyc-build
|
||||||
|
|
||||||
# This is needed to make sure the Python build process doesn't try to
|
# This is needed to make sure the Python build process doesn't try to
|
||||||
# regenerate those files with the pgen program. Otherwise, it builds
|
# regenerate those files with the pgen program. Otherwise, it builds
|
||||||
@ -217,6 +218,17 @@ PYTHON_PATH = $(TARGET_DIR)/usr/lib/python$(PYTHON_VERSION_MAJOR)/sysconfigdata/
|
|||||||
$(eval $(autotools-package))
|
$(eval $(autotools-package))
|
||||||
$(eval $(host-autotools-package))
|
$(eval $(host-autotools-package))
|
||||||
|
|
||||||
|
define PYTHON_CREATE_PYC_FILES
|
||||||
|
PYTHONPATH="$(PYTHON_PATH)" \
|
||||||
|
$(HOST_DIR)/usr/bin/python$(PYTHON_VERSION_MAJOR) \
|
||||||
|
support/scripts/pycompile.py \
|
||||||
|
$(TARGET_DIR)/usr/lib/python$(PYTHON_VERSION_MAJOR)
|
||||||
|
endef
|
||||||
|
|
||||||
|
ifeq ($(BR2_PACKAGE_PYTHON_PYC_ONLY)$(BR2_PACKAGE_PYTHON_PY_PYC),y)
|
||||||
|
TARGET_FINALIZE_HOOKS += PYTHON_CREATE_PYC_FILES
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(BR2_PACKAGE_PYTHON_PYC_ONLY),y)
|
ifeq ($(BR2_PACKAGE_PYTHON_PYC_ONLY),y)
|
||||||
define PYTHON_REMOVE_PY_FILES
|
define PYTHON_REMOVE_PY_FILES
|
||||||
find $(TARGET_DIR)/usr/lib/python$(PYTHON_VERSION_MAJOR) -name '*.py' -print0 | \
|
find $(TARGET_DIR)/usr/lib/python$(PYTHON_VERSION_MAJOR) -name '*.py' -print0 | \
|
||||||
@ -225,6 +237,8 @@ endef
|
|||||||
TARGET_FINALIZE_HOOKS += PYTHON_REMOVE_PY_FILES
|
TARGET_FINALIZE_HOOKS += PYTHON_REMOVE_PY_FILES
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# Normally, *.pyc files should not have been compiled, but just in
|
||||||
|
# case, we make sure we remove all of them.
|
||||||
ifeq ($(BR2_PACKAGE_PYTHON_PY_ONLY),y)
|
ifeq ($(BR2_PACKAGE_PYTHON_PY_ONLY),y)
|
||||||
define PYTHON_REMOVE_PYC_FILES
|
define PYTHON_REMOVE_PYC_FILES
|
||||||
find $(TARGET_DIR)/usr/lib/python$(PYTHON_VERSION_MAJOR) -name '*.pyc' -print0 | \
|
find $(TARGET_DIR)/usr/lib/python$(PYTHON_VERSION_MAJOR) -name '*.pyc' -print0 | \
|
||||||
|
@ -78,10 +78,6 @@ ifeq ($(BR2_PACKAGE_PYTHON3_PYC_ONLY),y)
|
|||||||
PYTHON3_CONF_OPTS += --enable-old-stdlib-cache
|
PYTHON3_CONF_OPTS += --enable-old-stdlib-cache
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(BR2_PACKAGE_PYTHON3_PY_ONLY),y)
|
|
||||||
PYTHON3_CONF_OPTS += --disable-pyc-build
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(BR2_PACKAGE_PYTHON3_SQLITE),y)
|
ifeq ($(BR2_PACKAGE_PYTHON3_SQLITE),y)
|
||||||
PYTHON3_DEPENDENCIES += sqlite
|
PYTHON3_DEPENDENCIES += sqlite
|
||||||
else
|
else
|
||||||
@ -135,7 +131,8 @@ PYTHON3_CONF_OPTS += \
|
|||||||
--disable-lib2to3 \
|
--disable-lib2to3 \
|
||||||
--disable-tk \
|
--disable-tk \
|
||||||
--disable-nis \
|
--disable-nis \
|
||||||
--disable-idle3
|
--disable-idle3 \
|
||||||
|
--disable-pyc-build
|
||||||
|
|
||||||
# Python builds two tools to generate code: 'pgen' and
|
# Python builds two tools to generate code: 'pgen' and
|
||||||
# '_freeze_importlib'. Unfortunately, for the target Python, they are
|
# '_freeze_importlib'. Unfortunately, for the target Python, they are
|
||||||
@ -212,6 +209,17 @@ PYTHON3_PATH = $(TARGET_DIR)/usr/lib/python$(PYTHON3_VERSION_MAJOR)/sysconfigdat
|
|||||||
$(eval $(autotools-package))
|
$(eval $(autotools-package))
|
||||||
$(eval $(host-autotools-package))
|
$(eval $(host-autotools-package))
|
||||||
|
|
||||||
|
define PYTHON3_CREATE_PYC_FILES
|
||||||
|
PYTHONPATH="$(PYTHON3_PATH)" \
|
||||||
|
$(HOST_DIR)/usr/bin/python$(PYTHON3_VERSION_MAJOR) \
|
||||||
|
support/scripts/pycompile.py \
|
||||||
|
$(TARGET_DIR)/usr/lib/python$(PYTHON3_VERSION_MAJOR)
|
||||||
|
endef
|
||||||
|
|
||||||
|
ifeq ($(BR2_PACKAGE_PYTHON3_PYC_ONLY)$(BR2_PACKAGE_PYTHON3_PY_PYC),y)
|
||||||
|
TARGET_FINALIZE_HOOKS += PYTHON3_CREATE_PYC_FILES
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(BR2_PACKAGE_PYTHON3_PYC_ONLY),y)
|
ifeq ($(BR2_PACKAGE_PYTHON3_PYC_ONLY),y)
|
||||||
define PYTHON3_REMOVE_PY_FILES
|
define PYTHON3_REMOVE_PY_FILES
|
||||||
find $(TARGET_DIR)/usr/lib/python$(PYTHON3_VERSION_MAJOR) -name '*.py' -print0 | \
|
find $(TARGET_DIR)/usr/lib/python$(PYTHON3_VERSION_MAJOR) -name '*.py' -print0 | \
|
||||||
@ -220,6 +228,8 @@ endef
|
|||||||
TARGET_FINALIZE_HOOKS += PYTHON3_REMOVE_PY_FILES
|
TARGET_FINALIZE_HOOKS += PYTHON3_REMOVE_PY_FILES
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# Normally, *.pyc files should not have been compiled, but just in
|
||||||
|
# case, we make sure we remove all of them.
|
||||||
ifeq ($(BR2_PACKAGE_PYTHON3_PY_ONLY),y)
|
ifeq ($(BR2_PACKAGE_PYTHON3_PY_ONLY),y)
|
||||||
define PYTHON3_REMOVE_PYC_FILES
|
define PYTHON3_REMOVE_PYC_FILES
|
||||||
find $(TARGET_DIR)/usr/lib/python$(PYTHON3_VERSION_MAJOR) -name '*.pyc' -print0 | \
|
find $(TARGET_DIR)/usr/lib/python$(PYTHON3_VERSION_MAJOR) -name '*.pyc' -print0 | \
|
||||||
|
24
support/scripts/pycompile.py
Normal file
24
support/scripts/pycompile.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# Wrapper for python2 and python3 around compileall to raise exception
|
||||||
|
# when a python byte code generation failed.
|
||||||
|
#
|
||||||
|
# Inspired from:
|
||||||
|
# http://stackoverflow.com/questions/615632/how-to-detect-errors-from-compileall-compile-dir
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
import sys
|
||||||
|
import py_compile
|
||||||
|
import compileall
|
||||||
|
|
||||||
|
class ReportProblem:
|
||||||
|
def __nonzero__(self):
|
||||||
|
type, value, traceback = sys.exc_info()
|
||||||
|
if type is not None and issubclass(type, py_compile.PyCompileError):
|
||||||
|
print("Cannot compile %s" %value.file)
|
||||||
|
raise value
|
||||||
|
return 1
|
||||||
|
|
||||||
|
report_problem = ReportProblem()
|
||||||
|
|
||||||
|
compileall.compile_dir(sys.argv[1], quiet=report_problem)
|
Loading…
Reference in New Issue
Block a user