diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingHelper.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingHelper.java index eb9c6c537e4b47..971f383bda5503 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingHelper.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLinkingHelper.java @@ -693,7 +693,9 @@ private boolean createDynamicLinkAction( ImmutableList.of( "-Wl,-soname=" + SolibSymlinkAction.getDynamicLibrarySoname( - linkerOutput.getRootRelativePath(), /* preserveName= */ false)); + linkerOutput.getRootRelativePath(), + /* preserveName= */ false, + actionConstructionContext.getConfiguration().getMnemonic())); } } 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 77591363a6ddfa..9a9136a6646743 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 @@ -267,7 +267,10 @@ private Pair addLinkerInputs( // When COPY_DYNAMIC_LIBRARIES_TO_BINARY is enabled, dynamic libraries are not symlinked // under solibDir, so don't check it and don't include solibDir. if (!featureConfiguration.isEnabled(CppRuleClasses.COPY_DYNAMIC_LIBRARIES_TO_BINARY)) { - if (libDir.equals(solibDir)) { + // The first fragment is bazel-out, and the second may contain a configuration mnemonic. + // We should always add the default solib dir because that's where libraries will be found + // e.g. in remote execution, so we ignore the first two fragments. + if (libDir.subFragment(2).equals(solibDir.subFragment(2))) { includeSolibDir = true; } if (libDir.equals(toolchainLibrariesSolibDir)) { diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/SolibSymlinkAction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/SolibSymlinkAction.java index 6050e65e74d4ac..c1cb712fe23eac 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/SolibSymlinkAction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/SolibSymlinkAction.java @@ -140,6 +140,7 @@ public static Artifact getDynamicLibrarySymlink( getMangledName( actionRegistry.getOwner().getLabel(), solibDir, + actionConstructionContext.getConfiguration().getMnemonic(), library.getRootRelativePath(), preserveName, prefixConsumer); @@ -234,11 +235,12 @@ private static Artifact getDynamicLibrarySymlinkInternal( private static PathFragment getMangledName( Label label, String solibDir, + String mnemonic, PathFragment libraryPath, boolean preserveName, boolean prefixConsumer) { String escapedRulePath = Actions.escapedPath("_" + label); - String soname = getDynamicLibrarySoname(libraryPath, preserveName); + String soname = getDynamicLibrarySoname(libraryPath, preserveName, mnemonic); PathFragment solibDirPath = PathFragment.create(solibDir); if (preserveName) { String escapedLibraryPath = @@ -258,15 +260,21 @@ private static PathFragment getMangledName( * * @param libraryPath name of the shared library that needs to be mangled * @param preserveName true if filename should be preserved, false - mangled + * @param mnemonic the output directory mnemonic, to be mangled in for nondefault configurations * @return soname to embed in the dynamic library */ public static String getDynamicLibrarySoname(PathFragment libraryPath, - boolean preserveName) { + boolean preserveName, + String mnemonic) { String mangledName; if (preserveName) { mangledName = libraryPath.getBaseName(); } else { - mangledName = "lib" + Actions.escapedPath(libraryPath.getPathString()); + String mnemonicMangling = ""; + if (mnemonic.indexOf("ST-") > -1) { + mnemonicMangling = mnemonic.substring(mnemonic.indexOf("ST-")) + "_"; + } + mangledName = "lib" + mnemonicMangling + Actions.escapedPath(libraryPath.getPathString()); } return mangledName; } 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 458e524ba63d70..2b556d51e69f90 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 @@ -18,6 +18,7 @@ import static com.google.common.collect.Iterables.getOnlyElement; import static com.google.common.truth.Truth.assertThat; +import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.devtools.build.lib.actions.ActionExecutionException; @@ -2021,4 +2022,116 @@ public void testCcLibraryProducesEmptyArchive() throws Exception { .toList()) .isNotEmpty(); } + + @Test + public void testRpathIsNotAddedWhenThereAreNoSoDeps() throws Exception { + AnalysisMock.get() + .ccSupport() + .setupCcToolchainConfig( + mockToolsConfig, + CcToolchainConfig.builder().withFeatures(CppRuleClasses.SUPPORTS_DYNAMIC_LINKER)); + + prepareCustomTransition(); + + scratch.file( + "BUILD", + "cc_binary(", + " name = 'main',", + " srcs = ['main.cc'],", + " linkstatic = 0,", + ")"); + + ConfiguredTarget main = getConfiguredTarget("//:main"); + Artifact mainBin = getBinArtifact("main", main); + CppLinkAction action = (CppLinkAction) getGeneratingAction(mainBin); + assertThat(Joiner.on(" ").join(action.getLinkCommandLine().arguments())).doesNotContain( + "-Wl,-rpath"); + } + + @Test + public void testRpathAndLinkPathsWithoutTransitions() throws Exception { + AnalysisMock.get() + .ccSupport() + .setupCcToolchainConfig( + mockToolsConfig, + CcToolchainConfig.builder().withFeatures(CppRuleClasses.SUPPORTS_DYNAMIC_LINKER)); + + prepareCustomTransition(); + useConfiguration("--cpu=k8", "--compilation_mode=fastbuild"); + + scratch.file( + "no-transition/BUILD", + "cc_binary(", + " name = 'main',", + " srcs = ['main.cc'],", + " linkstatic = 0,", + " deps = ['dep1'],", + ")", + "", + "cc_library(", + " name = 'dep1',", + " srcs = ['test.cc'],", + " hdrs = ['test.h'],", + ")"); + + ConfiguredTarget main = getConfiguredTarget("//no-transition:main"); + Artifact mainBin = getBinArtifact("main", main); + CppLinkAction action = (CppLinkAction) getGeneratingAction(mainBin); + List linkArgv = action.getLinkCommandLine().arguments(); + assertThat(linkArgv).contains("-Wl,-rpath,$ORIGIN/../_solib_k8/"); + assertThat(linkArgv).contains("-Lbazel-out/k8-fastbuild/bin/_solib_k8"); + assertThat(linkArgv).contains("-lno-transition_Slibdep1"); + assertThat(Joiner.on(" ").join(linkArgv)).doesNotContain( + "-Wl,-rpath,$ORIGIN/../_solib_k8/../../../k8-fastbuild-ST-"); + assertThat(Joiner.on(" ").join(linkArgv)).doesNotContain("-Lbazel-out/k8-fastbuild-ST-"); + assertThat(Joiner.on(" ").join(linkArgv)).doesNotContain("-lST-"); + } + + @Test + public void testRpathRootIsAddedEvenWithTransitionedDepsOnly() throws Exception { + AnalysisMock.get() + .ccSupport() + .setupCcToolchainConfig( + mockToolsConfig, + CcToolchainConfig.builder().withFeatures(CppRuleClasses.SUPPORTS_DYNAMIC_LINKER)); + + prepareCustomTransition(); + useConfiguration("--cpu=k8", "--compilation_mode=fastbuild"); + + scratch.file( + "transition/BUILD", + "load(':custom_transition.bzl', 'apply_custom_transition')", + "cc_binary(", + " name = 'main',", + " srcs = ['main.cc'],", + " linkstatic = 0,", + " deps = ['dep1'],", + ")", + "", + "apply_custom_transition(", + " name = 'dep1',", + " deps = [", + " ':dep2',", + " ],", + ")", + "", + "cc_library(", + " name = 'dep2',", + " srcs = ['test.cc'],", + " hdrs = ['test.h'],", + ")"); + + ConfiguredTarget main = getConfiguredTarget("//transition:main"); + Artifact mainBin = getBinArtifact("main", main); + CppLinkAction action = (CppLinkAction) getGeneratingAction(mainBin); + List linkArgv = action.getLinkCommandLine().arguments(); + assertThat(linkArgv).contains("-Wl,-rpath,$ORIGIN/../_solib_k8/"); + assertThat(Joiner.on(" ").join(linkArgv)).contains( + "-Wl,-rpath,$ORIGIN/../_solib_k8/../../../k8-fastbuild-ST-"); + assertThat(Joiner.on(" ").join(linkArgv)).contains("-Lbazel-out/k8-fastbuild-ST-"); + assertThat(Joiner.on(" ").join(linkArgv)).containsMatch("-lST-[0-9a-f]+_transition_Slibdep2"); + assertThat(Joiner.on(" ").join(linkArgv)).doesNotContain( + "-Lbazel-out/k8-fastbuild/bin/_solib_k8"); + assertThat(Joiner.on(" ").join(linkArgv)).doesNotContain("-ltransition_Slibdep2"); + } }