2 # This script will populate the root directory with libs from the sysroot.
3 # (C) 2007 Yann E. MORIN
4 # Licensed under the GPL v2
7 # Use the tools discovered by crosstool-NG's ./configure:
8 install="@@CT_install@@"
12 # Detect where the toolchain is:
13 CT_PREFIX_DIR="$(cd "$(dirname "$0")/.."; pwd)"
14 CT_GCC="${0%-populate}-gcc"
15 CT_READELF="${0%-populate}-readelf"
16 CT_CFG_PREFIX_DIR="$("${CT_GCC}" -v 2>&1 \
18 |"${grep}" -E -- '--prefix=' \
21 CT_CFG_SYSROOT_DIR="$("${CT_GCC}" -v 2>&1 \
23 |"${grep}" -E -- '--with-sysroot=' \
26 CT_SYSROOT_DIR="$(echo "${CT_CFG_SYSROOT_DIR}" \
27 |"${sed}" -r -e "s:^${CT_CFG_PREFIX_DIR}:${CT_PREFIX_DIR}:;" \
28 |"${sed}" -r -e 's,/+,/,g;' \
31 myname=$(basename "$0")
36 $myname - populate the target root file system
39 $myname OPTIONS -s source_root -d destination_root
42 $myname will 'populate' your target root file system ('src_dir') with
43 libraries from the toolchain (eg. libc.so...), storing the result into
48 use 'src_dir' as the un-populated (source) root directory
51 use 'dst_dir' as the place to put the populated root directory
54 use 'sysroot_dir' as the sysroot instead of the toolchain default
57 Always add the specified shared library/ies name1, name2... from the
58 toolchain (in the sys-root). Actual library names are searched as
59 follows (where 'name' is replaced with the given name) in the
64 If the file is found, then the SONAME of the library is used, and the
65 library is copied with that name. If the library was not found, this
66 yields an error (unless -f was given).
69 Read 'file' for a list of shared libraries to always add from the
70 toolchain. The file should contain one library name per line; text
71 after a # is ignored until the end of the line; spaces are ignored;
72 empty lines are ignored. Libraries are searched for as with -l.
74 -f force execution: if destination directory already exists, it will be
75 removed first; if a specified library (above) was not found, continue.
76 Note: if using -m and the destination directory already exists, it
77 is *not* removed, see below.
79 -m Merge the source root directory with the destination root directory.
80 If the latter does not exist, it is created, and -m is ignored.
81 If the destination droot directory exists, then the content of the
82 source root directory is copied in there, and the result is populated
84 It can be usefull if constructing a rootfs incrementally from many
85 smaller source root directories, or if your destination root directory
86 is an NFS export that your target mounts as / (and you don't want to
87 re-run exportfs -av everytime). USE WITH CARE!
89 -v Be verbose. By default, populate is absolutely silent.
102 while getopts ":s:d:r:l:L:fmvh" CT_OPT; do
104 s) CT_ROOT_SRC_DIR="${OPTARG}";;
105 d) CT_ROOT_DST_DIR="${OPTARG}";;
106 r) CT_SYSROOT_DIR="${OPTARG}";;
107 l) CT_LIB_LIST="${CT_LIB_LIST}:${OPTARG}";;
108 L) CT_LIB_FILE="${OPTARG}";;
111 v) CT_PRINTF=printf;;
115 :) echo "$myname: '-${OPTARG}' takes exactly one argument."
118 ?) echo "$myname: unknown option '-${OPTARG}'."
125 if [ -z "${CT_ROOT_SRC_DIR}" -o -z "${CT_ROOT_DST_DIR}" ]; then
129 if [ ! -d "${CT_ROOT_SRC_DIR}" ]; then
130 echo "$myname: '${CT_ROOT_SRC_DIR}': no such file or directory"
133 if [ ! -d "${CT_SYSROOT_DIR}" ]; then
134 echo "$myname: '${CT_SYSROOT_DIR}': no such file or directory"
137 # If the dest dir does not exist, all is well
138 # If merging, we accept an existing dest directory
139 # If forcing and not merging, we remove an exiting dest directory
140 # If not forcing and not merging, we do not accept an exiting dest directory
141 if [ -d "${CT_ROOT_DST_DIR}" ]; then
142 case "${CT_FORCE}:${CT_MERGE}" in
144 y:) rm -rf "${CT_ROOT_DST_DIR}";;
145 :) echo "$myname: '${CT_ROOT_DST_DIR}': already exists" && exit 1 ;;
148 src_inode=$(stat -c '%i' "${CT_ROOT_SRC_DIR}/.")
149 dst_inode=$(stat -c '%i' "${CT_ROOT_DST_DIR}/." 2>/dev/null || true)
150 if [ "${src_inode}" -eq "$((dst_inode+0))" ]; then
151 echo "$myname: source and destination are the same!"
155 # Check existence of the forced libraries file
156 if [ -n "${CT_LIB_FILE}" -a ! \( -f "${CT_LIB_FILE}" -a -r "${CT_LIB_FILE}" \) ]; then
157 echo "$myname: forced libraries file '${CT_LIB_FILE}' not found!"
161 # Create the working copy, no issue if already existing
162 mkdir -p "${CT_ROOT_DST_DIR}"
164 # Make all path absolute
165 CT_ROOT_SRC_DIR=$(cd "${CT_ROOT_SRC_DIR}"; pwd)
166 CT_ROOT_DST_DIR=$(cd "${CT_ROOT_DST_DIR}"; pwd)
168 # Populate the destination directory with files from the source directory
169 pushd "${CT_ROOT_SRC_DIR}" >/dev/null
170 cp -a . "${CT_ROOT_DST_DIR}"
173 # A function do search for a library
174 # Usage: do_add_lib libname
175 # returns: 0 if library was found and added, !0 otherwise
182 for dir in lib usr/lib; do
183 ${CT_PRINTF} " trying in '%s'" "${dir}"
184 libfile="${CT_SYSROOT_DIR}/${dir}/${libname}"
185 ${CT_PRINTF} ": '%s'\n" "${libfile}"
186 if [ -e "${libfile}" ]; then
188 true_libname=$("${CT_READELF}" -d "${libfile}" \
189 |"${grep}" "Library soname:" \
190 |"${sed}" -r -e 's,.+\[(.+)\] *$,\1,;' \
196 ${CT_PRINTF} " installing as '%s/%s', mode='%s'\n" "${dir}" "${true_libname}" "${mode}"
197 "${install}" -m "${mode}" "${libfile}" "${dir}/${true_libname}"
205 # We'll work in the copied rootfs
206 pushd "${CT_ROOT_DST_DIR}" >/dev/null
208 # First of, copy the forced libraries into the working copy
210 if [ -n "${CT_LIB_FILE}" ]; then
211 lib_list=$("${sed}" -r -e ':loop; s/#.*//;' \
212 -e 's/[[:space:]]+//g;' \
213 -e 's/([^:])$/\1:/;' \
214 -e '/$/N; s/\n//; tloop;' \
218 CT_LIB_LIST=$(echo "${CT_LIB_LIST}:${lib_list}" \
219 |"${sed}" -r -e 's/^:+//; s/:+$//; s/:+/ /g;' \
221 if [ -n "${CT_LIB_LIST}" ]; then
222 ${CT_PRINTF} "Installing forced libraries...\n"
223 for name in ${CT_LIB_LIST}; do
224 [ -z "${name}" ] && continue
226 for libname in "lib${name}.so" "${name}.so" "${name}"; do
227 ${CT_PRINTF} " searching for '%s'\n" "${libname}"
228 if do_add_lib "${libname}"; then
233 if [ ${found} -eq 0 ]; then
234 echo "$myname: library '${libname}' not found!"
235 [ "${CT_FORCE}" = y ] || exit 1
240 # Parse the working copy for executables and libraries
242 while [ ${still_needed} -eq 1 ]; do
243 ${CT_PRINTF} "Looping...\n"
245 for f in $(find . -type f -exec file {} \; \
246 |"${grep}" -E ': ELF [[:digit:]]+-bit (L|M)SB (executable|shared object),' \
249 ${CT_PRINTF} "Scanning '%s'\n" "${f}"
250 for libname in $("${CT_READELF}" -d "${f}" \
251 |"${grep}" -E '\(NEEDED\)[[:space:]]+Shared library:' \
252 |"${sed}" -r -e 's,.+\[(.+)\] *$,\1,;' \
254 ${CT_PRINTF} " searching for '%s'\n" "${libname}"
255 if [ -e "lib/${libname}" \
256 -o -e "usr/lib/${libname}" ]; then
257 ${CT_PRINTF} " already present\n"
260 if do_add_lib "${libname}"; then
263 echo "$myname: library '${libname}' not found!"
269 # OK, we're done. Back off.