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@1190: # Use the tols 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@217: -v Be verbose 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@217: CT_ECHO=true 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@217: v) CT_ECHO=echo;; 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@217: src_inode=$(ls -di "${CT_ROOT_SRC_DIR}") yann@217: dst_inode=$(ls -di "${CT_ROOT_DST_DIR}" 2>/dev/null) yann@217: if [ "${src_inode}" = "${dst_inode}" ]; 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@1177: # Populate the destination directory with files form the source directory yann@910: pushd "${CT_ROOT_SRC_DIR}" >/dev/null yann@217: tar cf - . |(cd "${CT_ROOT_DST_DIR}"; tar xf -) 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@1177: for dir in lib usr/lib; do yann@910: ${CT_ECHO} -n " trying in '${dir}'" yann@1177: libfile="${CT_SYSROOT_DIR}/${dir}/${libname}" yann@910: ${CT_ECHO} ": '${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@1177: ${CT_ECHO} " installing as '${dir}/${true_libname}'" yann@1177: "${install}" -m 0644 "${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@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@910: ${CT_ECHO} "Installing forced libraries..." yann@910: pushd "${CT_ROOT_DST_DIR}" >/dev/null yann@910: for name in ${CT_LIB_LIST}; do yann@910: [ -z "${name}" ] && continue yann@910: found=0 yann@910: for libname in "lib${name}.so" "${name}.so" "${name}"; do yann@910: ${CT_ECHO} " searching for '${libname}'" yann@910: if do_add_lib "${libname}"; then yann@910: found=1 yann@910: break yann@910: fi yann@910: done yann@910: if [ ${found} -eq 0 ]; then yann@910: echo "$myname: library '${libname}' not found!" yann@910: [ "${CT_FORCE}" = y ] || exit 1 yann@910: fi yann@910: done yann@910: popd >/dev/null yann@217: yann@217: # Parse the working copy for executables and libraries yann@910: pushd "${CT_ROOT_DST_DIR}" >/dev/null yann@217: still_needed=1 yann@217: while [ ${still_needed} -eq 1 ]; do yann@217: ${CT_ECHO} "Looping..." 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@523: ${CT_ECHO} "Scanning '${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@523: ${CT_ECHO} " searching for '${libname}'" yann@259: if [ -e "lib/${libname}" \ yann@259: -o -e "usr/lib/${libname}" ]; then yann@217: ${CT_ECHO} " already present" 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@910: popd >/dev/null