diff options
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java | 68 |
1 files changed, 63 insertions, 5 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java index 38aa8b9299..13866e81d5 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java @@ -18,6 +18,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.devtools.build.lib.actions.Artifact; +import com.google.devtools.build.lib.actions.FailAction; import com.google.devtools.build.lib.analysis.AnalysisEnvironment; import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.analysis.RuleContext; @@ -26,7 +27,9 @@ import com.google.devtools.build.lib.analysis.config.BuildConfiguration; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.packages.BuildType; +import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException; import com.google.devtools.build.lib.rules.cpp.CcCompilationOutputs.Builder; +import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.ExpansionException; import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration; import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Variables.VariablesExtension; import com.google.devtools.build.lib.rules.cpp.CppCompileAction.DotdFile; @@ -737,6 +740,49 @@ public final class CppModel { } /** + * Returns the linked artifact resulting from a linking of the given type. Consults the feature + * configuration to obtain an action_config that provides the artifact. If the feature + * configuration provides no artifact, uses a default. + * + * <p>We cannot assume that the feature configuration contains an action_config for the link + * action, because the linux link action depends on hardcoded values in + * LinkCommandLine.getRawLinkArgv(), which are applied on the condition that an action_config is + * not present. + * TODO(b/30393154): Assert that the given link action has an action_config. + * + * @throws RuleErrorException + */ + private Artifact getLinkedArtifact(LinkTargetType linkTargetType) throws RuleErrorException { + Artifact result = null; + Artifact linuxDefault = CppHelper.getLinuxLinkedArtifact(ruleContext, linkTargetType); + CcToolchainFeatures toolchain = CppHelper.getToolchain(ruleContext).getFeatures(); + + if (toolchain.hasPatternForArtifactCategory(linkTargetType.getLinkerOutput())) { + try { + result = toolchain.getArtifactForCategory(linkTargetType.getLinkerOutput(), ruleContext); + } catch (ExpansionException e) { + ruleContext.throwWithRuleError(e.getMessage()); + } + } else { + return linuxDefault; + } + // If the linked artifact is not the linux default, then a FailAction is generated for the + // linux default to satisfy the requirement of the implicit output. + // TODO(b/30132703): Remove the implicit outputs of cc_library. + if (!result.equals(linuxDefault)) { + ruleContext.registerAction( + new FailAction( + ruleContext.getActionOwner(), + ImmutableList.of(linuxDefault), + String.format( + "the given toolchain supports creation of %s instead of %s", + linuxDefault.getExecPathString(), result.getExecPathString()))); + } + + return result; + } + + /** * Constructs the C++ linker actions. It generally generates two actions, one for a static library * and one for a dynamic library. If PIC is required for shared libraries, but not for binaries, * it additionally creates a third action to generate a PIC static library. @@ -745,8 +791,11 @@ public final class CppModel { * can be used for linking, but doesn't contain any executable code. This increases the number of * cache hits for link actions. Call {@link #setAllowInterfaceSharedObjects(boolean)} to enable * this behavior. + * + * @throws RuleErrorException */ - public CcLinkingOutputs createCcLinkActions(CcCompilationOutputs ccOutputs) { + public CcLinkingOutputs createCcLinkActions(CcCompilationOutputs ccOutputs) + throws RuleErrorException { // 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 setLinkType(). Preconditions.checkState(linkType.isStaticLibraryLink(), "can only handle static links"); @@ -775,7 +824,11 @@ public final class CppModel { // // 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. - Artifact linkedArtifact = CppHelper.getLinkedArtifact(ruleContext, linkType); + + // If the crosstool is configured to select an output artifact, we use that selection. + // Otherwise, we use linux defaults. + Artifact linkedArtifact = getLinkedArtifact(linkType); + CppLinkAction maybePicAction = newLinkActionBuilder(linkedArtifact) .addNonLibraryInputs(ccOutputs.getObjectFiles(usePicForBinaries)) @@ -796,7 +849,10 @@ public final class CppModel { ? LinkTargetType.ALWAYS_LINK_PIC_STATIC_LIBRARY : LinkTargetType.PIC_STATIC_LIBRARY; - Artifact picArtifact = CppHelper.getLinkedArtifact(ruleContext, picLinkType); + // 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) .addNonLibraryInputs(ccOutputs.getObjectFiles(true)) @@ -817,7 +873,9 @@ public final class CppModel { // Create dynamic library. Artifact soImpl; if (soImplArtifact == null) { - soImpl = CppHelper.getLinkedArtifact(ruleContext, LinkTargetType.DYNAMIC_LIBRARY); + // If the crosstool is configured to select an output artifact, we use that selection. + // Otherwise, we use linux defaults. + soImpl = getLinkedArtifact(LinkTargetType.DYNAMIC_LIBRARY); } else { soImpl = soImplArtifact; } @@ -826,7 +884,7 @@ public final class CppModel { Artifact soInterface = null; if (cppConfiguration.useInterfaceSharedObjects() && allowInterfaceSharedObjects) { soInterface = - CppHelper.getLinkedArtifact(ruleContext, LinkTargetType.INTERFACE_DYNAMIC_LIBRARY); + CppHelper.getLinuxLinkedArtifact(ruleContext, LinkTargetType.INTERFACE_DYNAMIC_LIBRARY); sonameLinkopts = ImmutableList.of("-Wl,-soname=" + SolibSymlinkAction.getDynamicLibrarySoname(soImpl.getRootRelativePath(), false)); } |