scripts/xldd.in
author Anthony Foiani <anthony.foiani@gmail.com>
Thu Oct 07 22:37:06 2010 +0200 (2010-10-07)
changeset 2138 2242d87c5404
child 2183 dbecd99ecba5
permissions -rwxr-xr-x
scripts: always create lib32 and lib64 symlinks

Unconditionally create the lib32 -> lib/ and lib64 -> lib/ symlinks.

This is reportedly a fix to build a toolchain for a 32-bit target on
a 'pure' 64-bit host (eg. on Fedora FC12, host libs are in lib64/,
and there is no lib -> lib64 symlink, as we can see on other distors,
as Debian). As gcc only puts static host lib in lib64/ (along with
target files in subdirs), we can safely create the symlinks.

Also note that the symlinks are summarily removed at the end
of the build.

Signed-off-by: Anthony Foiani <anthony.foiani@gmail.com>
[Yann E. MORIN: fix a comment, rephrase the commit log]
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
     1 #!@@CT_bash@@
     2 
     3 # NON-CONFIGURABLE STUFF!
     4 export LC_ALL=C
     5 sed="@@CT_sed@@"
     6 grep="@@CT_grep@@"
     7 my_name="$( basename "${0}" )"
     8 prefix="${0%-ldd}"
     9 gcc="${prefix}-gcc"
    10 readelf="${prefix}-readelf"
    11 fake_load_addr="$((0xdeadbeef))"
    12 fake_load_addr_sys="$((0x8badf00d))"
    13 ld_library_path="/lib:/usr/lib"
    14 
    15 do_error() {
    16     printf "%s: %s\n" "${my_name}" "$*" >&2
    17 }
    18 
    19 do_opt_error() {
    20     do_error "$@"
    21     printf "Try \`%s --help' for more information\n >&2"
    22 }
    23 
    24 show_version() {
    25     # Fake a real ldd, just in case some dumb script would check
    26     cat <<_EOF_
    27 ldd (crosstool-NG) 1.8.0
    28 Copyright (C) 2010 "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
    29 This is free software; see the source for copying conditions.  There is NO
    30 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    31 Licensed under the GPLv2, see the file LICENSES in the top-directory of the
    32 sources for this package.
    33 _EOF_
    34 }
    35 
    36 show_help() {
    37     cat <<_EOF_
    38 Usage: ${my_name} [OPTION]... --root DIR FILE...
    39       --help              print this help and exit
    40       --version           print version information and exit
    41       --root dir          treat dir as being the root of the target
    42   -s, --show-system       mark libs from the sysroot with a trailing '[*]'
    43 
    44 _EOF_
    45     cat <<_EOF_ |fmt
    46 ${my_name} tries to mimick the behavior of a real native ldd, but can be
    47 used in a cross-development environment. Here is how it differs from a
    48 real native ldd:
    49 
    50 The LD_LIBRARY_PATH variable is not used, as it can not reliably be
    51 guessed except at runtime, and we can't run.
    52 
    53 ${my_name} does not scan /etc/ld.so.cache, but instead uses /etc/ld.so.conf
    54 (it understands the include directives therein for libces that have that).
    55 [Note: this is missing for now...]
    56 
    57 ${my_name} will search the directory specified with --root for libraries
    58 to resolve the NEEDED tags. If --root is not set, then ${my_name} will
    59 use the value in the environment variable \${CT_XLDD_ROOT}. If neither
    60 is set, then this is an error.
    61 
    62 If NEEDED libraries can't be found in the specified root directory, then
    63 ${my_name} will also look in the sysroot of the toolchain to see if it
    64 can find them.
    65 
    66 For NEEDED libraries that were found, the output will look like:
    67         libneeded.so => /path/to/libneeded.so (0xloadaddr)
    68 
    69 and for those that were not found, the output will look like:
    70         libneeded.so not found
    71 
    72 The paths are relative to the specified root directory, or to the sysroot
    73 (eg. /lib/libneeded.so, /usr/lib/libneeded.so, and so on...).
    74 
    75 The expected load address 'loadaddr' is a faked address to match the output
    76 of the real ldd, but has no actual meaning (set to some constants for now,
    77 0x8badf00d for libraries from the sysroot, 0xdeadbeff for others).
    78 _EOF_
    79 
    80 # Unimplemeted yet:
    81 #  -d, --data-relocs       process data relocations
    82 #  -r, --function-relocs   process data and function relocations
    83 #  -u, --unused            print unused direct dependencies
    84 #  -v, --verbose           print all information
    85 
    86 # See also this thread:
    87 #  http://sourceware.org/ml/crossgcc/2008-09/msg00057.html
    88 }
    89 
    90 # Parse command line options
    91 root="${CT_XLDD_ROOT}"
    92 show_system=
    93 while true; do
    94     case "${1}" in
    95         --help)
    96             show_help
    97             exit 0
    98             ;;
    99         --version)
   100             show_version
   101             exit 0
   102             ;;
   103         --root)
   104             root="$2"
   105             shift
   106             ;;
   107         --root=*)
   108             root="${1#--root=}"
   109             ;;
   110         --show-system|-s)
   111             show_system=1
   112             ;;
   113         -*)
   114             do_opt_error "unrecognized option \`${1}'"
   115             exit 1
   116             ;;
   117         *)
   118             break
   119             ;;
   120     esac
   121     shift
   122 done
   123 
   124 # Sanity checks
   125 if [ -z "${root}" ]; then
   126     do_opt_error "no root given"
   127     exit 1
   128 fi
   129 if [ ! -d "${root}" ]; then
   130     do_error "\`${root}': no such file or directory"
   131     exit 1
   132 fi
   133 
   134 sysroot="$( "${gcc}" -print-sysroot )"
   135 
   136 do_report_needed_found() {
   137     local needed="${1}"
   138     local path="${2}"
   139     local system="${3}"
   140     local loadaddr
   141     local sys
   142 
   143     if [ -z "${system}" ]; then
   144         loadaddr="${fake_load_addr}"
   145     else
   146         loadaddr="${fake_load_addr_sys}"
   147         if [ -n "${show_system}" ]; then
   148             sys=" [*]"
   149         fi
   150     fi
   151 
   152     # 8 to fake a 32-bit load address
   153     printf "%8s%s => %s (0x%0*x)%s\n"   \
   154            ""                           \
   155            "${needed}"                  \
   156            "${path}"                    \
   157            8                            \
   158            "${loadaddr}"                \
   159            "${sys}"
   160 }
   161 
   162 # Search a needed file, scanning ${lib_dir} in the root directory
   163 do_find_needed() {
   164     local needed="${1}"
   165     local found
   166     local found_sysroot
   167     local d
   168 
   169     for d in "${needed_search_path[@]}"; do
   170         if [ -f "${root}${d}/${needed}" ]; then
   171             found="${d}/${needed}"
   172         fi
   173     done
   174     if [ -z "${found}" ]; then
   175     for d in "${needed_search_path[@]}"; do
   176         if [ -f "${sysroot}${d}/${needed}" ]; then
   177             found_sysroot="${d}/${needed}"
   178         fi
   179     done
   180     fi
   181 
   182     if [ -n "${found}" ]; then
   183         do_report_needed_found "${needed}" "${found}"
   184         do_process_file "${root}${found}"
   185     elif [ -n "${found_sysroot}" ]; then
   186         do_report_needed_found "${needed}" "${found_sysroot}" "sys"
   187         do_process_file "${sysroot}${found_sysroot}"
   188     else
   189         printf "%8c%s not found\n" "" "${needed}"
   190     fi
   191 }
   192 
   193 # Scan a file for all NEEDED tags
   194 do_process_file() {
   195     local file="${1}"
   196 
   197     "${readelf}" -d "${file}"                                           \
   198     |"${grep}" -E '\(NEEDED\)'                                          \
   199     |"${sed}" -r -e 's/^.*Shared library:[[:space:]]+\[(.*)\]$/\1/;'    \
   200     |while read needed; do
   201         do_find_needed "${needed}"
   202      done
   203 }
   204 
   205 # Build up the full list of search directories
   206 declare -a needed_search_path
   207 ld_library_path="${ld_library_path}:"
   208 while [ -n "${ld_library_path}" ]; do
   209     d="${ld_library_path%%:*}"
   210     [ -n "${d}" ] && needed_search_path+=( "${d}" )
   211     ld_library_path="${ld_library_path#*:}"
   212 done
   213 
   214 do_process_file "${1}"