use of com.google.devtools.build.lib.packages.Attribute in project bazel by bazelbuild.
the class XmlOutputFormatter method createTargetElement.
/**
* Creates and returns a new DOM tree for the specified build target.
*
* XML structure:
* - element tag is <source-file>, <generated-file> or <rule
* class="cc_library">, following the terminology of
* {@link Target#getTargetKind()}.
* - 'name' attribute is target's label.
* - 'location' attribute is consistent with output of --output location.
* - rule attributes are represented in the DOM structure.
* @throws InterruptedException
*/
private Element createTargetElement(Document doc, Target target) throws InterruptedException {
Element elem;
if (target instanceof Rule) {
Rule rule = (Rule) target;
elem = doc.createElement("rule");
elem.setAttribute("class", rule.getRuleClass());
for (Attribute attr : rule.getAttributes()) {
PossibleAttributeValues values = getPossibleAttributeValues(rule, attr);
if (values.source == AttributeValueSource.RULE || options.xmlShowDefaultValues) {
Element attrElem = createValueElement(doc, attr.getType(), values);
attrElem.setAttribute("name", attr.getName());
elem.appendChild(attrElem);
}
}
// host-configuration outputs, and default values.
for (Label label : rule.getLabels(dependencyFilter)) {
Element inputElem = doc.createElement("rule-input");
inputElem.setAttribute("name", label.toString());
elem.appendChild(inputElem);
}
for (Label label : aspectResolver.computeAspectDependencies(target, dependencyFilter).values()) {
Element inputElem = doc.createElement("rule-input");
inputElem.setAttribute("name", label.toString());
elem.appendChild(inputElem);
}
for (OutputFile outputFile : rule.getOutputFiles()) {
Element outputElem = doc.createElement("rule-output");
outputElem.setAttribute("name", outputFile.getLabel().toString());
elem.appendChild(outputElem);
}
for (String feature : rule.getFeatures()) {
Element outputElem = doc.createElement("rule-default-setting");
outputElem.setAttribute("name", feature);
elem.appendChild(outputElem);
}
} else if (target instanceof PackageGroup) {
PackageGroup packageGroup = (PackageGroup) target;
elem = doc.createElement("package-group");
elem.setAttribute("name", packageGroup.getName());
Element includes = createValueElement(doc, BuildType.LABEL_LIST, packageGroup.getIncludes());
includes.setAttribute("name", "includes");
elem.appendChild(includes);
Element packages = createValueElement(doc, Type.STRING_LIST, packageGroup.getContainedPackages());
packages.setAttribute("name", "packages");
elem.appendChild(packages);
} else if (target instanceof OutputFile) {
OutputFile outputFile = (OutputFile) target;
elem = doc.createElement("generated-file");
elem.setAttribute("generating-rule", outputFile.getGeneratingRule().getLabel().toString());
} else if (target instanceof InputFile) {
elem = doc.createElement("source-file");
InputFile inputFile = (InputFile) target;
if (inputFile.getName().equals("BUILD")) {
addSubincludedFilesToElement(doc, elem, inputFile);
addSkylarkFilesToElement(doc, elem, inputFile);
addFeaturesToElement(doc, elem, inputFile);
elem.setAttribute("package_contains_errors", String.valueOf(inputFile.getPackage().containsErrors()));
}
addPackageGroupsToElement(doc, elem, inputFile);
} else if (target instanceof EnvironmentGroup) {
EnvironmentGroup envGroup = (EnvironmentGroup) target;
elem = doc.createElement("environment-group");
elem.setAttribute("name", envGroup.getName());
Element environments = createValueElement(doc, BuildType.LABEL_LIST, envGroup.getEnvironments());
environments.setAttribute("name", "environments");
elem.appendChild(environments);
Element defaults = createValueElement(doc, BuildType.LABEL_LIST, envGroup.getDefaults());
defaults.setAttribute("name", "defaults");
elem.appendChild(defaults);
} else if (target instanceof FakeSubincludeTarget) {
elem = doc.createElement("source-file");
} else {
throw new IllegalArgumentException(target.toString());
}
elem.setAttribute("name", target.getLabel().toString());
String location = getLocation(target, options.relativeLocations);
if (!options.xmlLineNumbers) {
int firstColon = location.indexOf(':');
if (firstColon != -1) {
location = location.substring(0, firstColon);
}
}
elem.setAttribute("location", location);
return elem;
}
use of com.google.devtools.build.lib.packages.Attribute in project bazel by bazelbuild.
the class TransitiveBaseTraversalFunction method getStrictLabelAspectKeys.
/**
* Return an Iterable of SkyKeys corresponding to the Aspect-related dependencies of target.
*
* <p>This method may return a precise set of aspect keys, but may need to request additional
* dependencies from the env to do so.
*/
private Iterable<SkyKey> getStrictLabelAspectKeys(Target target, Map<SkyKey, ValueOrException2<NoSuchPackageException, NoSuchTargetException>> depMap, Environment env) throws InterruptedException {
List<SkyKey> depKeys = Lists.newArrayList();
if (target instanceof Rule) {
Map<Label, ValueOrException2<NoSuchPackageException, NoSuchTargetException>> labelDepMap = new HashMap<>(depMap.size());
for (Entry<SkyKey, ValueOrException2<NoSuchPackageException, NoSuchTargetException>> entry : depMap.entrySet()) {
labelDepMap.put((Label) entry.getKey().argument(), entry.getValue());
}
Multimap<Attribute, Label> transitions = ((Rule) target).getTransitions(DependencyFilter.NO_NODEP_ATTRIBUTES);
for (Entry<Attribute, Label> entry : transitions.entries()) {
ValueOrException2<NoSuchPackageException, NoSuchTargetException> value = labelDepMap.get(entry.getValue());
for (Label label : getAspectLabels((Rule) target, entry.getKey(), entry.getValue(), value, env)) {
depKeys.add(getKey(label));
}
}
}
return depKeys;
}
use of com.google.devtools.build.lib.packages.Attribute in project bazel by bazelbuild.
the class TransitiveTargetFunction method computeSkyValue.
@Override
public SkyValue computeSkyValue(TargetAndErrorIfAny targetAndErrorIfAny, TransitiveTargetValueBuilder builder) {
Target target = targetAndErrorIfAny.getTarget();
NoSuchTargetException errorLoadingTarget = targetAndErrorIfAny.getErrorLoadingTarget();
// Get configuration fragments directly required by this rule.
if (target instanceof Rule) {
Rule rule = (Rule) target;
// Declared by the rule class:
ConfigurationFragmentPolicy configurationFragmentPolicy = rule.getRuleClassObject().getConfigurationFragmentPolicy();
for (ConfigurationFragmentFactory factory : ruleClassProvider.getConfigurationFragments()) {
Class<? extends Fragment> fragment = factory.creates();
// (named) fragments.
if (configurationFragmentPolicy.isLegalConfigurationFragment(fragment)) {
addFragmentIfNew(builder, fragment.asSubclass(BuildConfiguration.Fragment.class));
}
}
// Declared by late-bound attributes:
for (Attribute attr : rule.getAttributes()) {
if (attr.isLateBound()) {
addFragmentsIfNew(builder, attr.getLateBoundDefault().getRequiredConfigurationFragments());
}
}
// corresponding fragments in their configurations to properly resolve:
if (rule.getRuleClass().equals(ConfigSettingRule.RULE_NAME)) {
addFragmentsIfNew(builder, ConfigSettingRule.requiresConfigurationFragments(rule, optionsToFragmentMap));
}
// Fragments to unconditionally include:
addFragmentIfNew(builder, ruleClassProvider.getUniversalFragment().asSubclass(BuildConfiguration.Fragment.class));
}
return builder.build(errorLoadingTarget);
}
use of com.google.devtools.build.lib.packages.Attribute in project bazel by bazelbuild.
the class DependencyResolver method resolveLateBoundAttributes.
/**
* Resolves the dependencies for all late-bound attributes in this rule.
*
* <p>Late-bound attributes need special handling because they require configuration
* transitions to determine their values.
*
* <p>In other words, the normal process of dependency resolution is:
* <ol>
* <li>Find every label value in the rule's attributes</li>
* <li>Apply configuration transitions over each value to get its dep configuration
* <li>Return each value with its dep configuration</li>
* </ol>
*
* This doesn't work for late-bound attributes because you can't get their values without
* knowing the configuration first. And that configuration may not be the owning rule's
* configuration. Specifically, {@link LateBoundDefault#useHostConfiguration()} switches to the
* host config and late-bound split attributes branch into multiple split configs.
*
* <p>This method implements that logic and makes sure the normal configuration
* transition logic mixes with it cleanly.
*
* @param depResolver the resolver for this rule's deps
* @param ruleConfig the rule's configuration
* @param hostConfig the equivalent host configuration
*/
private void resolveLateBoundAttributes(RuleResolver depResolver, BuildConfiguration ruleConfig, BuildConfiguration hostConfig) throws EvalException, InvalidConfigurationException, InconsistentAspectOrderException, InterruptedException {
ConfiguredAttributeMapper attributeMap = depResolver.attributeMap;
for (AttributeAndOwner attributeAndOwner : depResolver.attributes) {
Attribute attribute = attributeAndOwner.attribute;
if (!attribute.isLateBound() || !attribute.getCondition().apply(attributeMap)) {
continue;
}
@SuppressWarnings("unchecked") LateBoundDefault<BuildConfiguration> lateBoundDefault = (LateBoundDefault<BuildConfiguration>) attribute.getLateBoundDefault();
Collection<BuildOptions> splitOptions = getSplitOptions(depResolver.rule, attribute, ruleConfig);
if (!splitOptions.isEmpty()) {
// Late-bound attribute with a split transition:
// Since we want to get the same results as BuildConfiguration.evaluateTransition (but
// skip it since we've already applied the split), we want to make sure this logic
// doesn't do anything differently. evaluateTransition has additional logic
// for host configs and attributes with configurators. So we check here that neither of
// of those apply, in the name of keeping the fork as simple as possible.
Verify.verify(attribute.getConfigurator() == null);
Verify.verify(!lateBoundDefault.useHostConfiguration());
Iterable<BuildConfiguration> splitConfigs;
if (!ruleConfig.useDynamicConfigurations()) {
splitConfigs = ruleConfig.getSplitConfigurations(attribute.getSplitTransition(depResolver.rule));
} else {
splitConfigs = getConfigurations(ruleConfig.fragmentClasses(), splitOptions);
if (splitConfigs == null) {
// Need Skyframe deps.
continue;
}
}
for (BuildConfiguration splitConfig : splitConfigs) {
for (Label dep : resolveLateBoundAttribute(depResolver.rule, attribute, splitConfig, attributeMap)) {
// Skip the normal config transition pipeline and directly feed the split config. This
// is because the split already had to be applied to determine the attribute's value.
// This makes the split logic in the normal pipeline redundant and potentially
// incorrect.
depResolver.resolveDep(attributeAndOwner, dep, splitConfig);
}
}
} else {
// Late-bound attribute without a split transition:
for (Label dep : resolveLateBoundAttribute(depResolver.rule, attribute, lateBoundDefault.useHostConfiguration() ? hostConfig : ruleConfig, attributeMap)) {
// Process this dep like a normal attribute.
depResolver.resolveDep(attributeAndOwner, dep);
}
}
}
}
use of com.google.devtools.build.lib.packages.Attribute in project bazel by bazelbuild.
the class DependencyResolver method resolveImplicitAttributes.
/** Resolves the dependencies for all implicit attributes in this rule. */
private void resolveImplicitAttributes(RuleResolver depResolver) throws InterruptedException, InconsistentAspectOrderException {
// Since the attributes that come from aspects do not appear in attributeMap, we have to get
// their values from somewhere else. This incidentally means that aspects attributes are not
// configurable. It would be nice if that wasn't the case, but we'd have to revamp how
// attribute mapping works, which is a large chunk of work.
Rule rule = depResolver.rule;
Label ruleLabel = rule.getLabel();
ConfiguredAttributeMapper attributeMap = depResolver.attributeMap;
ImmutableSet<String> mappedAttributes = ImmutableSet.copyOf(attributeMap.getAttributeNames());
for (AttributeAndOwner attributeAndOwner : depResolver.attributes) {
Attribute attribute = attributeAndOwner.attribute;
if (!attribute.isImplicit() || !attribute.getCondition().apply(attributeMap)) {
continue;
}
if (attribute.getType() == BuildType.LABEL) {
Label label = mappedAttributes.contains(attribute.getName()) ? attributeMap.get(attribute.getName(), BuildType.LABEL) : BuildType.LABEL.cast(attribute.getDefaultValue(rule));
if (label != null) {
label = ruleLabel.resolveRepositoryRelative(label);
depResolver.resolveDep(attributeAndOwner, label);
}
} else if (attribute.getType() == BuildType.LABEL_LIST) {
List<Label> labelList;
if (mappedAttributes.contains(attribute.getName())) {
labelList = new ArrayList<>();
for (Label label : attributeMap.get(attribute.getName(), BuildType.LABEL_LIST)) {
labelList.add(label);
}
} else {
labelList = BuildType.LABEL_LIST.cast(attribute.getDefaultValue(rule));
}
for (Label label : labelList) {
depResolver.resolveDep(attributeAndOwner, ruleLabel.resolveRepositoryRelative(label));
}
}
}
}
Aggregations