Skip to content

Commit

Permalink
Workaround erroneous response file expansion
Browse files Browse the repository at this point in the history
Bazel 4.0.0's own cc_wrapper expands response files. However, it
fails to make exceptions for legitimate arguments starting with
`@` on macOS, such as `-install_name @rpath/...` or `-rpath
@loader_path/...`.
We use `-Wl,...` syntax for these arguments as a workaround.
  • Loading branch information
aherrmann committed Feb 22, 2021
1 parent d6cdb11 commit 57986d1
Showing 1 changed file with 39 additions and 6 deletions.
45 changes: 39 additions & 6 deletions haskell/private/cc_wrapper.py.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,26 @@ used to avoid command line length limitations.
See https://gitlab.haskell.org/ghc/ghc/issues/17185.
- Fixes invocations that handle temporary and intermediate binaries
- Fixes invocations that handle temporary and intermediate binaries.
GHC with Template Haskell or tools like hsc2hs build temporary Haskell
binaries (that e.g. generate other Haskell code) as part of the build
process. This wrapper ensures that linking behaviour for these binaries
matches the characteristics of the wider build (e.g. runpath configuration,
etc.)
- Avoids arguments starting with `@`.
Bazel 4.0.0 has its own cc_wrapper on macOS which attempts to expand any
argument starting with `@` as a response file. This will wrongly interpret
the follwoing types of arguments as referencing a response file:
-install_name @rpath/...
-Xlinker -rpath -Xlinker @executable_path/...
-Xlinker -rpath -Xlinker @loader_path/...
See https://github.com/bazelbuild/bazel/pull/13044
"""

from bazel_tools.tools.python.runfiles import runfiles as bazel_runfiles
Expand Down Expand Up @@ -198,6 +210,8 @@ class Args:
pass
elif self._handle_linker_arg(arg, args, out):
pass
elif self._handle_install_name(arg, args, out):
pass
elif self._handle_print_file_name(arg, args, out):
pass
elif self._handle_compile(arg, args, out):
Expand Down Expand Up @@ -324,7 +338,15 @@ class Args:
raise RuntimeError("Unhandled _prev_ld_arg '{}'.".format(self._prev_ld_arg))

if forward_ld_args:
if use_xlinker:
# Avoid arguments starting with `@`, see module docstring.
# Use `-Wl,...` in those cases instead of `-Xlinker ...`.
starts_with_at = any(
ld_arg.startswith("@rpath") or
ld_arg.startswith("@loader_path") or
ld_arg.startswith("@executable_path")
for ld_arg in forward_ld_args
)
if use_xlinker and not starts_with_at:
out.extend(
arg
for ld_arg in forward_ld_args
Expand All @@ -335,6 +357,18 @@ class Args:

return True

def _handle_install_name(self, arg, args, out):
consumed, install_name = argument(arg, args, long = "-install_name")

if consumed:
# Avoid arguments starting with `@`, see module docstring.
# The compiler wrapper forwards `-install_name` to the linker.
# Here we use `-Wl,-install_name,...` directly to send the flag to
# the linker and avoid an argument starting with `@`.
out.append("-Wl,-install_name,{}".format(install_name))

return consumed

def _handle_rpath(self, rpath, out):
# Filter out all RPATH flags for now and manually add the needed ones
# later on.
Expand Down Expand Up @@ -518,11 +552,10 @@ def shorten_path(input_path):

def rpath_args(rpaths):
"""Generate arguments for RUNPATHs."""
# Avoid arguments starting with `@`, see module docstring.
# Pass `-rpath` flags using `-Wl,...` instead of `-Xlinker ...`.
for rpath in rpaths:
yield "-Xlinker"
yield "-rpath"
yield "-Xlinker"
yield rpath
yield "-Wl,-rpath,{}".format(rpath)


# --------------------------------------------------------------------
Expand Down

0 comments on commit 57986d1

Please sign in to comment.