| #!/bin/bash | 
 | # | 
 | # Copyright 2016 The Bazel Authors. All rights reserved. | 
 | # | 
 | # Licensed under the Apache License, Version 2.0 (the "License"); | 
 | # you may not use this file except in compliance with the License. | 
 | # You may obtain a copy of the License at | 
 | # | 
 | #    http://www.apache.org/licenses/LICENSE-2.0 | 
 | # | 
 | # Unless required by applicable law or agreed to in writing, software | 
 | # distributed under the License is distributed on an "AS IS" BASIS, | 
 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | # See the License for the specific language governing permissions and | 
 | # limitations under the License. | 
 | # | 
 | # libtool.sh runs the command passed to it using "xcrunwrapper libtool". | 
 | # | 
 | # It creates symbolic links for all input files with a path-hash appended | 
 | # to their original name (foo.o becomes foo_{md5sum}.o). This is to circumvent | 
 | # a bug in the original libtool that arises when two input files have the same | 
 | # base name (even if they are in different directories). | 
 |  | 
 | set -eu | 
 |  | 
 | # A trick to allow invoking this script in multiple contexts. | 
 | if [ -z ${MY_LOCATION+x} ]; then | 
 |   if [ -d "$0.runfiles/" ]; then | 
 |     MY_LOCATION="$0.runfiles/bazel_tools/tools/objc" | 
 |   else | 
 |     MY_LOCATION="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | 
 |   fi | 
 | fi | 
 |  | 
 | function invoke_libtool() { | 
 |   # Just invoke libtool via xcrunwrapper | 
 |   "${MY_LOCATION}/xcrunwrapper.sh" libtool "$@" \ | 
 |   2> >(grep -v "the table of contents is empty (no object file members in the"` | 
 |               `" library define global symbols)$" >&2) | 
 |   # ^ Filtering a warning that's unlikely to indicate a real issue | 
 |   # ...and not silencable via a flag. | 
 | } | 
 |  | 
 | if [ ! -f "${MY_LOCATION}"/libtool_check_unique ] ; then | 
 |   echo "libtool_check_unique not found. Please file an issue at github.com/bazelbuild/bazel" | 
 |   exit 1 | 
 | elif "${MY_LOCATION}"/libtool_check_unique "$@"; then | 
 |   # If there are no duplicate .o basenames, | 
 |   # libtool can be invoked with the original arguments. | 
 |   invoke_libtool "$@" | 
 |   exit | 
 | fi | 
 |  | 
 | TEMPDIR="$(mktemp -d "${TMPDIR:-/tmp}/libtool.XXXXXXXX")" | 
 | trap 'rm -rf "$TEMPDIR"' EXIT | 
 |  | 
 | # Creates a symbolic link to the input argument file and returns the symlink | 
 | # file path. | 
 | function hash_objfile() { | 
 |   ORIGINAL_NAME="$1" | 
 |   ORIGINAL_HASH="$(/sbin/md5 -qs "${ORIGINAL_NAME}")" | 
 |   SYMLINK_NAME="${TEMPDIR}/$(basename "${ORIGINAL_NAME%.o}_${ORIGINAL_HASH}.o")" | 
 |   if [[ ! -e "$SYMLINK_NAME" ]]; then | 
 |     case "${ORIGINAL_NAME}" in | 
 |       /*) ln -sf "$ORIGINAL_NAME" "$SYMLINK_NAME" ;; | 
 |       *) ln -sf "$(pwd)/$ORIGINAL_NAME" "$SYMLINK_NAME" ;; | 
 |     esac | 
 |   fi | 
 |   echo "$SYMLINK_NAME" | 
 | } | 
 |  | 
 | python_executable=/usr/bin/python3 | 
 | if [[ ! -x "$python_executable" ]]; then | 
 |   python_executable=python3 | 
 | fi | 
 |  | 
 | ARGS=() | 
 | handle_filelist=0 | 
 | keep_next=0 | 
 |  | 
 | function parse_option() { | 
 |   local -r ARG="$1" | 
 |   if [[ "$handle_filelist" == "1" ]]; then | 
 |     handle_filelist=0 | 
 |     HASHED_FILELIST="${ARG%.objlist}_hashes.objlist" | 
 |     rm -f "${HASHED_FILELIST}" | 
 |     # Use python helper script for fast md5 calculation of many strings. | 
 |     "$python_executable" "${MY_LOCATION}/make_hashed_objlist.py" \ | 
 |       "${ARG}" "${HASHED_FILELIST}" "${TEMPDIR}" | 
 |     ARGS+=("${HASHED_FILELIST}") | 
 |   elif [[ "$keep_next" == "1" ]]; then | 
 |     keep_next=0 | 
 |     ARGS+=("$ARG") | 
 |   else | 
 |     case "${ARG}" in | 
 |       # Filelist flag, need to symlink each input in the contents of file and | 
 |       # pass a new filelist which contains the symlinks. | 
 |       -filelist) | 
 |         handle_filelist=1 | 
 |         ARGS+=("${ARG}") | 
 |         ;; | 
 |       @*) | 
 |         path="${ARG:1}" | 
 |         while IFS= read -r opt | 
 |         do | 
 |           parse_option "$opt" | 
 |         done < "$path" || exit 1 | 
 |         ;; | 
 |       # Flags with no args | 
 |       -static|-s|-a|-c|-L|-T|-D|-no_warning_for_no_symbols) | 
 |         ARGS+=("${ARG}") | 
 |         ;; | 
 |       # Single-arg flags | 
 |       -arch_only|-syslibroot|-o) | 
 |         keep_next=1 | 
 |         ARGS+=("${ARG}") | 
 |         ;; | 
 |       # Any remaining flags are unexpected and may ruin flag parsing. | 
 |       # Add any flags here to libtool_check_unique.cc as well | 
 |       -*) | 
 |         echo "Unrecognized libtool flag ${ARG}" | 
 |         exit 1 | 
 |         ;; | 
 |       # Archive inputs can remain untouched, as they come from other targets. | 
 |       *.a) | 
 |         ARGS+=("${ARG}") | 
 |         ;; | 
 |       # Remaining args are input objects | 
 |       *) | 
 |         ARGS+=("$(hash_objfile "${ARG}")") | 
 |         ;; | 
 |     esac | 
 |   fi | 
 | } | 
 |  | 
 | for arg in "$@"; do | 
 |   parse_option "$arg" | 
 | done | 
 |  | 
 | printf '%s\n' "${ARGS[@]}" > "$TEMPDIR/processed.params" | 
 | invoke_libtool "@$TEMPDIR/processed.params" |