diff --git a/extensions/uboot-binman-fix-pkg-resources.sh b/extensions/uboot-binman-fix-pkg-resources.sh new file mode 100644 index 000000000000..a8ad96fef7ef --- /dev/null +++ b/extensions/uboot-binman-fix-pkg-resources.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash +# +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (c) 2013-2026 Igor Pecovnik, igor@armbian.com +# +# This file is a part of the Armbian Build Framework +# https://github.com/armbian/build/ +# +# Fix binman's use of pkg_resources (removed in setuptools >= 82) +# by migrating to importlib.resources. +# +# Safe for all U-Boot versions: no-op if pkg_resources is not used. +# Can be removed once all BOOTBRANCH versions are >= v2025.10. + +function pre_config_uboot_target__fix_binman_pkg_resources() { + local control_py="tools/binman/control.py" + + # Skip if file doesn't exist or doesn't use pkg_resources + [[ -f "${control_py}" ]] || return 0 + grep -q 'import pkg_resources' "${control_py}" || return 0 + + display_alert "Patching binman" "migrating pkg_resources to importlib.resources" "info" + + python3 << 'PYTHON_SCRIPT' +import re + +control_py = "tools/binman/control.py" + +with open(control_py, "r") as f: + content = f.read() + +# 1. Remove "import pkg_resources" line +content = re.sub(r'^import pkg_resources\b[^\n]*\n', '', content, flags=re.MULTILINE) + +# 2. Ensure importlib_resources alias is available +has_importlib_alias = 'importlib_resources' in content +has_importlib_dotted = re.search(r'^import importlib\.resources\s*$', content, flags=re.MULTILINE) + +if not has_importlib_alias and has_importlib_dotted: + # New U-Boot (v2024.01+): has "import importlib.resources" without alias + content = re.sub( + r'^import importlib\.resources\s*$', + 'import importlib.resources as importlib_resources', + content, count=1, flags=re.MULTILINE + ) + # Update existing dotted usage to use the alias + content = re.sub(r'\bimportlib\.resources\.', 'importlib_resources.', content) +elif not has_importlib_alias: + # Old U-Boot (<=v2023.x): no importlib.resources at all + import_block = ( + 'try:\n' + ' import importlib.resources as importlib_resources\n' + ' importlib_resources.files\n' + 'except (ImportError, AttributeError):\n' + ' import importlib_resources\n' + ) + # Insert after the last top-level import line + lines = content.split('\n') + last_import_idx = 0 + for i, line in enumerate(lines): + if re.match(r'^(?:import |from \S+ import )', line): + last_import_idx = i + lines.insert(last_import_idx + 1, import_block) + content = '\n'.join(lines) + +# 3. Replace pkg_resources.resource_string(__name__, X) +# with importlib_resources.files(__package__).joinpath(X).read_bytes() +content = re.sub( + r'pkg_resources\.resource_string\s*\(\s*__name__\s*,\s*(.+?)\s*\)', + r'importlib_resources.files(__package__).joinpath(\1).read_bytes()', + content +) + +# 4. Replace pkg_resources.resource_listdir(__name__, X) +# with [r.name for r in importlib_resources.files(__package__).joinpath(X).iterdir() if r.is_file()] +content = re.sub( + r'pkg_resources\.resource_listdir\s*\(\s*__name__\s*,\s*(.+?)\s*\)', + r'[r.name for r in importlib_resources.files(__package__).joinpath(\1).iterdir() if r.is_file()]', + content +) + +with open(control_py, "w") as f: + f.write(content) + +print("binman control.py patched successfully") +PYTHON_SCRIPT +} diff --git a/lib/functions/configuration/main-config.sh b/lib/functions/configuration/main-config.sh index 3b276d07fbd3..b718492eed78 100644 --- a/lib/functions/configuration/main-config.sh +++ b/lib/functions/configuration/main-config.sh @@ -65,6 +65,9 @@ function do_main_configuration() { # Armbian config is central tool used in all builds. As its build externally, we have moved it to extension. Enable it here. enable_extension "armbian-config" + # Fix binman pkg_resources removal in setuptools >= 82. Can be removed when all U-Boot versions are >= v2025.10. + enable_extension "uboot-binman-fix-pkg-resources" + # Network stack to use, default to network-manager; configuration can override this. # Will be made read-only further down. declare -g NETWORKING_STACK="${NETWORKING_STACK}" diff --git a/requirements.txt b/requirements.txt index 279a7f8becc0..2edcf99d860f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,7 +6,7 @@ # Dependabot will keep these versions up to date. pip == 26.0.1 # pip is the package installer for Python -setuptools == 80.10.2 # for building Python packages +setuptools == 82.0.1 # for building Python packages pyelftools == 0.32 # for building U-Boot unidiff == 0.7.5 # for parsing unified diff GitPython == 3.1.46 # for manipulating git repos