__init__.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. """
  2. BitBake Parsers
  3. File parsers for the BitBake build tools.
  4. """
  5. # Copyright (C) 2003, 2004 Chris Larson
  6. # Copyright (C) 2003, 2004 Phil Blundell
  7. #
  8. # SPDX-License-Identifier: GPL-2.0-only
  9. #
  10. # Based on functions from the base bb module, Copyright 2003 Holger Schurig
  11. #
  12. handlers = []
  13. import errno
  14. import logging
  15. import os
  16. import stat
  17. import bb
  18. import bb.utils
  19. import bb.siggen
  20. logger = logging.getLogger("BitBake.Parsing")
  21. class ParseError(Exception):
  22. """Exception raised when parsing fails"""
  23. def __init__(self, msg, filename, lineno=0):
  24. self.msg = msg
  25. self.filename = filename
  26. self.lineno = lineno
  27. Exception.__init__(self, msg, filename, lineno)
  28. def __str__(self):
  29. if self.lineno:
  30. return "ParseError at %s:%d: %s" % (self.filename, self.lineno, self.msg)
  31. else:
  32. return "ParseError in %s: %s" % (self.filename, self.msg)
  33. class SkipRecipe(Exception):
  34. """Exception raised to skip this recipe"""
  35. class SkipPackage(SkipRecipe):
  36. """Exception raised to skip this recipe (use SkipRecipe in new code)"""
  37. __mtime_cache = {}
  38. def cached_mtime(f):
  39. if f not in __mtime_cache:
  40. __mtime_cache[f] = os.stat(f)[stat.ST_MTIME]
  41. return __mtime_cache[f]
  42. def cached_mtime_noerror(f):
  43. if f not in __mtime_cache:
  44. try:
  45. __mtime_cache[f] = os.stat(f)[stat.ST_MTIME]
  46. except OSError:
  47. return 0
  48. return __mtime_cache[f]
  49. def update_mtime(f):
  50. try:
  51. __mtime_cache[f] = os.stat(f)[stat.ST_MTIME]
  52. except OSError:
  53. if f in __mtime_cache:
  54. del __mtime_cache[f]
  55. return 0
  56. return __mtime_cache[f]
  57. def update_cache(f):
  58. if f in __mtime_cache:
  59. logger.debug(1, "Updating mtime cache for %s" % f)
  60. update_mtime(f)
  61. def clear_cache():
  62. global __mtime_cache
  63. __mtime_cache = {}
  64. def mark_dependency(d, f):
  65. if f.startswith('./'):
  66. f = "%s/%s" % (os.getcwd(), f[2:])
  67. deps = (d.getVar('__depends', False) or [])
  68. s = (f, cached_mtime_noerror(f))
  69. if s not in deps:
  70. deps.append(s)
  71. d.setVar('__depends', deps)
  72. def check_dependency(d, f):
  73. s = (f, cached_mtime_noerror(f))
  74. deps = (d.getVar('__depends', False) or [])
  75. return s in deps
  76. def supports(fn, data):
  77. """Returns true if we have a handler for this file, false otherwise"""
  78. for h in handlers:
  79. if h['supports'](fn, data):
  80. return 1
  81. return 0
  82. def handle(fn, data, include = 0):
  83. """Call the handler that is appropriate for this file"""
  84. for h in handlers:
  85. if h['supports'](fn, data):
  86. with data.inchistory.include(fn):
  87. return h['handle'](fn, data, include)
  88. raise ParseError("not a BitBake file", fn)
  89. def init(fn, data):
  90. for h in handlers:
  91. if h['supports'](fn):
  92. return h['init'](data)
  93. def init_parser(d):
  94. bb.parse.siggen = bb.siggen.init(d)
  95. def resolve_file(fn, d):
  96. if not os.path.isabs(fn):
  97. bbpath = d.getVar("BBPATH")
  98. newfn, attempts = bb.utils.which(bbpath, fn, history=True)
  99. for af in attempts:
  100. mark_dependency(d, af)
  101. if not newfn:
  102. raise IOError(errno.ENOENT, "file %s not found in %s" % (fn, bbpath))
  103. fn = newfn
  104. else:
  105. mark_dependency(d, fn)
  106. if not os.path.isfile(fn):
  107. raise IOError(errno.ENOENT, "file %s not found" % fn)
  108. return fn
  109. # Used by OpenEmbedded metadata
  110. __pkgsplit_cache__={}
  111. def vars_from_file(mypkg, d):
  112. if not mypkg or not mypkg.endswith((".bb", ".bbappend")):
  113. return (None, None, None)
  114. if mypkg in __pkgsplit_cache__:
  115. return __pkgsplit_cache__[mypkg]
  116. myfile = os.path.splitext(os.path.basename(mypkg))
  117. parts = myfile[0].split('_')
  118. __pkgsplit_cache__[mypkg] = parts
  119. if len(parts) > 3:
  120. raise ParseError("Unable to generate default variables from filename (too many underscores)", mypkg)
  121. exp = 3 - len(parts)
  122. tmplist = []
  123. while exp != 0:
  124. exp -= 1
  125. tmplist.append(None)
  126. parts.extend(tmplist)
  127. return parts
  128. def get_file_depends(d):
  129. '''Return the dependent files'''
  130. dep_files = []
  131. depends = d.getVar('__base_depends', False) or []
  132. depends = depends + (d.getVar('__depends', False) or [])
  133. for (fn, _) in depends:
  134. dep_files.append(os.path.abspath(fn))
  135. return " ".join(dep_files)
  136. from bb.parse.parse_py import __version__, ConfHandler, BBHandler