#!/bin/bash # # Copyright 2015 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. # # OS X relpath is not really working. This is a wrapper script around gcc # to simulate relpath 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 behave 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 global GCC := '/usr/bin/gcc' global INSTALL_NAME_TOOL := '"/usr/bin/install_name_tool'" global LIBS := '' global LIB_DIRS := '' global RPATH := '' global OUTPUT := '' # let parse the option list for i in [@Argv] { if [[ "${OUTPUT}" = "1" ]] { global OUTPUT := $i } elif [[ "$i" =~ ^-l(.*)$ ]] { # lib global LIBS := ""$(BASH_REMATCH[1]) $LIBS"" } elif [[ "$i" =~ ^-L(.*)$ ]] { # lib global LIB_DIRS := ""$(BASH_REMATCH[1]) $LIB_DIRS"" } elif [[ "$i" =~ ^-Wl,-rpath,\$ORIGIN/(.*)$ ]] { # rpath global RPATH := $(BASH_REMATCH[1]) } elif [[ "$i" = "-o" ]] { # output is coming global OUTPUT := '1' } } # Call gcc $(GCC) @Argv proc get_library_path { for libdir in [$(LIB_DIRS)] { if test -f $(libdir)/lib$1.so { echo "$(libdir)/lib$1.so" } } } # A convenient method to return the actual path even for non symlinks # and multi-level symlinks. proc get_realpath { var previous = $1 var next = $[readlink $(previous)] while [ -n "${next}" ] { previous := $(next) next := $[readlink $(previous)] } echo $(previous) } # Get the path of a lib inside a tool proc 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 test -n $(RPATH) { for lib in [$(LIBS)] { global libpath := $[get_library_path $(lib)] if test -n $(libpath) { $(INSTALL_NAME_TOOL) -change $[get_otool_path $(libpath)] "@loader_path/$(RPATH)/lib$(lib).so" $(OUTPUT) } } } (CommandList children: [ (C {(set)} {(-eu)}) (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:GCC) op:Equal rhs:{(/usr/bin/gcc)} spids:[86])] spids: [86] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:INSTALL_NAME_TOOL) op: Equal rhs: {(DQ (/usr/bin/install_name_tool))} spids: [89] ) ] spids: [89] ) (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:LIBS) op:Equal rhs:{(SQ )} spids:[95])] spids: [95] ) (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:LIB_DIRS) op:Equal rhs:{(SQ )} spids:[97])] spids: [97] ) (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:RPATH) op:Equal rhs:{(SQ )} spids:[99])] spids: [99] ) (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:OUTPUT) op:Equal rhs:{(SQ )} spids:[101])] spids: [101] ) (ForEach iter_name: i iter_words: [{(DQ ($ VSub_At "$@"))}] do_arg_iter: False body: (DoGroup children: [ (If arms: [ (if_arm cond: [ (Sentence child: (DBracket expr: (BoolBinary op_id: BoolBinary_GlobEqual left: {(DQ (${ VSub_Name OUTPUT))} right: {(DQ (1))} ) ) terminator: ) ] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:OUTPUT) op: Equal rhs: {($ VSub_Name "$i")} spids: [142] ) ] spids: [142] ) ] spids: [-1 139] ) (if_arm cond: [ (Sentence child: (DBracket expr: (BoolBinary op_id: BoolBinary_EqualTilde left: {(DQ ($ VSub_Name "$i"))} right: {(Lit_Other "^") (-l) ("(") (.) (Lit_Other "*") (")") (Lit_Other "$")} ) ) terminator: ) ] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:LIBS) op: Equal rhs: { (DQ (BracedVarSub token: bracket_op: (ArrayIndex expr:(ArithWord w:{(Lit_Digits 1)})) spids: [176 181] ) (" ") ($ VSub_Name "$LIBS") ) } spids: [174] ) ] spids: [174] ) ] spids: [146 167] ) (if_arm cond: [ (Sentence child: (DBracket expr: (BoolBinary op_id: BoolBinary_EqualTilde left: {(DQ ($ VSub_Name "$i"))} right: {(Lit_Other "^") (-L) ("(") (.) (Lit_Other "*") (")") (Lit_Other "$")} ) ) terminator: ) ] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:LIB_DIRS) op: Equal rhs: { (DQ (BracedVarSub token: bracket_op: (ArrayIndex expr:(ArithWord w:{(Lit_Digits 1)})) spids: [217 222] ) (" ") ($ VSub_Name "$LIB_DIRS") ) } spids: [215] ) ] spids: [215] ) ] spids: [187 208] ) (if_arm cond: [ (Sentence child: (DBracket expr: (BoolBinary op_id: BoolBinary_EqualTilde left: {(DQ ($ VSub_Name "$i"))} right: {(Lit_Other "^") (-Wl) (Lit_Comma ",") (-rpath) (Lit_Comma ",") (EscapedLiteralPart token: ) (ORIGIN/) ("(") (.) (Lit_Other "*") (")") (Lit_Other "$") } ) ) terminator: ) ] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:RPATH) op: Equal rhs: { (BracedVarSub token: bracket_op: (ArrayIndex expr:(ArithWord w:{(Lit_Digits 1)})) spids: [262 267] ) } spids: [261] ) ] spids: [261] ) ] spids: [228 254] ) (if_arm cond: [ (Sentence child: (DBracket expr: (BoolBinary op_id: BoolBinary_GlobEqual left: {(DQ ($ VSub_Name "$i"))} right: {(DQ (-o))} ) ) terminator: ) ] action: [ (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:OUTPUT) op:Equal rhs:{(1)} spids:[294])] spids: [294] ) ] spids: [270 287] ) ] spids: [-1 298] ) ] spids: [117 300] ) spids: [111 115] ) (C {(${ VSub_Name GCC)} {(DQ ($ VSub_At "$@"))}) (FuncDef name: get_library_path body: (BraceGroup children: [ (ForEach iter_name: libdir iter_words: [{(${ VSub_Name LIB_DIRS)}] do_arg_iter: False body: (DoGroup children: [ (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(-f)} {(${ VSub_Name libdir) (/lib) ($ VSub_Number "$1") (.so)} {(Lit_Other "]")} ) terminator: ) ] action: [ (C {(echo)} {(DQ (${ VSub_Name libdir) (/lib) ($ VSub_Number "$1") (.so))}) ] spids: [-1 354] ) ] spids: [-1 369] ) ] spids: [335 372] ) spids: [329 333] ) ] spids: [321] ) spids: [315 320] ) (FuncDef name: get_realpath body: (BraceGroup children: [ (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:previous) op: Equal rhs: {(DQ ($ VSub_Number "$1"))} spids: [394] ) ] spids: [392] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:next) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [(C {(readlink)} {(DQ (${ VSub_Name previous))})] ) left_token: spids: [403 411] ) } spids: [402] ) ] spids: [400] ) (While cond: [ (Sentence child: (C {(Lit_Other "[")} {(-n)} {(DQ (${ VSub_Name next))} {(Lit_Other "]")}) terminator: ) ] body: (DoGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:previous) op: Equal rhs: {(DQ (${ VSub_Name next))} spids: [432] ) ] spids: [432] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:next) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [(C {(readlink)} {(DQ (${ VSub_Name previous))})] ) left_token: spids: [441 449] ) } spids: [440] ) ] spids: [440] ) ] spids: [429 452] ) ) (C {(echo)} {(DQ (${ VSub_Name previous))}) ] spids: [389] ) spids: [383 388] ) (FuncDef name: get_otool_path body: (BraceGroup children: [ (Pipeline children: [ (C {(get_realpath)} {($ VSub_Number "$1")}) (C {(sed)} {(SQ <"s|^.*/bazel-out/|bazel-out/|">)}) ] negated: False ) ] spids: [475] ) spids: [469 474] ) (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(-n)} {(DQ (${ VSub_Name RPATH))} {(Lit_Other "]")}) terminator: ) ] action: [ (ForEach iter_name: lib iter_words: [{(${ VSub_Name LIBS)}] do_arg_iter: False body: (DoGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:libpath) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [(C {(get_library_path)} {(${ VSub_Name lib)})] ) left_token: spids: [533 539] ) } spids: [532] ) ] spids: [532] ) (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(-n)} {(DQ (${ VSub_Name libpath))} {(Lit_Other "]")} ) terminator: ) ] action: [ (C {(${ VSub_Name INSTALL_NAME_TOOL)} {(-change)} { (CommandSubPart command_list: (CommandList children: [(C {(get_otool_path)} {(DQ (${ VSub_Name libpath))})] ) left_token: spids: [566 574] ) } {(DQ ("@loader_path/") (${ VSub_Name RPATH) (/lib) (${ VSub_Name lib) (.so))} {(DQ (${ VSub_Name OUTPUT))} ) ] spids: [-1 557] ) ] spids: [-1 595] ) ] spids: [529 598] ) spids: [523 527] ) ] spids: [-1 515] ) ] spids: [-1 600] ) ] )