0c5472ace2
This script checks for inconsistencies on symbols declared in Config.in and used in .mk files. Currently it checks only symbols following the pattern BR2_\w+ . The script first gets the list of all files in the repository (using git ls-files like 'make check-flake8' already do). Then it parses all relevant files, searching for symbol definitions and usages, and add entries into a database. At the end, the database is searched for inconsistencies: - symbol that is part of "choice" and is referenced with "select"; - legacy symbol being referenced in packages; - legacy symbol being redefined in packages; - symbol referenced but not defined; - symbol defined but not referenced; - legacy symbol that has a Note stating it is referenced by a package (for legacy handling) but is referenced in the package without a comment "# legacy"; - legacy symbol that has a Note stating it is referenced by a package but it is not actually referenced. There is also a debug parameter --search that dumps any filename or symbol entries from the database that matches a regexp. Sample usages: $ utils/check-symbols $ utils/docker-run utils/check-symbols $ utils/check-symbols --search 'GETTEXT\b|\/openssl' At same time the script is created: - add unit tests for it, they can be run using: utils/docker-run python3 -m pytest -v utils/checksymbolslib/ - add two more GitLab CI jobs: check-symbols (to check current tree using the script) and check-check-symbols (to check the script against its unit tests) Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com> Signed-off-by: Ricardo Martincoski <ricardo.martincoski@gmail.com> [Peter: print warnings to stderr, rename change_current_dir() to change_to_top_dir()] Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
141 lines
4.4 KiB
Python
141 lines
4.4 KiB
Python
import os
|
|
import re
|
|
|
|
|
|
ignored_directories = [
|
|
'support/testing/',
|
|
]
|
|
# Makefile
|
|
symbols_used_only_in_source_code = [
|
|
'BR2_USE_CCACHE',
|
|
]
|
|
# package/skeleton/Config.in
|
|
symbols_used_only_for_host_variant = [
|
|
'BR2_PACKAGE_SKELETON',
|
|
]
|
|
# Makefile
|
|
# package/pkg-generic.mk
|
|
symbols_defined_only_at_command_line = [
|
|
'BR2_GRAPH_ALT',
|
|
'BR2_GRAPH_DEPS_OPTS',
|
|
'BR2_GRAPH_DOT_OPTS',
|
|
'BR2_GRAPH_OUT',
|
|
'BR2_GRAPH_SIZE_OPTS',
|
|
'BR2_INSTRUMENTATION_SCRIPTS',
|
|
]
|
|
# Makefile
|
|
symbols_defined_only_when_using_br2_external = [
|
|
'BR2_EXTERNAL',
|
|
'BR2_EXTERNAL_DIRS',
|
|
'BR2_EXTERNAL_MKS',
|
|
'BR2_EXTERNAL_NAMES',
|
|
]
|
|
# boot/barebox/barebox.mk
|
|
symbols_defined_only_for_barebox_variant = [
|
|
'BR2_TARGET_BAREBOX_AUX_BAREBOXENV',
|
|
]
|
|
# toolchain/toolchain/toolchain.mk
|
|
# toolchain/toolchain-buildroot/toolchain-buildroot.mk
|
|
symbols_not_defined_for_fake_virtual_packages = [
|
|
'BR2_PACKAGE_HAS_TOOLCHAIN',
|
|
'BR2_PACKAGE_HAS_TOOLCHAIN_BUILDROOT',
|
|
'BR2_PACKAGE_PROVIDES_TOOLCHAIN',
|
|
'BR2_PACKAGE_PROVIDES_TOOLCHAIN_BUILDROOT',
|
|
]
|
|
# fs/common.mk
|
|
suffixes_not_defined_for_all_rootfs_types = [
|
|
'_BZIP2',
|
|
'_GZIP',
|
|
'_LZ4',
|
|
'_LZMA',
|
|
'_LZO',
|
|
'_XZ',
|
|
'_ZSTD',
|
|
]
|
|
# fs/common.mk
|
|
rootfs_prefix = 'BR2_TARGET_ROOTFS_'
|
|
# package/pkg-generic.mk
|
|
package_prefix = 'BR2_PACKAGE_'
|
|
# package/pkg-generic.mk
|
|
boot_prefix = 'BR2_TARGET_'
|
|
# package/pkg-generic.mk
|
|
toolchain_prefix = 'BR2_'
|
|
# boot/barebox/barebox.mk
|
|
barebox_infra_suffixes = [
|
|
'',
|
|
'_BAREBOXENV',
|
|
'_BOARD_DEFCONFIG',
|
|
'_CONFIG_FRAGMENT_FILES',
|
|
'_CUSTOM_CONFIG_FILE',
|
|
'_CUSTOM_EMBEDDED_ENV_PATH',
|
|
'_CUSTOM_ENV',
|
|
'_CUSTOM_ENV_PATH',
|
|
'_IMAGE_FILE',
|
|
'_USE_CUSTOM_CONFIG',
|
|
'_USE_DEFCONFIG',
|
|
]
|
|
re_kconfig_symbol = re.compile(r'\b(BR2_\w+)\b')
|
|
# Example lines to be handled:
|
|
# config BR2_TOOLCHAIN_EXTERNAL_PREFIX
|
|
# menuconfig BR2_PACKAGE_GST1_PLUGINS_BASE
|
|
re_kconfig_config = re.compile(r'^\s*(menu|)config\s+(BR2_\w+)')
|
|
# Example lines to be handled:
|
|
# default "uclibc" if BR2_TOOLCHAIN_BUILDROOT_UCLIBC
|
|
# default BR2_TARGET_GRUB2_BUILTIN_MODULES if BR2_TARGET_GRUB2_BUILTIN_MODULES != ""
|
|
# default y if BR2_HOSTARCH = "powerpc"
|
|
re_kconfig_default = re.compile(r'^\s*default\s')
|
|
re_kconfig_default_before_conditional = re.compile(r'^.*\bif\b')
|
|
re_kconfig_default_legacy_comment = re.compile(r'#\s*legacy')
|
|
# Example lines to be handled:
|
|
# depends on !(BR2_TOOLCHAIN_USES_GLIBC && BR2_TOOLCHAIN_USES_MUSL)
|
|
# depends on BR2_HOSTARCH = "x86_64" || BR2_HOSTARCH = "x86"
|
|
re_kconfig_depends = re.compile(r'^\s*depends on\s')
|
|
# Example lines to be handled:
|
|
# select BR2_PACKAGE_HOST_NODEJS if BR2_PACKAGE_NODEJS_MODULES_ADDITIONAL != ""
|
|
# select BR2_PACKAGE_LIBDRM if !(BR2_arm && BR2_PACKAGE_IMX_GPU_VIV_OUTPUT_FB)
|
|
# select BR2_PACKAGE_OPENSSL if !(BR2_PACKAGE_GNUTLS || BR2_PACKAGE_MBEDTLS)
|
|
re_kconfig_select = re.compile(r'^\s*select\s')
|
|
re_kconfig_select_conditional = re.compile(r'\bif\s.*')
|
|
# Example lines to be handled:
|
|
# if !BR2_SKIP_LEGACY
|
|
# if (BR2_PACKAGE_FREESCALE_IMX_PLATFORM_IMX51 || BR2_PACKAGE_FREESCALE_IMX_PLATFORM_IMX53)
|
|
# if BR2_PACKAGE_HAS_LUAINTERPRETER && !BR2_STATIC_LIBS
|
|
# if BR2_PACKAGE_QEMU_CUSTOM_TARGETS = ""
|
|
re_kconfig_if = re.compile(r'^\s*if\s')
|
|
# Example lines to be handled:
|
|
# source "$BR2_BASE_DIR/.br2-external.in.jpeg"
|
|
re_kconfig_source = re.compile(r'^\s*source\b')
|
|
|
|
re_kconfig_choice = re.compile(r'^\s*choice\b')
|
|
re_kconfig_endchoice = re.compile(r'^\s*endchoice\b')
|
|
re_makefile_eval = re.compile(r'^\s*\$\(eval\b')
|
|
re_menu = re.compile(r'^\s*menu\b')
|
|
re_endmenu = re.compile(r'^\s*endmenu\b')
|
|
re_comments = re.compile(r'#.*$')
|
|
re_legacy_special_comment = re.compile(r'#.*(BR2_\w+)\s.*still referenced')
|
|
re_host_symbol = re.compile(r'(BR2_PACKAGE_HOST_\w+|BR2_PACKAGE_HAS_HOST_\w+)')
|
|
re_makefile_symbol_usage = re.compile(r'\$\((BR2_\w+)\)')
|
|
re_makefile_symbol_export = re.compile(r'export\s*(BR2_\w+)')
|
|
re_makefile_symbol_attribution = re.compile(r'^\s*(BR2_\w+)\s*[?:=]')
|
|
|
|
|
|
def get_package_from_filename(filename):
|
|
package = os.path.basename(filename)[:-3].upper().replace('-', '_')
|
|
return package
|
|
|
|
|
|
def is_an_optional_symbol_for_a_roofts(symbol):
|
|
if not symbol.startswith(rootfs_prefix):
|
|
return False
|
|
for sufix in suffixes_not_defined_for_all_rootfs_types:
|
|
if symbol.endswith(sufix):
|
|
return True
|
|
return False
|
|
|
|
|
|
def file_belongs_to_an_ignored_diretory(filename):
|
|
for d in ignored_directories:
|
|
if filename.startswith(d):
|
|
return True
|
|
return False
|