Browse Source

scripts: zephyr modules: introducing Zephyr module dependency handling

This commit introduces the possibility of adding dependencies between
Zephyr modules to ensure that a Zephyr module on which other modules
depends is processed first.

The dependency chain is ordered using a topological sort.

This allows to add dependencies to a zephyr/module.yml as:

build:
  cmake: .
  depends:
    - fatfs

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
pull/26140/head
Torsten Rasmussen 5 years ago committed by Carles Cufí
parent
commit
3917ee51a9
  1. 52
      scripts/zephyr_module.py

52
scripts/zephyr_module.py

@ -25,6 +25,7 @@ import pykwalify.core @@ -25,6 +25,7 @@ import pykwalify.core
import subprocess
import re
from pathlib import Path, PurePath
from collections import namedtuple
METADATA_SCHEMA = '''
## A pykwalify schema for basic validation of the structure of a
@ -44,6 +45,11 @@ mapping: @@ -44,6 +45,11 @@ mapping:
kconfig:
required: false
type: str
depends:
required: false
type: seq
sequence:
- type: str
tests:
required: false
type: seq
@ -215,6 +221,14 @@ def main(): @@ -215,6 +221,14 @@ def main():
cmake = ""
sanitycheck = ""
Module = namedtuple('Module', ['project', 'meta', 'depends'])
# dep_modules is a list of all modules that has an unresolved dependency
dep_modules = []
# start_modules is a list modules with no depends left (no incoming edge)
start_modules = []
# sorted_modules is a topological sorted list of the modules
sorted_modules = []
for project in projects:
# Avoid including Zephyr base project as module.
if project == os.environ.get('ZEPHYR_BASE'):
@ -222,13 +236,45 @@ def main(): @@ -222,13 +236,45 @@ def main():
meta = process_module(project)
if meta:
kconfig += process_kconfig(project, meta)
cmake += process_cmake(project, meta)
sanitycheck += process_sanitycheck(project, meta)
section = meta.get('build', dict())
deps = section.get('depends', [])
if not deps:
start_modules.append(Module(project, meta, []))
else:
dep_modules.append(Module(project, meta, deps))
elif project in extra_modules:
sys.exit(f'{project}, given in ZEPHYR_EXTRA_MODULES, '
'is not a valid zephyr module')
# This will do a topological sort to ensure the modules are ordered
# according to dependency settings.
while start_modules:
node = start_modules.pop(0)
sorted_modules.append(node)
node_name = PurePath(node.project).name
to_remove = []
for module in dep_modules:
if node_name in module.depends:
module.depends.remove(node_name)
if not module.depends:
start_modules.append(module)
to_remove.append(module)
for module in to_remove:
dep_modules.remove(module)
if dep_modules:
# If there are any modules with unresolved dependencies, then the
# modules contains unmet or cyclic dependencies. Error out.
error = 'Unmet or cyclic dependencies in modules:\n'
for module in dep_modules:
error += f'{module.project} depends on: {module.depends}\n'
sys.exit(error)
for module in sorted_modules:
kconfig += process_kconfig(module.project, module.meta)
cmake += process_cmake(module.project, module.meta)
sanitycheck += process_sanitycheck(module.project, module.meta)
if args.kconfig_out:
with open(args.kconfig_out, 'w', encoding="utf-8") as fp:
fp.write(kconfig)

Loading…
Cancel
Save