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 # Detect where the toolchain is:
8 CT_PREFIX_DIR="$(cd "$(dirname "$0")/.."; pwd)"
9 CT_BIN_DIR="${CT_PREFIX_DIR}/bin"
10 CT_READELF="${CT_BIN_DIR}/@@CT_TARGET@@-readelf"
11 CT_LIB_DIR="${CT_PREFIX_DIR}/lib"
12 CT_SYSROOT_DIR="$(cd "${CT_BIN_DIR}/../@@CT_TARGET@@/sys-root"; pwd)"
14 myname=$(basename "$0")
16 # Use the tools discovered by crosstool-NG's ./configure:
17 install="@@CT_install@@"
24 $myname - populate the target root file system
27 $myname OPTIONS -s source_root -d destination_root
30 $myname will 'populate' your target root file system ('src_dir') with
31 libraries from the toolchain (eg. libc.so...), storing the result into
36 use 'src_dir' as the un-populated (source) root directory
39 use 'dst_dir' as the place to put the populated root directory
42 use 'sysroot_dir' as the sysroot instead of the toolchain default
45 Always add the specified shared library/ies name1, name2... from the
46 toolchain (in the sys-root). Actual library names are searched as
47 follows (where 'name' is replaced with the given name) in the
52 If the file is found, then the SONAME of the library is used, and the
53 library is copied with that name. If the library was not found, this
54 yields an error (unless -f was given).
57 Read 'file' for a list of shared libraries to always add from the
58 toolchain. The file should contain one library name per line; text
59 after a # is ignored until the end of the line; spaces are ignored;
60 empty lines are ignored. Libraries are searched for as with -l.
62 -f force execution: if destination directory already exists, it will be
63 removed first; if a specified library (above) was not found, continue.
64 Note: if using -m and the destination directory already exists, it
65 is *not* removed, see below.
67 -m Merge the source root directory with the destination root directory.
68 If the latter does not exist, it is created, and -m is ignored.
69 If the destination droot directory exists, then the content of the
70 source root directory is copied in there, and the result is populated
72 It can be usefull if constructing a rootfs incrementally from many
73 smaller source root directories, or if your destination root directory
74 is an NFS export that your target mounts as / (and you don't want to
75 re-run exportfs -av everytime). USE WITH CARE!
77 -v Be verbose. By default, populate is absolutely silent.
90 while getopts ":s:d:r:l:L:fmvh" CT_OPT; do
92 s) CT_ROOT_SRC_DIR="${OPTARG}";;
93 d) CT_ROOT_DST_DIR="${OPTARG}";;
94 r) CT_SYSROOT_DIR="${OPTARG}";;
95 l) CT_LIB_LIST="${CT_LIB_LIST}:${OPTARG}";;
96 L) CT_LIB_FILE="${OPTARG}";;
103 :) echo "$myname: '-${OPTARG}' takes exactly one argument."
106 ?) echo "$myname: unknown option '-${OPTARG}'."
113 if [ -z "${CT_ROOT_SRC_DIR}" -o -z "${CT_ROOT_DST_DIR}" ]; then
117 if [ ! -d "${CT_ROOT_SRC_DIR}" ]; then
118 echo "$myname: '${CT_ROOT_SRC_DIR}': no such file or directory"
121 if [ ! -d "${CT_SYSROOT_DIR}" ]; then
122 echo "$myname: '${CT_SYSROOT_DIR}': no such file or directory"
125 # If the dest dir does not exist, all is well
126 # If merging, we accept an existing dest directory
127 # If forcing and not merging, we remove an exiting dest directory
128 # If not forcing and not merging, we do not accept an exiting dest directory
129 if [ -d "${CT_ROOT_DST_DIR}" ]; then
130 case "${CT_FORCE}:${CT_MERGE}" in
132 y:) rm -rf "${CT_ROOT_DST_DIR}";;
133 :) echo "$myname: '${CT_ROOT_DST_DIR}': already exists" && exit 1 ;;
136 src_inode=$(stat -c '%i' "${CT_ROOT_SRC_DIR}/.")
137 dst_inode=$(stat -c '%i' "${CT_ROOT_DST_DIR}/." 2>/dev/null || true)
138 if [ "${src_inode}" -eq "$((dst_inode+0))" ]; then
139 echo "$myname: source and destination are the same!"
143 # Check existence of the forced libraries file
144 if [ -n "${CT_LIB_FILE}" -a ! \( -f "${CT_LIB_FILE}" -a -r "${CT_LIB_FILE}" \) ]; then
145 echo "$myname: forced libraries file '${CT_LIB_FILE}' not found!"
149 # Create the working copy, no issue if already existing
150 mkdir -p "${CT_ROOT_DST_DIR}"
152 # Make all path absolute
153 CT_ROOT_SRC_DIR=$(cd "${CT_ROOT_SRC_DIR}"; pwd)
154 CT_ROOT_DST_DIR=$(cd "${CT_ROOT_DST_DIR}"; pwd)
156 # Populate the destination directory with files from the source directory
157 pushd "${CT_ROOT_SRC_DIR}" >/dev/null
158 cp -a . "${CT_ROOT_DST_DIR}"
161 # A function do search for a library
162 # Usage: do_add_lib libname
163 # returns: 0 if library was found and added, !0 otherwise
170 for dir in lib usr/lib; do
171 ${CT_PRINTF} " trying in '%s'" "${dir}"
172 libfile="${CT_SYSROOT_DIR}/${dir}/${libname}"
173 ${CT_PRINTF} ": '%s'\n" "${libfile}"
174 if [ -e "${libfile}" ]; then
176 true_libname=$("${CT_READELF}" -d "${libfile}" \
177 |"${grep}" "Library soname:" \
178 |"${sed}" -r -e 's,.+\[(.+)\] *$,\1,;' \
184 ${CT_PRINTF} " installing as '%s/%s', mode='%s'\n" "${dir}" "${true_libname}" "${mode}"
185 "${install}" -m "${mode}" "${libfile}" "${dir}/${true_libname}"
193 # We'll work in the copied rootfs
194 pushd "${CT_ROOT_DST_DIR}" >/dev/null
196 # First of, copy the forced libraries into the working copy
197 if [ -n "${CT_LIB_FILE}" ]; then
198 lib_list=$("${sed}" -r -e ':loop; s/#.*//;' \
199 -e 's/[[:space:]]+//g;' \
200 -e 's/([^:])$/\1:/;' \
201 -e '/$/N; s/\n//; tloop;' \
204 CT_LIB_LIST=$(echo "${CT_LIB_LIST}:${lib_list}" \
205 |"${sed}" -r -e 's/:+/:/g; s/^:+//; s/:+$//;' \
208 CT_LIB_LIST=$(echo "${CT_LIB_LIST}:${lib_list}" \
209 |"${sed}" -r -e 's/^:+//; s/:+$//; s/:+/ /g;' \
211 if [ -n "${CT_LIB_LIST}" ]; then
212 ${CT_PRINTF} "Installing forced libraries...\n"
213 for name in ${CT_LIB_LIST}; do
214 [ -z "${name}" ] && continue
216 for libname in "lib${name}.so" "${name}.so" "${name}"; do
217 ${CT_PRINTF} " searching for '%s'\n" "${libname}"
218 if do_add_lib "${libname}"; then
223 if [ ${found} -eq 0 ]; then
224 echo "$myname: library '${libname}' not found!"
225 [ "${CT_FORCE}" = y ] || exit 1
230 # Parse the working copy for executables and libraries
232 while [ ${still_needed} -eq 1 ]; do
233 ${CT_PRINTF} "Looping...\n"
235 for f in $(find . -type f -exec file {} \; \
236 |"${grep}" -E ': ELF [[:digit:]]+-bit (L|M)SB (executable|shared object),' \
239 ${CT_PRINTF} "Scanning '%s'\n" "${f}"
240 for libname in $("${CT_READELF}" -d "${f}" \
241 |"${grep}" -E '\(NEEDED\)[[:space:]]+Shared library:' \
242 |"${sed}" -r -e 's,.+\[(.+)\] *$,\1,;' \
244 ${CT_PRINTF} " searching for '%s'\n" "${libname}"
245 if [ -e "lib/${libname}" \
246 -o -e "usr/lib/${libname}" ]; then
247 ${CT_PRINTF} " already present\n"
250 if do_add_lib "${libname}"; then
253 echo "$myname: library '${libname}' not found!"
259 # OK, we're done. Back off.