]> Git Repo - buildroot-mgba.git/blame - support/scripts/fix-rpath
support/scripts/fix-rpath: parallelize patching files
[buildroot-mgba.git] / support / scripts / fix-rpath
CommitLineData
022b8adb
SM
1#!/usr/bin/env bash
2
3# Copyright (C) 2016 Samuel Martin <[email protected]>
4# Copyright (C) 2017 Wolfgang Grandegger <[email protected]>
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14# General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20usage() {
21 cat <<EOF >&2
22Usage: ${0} TREE_KIND
23
24Description:
25
26 This script scans a tree and sanitize ELF files' RPATH found in there.
27
28 Sanitization behaves the same whatever the kind of the processed tree,
29 but the resulting RPATH differs. The rpath sanitization is done using
0bc81f52 30 "patchelf --make-rpath-relative".
022b8adb
SM
31
32Arguments:
33
34 TREE_KIND Kind of tree to be processed.
35 Allowed values: host, target, staging
36
37Environment:
38
39 PATCHELF patchelf program to use
40 (default: HOST_DIR/bin/patchelf)
41
42 HOST_DIR host directory
43 STAGING_DIR staging directory
44 TARGET_DIR target directory
45
46 TOOLCHAIN_EXTERNAL_DOWNLOAD_INSTALL_DIR
47 (default HOST_DIR/opt/ext-toolchain)
17dd0d49 48
13490040
VD
49 PARALLEL_JOBS number of parallel jobs to run
50
17dd0d49
WG
51Returns: 0 if success or 1 in case of error
52
022b8adb
SM
53EOF
54}
55
56: ${PATCHELF:=${HOST_DIR}/bin/patchelf}
57
58# ELF files should not be in these sub-directories
59HOST_EXCLUDEPATHS="/share/terminfo"
60STAGING_EXCLUDEPATHS="/usr/include /usr/share/terminfo"
184cb52f 61TARGET_EXCLUDEPATHS="/lib/firmware"
022b8adb 62
13490040
VD
63patch_file() {
64 PATCHELF="${1}"
65 rootdir="${2}"
66 sanitize_extra_args="${3}"
67 file="${4}"
68
69 # check if it's an ELF file
70 rpath=$(${PATCHELF} --print-rpath "${file}" 2>&1)
71 if test $? -ne 0 ; then
72 return 0
73 fi
74
75 # make files writable if necessary
76 changed=$(chmod -c u+w "${file}")
77
78 # With per-package directory support, most RPATH of host
79 # binaries will point to per-package directories. This won't
80 # work with the --make-rpath-relative ${rootdir} invocation as
81 # the per-package host directory is not within ${rootdir}. So,
82 # we rewrite all RPATHs pointing to per-package directories so
83 # that they point to the global host directry.
84 changed_rpath=$(echo ${rpath} | sed "s@${PER_PACKAGE_DIR}/[^/]\+/host@${HOST_DIR}@")
85 if test "${rpath}" != "${changed_rpath}" ; then
86 ${PATCHELF} --set-rpath ${changed_rpath} "${file}"
87 fi
88
89 # call patchelf to sanitize the rpath
90 ${PATCHELF} --make-rpath-relative "${rootdir}" ${sanitize_extra_args[@]} "${file}"
91 # restore the original permission
92 test "${changed}" != "" && chmod u-w "${file}"
93}
94
022b8adb
SM
95main() {
96 local rootdir
97 local tree="${1}"
98 local find_args=( )
99 local sanitize_extra_args=( )
100
17dd0d49
WG
101 if ! "${PATCHELF}" --version > /dev/null 2>&1; then
102 echo "Error: can't execute patchelf utility '${PATCHELF}'"
103 exit 1
104 fi
105
022b8adb
SM
106 case "${tree}" in
107 host)
108 rootdir="${HOST_DIR}"
109
110 # do not process the sysroot (only contains target binaries)
111 find_args+=( "-path" "${STAGING_DIR}" "-prune" "-o" )
112
113 # do not process the external toolchain installation directory to
114 # avoid breaking it.
115 test "${TOOLCHAIN_EXTERNAL_DOWNLOAD_INSTALL_DIR}" != "" && \
116 find_args+=( "-path" "${TOOLCHAIN_EXTERNAL_DOWNLOAD_INSTALL_DIR}" "-prune" "-o" )
117
118 for excludepath in ${HOST_EXCLUDEPATHS}; do
0bc81f52 119 find_args+=( "-path" "${HOST_DIR}""${excludepath}" "-prune" "-o" )
022b8adb
SM
120 done
121
122 # do not process the patchelf binary but a copy to work-around "file in use"
123 find_args+=( "-path" "${PATCHELF}" "-prune" "-o" )
124 cp "${PATCHELF}" "${PATCHELF}.__to_be_patched"
125
126 # we always want $ORIGIN-based rpaths to make it relocatable.
127 sanitize_extra_args+=( "--relative-to-file" )
128 ;;
129
130 staging)
131 rootdir="${STAGING_DIR}"
132
133 # ELF files should not be in these sub-directories
134 for excludepath in ${STAGING_EXCLUDEPATHS}; do
135 find_args+=( "-path" "${STAGING_DIR}""${excludepath}" "-prune" "-o" )
136 done
137
138 # should be like for the target tree below
139 sanitize_extra_args+=( "--no-standard-lib-dirs" )
140 ;;
141
142 target)
143 rootdir="${TARGET_DIR}"
184cb52f
TP
144
145 for excludepath in ${TARGET_EXCLUDEPATHS}; do
146 find_args+=( "-path" "${TARGET_DIR}""${excludepath}" "-prune" "-o" )
147 done
148
022b8adb
SM
149 # we don't want $ORIGIN-based rpaths but absolute paths without rootdir.
150 # we also want to remove rpaths pointing to /lib or /usr/lib.
151 sanitize_extra_args+=( "--no-standard-lib-dirs" )
152 ;;
153
154 *)
155 usage
156 exit 1
157 ;;
158 esac
159
13490040
VD
160 find_args+=( "-type" "f" "-print0" )
161
162 export -f patch_file
163 # Limit the number of cores used
164 find "${rootdir}" ${find_args[@]} | xargs -0 -r -P ${PARALLEL_JOBS} -I {} bash -c "patch_file '${PATCHELF}' '${rootdir}' '${sanitize_extra_args}' $@" _ {}
022b8adb
SM
165
166 # Restore patched patchelf utility
167 test "${tree}" = "host" && mv "${PATCHELF}.__to_be_patched" "${PATCHELF}"
168
169 # ignore errors
170 return 0
171}
172
173main ${@}
This page took 0.5656 seconds and 4 git commands to generate.