| #!/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 | |
| WRAPPER="${MY_LOCATION}/xcrunwrapper.sh" | |
| # 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="${ORIGINAL_NAME%.o}_${ORIGINAL_HASH}.o" | |
| if [[ ! -e "$SYMLINK_NAME" ]]; then | |
| ln -sf "$(basename "$ORIGINAL_NAME")" "$SYMLINK_NAME" | |
| fi | |
| echo "$SYMLINK_NAME" | |
| } | |
| ARGS=() | |
| while [[ $# -gt 0 ]]; do | |
| ARG="$1" | |
| shift | |
| # Libtool artifact symlinking. Apple's libtool has a bug when there are two | |
| # input files with the same basename. We thus create symlinks that are named | |
| # with a hash suffix for each input, and pass them to libtool. | |
| # See b/28186497. | |
| 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) | |
| ARGS+=("${ARG}") | |
| ARG="$1" | |
| shift | |
| HASHED_FILELIST="${ARG%.objlist}_hashes.objlist" | |
| rm -f "${HASHED_FILELIST}" | |
| # Use python helper script for fast md5 calculation of many strings. | |
| python "${MY_LOCATION}/make_hashed_objlist.py" "${ARG}" "${HASHED_FILELIST}" | |
| ARGS+=("${HASHED_FILELIST}") | |
| ;; | |
| # Output flag | |
| -o) | |
| ARGS+=("${ARG}") | |
| ARG="$1" | |
| shift | |
| ARGS+=("${ARG}") | |
| OUTPUTFILE="${ARG}" | |
| ;; | |
| # Flags with no args | |
| -static|-s|-a|-c|-L|-T|-no_warning_for_no_symbols) | |
| ARGS+=("${ARG}") | |
| ;; | |
| # Single-arg flags | |
| -arch_only|-syslibroot) | |
| ARGS+=("${ARG}") | |
| ARG="$1" | |
| shift | |
| ARGS+=("${ARG}") | |
| ;; | |
| # Any remaining flags are unexpected and may ruin flag parsing. | |
| -*) | |
| 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+=("$(echo "$(hash_objfile "${ARG}")")") | |
| ;; | |
| esac | |
| done | |
| # Ensure 0 timestamping for hermetic results. | |
| export ZERO_AR_DATE=1 | |
| "${WRAPPER}" libtool "${ARGS[@]}" | |
| # Prevents a pre-Xcode-8 bug in which passing zero-date archive files to ld | |
| # would cause ld to error. | |
| touch "$OUTPUTFILE" |