yann@217: #!/bin/bash yann@217: 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@217: yann@755: # Detect where the toolchain is: yann@770: BIN_DIR="$(cd "$(dirname "$0")"; pwd)" yann@755: CT_READELF="${BIN_DIR}/@@CT_TARGET@@-readelf" yann@755: CT_SYSROOT_DIR="${BIN_DIR}/../@@CT_TARGET@@/sys-root" yann@217: yann@217: myname=$(basename "$0") yann@217: 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@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@217: if [ -d "${CT_ROOT_DST_DIR}" ]; then yann@217: mv "${CT_ROOT_DST_DIR}" "${CT_ROOT_DST_DIR}.$$" yann@320: setsid nohup rm -rf "${CT_ROOT_DST_DIR}.$$" >/dev/null 2>&1 & yann@217: fi 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@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 ret=1 yann@910: local true_libname yann@910: for dir in . usr; do yann@910: ${CT_ECHO} -n " trying in '${dir}'" yann@910: libfile="${CT_SYSROOT_DIR}/${dir}/lib/${libname}" yann@910: ${CT_ECHO} ": '${libfile}'" yann@910: if [ -e "${libfile}" ]; then yann@910: mkdir -p "${dir}/lib" yann@910: true_libname=$("${CT_READELF}" -d "${libfile}" |egrep "SONAME" |sed -r -e 's,.+\[(.+)\] *$,\1,;') yann@910: ${CT_ECHO} " installing as '${dir}/lib/${true_libname}'" yann@910: cat "${libfile}" >"${dir}/lib/${true_libname}" yann@910: ret=0 yann@910: break yann@910: fi yann@910: done yann@910: return ${ret} 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@910: lib_list=$(sed -r -e ':loop; s/#.*//; s/[[:space:]]+//g; s/([^:])$/\1:/; /$/N; s/\n//; tloop;' "${CT_LIB_FILE}") yann@910: CT_LIB_LIST=$(echo "${CT_LIB_LIST}:${lib_list}" |sed -r -e 's/:+/:/g; s/^:+//; s/:+$//;') yann@910: fi yann@910: CT_LIB_LIST="${CT_LIB_LIST//:/ }" 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@217: for f in $(find . -type f -exec file {} \; |egrep ': ELF [[:digit:]]+-bit .SB (executable|shared object),' |cut -d ":" -f 1); do yann@523: ${CT_ECHO} "Scanning '${f}'" yann@217: for libname in $("${CT_READELF}" -d "${f}" |egrep '(NEEDED)' |sed -r -e 's,.+\[(.+)\] *$,\1,;'); 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