Fix osx_cc_wrapper to also update dylibs

In https://github.com/bazelbuild/bazel/commit/f426544e67170d31b9d228ecf4cdc4b6ce1ba00d I updated osx_cc_wrapper to work correctly in case both
precompiled .so and cc_library-made .so are linked into a single binary. This cl
makes osx_cc_wrapper work also when a precompiled .dylib is provided.

Fixes #3450 again for dylibs
Fixes #407
One step closer to finishing #1576

RELNOTES: None.
PiperOrigin-RevId: 171683650
diff --git a/src/test/shell/bazel/cpp_darwin_integration_test.sh b/src/test/shell/bazel/cpp_darwin_integration_test.sh
index 8b5eabb..8719ff6 100755
--- a/src/test/shell/bazel/cpp_darwin_integration_test.sh
+++ b/src/test/shell/bazel/cpp_darwin_integration_test.sh
@@ -30,22 +30,49 @@
 )
 cc_binary(
   name = "libbar.so",
+  srcs = [ "bar.cc" ],
+  linkshared = 1,
+)
+cc_binary(
+  name = "libbaz.dylib",
+  srcs = [ "baz.cc" ],
   linkshared = 1,
 )
 cc_test(
   name = "test",
-  srcs = [ "test.cc", ":libbar.so" ],
+  srcs = [ "test.cc", ":libbar.so", ":libbaz.dylib"  ],
   deps = [":foo"],
 )
 EOF
   cat > cpp/rpaths/foo.cc <<EOF
-  int foo() { return 42; }
+  int foo() { return 2; }
+EOF
+  cat > cpp/rpaths/bar.cc <<EOF
+  int bar() { return 12; }
+EOF
+  cat > cpp/rpaths/baz.cc <<EOF
+  int baz() { return 42; }
 EOF
   cat > cpp/rpaths/test.cc <<EOF
-  int main() {}
+  int foo();
+  int bar();
+  int baz();
+  int main() {
+    int result = foo() + bar() + baz();
+    if (result == 56) {
+      return 0;
+    } else {
+      return result;
+    }
+  }
 EOF
-  assert_build //cpp/rpaths:test >& $TEST_log || fail "//cpp/rpaths:test didn't build"
-  ./bazel-bin/cpp/rpaths/test >& $TEST_log || fail "//cpp/rpaths:test execution failed"
+  assert_build //cpp/rpaths:test -s || fail "//cpp/rpaths:test didn't build"
+  # Paths originally hardcoded in the binary assume workspace directory. Let's change the
+  # directory and execute the binary to test whether the paths in the binary have been
+  # updated to use @loader_path.
+  cd bazel-bin
+  ./cpp/rpaths/test >& $TEST_log || \
+      fail "//cpp/rpaths:test execution failed, expected to return 0, but got $?"
 }
 
 run_suite "Tests for Bazel's C++ rules on Darwin"
diff --git a/tools/cpp/osx_cc_wrapper.sh b/tools/cpp/osx_cc_wrapper.sh
index 8aba869..9438567 100755
--- a/tools/cpp/osx_cc_wrapper.sh
+++ b/tools/cpp/osx_cc_wrapper.sh
@@ -57,6 +57,8 @@
     for libdir in ${LIB_DIRS}; do
         if [ -f ${libdir}/lib$1.so ]; then
             echo "${libdir}/lib$1.so"
+        elif [ -f ${libdir}/lib$1.dylib ]; then
+            echo "${libdir}/lib$1.dylib"
         fi
     done
 }
@@ -82,11 +84,18 @@
 # Do replacements in the output
 for rpath in ${RPATHS}; do
     for lib in ${LIBS}; do
-        if [ -f "`dirname ${OUTPUT}`/${rpath}/lib${lib}.so" ]; then
+        if [ -f "$(dirname ${OUTPUT})/${rpath}/lib${lib}.so" ]; then
+            libname="lib${lib}.so"
+        elif [ -f "$(dirname ${OUTPUT})/${rpath}/lib${lib}.dylib" ]; then
+            libname="lib${lib}.dylib"
+        fi
+        # ${libname-} --> return $libname if defined, or undefined otherwise. This is to make
+        # this set -e friendly
+        if [[ -n "${libname-}" ]]; then
             libpath=$(get_library_path ${lib})
             if [ -n "${libpath}" ]; then
                 ${INSTALL_NAME_TOOL} -change $(get_otool_path "${libpath}") \
-                    "@loader_path/${rpath}/lib${lib}.so" "${OUTPUT}"
+                    "@loader_path/${rpath}/${libname}" "${OUTPUT}"
             fi
         fi
     done
diff --git a/tools/cpp/osx_cc_wrapper.sh.tpl b/tools/cpp/osx_cc_wrapper.sh.tpl
index fb32e1e..713c711 100644
--- a/tools/cpp/osx_cc_wrapper.sh.tpl
+++ b/tools/cpp/osx_cc_wrapper.sh.tpl
@@ -59,6 +59,8 @@
     for libdir in ${LIB_DIRS}; do
         if [ -f ${libdir}/lib$1.so ]; then
             echo "${libdir}/lib$1.so"
+        elif [ -f ${libdir}/lib$1.dylib ]; then
+            echo "${libdir}/lib$1.dylib"
         fi
     done
 }
@@ -84,11 +86,18 @@
 # Do replacements in the output
 for rpath in ${RPATHS}; do
     for lib in ${LIBS}; do
-        if [ -f "`dirname ${OUTPUT}`/${rpath}/lib${lib}.so" ]; then
+        if [ -f "$(dirname ${OUTPUT})/${rpath}/lib${lib}.so" ]; then
+            libname="lib${lib}.so"
+        elif [ -f "$(dirname ${OUTPUT})/${rpath}/lib${lib}.dylib" ]; then
+            libname="lib${lib}.dylib"
+        fi
+        # ${libname-} --> return $libname if defined, or undefined otherwise. This is to make
+        # this set -e friendly
+        if [[ -n "${libname-}" ]]; then
             libpath=$(get_library_path ${lib})
             if [ -n "${libpath}" ]; then
                 ${INSTALL_NAME_TOOL} -change $(get_otool_path "${libpath}") \
-                    "@loader_path/${rpath}/lib${lib}.so" "${OUTPUT}"
+                    "@loader_path/${rpath}/${libname}" "${OUTPUT}"
             fi
         fi
     done