@@ -61,6 +61,7 @@ public class LibrariesToLinkCollector {
6161 private final RuleErrorConsumer ruleErrorConsumer ;
6262 private final Artifact output ;
6363 private final String workspaceName ;
64+ private final Artifact dynamicLibrarySolibSymlinkOutput ;
6465
6566 public LibrariesToLinkCollector (
6667 boolean isNativeDeps ,
@@ -79,7 +80,8 @@ public LibrariesToLinkCollector(
7980 Iterable <LinkerInput > linkerInputs ,
8081 boolean needWholeArchive ,
8182 RuleErrorConsumer ruleErrorConsumer ,
82- String workspaceName ) {
83+ String workspaceName ,
84+ Artifact dynamicLibrarySolibSymlinkOutput ) {
8385 this .isNativeDeps = isNativeDeps ;
8486 this .cppConfiguration = cppConfiguration ;
8587 this .ccToolchainProvider = toolchain ;
@@ -95,6 +97,7 @@ public LibrariesToLinkCollector(
9597 this .ruleErrorConsumer = ruleErrorConsumer ;
9698 this .output = output ;
9799 this .workspaceName = workspaceName ;
100+ this .dynamicLibrarySolibSymlinkOutput = dynamicLibrarySolibSymlinkOutput ;
98101
99102 needToolchainLibrariesRpath =
100103 toolchainLibrariesSolibDir != null
@@ -164,81 +167,88 @@ private NestedSet<String> collectToolchainRuntimeLibrarySearchDirectories(
164167 }
165168
166169 private ImmutableList <String > findPotentialSolibParents () {
167- // The runtime location of the solib directory relative to the binary depends on four factors:
168- //
169- // * whether the binary is contained in the main repository or an external repository;
170- // * whether the binary is executed directly or from a runfiles tree;
171- // * whether the binary is staged as a symlink (sandboxed execution; local execution if the
172- // binary is in the runfiles of another target) or a regular file (remote execution) - the
173- // dynamic linker follows sandbox and runfiles symlinks into its location under the
174- // unsandboxed execroot, which thus becomes the effective $ORIGIN;
175- // * whether --experimental_sibling_repository_layout is enabled or not.
176- //
177- // The rpaths emitted into the binary thus have to cover the following cases (assuming that
178- // the binary target is located in the pkg `pkg` and has name `file`) for the directory used
179- // as $ORIGIN by the dynamic linker and the directory containing the solib directories:
180- //
181- // 1. main, direct, symlink:
182- // $ORIGIN: $EXECROOT/pkg
183- // solib root: $EXECROOT
184- // 2. main, direct, regular file:
185- // $ORIGIN: $EXECROOT/pkg
186- // solib root: $EXECROOT/pkg/file.runfiles/main_repo
187- // 3. main, runfiles, symlink:
188- // $ORIGIN: $EXECROOT/pkg
189- // solib root: $EXECROOT
190- // 4. main, runfiles, regular file:
191- // $ORIGIN: other_target.runfiles/main_repo/pkg
192- // solib root: other_target.runfiles/main_repo
193- // 5a. external, direct, symlink:
194- // $ORIGIN: $EXECROOT/external/other_repo/pkg
195- // solib root: $EXECROOT
196- // 5b. external, direct, symlink, with --experimental_sibling_repository_layout:
197- // $ORIGIN: $EXECROOT/../other_repo/pkg
198- // solib root: $EXECROOT/../other_repo
199- // 6a. external, direct, regular file:
200- // $ORIGIN: $EXECROOT/external/other_repo/pkg
201- // solib root: $EXECROOT/external/other_repo/pkg/file.runfiles/main_repo
202- // 6b. external, direct, regular file, with --experimental_sibling_repository_layout:
203- // $ORIGIN: $EXECROOT/../other_repo/pkg
204- // solib root: $EXECROOT/../other_repo/pkg/file.runfiles/other_repo
205- // 7a. external, runfiles, symlink:
206- // $ORIGIN: $EXECROOT/external/other_repo/pkg
207- // solib root: $EXECROOT
208- // 7b. external, runfiles, symlink, with --experimental_sibling_repository_layout:
209- // $ORIGIN: $EXECROOT/../other_repo/pkg
210- // solib root: $EXECROOT/../other_repo
211- // 8a. external, runfiles, regular file:
212- // $ORIGIN: other_target.runfiles/some_repo/pkg
213- // solib root: other_target.runfiles/main_repo
214- // 8b. external, runfiles, regular file, with --experimental_sibling_repository_layout:
215- // $ORIGIN: other_target.runfiles/some_repo/pkg
216- // solib root: other_target.runfiles/some_repo
217- //
218- // Cases 1, 3, 4, 5, 7, and 8b are covered by an rpath that walks up the root relative path.
219- // Cases 2 and 6 covered by walking into file.runfiles/main_repo.
220- // Case 8a is covered by walking up some_repo/pkg and then into main_repo.
221- boolean isExternal =
222- output .getRunfilesPath ().startsWith (LabelConstants .EXTERNAL_RUNFILES_PATH_PREFIX );
223- boolean usesLegacyRepositoryLayout = output .getRoot ().isLegacy ();
224170 ImmutableList .Builder <String > solibParents = ImmutableList .builder ();
225- // Handles cases 1, 3, 4, 5, and 7.
226- solibParents .add ("../" .repeat (output .getRootRelativePath ().segmentCount () - 1 ));
227- // Handle cases 2 and 6.
228- String solibRepositoryName ;
229- if (isExternal && !usesLegacyRepositoryLayout ) {
230- // Case 6b
231- solibRepositoryName = output .getRunfilesPath ().getSegment (1 );
232- } else {
233- // Cases 2 and 6a
234- solibRepositoryName = workspaceName ;
171+ ImmutableList .Builder <Artifact > outputs = ImmutableList .builder ();
172+ outputs .add (output );
173+ if (dynamicLibrarySolibSymlinkOutput != null ) {
174+ outputs .add (dynamicLibrarySolibSymlinkOutput );
235175 }
236- solibParents .add (output .getFilename () + ".runfiles/" + solibRepositoryName + "/" );
237- if (isExternal && usesLegacyRepositoryLayout ) {
238- // Handles case 8a. The runfiles path is of the form ../some_repo/pkg/file and we need to
239- // walk up some_repo/pkg and then down into main_repo.
240- solibParents .add (
241- "../" .repeat (output .getRunfilesPath ().segmentCount () - 2 ) + workspaceName + "/" );
176+ for (Artifact output : outputs .build ()) {
177+ // The runtime location of the solib directory relative to the binary depends on four factors:
178+ //
179+ // * whether the binary is contained in the main repository or an external repository;
180+ // * whether the binary is executed directly or from a runfiles tree;
181+ // * whether the binary is staged as a symlink (sandboxed execution; local execution if the
182+ // binary is in the runfiles of another target) or a regular file (remote execution) - the
183+ // dynamic linker follows sandbox and runfiles symlinks into its location under the
184+ // unsandboxed execroot, which thus becomes the effective $ORIGIN;
185+ // * whether --experimental_sibling_repository_layout is enabled or not.
186+ //
187+ // The rpaths emitted into the binary thus have to cover the following cases (assuming that
188+ // the binary target is located in the pkg `pkg` and has name `file`) for the directory used
189+ // as $ORIGIN by the dynamic linker and the directory containing the solib directories:
190+ //
191+ // 1. main, direct, symlink:
192+ // $ORIGIN: $EXECROOT/pkg
193+ // solib root: $EXECROOT
194+ // 2. main, direct, regular file:
195+ // $ORIGIN: $EXECROOT/pkg
196+ // solib root: $EXECROOT/pkg/file.runfiles/main_repo
197+ // 3. main, runfiles, symlink:
198+ // $ORIGIN: $EXECROOT/pkg
199+ // solib root: $EXECROOT
200+ // 4. main, runfiles, regular file:
201+ // $ORIGIN: other_target.runfiles/main_repo/pkg
202+ // solib root: other_target.runfiles/main_repo
203+ // 5a. external, direct, symlink:
204+ // $ORIGIN: $EXECROOT/external/other_repo/pkg
205+ // solib root: $EXECROOT
206+ // 5b. external, direct, symlink, with --experimental_sibling_repository_layout:
207+ // $ORIGIN: $EXECROOT/../other_repo/pkg
208+ // solib root: $EXECROOT/../other_repo
209+ // 6a. external, direct, regular file:
210+ // $ORIGIN: $EXECROOT/external/other_repo/pkg
211+ // solib root: $EXECROOT/external/other_repo/pkg/file.runfiles/main_repo
212+ // 6b. external, direct, regular file, with --experimental_sibling_repository_layout:
213+ // $ORIGIN: $EXECROOT/../other_repo/pkg
214+ // solib root: $EXECROOT/../other_repo/pkg/file.runfiles/other_repo
215+ // 7a. external, runfiles, symlink:
216+ // $ORIGIN: $EXECROOT/external/other_repo/pkg
217+ // solib root: $EXECROOT
218+ // 7b. external, runfiles, symlink, with --experimental_sibling_repository_layout:
219+ // $ORIGIN: $EXECROOT/../other_repo/pkg
220+ // solib root: $EXECROOT/../other_repo
221+ // 8a. external, runfiles, regular file:
222+ // $ORIGIN: other_target.runfiles/some_repo/pkg
223+ // solib root: other_target.runfiles/main_repo
224+ // 8b. external, runfiles, regular file, with --experimental_sibling_repository_layout:
225+ // $ORIGIN: other_target.runfiles/some_repo/pkg
226+ // solib root: other_target.runfiles/some_repo
227+ //
228+ // Cases 1, 3, 4, 5, 7, and 8b are covered by an rpath that walks up the root relative path.
229+ // Cases 2 and 6 covered by walking into file.runfiles/main_repo.
230+ // Case 8a is covered by walking up some_repo/pkg and then into main_repo.
231+ boolean isExternal =
232+ output .getRunfilesPath ().startsWith (LabelConstants .EXTERNAL_RUNFILES_PATH_PREFIX );
233+ boolean usesLegacyRepositoryLayout = output .getRoot ().isLegacy ();
234+ // Handles cases 1, 3, 4, 5, and 7.
235+ solibParents .add ("../" .repeat (output .getRootRelativePath ().segmentCount () - 1 ));
236+ // Handle cases 2 and 6.
237+ String solibRepositoryName ;
238+ if (isExternal && !usesLegacyRepositoryLayout ) {
239+ // Case 6b
240+ solibRepositoryName = output .getRunfilesPath ().getSegment (1 );
241+ } else {
242+ // Cases 2 and 6a
243+ solibRepositoryName = workspaceName ;
244+ }
245+ solibParents .add (output .getFilename () + ".runfiles/" + solibRepositoryName + "/" );
246+ if (isExternal && usesLegacyRepositoryLayout ) {
247+ // Handles case 8a. The runfiles path is of the form ../some_repo/pkg/file and we need to
248+ // walk up some_repo/pkg and then down into main_repo.
249+ solibParents .add (
250+ "../" .repeat (output .getRunfilesPath ().segmentCount () - 2 ) + workspaceName + "/" );
251+ }
242252 }
243253
244254 return solibParents .build ();
0 commit comments