Skip to content

Commit 91d7af8

Browse files
author
Ryan Torok
committed
[wrapper] Make cc_wrapper.sh POSIX-compliant and use /bin/sh
Some Linux distributions, such as NixOS, do not provide /bin/bash. This commit aims to make the LLVM toolchain compatible with these platforms by only using POSIX-compatible features in the shell script and replacing the shebang with #!/bin/sh . This commit does not update the corresponding MacOS script, as all MacOS builds should have /bin/bash. Supercedes bazel-contrib#543.
1 parent 283c024 commit 91d7af8

File tree

1 file changed

+47
-36
lines changed

1 file changed

+47
-36
lines changed

toolchain/cc_wrapper.sh.tpl

Lines changed: 47 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/bash
1+
#!/bin/sh
22
#
33
# Copyright 2021 The Bazel Authors. All rights reserved.
44
#
@@ -16,16 +16,16 @@
1616

1717
# shellcheck disable=SC1083
1818

19-
set -euo pipefail
19+
set -euo
2020

21-
CLEANUP_FILES=()
22-
23-
function cleanup() {
24-
if [[ ${#CLEANUP_FILES[@]} -gt 0 ]]; then
25-
rm -f "${CLEANUP_FILES[@]}"
26-
fi
21+
cleanup() {
22+
while read -r f; do
23+
rm -f "${f}"
24+
done <"${CLEANUP_FILES}"
2725
}
2826

27+
CLEANUP_FILES=""
28+
2929
trap cleanup EXIT
3030

3131
# See note in toolchain/internal/configure.bzl where we define
@@ -50,13 +50,13 @@ trap cleanup EXIT
5050
#
5151

5252
dirname_shim() {
53-
local path="$1"
53+
path="$1"
5454

5555
# Remove trailing slashes
5656
path="${path%/}"
5757

5858
# If there's no slash, return "."
59-
if [[ "${path}" != */* ]]; then
59+
if [ "${path}" != "*/*" ]; then
6060
echo "."
6161
return
6262
fi
@@ -68,74 +68,85 @@ dirname_shim() {
6868
echo "${path:-/}"
6969
}
7070

71-
script_dir=$(dirname_shim "${BASH_SOURCE[0]}")
71+
script_dir=$(dirname_shim "$0")
7272
toolchain_path_prefix="%{toolchain_path_prefix}"
7373

7474
# Sometimes this path may be an absolute path in which case we dont do anything because
7575
# This is using the host toolchain to build.
76-
if [[ ${toolchain_path_prefix} != /* ]]; then
76+
if [ "${toolchain_path_prefix}" != "/*" ]; then
7777
toolchain_path_prefix="${script_dir}/../../${toolchain_path_prefix#external/}"
7878
fi
7979

80-
if [[ ! -f ${toolchain_path_prefix}bin/clang ]]; then
80+
if [ ! -f "${toolchain_path_prefix}bin/clang" ]; then
8181
echo >&2 "ERROR: could not find clang; PWD=\"${PWD}\"; PATH=\"${PATH}\"; toolchain_path_prefix=${toolchain_path_prefix}."
8282
exit 5
8383
fi
8484

8585
OUTPUT=
8686

87-
function parse_option() {
88-
local -r opt="$1"
89-
if [[ "${OUTPUT}" = "1" ]]; then
90-
OUTPUT=${opt}
91-
elif [[ "${opt}" = "-o" ]]; then
87+
parse_option() {
88+
po_opt="$1"
89+
if [ "${OUTPUT}" = "1" ]; then
90+
OUTPUT=${po_opt}
91+
elif [ "${po_opt}" = "-o" ]; then
9292
# output is coming
9393
OUTPUT=1
9494
fi
9595
}
9696

97-
function sanitize_option() {
98-
local -r opt=$1
99-
if [[ ${opt} == */cc_wrapper.sh ]]; then
97+
sanitize_option() {
98+
so_opt="$1"
99+
if [ "${so_opt}" = "*/cc_wrapper.sh" ]; then
100100
printf "%s" "${toolchain_path_prefix}bin/clang"
101-
elif [[ ${opt} =~ ^-fsanitize-(ignore|black)list=[^/] ]] && [[ ${script_dir} == /* ]]; then
101+
elif eval "case ${so_opt} in *^-fsanitize-(ignore|black)list=[^/]*) [ ${script_dir} == /* ] ;; esac"; then
102+
# Split flag name and value.
103+
#
102104
# shellcheck disable=SC2206
103-
parts=(${opt/=/ }) # Split flag name and value into array.
104-
printf "%s" "${parts[0]}=${script_dir}/../../../${parts[1]}"
105+
part0=$(echo "${so_opt}" | cut -d '=' -f 1)
106+
part1=$(echo "${so_opt}" | cut -d '=' -f 2)
107+
printf "%s" "${part0}=${script_dir}/../../../${part1}"
105108
else
106-
printf "%s" "${opt}"
109+
printf "%s" "${so_opt}"
107110
fi
108111
}
109112

110-
cmd=()
111-
for ((i = 0; i <= $#; i++)); do
112-
if [[ ${!i} == @* && -r "${i:1}" ]]; then
113+
COUNT=$#
114+
i=0
115+
while [ "${i}" -le "${COUNT}" ]; do
116+
temp=""
117+
eval "temp=\${${i}}"
118+
substr="${temp#?}"
119+
if eval "case ${temp} in @*) [ -r ${substr} ] ;; esac"; then
113120
# Create a new, sanitized file.
114121
tmpfile=$(mktemp)
115-
CLEANUP_FILES+=("${tmpfile}")
122+
# POSIX shell does not support arrays, so we write the cleanup files as an
123+
# array-separated list. We do not need to worry about spaces in filenames,
124+
# because `mktemp` cannot use them when using the default template.
125+
CLEANUP_FILES="${CLEANUP_FILES} ${tmpfile}"
116126
while IFS= read -r opt; do
117127
opt="$(
118128
set -e
119129
sanitize_option "${opt}"
120130
)"
121131
parse_option "${opt}"
122132
echo "${opt}" >>"${tmpfile}"
123-
done <"${!i:1}"
124-
cmd+=("@${tmpfile}")
133+
done <"${substr}"
134+
cmd="${cmd} ${tmpfile}"
125135
else
126136
opt="$(
127137
set -e
128-
sanitize_option "${!i}"
138+
sanitize_option "${temp}"
129139
)"
130140
parse_option "${opt}"
131-
cmd+=("${opt}")
141+
cmd="${cmd} ${opt}"
132142
fi
143+
i=$((i + 1))
133144
done
134145

135146
# Call the C++ compiler.
136-
"${cmd[@]}"
147+
${cmd}
137148

138149
# Generate an empty file if header processing succeeded.
139-
if [[ "${OUTPUT}" == *.h.processed ]]; then
140-
echo -n >"${OUTPUT}"
150+
if [ "${OUTPUT}" = "*.h.processed" ]; then
151+
true >"${OUTPUT}"
141152
fi

0 commit comments

Comments
 (0)