blob: 800bc055080c73b9cfabd0bfb8fefc40f94c2675 [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=
Marcel Hlopkof4265442017-08-17 22:13:39 +020035RPATHS=
Damien Martin-Guillerez28ac6152015-03-25 19:46:39 +000036OUTPUT=
37# let parse the option list
38for i in "$@"; do
39 if [[ "${OUTPUT}" = "1" ]]; then
40 OUTPUT=$i
41 elif [[ "$i" =~ ^-l(.*)$ ]]; then
Damien Martin-Guillerez28ac6152015-03-25 19:46:39 +000042 LIBS="${BASH_REMATCH[1]} $LIBS"
43 elif [[ "$i" =~ ^-L(.*)$ ]]; then
Damien Martin-Guillerez28ac6152015-03-25 19:46:39 +000044 LIB_DIRS="${BASH_REMATCH[1]} $LIB_DIRS"
45 elif [[ "$i" =~ ^-Wl,-rpath,\$ORIGIN/(.*)$ ]]; then
Marcel Hlopkof4265442017-08-17 22:13:39 +020046 RPATHS="${BASH_REMATCH[1]} ${RPATHS}"
Damien Martin-Guillerez28ac6152015-03-25 19:46:39 +000047 elif [[ "$i" = "-o" ]]; then
48 # output is coming
49 OUTPUT=1
50 fi
51done
52
53# Call gcc
54${GCC} "$@"
55
56function get_library_path() {
57 for libdir in ${LIB_DIRS}; do
Ulf Adams8284bd72015-08-19 11:27:02 +000058 if [ -f ${libdir}/lib$1.so ]; then
59 echo "${libdir}/lib$1.so"
hlopko600ab492017-10-12 18:30:29 +020060 elif [ -f ${libdir}/lib$1.dylib ]; then
61 echo "${libdir}/lib$1.dylib"
Damien Martin-Guillerez28ac6152015-03-25 19:46:39 +000062 fi
63 done
64}
65
66# A convenient method to return the actual path even for non symlinks
67# and multi-level symlinks.
68function get_realpath() {
69 local previous="$1"
70 local next=$(readlink "${previous}")
71 while [ -n "${next}" ]; do
72 previous="${next}"
73 next=$(readlink "${previous}")
74 done
75 echo "${previous}"
76}
77
78# Get the path of a lib inside a tool
79function get_otool_path() {
80 # the lib path is the path of the original lib relative to the workspace
81 get_realpath $1 | sed 's|^.*/bazel-out/|bazel-out/|'
82}
83
84# Do replacements in the output
Marcel Hlopkof4265442017-08-17 22:13:39 +020085for rpath in ${RPATHS}; do
Damien Martin-Guillerez28ac6152015-03-25 19:46:39 +000086 for lib in ${LIBS}; do
hlopko4f5a92b2017-12-12 04:34:58 -080087 unset libname
hlopko600ab492017-10-12 18:30:29 +020088 if [ -f "$(dirname ${OUTPUT})/${rpath}/lib${lib}.so" ]; then
89 libname="lib${lib}.so"
90 elif [ -f "$(dirname ${OUTPUT})/${rpath}/lib${lib}.dylib" ]; then
91 libname="lib${lib}.dylib"
92 fi
93 # ${libname-} --> return $libname if defined, or undefined otherwise. This is to make
94 # this set -e friendly
95 if [[ -n "${libname-}" ]]; then
Marcel Hlopkof4265442017-08-17 22:13:39 +020096 libpath=$(get_library_path ${lib})
97 if [ -n "${libpath}" ]; then
98 ${INSTALL_NAME_TOOL} -change $(get_otool_path "${libpath}") \
hlopko600ab492017-10-12 18:30:29 +020099 "@loader_path/${rpath}/${libname}" "${OUTPUT}"
Marcel Hlopkof4265442017-08-17 22:13:39 +0200100 fi
Damien Martin-Guillerez28ac6152015-03-25 19:46:39 +0000101 fi
102 done
Marcel Hlopkof4265442017-08-17 22:13:39 +0200103done
Damien Martin-Guillerez28ac6152015-03-25 19:46:39 +0000104