Skip to content

Commit 81065cf

Browse files
Grzegorz SwiderskiChromeos LUCI
authored andcommitted
scripts: ci: check_compliance: Add sysbuild Kconfig checks
Introduce sysbuild-specific variants of existing Kconfig checks: * SysbuildKconfig * SysbuildKconfigBasic * SysbuildKconfigBasicNoModules This involves a few additions to the base `KconfigCheck` class: * Supporting a variable symbol prefix, to handle `SB_CONFIG_`. * Generating extra files, including `Kconfig.sysbuild.modules`. Although these are never sourced outside of sysbuild Kconfig, they're still generated for every regular Zephyr build, so it's natural to let all Kconfig checks follow this behavior. (cherry picked from commit 7ce6ac2) Original-Signed-off-by: Grzegorz Swiderski <[email protected]> GitOrigin-RevId: 7ce6ac2 Cr-Build-Id: 8725452993329915921 Cr-Build-Url: https://cr-buildbucket.appspot.com/build/8725452993329915921 Copybot-Job-Name: zephyr-main-copybot-downstream Change-Id: Id5a7033e17412e4bbf2ad2ab6860801d95017779 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/zephyr/+/6183331 Tested-by: ChromeOS Prod (Robot) <[email protected]> Reviewed-by: Jonathon Murphy <[email protected]> Commit-Queue: Jonathon Murphy <[email protected]>
1 parent e5eef06 commit 81065cf

File tree

3 files changed

+72
-7
lines changed

3 files changed

+72
-7
lines changed

.github/workflows/compliance.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ jobs:
8282
git log --pretty=oneline | head -n 10
8383
# Increase rename limit to allow for large PRs
8484
git config diff.renameLimit 10000
85-
./scripts/ci/check_compliance.py --annotate -e KconfigBasic -e ClangFormat \
85+
./scripts/ci/check_compliance.py --annotate -e KconfigBasic -e SysbuildKconfigBasic -e ClangFormat \
8686
-c origin/${BASE_REF}..
8787
8888
- name: upload-results

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,5 +104,8 @@ Nits.txt
104104
Pylint.txt
105105
Ruff.txt
106106
SphinxLint.txt
107+
SysbuildKconfig.txt
108+
SysbuildKconfigBasic.txt
109+
SysbuildKconfigBasicNoModules.txt
107110
TextEncoding.txt
108111
YAMLLint.txt

scripts/ci/check_compliance.py

Lines changed: 68 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,9 @@ class KconfigCheck(ComplianceTest):
374374
# Top-level Kconfig file. The path can be relative to srctree (ZEPHYR_BASE).
375375
FILENAME = "Kconfig"
376376

377+
# Kconfig symbol prefix/namespace.
378+
CONFIG_ = "CONFIG_"
379+
377380
def run(self):
378381
kconf = self.parse_kconfig()
379382

@@ -385,7 +388,7 @@ def run(self):
385388
self.check_soc_name_sync(kconf)
386389
self.check_no_undef_outside_kconfig(kconf)
387390

