21
21
import com .google .common .collect .Iterables ;
22
22
import com .google .devtools .build .lib .actions .ActionRegistry ;
23
23
import com .google .devtools .build .lib .actions .Artifact ;
24
+ import com .google .devtools .build .lib .actions .ArtifactRoot ;
24
25
import com .google .devtools .build .lib .actions .CommandLineExpansionException ;
25
26
import com .google .devtools .build .lib .analysis .FileProvider ;
26
27
import com .google .devtools .build .lib .analysis .RuleContext ;
@@ -87,7 +88,9 @@ public CcLinkingOutputs getCcLinkingOutputs() {
87
88
private final BuildConfiguration configuration ;
88
89
private final CppConfiguration cppConfiguration ;
89
90
90
- private final List <Artifact > nonCodeLinkerInputs = new ArrayList <>();
91
+ private final NestedSetBuilder <Artifact > additionalLinkerInputsBuilder =
92
+ NestedSetBuilder .stableOrder ();
93
+ private final List <Artifact > linkerOutputs = new ArrayList <>();
91
94
private final List <String > linkopts = new ArrayList <>();
92
95
private final List <CcLinkingContext > ccLinkingContexts = new ArrayList <>();
93
96
private final NestedSetBuilder <Artifact > linkstamps = NestedSetBuilder .stableOrder ();
@@ -96,6 +99,7 @@ public CcLinkingOutputs getCcLinkingOutputs() {
96
99
@ Nullable private Artifact linkerOutputArtifact ;
97
100
private LinkTargetType staticLinkType = LinkTargetType .STATIC_LIBRARY ;
98
101
private LinkTargetType dynamicLinkType = LinkTargetType .NODEPS_DYNAMIC_LIBRARY ;
102
+ private NestedSet <Artifact > additionalLinkerInputs ;
99
103
private boolean neverlink ;
100
104
101
105
private boolean emitInterfaceSharedLibraries ;
@@ -194,19 +198,27 @@ public CcLinkingHelper addAdditionalLinkstampDefines(List<String> additionalLink
194
198
return this ;
195
199
}
196
200
197
- /** Adds the corresponding non-code files as linker inputs. */
201
+ /**
202
+ * Adds the corresponding non-code files as linker inputs.
203
+ *
204
+ * <p>TODO(bazel-team): There is no practical difference in non-code inputs and additional linker
205
+ * inputs in CppLinkActionBuilder. So these should be merged. Even before that happens, it's
206
+ * totally fine for nonCodeLinkerInputs to contains precompiled libraries.
207
+ */
198
208
public CcLinkingHelper addNonCodeLinkerInputs (List <Artifact > nonCodeLinkerInputs ) {
199
- for (Artifact nonCodeLinkerInput : nonCodeLinkerInputs ) {
200
- String basename = nonCodeLinkerInput .getFilename ();
201
- Preconditions .checkArgument (!Link .OBJECT_FILETYPES .matches (basename ));
202
- Preconditions .checkArgument (!Link .ARCHIVE_LIBRARY_FILETYPES .matches (basename ));
203
- Preconditions .checkArgument (!Link .SHARED_LIBRARY_FILETYPES .matches (basename ));
204
- this .nonCodeLinkerInputs .add (nonCodeLinkerInput );
205
- }
206
- if (fdoContext .getPropellerOptimizeInputFile () != null
207
- && fdoContext .getPropellerOptimizeInputFile ().getLdArtifact () != null ) {
208
- this .nonCodeLinkerInputs .add (fdoContext .getPropellerOptimizeInputFile ().getLdArtifact ());
209
- }
209
+ this .additionalLinkerInputsBuilder .addAll (nonCodeLinkerInputs );
210
+ return this ;
211
+ }
212
+
213
+ public CcLinkingHelper addTransitiveAdditionalLinkerInputs (
214
+ NestedSet <Artifact > additionalLinkerInputs ) {
215
+ this .additionalLinkerInputsBuilder .addTransitive (additionalLinkerInputs );
216
+ return this ;
217
+ }
218
+
219
+ /** TODO(bazel-team): Add to Starlark API */
220
+ public CcLinkingHelper addLinkerOutputs (List <Artifact > linkerOutputs ) {
221
+ this .linkerOutputs .addAll (linkerOutputs );
210
222
return this ;
211
223
}
212
224
@@ -361,6 +373,9 @@ public CcLinkingOutputs link(CcCompilationOutputs ccOutputs)
361
373
throws RuleErrorException , InterruptedException {
362
374
Preconditions .checkNotNull (ccOutputs );
363
375
376
+ Preconditions .checkState (additionalLinkerInputs == null );
377
+ additionalLinkerInputs = additionalLinkerInputsBuilder .build ();
378
+
364
379
// Create link actions (only if there are object files or if explicitly requested).
365
380
//
366
381
// On some systems, the linker gives an error message if there are no input files. Even with
@@ -401,7 +416,8 @@ public CcLinkingContext buildCcLinkingContextFromLibrariesToLink(
401
416
CcLinkingContext .LinkOptions .of (
402
417
ImmutableList .copyOf (linkopts ), symbolGenerator )))
403
418
.addLibraries (librariesToLink )
404
- .addNonCodeInputs (nonCodeLinkerInputs )
419
+ // additionalLinkerInputsBuilder not expected to be a big list for now.
420
+ .addNonCodeInputs (additionalLinkerInputsBuilder .build ().toList ())
405
421
.addLinkstamps (linkstampBuilder .build ())
406
422
.build ();
407
423
}
@@ -629,7 +645,6 @@ private CppLinkAction registerActionForStaticLibrary(
629
645
CppLinkAction action =
630
646
newLinkActionBuilder (linkedArtifact , linkTargetTypeUsedForNaming )
631
647
.addObjectFiles (ccOutputs .getObjectFiles (usePic ))
632
- .addNonCodeInputs (nonCodeLinkerInputs )
633
648
.addLtoCompilationContext (ccOutputs .getLtoCompilationContext ())
634
649
.setUsePicForLtoBackendActions (usePic )
635
650
.setLinkingMode (LinkingMode .STATIC )
@@ -694,7 +709,6 @@ private boolean createDynamicLinkAction(
694
709
.addActionInputs (linkActionInputs )
695
710
.addLinkopts (linkopts )
696
711
.addLinkopts (sonameLinkopts )
697
- .addNonCodeInputs (nonCodeLinkerInputs )
698
712
.addVariablesExtensions (variablesExtensions );
699
713
700
714
dynamicLinkActionBuilder .addObjectFiles (ccOutputs .getObjectFiles (usePic ));
@@ -829,28 +843,43 @@ private boolean createDynamicLinkAction(
829
843
830
844
private CppLinkActionBuilder newLinkActionBuilder (
831
845
Artifact outputArtifact , LinkTargetType linkType ) {
832
- return new CppLinkActionBuilder (
833
- ruleErrorConsumer ,
834
- actionConstructionContext ,
835
- label ,
836
- outputArtifact ,
837
- configuration ,
838
- ccToolchain ,
839
- fdoContext ,
840
- featureConfiguration ,
841
- semantics )
842
- .setGrepIncludes (grepIncludes )
843
- .setIsStampingEnabled (isStampingEnabled )
844
- .setTestOrTestOnlyTarget (isTestOrTestOnlyTarget )
845
- .setLinkType (linkType )
846
- .setLinkerFiles (
847
- (cppConfiguration .useSpecificToolFiles ()
848
- && linkType .linkerOrArchiver () == LinkerOrArchiver .ARCHIVER )
849
- ? ccToolchain .getArFiles ()
850
- : ccToolchain .getLinkerFiles ())
851
- .setLinkArtifactFactory (linkArtifactFactory )
852
- .setUseTestOnlyFlags (useTestOnlyFlags )
853
- .addExecutionInfo (executionInfo );
846
+ if (!additionalLinkerInputsBuilder .isEmpty ()) {
847
+ if (fdoContext .getPropellerOptimizeInputFile () != null
848
+ && fdoContext .getPropellerOptimizeInputFile ().getLdArtifact () != null ) {
849
+ this .additionalLinkerInputsBuilder .add (
850
+ fdoContext .getPropellerOptimizeInputFile ().getLdArtifact ());
851
+ }
852
+ }
853
+ CppLinkActionBuilder builder =
854
+ new CppLinkActionBuilder (
855
+ ruleErrorConsumer ,
856
+ actionConstructionContext ,
857
+ label ,
858
+ outputArtifact ,
859
+ configuration ,
860
+ ccToolchain ,
861
+ fdoContext ,
862
+ featureConfiguration ,
863
+ semantics )
864
+ .setGrepIncludes (grepIncludes )
865
+ .setMnemonic (
866
+ featureConfiguration .isEnabled (CppRuleClasses .LANG_OBJC ) ? "ObjcLink" : null )
867
+ .setIsStampingEnabled (isStampingEnabled )
868
+ .setTestOrTestOnlyTarget (isTestOrTestOnlyTarget )
869
+ .setLinkType (linkType )
870
+ .setLinkerFiles (
871
+ (cppConfiguration .useSpecificToolFiles ()
872
+ && linkType .linkerOrArchiver () == LinkerOrArchiver .ARCHIVER )
873
+ ? ccToolchain .getArFiles ()
874
+ : ccToolchain .getLinkerFiles ())
875
+ .setLinkArtifactFactory (linkArtifactFactory )
876
+ .setUseTestOnlyFlags (useTestOnlyFlags )
877
+ .addTransitiveActionInputs (additionalLinkerInputs )
878
+ .addExecutionInfo (executionInfo );
879
+ for (Artifact output : linkerOutputs ) {
880
+ builder .addActionOutput (output );
881
+ }
882
+ return builder ;
854
883
}
855
884
856
885
/**
@@ -876,12 +905,28 @@ private Artifact getLinkedArtifact(LinkTargetType linkTargetType) throws RuleErr
876
905
linkedName =
877
906
CppHelper .getArtifactNameForCategory (
878
907
ruleErrorConsumer , ccToolchain , linkTargetType .getLinkerOutput (), linkedName );
908
+
909
+ ArtifactRoot artifactRoot = configuration .getBinDirectory (label .getRepository ());
910
+ if (linkTargetType .equals (LinkTargetType .OBJC_FULLY_LINKED_ARCHIVE )) {
911
+ // TODO(blaze-team): This unfortunate editing of the name is here bedcause Objective-C rules
912
+ // were creating this type of archive without the lib prefix, unlike what the objective-c
913
+ // toolchain says with getArtifactNameForCategory.
914
+ // This can be fixed either when implicit outputs are removed from objc_library by keeping the
915
+ // lib prefix, or by editing the toolchain not to add it.
916
+ Preconditions .checkState (linkedName .startsWith ("lib" ));
917
+ linkedName = linkedName .substring (3 );
918
+ artifactRoot =
919
+ ((RuleContext ) actionConstructionContext ).getRule ().hasBinaryOutput ()
920
+ ? configuration .getBinDir ()
921
+ : configuration .getGenfilesDir ();
922
+ }
879
923
PathFragment artifactFragment =
880
924
PathFragment .create (label .getName ()).getParentDirectory ().getRelative (linkedName );
881
925
882
926
return CppHelper .getLinkedArtifact (
883
927
label ,
884
928
actionConstructionContext ,
929
+ artifactRoot ,
885
930
configuration ,
886
931
linkTargetType ,
887
932
linkedArtifactNameSuffix ,
0 commit comments