summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChen Qi <Qi.Chen@windriver.com>2025-04-17 01:05:14 -0700
committerKhem Raj <raj.khem@gmail.com>2025-04-19 14:36:05 -0700
commit93a6ada53c0ea49ea7b22163cf6a6d5e80c3b278 (patch)
treed6835cd122cf9b45ac7b6172324195e50a91e6a6
parent62d3384378db0d96d123168e10723ff9fd756f1f (diff)
downloadmeta-openembedded-93a6ada53c0ea49ea7b22163cf6a6d5e80c3b278.tar.gz
check-version-mismatch.bbclass: handle non-elf executables
Using qemu to run non-elf executables such as shell scripts directly is destined to fail. In such case, we check its interperter and try out best to run it accordingly. We'll also need to skip the "/etc" directory as files under it are configuration files and init scripts. And the init script will send SIGTERM and SIGKILL to all processes, giving users annoying behavior. Signed-off-by: Chen Qi <Qi.Chen@windriver.com> Signed-off-by: Khem Raj <raj.khem@gmail.com>
-rw-r--r--meta-oe/classes/check-version-mismatch.bbclass60
1 files changed, 60 insertions, 0 deletions
diff --git a/meta-oe/classes/check-version-mismatch.bbclass b/meta-oe/classes/check-version-mismatch.bbclass
index 154e86b4d0..1237855b43 100644
--- a/meta-oe/classes/check-version-mismatch.bbclass
+++ b/meta-oe/classes/check-version-mismatch.bbclass
@@ -13,6 +13,7 @@ python do_package_check_version_mismatch() {
13 import subprocess 13 import subprocess
14 import shutil 14 import shutil
15 import signal 15 import signal
16 import glob
16 17
17 classes_skip = ["nopackage", "image", "native", "cross", "crosssdk", "cross-canadian"] 18 classes_skip = ["nopackage", "image", "native", "cross", "crosssdk", "cross-canadian"]
18 for cs in classes_skip: 19 for cs in classes_skip:
@@ -173,6 +174,42 @@ python do_package_check_version_mismatch() {
173 else: 174 else:
174 return True 175 return True
175 176
177 def is_elf_binary(fexec):
178 fexec_real = os.path.realpath(fexec)
179 elf = oe.qa.ELFFile(fexec_real)
180 try:
181 elf.open()
182 elf.close()
183 return True
184 except:
185 return False
186
187 def get_shebang(fexec):
188 try:
189 with open(fexec, 'r') as f:
190 first_line = f.readline().strip()
191 if first_line.startswith("#!"):
192 return first_line
193 else:
194 return None
195 except Exception as e:
196 return None
197
198 def get_interpreter_from_shebang(shebang):
199 if not shebang:
200 return None
201 hosttools_path = d.getVar("TMPDIR") + "/hosttools"
202 if "/sh" in shebang:
203 return hosttools_path + "/sh"
204 elif "/bash" in shebang:
205 return hosttools_path + "/bash"
206 elif "python" in shebang:
207 return hosttools_path + "/python3"
208 elif "perl" in shebang:
209 return hosttools_path + "/perl"
210 else:
211 return None
212
176 # helper function to get PKGV, useful for recipes such as perf 213 # helper function to get PKGV, useful for recipes such as perf
177 def get_pkgv(pn): 214 def get_pkgv(pn):
178 pkgdestwork = d.getVar("PKGDESTWORK") 215 pkgdestwork = d.getVar("PKGDESTWORK")
@@ -275,6 +312,9 @@ python do_package_check_version_mismatch() {
275 return 312 return
276 313
277 skipped_directories = [".debug", "ptest", "installed-tests", "tests", "test", "__pycache__", "testcases"] 314 skipped_directories = [".debug", "ptest", "installed-tests", "tests", "test", "__pycache__", "testcases"]
315 # avoid checking configuration files, they don't give useful version information and some init scripts
316 # will kill all processes
317 skipped_directories.append("etc")
278 pkgd_libdir = pkgd + d.getVar("libdir") 318 pkgd_libdir = pkgd + d.getVar("libdir")
279 pkgd_base_libdir = pkgd + d.getVar("base_libdir") 319 pkgd_base_libdir = pkgd + d.getVar("base_libdir")
280 extra_exec_libdirs = [] 320 extra_exec_libdirs = []
@@ -312,8 +352,28 @@ python do_package_check_version_mismatch() {
312 # first we extend qemu_exec to include library path if needed 352 # first we extend qemu_exec to include library path if needed
313 if extra_exec_libdirs: 353 if extra_exec_libdirs:
314 qemu_exec += ":" + ":".join(extra_exec_libdirs) 354 qemu_exec += ":" + ":".join(extra_exec_libdirs)
355 orig_qemu_exec = qemu_exec
315 for fexec in executables: 356 for fexec in executables:
357 qemu_exec = orig_qemu_exec
316 for version_option in ["--version", "-V", "-v", "--help"]: 358 for version_option in ["--version", "-V", "-v", "--help"]:
359 if not is_elf_binary(fexec):
360 shebang = get_shebang(fexec)
361 interpreter = get_interpreter_from_shebang(shebang)
362 if not interpreter:
363 bb.debug(1, "file %s is not supported to run" % fexec)
364 elif interpreter.endswith("perl"):
365 perl5lib_extra = pkgd + d.getVar("libdir") + "/perl5/site_perl"
366 for p in glob.glob("%s/usr/share/*" % pkgd):
367 perl5lib_extra += ":%s" % p
368 qemu_exec += " -E PERL5LIB=%s:$PERL5LIB %s" % (perl5lib_extra, interpreter)
369 elif interpreter.endswith("python3"):
370 pythonpath_extra = glob.glob("%s%s/python3*/site-packages" % (pkgd, d.getVar("libdir")))
371 if pythonpath_extra:
372 qemu_exec += " -E PYTHONPATH=%s:$PYTHONPATH %s" % (pythonpath_extra[0], interpreter)
373 else:
374 qemu_exec += " %s" % interpreter
375 # remove the '-E LD_LIBRARY_PATH=xxx'
376 qemu_exec = re.sub(r"-E\s+LD_LIBRARY_PATH=\S+", "", qemu_exec)
317 version_check_cmd_full = "%s %s %s" % (qemu_exec, fexec, version_option) 377 version_check_cmd_full = "%s %s %s" % (qemu_exec, fexec, version_option)
318 version_check_cmd = version_check_cmd_full 378 version_check_cmd = version_check_cmd_full
319 #version_check_cmd = "%s %s" % (os.path.relpath(fexec, pkgd), version_option) 379 #version_check_cmd = "%s %s" % (os.path.relpath(fexec, pkgd), version_option)