388-
def get_modules(self, modules_file, settings_file):
391+
def get_modules(self, modules_file, sysbuild_modules_file, settings_file):
389392
"""
390393
Get a list of modules and put them in a file that is parsed by
391394
Kconfig
@@ -398,7 +401,9 @@ def get_modules(self, modules_file, settings_file):
398401
zephyr_module_path = os.path.join(ZEPHYR_BASE, "scripts",
399402
"zephyr_module.py")
400403
cmd = [sys.executable, zephyr_module_path,
401-
'--kconfig-out', modules_file, '--settings-out', settings_file]
404+
'--kconfig-out', modules_file,
405+
'--sysbuild-kconfig-out', sysbuild_modules_file,
406+
'--settings-out', settings_file]
402407
try:
403408
subprocess.run(cmd, check=True, stdout=subprocess.PIPE,
404409
stderr=subprocess.STDOUT)
@@ -485,6 +490,7 @@ def get_v2_model(self, kconfig_dir, settings_file):
485490

486491
kconfig_file = os.path.join(kconfig_dir, 'boards', 'Kconfig')
487492
kconfig_boards_file = os.path.join(kconfig_dir, 'boards', 'Kconfig.boards')
493+
kconfig_sysbuild_file = os.path.join(kconfig_dir, 'boards', 'Kconfig.sysbuild')
488494
kconfig_defconfig_file = os.path.join(kconfig_dir, 'boards', 'Kconfig.defconfig')
489495

490496
board_roots = self.get_module_setting_root('board', settings_file)
@@ -501,6 +507,11 @@ def get_v2_model(self, kconfig_dir, settings_file):
501507
for board_dir in board.directories:
502508
fp.write('osource "' + (board_dir / 'Kconfig.defconfig').as_posix() + '"\n')
503509

510+
with open(kconfig_sysbuild_file, 'w') as fp:
511+
for board in v2_boards:
512+
for board_dir in board.directories:
513+
fp.write('osource "' + (board_dir / 'Kconfig.sysbuild').as_posix() + '"\n')
514+
504515
with open(kconfig_boards_file, 'w') as fp:
505516
for board in v2_boards:
506517
board_str = 'BOARD_' + re.sub(r"[^a-zA-Z0-9_]", "_", board.name).upper()
@@ -522,6 +533,7 @@ def get_v2_model(self, kconfig_dir, settings_file):
522533
fp.write('osource "' + (board_dir / 'Kconfig').as_posix() + '"\n')
523534

524535
kconfig_defconfig_file = os.path.join(kconfig_dir, 'soc', 'Kconfig.defconfig')
536+
kconfig_sysbuild_file = os.path.join(kconfig_dir, 'soc', 'Kconfig.sysbuild')
525537
kconfig_soc_file = os.path.join(kconfig_dir, 'soc', 'Kconfig.soc')
526538
kconfig_file = os.path.join(kconfig_dir, 'soc', 'Kconfig')
527539

@@ -533,6 +545,10 @@ def get_v2_model(self, kconfig_dir, settings_file):
533545
for folder in soc_folders:
534546
fp.write('osource "' + (Path(folder) / 'Kconfig.defconfig').as_posix() + '"\n')
535547

548+
with open(kconfig_sysbuild_file, 'w') as fp:
549+
for folder in soc_folders:
550+
fp.write('osource "' + (Path(folder) / 'Kconfig.sysbuild').as_posix() + '"\n')
551+
536552
with open(kconfig_soc_file, 'w') as fp:
537553
for folder in soc_folders:
538554
fp.write('source "' + (Path(folder) / 'Kconfig.soc').as_posix() + '"\n')
@@ -587,6 +603,7 @@ def parse_kconfig(self):
587603

588604
# For multi repo support
589605
self.get_modules(os.path.join(kconfiglib_dir, "Kconfig.modules"),
606+
os.path.join(kconfiglib_dir, "Kconfig.sysbuild.modules"),
590607
os.path.join(kconfiglib_dir, "settings_file.txt"))
591608
# For Kconfig.dts support
592609
self.get_kconfig_dts(os.path.join(kconfiglib_dir, "Kconfig.dts"),
@@ -833,7 +850,7 @@ def check_no_undef_outside_kconfig(self, kconf):
833850
undef_to_locs = collections.defaultdict(list)
834851

835852
# Warning: Needs to work with both --perl-regexp and the 're' module
836-
regex = r"\bCONFIG_[A-Z0-9_]+\b(?!\s*##|[$@{(.*])"
853+
regex = r"\b" + self.CONFIG_ + r"[A-Z0-9_]+\b(?!\s*##|[$@{(.*])"
837854

838855
# Skip doc/releases and doc/security/vulnerabilities.rst, which often
839856
# reference removed symbols
@@ -849,7 +866,7 @@ def check_no_undef_outside_kconfig(self, kconf):
849866
# Extract symbol references (might be more than one) within the
850867
# line
851868
for sym_name in re.findall(regex, line):
852-
sym_name = sym_name[7:] # Strip CONFIG_
869+
sym_name = sym_name[len(self.CONFIG_):] # Strip CONFIG_
853870
if sym_name not in defined_syms and \
854871
sym_name not in self.UNDEF_KCONFIG_ALLOWLIST and \
855872
not (sym_name.endswith("_MODULE") and sym_name[:-7] in defined_syms):
@@ -865,7 +882,7 @@ def check_no_undef_outside_kconfig(self, kconf):
865882
#
866883
# CONFIG_ALSO_MISSING arch/xtensa/core/fatal.c:273
867884
# CONFIG_MISSING arch/xtensa/core/fatal.c:264, subsys/fb/cfb.c:20
868-
undef_desc = "\n".join(f"CONFIG_{sym_name:35} {', '.join(locs)}"
885+
undef_desc = "\n".join(f"{self.CONFIG_}{sym_name:35} {', '.join(locs)}"
869886
for sym_name, locs in sorted(undef_to_locs.items()))
870887

871888
self.failure(f"""
@@ -1031,10 +1048,13 @@ class KconfigBasicNoModulesCheck(KconfigBasicCheck):
10311048
"""
10321049
name = "KconfigBasicNoModules"
10331050

1034-
def get_modules(self, modules_file, settings_file):
1051+
def get_modules(self, modules_file, sysbuild_modules_file, settings_file):
10351052
with open(modules_file, 'w') as fp_module_file:
10361053
fp_module_file.write("# Empty\n")
10371054

1055+
with open(sysbuild_modules_file, 'w') as fp_module_file:
1056+
fp_module_file.write("# Empty\n")
1057+
10381058

10391059
class KconfigHWMv2Check(KconfigBasicCheck):
10401060
"""
@@ -1050,6 +1070,48 @@ class KconfigHWMv2Check(KconfigBasicCheck):
10501070
FILENAME = os.path.join(os.path.dirname(__file__), "Kconfig.board.v2")
10511071

