From d06a388e59c6a0b49634e3490be529358b3bf5b4 Mon Sep 17 00:00:00 2001 From: Bryan Forbes Date: Sun, 20 Sep 2026 14:06:28 -0500 Subject: [PATCH] fix(python-evdev): build ecodes.py on host The build for `python-evdev` relies on generating, compiling, and importing a C extension module called `_ecodes` during the build process to then generate a static `ecodes` Python module. If that fails, `ecodes_runtime` is copied to `ecodes` and importing it at runtime builds the static dicts on the fly. The problem is that when cross-compiling, the `_ecodes` module is built for the target and may not be importable on the host, so the build falls back to `ecodes_runtime`. For smaller ARM boards build on x86_64, this can cause a large runtime cost when importing `ecodes` because the structures are built on the fly instead of being pre-built. This change adds a host build of `python-evdev` to generate `_ecodes.so` for the host (which allows the static `ecodes.py` to be generated), and the target uses the generated `ecodes.py` from the host build instead of falling back to `ecodes_runtime.py`. The host build uses the same headers as the target build, so the generated `ecodes.py` is valid for the target. --- package/python-evdev/python-evdev.mk | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/package/python-evdev/python-evdev.mk b/package/python-evdev/python-evdev.mk index 169055ab27f..35e89def8de 100644 --- a/package/python-evdev/python-evdev.mk +++ b/package/python-evdev/python-evdev.mk @@ -11,8 +11,31 @@ PYTHON_EVDEV_SETUP_TYPE = setuptools PYTHON_EVDEV_LICENSE = Revised BSD License PYTHON_EVDEV_LICENSE_FILES = LICENSE +# batocera - Build python-evdev for the host so we get a generated ecodes.py with +# static dicts instead of using ecodes_runtime.py (which builds the dicts on the fly +# when it is first imported) +PYTHON_EVDEV_DEPENDENCIES = host-python-evdev + PYTHON_EVDEV_BUILD_OPTS = \ -C--build-option=build_ecodes \ -C--build-option=--evdev-headers=$(STAGING_DIR)/usr/include/linux/input.h:$(STAGING_DIR)/usr/include/linux/input-event-codes.h:$(STAGING_DIR)/usr/include/linux/uinput.h +# batocera - Build with the headers in staging so the generated ecodes.py is for the target +HOST_PYTHON_EVDEV_BUILD_OPTS = \ + -C--build-option=build_ecodes \ + -C--build-option=--evdev-headers=$(STAGING_DIR)/usr/include/linux/input.h:$(STAGING_DIR)/usr/include/linux/input-event-codes.h:$(STAGING_DIR)/usr/include/linux/uinput.h + +# batocera - For cross-compilation, we need to install the ecodes.py that was generated on +# the host because the target generation will fail due to the evdev build process trying to +# import the target ecodes.so. Since both the host and the target build with the same headers, +# the source of the module will be the same and the host build process will generate +# a static ecodes.py (rather than copy the dynamic ecodes_runtime.py). +define PYTHON_EVDEV_INSTALL_ECODES_MODULE + $(INSTALL) -m 0644 $(HOST_DIR)/usr/lib/python$(PYTHON3_VERSION_MAJOR)/site-packages/evdev/ecodes.py \ + $(TARGET_DIR)/usr/lib/python$(PYTHON3_VERSION_MAJOR)/site-packages/evdev +endef +PYTHON_EVDEV_POST_INSTALL_TARGET_HOOKS += PYTHON_EVDEV_INSTALL_ECODES_MODULE + $(eval $(python-package)) +# batocera - add a host package for python-evdev so we can generate the ecodes.py module on the host +$(eval $(host-python-package))