aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/cpp
diff options
context:
space:
mode:
authorGravatar Damien Martin-Guillerez <dmarting@google.com>2015-03-25 19:46:39 +0000
committerGravatar Damien Martin-Guillerez <dmarting@google.com>2015-03-25 20:07:14 +0000
commit28ac615402bfbba56fbcbc6b4f3f51fca8bc9612 (patch)
treefab35ad69246a14209c4ff5450ff88764f4ff1b1 /tools/cpp
parentbf9b63b46142836a0c329b3c4b389c72462071b2 (diff)
Use a wrapper around gcc on OSX to simulate rpath
OS X does not have rpath so binary fails when not executing from the good path. This wrapper rewrite the path after the compilation to fix that behavior. Fixes #46 -- MOS_MIGRATED_REVID=89527942
Diffstat (limited to 'tools/cpp')
-rw-r--r--tools/cpp/CROSSTOOL2
-rwxr-xr-xtools/cpp/osx_gcc_wrapper.sh94
2 files changed, 95 insertions, 1 deletions
diff --git a/tools/cpp/CROSSTOOL b/tools/cpp/CROSSTOOL
index 073714d6bc..8bf19dea43 100644
--- a/tools/cpp/CROSSTOOL
+++ b/tools/cpp/CROSSTOOL
@@ -69,7 +69,7 @@ toolchain {
tool_path { name: "compat-ld" path: "/usr/bin/ld" }
tool_path { name: "cpp" path: "/usr/bin/cpp" }
tool_path { name: "dwp" path: "/usr/bin/dwp" }
- tool_path { name: "gcc" path: "/usr/bin/gcc" }
+ tool_path { name: "gcc" path: "osx_gcc_wrapper.sh" }
cxx_flag: "-std=c++0x"
ar_flag: "-static"
ar_flag: "-s"
diff --git a/tools/cpp/osx_gcc_wrapper.sh b/tools/cpp/osx_gcc_wrapper.sh
new file mode 100755
index 0000000000..a8eb46ab8f
--- /dev/null
+++ b/tools/cpp/osx_gcc_wrapper.sh
@@ -0,0 +1,94 @@
+#!/bin/bash
+#
+# Copyright 2015 Google Inc. 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.
+#
+# OS X rpath is not really working. This is a wrapper script around gcc
+# to simulate rpath behavior.
+#
+# This wrapper uses install_name_tool to replace all paths in the binary
+# (bazel-out/.../path/to/original/library.so) by the paths relative to
+# the binary. It parses the command line to behaves as rpath is supposed
+# to work.
+#
+# See https://blogs.oracle.com/dipol/entry/dynamic_libraries_rpath_and_mac
+# on how to set those paths for Mach-O binaries.
+#
+set -eu
+
+GCC="/usr/bin/gcc"
+INSTALL_NAME_TOOL="/usr/bin/install_name_tool"
+
+LIBS=
+LIB_DIRS=
+RPATH=
+OUTPUT=
+# let parse the option list
+for i in "$@"; do
+ if [[ "${OUTPUT}" = "1" ]]; then
+ OUTPUT=$i
+ elif [[ "$i" =~ ^-l(.*)$ ]]; then
+ # lib
+ LIBS="${BASH_REMATCH[1]} $LIBS"
+ elif [[ "$i" =~ ^-L(.*)$ ]]; then
+ # lib
+ LIB_DIRS="${BASH_REMATCH[1]} $LIB_DIRS"
+ elif [[ "$i" =~ ^-Wl,-rpath,\$ORIGIN/(.*)$ ]]; then
+ # rpath
+ RPATH=${BASH_REMATCH[1]}
+ elif [[ "$i" = "-o" ]]; then
+ # output is coming
+ OUTPUT=1
+ fi
+done
+
+# Call gcc
+${GCC} "$@"
+
+function get_library_path() {
+ for libdir in ${LIB_DIRS}; do
+ if [ -f ${libdir}/lib$1.so ]; then
+ echo "${libdir}/lib$1.so"
+ fi
+ done
+}
+
+# A convenient method to return the actual path even for non symlinks
+# and multi-level symlinks.
+function get_realpath() {
+ local previous="$1"
+ local next=$(readlink "${previous}")
+ while [ -n "${next}" ]; do
+ previous="${next}"
+ next=$(readlink "${previous}")
+ done
+ echo "${previous}"
+}
+
+# Get the path of a lib inside a tool
+function get_otool_path() {
+ # the lib path is the path of the original lib relative to the workspace
+ get_realpath $1 | sed 's|^.*/bazel-out/|bazel-out/|'
+}
+
+# Do replacements in the output
+if [ -n "${RPATH}" ]; then
+ for lib in ${LIBS}; do
+ libpath=$(get_library_path ${lib})
+ if [ -n "${libpath}" ]; then
+ ${INSTALL_NAME_TOOL} -change $(get_otool_path "${libpath}") "@loader_path/${RPATH}/lib${lib}.so" "${OUTPUT}"
+ fi
+ done
+fi
+