mirror of
https://github.com/crosstool-ng/crosstool-ng.git
synced 2024-12-19 04:47:52 +00:00
c564be2675
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(-)
235 lines
7.6 KiB
Plaintext
235 lines
7.6 KiB
Plaintext
#!@@CT_bash@@
|
|
# This script will populate the root directory with libs from the sysroot.
|
|
# (C) 2007 Yann E. MORIN
|
|
# Licensed under the GPL v2
|
|
set -e
|
|
|
|
# Detect where the toolchain is:
|
|
CT_PREFIX_DIR="$(cd "$(dirname "$0")/.."; pwd)"
|
|
CT_BIN_DIR="${CT_PREFIX_DIR}/bin"
|
|
CT_READELF="${CT_BIN_DIR}/@@CT_TARGET@@-readelf"
|
|
CT_LIB_DIR="${CT_PREFIX_DIR}/lib"
|
|
CT_SYSROOT_DIR="$(cd "${CT_BIN_DIR}/../@@CT_TARGET@@/sys-root"; pwd)"
|
|
|
|
myname=$(basename "$0")
|
|
|
|
# Use the tools discovered by crosstool-NG's ./configure:
|
|
install="@@CT_install@@"
|
|
grep="@@CT_grep@@"
|
|
sed="@@CT_sed@@"
|
|
|
|
doHelp() {
|
|
cat <<_EOF_
|
|
NAME
|
|
$myname - populate the target root file system
|
|
|
|
SYNOPSIS
|
|
$myname OPTIONS -s source_root -d destination_root
|
|
|
|
DESCRIPTION
|
|
$myname will 'populate' your target root file system ('src_dir') with
|
|
libraries from the toolchain (eg. libc.so...), storing the result into
|
|
'dst_dir'.
|
|
|
|
OPTIONS
|
|
-s src_dir
|
|
use 'src_dir' as the un-populated (source) root directory
|
|
|
|
-d dst_dir
|
|
use 'dst_dir' as the place to put the populated root directory
|
|
|
|
-l name1[:name2[...]]
|
|
Always add the specified shared library/ies name1, name2... from the
|
|
toolchain (in the sys-root). Actual library names are searched as
|
|
follows (where 'name' is replaced with the given name) in the
|
|
sys-root directory:
|
|
- libname.so
|
|
- name.so
|
|
- name
|
|
If the file is found, then the SONAME of the library is used, and the
|
|
library is copied with that name. If the library was not found, this
|
|
yields an error (unless -f was given).
|
|
|
|
-L file
|
|
Read 'file' for a list of shared libraries to always add from the
|
|
toolchain. The file should contain one library name per line; text
|
|
after a # is ignored until the end of the line; spaces are ignored;
|
|
empty lines are ignored. Libraries are searched for as with -l.
|
|
|
|
-f force execution: if destination directory already exists, it will be
|
|
removed first; if a specified library (above) was not found, continue.
|
|
|
|
-v Be verbose. By default, populate is absolutely silent.
|
|
|
|
_EOF_
|
|
}
|
|
|
|
CT_ROOT_SRC_DIR=
|
|
CT_ROOT_DST_DIR=
|
|
CT_LIB_LIST=
|
|
CT_LIB_FILE=
|
|
CT_FORCE=no
|
|
CT_PRINTF=:
|
|
OPTIND=1
|
|
while getopts ":s:d:l:L:fvh" CT_OPT; do
|
|
case "${CT_OPT}" in
|
|
s) CT_ROOT_SRC_DIR="${OPTARG}";;
|
|
d) CT_ROOT_DST_DIR="${OPTARG}";;
|
|
l) CT_LIB_LIST="${CT_LIB_LIST}:${OPTARG}";;
|
|
L) CT_LIB_FILE="${OPTARG}";;
|
|
f) CT_FORCE=y;;
|
|
v) CT_PRINTF=printf;;
|
|
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=$(stat -c '%i' "${CT_ROOT_SRC_DIR}/.")
|
|
dst_inode=$(stat -c '%i' "${CT_ROOT_DST_DIR}/." 2>/dev/null || true)
|
|
if [ "${src_inode}" -eq "$((dst_inode+0))" ]; then
|
|
echo "$myname: source and destination are the same!"
|
|
exit 1
|
|
fi
|
|
|
|
# Check existence of the forced libraries file
|
|
if [ -n "${CT_LIB_FILE}" -a ! \( -f "${CT_LIB_FILE}" -a -r "${CT_LIB_FILE}" \) ]; then
|
|
echo "$myname: forced libraries file '${CT_LIB_FILE}' not found!"
|
|
exit 1
|
|
fi
|
|
|
|
# Get rid of potentially older destination directory
|
|
rm -rf "${CT_ROOT_DST_DIR}"
|
|
|
|
# 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)
|
|
|
|
# Populate the destination directory with files form the source directory
|
|
pushd "${CT_ROOT_SRC_DIR}" >/dev/null
|
|
tar cf - . |tar xf - -C "${CT_ROOT_DST_DIR}"
|
|
popd >/dev/null
|
|
|
|
# A function do search for a library
|
|
# Usage: do_add_lib libname
|
|
# returns: 0 if library was found and added, !0 otherwise
|
|
do_add_lib() {
|
|
local libname="$1"
|
|
local true_libname
|
|
local dir
|
|
local mode
|
|
|
|
for dir in lib usr/lib; do
|
|
${CT_PRINTF} " trying in '%s'" "${dir}"
|
|
libfile="${CT_SYSROOT_DIR}/${dir}/${libname}"
|
|
${CT_PRINTF} ": '%s'\n" "${libfile}"
|
|
if [ -e "${libfile}" ]; then
|
|
mkdir -p "${dir}"
|
|
true_libname=$("${CT_READELF}" -d "${libfile}" \
|
|
|"${grep}" "Library soname:" \
|
|
|"${sed}" -r -e 's,.+\[(.+)\] *$,\1,;' \
|
|
)
|
|
case "${libfile}" in
|
|
*/ld*) mode=0755;;
|
|
*) mode=0644;;
|
|
esac
|
|
${CT_PRINTF} " installing as '%s/%s', mode='%s'\n" "${dir}" "${true_libname}" "${mode}"
|
|
"${install}" -m "${mode}" "${libfile}" "${dir}/${true_libname}"
|
|
return 0
|
|
break
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
# We'll work in the copied rootfs
|
|
pushd "${CT_ROOT_DST_DIR}" >/dev/null
|
|
|
|
# First of, copy the forced libraries into the working copy
|
|
if [ -n "${CT_LIB_FILE}" ]; then
|
|
lib_list=$("${sed}" -r -e ':loop; s/#.*//;' \
|
|
-e 's/[[:space:]]+//g;' \
|
|
-e 's/([^:])$/\1:/;' \
|
|
-e '/$/N; s/\n//; tloop;' \
|
|
"${CT_LIB_FILE}"
|
|
)
|
|
CT_LIB_LIST=$(echo "${CT_LIB_LIST}:${lib_list}" \
|
|
|"${sed}" -r -e 's/:+/:/g; s/^:+//; s/:+$//;' \
|
|
)
|
|
fi
|
|
CT_LIB_LIST=$(echo "${CT_LIB_LIST}:${lib_list}" \
|
|
|"${sed}" -r -e 's/^:+//; s/:+$//; s/:+/ /g;' \
|
|
)
|
|
if [ -n "${CT_LIB_LIST}" ]; then
|
|
${CT_PRINTF} "Installing forced libraries...\n"
|
|
for name in ${CT_LIB_LIST}; do
|
|
[ -z "${name}" ] && continue
|
|
found=0
|
|
for libname in "lib${name}.so" "${name}.so" "${name}"; do
|
|
${CT_PRINTF} " searching for '%s'\n" "${libname}"
|
|
if do_add_lib "${libname}"; then
|
|
found=1
|
|
break
|
|
fi
|
|
done
|
|
if [ ${found} -eq 0 ]; then
|
|
echo "$myname: library '${libname}' not found!"
|
|
[ "${CT_FORCE}" = y ] || exit 1
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Parse the working copy for executables and libraries
|
|
still_needed=1
|
|
while [ ${still_needed} -eq 1 ]; do
|
|
${CT_PRINTF} "Looping...\n"
|
|
still_needed=0
|
|
for f in $(find . -type f -exec file {} \; \
|
|
|"${grep}" -E ': ELF [[:digit:]]+-bit (L|M)SB (executable|shared object),' \
|
|
|cut -d ":" -f 1 \
|
|
); do
|
|
${CT_PRINTF} "Scanning '%s'\n" "${f}"
|
|
for libname in $("${CT_READELF}" -d "${f}" \
|
|
|"${grep}" -E '\(NEEDED\)[[:space:]]+Shared library:' \
|
|
|"${sed}" -r -e 's,.+\[(.+)\] *$,\1,;' \
|
|
); do
|
|
${CT_PRINTF} " searching for '%s'\n" "${libname}"
|
|
if [ -e "lib/${libname}" \
|
|
-o -e "usr/lib/${libname}" ]; then
|
|
${CT_PRINTF} " already present\n"
|
|
continue
|
|
fi
|
|
if do_add_lib "${libname}"; then
|
|
still_needed=1
|
|
else
|
|
echo "$myname: library '${libname}' not found!"
|
|
fi
|
|
done
|
|
done
|
|
done
|
|
|
|
# OK, we're done. Back off.
|
|
popd >/dev/null
|