scripts/populate.in
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Thu Jun 11 21:47:19 2009 +0000 (2009-06-11)
changeset 1352 d7ddcb75e0f7
parent 1190 15908c920549
child 1410 23a8ffdf8574
permissions -rw-r--r--
populate: fix installing dynamic linker 'ld.so'

The dynamic linker, ld.so, needs the execute bit to be set.
Detect tht the library being installed is in fact ld.so and
install it with 0755 instead of 0644.

Fix detecting src == dst.

Use a simpler command to copy src -> dst.

Also change echo to printf, get rid of 'echo -n', which is
highly non-portable.


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