Make rules_cc more compatible on Posix systems.

The patch from
https://github.com/bazelbuild/rules_cc/pull/466
Replaces `bash` with `/bin/sh`. Not yet submitted upstream,
so for now, locally as patch.
diff --git a/MODULE.bazel b/MODULE.bazel
index a336ab1..5d1ce6a 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -10,7 +10,6 @@
 bazel_dep(name = "protobuf", version = "31.0-rc2")
 bazel_dep(name = "re2", version = "2024-07-02.bcr.1")
 bazel_dep(name = "rules_bison", version = "0.3")
-bazel_dep(name = "rules_cc", version = "0.1.2")
 bazel_dep(name = "rules_flex", version = "0.3")
 bazel_dep(name = "rules_license", version = "1.0.0")
 bazel_dep(name = "rules_m4", version = "0.2.3")
@@ -20,3 +19,11 @@
 
 # To build compilation DB and run build-cleaning
 bazel_dep(name = "bant", version = "0.2.0", dev_dependency = True)
+
+# Make rules_cc more compatible to compile on Posix systems: use /bin/sh
+bazel_dep(name = "rules_cc", version = "0.2.1")
+single_version_override(
+    module_name = "rules_cc",
+    patch_strip = 1,
+    patches = ["//bazel:rules_cc_466.patch"],
+)
diff --git a/bazel/rules_cc_466.patch b/bazel/rules_cc_466.patch
new file mode 100644
index 0000000..a09f80b
--- /dev/null
+++ b/bazel/rules_cc_466.patch
@@ -0,0 +1,275 @@
+From 5f655475e956af645508076e3906385dfd414a11 Mon Sep 17 00:00:00 2001
+From: UebelAndre <github@uebelandre.com>
+Date: Tue, 19 Aug 2025 07:29:30 -0700
+Subject: [PATCH] Update cc_wrapper templates to posix shell.
+
+---
+ cc/private/toolchain/linux_cc_wrapper.sh.tpl |  41 +++---
+ cc/private/toolchain/osx_cc_wrapper.sh.tpl   | 145 +++++++++++--------
+ 2 files changed, 109 insertions(+), 77 deletions(-)
+
+diff --git a/cc/private/toolchain/linux_cc_wrapper.sh.tpl b/cc/private/toolchain/linux_cc_wrapper.sh.tpl
+index 1d030d4a..29fb3794 100644
+--- a/cc/private/toolchain/linux_cc_wrapper.sh.tpl
++++ b/cc/private/toolchain/linux_cc_wrapper.sh.tpl
+@@ -1,4 +1,4 @@
+-#!/usr/bin/env bash
++#!/bin/sh
+ #
+ # Copyright 2015 The Bazel Authors. All rights reserved.
+ #
+@@ -20,26 +20,31 @@ set -eu
+ 
+ OUTPUT=
+ 
+-function parse_option() {
+-    local -r opt="$1"
+-    if [[ "${OUTPUT}" = "1" ]]; then
++parse_option() {
++    opt=$1
++    if [ "$OUTPUT" = "1" ]; then
+         OUTPUT=$opt
+-    elif [[ "$opt" = "-o" ]]; then
++    elif [ "$opt" = "-o" ]; then
+         # output is coming
+         OUTPUT=1
+     fi
+ }
+ 
+-# let parse the option list
++# parse the option list
+ for i in "$@"; do
+-    if [[ "$i" = @* && -r "${i:1}" ]]; then
+-        while IFS= read -r opt
+-        do
+-            parse_option "$opt"
+-        done < "${i:1}" || exit 1
+-    else
+-        parse_option "$i"
+-    fi
++    case $i in
++        @*)
++            file=${i#@}
++            if [ -r "$file" ]; then
++                while IFS= read -r opt; do
++                    parse_option "$opt"
++                done < "$file" || exit 1
++            fi
++            ;;
++        *)
++            parse_option "$i"
++            ;;
++    esac
+ done
+ 
+ # Set-up the environment
+@@ -49,6 +54,8 @@ done
+ %{cc} "$@"
+ 
+ # Generate an empty file if header processing succeeded.
+-if [[ "${OUTPUT}" == *.h.processed ]]; then
+-  echo -n > "${OUTPUT}"
+-fi
++case $OUTPUT in
++    *.h.processed)
++        : > "$OUTPUT"
++        ;;
++esac
+diff --git a/cc/private/toolchain/osx_cc_wrapper.sh.tpl b/cc/private/toolchain/osx_cc_wrapper.sh.tpl
+index 0a2d5689..62f5ff68 100644
+--- a/cc/private/toolchain/osx_cc_wrapper.sh.tpl
++++ b/cc/private/toolchain/osx_cc_wrapper.sh.tpl
+@@ -1,4 +1,4 @@
+-#!/usr/bin/env bash
++#!/bin/sh
+ #
+ # Copyright 2015 The Bazel Authors. All rights reserved.
+ #
+@@ -33,21 +33,36 @@ LIB_DIRS=
+ RPATHS=
+ OUTPUT=
+ 
+-function parse_option() {
+-    local -r opt="$1"
+-    if [[ "${OUTPUT}" = "1" ]]; then
++XCRUN=/usr/bin/xcrun
++[ -x "$XCRUN" ] || XCRUN="xcrun"
++
++DIRNAME=/usr/bin/dirname
++[ -x "$DIRNAME" ] || DIRNAME="dirname"
++
++BASENAME=/usr/bin/basename
++[ -x "$BASENAME" ] || BASENAME="basename"
++
++READLINK=/usr/bin/readlink
++[ -x "$READLINK" ] || READLINK="readlink"
++
++SED=/usr/bin/sed
++[ -x "$SED" ] || SED="sed"
++
++parse_option() {
++    opt=$1
++    if [ "$OUTPUT" = "1" ]; then
+         OUTPUT=$opt
+-    elif [[ "$opt" =~ ^-l(.*)$ ]]; then
+-        LIBS="${BASH_REMATCH[1]} $LIBS"
+-    elif [[ "$opt" =~ ^(.*)\.so$ ]]; then
+-        LIB_PATHS="${opt} $LIB_PATHS"
+-    elif [[ "$opt" =~ ^(.*)\.dylib$ ]]; then
+-        LIB_PATHS="${opt} $LIB_PATHS"
+-    elif [[ "$opt" =~ ^-L(.*)$ ]]; then
+-        LIB_DIRS="${BASH_REMATCH[1]} $LIB_DIRS"
+-    elif [[ "$opt" =~ ^\@loader_path/(.*)$ ]]; then
+-        RPATHS="${BASH_REMATCH[1]} ${RPATHS}"
+-    elif [[ "$opt" = "-o" ]]; then
++    elif [ "${opt#-l}" != "$opt" ]; then
++        LIBS="${opt#-l} $LIBS"
++    elif [ "${opt%.so}" != "$opt" ]; then
++        LIB_PATHS="$opt $LIB_PATHS"
++    elif [ "${opt%.dylib}" != "$opt" ]; then
++        LIB_PATHS="$opt $LIB_PATHS"
++    elif [ "${opt#-L}" != "$opt" ]; then
++        LIB_DIRS="${opt#-L} $LIB_DIRS"
++    elif [ "${opt#@loader_path/}" != "$opt" ]; then
++        RPATHS="${opt#@loader_path/} $RPATHS"
++    elif [ "$opt" = "-o" ]; then
+         # output is coming
+         OUTPUT=1
+     fi
+@@ -55,14 +70,19 @@ function parse_option() {
+ 
+ # let parse the option list
+ for i in "$@"; do
+-    if [[ "$i" = @* && -r "${i:1}" ]]; then
+-        while IFS= read -r opt
+-        do
+-            parse_option "$opt"
+-        done < "${i:1}" || exit 1
+-    else
+-        parse_option "$i"
+-    fi
++    case $i in
++        @*)
++            file=${i#@}
++            if [ -r "$file" ]; then
++                while IFS= read -r opt; do
++                    parse_option "$opt"
++                done < "$file" || exit 1
++            fi
++            ;;
++        *)
++            parse_option "$i"
++            ;;
++    esac
+ done
+ 
+ # Set-up the environment
+@@ -72,66 +92,71 @@ done
+ %{cc} "$@"
+ 
+ # Generate an empty file if header processing succeeded.
+-if [[ "${OUTPUT}" == *.h.processed ]]; then
+-  echo -n > "${OUTPUT}"
+-fi
+-
+-function get_library_path() {
+-    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"
++case $OUTPUT in
++    *.h.processed)
++        : > "$OUTPUT"
++        ;;
++esac
++
++get_library_path() {
++    lib=$1
++    for libdir in $LIB_DIRS; do
++        if [ -f "$libdir/lib$lib.so" ]; then
++            echo "$libdir/lib$lib.so"
++            return
++        elif [ -f "$libdir/lib$lib.dylib" ]; then
++            echo "$libdir/lib$lib.dylib"
++            return
+         fi
+     done
+ }
+ 
+ # A convenient method to return the actual path even for non symlinks
+ # and multi-level symlinks.
+-function get_realpath() {
+-    local previous="$1"
+-    local next=$(readlink "${previous}")
+-    while [ -n "${next}" ]; do
+-        previous="${next}"
+-        next=$(readlink "${previous}")
++get_realpath() {
++    previous=$1
++    next=$($READLINK "$previous" 2>/dev/null || true)
++    while [ -n "$next" ]; do
++        previous=$next
++        next=$($READLINK "$previous" 2>/dev/null || true)
+     done
+-    echo "${previous}"
++    echo "$previous"
+ }
+ 
+ # Get the path of a lib inside a tool
+-function get_otool_path() {
++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/|'
++    get_realpath "$1" | $SED 's|^.*/bazel-out/|bazel-out/|'
+ }
+ 
+-function call_install_name() {
+-    /usr/bin/xcrun install_name_tool -change $(get_otool_path "$1") \
+-        "@loader_path/$2/$3" "${OUTPUT}"
++call_install_name() {
++    $XCRUN install_name_tool -change "$(get_otool_path "$1")" \
++        "@loader_path/$2/$3" "$OUTPUT"
+ }
+ 
+ # Do replacements in the output
+-for rpath in ${RPATHS}; do
+-    for lib in ${LIBS}; do
+-        unset libname
+-        if [ -f "$(/usr/bin/dirname ${OUTPUT})/${rpath}/lib${lib}.so" ]; then
+-            libname="lib${lib}.so"
+-        elif [ -f "$(/usr/bin/dirname ${OUTPUT})/${rpath}/lib${lib}.dylib" ]; then
+-            libname="lib${lib}.dylib"
++for rpath in $RPATHS; do
++    for lib in $LIBS; do
++        libname=
++        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
+-                call_install_name "${libpath}" "${rpath}" "${libname}"
++        if [ -n "$libname" ]; then
++            libpath=$(get_library_path "$lib")
++            if [ -n "$libpath" ]; then
++                call_install_name "$libpath" "$rpath" "$libname"
+             fi
+         fi
+     done
+-    for libpath in ${LIB_PATHS}; do
++    for libpath in $LIB_PATHS; do
+         if [ -f "$libpath" ]; then
+-            libname=$(/usr/bin/basename "$libpath")
+-            if [ -f "$(/usr/bin/dirname ${OUTPUT})/${rpath}/${libname}" ]; then
+-                call_install_name "${libpath}" "${rpath}" "${libname}"
++            libname=$($BASENAME "$libpath")
++            if [ -f "$($DIRNAME "$OUTPUT")/$rpath/$libname" ]; then
++                call_install_name "$libpath" "$rpath" "$libname"
+             fi
+         fi
+     done