diff --git a/scripts/appimage_lib_policy.sh b/scripts/appimage_lib_policy.sh index 35925227a0..81936d83c6 100755 --- a/scripts/appimage_lib_policy.sh +++ b/scripts/appimage_lib_policy.sh @@ -23,7 +23,13 @@ appimage_is_host_library() { } appimage_is_elf_file() { - file -b "$1" 2>/dev/null | grep -q '^ELF ' + # Read the four-byte ELF magic rather than asking file(1): this runs once per candidate, and an + # AppDir holds thousands of them (the bundled Python runtime alone is ~5k files, none of them + # ELF). Two processes per call made this ~14 s of a ~95 s image build on its own. + local magic + [[ -f "$1" && -r "$1" ]] || return 1 + IFS= read -r -n 4 -d '' magic < "$1" 2>/dev/null + [[ $magic == $'\177ELF' ]] } appimage_list_direct_dependencies() { diff --git a/src/dev-utils/platform/unix/build_linux_image.sh.in b/src/dev-utils/platform/unix/build_linux_image.sh.in index 873cf2e1b1..8466597d34 100755 --- a/src/dev-utils/platform/unix/build_linux_image.sh.in +++ b/src/dev-utils/platform/unix/build_linux_image.sh.in @@ -118,9 +118,13 @@ bundle_dependency_closure() { # (scripts/check_appimage_libs.sh). local -a search_dirs=("$dst_dir") - while [ ${#queue[@]} -gt 0 ]; do - target="${queue[0]}" - queue=("${queue[@]:1}") + # Walked with a read index rather than by reslicing the array: "${queue[@]:1}" rebuilds the whole + # queue on every pop, so draining it costs O(n^2). At the ~5k entries this bundle reaches that was + # ~22 s of the image build spent copying an array around. + local head=0 + while [ "$head" -lt ${#queue[@]} ]; do + target="${queue[$head]}" + head=$((head + 1)) if [ ! -e "$target" ] || ! appimage_is_elf_file "$target"; then continue