10521072

1073+
class SysbuildKconfigCheck(KconfigCheck):
1074+
"""
1075+
Checks if we are introducing any new warnings/errors with sysbuild Kconfig,
1076+
for example using undefined Kconfig variables.
1077+
"""
1078+
name = "SysbuildKconfig"
1079+
1080+
FILENAME = "share/sysbuild/Kconfig"
1081+
CONFIG_ = "SB_CONFIG_"
1082+
1083+
# A different allowlist is used for symbols prefixed with SB_CONFIG_ (omitted here).
1084+
UNDEF_KCONFIG_ALLOWLIST = {
1085+
# zephyr-keep-sorted-start re(^\s+")
1086+
"FOO",
1087+
"SECOND_SAMPLE", # Used in sysbuild documentation
1088+
"SUIT_ENVELOPE", # Used by nRF runners to program provisioning data
1089+
"SUIT_MPI_APP_AREA_PATH", # Used by nRF runners to program provisioning data
1090+
"SUIT_MPI_GENERATE", # Used by nRF runners to program provisioning data
1091+
"SUIT_MPI_RAD_AREA_PATH", # Used by nRF runners to program provisioning data
1092+
# zephyr-keep-sorted-stop
1093+
}
1094+
1095+
1096+
class SysbuildKconfigBasicCheck(SysbuildKconfigCheck, KconfigBasicCheck):
1097+
"""
1098+
Checks if we are introducing any new warnings/errors with sysbuild Kconfig,
1099+
for example using undefined Kconfig variables.
1100+
This runs the basic Kconfig test, which is checking only for undefined
1101+
references inside the sysbuild Kconfig tree.
1102+
"""
1103+
name = "SysbuildKconfigBasic"
1104+
1105+
1106+
class SysbuildKconfigBasicNoModulesCheck(SysbuildKconfigCheck, KconfigBasicNoModulesCheck):
1107+
"""
1108+
Checks if we are introducing any new warnings/errors with sysbuild Kconfig
1109+
when no modules are available. Catches symbols used in the main repository
1110+
but defined only in a module.
1111+
"""
1112+
name = "SysbuildKconfigBasicNoModules"
1113+
1114+
10531115
class Nits(ComplianceTest):
10541116
"""
10551117
Checks various nits in added/modified files. Doesn't check stuff that's

0 commit comments

Comments
 (0)