summaryrefslogtreecommitdiff
path: root/tools/populate.in
blob: 00c0c754690e46faccb051d06ef9888a355e2786 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#!/bin/bash

# This script will populate the root directory with libs from the sysroot.
# (C) 2007 Yann E. MORIN
# Licensed under the GPL v2

# Detect where the toolchain is:
BIN_DIR="$(cd "$(dirname "$(readlink -fn "$0")")"; pwd)"
CT_READELF="${BIN_DIR}/@@CT_TARGET@@-readelf"
CT_SYSROOT_DIR="${BIN_DIR}/../@@CT_TARGET@@/sys-root"

myname=$(basename "$0")

doHelp() {
    cat <<_EOF_
$myname [-f] [-v] -s source_root -d destination_root

    -s dir
        use 'dir' as the un-populated (source) root directory

    -d dir
        use 'dir' as the place to put the populated root directory

    -f  force execution: if destination directory already exists,
        it will be removed first.

    -v  Be verbose
_EOF_
}

CT_ROOT_SRC_DIR=
CT_ROOT_DST_DIR=
CT_FORCE=no
CT_ECHO=true
while getopts ":s:d:fvh" CT_OPT; do
    case "${CT_OPT}" in
        s)  CT_ROOT_SRC_DIR="${OPTARG}";;
        d)  CT_ROOT_DST_DIR="${OPTARG}";;
        f)  CT_FORCE=y;;
        v)  CT_ECHO=echo;;
        h)  doHelp
            exit 0
            ;;
        :)  echo "$myname: '-${OPTARG}' takes exactly one argument."
            exit 1
            ;;
        ?)  echo "$myname: unknown option '-${OPTARG}'."
            exit 1
            ;;
    esac
done

# Sanity checks
if [ -z "${CT_ROOT_SRC_DIR}" -o -z "${CT_ROOT_DST_DIR}" ]; then
    doHelp
    exit 1
fi
if [ ! -d "${CT_ROOT_SRC_DIR}" ]; then
    echo "$myname: '${CT_ROOT_SRC_DIR}': no such file or directory"
    exit 1
fi
if [ -d "${CT_ROOT_DST_DIR}" -a "${CT_FORCE}" != "y" ]; then
    echo "$myname: '${CT_ROOT_DST_DIR}': already exists"
    exit 1
fi
src_inode=$(ls -di "${CT_ROOT_SRC_DIR}")
dst_inode=$(ls -di "${CT_ROOT_DST_DIR}" 2>/dev/null)
if [ "${src_inode}" = "${dst_inode}" ]; then
    echo "$myname: source and destination are the same!"
    exit 1
fi

# Get rid of potentially older destination directory
if [ -d "${CT_ROOT_DST_DIR}" ]; then
    mv "${CT_ROOT_DST_DIR}" "${CT_ROOT_DST_DIR}.$$"
    setsid nohup rm -rf "${CT_ROOT_DST_DIR}.$$" >/dev/null 2>&1 &
fi

# Create the working copy
mkdir -p "${CT_ROOT_DST_DIR}"

# Make all path absolute
CT_ROOT_SRC_DIR=$(cd "${CT_ROOT_SRC_DIR}"; pwd)
CT_ROOT_DST_DIR=$(cd "${CT_ROOT_DST_DIR}"; pwd)

cd "${CT_ROOT_SRC_DIR}"
tar cf - . |(cd "${CT_ROOT_DST_DIR}"; tar xf -)

# Parse the working copy for executables and libraries
cd "${CT_ROOT_DST_DIR}"
still_needed=1
while [ ${still_needed} -eq 1 ]; do
    ${CT_ECHO} "Looping..."
    still_needed=0
    for f in $(find . -type f -exec file {} \; |egrep ': ELF [[:digit:]]+-bit .SB (executable|shared object),' |cut -d ":" -f 1); do
        ${CT_ECHO} "Scanning '${f}'"
        for libname in $("${CT_READELF}" -d "${f}" |egrep '(NEEDED)' |sed -r -e 's,.+\[(.+)\] *$,\1,;'); do
            ${CT_ECHO} "  searching for '${libname}'"
            if [    -e "lib/${libname}"     \
                 -o -e "usr/lib/${libname}" ]; then
                ${CT_ECHO} "    already present"
                continue
            fi
            for dir in . usr; do
                ${CT_ECHO} -n "    trying in '${dir}'"
                libfile="${CT_SYSROOT_DIR}/${dir}/lib/${libname}"
                ${CT_ECHO} ": '${libfile}'"
                if [ -e "${libfile}" ]; then
                    mkdir -p "${dir}/lib"
                    ${CT_ECHO} "      installing '${dir}/lib/${libname}'"
                    cp "${libfile}" "${dir}/lib/${libname}"
                    still_needed=1
                    break
                fi
            done
        done
    done
done