diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionBuilder.java index 232187eaf42100..0b241999cde846 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionBuilder.java @@ -26,6 +26,7 @@ import com.google.devtools.build.lib.actions.ActionOwner; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.ParameterFile; +import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.RuleErrorConsumer; import com.google.devtools.build.lib.analysis.actions.ActionConstructionContext; import com.google.devtools.build.lib.analysis.actions.ParameterFileWriteAction; @@ -798,7 +799,8 @@ public CppLinkAction build() throws InterruptedException, RuleErrorException { allowLtoIndexing, nonExpandedLinkerInputs, needWholeArchive, - ruleErrorConsumer); + ruleErrorConsumer, + ((RuleContext) actionConstructionContext).getWorkspaceName()); CollectedLibrariesToLink collectedLibrariesToLink = librariesToLinkCollector.collectLibrariesToLink(); diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/LibrariesToLinkCollector.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/LibrariesToLinkCollector.java index b5e4d5ac2c2e84..6b974efb79fa6d 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/LibrariesToLinkCollector.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/LibrariesToLinkCollector.java @@ -47,7 +47,7 @@ public class LibrariesToLinkCollector { private final Artifact thinltoParamFile; private final FeatureConfiguration featureConfiguration; private final boolean needWholeArchive; - private final String rpathRoot; + private final ImmutableList rpathRoots; private final boolean needToolchainLibrariesRpath; private final Map ltoMap; private final RuleErrorConsumer ruleErrorConsumer; @@ -68,7 +68,8 @@ public LibrariesToLinkCollector( boolean allowLtoIndexing, Iterable linkerInputs, boolean needWholeArchive, - RuleErrorConsumer ruleErrorConsumer) { + RuleErrorConsumer ruleErrorConsumer, + String workspaceName) { this.isNativeDeps = isNativeDeps; this.cppConfiguration = cppConfiguration; this.ccToolchainProvider = toolchain; @@ -103,12 +104,25 @@ public LibrariesToLinkCollector( // and the second could use $ORIGIN/../_solib_[arch]. But since this is a shared // artifact, both are symlinks to the same place, so // there's no *one* RPATH setting that fits all targets involved in the sharing. - rpathRoot = ccToolchainProvider.getSolibDirectory() + "/"; + rpathRoots = ImmutableList.of(ccToolchainProvider.getSolibDirectory() + "/"); } else { - rpathRoot = - "../".repeat(outputArtifact.getRootRelativePath().segmentCount() - 1) - + ccToolchainProvider.getSolibDirectory() - + "/"; + // When the binary gets run through remote execution as the main executable (i.e., not as a + // dependency of another target), it will not be able to find its libraries at + // $ORIGIN/../../../_solib_[arch], as execution is not taking place inside the runfiles + // directory. Solve this by adding ${executable}.runfiles/${workspace}/_solib_[arch] as an + // rpath root. + PathFragment rootRelativePath = outputArtifact.getRootRelativePath(); + String solibDirectory = ccToolchainProvider.getSolibDirectory(); + rpathRoots = ImmutableList.of( + rootRelativePath.getBaseName() + + ".runfiles/" + + workspaceName + + "/" + + solibDirectory + + "/", + "../".repeat(rootRelativePath.segmentCount() - 1) + + solibDirectory + + "/"); } ltoMap = generateLtoMap(); @@ -183,10 +197,7 @@ public CollectedLibrariesToLink collectLibrariesToLink() { // directory. In other words, given blaze-bin/my/package/binary, rpathRoot would be // "../../_solib_[arch]". if (needToolchainLibrariesRpath) { - runtimeLibrarySearchDirectories.add( - "../".repeat(outputArtifact.getRootRelativePath().segmentCount() - 1) - + toolchainLibrariesSolibName - + "/"); + runtimeLibrarySearchDirectories.addAll(rpathRoots); } if (isNativeDeps) { // We also retain the $ORIGIN/ path to solibs that are in _solib_, as opposed to @@ -218,7 +229,7 @@ public CollectedLibrariesToLink collectLibrariesToLink() { NestedSetBuilder allRuntimeLibrarySearchDirectories = NestedSetBuilder.linkOrder(); // rpath ordering matters for performance; first add the one where most libraries are found. if (includeSolibDir) { - allRuntimeLibrarySearchDirectories.add(rpathRoot); + allRuntimeLibrarySearchDirectories.addAll(rpathRoots); } allRuntimeLibrarySearchDirectories.addAll(rpathRootsForExplicitSoDeps.build()); if (includeToolchainLibrariesSolibDir) { @@ -330,8 +341,10 @@ private void addDynamicInputLinkOptions( commonParent = commonParent.getParentDirectory(); } - rpathRootsForExplicitSoDeps.add( - rpathRoot + dotdots + libDir.relativeTo(commonParent).getPathString()); + for (String rpathRoot : rpathRoots) { + rpathRootsForExplicitSoDeps.add( + rpathRoot + dotdots + libDir.relativeTo(commonParent).getPathString()); + } } librarySearchDirectories.add(inputArtifact.getExecPath().getParentDirectory().getPathString()); diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcLibraryConfiguredTargetTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcLibraryConfiguredTargetTest.java index 12e7f8846d655e..8504880c6778f4 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcLibraryConfiguredTargetTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcLibraryConfiguredTargetTest.java @@ -2116,6 +2116,7 @@ public void testRpathAndLinkPathsWithoutTransitions() throws Exception { Artifact mainBin = getBinArtifact("main", main); CppLinkAction action = (CppLinkAction) getGeneratingAction(mainBin); List linkArgv = action.getLinkCommandLine().arguments(); + assertThat(linkArgv).contains("-Wl,-rpath,$ORIGIN/main.runfiles/__main__/_solib_k8/"); assertThat(linkArgv).contains("-Wl,-rpath,$ORIGIN/../_solib_k8/"); assertThat(linkArgv) .contains("-L" + TestConstants.PRODUCT_NAME + "-out/k8-fastbuild/bin/_solib_k8"); @@ -2176,6 +2177,7 @@ public void testRpathRootIsAddedEvenWithTransitionedDepsOnly() throws Exception Artifact mainBin = getBinArtifact("main", main); CppLinkAction action = (CppLinkAction) getGeneratingAction(mainBin); List linkArgv = action.getLinkCommandLine().arguments(); + assertThat(linkArgv).contains("-Wl,-rpath,$ORIGIN/main.runfiles/__main__/_solib_k8/"); assertThat(linkArgv).contains("-Wl,-rpath,$ORIGIN/../_solib_k8/"); assertThat(Joiner.on(" ").join(linkArgv)) .contains("-Wl,-rpath,$ORIGIN/../_solib_k8/../../../k8-fastbuild-ST-");