cc_library
rules.
*/
public abstract class CcLibrary implements RuleConfiguredTargetFactory {
private final CppSemantics semantics;
protected CcLibrary(CppSemantics semantics) {
this.semantics = semantics;
}
// These file extensions don't generate object files.
private static final FileTypeSet NO_OBJECT_GENERATING_FILETYPES = FileTypeSet.of(
CppFileTypes.CPP_HEADER, CppFileTypes.ARCHIVE, CppFileTypes.PIC_ARCHIVE,
CppFileTypes.ALWAYS_LINK_LIBRARY, CppFileTypes.ALWAYS_LINK_PIC_LIBRARY,
CppFileTypes.SHARED_LIBRARY, CppFileTypes.VERSIONED_SHARED_LIBRARY);
private static Runfiles collectRunfiles(RuleContext context,
CcLinkingOutputs ccLinkingOutputs,
CcToolchainProvider ccToolchain,
boolean neverLink, boolean addDynamicRuntimeInputArtifactsToRunfiles,
boolean linkingStatically) {
Runfiles.Builder builder = new Runfiles.Builder(
context.getWorkspaceName(), context.getConfiguration().legacyExternalRunfiles());
// neverlink= true creates a library that will never be linked into any binary that depends on
// it, but instead be loaded as an extension. So we need the dynamic library for this in the
// runfiles.
builder.addArtifacts(ccLinkingOutputs.getLibrariesForRunfiles(linkingStatically && !neverLink));
builder.add(context, CppRunfilesProvider.runfilesFunction(linkingStatically));
builder.addDataDeps(context);
if (addDynamicRuntimeInputArtifactsToRunfiles) {
builder.addTransitiveArtifacts(ccToolchain.getDynamicRuntimeLinkInputs());
}
return builder.build();
}
@Override
public ConfiguredTarget create(RuleContext context)
throws RuleErrorException, InterruptedException {
RuleConfiguredTargetBuilder builder = new RuleConfiguredTargetBuilder(context);
LinkTargetType staticLinkType = getStaticLinkType(context);
boolean linkStatic = context.attributes().get("linkstatic", Type.BOOLEAN);
init(semantics, context, builder, staticLinkType,
/*neverLink =*/ false,
linkStatic,
/*addDynamicRuntimeInputArtifactsToRunfiles =*/ false);
return builder.build();
}
public static void init(
CppSemantics semantics,
RuleContext ruleContext,
RuleConfiguredTargetBuilder targetBuilder,
LinkTargetType staticLinkType,
boolean neverLink,
boolean linkStatic,
boolean addDynamicRuntimeInputArtifactsToRunfiles)
throws RuleErrorException, InterruptedException {
final CcCommon common = new CcCommon(ruleContext);
CcToolchainProvider ccToolchain = common.getToolchain();
if (CppHelper.shouldUseToolchainForMakeVariables(ruleContext)) {
ImmutableMap.BuilderIn some cases, this may return "true" even though the rule actually has no object files.
* For example, it will return true for a rule such as
* cc_library(name = 'foo', srcs = [':bar'])
because we can't tell what ':bar' is;
* it might be a genrule that generates a source file, or it might be a genrule that generates a
* header file. Likewise,
* cc_library(name = 'foo', srcs = select({':a': ['foo.cc'], ':b': []}))
returns
* "true" even though the sources *may* be empty. This reflects the fact that there's no way
* to tell which value "srcs" will take without knowing the rule's configuration.
*
*
In other cases, this may return "false" even though the rule actually does have object
* files. For example, it will return false for a rule such as
* cc_library(name = 'foo', srcs = ['bar.h'])
but as in the other example above,
* we can't tell whether 'bar.h' is a file name or a rule name, and 'bar.h' could in fact be the
* name of a genrule that generates a source file.
*/
public static boolean appearsToHaveObjectFiles(AttributeMap rule) {
if ((rule instanceof RawAttributeMapper) && rule.isConfigurable("srcs")) {
// Since this method gets called by loading phase logic (e.g. the cc_library implicit outputs
// function), the attribute mapper may not be able to resolve configurable attributes. When
// that's the case, there's no way to know which value a configurable "srcs" will take, so
// we conservatively assume object files are possible.
return true;
}
List