yann@1177: #!@@CT_bash@@ yann@217: # This script will populate the root directory with libs from the sysroot. yann@217: # (C) 2007 Yann E. MORIN yann@217: # Licensed under the GPL v2 yann@1177: set -e yann@217: yann@755: # Detect where the toolchain is: yann@1177: CT_PREFIX_DIR="$(cd "$(dirname "$0")/.."; pwd)" yann@1177: CT_BIN_DIR="${CT_PREFIX_DIR}/bin" yann@1177: CT_READELF="${CT_BIN_DIR}/@@CT_TARGET@@-readelf" yann@1177: CT_LIB_DIR="${CT_PREFIX_DIR}/lib" yann@1177: CT_SYSROOT_DIR="$(cd "${CT_BIN_DIR}/../@@CT_TARGET@@/sys-root"; pwd)" yann@217: yann@217: myname=$(basename "$0") yann@217: yann@1400: # Use the tools discovered by crosstool-NG's ./configure: yann@1190: install="@@CT_install@@" yann@1190: grep="@@CT_grep@@" yann@1190: sed="@@CT_sed@@" yann@1177: yann@217: doHelp() { yann@217: cat <<_EOF_ yann@910: NAME yann@910: $myname - populate the target root file system yann@217: yann@910: SYNOPSIS yann@910: $myname OPTIONS -s source_root -d destination_root yann@217: yann@910: DESCRIPTION yann@910: $myname will 'populate' your target root file system ('src_dir') with yann@910: libraries from the toolchain (eg. libc.so...), storing the result into yann@910: 'dst_dir'. yann@217: yann@910: OPTIONS yann@910: -s src_dir yann@910: use 'src_dir' as the un-populated (source) root directory yann@910: yann@910: -d dst_dir yann@910: use 'dst_dir' as the place to put the populated root directory yann@910: yann@910: -l name1[:name2[...]] yann@910: Always add the specified shared library/ies name1, name2... from the yann@910: toolchain (in the sys-root). Actual library names are searched as yann@910: follows (where 'name' is replaced with the given name) in the yann@910: sys-root directory: yann@910: - libname.so yann@910: - name.so yann@910: - name yann@910: If the file is found, then the SONAME of the library is used, and the yann@910: library is copied with that name. If the library was not found, this yann@910: yields an error (unless -f was given). yann@910: yann@910: -L file yann@910: Read 'file' for a list of shared libraries to always add from the yann@910: toolchain. The file should contain one library name per line; text yann@910: after a # is ignored until the end of the line; spaces are ignored; yann@910: empty lines are ignored. Libraries are searched for as with -l. yann@910: yann@910: -f force execution: if destination directory already exists, it will be yann@910: removed first; if a specified library (above) was not found, continue. yann@258: yann@1352: -v Be verbose. By default, populate is absolutely silent. yann@910: yann@217: _EOF_ yann@217: } yann@217: yann@217: CT_ROOT_SRC_DIR= yann@217: CT_ROOT_DST_DIR= yann@910: CT_LIB_LIST= yann@910: CT_LIB_FILE= yann@259: CT_FORCE=no yann@1352: CT_PRINTF=: yann@1177: OPTIND=1 yann@910: while getopts ":s:d:l:L:fvh" CT_OPT; do yann@217: case "${CT_OPT}" in yann@217: s) CT_ROOT_SRC_DIR="${OPTARG}";; yann@217: d) CT_ROOT_DST_DIR="${OPTARG}";; yann@910: l) CT_LIB_LIST="${CT_LIB_LIST}:${OPTARG}";; yann@910: L) CT_LIB_FILE="${OPTARG}";; yann@259: f) CT_FORCE=y;; yann@1352: v) CT_PRINTF=printf;; yann@217: h) doHelp yann@217: exit 0 yann@217: ;; yann@523: :) echo "$myname: '-${OPTARG}' takes exactly one argument." yann@217: exit 1 yann@217: ;; yann@523: ?) echo "$myname: unknown option '-${OPTARG}'." yann@217: exit 1 yann@217: ;; yann@217: esac yann@217: done yann@217: yann@217: # Sanity checks yann@217: if [ -z "${CT_ROOT_SRC_DIR}" -o -z "${CT_ROOT_DST_DIR}" ]; then yann@217: doHelp yann@217: exit 1 yann@217: fi yann@217: if [ ! -d "${CT_ROOT_SRC_DIR}" ]; then yann@523: echo "$myname: '${CT_ROOT_SRC_DIR}': no such file or directory" yann@217: exit 1 yann@217: fi yann@259: if [ -d "${CT_ROOT_DST_DIR}" -a "${CT_FORCE}" != "y" ]; then yann@523: echo "$myname: '${CT_ROOT_DST_DIR}': already exists" yann@217: exit 1 yann@217: fi yann@1352: src_inode=$(stat -c '%i' "${CT_ROOT_SRC_DIR}/.") yann@1352: dst_inode=$(stat -c '%i' "${CT_ROOT_DST_DIR}/." 2>/dev/null || true) yann@1352: if [ "${src_inode}" -eq "$((dst_inode+0))" ]; then yann@217: echo "$myname: source and destination are the same!" yann@217: exit 1 yann@217: fi yann@217: yann@910: # Check existence of the forced libraries file yann@910: if [ -n "${CT_LIB_FILE}" -a ! \( -f "${CT_LIB_FILE}" -a -r "${CT_LIB_FILE}" \) ]; then yann@910: echo "$myname: forced libraries file '${CT_LIB_FILE}' not found!" yann@910: exit 1 yann@910: fi yann@910: yann@217: # Get rid of potentially older destination directory yann@1177: rm -rf "${CT_ROOT_DST_DIR}" yann@217: yann@217: # Create the working copy yann@217: mkdir -p "${CT_ROOT_DST_DIR}" yann@217: yann@217: # Make all path absolute yann@253: CT_ROOT_SRC_DIR=$(cd "${CT_ROOT_SRC_DIR}"; pwd) yann@253: CT_ROOT_DST_DIR=$(cd "${CT_ROOT_DST_DIR}"; pwd) yann@217: yann@1678: # Populate the destination directory with files from the source directory yann@910: pushd "${CT_ROOT_SRC_DIR}" >/dev/null yann@1678: cp -a . "${CT_ROOT_DST_DIR}" yann@910: popd >/dev/null yann@910: yann@910: # A function do search for a library yann@910: # Usage: do_add_lib libname yann@910: # returns: 0 if library was found and added, !0 otherwise yann@910: do_add_lib() { yann@910: local libname="$1" yann@910: local true_libname yann@1177: local dir yann@1352: local mode yann@1352: yann@1177: for dir in lib usr/lib; do yann@1352: ${CT_PRINTF} " trying in '%s'" "${dir}" yann@1177: libfile="${CT_SYSROOT_DIR}/${dir}/${libname}" yann@1352: ${CT_PRINTF} ": '%s'\n" "${libfile}" yann@910: if [ -e "${libfile}" ]; then yann@1177: mkdir -p "${dir}" yann@1177: true_libname=$("${CT_READELF}" -d "${libfile}" \ yann@1177: |"${grep}" "Library soname:" \ yann@1177: |"${sed}" -r -e 's,.+\[(.+)\] *$,\1,;' \ yann@1177: ) yann@1352: case "${libfile}" in yann@1352: */ld*) mode=0755;; yann@1352: *) mode=0644;; yann@1352: esac yann@1352: ${CT_PRINTF} " installing as '%s/%s', mode='%s'\n" "${dir}" "${true_libname}" "${mode}" yann@1352: "${install}" -m "${mode}" "${libfile}" "${dir}/${true_libname}" yann@1177: return 0 yann@910: break yann@910: fi yann@910: done yann@1177: return 1 yann@910: } yann@910: yann@1352: # We'll work in the copied rootfs yann@1352: pushd "${CT_ROOT_DST_DIR}" >/dev/null yann@1352: yann@910: # First of, copy the forced libraries into the working copy yann@910: if [ -n "${CT_LIB_FILE}" ]; then yann@1177: lib_list=$("${sed}" -r -e ':loop; s/#.*//;' \ yann@1177: -e 's/[[:space:]]+//g;' \ yann@1177: -e 's/([^:])$/\1:/;' \ yann@1177: -e '/$/N; s/\n//; tloop;' \ yann@1177: "${CT_LIB_FILE}" yann@1177: ) yann@1177: CT_LIB_LIST=$(echo "${CT_LIB_LIST}:${lib_list}" \ yann@1177: |"${sed}" -r -e 's/:+/:/g; s/^:+//; s/:+$//;' \ yann@1177: ) yann@910: fi yann@1177: CT_LIB_LIST=$(echo "${CT_LIB_LIST}:${lib_list}" \ yann@1177: |"${sed}" -r -e 's/^:+//; s/:+$//; s/:+/ /g;' \ yann@1177: ) yann@1352: if [ -n "${CT_LIB_LIST}" ]; then yann@1352: ${CT_PRINTF} "Installing forced libraries...\n" yann@1352: for name in ${CT_LIB_LIST}; do yann@1352: [ -z "${name}" ] && continue yann@1352: found=0 yann@1352: for libname in "lib${name}.so" "${name}.so" "${name}"; do yann@1352: ${CT_PRINTF} " searching for '%s'\n" "${libname}" yann@1352: if do_add_lib "${libname}"; then yann@1352: found=1 yann@1352: break yann@1352: fi yann@1352: done yann@1352: if [ ${found} -eq 0 ]; then yann@1352: echo "$myname: library '${libname}' not found!" yann@1352: [ "${CT_FORCE}" = y ] || exit 1 yann@910: fi yann@910: done yann@1352: fi yann@217: yann@217: # Parse the working copy for executables and libraries yann@217: still_needed=1 yann@217: while [ ${still_needed} -eq 1 ]; do yann@1352: ${CT_PRINTF} "Looping...\n" yann@217: still_needed=0 yann@1177: for f in $(find . -type f -exec file {} \; \ yann@1177: |"${grep}" -E ': ELF [[:digit:]]+-bit (L|M)SB (executable|shared object),' \ yann@1177: |cut -d ":" -f 1 \ yann@1177: ); do yann@1352: ${CT_PRINTF} "Scanning '%s'\n" "${f}" yann@1177: for libname in $("${CT_READELF}" -d "${f}" \ yann@1177: |"${grep}" -E '\(NEEDED\)[[:space:]]+Shared library:' \ yann@1177: |"${sed}" -r -e 's,.+\[(.+)\] *$,\1,;' \ yann@1177: ); do yann@1352: ${CT_PRINTF} " searching for '%s'\n" "${libname}" yann@259: if [ -e "lib/${libname}" \ yann@259: -o -e "usr/lib/${libname}" ]; then yann@1352: ${CT_PRINTF} " already present\n" yann@217: continue yann@217: fi yann@910: if do_add_lib "${libname}"; then yann@910: still_needed=1 yann@910: else yann@910: echo "$myname: library '${libname}' not found!" yann@910: fi yann@217: done yann@217: done yann@217: done yann@1352: yann@1352: # OK, we're done. Back off. yann@910: popd >/dev/null