tools/populate.in
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Mon Oct 13 20:36:37 2008 +0000 (2008-10-13)
changeset 925 ac50e4f1360a
parent 770 1af057f49f7e
permissions -rw-r--r--
No one sane would you 'ct-ng config' to configure crosstool-NG.
Remove this useless rule.

/trunk/kconfig/kconfig.mk | 8 2 6 0 ++------
/trunk/ct-ng.comp | 2 1 1 0 +-
2 files changed, 3 insertions(+), 7 deletions(-)
     1 #!/bin/bash
     2 
     3 # This script will populate the root directory with libs from the sysroot.
     4 # (C) 2007 Yann E. MORIN
     5 # Licensed under the GPL v2
     6 
     7 # Detect where the toolchain is:
     8 BIN_DIR="$(cd "$(dirname "$0")"; pwd)"
     9 CT_READELF="${BIN_DIR}/@@CT_TARGET@@-readelf"
    10 CT_SYSROOT_DIR="${BIN_DIR}/../@@CT_TARGET@@/sys-root"
    11 
    12 myname=$(basename "$0")
    13 
    14 doHelp() {
    15     cat <<_EOF_
    16 NAME
    17     $myname - populate the target root file system
    18 
    19 SYNOPSIS
    20     $myname OPTIONS -s source_root -d destination_root
    21 
    22 DESCRIPTION
    23     $myname will 'populate' your target root file system ('src_dir') with
    24     libraries from the toolchain (eg. libc.so...), storing the result into
    25     'dst_dir'.
    26 
    27 OPTIONS
    28     -s src_dir
    29         use 'src_dir' as the un-populated (source) root directory
    30 
    31     -d dst_dir
    32         use 'dst_dir' as the place to put the populated root directory
    33 
    34     -l name1[:name2[...]]
    35         Always add the specified shared library/ies name1, name2... from the
    36         toolchain (in the sys-root). Actual library names are searched as
    37         follows (where 'name' is replaced with the given name) in the
    38         sys-root directory:
    39           - libname.so
    40           - name.so
    41           - name
    42         If the file is found, then the SONAME of the library is used, and the
    43         library is copied with that name. If the library was not found, this
    44         yields an error (unless -f was given).
    45 
    46     -L file
    47         Read 'file' for a list of shared libraries to always add from the
    48         toolchain. The file should contain one library name per line; text
    49         after a # is ignored until the end of the line; spaces are ignored;
    50         empty lines are ignored. Libraries are searched for as with -l.
    51 
    52     -f  force execution: if destination directory already exists, it will be
    53         removed first; if a specified library (above) was not found, continue.
    54 
    55     -v  Be verbose
    56 
    57 _EOF_
    58 }
    59 
    60 CT_ROOT_SRC_DIR=
    61 CT_ROOT_DST_DIR=
    62 CT_LIB_LIST=
    63 CT_LIB_FILE=
    64 CT_FORCE=no
    65 CT_ECHO=true
    66 while getopts ":s:d:l:L:fvh" CT_OPT; do
    67     case "${CT_OPT}" in
    68         s)  CT_ROOT_SRC_DIR="${OPTARG}";;
    69         d)  CT_ROOT_DST_DIR="${OPTARG}";;
    70         l)  CT_LIB_LIST="${CT_LIB_LIST}:${OPTARG}";;
    71         L)  CT_LIB_FILE="${OPTARG}";;
    72         f)  CT_FORCE=y;;
    73         v)  CT_ECHO=echo;;
    74         h)  doHelp
    75             exit 0
    76             ;;
    77         :)  echo "$myname: '-${OPTARG}' takes exactly one argument."
    78             exit 1
    79             ;;
    80         ?)  echo "$myname: unknown option '-${OPTARG}'."
    81             exit 1
    82             ;;
    83     esac
    84 done
    85 
    86 # Sanity checks
    87 if [ -z "${CT_ROOT_SRC_DIR}" -o -z "${CT_ROOT_DST_DIR}" ]; then
    88     doHelp
    89     exit 1
    90 fi
    91 if [ ! -d "${CT_ROOT_SRC_DIR}" ]; then
    92     echo "$myname: '${CT_ROOT_SRC_DIR}': no such file or directory"
    93     exit 1
    94 fi
    95 if [ -d "${CT_ROOT_DST_DIR}" -a "${CT_FORCE}" != "y" ]; then
    96     echo "$myname: '${CT_ROOT_DST_DIR}': already exists"
    97     exit 1
    98 fi
    99 src_inode=$(ls -di "${CT_ROOT_SRC_DIR}")
   100 dst_inode=$(ls -di "${CT_ROOT_DST_DIR}" 2>/dev/null)
   101 if [ "${src_inode}" = "${dst_inode}" ]; then
   102     echo "$myname: source and destination are the same!"
   103     exit 1
   104 fi
   105 
   106 # Check existence of the forced libraries file
   107 if [ -n "${CT_LIB_FILE}" -a ! \( -f "${CT_LIB_FILE}" -a -r "${CT_LIB_FILE}" \) ]; then
   108     echo "$myname: forced libraries file '${CT_LIB_FILE}' not found!"
   109     exit 1
   110 fi
   111 
   112 # Get rid of potentially older destination directory
   113 if [ -d "${CT_ROOT_DST_DIR}" ]; then
   114     mv "${CT_ROOT_DST_DIR}" "${CT_ROOT_DST_DIR}.$$"
   115     setsid nohup rm -rf "${CT_ROOT_DST_DIR}.$$" >/dev/null 2>&1 &
   116 fi
   117 
   118 # Create the working copy
   119 mkdir -p "${CT_ROOT_DST_DIR}"
   120 
   121 # Make all path absolute
   122 CT_ROOT_SRC_DIR=$(cd "${CT_ROOT_SRC_DIR}"; pwd)
   123 CT_ROOT_DST_DIR=$(cd "${CT_ROOT_DST_DIR}"; pwd)
   124 
   125 pushd "${CT_ROOT_SRC_DIR}" >/dev/null
   126 tar cf - . |(cd "${CT_ROOT_DST_DIR}"; tar xf -)
   127 popd >/dev/null
   128 
   129 # A function do search for a library
   130 # Usage: do_add_lib libname
   131 # returns: 0 if library was found and added, !0 otherwise
   132 do_add_lib() {
   133     local libname="$1"
   134     local ret=1
   135     local true_libname
   136     for dir in . usr; do
   137         ${CT_ECHO} -n "    trying in '${dir}'"
   138         libfile="${CT_SYSROOT_DIR}/${dir}/lib/${libname}"
   139         ${CT_ECHO} ": '${libfile}'"
   140         if [ -e "${libfile}" ]; then
   141             mkdir -p "${dir}/lib"
   142             true_libname=$("${CT_READELF}" -d "${libfile}" |egrep "SONAME" |sed -r -e 's,.+\[(.+)\] *$,\1,;')
   143             ${CT_ECHO} "      installing as '${dir}/lib/${true_libname}'"
   144             cat "${libfile}" >"${dir}/lib/${true_libname}"
   145             ret=0
   146             break
   147         fi
   148     done
   149     return ${ret}
   150 }
   151 
   152 # First of, copy the forced libraries into the working copy
   153 if [ -n "${CT_LIB_FILE}" ]; then
   154     lib_list=$(sed -r -e ':loop; s/#.*//; s/[[:space:]]+//g; s/([^:])$/\1:/; /$/N; s/\n//; tloop;' "${CT_LIB_FILE}")
   155     CT_LIB_LIST=$(echo "${CT_LIB_LIST}:${lib_list}" |sed -r -e 's/:+/:/g; s/^:+//; s/:+$//;')
   156 fi
   157 CT_LIB_LIST="${CT_LIB_LIST//:/ }"
   158 ${CT_ECHO} "Installing forced libraries..."
   159 pushd "${CT_ROOT_DST_DIR}" >/dev/null
   160 for name in ${CT_LIB_LIST}; do
   161     [ -z "${name}" ] && continue
   162     found=0
   163     for libname in "lib${name}.so" "${name}.so" "${name}"; do
   164         ${CT_ECHO} "  searching for '${libname}'"
   165         if do_add_lib "${libname}"; then
   166             found=1
   167             break
   168         fi
   169     done
   170     if [ ${found} -eq 0 ]; then
   171         echo "$myname: library '${libname}' not found!"
   172         [ "${CT_FORCE}" = y ] || exit 1
   173     fi
   174 done
   175 popd >/dev/null
   176 
   177 # Parse the working copy for executables and libraries
   178 pushd "${CT_ROOT_DST_DIR}" >/dev/null
   179 still_needed=1
   180 while [ ${still_needed} -eq 1 ]; do
   181     ${CT_ECHO} "Looping..."
   182     still_needed=0
   183     for f in $(find . -type f -exec file {} \; |egrep ': ELF [[:digit:]]+-bit .SB (executable|shared object),' |cut -d ":" -f 1); do
   184         ${CT_ECHO} "Scanning '${f}'"
   185         for libname in $("${CT_READELF}" -d "${f}" |egrep '(NEEDED)' |sed -r -e 's,.+\[(.+)\] *$,\1,;'); do
   186             ${CT_ECHO} "  searching for '${libname}'"
   187             if [    -e "lib/${libname}"     \
   188                  -o -e "usr/lib/${libname}" ]; then
   189                 ${CT_ECHO} "    already present"
   190                 continue
   191             fi
   192             if do_add_lib "${libname}"; then
   193                 still_needed=1
   194             else
   195                 echo "$myname: library '${libname}' not found!"
   196             fi
   197         done
   198     done
   199 done
   200 popd >/dev/null