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="$(printf "${CT_CFG_SYSROOT_DIR}\n" \
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 This script will 'populate' your target root file system 'source_root'
43 with libraries from the toolchain (eg. libc.so...), storing the result
48 Use 'src_dir' as the un-populated (source) root directory.
51 Use 'dst_dir' as the place to put the populated root directory.
52 See the -f and -m options, below, on the required (non-)existence
56 Use 'sysroot_dir' as the sysroot instead of the toolchain default.
59 Always add the specified shared library/ies name1, name2... from the
60 toolchain (in the sys-root). Actual library names are searched as
61 follows (where 'name' is replaced with the given name) in the
66 If the file is found, then the SONAME of the library is used, and the
67 library is copied with that name. If the library was not found, this
68 yields an error (unless -f was given).
71 Read 'file' for a list of shared libraries to always add from the
72 toolchain. The file should contain one library name per line; text
73 after a # is ignored until the end of the line; spaces are ignored;
74 empty lines are ignored. Libraries are searched for as with -l.
76 -f Force execution: if destination directory already exists, it will be
77 removed first; if a specified library (above) was not found, continue.
78 Note: if using -m and the destination directory already exists, it
79 is *not* removed, see below.
81 -m Merge the source root directory with the destination root directory.
82 If the latter does not exist, it is created, and -m is ignored.
83 If the destination root directory exists, then the content of the
84 source root directory is copied in there, and the result is populated
86 It can be usefull if constructing a rootfs incrementally from many
87 smaller source root directories, or if your destination root directory
88 is an NFS export that your target mounts as / (and you don't want to
89 re-run exportfs -av everytime). USE WITH CARE!
91 -v Be verbose. By default, populate is absolutely silent.
104 while getopts ":s:d:r:l:L:fmvh" CT_OPT; do
106 s) CT_ROOT_SRC_DIR="${OPTARG}";;
107 d) CT_ROOT_DST_DIR="${OPTARG}";;
108 r) CT_SYSROOT_DIR="${OPTARG}";;
109 l) CT_LIB_LIST="${CT_LIB_LIST}:${OPTARG}";;
110 L) CT_LIB_FILE="${OPTARG}";;
113 v) CT_PRINTF=printf;;
117 :) printf "$myname: '-${OPTARG}' takes exactly one argument.\n"
120 ?) printf "$myname: unknown option '-${OPTARG}'.\n"
127 if [ -z "${CT_ROOT_SRC_DIR}" -o -z "${CT_ROOT_DST_DIR}" ]; then
131 if [ ! -d "${CT_ROOT_SRC_DIR}" ]; then
132 printf "$myname: '${CT_ROOT_SRC_DIR}': no such file or directory\n"
135 if [ ! -d "${CT_SYSROOT_DIR}" ]; then
136 printf "$myname: '${CT_SYSROOT_DIR}': no such file or directory\n"
139 # If the dest dir does not exist, all is well
140 # If merging, we accept an existing dest directory
141 # If forcing and not merging, we remove an exiting dest directory
142 # If not forcing and not merging, we do not accept an exiting dest directory
143 if [ -d "${CT_ROOT_DST_DIR}" ]; then
144 case "${CT_FORCE}:${CT_MERGE}" in
146 y:) rm -rf "${CT_ROOT_DST_DIR}";;
147 :) printf "$myname: '${CT_ROOT_DST_DIR}': already exists\n"
152 src_inode=$(ls -1id "${CT_ROOT_SRC_DIR}/." |awk '{ print $1 }')
153 dst_inode=$(ls -1id "${CT_ROOT_DST_DIR}/." 2>/dev/null |awk '{ print $1 }')
154 if [ "${src_inode}" -eq "$((dst_inode+0))" ]; then
155 printf "$myname: source and destination are the same!\n"
159 # Check existence of the forced libraries file
160 if [ -n "${CT_LIB_FILE}" -a ! \( -f "${CT_LIB_FILE}" -a -r "${CT_LIB_FILE}" \) ]; then
161 printf "$myname: forced libraries file '${CT_LIB_FILE}' not found!\n"
165 # Create the working copy, no issue if already existing
166 mkdir -p "${CT_ROOT_DST_DIR}"
168 # Make all path absolute
169 CT_ROOT_SRC_DIR=$(cd "${CT_ROOT_SRC_DIR}"; pwd)
170 CT_ROOT_DST_DIR=$(cd "${CT_ROOT_DST_DIR}"; pwd)
171 CT_SYSROOT_DIR=$(cd "${CT_SYSROOT_DIR}"; pwd)
173 # Populate the destination directory with files from the source directory
174 cd "${CT_ROOT_SRC_DIR}"
175 cp -a . "${CT_ROOT_DST_DIR}"
178 # A function do search for a library
179 # Usage: do_add_lib libname
180 # returns: 0 if library was found and added, !0 otherwise
187 for dir in lib usr/lib; do
188 ${CT_PRINTF} " trying in '%s'" "${dir}"
189 libfile="${CT_SYSROOT_DIR}/${dir}/${libname}"
190 ${CT_PRINTF} ": '%s'\n" "${libfile}"
191 if [ -e "${libfile}" ]; then
193 true_libname=$("${CT_READELF}" -d "${libfile}" \
194 |"${grep}" "Library soname:" \
195 |"${sed}" -r -e 's,.+\[(.+)\] *$,\1,;' \
201 ${CT_PRINTF} " installing as '%s/%s', mode='%s'\n" "${dir}" "${true_libname}" "${mode}"
202 "${install}" -m "${mode}" "${libfile}" "${dir}/${true_libname}"
209 # We'll work in the copied rootfs
210 cd "${CT_ROOT_DST_DIR}"
212 # First of, copy the forced libraries into the working copy
214 if [ -n "${CT_LIB_FILE}" ]; then
215 lib_list=$("${sed}" -r -e ':loop; s/#.*//;' \
216 -e 's/[[:space:]]+//g;' \
217 -e 's/([^:])$/\1:/;' \
218 -e '/$/N; s/\n//; tloop;' \
222 CT_LIB_LIST=$(printf "${CT_LIB_LIST}:${lib_list}\n" \
223 |"${sed}" -r -e 's/^:+//; s/:+$//; s/:+/ /g;' \
225 if [ -n "${CT_LIB_LIST}" ]; then
226 ${CT_PRINTF} "Installing forced libraries...\n"
227 for name in ${CT_LIB_LIST}; do
228 [ -z "${name}" ] && continue
230 for libname in "lib${name}.so" "${name}.so" "${name}"; do
231 ${CT_PRINTF} " searching for '%s'\n" "${libname}"
232 if do_add_lib "${libname}"; then
237 if [ ${found} -eq 0 ]; then
238 printf "$myname: library '${libname}' not found!\n"
239 [ "${CT_FORCE}" = "y" ] || exit 1
244 # Parse the working copy for executables and libraries
246 while [ ${still_needed} -eq 1 ]; do
247 ${CT_PRINTF} "Looping...\n"
249 for f in $(find . -type f -exec file {} \; \
250 |"${grep}" -E ': ELF [[:digit:]]+-bit (L|M)SB (executable|shared object),' \
253 ${CT_PRINTF} "Scanning '%s'\n" "${f}"
254 for libname in $("${CT_READELF}" -d "${f}" \
255 |"${grep}" -E '\(NEEDED\)[[:space:]]+Shared library:' \
256 |"${sed}" -r -e 's,.+\[(.+)\] *$,\1,;' \
258 ${CT_PRINTF} " searching for '%s'\n" "${libname}"
259 if [ -e "lib/${libname}" \
260 -o -e "usr/lib/${libname}" ]; then
261 ${CT_PRINTF} " already present\n"
264 if do_add_lib "${libname}"; then
267 printf "$myname: library '${libname}' not found!\n"
268 [ "${CT_FORCE}" = "y" ] || exit 1
274 # OK, we're done. Back off.