#!/bin/sh # Copyright (C) 2014 Codethink Limited # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # # =*= License: GPL-2 =*= set -eu die(){ echo "$@" >&2 exit 1 } shellescape(){ echo "'$(echo "$1" | sed -e "s/'/'\\''/g")'" } ########################## END OF COMMON HEADER ############################### # # The above lines, as well as being part of this script, are copied into the # self-installing SDK blob's header script, as a means of re-using content. # help(){ cat <>"$OUTPUT_SCRIPT" <>"$OUTPUT_SCRIPT" <<'EOF' ########################### START OF HEADER SCRIPT ############################ usage(){ cat <&2 usage >&2 exit 1 fi TOOLCHAIN_PATH="$(readlink -f \"$1\")" sedescape(){ # Escape the passed in string so it can be safely interpolated into # a sed expression as a literal value. echo "$1" | sed -e 's/[\/&]/\\&/g' } prepend_to_path_elements(){ # Prepend $1 to every entry in the : separated list specified as $2. local prefix="$1" ( # Split path into components IFS=: set -- $2 # Print path back out with new prefix printf %s "$prefix/$1" shift for arg in "$@"; do printf ":%s" "$prefix/$arg" done ) } extract_rootfs(){ # Extract the bzipped tarball at the end of the script passed as $1 # to the path specified as $2 local selfextractor="$1" local target="$2" local script_end="$(($(\ grep -aEn -m1 -e '^#+ END OF HEADER SCRIPT #+$' "$selfextractor" | cut -d: -f1) + 1 ))" mkdir -p "$target" tail -n +"$script_end" "$selfextractor" | tar -xj -C "$target" . } amend_text_file_paths(){ # Replace all instances of $3 with $4 in the directory specified by $1 # excluding the subdirectory $2 local root="$1" local inner_sysroot="$2" local old_prefix="$3" local new_prefix="$4" find "$root" \( -path "$inner_sysroot" -prune \) -o -type f \ -exec sh -c 'file "$1" | grep -q text' - {} \; \ -exec sed -i -e \ "s/$(sedescape "$old_prefix")/$(sedescape "$new_prefix")/g" {} + } filter_patchelf_errors(){ # Filter out warnings from patchelf that are acceptable # The warning that it's making a file bigger is just noise # The warning about not being an ELF executable just means we got a # false positive from file that it was an ELF binary # Failing to find .interp is because for convenience, we set the # interpreter in the same command as setting the rpath, even though # we give it both executables and libraries. grep -v -e 'warning: working around a Linux kernel bug' \ -e 'not an ELF executable' \ -e 'cannot find section .interp' } patch_elves(){ # Set the interpreter and library paths of ELF binaries in $1, # except for the $2 subdirectory, using the patchelf command in the # toolchain specified as $3, so that it uses the linker specified # as $4 as the interpreter, and the runtime path specified by $5. # # The patchelf inside the toolchain is used to ensure that it works # independently of the availability of patchelf on the host. # # This is possible by invoking the linker directly and specifying # --linker-path as the RPATH we want to set the binaries to use. local root="$1" local inner_sysroot="$2" local patchelf="$3" local linker="$4" local lib_path="$5" find "$root" \( -path "$inner_sysroot" -prune \) -o -type f \ -type f -perm +u=x \ -exec sh -c 'file "$1" | grep -q "ELF"' - {} \; \ -exec "$linker" --library-path "$lib_path" \ "$patchelf" --set-interpreter "$linker" \ --set-rpath "$lib_path" {} \; 2>&1 \ | filter_patchelf_errors } generate_environment_setup(){ local target="$1" install -m 644 -D /dev/stdin "$target" <>"$OUTPUT_SCRIPT" .