support/scripts/fix-rpath: parallelize patching files
Using "xargs" instead of "while read" loop allows for the patching of files to be parallelized. This significantly reduces the amount of time it takes to fix all the paths. On a larger RFS(~300MB) this script was taking 5 minutes, it now only takes about 30s on a 12 core machine. Signed-off-by: Victor Dumas <dumasv.dev@gmail.com> [Thomas: take into account the suggestion of Quentin Schulz to pass PARALLEL_JOBS through the environment down to the fix-rpath script] Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
This commit is contained in:
parent
552a054d45
commit
134900401f
12
Makefile
12
Makefile
@ -594,8 +594,12 @@ world: target-post-image
|
|||||||
.PHONY: prepare-sdk
|
.PHONY: prepare-sdk
|
||||||
prepare-sdk: world
|
prepare-sdk: world
|
||||||
@$(call MESSAGE,"Rendering the SDK relocatable")
|
@$(call MESSAGE,"Rendering the SDK relocatable")
|
||||||
PER_PACKAGE_DIR=$(PER_PACKAGE_DIR) $(TOPDIR)/support/scripts/fix-rpath host
|
PARALLEL_JOBS=$(PARALLEL_JOBS) \
|
||||||
PER_PACKAGE_DIR=$(PER_PACKAGE_DIR) $(TOPDIR)/support/scripts/fix-rpath staging
|
PER_PACKAGE_DIR=$(PER_PACKAGE_DIR) \
|
||||||
|
$(TOPDIR)/support/scripts/fix-rpath host
|
||||||
|
PARALLEL_JOBS=$(PARALLEL_JOBS) \
|
||||||
|
PER_PACKAGE_DIR=$(PER_PACKAGE_DIR) \
|
||||||
|
$(TOPDIR)/support/scripts/fix-rpath staging
|
||||||
$(INSTALL) -m 755 $(TOPDIR)/support/misc/relocate-sdk.sh $(HOST_DIR)/relocate-sdk.sh
|
$(INSTALL) -m 755 $(TOPDIR)/support/misc/relocate-sdk.sh $(HOST_DIR)/relocate-sdk.sh
|
||||||
mkdir -p $(HOST_DIR)/share/buildroot
|
mkdir -p $(HOST_DIR)/share/buildroot
|
||||||
echo $(HOST_DIR) > $(HOST_DIR)/share/buildroot/sdk-location
|
echo $(HOST_DIR) > $(HOST_DIR)/share/buildroot/sdk-location
|
||||||
@ -765,7 +769,9 @@ endif
|
|||||||
ln -sf ../usr/lib/os-release $(TARGET_DIR)/etc
|
ln -sf ../usr/lib/os-release $(TARGET_DIR)/etc
|
||||||
|
|
||||||
@$(call MESSAGE,"Sanitizing RPATH in target tree")
|
@$(call MESSAGE,"Sanitizing RPATH in target tree")
|
||||||
PER_PACKAGE_DIR=$(PER_PACKAGE_DIR) $(TOPDIR)/support/scripts/fix-rpath target
|
PARALLEL_JOBS=$(PARALLEL_JOBS) \
|
||||||
|
PER_PACKAGE_DIR=$(PER_PACKAGE_DIR) \
|
||||||
|
$(TOPDIR)/support/scripts/fix-rpath target
|
||||||
|
|
||||||
# For a merged /usr, ensure that /lib, /bin and /sbin and their /usr
|
# For a merged /usr, ensure that /lib, /bin and /sbin and their /usr
|
||||||
# counterparts are appropriately setup as symlinks ones to the others.
|
# counterparts are appropriately setup as symlinks ones to the others.
|
||||||
|
@ -46,6 +46,8 @@ Environment:
|
|||||||
TOOLCHAIN_EXTERNAL_DOWNLOAD_INSTALL_DIR
|
TOOLCHAIN_EXTERNAL_DOWNLOAD_INSTALL_DIR
|
||||||
(default HOST_DIR/opt/ext-toolchain)
|
(default HOST_DIR/opt/ext-toolchain)
|
||||||
|
|
||||||
|
PARALLEL_JOBS number of parallel jobs to run
|
||||||
|
|
||||||
Returns: 0 if success or 1 in case of error
|
Returns: 0 if success or 1 in case of error
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
@ -58,6 +60,38 @@ HOST_EXCLUDEPATHS="/share/terminfo"
|
|||||||
STAGING_EXCLUDEPATHS="/usr/include /usr/share/terminfo"
|
STAGING_EXCLUDEPATHS="/usr/include /usr/share/terminfo"
|
||||||
TARGET_EXCLUDEPATHS="/lib/firmware"
|
TARGET_EXCLUDEPATHS="/lib/firmware"
|
||||||
|
|
||||||
|
patch_file() {
|
||||||
|
PATCHELF="${1}"
|
||||||
|
rootdir="${2}"
|
||||||
|
sanitize_extra_args="${3}"
|
||||||
|
file="${4}"
|
||||||
|
|
||||||
|
# check if it's an ELF file
|
||||||
|
rpath=$(${PATCHELF} --print-rpath "${file}" 2>&1)
|
||||||
|
if test $? -ne 0 ; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# make files writable if necessary
|
||||||
|
changed=$(chmod -c u+w "${file}")
|
||||||
|
|
||||||
|
# With per-package directory support, most RPATH of host
|
||||||
|
# binaries will point to per-package directories. This won't
|
||||||
|
# work with the --make-rpath-relative ${rootdir} invocation as
|
||||||
|
# the per-package host directory is not within ${rootdir}. So,
|
||||||
|
# we rewrite all RPATHs pointing to per-package directories so
|
||||||
|
# that they point to the global host directry.
|
||||||
|
changed_rpath=$(echo ${rpath} | sed "s@${PER_PACKAGE_DIR}/[^/]\+/host@${HOST_DIR}@")
|
||||||
|
if test "${rpath}" != "${changed_rpath}" ; then
|
||||||
|
${PATCHELF} --set-rpath ${changed_rpath} "${file}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# call patchelf to sanitize the rpath
|
||||||
|
${PATCHELF} --make-rpath-relative "${rootdir}" ${sanitize_extra_args[@]} "${file}"
|
||||||
|
# restore the original permission
|
||||||
|
test "${changed}" != "" && chmod u-w "${file}"
|
||||||
|
}
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
local rootdir
|
local rootdir
|
||||||
local tree="${1}"
|
local tree="${1}"
|
||||||
@ -123,34 +157,11 @@ main() {
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
find_args+=( "-type" "f" "-print" )
|
find_args+=( "-type" "f" "-print0" )
|
||||||
|
|
||||||
while read file ; do
|
export -f patch_file
|
||||||
# check if it's an ELF file
|
# Limit the number of cores used
|
||||||
rpath=$(${PATCHELF} --print-rpath "${file}" 2>&1)
|
find "${rootdir}" ${find_args[@]} | xargs -0 -r -P ${PARALLEL_JOBS} -I {} bash -c "patch_file '${PATCHELF}' '${rootdir}' '${sanitize_extra_args}' $@" _ {}
|
||||||
if test $? -ne 0 ; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
# make files writable if necessary
|
|
||||||
changed=$(chmod -c u+w "${file}")
|
|
||||||
|
|
||||||
# With per-package directory support, most RPATH of host
|
|
||||||
# binaries will point to per-package directories. This won't
|
|
||||||
# work with the --make-rpath-relative ${rootdir} invocation as
|
|
||||||
# the per-package host directory is not within ${rootdir}. So,
|
|
||||||
# we rewrite all RPATHs pointing to per-package directories so
|
|
||||||
# that they point to the global host directry.
|
|
||||||
changed_rpath=$(echo ${rpath} | sed "s@${PER_PACKAGE_DIR}/[^/]\+/host@${HOST_DIR}@")
|
|
||||||
if test "${rpath}" != "${changed_rpath}" ; then
|
|
||||||
${PATCHELF} --set-rpath ${changed_rpath} "${file}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# call patchelf to sanitize the rpath
|
|
||||||
${PATCHELF} --make-rpath-relative "${rootdir}" ${sanitize_extra_args[@]} "${file}"
|
|
||||||
# restore the original permission
|
|
||||||
test "${changed}" != "" && chmod u-w "${file}"
|
|
||||||
done < <(find "${rootdir}" ${find_args[@]})
|
|
||||||
|
|
||||||
# Restore patched patchelf utility
|
# Restore patched patchelf utility
|
||||||
test "${tree}" = "host" && mv "${PATCHELF}.__to_be_patched" "${PATCHELF}"
|
test "${tree}" = "host" && mv "${PATCHELF}.__to_be_patched" "${PATCHELF}"
|
||||||
|
Loading…
Reference in New Issue
Block a user