diff options
| author | Ross Burton <ross.burton@arm.com> | 2024-10-10 17:06:22 +0100 |
|---|---|---|
| committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2024-10-11 12:17:03 +0100 |
| commit | fe5cf7dc8113916389a1d9c8fe8050ce86f294af (patch) | |
| tree | 1b6e479ae5dae1560b099a9ea5e62145f53e10ba /meta/classes-global/insane.bbclass | |
| parent | c812b378e055e56e731713e72f2b5b9481b2dfb2 (diff) | |
| download | poky-fe5cf7dc8113916389a1d9c8fe8050ce86f294af.tar.gz | |
insane: use oe.cachedpath.CachedPath instead of os.path
The insane QAPATHTESTs make many os.stat() calls, the majority of which
are redundant with caching as the initial sweep does a stat() on every
entry to determine if it is a file or a directory, and from then on each
test that does further stat()s is redundant as the tree doesn't change.
Switch os.stat() and friends (os.path.isfile(), etc) to use a common
oe.cachedpath.CachedPath() instance that is shared between all of the
functions, meaning only one stat is done.
In my test case of ltp:do_package_qa, this reduces the time taken from
44s to 37s.
(From OE-Core rev: cad3c889439fd6a007debd6f2f6578f4a1e16c9c)
Signed-off-by: Ross Burton <ross.burton@arm.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/classes-global/insane.bbclass')
| -rw-r--r-- | meta/classes-global/insane.bbclass | 42 |
1 files changed, 28 insertions, 14 deletions
diff --git a/meta/classes-global/insane.bbclass b/meta/classes-global/insane.bbclass index bec349e97c..2d69bdec8d 100644 --- a/meta/classes-global/insane.bbclass +++ b/meta/classes-global/insane.bbclass | |||
| @@ -82,7 +82,9 @@ def package_qa_clean_path(path, d, pkg=None): | |||
| 82 | 82 | ||
| 83 | QAPATHTEST[shebang-size] = "package_qa_check_shebang_size" | 83 | QAPATHTEST[shebang-size] = "package_qa_check_shebang_size" |
| 84 | def package_qa_check_shebang_size(path, name, d, elf): | 84 | def package_qa_check_shebang_size(path, name, d, elf): |
| 85 | if elf or os.path.islink(path) or not os.path.isfile(path): | 85 | global cpath |
| 86 | |||
| 87 | if elf or cpath.islink(path) or not cpath.isfile(path): | ||
| 86 | return | 88 | return |
| 87 | 89 | ||
| 88 | try: | 90 | try: |
| @@ -167,8 +169,8 @@ def package_qa_check_dev(path, name, d, elf): | |||
| 167 | """ | 169 | """ |
| 168 | Check for ".so" library symlinks in non-dev packages | 170 | Check for ".so" library symlinks in non-dev packages |
| 169 | """ | 171 | """ |
| 170 | 172 | global cpath | |
| 171 | if not name.endswith("-dev") and not name.endswith("-dbg") and not name.endswith("-ptest") and not name.startswith("nativesdk-") and path.endswith(".so") and os.path.islink(path): | 173 | if not name.endswith("-dev") and not name.endswith("-dbg") and not name.endswith("-ptest") and not name.startswith("nativesdk-") and path.endswith(".so") and cpath.islink(path): |
| 172 | oe.qa.handle_error("dev-so", "non -dev/-dbg/nativesdk- package %s contains symlink .so '%s'" % \ | 174 | oe.qa.handle_error("dev-so", "non -dev/-dbg/nativesdk- package %s contains symlink .so '%s'" % \ |
| 173 | (name, package_qa_clean_path(path, d, name)), d) | 175 | (name, package_qa_clean_path(path, d, name)), d) |
| 174 | 176 | ||
| @@ -179,7 +181,8 @@ def package_qa_check_dev_elf(path, name, d, elf): | |||
| 179 | check that the file is not a link and is an ELF object as some recipes | 181 | check that the file is not a link and is an ELF object as some recipes |
| 180 | install link-time .so files that are linker scripts. | 182 | install link-time .so files that are linker scripts. |
| 181 | """ | 183 | """ |
| 182 | if name.endswith("-dev") and path.endswith(".so") and not os.path.islink(path) and elf: | 184 | global cpath |
| 185 | if name.endswith("-dev") and path.endswith(".so") and not cpath.islink(path) and elf: | ||
| 183 | oe.qa.handle_error("dev-elf", "-dev package %s contains non-symlink .so '%s'" % \ | 186 | oe.qa.handle_error("dev-elf", "-dev package %s contains non-symlink .so '%s'" % \ |
| 184 | (name, package_qa_clean_path(path, d, name)), d) | 187 | (name, package_qa_clean_path(path, d, name)), d) |
| 185 | 188 | ||
| @@ -422,9 +425,9 @@ def package_qa_check_buildpaths(path, name, d, elf): | |||
| 422 | explicitly ignored. | 425 | explicitly ignored. |
| 423 | """ | 426 | """ |
| 424 | import stat | 427 | import stat |
| 425 | 428 | global cpath | |
| 426 | # Ignore symlinks/devs/fifos | 429 | # Ignore symlinks/devs/fifos |
| 427 | mode = os.lstat(path).st_mode | 430 | mode = cpath.lstat(path).st_mode |
| 428 | if stat.S_ISLNK(mode) or stat.S_ISBLK(mode) or stat.S_ISFIFO(mode) or stat.S_ISCHR(mode) or stat.S_ISSOCK(mode): | 431 | if stat.S_ISLNK(mode) or stat.S_ISBLK(mode) or stat.S_ISFIFO(mode) or stat.S_ISCHR(mode) or stat.S_ISSOCK(mode): |
| 429 | return | 432 | return |
| 430 | 433 | ||
| @@ -469,7 +472,8 @@ def package_qa_check_symlink_to_sysroot(path, name, d, elf): | |||
| 469 | """ | 472 | """ |
| 470 | Check that the package doesn't contain any absolute symlinks to the sysroot. | 473 | Check that the package doesn't contain any absolute symlinks to the sysroot. |
| 471 | """ | 474 | """ |
| 472 | if os.path.islink(path): | 475 | global cpath |
| 476 | if cpath.islink(path): | ||
| 473 | target = os.readlink(path) | 477 | target = os.readlink(path) |
| 474 | if os.path.isabs(target): | 478 | if os.path.isabs(target): |
| 475 | tmpdir = d.getVar('TMPDIR') | 479 | tmpdir = d.getVar('TMPDIR') |
| @@ -760,14 +764,19 @@ def qa_check_staged(path,d): | |||
| 760 | oe.qa.handle_error("pkgconfig", error_msg, d) | 764 | oe.qa.handle_error("pkgconfig", error_msg, d) |
| 761 | 765 | ||
| 762 | if not skip_shebang_size: | 766 | if not skip_shebang_size: |
| 767 | global cpath | ||
| 768 | cpath = oe.cachedpath.CachedPath() | ||
| 763 | package_qa_check_shebang_size(path, "", d, None) | 769 | package_qa_check_shebang_size(path, "", d, None) |
| 770 | cpath = None | ||
| 764 | 771 | ||
| 765 | # Walk over all files in a directory and call func | 772 | # Walk over all files in a directory and call func |
| 766 | def package_qa_walk(checkfuncs, package, d): | 773 | def package_qa_walk(checkfuncs, package, d): |
| 774 | global cpath | ||
| 775 | |||
| 767 | elves = {} | 776 | elves = {} |
| 768 | for path in pkgfiles[package]: | 777 | for path in pkgfiles[package]: |
| 769 | elf = None | 778 | elf = None |
| 770 | if os.path.isfile(path) and not os.path.islink(path): | 779 | if cpath.isfile(path) and not cpath.islink(path): |
| 771 | elf = oe.qa.ELFFile(path) | 780 | elf = oe.qa.ELFFile(path) |
| 772 | try: | 781 | try: |
| 773 | elf.open() | 782 | elf.open() |
| @@ -915,11 +924,12 @@ def package_qa_check_deps(pkg, pkgdest, d): | |||
| 915 | 924 | ||
| 916 | QAPKGTEST[usrmerge] = "package_qa_check_usrmerge" | 925 | QAPKGTEST[usrmerge] = "package_qa_check_usrmerge" |
| 917 | def package_qa_check_usrmerge(pkg, d): | 926 | def package_qa_check_usrmerge(pkg, d): |
| 927 | global cpath | ||
| 918 | pkgdest = d.getVar('PKGDEST') | 928 | pkgdest = d.getVar('PKGDEST') |
| 919 | pkg_dir = pkgdest + os.sep + pkg + os.sep | 929 | pkg_dir = pkgdest + os.sep + pkg + os.sep |
| 920 | merged_dirs = ['bin', 'sbin', 'lib'] + d.getVar('MULTILIB_VARIANTS').split() | 930 | merged_dirs = ['bin', 'sbin', 'lib'] + d.getVar('MULTILIB_VARIANTS').split() |
| 921 | for f in merged_dirs: | 931 | for f in merged_dirs: |
| 922 | if os.path.exists(pkg_dir + f) and not os.path.islink(pkg_dir + f): | 932 | if cpath.exists(pkg_dir + f) and not cpath.islink(pkg_dir + f): |
| 923 | msg = "%s package is not obeying usrmerge distro feature. /%s should be relocated to /usr." % (pkg, f) | 933 | msg = "%s package is not obeying usrmerge distro feature. /%s should be relocated to /usr." % (pkg, f) |
| 924 | oe.qa.handle_error("usrmerge", msg, d) | 934 | oe.qa.handle_error("usrmerge", msg, d) |
| 925 | return | 935 | return |
| @@ -985,10 +995,11 @@ def package_qa_check_empty_dirs(pkg, d): | |||
| 985 | empty. | 995 | empty. |
| 986 | """ | 996 | """ |
| 987 | 997 | ||
| 998 | global cpath | ||
| 988 | pkgd = oe.path.join(d.getVar('PKGDEST'), pkg) | 999 | pkgd = oe.path.join(d.getVar('PKGDEST'), pkg) |
| 989 | for dir in (d.getVar('QA_EMPTY_DIRS') or "").split(): | 1000 | for dir in (d.getVar('QA_EMPTY_DIRS') or "").split(): |
| 990 | empty_dir = oe.path.join(pkgd, dir) | 1001 | empty_dir = oe.path.join(pkgd, dir) |
| 991 | if os.path.exists(empty_dir) and os.listdir(empty_dir): | 1002 | if cpath.exists(empty_dir) and os.listdir(empty_dir): |
| 992 | recommendation = (d.getVar('QA_EMPTY_DIRS_RECOMMENDATION:' + dir) or | 1003 | recommendation = (d.getVar('QA_EMPTY_DIRS_RECOMMENDATION:' + dir) or |
| 993 | "but it is expected to be empty") | 1004 | "but it is expected to be empty") |
| 994 | msg = "%s installs files in %s, %s" % (pkg, dir, recommendation) | 1005 | msg = "%s installs files in %s, %s" % (pkg, dir, recommendation) |
| @@ -1018,8 +1029,9 @@ HOST_USER_GID := "${@os.getgid()}" | |||
| 1018 | QAPATHTEST[host-user-contaminated] = "package_qa_check_host_user" | 1029 | QAPATHTEST[host-user-contaminated] = "package_qa_check_host_user" |
| 1019 | def package_qa_check_host_user(path, name, d, elf): | 1030 | def package_qa_check_host_user(path, name, d, elf): |
| 1020 | """Check for paths outside of /home which are owned by the user running bitbake.""" | 1031 | """Check for paths outside of /home which are owned by the user running bitbake.""" |
| 1032 | global cpath | ||
| 1021 | 1033 | ||
| 1022 | if not os.path.lexists(path): | 1034 | if not cpath.lexists(path): |
| 1023 | return | 1035 | return |
| 1024 | 1036 | ||
| 1025 | dest = d.getVar('PKGDEST') | 1037 | dest = d.getVar('PKGDEST') |
| @@ -1029,7 +1041,7 @@ def package_qa_check_host_user(path, name, d, elf): | |||
| 1029 | return | 1041 | return |
| 1030 | 1042 | ||
| 1031 | try: | 1043 | try: |
| 1032 | stat = os.lstat(path) | 1044 | stat = cpath.lstat(path) |
| 1033 | except OSError as exc: | 1045 | except OSError as exc: |
| 1034 | import errno | 1046 | import errno |
| 1035 | if exc.errno != errno.ENOENT: | 1047 | if exc.errno != errno.ENOENT: |
| @@ -1105,13 +1117,14 @@ python do_package_qa () { | |||
| 1105 | if not packages: | 1117 | if not packages: |
| 1106 | return | 1118 | return |
| 1107 | 1119 | ||
| 1108 | global pkgfiles | 1120 | global pkgfiles, cpath |
| 1109 | pkgfiles = {} | 1121 | pkgfiles = {} |
| 1122 | cpath = oe.cachedpath.CachedPath() | ||
| 1110 | pkgdest = d.getVar('PKGDEST') | 1123 | pkgdest = d.getVar('PKGDEST') |
| 1111 | for pkg in packages: | 1124 | for pkg in packages: |
| 1112 | pkgdir = os.path.join(pkgdest, pkg) | 1125 | pkgdir = os.path.join(pkgdest, pkg) |
| 1113 | pkgfiles[pkg] = [] | 1126 | pkgfiles[pkg] = [] |
| 1114 | for walkroot, dirs, files in os.walk(pkgdir): | 1127 | for walkroot, dirs, files in cpath.walk(pkgdir): |
| 1115 | # Don't walk into top-level CONTROL or DEBIAN directories as these | 1128 | # Don't walk into top-level CONTROL or DEBIAN directories as these |
| 1116 | # are temporary directories created by do_package. | 1129 | # are temporary directories created by do_package. |
| 1117 | if walkroot == pkgdir: | 1130 | if walkroot == pkgdir: |
| @@ -1159,6 +1172,7 @@ python do_package_qa () { | |||
| 1159 | 1172 | ||
| 1160 | package_qa_check_libdir(d) | 1173 | package_qa_check_libdir(d) |
| 1161 | 1174 | ||
| 1175 | cpath = None | ||
| 1162 | oe.qa.exit_if_errors(d) | 1176 | oe.qa.exit_if_errors(d) |
| 1163 | } | 1177 | } |
| 1164 | 1178 | ||
