diff options
author | 2018-06-04 03:29:40 -0700 | |
---|---|---|
committer | 2018-06-04 03:31:21 -0700 | |
commit | c581144266d43f49ea1b8a11c86204b2f7997956 (patch) | |
tree | 04b0e3c68600b541fd3dc02551c2ef4a803262ed /src/main/java/com/google/devtools/build | |
parent | 63748e4f0307b00f0cb91864d00f58ce54132689 (diff) |
C++: Makes JavaWrapCc use CcLinkingHelper
It doesn't use CcLinkParamsStore and CppLinkAction directly anymore.
RELNOTES:none
PiperOrigin-RevId: 199107747
Diffstat (limited to 'src/main/java/com/google/devtools/build')
4 files changed, 102 insertions, 82 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java index eb3fb4747d..b68f6b13ab 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java @@ -274,8 +274,8 @@ public abstract class CcBinary implements RuleConfiguredTargetFactory { ruleContext.getConfiguration()) .fromCommon(common) .addDeps(ImmutableList.of(CppHelper.mallocForTarget(ruleContext))) - .enableInterfaceSharedObjects(); - linkingHelper.setStaticLinkType(LinkTargetType.STATIC_LIBRARY); + .enableInterfaceSharedObjects() + .setAlwayslink(false); ccLinkingOutputs = linkingHelper.link(ccCompilationOutputs, ccCompilationContext).getCcLinkingOutputs(); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java index e8e84dfc48..6d2fb346e6 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java @@ -95,11 +95,13 @@ public abstract class CcLibrary implements RuleConfiguredTargetFactory { public ConfiguredTarget create(RuleContext context) throws InterruptedException, RuleErrorException, ActionConflictException { RuleConfiguredTargetBuilder builder = new RuleConfiguredTargetBuilder(context); - LinkTargetType staticLinkType = getStaticLinkType(context); boolean linkStatic = context.attributes().get("linkstatic", Type.BOOLEAN); - init(semantics, context, builder, - /* additionalCopts= */ImmutableList.of(), - staticLinkType, + init( + semantics, + context, + builder, + /* additionalCopts= */ ImmutableList.of(), + context.attributes().get("alwayslink", Type.BOOLEAN), /* neverLink= */ false, linkStatic, /* addDynamicRuntimeInputArtifactsToRunfiles= */ false); @@ -111,7 +113,7 @@ public abstract class CcLibrary implements RuleConfiguredTargetFactory { RuleContext ruleContext, RuleConfiguredTargetBuilder targetBuilder, ImmutableList<String> additionalCopts, - LinkTargetType staticLinkType, + boolean alwaysLink, boolean neverLink, boolean linkStatic, boolean addDynamicRuntimeInputArtifactsToRunfiles) @@ -167,7 +169,7 @@ public abstract class CcLibrary implements RuleConfiguredTargetFactory { // between Bazel and Blaze. .setGenerateLinkActionsIfEmpty( ruleContext.getRule().getImplicitOutputsFunction() != ImplicitOutputsFunction.NONE) - .setStaticLinkType(staticLinkType) + .setAlwayslink(alwaysLink) .setNeverLink(neverLink) .addLinkstamps(ruleContext.getPrerequisites("linkstamp", Mode.TARGET)); @@ -418,15 +420,6 @@ public abstract class CcLibrary implements RuleConfiguredTargetFactory { return artifactsToForceBuilder.build(); } - /** - * Returns the type of the generated static library. - */ - private static LinkTargetType getStaticLinkType(RuleContext context) { - return context.attributes().get("alwayslink", Type.BOOLEAN) - ? LinkTargetType.ALWAYS_LINK_STATIC_LIBRARY - : LinkTargetType.STATIC_LIBRARY; - } - private static void warnAboutEmptyLibraries(RuleContext ruleContext, CcCompilationOutputs ccCompilationOutputs, boolean linkstaticAttribute) { 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 919bd87407..3a0e65dada 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 @@ -100,7 +100,7 @@ public final class CcLinkingHelper { } @Override - public CcLinkingInfo getCcLinkParamsInfo() { + public CcLinkingInfo getCcLinkingInfo() { return (CcLinkingInfo) providers.getProvider(CcLinkingInfo.PROVIDER.getKey()); } @@ -152,6 +152,7 @@ public final class CcLinkingHelper { private final List<Artifact> nonCodeLinkerInputs = new ArrayList<>(); private final List<String> linkopts = new ArrayList<>(); private final List<TransitiveInfoCollection> deps = new ArrayList<>(); + private final List<CcLinkingInfo> ccLinkingInfos = new ArrayList<>(); private final NestedSetBuilder<Artifact> linkstamps = NestedSetBuilder.stableOrder(); private final List<Artifact> linkActionInputs = new ArrayList<>(); @@ -170,6 +171,7 @@ public final class CcLinkingHelper { private boolean emitInterfaceSharedObjects; private boolean shouldCreateDynamicLibrary = true; private boolean shouldCreateStaticLibraries = true; + private boolean willOnlyBeLinkedIntoDynamicLibraries; private final List<VariablesExtension> variablesExtensions = new ArrayList<>(); private final FeatureConfiguration featureConfiguration; @@ -267,9 +269,17 @@ public final class CcLinkingHelper { * (like from a "deps" attribute) and also implicit dependencies on runtime libraries. */ public CcLinkingHelper addDeps(Iterable<? extends TransitiveInfoCollection> deps) { - for (TransitiveInfoCollection dep : deps) { - this.deps.add(dep); - } + Iterables.addAll(this.ccLinkingInfos, AnalysisUtils.getProviders(deps, CcLinkingInfo.PROVIDER)); + Iterables.addAll(this.deps, deps); + return this; + } + + /** + * Adds additional {@link CcLinkingInfo} that will be used everywhere where CcLinkingInfos were + * obtained from deps. + */ + public CcLinkingHelper addCcLinkingInfos(Iterable<CcLinkingInfo> ccLinkingInfos) { + Iterables.addAll(this.ccLinkingInfos, ccLinkingInfos); return this; } @@ -325,8 +335,10 @@ public final class CcLinkingHelper { /** * Directly set the link type. This can be used instead of {@link #setAlwayslink}. Setting - * anything other than a static link causes this class to skip the link action creation. + * anything other than a static link causes this class to skip the link action creation. This + * exists only for Objective-C. */ + @Deprecated public CcLinkingHelper setStaticLinkType(LinkTargetType linkType) { Preconditions.checkNotNull(linkType); Preconditions.checkState(linkType.linkerOrArchiver() == LinkerOrArchiver.ARCHIVER); @@ -448,7 +460,7 @@ public final class CcLinkingHelper { // generate any link actions, effectively disabling header checking in some cases. if (linkType.linkerOrArchiver() == LinkerOrArchiver.ARCHIVER) { // TODO(bazel-team): This can't create the link action for a cc_binary yet. - ccLinkingOutputs = createCcLinkActions(ccOutputs, nonCodeLinkerInputs); + ccLinkingOutputs = createCcLinkActions(ccOutputs); } } CcLinkingOutputs originalLinkingOutputs = ccLinkingOutputs; @@ -624,7 +636,9 @@ public final class CcLinkingHelper { protected void collect( CcLinkParams.Builder builder, boolean linkingStatically, boolean linkShared) { builder.addLinkstamps(linkstamps.build(), ccCompilationContext); - builder.addTransitiveTargets(deps, CcLinkParamsStore.TO_LINK_PARAMS); + for (CcLinkingInfo ccLinkingInfo : ccLinkingInfos) { + builder.add(ccLinkingInfo.getCcLinkParamsStore()); + } if (!neverlink) { builder.addLibraries( ccLinkingOutputs.getPreferredLibraries( @@ -661,7 +675,7 @@ public final class CcLinkingHelper { } NestedSetBuilder<Artifact> builder = NestedSetBuilder.stableOrder(); - for (CcLinkingInfo dep : AnalysisUtils.getProviders(deps, CcLinkingInfo.PROVIDER)) { + for (CcLinkingInfo dep : ccLinkingInfos) { CcExecutionDynamicLibraries ccExecutionDynamicLibraries = dep.getCcExecutionDynamicLibraries(); if (ccExecutionDynamicLibraries != null) { @@ -686,8 +700,7 @@ public final class CcLinkingHelper { * * @throws RuleErrorException */ - private CcLinkingOutputs createCcLinkActions( - CcCompilationOutputs ccOutputs, Iterable<Artifact> nonCodeLinkerInputs) + private CcLinkingOutputs createCcLinkActions(CcCompilationOutputs ccOutputs) throws RuleErrorException, InterruptedException { // For now only handle static links. Note that the dynamic library link below ignores linkType. // TODO(bazel-team): Either support non-static links or move this check to setStaticLinkType(). @@ -713,13 +726,7 @@ public final class CcLinkingHelper { if (shouldCreateStaticLibraries) { createStaticLibraries( - result, - env, - usePicForBinaries, - usePicForDynamicLibs, - libraryIdentifier, - ccOutputs, - nonCodeLinkerInputs); + result, env, usePicForBinaries, usePicForDynamicLibs, libraryIdentifier, ccOutputs); } if (shouldCreateDynamicLibrary) { @@ -729,80 +736,100 @@ public final class CcLinkingHelper { return result.build(); } + public CcLinkingHelper setWillOnlyBeLinkedIntoDynamicLibraries( + boolean willOnlyBeLinkedIntoDynamicLibraries) { + this.willOnlyBeLinkedIntoDynamicLibraries = willOnlyBeLinkedIntoDynamicLibraries; + return this; + } + private void createStaticLibraries( CcLinkingOutputs.Builder result, AnalysisEnvironment env, boolean usePicForBinaries, boolean usePicForDynamicLibs, String libraryIdentifier, - CcCompilationOutputs ccOutputs, - Iterable<Artifact> nonCodeLinkerInputs) + CcCompilationOutputs ccOutputs) throws RuleErrorException, InterruptedException { // Create static library (.a). The linkType only reflects whether the library is alwayslink or - // not. The PIC-ness is determined by whether we need to use PIC or not. There are three cases + // not. The PIC-ness is determined by whether we need to use PIC or not. There are four cases // for (usePicForDynamicLibs usePicForBinaries): // - // (1) (false false) -> no pic code + // (1) (false false) -> no pic code is when toolchain and cppOptions don't need pic code for + // dynamic libraries or binaries // (2) (true false) -> shared libraries as pic, but not binaries // (3) (true true) -> both shared libraries and binaries as pic - // + // (4) (false true) -> only pic files generated when toolchain needs pic for shared libraries + // and {@link #willOnlyBeLinkedIntoDynamicLibraries} is set to true. + // In case (3), we always need PIC, so only create one static library containing the PIC - // object - // files. The name therefore does not match the content. + // object files. The name therefore does not match the content. // // Presumably, it is done this way because the .a file is an implicit output of every - // cc_library - // rule, so we can't use ".pic.a" that in the always-PIC case. + // cc_library rule, so we can't use ".pic.a" that in the always-PIC case. // If the crosstool is configured to select an output artifact, we use that selection. // Otherwise, we use linux defaults. - Artifact linkedArtifact = getLinkedArtifact(linkType); + boolean createPicAction; + boolean createNoPicAction; + if (willOnlyBeLinkedIntoDynamicLibraries) { + createPicAction = usePicForDynamicLibs; + createNoPicAction = !usePicForDynamicLibs; + } else { + createPicAction = usePicForBinaries || usePicForDynamicLibs; + createNoPicAction = !usePicForBinaries; + } + + if (createPicAction) { + LinkTargetType linkTargetTypeUsedForNaming; + if (!createNoPicAction) { + // Only PIC library created, name does not match content. + linkTargetTypeUsedForNaming = linkType; + } else { + linkTargetTypeUsedForNaming = + (linkType == LinkTargetType.ALWAYS_LINK_STATIC_LIBRARY) + ? LinkTargetType.ALWAYS_LINK_PIC_STATIC_LIBRARY + : LinkTargetType.PIC_STATIC_LIBRARY; + } + result.addPicStaticLibrary( + registerActionForStaticLibrary( + linkTargetTypeUsedForNaming, + ccOutputs, + /* usePic= */ true, + libraryIdentifier, + env) + .getOutputLibrary()); + } - CppLinkAction maybePicAction = + if (createNoPicAction) { + result.addStaticLibrary( + registerActionForStaticLibrary( + linkType, ccOutputs, /* usePic */ false, libraryIdentifier, env) + .getOutputLibrary()); + } + } + + private CppLinkAction registerActionForStaticLibrary( + LinkTargetType linkTargetTypeUsedForNaming, + CcCompilationOutputs ccOutputs, + boolean usePic, + String libraryIdentifier, + AnalysisEnvironment env) + throws RuleErrorException, InterruptedException { + Artifact linkedArtifact = getLinkedArtifact(linkTargetTypeUsedForNaming); + CppLinkAction action = newLinkActionBuilder(linkedArtifact) - .addObjectFiles(ccOutputs.getObjectFiles(usePicForBinaries)) + .addObjectFiles(ccOutputs.getObjectFiles(usePic)) .addNonCodeInputs(nonCodeLinkerInputs) .addLtoBitcodeFiles(ccOutputs.getLtoBitcodeFiles()) - .setUsePicForLtoBackendActions(usePicForBinaries) - .setLinkType(linkType) + .setUsePicForLtoBackendActions(usePic) + .setLinkType(linkTargetTypeUsedForNaming) .setLinkingMode(LinkingMode.LEGACY_FULLY_STATIC) .addActionInputs(linkActionInputs) .setLibraryIdentifier(libraryIdentifier) .addVariablesExtensions(variablesExtensions) .build(); - env.registerAction(maybePicAction); - if (usePicForBinaries) { - result.addPicStaticLibrary(maybePicAction.getOutputLibrary()); - } else { - result.addStaticLibrary(maybePicAction.getOutputLibrary()); - // Create a second static library (.pic.a). Only in case (2) do we need both PIC and non-PIC - // static libraries. In that case, the first static library contains the non-PIC code, and - // this - // one contains the PIC code, so the names match the content. - if (usePicForDynamicLibs) { - LinkTargetType picLinkType = - (linkType == LinkTargetType.ALWAYS_LINK_STATIC_LIBRARY) - ? LinkTargetType.ALWAYS_LINK_PIC_STATIC_LIBRARY - : LinkTargetType.PIC_STATIC_LIBRARY; - - // If the crosstool is configured to select an output artifact, we use that selection. - // Otherwise, we use linux defaults. - Artifact picArtifact = getLinkedArtifact(picLinkType); - CppLinkAction picAction = - newLinkActionBuilder(picArtifact) - .addObjectFiles(ccOutputs.getObjectFiles(/* usePic= */ true)) - .addLtoBitcodeFiles(ccOutputs.getLtoBitcodeFiles()) - .setUsePicForLtoBackendActions(true) - .setLinkType(picLinkType) - .setLinkingMode(LinkingMode.LEGACY_FULLY_STATIC) - .addActionInputs(linkActionInputs) - .setLibraryIdentifier(libraryIdentifier) - .addVariablesExtensions(variablesExtensions) - .build(); - env.registerAction(picAction); - result.addPicStaticLibrary(picAction.getOutputLibrary()); - } - } + env.registerAction(action); + return action; } private void createDynamicLibrary( diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/LinkingInfoApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/LinkingInfoApi.java index cf708412cc..d572708906 100644 --- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/LinkingInfoApi.java +++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/LinkingInfoApi.java @@ -30,5 +30,5 @@ import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory; public interface LinkingInfoApi { @SkylarkCallable(name = "cc_linking_info", documented = false) - public CcLinkingInfoApi getCcLinkParamsInfo(); + public CcLinkingInfoApi getCcLinkingInfo(); } |