git: fafe12496ba6 - main - Mk/Scripts/qa.sh: Filter baselibs() input to improve performance
Joseph Mingrone <[email protected]>
| Newsgroups | gmane.os.freebsd.devel.cvs.ports |
|---|---|
| Message-ID | <[email protected]> |
The branch main has been updated by jrm: URL: https://cgit.FreeBSD.org/ports/commit/?id=fafe12496ba6146c7155b5fc71642270a7b33926 commit fafe12496ba6146c7155b5fc71642270a7b33926 Author: Joseph Mingrone <[email protected]> AuthorDate: 2026-08-17 19:05:20 +0000 Commit: Joseph Mingrone <[email protected]> CommitDate: 2026-08-18 14:44:05 +0000 Mk/Scripts/qa.sh: Filter baselibs() input to improve performance After the baselibs() fix in f0f863b1a2d6, readelf is executed for each result from find(1). There are two concerns with this fix: 1. -exec readelf -d {} \; drops the filename from the error messages readelf prints "File: <name>" headers only when it is supplied with two or more files, and baselibs() uses ${file} from those headers. So, the two err() messages in baselibs() will break. This is moot for now, though, because nothing in the ports tree can trigger these errors. Those base soname versions for libarchive and libedit are long gone. 2. Performance hit with one readelf execution per staged file The costs are high for ports that stage many files. For emulators/linux_base-rl9, the find returns over 30k hits that the while loop must iterate over. It took about 15s for baselibs() to process these files on an i7-10710U build system. To fix these issues, use a filter similar to the one used by proxydeps(). This way, only ELF objects are fed to one instance of readelf, and the timing for baselibs() to process emulators/linux_base-rl9 drops to about 1.5s. PR: 296889 Reviewed by: portmgr (bapt) Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D58900 --- Mk/Scripts/qa.sh | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Mk/Scripts/qa.sh b/Mk/Scripts/qa.sh index d47478924a87..2556395ff3eb 100644 --- a/Mk/Scripts/qa.sh +++ b/Mk/Scripts/qa.sh @@ -116,6 +116,15 @@ baselibs() { local rc local found_openssl local file + + # list_stagedir_elfs() enters ${STAGEDIR}, but only inside the subshell + # that runs find. In the pipeline below that feeds the while loop, the + # paths find prints are relative, so file(1) and readelf must be in + # ${STAGEDIR} too, hence the cd ${STAGEDIR} before the whole pipeline. + # + # readelf prints "File:" headers only when given two or more operands, + # hence the trailing ld-elf.so.1. + [ "${PKGBASE}" = "pkg" -o "${PKGBASE}" = "pkg-devel" ] && return while read -r f; do @@ -136,7 +145,12 @@ baselibs() { ;; esac done <<-EOF - $(list_stagedir_elfs -exec readelf -d {} \; 2>/dev/null) + $(cd ${STAGEDIR} && list_stagedir_elfs | \ + file -F $'\1' -f - | \ + grep -a 'ELF.*FreeBSD.*dynamically linked' | \ + cut -f 1 -d $'\1' | \ + { tr '\n' '\000'; printf '%s\000' /libexec/ld-elf.so.1; } | \ + xargs -0 readelf -d) EOF if ! list_stagedir_elfs | egrep -q 'lib(crypto|ssl).so*'; then