diff options
| author | Chen Qi <Qi.Chen@windriver.com> | 2025-04-17 01:05:14 -0700 |
|---|---|---|
| committer | Khem Raj <raj.khem@gmail.com> | 2025-04-19 14:36:05 -0700 |
| commit | 93a6ada53c0ea49ea7b22163cf6a6d5e80c3b278 (patch) | |
| tree | d6835cd122cf9b45ac7b6172324195e50a91e6a6 | |
| parent | 62d3384378db0d96d123168e10723ff9fd756f1f (diff) | |
| download | meta-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.bbclass | 60 |
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) |
