use of com.google.devtools.build.lib.actions.FailAction in project bazel by bazelbuild.
the class CcLibrary method init.
public static void init(CppSemantics semantics, RuleContext ruleContext, RuleConfiguredTargetBuilder targetBuilder, LinkTargetType linkType, boolean neverLink, boolean linkStatic, boolean collectLinkstamp, boolean addDynamicRuntimeInputArtifactsToRunfiles) throws RuleErrorException, InterruptedException {
final CcCommon common = new CcCommon(ruleContext);
CcToolchainProvider ccToolchain = common.getToolchain();
FdoSupportProvider fdoSupport = common.getFdoSupport();
FeatureConfiguration featureConfiguration = CcCommon.configureFeatures(ruleContext, ccToolchain);
PrecompiledFiles precompiledFiles = new PrecompiledFiles(ruleContext);
semantics.validateAttributes(ruleContext);
if (ruleContext.hasErrors()) {
return;
}
CcLibraryHelper helper = new CcLibraryHelper(ruleContext, semantics, featureConfiguration, ccToolchain, fdoSupport).fromCommon(common).addLinkopts(common.getLinkopts()).addSources(common.getSources()).addPublicHeaders(common.getHeaders()).enableCcNativeLibrariesProvider().enableCompileProviders().enableInterfaceSharedObjects().setGenerateLinkActionsIfEmpty(ruleContext.getRule().getImplicitOutputsFunction() != ImplicitOutputsFunction.NONE).setLinkType(linkType).setNeverLink(neverLink).addPrecompiledFiles(precompiledFiles);
if (collectLinkstamp) {
helper.addLinkstamps(ruleContext.getPrerequisites("linkstamp", Mode.TARGET));
}
Artifact soImplArtifact = null;
boolean supportsDynamicLinker = ruleContext.getFragment(CppConfiguration.class).supportsDynamicLinker();
// TODO(djasper): This is hacky. We should actually try to figure out whether we generate
// ccOutputs.
boolean createDynamicLibrary = !linkStatic && supportsDynamicLinker && (appearsToHaveObjectFiles(ruleContext.attributes()) || featureConfiguration.isEnabled(CppRuleClasses.HEADER_MODULE_CODEGEN));
if (ruleContext.getRule().isAttrDefined("outs", Type.STRING_LIST)) {
List<String> outs = ruleContext.attributes().get("outs", Type.STRING_LIST);
if (outs.size() > 1) {
ruleContext.attributeError("outs", "must be a singleton list");
} else if (outs.size() == 1) {
PathFragment soImplFilename = new PathFragment(ruleContext.getLabel().getName());
soImplFilename = soImplFilename.replaceName(outs.get(0));
if (!soImplFilename.getPathString().endsWith(".so")) {
// Sanity check.
ruleContext.attributeError("outs", "file name must end in '.so'");
}
if (createDynamicLibrary) {
soImplArtifact = ruleContext.getBinArtifact(soImplFilename);
}
}
}
if (ruleContext.getRule().isAttrDefined("srcs", BuildType.LABEL_LIST)) {
ruleContext.checkSrcsSamePackage(true);
}
if (ruleContext.getRule().isAttrDefined("textual_hdrs", BuildType.LABEL_LIST)) {
helper.addPublicTextualHeaders(ruleContext.getPrerequisiteArtifacts("textual_hdrs", Mode.TARGET).list());
}
if (common.getLinkopts().contains("-static")) {
ruleContext.attributeWarning("linkopts", "Using '-static' here won't work. " + "Did you mean to use 'linkstatic=1' instead?");
}
helper.setCreateDynamicLibrary(createDynamicLibrary);
helper.setDynamicLibrary(soImplArtifact);
// which only happens when some rule explicitly depends on the dynamic library.
if (!createDynamicLibrary && !supportsDynamicLinker) {
Artifact solibArtifact = CppHelper.getLinuxLinkedArtifact(ruleContext, ruleContext.getConfiguration(), LinkTargetType.DYNAMIC_LIBRARY);
ruleContext.registerAction(new FailAction(ruleContext.getActionOwner(), ImmutableList.of(solibArtifact), "Toolchain does not support dynamic linking"));
} else if (!createDynamicLibrary && ruleContext.attributes().isConfigurable("srcs")) {
// If "srcs" is configurable, the .so output is always declared because the logic that
// determines implicit outs doesn't know which value of "srcs" will ultimately get chosen.
// Here, where we *do* have the correct value, it may not contain any source files to
// generate an .so with. If that's the case, register a fake generating action to prevent
// a "no generating action for this artifact" error.
Artifact solibArtifact = CppHelper.getLinuxLinkedArtifact(ruleContext, ruleContext.getConfiguration(), LinkTargetType.DYNAMIC_LIBRARY);
ruleContext.registerAction(new FailAction(ruleContext.getActionOwner(), ImmutableList.of(solibArtifact), "configurable \"srcs\" triggers an implicit .so output " + "even though there are no sources to compile in this configuration"));
}
/*
* Add the libraries from srcs, if any. For static/mostly static
* linking we setup the dynamic libraries if there are no static libraries
* to choose from. Path to the libraries will be mangled to avoid using
* absolute path names on the -rpath, but library filenames will be
* preserved (since some libraries might have SONAME tag) - symlink will
* be created to the parent directory instead.
*
* For compatibility with existing BUILD files, any ".a" or ".lo" files listed in
* srcs are assumed to be position-independent code, or at least suitable for
* inclusion in shared libraries, unless they end with ".nopic.a" or ".nopic.lo".
*
* Note that some target platforms do not require shared library code to be PIC.
*/
Iterable<LibraryToLink> staticLibrariesFromSrcs = LinkerInputs.opaqueLibrariesToLink(ArtifactCategory.STATIC_LIBRARY, precompiledFiles.getStaticLibraries());
Iterable<LibraryToLink> alwayslinkLibrariesFromSrcs = LinkerInputs.opaqueLibrariesToLink(ArtifactCategory.ALWAYSLINK_STATIC_LIBRARY, precompiledFiles.getAlwayslinkStaticLibraries());
Iterable<LibraryToLink> picStaticLibrariesFromSrcs = LinkerInputs.opaqueLibrariesToLink(ArtifactCategory.STATIC_LIBRARY, precompiledFiles.getPicStaticLibraries());
Iterable<LibraryToLink> picAlwayslinkLibrariesFromSrcs = LinkerInputs.opaqueLibrariesToLink(ArtifactCategory.ALWAYSLINK_STATIC_LIBRARY, precompiledFiles.getPicAlwayslinkLibraries());
helper.addStaticLibraries(staticLibrariesFromSrcs);
helper.addStaticLibraries(alwayslinkLibrariesFromSrcs);
helper.addPicStaticLibraries(picStaticLibrariesFromSrcs);
helper.addPicStaticLibraries(picAlwayslinkLibrariesFromSrcs);
helper.addDynamicLibraries(Iterables.transform(precompiledFiles.getSharedLibraries(), new Function<Artifact, LibraryToLink>() {
@Override
public LibraryToLink apply(Artifact library) {
return LinkerInputs.solibLibraryToLink(common.getDynamicLibrarySymlink(library, true), library, CcLinkingOutputs.libraryIdentifierOf(library));
}
}));
CcLibraryHelper.Info info = helper.build();
/*
* We always generate a static library, even if there aren't any source files.
* This keeps things simpler by avoiding special cases when making use of the library.
* For example, this is needed to ensure that building a library with "bazel build"
* will also build all of the library's "deps".
* However, we only generate a dynamic library if there are source files.
*/
// For now, we don't add the precompiled libraries to the files to build.
CcLinkingOutputs linkedLibraries = info.getCcLinkingOutputsExcludingPrecompiledLibraries();
NestedSetBuilder<Artifact> filesBuilder = NestedSetBuilder.stableOrder();
filesBuilder.addAll(LinkerInputs.toLibraryArtifacts(linkedLibraries.getStaticLibraries()));
filesBuilder.addAll(LinkerInputs.toLibraryArtifacts(linkedLibraries.getPicStaticLibraries()));
filesBuilder.addAll(LinkerInputs.toNonSolibArtifacts(linkedLibraries.getDynamicLibraries()));
filesBuilder.addAll(LinkerInputs.toNonSolibArtifacts(linkedLibraries.getExecutionDynamicLibraries()));
CcLinkingOutputs linkingOutputs = info.getCcLinkingOutputs();
if (!featureConfiguration.isEnabled(CppRuleClasses.HEADER_MODULE_CODEGEN)) {
warnAboutEmptyLibraries(ruleContext, info.getCcCompilationOutputs(), linkStatic);
}
NestedSet<Artifact> filesToBuild = filesBuilder.build();
Runfiles staticRunfiles = collectRunfiles(ruleContext, linkingOutputs, ccToolchain, neverLink, addDynamicRuntimeInputArtifactsToRunfiles, true);
Runfiles sharedRunfiles = collectRunfiles(ruleContext, linkingOutputs, ccToolchain, neverLink, addDynamicRuntimeInputArtifactsToRunfiles, false);
List<Artifact> instrumentedObjectFiles = new ArrayList<>();
instrumentedObjectFiles.addAll(info.getCcCompilationOutputs().getObjectFiles(false));
instrumentedObjectFiles.addAll(info.getCcCompilationOutputs().getObjectFiles(true));
InstrumentedFilesProvider instrumentedFilesProvider = common.getInstrumentedFilesProvider(instrumentedObjectFiles, /*withBaselineCoverage=*/
true);
CppHelper.maybeAddStaticLinkMarkerProvider(targetBuilder, ruleContext);
targetBuilder.setFilesToBuild(filesToBuild).addProviders(info.getProviders()).addSkylarkTransitiveInfo(CcSkylarkApiProvider.NAME, new CcSkylarkApiProvider()).addOutputGroups(info.getOutputGroups()).addProvider(InstrumentedFilesProvider.class, instrumentedFilesProvider).addProvider(RunfilesProvider.class, RunfilesProvider.withData(staticRunfiles, sharedRunfiles)).addProvider(CppRunfilesProvider.class, new CppRunfilesProvider(staticRunfiles, sharedRunfiles)).addOutputGroup(OutputGroupProvider.HIDDEN_TOP_LEVEL, collectHiddenTopLevelArtifacts(ruleContext, info.getCcCompilationOutputs())).addOutputGroup(CcLibraryHelper.HIDDEN_HEADER_TOKENS, CcLibraryHelper.collectHeaderTokens(ruleContext, info.getCcCompilationOutputs()));
}
use of com.google.devtools.build.lib.actions.FailAction in project bazel by bazelbuild.
the class UnknownRuleConfiguredTarget method create.
@Override
public ConfiguredTarget create(RuleContext context) {
// TODO(bazel-team): (2009) why isn't this an error? It would stop the build more promptly...
context.ruleWarning("cannot build " + context.getRule().getRuleClass() + " rules");
ImmutableList<Artifact> outputArtifacts = context.getOutputArtifacts();
NestedSet<Artifact> filesToBuild;
if (outputArtifacts.isEmpty()) {
// Gotta build *something*...
filesToBuild = NestedSetBuilder.create(Order.STABLE_ORDER, context.createOutputArtifact());
} else {
filesToBuild = NestedSetBuilder.wrap(Order.STABLE_ORDER, outputArtifacts);
}
Rule rule = context.getRule();
context.registerAction(new FailAction(context.getActionOwner(), filesToBuild, "cannot build " + rule.getRuleClass() + " rules such as " + rule.getLabel()));
return new RuleConfiguredTargetBuilder(context).setFilesToBuild(filesToBuild).add(RunfilesProvider.class, RunfilesProvider.simple(Runfiles.EMPTY)).build();
}
use of com.google.devtools.build.lib.actions.FailAction in project bazel by bazelbuild.
the class AndroidBinary method createEmptyProguardAction.
private static ProguardOutput createEmptyProguardAction(RuleContext ruleContext, JavaSemantics semantics, Artifact proguardOutputJar, Artifact deployJarArtifact, Artifact proguardOutputMap) throws InterruptedException {
NestedSetBuilder<Artifact> failures = NestedSetBuilder.<Artifact>stableOrder();
ProguardOutput outputs = ProguardHelper.getProguardOutputs(proguardOutputJar, /* proguardSeeds */
(Artifact) null, /* proguardUsage */
(Artifact) null, ruleContext, semantics, proguardOutputMap);
outputs.addAllToSet(failures);
JavaOptimizationMode optMode = getJavaOptimizationMode(ruleContext);
ruleContext.registerAction(new FailAction(ruleContext.getActionOwner(), failures.build(), String.format("Can't run Proguard %s", optMode == JavaOptimizationMode.LEGACY ? "without proguard_specs" : "in optimization mode " + optMode)));
return new ProguardOutput(deployJarArtifact, null, null, null, null, null, null);
}
use of com.google.devtools.build.lib.actions.FailAction in project bazel by bazelbuild.
the class CppModel method getLinkedArtifact.
/**
* 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, configuration, linkTargetType, linkedArtifactNameSuffix);
try {
String maybePicName = ruleContext.getLabel().getName() + linkedArtifactNameSuffix;
if (linkTargetType.picness() == Picness.PIC) {
maybePicName = CppHelper.getArtifactNameForCategory(ruleContext, ccToolchain, ArtifactCategory.PIC_FILE, maybePicName);
}
String linkedName = CppHelper.getArtifactNameForCategory(ruleContext, ccToolchain, linkTargetType.getLinkerOutput(), maybePicName);
PathFragment artifactFragment = new PathFragment(ruleContext.getLabel().getName()).getParentDirectory().getRelative(linkedName);
result = ruleContext.getPackageRelativeArtifact(artifactFragment, configuration.getBinDirectory(ruleContext.getRule().getRepository()));
} catch (ExpansionException e) {
ruleContext.throwWithRuleError(e.getMessage());
}
// 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;
}
use of com.google.devtools.build.lib.actions.FailAction in project bazel by bazelbuild.
the class ConfiguredTargetFactory method createFailConfiguredTarget.
/**
* A pseudo-implementation for configured targets that creates fail actions for all declared
* outputs, both implicit and explicit.
*/
private static ConfiguredTarget createFailConfiguredTarget(RuleContext ruleContext) {
RuleConfiguredTargetBuilder builder = new RuleConfiguredTargetBuilder(ruleContext);
if (!ruleContext.getOutputArtifacts().isEmpty()) {
ruleContext.registerAction(new FailAction(ruleContext.getActionOwner(), ruleContext.getOutputArtifacts(), "Can't build this"));
}
builder.add(RunfilesProvider.class, RunfilesProvider.simple(Runfiles.EMPTY));
return builder.build();
}
Aggregations