blob: 5ea4b52c1b5e69b1bfb5d3bf5f4e6fff64dad2b2 [file] [log] [blame]
Damien Martin-Guillerez28ac6152015-03-25 19:46:39 +00001#!/bin/bash
2#
Damien Martin-Guillerezf88f4d82015-09-25 13:56:55 +00003# Copyright 2015 The Bazel Authors. All rights reserved.
Damien Martin-Guillerez28ac6152015-03-25 19:46:39 +00004#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
Damien Martin-Guillerez8fa5ae62016-03-02 16:24:13 +000017# OS X relpath is not really working. This is a wrapper script around gcc
18# to simulate relpath behavior.
Damien Martin-Guillerez28ac6152015-03-25 19:46:39 +000019#
20# This wrapper uses install_name_tool to replace all paths in the binary
21# (bazel-out/.../path/to/original/library.so) by the paths relative to
Damien Martin-Guillerez8fa5ae62016-03-02 16:24:13 +000022# the binary. It parses the command line to behave as rpath is supposed
Damien Martin-Guillerez28ac6152015-03-25 19:46:39 +000023# to work.
24#
25# See https://blogs.oracle.com/dipol/entry/dynamic_libraries_rpath_and_mac
26# on how to set those paths for Mach-O binaries.
27#
28set -eu
29
Damien Martin-Guillerez28ac6152015-03-25 19:46:39 +000030INSTALL_NAME_TOOL="/usr/bin/install_name_tool"
31
32LIBS=
33LIB_DIRS=
34RPATH=
35OUTPUT=
36# let parse the option list
37for i in "$@"; do
38 if [[ "${OUTPUT}" = "1" ]]; then
39 OUTPUT=$i
40 elif [[ "$i" =~ ^-l(.*)$ ]]; then
41 # lib
42 LIBS="${BASH_REMATCH[1]} $LIBS"
43 elif [[ "$i" =~ ^-L(.*)$ ]]; then
44 # lib
45 LIB_DIRS="${BASH_REMATCH[1]} $LIB_DIRS"
46 elif [[ "$i" =~ ^-Wl,-rpath,\$ORIGIN/(.*)$ ]]; then
47 # rpath
48 RPATH=${BASH_REMATCH[1]}
49 elif [[ "$i" = "-o" ]]; then
50 # output is coming
51 OUTPUT=1
52 fi
53done
54
Damien Martin-Guillerez6dab8152016-05-06 12:44:26 +000055# Set-up the environment
56%{env}
57
Damien Martin-Guillerez8fa5ae62016-03-02 16:24:13 +000058# Call the C++ compiler
59%{cc} "$@"
Damien Martin-Guillerez28ac6152015-03-25 19:46:39 +000060
61function get_library_path() {
62 for libdir in ${LIB_DIRS}; do
Ulf Adams8284bd72015-08-19 11:27:02 +000063 if [ -f ${libdir}/lib$1.so ]; then
64 echo "${libdir}/lib$1.so"
Damien Martin-Guillerez28ac6152015-03-25 19:46:39 +000065 fi
66 done
67}
68
69# A convenient method to return the actual path even for non symlinks
70# and multi-level symlinks.
71function get_realpath() {
72 local previous="$1"
73 local next=$(readlink "${previous}")
74 while [ -n "${next}" ]; do
75 previous="${next}"
76 next=$(readlink "${previous}")
77 done
78 echo "${previous}"
79}
80
81# Get the path of a lib inside a tool
82function get_otool_path() {
83 # the lib path is the path of the original lib relative to the workspace
84 get_realpath $1 | sed 's|^.*/bazel-out/|bazel-out/|'
85}
86
87# Do replacements in the output
88if [ -n "${RPATH}" ]; then
89 for lib in ${LIBS}; do
90 libpath=$(get_library_path ${lib})
91 if [ -n "${libpath}" ]; then
Ulf Adams8284bd72015-08-19 11:27:02 +000092 ${INSTALL_NAME_TOOL} -change $(get_otool_path "${libpath}") "@loader_path/${RPATH}/lib${lib}.so" "${OUTPUT}"
Damien Martin-Guillerez28ac6152015-03-25 19:46:39 +000093 fi
94 done
95fi
96