@@ -17,39 +17,41 @@ load(
1717 "paths" ,
1818)
1919
20- # TODO: Replace with a Bazel-provided function when it's available.
21- # https://github.com/bazelbuild/bazel/issues/14307
22- def _rlocation_path (ctx , file ):
23- """Returns the path relative to the runfiles directory."""
24- if file .short_path .startswith ("../" ):
25- return file .short_path [3 :]
26- else :
27- return ctx .workspace_name + "/" + file .short_path
28-
2920def _rpath (go , library , executable = None ):
3021 """Returns the potential rpaths of a library, possibly relative to another file."""
3122 if not executable :
3223 return [paths .dirname (library .short_path )]
3324
34- origin = go .mode .goos == "darwin" and "@loader_path" or "$ORIGIN"
25+ origin = "@loader_path" if go .mode .goos == "darwin" else "$ORIGIN"
3526
36- # Accomodate for two kinds of executable paths.
27+ # Accommodate for three kinds of executable paths.
3728 rpaths = []
29+ library_dir = paths .dirname (library .short_path )
30+
31+ # Based on the logic for Bazel's own C++ rules:
32+ # https://github.com/bazelbuild/bazel/blob/51a4b8e5de225ba163d19ddcc330aff8860a1520/src/main/starlark/builtins_bzl/common/cc/link/collect_solib_dirs.bzl#L301
33+ # with the bug fix https://github.com/bazelbuild/bazel/pull/27154.
34+ # We ignore the cases for --experimental_sibling_repository_layout.
3835
3936 # 1. Where the executable is inside its own .runfiles directory.
40- # This is the case for generated libraries as well as remote builds .
41- # a) go back to the runfiles root from the executable file in .runfiles
42- depth = _rlocation_path ( go . _ctx , executable ) .count ("/" )
37+ # This covers the cases 1, 3, 4, 5, and 7 in the linked code above .
38+ # a) go back to the workspace root from the executable file in .runfiles
39+ depth = executable . short_path .count ("/" )
4340 back_to_root = paths .join (* ([".." ] * depth ))
4441
45- # b) then walk back to the library's dir within runfiles dir.
46- rpaths .append (paths .join (origin , back_to_root , paths . dirname ( _rlocation_path ( go . _ctx , library )) ))
42+ # b) then walk back to the library's short path
43+ rpaths .append (paths .join (origin , back_to_root , library_dir ))
4744
4845 # 2. Where the executable is outside the .runfiles directory:
49- # This is the case for local pre-built libraries, as well as local
50- # generated libraries.
46+ # This covers the cases 2 and 6 in the linked code above.
5147 runfiles_dir = paths .basename (executable .short_path ) + ".runfiles"
52- rpaths .append (paths .join (origin , runfiles_dir , go ._ctx .workspace_name , paths .dirname (library .short_path )))
48+ rpaths .append (paths .join (origin , runfiles_dir , go ._ctx .workspace_name , library_dir ))
49+
50+ # 3. Where the executable is from a different repo
51+ # This covers the case 8 in the linked code above.
52+ if executable .short_path .startswith ("../" ):
53+ back_to_repo_root = paths .join (* ([".." ] * (depth - 1 )))
54+ rpaths .append (paths .join (origin , back_to_repo_root , go ._ctx .workspace_name , library_dir ))
5355
5456 return rpaths
5557
0 commit comments