blob: 739fca5de6c51375de37fb8d4f3ae8bc4686a0bb [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-Guillerez8fa5ae62016-03-02 16:24:13 +000030GCC=/usr/bin/gcc
Damien Martin-Guillerez28ac6152015-03-25 19:46:39 +000031INSTALL_NAME_TOOL="/usr/bin/install_name_tool"
32
33LIBS=
34LIB_DIRS=
35RPATH=
36OUTPUT=
37# let parse the option list
38for i in "$@"; do
39 if [[ "${OUTPUT}" = "1" ]]; then
40 OUTPUT=$i
41 elif [[ "$i" =~ ^-l(.*)$ ]]; then
42 # lib
43 LIBS="${BASH_REMATCH[1]} $LIBS"
44 elif [[ "$i" =~ ^-L(.*)$ ]]; then
45 # lib
46 LIB_DIRS="${BASH_REMATCH[1]} $LIB_DIRS"
47 elif [[ "$i" =~ ^-Wl,-rpath,\$ORIGIN/(.*)$ ]]; then
48 # rpath
49 RPATH=${BASH_REMATCH[1]}
50 elif [[ "$i" = "-o" ]]; then
51 # output is coming
52 OUTPUT=1
53 fi
54done
55
56# Call gcc
57${GCC} "$@"
58
59function get_library_path() {
60 for libdir in ${LIB_DIRS}; do
Ulf Adams8284bd72015-08-19 11:27:02 +000061 if [ -f ${libdir}/lib$1.so ]; then
62 echo "${libdir}/lib$1.so"
Damien Martin-Guillerez28ac6152015-03-25 19:46:39 +000063 fi
64 done
65}
66
67# A convenient method to return the actual path even for non symlinks
68# and multi-level symlinks.
69function get_realpath() {
70 local previous="$1"
71 local next=$(readlink "${previous}")
72 while [ -n "${next}" ]; do
73 previous="${next}"
74 next=$(readlink "${previous}")
75 done
76 echo "${previous}"
77}
78
79# Get the path of a lib inside a tool
80function get_otool_path() {
81 # the lib path is the path of the original lib relative to the workspace
82 get_realpath $1 | sed 's|^.*/bazel-out/|bazel-out/|'
83}
84
85# Do replacements in the output
86if [ -n "${RPATH}" ]; then
87 for lib in ${LIBS}; do
88 libpath=$(get_library_path ${lib})
89 if [ -n "${libpath}" ]; then
Ulf Adams8284bd72015-08-19 11:27:02 +000090 ${INSTALL_NAME_TOOL} -change $(get_otool_path "${libpath}") "@loader_path/${RPATH}/lib${lib}.so" "${OUTPUT}"
Damien Martin-Guillerez28ac6152015-03-25 19:46:39 +000091 fi
92 done
93fi
94