From 1168c6c8e21c170011e872bd4955298eced7d1fb Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sun, 10 May 2026 06:18:42 +0200 Subject: [PATCH] modemd: package Python scripts for compiled deployment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Python scripts without a .py extension are never cached as bytecode by CPython — every invocation re-parses the source. Packaging as a wheel pre-compiles all modules to .pyc and installs thin import stubs as the executables, matching the approach used by bin/show and statd. Restructure the modemd Python scripts into a proper Python package (src/modemd/modemd/): each script becomes a module with a main() entry point. pyproject.toml declares 11 entry points; the Buildroot MODEMD_BUILD_PYTHON hook builds a wheel via PEP 517, then pyinstaller.py installs compiled stubs to /usr/libexec/modemd/ and pre-compiled .pyc modules to site-packages. /sbin/modemd is now a symlink to the compiled stub. Signed-off-by: Joachim Wiberg --- package/modemd/modemd.mk | 35 ++++++++++++------- src/modemd/{modemd => modemd/__init__.py} | 9 +++-- .../{modem-carrier => modemd/carrier.py} | 8 +++-- src/modemd/{modem-info => modemd/info.py} | 8 +++-- src/modemd/{modem-power => modemd/power.py} | 8 +++-- src/modemd/{modem-rpc => modemd/rpc.py} | 8 +++-- .../scan_networks.py} | 9 +++-- src/modemd/{sim-setup => modemd/sim_setup.py} | 8 +++-- src/modemd/{modem-sms => modemd/sms.py} | 8 +++-- src/modemd/{modem-udev => modemd/udev.py} | 9 +++-- .../update_firmware.py} | 9 +++-- src/modemd/{modem-ussd => modemd/ussd.py} | 9 +++-- src/modemd/pyproject.toml | 28 +++++++++++++++ 13 files changed, 111 insertions(+), 45 deletions(-) rename src/modemd/{modemd => modemd/__init__.py} (99%) mode change 100755 => 100644 rename src/modemd/{modem-carrier => modemd/carrier.py} (99%) mode change 100755 => 100644 rename src/modemd/{modem-info => modemd/info.py} (99%) mode change 100755 => 100644 rename src/modemd/{modem-power => modemd/power.py} (98%) mode change 100755 => 100644 rename src/modemd/{modem-rpc => modemd/rpc.py} (97%) mode change 100755 => 100644 rename src/modemd/{modem-scan-networks => modemd/scan_networks.py} (97%) mode change 100755 => 100644 rename src/modemd/{sim-setup => modemd/sim_setup.py} (99%) mode change 100755 => 100644 rename src/modemd/{modem-sms => modemd/sms.py} (99%) mode change 100755 => 100644 rename src/modemd/{modem-udev => modemd/udev.py} (99%) mode change 100755 => 100644 rename src/modemd/{modem-update-firmware => modemd/update_firmware.py} (99%) mode change 100755 => 100644 rename src/modemd/{modem-ussd => modemd/ussd.py} (97%) mode change 100755 => 100644 create mode 100644 src/modemd/pyproject.toml diff --git a/package/modemd/modemd.mk b/package/modemd/modemd.mk index 8b84dfac..afe36c13 100644 --- a/package/modemd/modemd.mk +++ b/package/modemd/modemd.mk @@ -10,13 +10,34 @@ MODEMD_SITE = $(BR2_EXTERNAL_INFIX_PATH)/src/modemd MODEMD_LICENSE = BSD-3-Clause MODEMD_LICENSE_FILES = LICENSE MODEMD_REDISTRIBUTE = NO -MODEMD_DEPENDENCIES = modem-manager jansson python3 +MODEMD_DEPENDENCIES = modem-manager jansson python3 \ + host-python3 host-python-pypa-build host-python-installer \ + host-python-poetry-core define MODEMD_BUILD_CMDS $(TARGET_CC) $(TARGET_CFLAGS) $(TARGET_LDFLAGS) \ $(MODEMD_DIR)/modem-command.c -o $(MODEMD_DIR)/modem-command -ljansson endef +define MODEMD_BUILD_PYTHON + cd $(MODEMD_SITE) && \ + $(PKG_PYTHON_PEP517_ENV) $(HOST_DIR)/bin/python3 $(PKG_PYTHON_PEP517_BUILD_CMD) -o $(@D)/dist + mkdir -p $(TARGET_DIR)/usr/libexec/modemd + rm -f $(TARGET_DIR)/usr/libexec/modemd/modemd \ + $(TARGET_DIR)/usr/libexec/modemd/modem-* \ + $(TARGET_DIR)/usr/libexec/modemd/sim-setup + cd $(@D) && \ + $(HOST_DIR)/bin/python3 $(TOPDIR)/support/scripts/pyinstaller.py \ + dist/*.whl \ + --interpreter=/usr/bin/python3 \ + --script-kind=posix \ + --purelib=$(TARGET_DIR)/usr/lib/python$(PYTHON3_VERSION_MAJOR)/site-packages \ + --headers=$(TARGET_DIR)/usr/include/python$(PYTHON3_VERSION_MAJOR) \ + --scripts=$(TARGET_DIR)/usr/libexec/modemd \ + --data=$(TARGET_DIR) +endef +MODEMD_POST_INSTALL_TARGET_HOOKS += MODEMD_BUILD_PYTHON + define MODEMD_INSTALL_TARGET_CMDS mkdir -p $(TARGET_DIR)/usr/libexec/modemd mkdir -p $(TARGET_DIR)/lib/udev/rules.d @@ -27,18 +48,8 @@ define MODEMD_INSTALL_TARGET_CMDS install -m 644 $(MODEMD_DIR)/qmi-wwan-ids.rules $(TARGET_DIR)/lib/udev/rules.d/91-qmi-wwan-ids.rules install -m 644 $(MODEMD_DIR)/77-mm-dell-port-types.rules $(TARGET_DIR)/etc/udev/rules.d/77-mm-dell-port-types.rules install -D -m 644 $(MODEMD_DIR)/modemd.modules-load $(TARGET_DIR)/etc/modules-load.d/modemd.conf - install -m 755 $(MODEMD_DIR)/modem-udev $(TARGET_DIR)/usr/libexec/modemd/ - install -m 755 $(MODEMD_DIR)/modemd $(TARGET_DIR)/sbin/modemd install -m 755 $(MODEMD_DIR)/modem-command $(TARGET_DIR)/sbin/modem-command - install -m 755 $(MODEMD_DIR)/modem-info $(TARGET_DIR)/usr/libexec/modemd/ - install -m 755 $(MODEMD_DIR)/modem-rpc $(TARGET_DIR)/usr/libexec/modemd/ - install -m 755 $(MODEMD_DIR)/modem-sms $(TARGET_DIR)/usr/libexec/modemd/ - install -m 755 $(MODEMD_DIR)/modem-scan-networks $(TARGET_DIR)/usr/libexec/modemd/ - install -m 755 $(MODEMD_DIR)/modem-update-firmware $(TARGET_DIR)/usr/libexec/modemd/ - install -m 755 $(MODEMD_DIR)/modem-ussd $(TARGET_DIR)/usr/libexec/modemd/ - install -m 755 $(MODEMD_DIR)/modem-carrier $(TARGET_DIR)/usr/libexec/modemd/ - install -m 755 $(MODEMD_DIR)/modem-power $(TARGET_DIR)/usr/libexec/modemd/ - install -m 755 $(MODEMD_DIR)/sim-setup $(TARGET_DIR)/usr/libexec/modemd/ + ln -sf /usr/libexec/modemd/modemd $(TARGET_DIR)/sbin/modemd endef $(eval $(generic-package)) diff --git a/src/modemd/modemd b/src/modemd/modemd/__init__.py old mode 100755 new mode 100644 similarity index 99% rename from src/modemd/modemd rename to src/modemd/modemd/__init__.py index fee12bec..b3409453 --- a/src/modemd/modemd +++ b/src/modemd/modemd/__init__.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - import threading import subprocess import argparse @@ -1625,7 +1623,8 @@ def sighandler(signum, frame): fatal("Exiting on signal %d" % signum) -if __name__ == "__main__": +def main(): + global debug syslog.openlog(logoption=syslog.LOG_PID, facility=syslog.LOG_DAEMON) if os.geteuid() != 0: @@ -1692,3 +1691,7 @@ if __name__ == "__main__": [th.join() for th in threads] fatal("Abnormal exit") + + +if __name__ == "__main__": + main() diff --git a/src/modemd/modem-carrier b/src/modemd/modemd/carrier.py old mode 100755 new mode 100644 similarity index 99% rename from src/modemd/modem-carrier rename to src/modemd/modemd/carrier.py index d5cc8507..d966978c --- a/src/modemd/modem-carrier +++ b/src/modemd/modemd/carrier.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - import subprocess import argparse import json @@ -272,7 +270,7 @@ def runlist(index, manf, model): sys.exit(0) -if __name__ == "__main__": +def main(): parser = argparse.ArgumentParser(prog='modem-carrier') parser.add_argument("-i", "--index", default=0, help="Modem index") parser.add_argument("-m", "--manf", default=0, help="Modem manufacturer") @@ -312,3 +310,7 @@ if __name__ == "__main__": runget(index, manf, model) sys.exit(0) + + +if __name__ == "__main__": + main() diff --git a/src/modemd/modem-info b/src/modemd/modemd/info.py old mode 100755 new mode 100644 similarity index 99% rename from src/modemd/modem-info rename to src/modemd/modemd/info.py index 65b71394..6de9b958 --- a/src/modemd/modem-info +++ b/src/modemd/modemd/info.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - import subprocess import argparse import syslog @@ -531,7 +529,7 @@ def print_all(): print(data) -if __name__ == "__main__": +def main(): parser = argparse.ArgumentParser(prog='modem-info') parser.add_argument("-i", "--index", default=0, help="Modem index") args = parser.parse_args() @@ -545,3 +543,7 @@ if __name__ == "__main__": print_modem(int(args.index)) else: print_all() + + +if __name__ == "__main__": + main() diff --git a/src/modemd/modem-power b/src/modemd/modemd/power.py old mode 100755 new mode 100644 similarity index 98% rename from src/modemd/modem-power rename to src/modemd/modemd/power.py index 9bcb67a0..3cc3e22e --- a/src/modemd/modem-power +++ b/src/modemd/modemd/power.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - import subprocess import argparse import json @@ -65,7 +63,7 @@ def reset(index, info): return True -if __name__ == "__main__": +def main(): parser = argparse.ArgumentParser(prog='modem-power') parser.add_argument("-i", "--index", default=0, help="Modem index") args = parser.parse_args() @@ -84,3 +82,7 @@ if __name__ == "__main__": fatal("Unable to power-cycle modem") sys.exit(0) + + +if __name__ == "__main__": + main() diff --git a/src/modemd/modem-rpc b/src/modemd/modemd/rpc.py old mode 100755 new mode 100644 similarity index 97% rename from src/modemd/modem-rpc rename to src/modemd/modemd/rpc.py index ff9f86eb..58707a9c --- a/src/modemd/modem-rpc +++ b/src/modemd/modemd/rpc.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - import argparse import json import sys @@ -21,7 +19,7 @@ def sendrpc(index, rpc): os.unlink(path) -if __name__ == "__main__": +def main(): parser = argparse.ArgumentParser(prog='modem-rpc') parser.add_argument("-i", "--index", default=0, help="Modem index") parser.add_argument("-r", "--rpc", default=0, help="RPC command") @@ -48,3 +46,7 @@ if __name__ == "__main__": } sendrpc(index, rpc) + + +if __name__ == "__main__": + main() diff --git a/src/modemd/modem-scan-networks b/src/modemd/modemd/scan_networks.py old mode 100755 new mode 100644 similarity index 97% rename from src/modemd/modem-scan-networks rename to src/modemd/modemd/scan_networks.py index 288e7fa6..377e8826 --- a/src/modemd/modem-scan-networks +++ b/src/modemd/modemd/scan_networks.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - import argparse import subprocess import json @@ -65,7 +63,8 @@ def scan(mpath): return True -if __name__ == "__main__": +def main(): + global index parser = argparse.ArgumentParser(prog='modem-scan-networks') parser.add_argument("-i", "--index", default=0, help="Modem index") args = parser.parse_args() @@ -77,3 +76,7 @@ if __name__ == "__main__": print("Scanning networks on modem%d, please stand by ..." % index) if not scan(m["path"]): print("Operation failed.", file=sys.stderr) + + +if __name__ == "__main__": + main() diff --git a/src/modemd/sim-setup b/src/modemd/modemd/sim_setup.py old mode 100755 new mode 100644 similarity index 99% rename from src/modemd/sim-setup rename to src/modemd/modemd/sim_setup.py index a19b4a51..edf86e46 --- a/src/modemd/sim-setup +++ b/src/modemd/modemd/sim_setup.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - import subprocess import json import fcntl @@ -254,7 +252,7 @@ def read_setup(): return setup -if __name__ == "__main__": +def main(): setup = read_setup() if setup is None: sys.exit(0) @@ -263,3 +261,7 @@ if __name__ == "__main__": fatal("Unable set up SIMs") sys.exit(0) + + +if __name__ == "__main__": + main() diff --git a/src/modemd/modem-sms b/src/modemd/modemd/sms.py old mode 100755 new mode 100644 similarity index 99% rename from src/modemd/modem-sms rename to src/modemd/modemd/sms.py index cf6c8b42..5735abad --- a/src/modemd/modem-sms +++ b/src/modemd/modemd/sms.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - from datetime import datetime import argparse import locale @@ -106,7 +104,7 @@ def listlocale(): return ", ".join(locales) -if __name__ == "__main__": +def main(): parser = argparse.ArgumentParser(prog='modem-sms') parser.add_argument("-d", action="store_true", help="Delete SMS") parser.add_argument("-s", action="store_true", help="Send SMS") @@ -140,3 +138,7 @@ if __name__ == "__main__": delete(index) else: show(index) + + +if __name__ == "__main__": + main() diff --git a/src/modemd/modem-udev b/src/modemd/modemd/udev.py old mode 100755 new mode 100644 similarity index 99% rename from src/modemd/modem-udev rename to src/modemd/modemd/udev.py index 64d6b1e2..aaf6d3c2 --- a/src/modemd/modem-udev +++ b/src/modemd/modemd/udev.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - import shutil import errno import time @@ -283,7 +281,8 @@ def apply(): return True -if __name__ == "__main__": +def main(): + global debug with open("/proc/cmdline", 'r') as fd: cmdline = fd.read() if "debug" in cmdline: @@ -314,3 +313,7 @@ if __name__ == "__main__": dbg("ended") sys.exit(rc) + + +if __name__ == "__main__": + main() diff --git a/src/modemd/modem-update-firmware b/src/modemd/modemd/update_firmware.py old mode 100755 new mode 100644 similarity index 99% rename from src/modemd/modem-update-firmware rename to src/modemd/modemd/update_firmware.py index b8675108..d7eb46c4 --- a/src/modemd/modem-update-firmware +++ b/src/modemd/modemd/update_firmware.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - import subprocess import argparse import urllib.parse @@ -347,7 +345,8 @@ def download(url, checksum): return True -if __name__ == "__main__": +def main(): + global debug, index syslog.openlog(logoption=syslog.LOG_PID, facility=syslog.LOG_DAEMON) parser = argparse.ArgumentParser(prog='modem-firmware-update') @@ -387,3 +386,7 @@ if __name__ == "__main__": fatal("Firmware update failed") rmdir(tempdir) + + +if __name__ == "__main__": + main() diff --git a/src/modemd/modem-ussd b/src/modemd/modemd/ussd.py old mode 100755 new mode 100644 similarity index 97% rename from src/modemd/modem-ussd rename to src/modemd/modemd/ussd.py index e1b1e10c..2940f96e --- a/src/modemd/modem-ussd +++ b/src/modemd/modemd/ussd.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - import argparse import subprocess import sys @@ -49,7 +47,8 @@ def ussd(index, code): return True -if __name__ == "__main__": +def main(): + global verbose parser = argparse.ArgumentParser(prog='modem-ussd') parser.add_argument("-i", "--index", default=0, help="Modem index") parser.add_argument("-c", "--code", default=None, help="USSD codec") @@ -70,3 +69,7 @@ if __name__ == "__main__": sys.exit(0) sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/src/modemd/pyproject.toml b/src/modemd/pyproject.toml new file mode 100644 index 00000000..553b9757 --- /dev/null +++ b/src/modemd/pyproject.toml @@ -0,0 +1,28 @@ +[tool.poetry] +name = "modemd" +version = "1.0" +description = "Infix modem daemon and utilities" +license = "BSD-3-Clause" +packages = [ + { include = "modemd" } +] +authors = [ + "KernelKit developers" +] + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" + +[tool.poetry.scripts] +modemd = "modemd:main" +modem-info = "modemd.info:main" +modem-carrier = "modemd.carrier:main" +modem-rpc = "modemd.rpc:main" +modem-sms = "modemd.sms:main" +modem-scan-networks = "modemd.scan_networks:main" +modem-update-firmware = "modemd.update_firmware:main" +modem-ussd = "modemd.ussd:main" +modem-power = "modemd.power:main" +modem-udev = "modemd.udev:main" +sim-setup = "modemd.sim_setup:main"