@@ -61,6 +61,7 @@ public class LibrariesToLinkCollector {
61
61
private final RuleErrorConsumer ruleErrorConsumer ;
62
62
private final Artifact output ;
63
63
private final String workspaceName ;
64
+ private final Artifact dynamicLibrarySolibSymlinkOutput ;
64
65
65
66
public LibrariesToLinkCollector (
66
67
boolean isNativeDeps ,
@@ -79,7 +80,8 @@ public LibrariesToLinkCollector(
79
80
Iterable <LinkerInput > linkerInputs ,
80
81
boolean needWholeArchive ,
81
82
RuleErrorConsumer ruleErrorConsumer ,
82
- String workspaceName ) {
83
+ String workspaceName ,
84
+ Artifact dynamicLibrarySolibSymlinkOutput ) {
83
85
this .isNativeDeps = isNativeDeps ;
84
86
this .cppConfiguration = cppConfiguration ;
85
87
this .ccToolchainProvider = toolchain ;
@@ -95,6 +97,7 @@ public LibrariesToLinkCollector(
95
97
this .ruleErrorConsumer = ruleErrorConsumer ;
96
98
this .output = output ;
97
99
this .workspaceName = workspaceName ;
100
+ this .dynamicLibrarySolibSymlinkOutput = dynamicLibrarySolibSymlinkOutput ;
98
101
99
102
needToolchainLibrariesRpath =
100
103
toolchainLibrariesSolibDir != null
@@ -164,81 +167,88 @@ private NestedSet<String> collectToolchainRuntimeLibrarySearchDirectories(
164
167
}
165
168
166
169
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 ();
224
170
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 );
235
175
}
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
+ }
242
252
}
243
253
244
254
return solibParents .build ();
0 commit comments