Skip to content

Commit af27ea4

Browse files
authored
support runtime/test-time compiler invokations (#518)
This commit changes the cc_wrapper.sh script to allow for it to find paths when invoked at runtime with runfiles as apposed to strictly using build-rule invokes. fixes #517 Work towards buildbuddy-io/bazel_env.bzl#51
1 parent 716ae33 commit af27ea4

File tree

2 files changed

+107
-39
lines changed

2 files changed

+107
-39
lines changed

toolchain/cc_wrapper.sh.tpl

Lines changed: 51 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,6 @@
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
1616

17-
# OS X relpath is not really working. This is a wrapper script around gcc
18-
# to simulate relpath behavior.
19-
#
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
22-
# the binary. It parses the command line to behave as rpath is supposed
23-
# 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-
2817
# shellcheck disable=SC1083
2918

3019
set -euo pipefail
@@ -42,27 +31,65 @@ trap cleanup EXIT
4231
# See note in toolchain/internal/configure.bzl where we define
4332
# `wrapper_bin_prefix` for why this wrapper is needed.
4433

45-
if [[ -f %{toolchain_path_prefix}bin/clang ]]; then
46-
execroot_path=""
47-
elif [[ ${BASH_SOURCE[0]} == "/"* ]]; then
48-
# Some consumers of `CcToolchainConfigInfo` (e.g. `cmake` from rules_foreign_cc)
49-
# change CWD and call $CC (this script) with its absolute path.
50-
# For cases like this, we'll try to find `clang` through an absolute path.
51-
# This script is at _execroot_/external/_repo_name_/bin/cc_wrapper.sh
52-
execroot_path="${BASH_SOURCE[0]%/*/*/*/*}/"
53-
else
54-
echo >&2 "ERROR: could not find clang; PWD=\"${PWD}\"; PATH=\"${PATH}\"."
34+
# this script is located at either
35+
# - <execroot>/external/<repo_name>/bin/cc_wrapper.sh
36+
# - <runfiles>/<repo_name>/bin/cc_wrapper.sh
37+
# The clang is located at
38+
# - <execroot>/external/<repo_name2>/bin/clang
39+
# - <runfiles>/<repo_name2>/bin/clang
40+
#
41+
# In both cases, getting to clang can be done via
42+
# Finding the current dir of this script,
43+
# - <execroot>/external/<repo_name>/bin/
44+
# - <runfiles>/<repo_name>/bin/
45+
# going back 2 directories
46+
# - <execroot>/external
47+
# - <runfiles>
48+
#
49+
# Going into %{toolchain_path_prefix} without the `external/` prefix + `bin/clang`
50+
#
51+
52+
dirname_shim() {
53+
local path="$1"
54+
55+
# Remove trailing slashes
56+
path="${path%/}"
57+
58+
# If there's no slash, return "."
59+
if [[ "${path}" != */* ]]; then
60+
echo "."
61+
return
62+
fi
63+
64+
# Remove the last component after the final slash
65+
path="${path%/*}"
66+
67+
# If it becomes empty, it means root "/"
68+
echo "${path:-/}"
69+
}
70+
71+
script_dir=$(dirname_shim "${BASH_SOURCE[0]}")
72+
toolchain_path_prefix="%{toolchain_path_prefix}"
73+
74+
# Sometimes this path may be an absolute path in which case we dont do anything because
75+
# This is using the host toolchain to build.
76+
if [[ ${toolchain_path_prefix} != /* ]]; then
77+
toolchain_path_prefix="${script_dir}/../../${toolchain_path_prefix#external/}"
78+
fi
79+
80+
if [[ ! -f ${toolchain_path_prefix}bin/clang ]]; then
81+
echo >&2 "ERROR: could not find clang; PWD=\"${PWD}\"; PATH=\"${PATH}\"; toolchain_path_prefix=${toolchain_path_prefix}."
5582
exit 5
5683
fi
5784

5885
function sanitize_option() {
5986
local -r opt=$1
6087
if [[ ${opt} == */cc_wrapper.sh ]]; then
61-
printf "%s" "${execroot_path}%{toolchain_path_prefix}bin/clang"
62-
elif [[ ${opt} =~ ^-fsanitize-(ignore|black)list=[^/] ]]; then
88+
printf "%s" "${toolchain_path_prefix}bin/clang"
89+
elif [[ ${opt} =~ ^-fsanitize-(ignore|black)list=[^/] ]] && [[ ${script_dir} == /* ]]; then
6390
# shellcheck disable=SC2206
6491
parts=(${opt/=/ }) # Split flag name and value into array.
65-
printf "%s" "${parts[0]}=${execroot_path}${parts[1]}"
92+
printf "%s" "${parts[0]}=${script_dir}/../../../${parts[1]}"
6693
else
6794
printf "%s" "${opt}"
6895
fi

toolchain/osx_cc_wrapper.sh.tpl

Lines changed: 56 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -63,31 +63,72 @@ function parse_option() {
6363
fi
6464
}
6565

66-
if [[ -f %{toolchain_path_prefix}bin/clang ]]; then
67-
execroot_path=""
68-
execroot_abs_path="${PWD}/"
69-
elif [[ ${BASH_SOURCE[0]} == "/"* ]]; then
70-
# Some consumers of `CcToolchainConfigInfo` (e.g. `cmake` from rules_foreign_cc)
71-
# change CWD and call $CC (this script) with its absolute path.
72-
# For cases like this, we'll try to find `clang` through an absolute path.
73-
# This script is at _execroot_/external/_repo_name_/bin/cc_wrapper.sh
74-
execroot_path="${BASH_SOURCE[0]%/*/*/*/*}/"
75-
execroot_abs_path="$(cd "${execroot_path}" && pwd -P)/"
66+
# See note in toolchain/internal/configure.bzl where we define
67+
# `wrapper_bin_prefix` for why this wrapper is needed.
68+
69+
# this script is located at either
70+
# - <execroot>/external/<repo_name>/bin/cc_wrapper.sh
71+
# - <runfiles>/<repo_name>/bin/cc_wrapper.sh
72+
# The clang is located at
73+
# - <execroot>/external/<repo_name2>/bin/clang
74+
# - <runfiles>/<repo_name2>/bin/clang
75+
#
76+
# In both cases, getting to clang can be done via
77+
# Finding the current dir of this script,
78+
# - <execroot>/external/<repo_name>/bin/
79+
# - <runfiles>/<repo_name>/bin/
80+
# going back 2 directories
81+
# - <execroot>/external
82+
# - <runfiles>
83+
#
84+
# Going into %{toolchain_path_prefix} without the `external/` prefix + `bin/clang`
85+
#
86+
87+
dirname_shim() {
88+
local path="$1"
89+
90+
# Remove trailing slashes
91+
path="${path%/}"
92+
93+
# If there's no slash, return "."
94+
if [[ "${path}" != */* ]]; then
95+
echo "."
96+
return
97+
fi
98+
99+
# Remove the last component after the final slash
100+
path="${path%/*}"
101+
102+
# If it becomes empty, it means root "/"
103+
echo "${path:-/}"
104+
}
105+
106+
script_dir=$(dirname_shim "${BASH_SOURCE[0]}")
107+
toolchain_path_prefix="%{toolchain_path_prefix}"
108+
# Sometimes this path may be an absolute path in which case we dont do anything because
109+
# This is using the host toolchain to build.
110+
if [[ ${toolchain_path_prefix} != /* ]]; then
111+
toolchain_path_prefix="${script_dir}/../../${toolchain_path_prefix#external/}"
112+
toolchain_path_prefix_abs="$(cd "${toolchain_path_prefix}" && pwd -P)/"
76113
else
77-
echo >&2 "ERROR: could not find clang; PWD=\"${PWD}\"; PATH=\"${PATH}\"."
114+
toolchain_path_prefix_abs="${toolchain_path_prefix}"
115+
fi
116+
117+
if [[ ! -f ${toolchain_path_prefix}bin/clang ]]; then
118+
echo >&2 "ERROR: could not find clang; PWD=\"${PWD}\"; PATH=\"${PATH}\"; toolchain_path_prefix=${toolchain_path_prefix}."
78119
exit 5
79120
fi
80121

81122
function sanitize_option() {
82123
local -r opt=$1
83124
if [[ ${opt} == */cc_wrapper.sh ]]; then
84-
printf "%s" "${execroot_path}%{toolchain_path_prefix}bin/clang"
125+
printf "%s" "${toolchain_path_prefix}bin/clang"
85126
elif [[ ${opt} == "-fuse-ld=ld64.lld" ]]; then
86-
echo "--ld-path=${execroot_abs_path}%{toolchain_path_prefix}bin/ld64.lld"
87-
elif [[ ${opt} =~ ^-fsanitize-(ignore|black)list=[^/] ]]; then
127+
echo "--ld-path=${toolchain_path_prefix_abs}bin/ld64.lld"
128+
elif [[ ${opt} =~ ^-fsanitize-(ignore|black)list=[^/] ]] && [[ ${script_dir} == /* ]]; then
88129
# shellcheck disable=SC2206
89130
parts=(${opt/=/ }) # Split flag name and value into array.
90-
printf "%s" "${parts[0]}=${execroot_path}${parts[1]}"
131+
printf "%s" "${parts[0]}=${script_dir}/../../../${parts[1]}"
91132
else
92133
printf "%s" "${opt}"
93134
fi

0 commit comments

Comments
 (0)