blob: 2420c3aaaa34a8d97cb6cac7f13bfd0eba8336cd [file] [log] [blame]
#!/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"
# Ensure 0 timestamping for hermetic results.
export ZERO_AR_DATE=1
if [ ! -f "${MY_LOCATION}"/libtool_check_unique ] ; then
echo "libtool_check_unique not found. Please file an issue at github.com/bazelbuild/bazel"
elif "${MY_LOCATION}"/libtool_check_unique "$@"; then
# If there are no duplicate .o basenames,
# libtool can be invoked with the original arguments.
"${WRAPPER}" 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/python2.7
if [[ ! -x "$python_executable" ]]; then
python_executable=python
fi
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_executable" "${MY_LOCATION}/make_hashed_objlist.py" \
"${ARG}" "${HASHED_FILELIST}" "${TEMPDIR}"
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|-D|-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
"${WRAPPER}" libtool "${ARGS[@]}"