features_check.bbclass 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. # Allow checking of required and conflicting features
  2. #
  3. # xxx = [DISTRO,MACHINE,COMBINED]
  4. #
  5. # ANY_OF_xxx_FEATURES: ensure at least one item on this list is included
  6. # in xxx_FEATURES.
  7. # REQUIRED_xxx_FEATURES: ensure every item on this list is included
  8. # in xxx_FEATURES.
  9. # CONFLICT_xxx_FEATURES: ensure no item in this list is included in
  10. # xxx_FEATURES.
  11. #
  12. # Copyright 2019 (C) Texas Instruments Inc.
  13. # Copyright 2013 (C) O.S. Systems Software LTDA.
  14. python () {
  15. if d.getVar('PARSE_ALL_RECIPES', False):
  16. return
  17. unused = True
  18. for kind in ['DISTRO', 'MACHINE', 'COMBINED']:
  19. if d.getVar('ANY_OF_' + kind + '_FEATURES') is None and \
  20. d.overridedata.get('ANY_OF_' + kind + '_FEATURES') is None and \
  21. d.getVar('REQUIRED_' + kind + '_FEATURES') is None and \
  22. d.overridedata.get('REQUIRED_' + kind + '_FEATURES') is None and \
  23. d.getVar('CONFLICT_' + kind + '_FEATURES') is None and \
  24. d.overridedata.get('CONFLICT_' + kind + '_FEATURES') is None:
  25. continue
  26. unused = False
  27. # Assume at least one var is set.
  28. features = set((d.getVar(kind + '_FEATURES') or '').split())
  29. any_of_features = set((d.getVar('ANY_OF_' + kind + '_FEATURES') or '').split())
  30. if any_of_features:
  31. if set.isdisjoint(any_of_features, features):
  32. raise bb.parse.SkipRecipe("one of '%s' needs to be in %s_FEATURES"
  33. % (' '.join(any_of_features), kind))
  34. required_features = set((d.getVar('REQUIRED_' + kind + '_FEATURES') or '').split())
  35. if required_features:
  36. missing = set.difference(required_features, features)
  37. if missing:
  38. raise bb.parse.SkipRecipe("missing required %s feature%s '%s' (not in %s_FEATURES)"
  39. % (kind.lower(), 's' if len(missing) > 1 else '', ' '.join(missing), kind))
  40. conflict_features = set((d.getVar('CONFLICT_' + kind + '_FEATURES') or '').split())
  41. if conflict_features:
  42. conflicts = set.intersection(conflict_features, features)
  43. if conflicts:
  44. raise bb.parse.SkipRecipe("conflicting %s feature%s '%s' (in %s_FEATURES)"
  45. % (kind.lower(), 's' if len(conflicts) > 1 else '', ' '.join(conflicts), kind))
  46. if unused:
  47. bb.warn("Recipe inherits features_check but doesn't use it")
  48. }