1717import com .google .common .collect .ImmutableList ;
1818import com .google .common .collect .ImmutableSet ;
1919import com .google .common .collect .Iterables ;
20- import com .google .common .collect .Lists ;
2120import com .google .devtools .build .lib .actions .Artifact ;
2221import com .google .devtools .build .lib .analysis .RuleErrorConsumer ;
2322import com .google .devtools .build .lib .cmdline .LabelConstants ;
@@ -41,6 +40,7 @@ public class LibrariesToLinkCollector {
4140 private final PathFragment toolchainLibrariesSolibDir ;
4241 private final CppConfiguration cppConfiguration ;
4342 private final CcToolchainProvider ccToolchainProvider ;
43+ private final Artifact outputArtifact ;
4444 private final boolean isLtoIndexing ;
4545 private final PathFragment solibDir ;
4646 private final Iterable <? extends LinkerInput > linkerInputs ;
@@ -49,8 +49,7 @@ public class LibrariesToLinkCollector {
4949 private final Artifact thinltoParamFile ;
5050 private final FeatureConfiguration featureConfiguration ;
5151 private final boolean needWholeArchive ;
52- private final ImmutableList <String > potentialExecRoots ;
53- private final ImmutableList <String > rpathRoots ;
52+ private final String rpathRoot ;
5453 private final boolean needToolchainLibrariesRpath ;
5554 private final Map <Artifact , Artifact > ltoMap ;
5655 private final RuleErrorConsumer ruleErrorConsumer ;
@@ -77,6 +76,7 @@ public LibrariesToLinkCollector(
7776 this .cppConfiguration = cppConfiguration ;
7877 this .ccToolchainProvider = toolchain ;
7978 this .toolchainLibrariesSolibDir = toolchainLibrariesSolibDir ;
79+ this .outputArtifact = output ;
8080 this .solibDir = solibDir ;
8181 this .isLtoIndexing = isLtoIndexing ;
8282 this .allLtoArtifacts = allLtoArtifacts ;
@@ -106,13 +106,12 @@ public LibrariesToLinkCollector(
106106 // and the second could use $ORIGIN/../_solib_[arch]. But since this is a shared
107107 // artifact, both are symlinks to the same place, so
108108 // there's no *one* RPATH setting that fits all targets involved in the sharing.
109- potentialExecRoots = ImmutableList .of ();
110- rpathRoots = ImmutableList .of (ccToolchainProvider .getSolibDirectory () + "/" );
109+ rpathRoot = ccToolchainProvider .getSolibDirectory () + "/" ;
111110 } else {
112111 // When executed from within a runfiles directory, the binary lies under a path such as
113112 // target.runfiles/some_repo/pkg/file, whereas the solib directory is located under
114113 // target.runfiles/main_repo.
115- PathFragment runfilesPath = output .getRunfilesPath ();
114+ PathFragment runfilesPath = outputArtifact .getRunfilesPath ();
116115 String runfilesExecRoot ;
117116 if (runfilesPath .startsWith (LabelConstants .EXTERNAL_RUNFILES_PATH_PREFIX )) {
118117 // runfilesPath is of the form ../some_repo/pkg/file, walk back some_repo/pkg and then
@@ -122,22 +121,7 @@ public LibrariesToLinkCollector(
122121 // runfilesPath is of the form pkg/file, walk back pkg to reach the main workspace.
123122 runfilesExecRoot = "../" .repeat (runfilesPath .segmentCount () - 1 );
124123 }
125-
126- // When the binary gets run through remote execution as the main executable (i.e., not as a
127- // dependency of another target), it will not be able to find its libraries at
128- // $ORIGIN/../../../_solib_[arch], as execution is not taking place inside the runfiles
129- // directory. Solve this by adding ${executable}.runfiles/${workspace}/_solib_[arch] as an
130- // alternative rpath root.
131- PathFragment rootRelativePath = output .getRootRelativePath ();
132- potentialExecRoots =
133- ImmutableList .of (
134- rootRelativePath .getBaseName () + ".runfiles/" + workspaceName + "/" ,
135- runfilesExecRoot );
136- rpathRoots =
137- ImmutableList .copyOf (
138- Lists .transform (
139- potentialExecRoots ,
140- (execRoot ) -> execRoot + ccToolchainProvider .getSolibDirectory () + "/" ));
124+ rpathRoot = runfilesExecRoot + ccToolchainProvider .getSolibDirectory () + "/" ;
141125 }
142126
143127 ltoMap = generateLtoMap ();
@@ -212,10 +196,10 @@ public CollectedLibrariesToLink collectLibrariesToLink() {
212196 // directory. In other words, given blaze-bin/my/package/binary, rpathRoot would be
213197 // "../../_solib_[arch]".
214198 if (needToolchainLibrariesRpath ) {
215- for ( String potentialExecRoot : potentialExecRoots ) {
216- runtimeLibrarySearchDirectories . add (
217- potentialExecRoot + toolchainLibrariesSolibName + "/" );
218- }
199+ runtimeLibrarySearchDirectories . add (
200+ "../" . repeat ( outputArtifact . getRootRelativePath (). segmentCount () - 1 )
201+ + toolchainLibrariesSolibName
202+ + "/" );
219203 }
220204 if (isNativeDeps ) {
221205 // We also retain the $ORIGIN/ path to solibs that are in _solib_<arch>, as opposed to
@@ -247,9 +231,7 @@ public CollectedLibrariesToLink collectLibrariesToLink() {
247231 NestedSetBuilder <String > allRuntimeLibrarySearchDirectories = NestedSetBuilder .linkOrder ();
248232 // rpath ordering matters for performance; first add the one where most libraries are found.
249233 if (includeSolibDir ) {
250- for (String rpathRoot : rpathRoots ) {
251- allRuntimeLibrarySearchDirectories .add (rpathRoot );
252- }
234+ allRuntimeLibrarySearchDirectories .add (rpathRoot );
253235 }
254236 allRuntimeLibrarySearchDirectories .addAll (rpathRootsForExplicitSoDeps .build ());
255237 if (includeToolchainLibrariesSolibDir ) {
@@ -364,21 +346,17 @@ private void addDynamicInputLinkOptions(
364346 // When all dynamic deps are built in transitioned configurations, the default solib dir is
365347 // not created. While resolving paths, the dynamic linker stops at the first directory that
366348 // does not exist, even when followed by "../". We thus have to normalize the relative path.
367- for (String rpathRoot : rpathRoots ) {
368- String relativePathToRoot =
369- rpathRoot + dotdots + libDir .relativeTo (commonParent ).getPathString ();
370- String normalizedPathToRoot = PathFragment .create (relativePathToRoot ).getPathString ();
371- rpathRootsForExplicitSoDeps .add (normalizedPathToRoot );
372- }
349+ String relativePathToRoot =
350+ rpathRoot + dotdots + libDir .relativeTo (commonParent ).getPathString ();
351+ String normalizedPathToRoot = PathFragment .create (relativePathToRoot ).getPathString ();
352+ rpathRootsForExplicitSoDeps .add (normalizedPathToRoot );
373353
374354 // Unless running locally, libraries will be available under the root relative path, so we
375355 // should add that to the rpath as well.
376356 if (inputArtifact .getRootRelativePathString ().startsWith ("_solib_" )) {
377357 PathFragment artifactPathUnderSolib = inputArtifact .getRootRelativePath ().subFragment (1 );
378- for (String rpathRoot : rpathRoots ) {
379- rpathRootsForExplicitSoDeps .add (
380- rpathRoot + artifactPathUnderSolib .getParentDirectory ().getPathString ());
381- }
358+ rpathRootsForExplicitSoDeps .add (
359+ rpathRoot + artifactPathUnderSolib .getParentDirectory ().getPathString ());
382360 }
383361 }
384362
0 commit comments