use of com.google.devtools.build.lib.packages.EnvironmentGroup 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.EnvironmentGroup in project bazel by bazelbuild.
the class ConstraintSemantics method checkConstraints.
/**
* Performs constraint checking on the given rule's dependencies and reports any errors. This
* includes:
*
* <ul>
* <li>Static environment checking: if this rule supports environment E, all deps outside
* selects must also support E
* <li>Refined environment computation: this rule's refined environments are its static
* environments intersected with the refined environments of all dependencies (including
* chosen deps in selects)
* <li>Refined environment checking: no environment groups can be "emptied" due to refinement
* </ul>
*
* @param ruleContext the rule to analyze
* @param staticEnvironments the rule's supported environments, as defined by the return
* value of {@link #getSupportedEnvironments}. In particular, for any environment group that's
* not in this collection, the rule is assumed to support the defaults for that group.
* @param refinedEnvironments a builder for populating this rule's refined environments
* @param removedEnvironmentCulprits a builder for populating the core dependencies that trigger
* pruning away environments through refinement. If multiple dependencies qualify (e.g.
* two direct deps under the current rule), one is arbitrarily chosen.
*/
public static void checkConstraints(RuleContext ruleContext, EnvironmentCollection staticEnvironments, EnvironmentCollection.Builder refinedEnvironments, Map<Label, Target> removedEnvironmentCulprits) {
Set<EnvironmentWithGroup> refinedEnvironmentsSoFar = new LinkedHashSet<>();
// Start with the full set of static environments:
refinedEnvironmentsSoFar.addAll(staticEnvironments.getGroupedEnvironments());
Set<EnvironmentGroup> groupsWithEnvironmentsRemoved = new LinkedHashSet<>();
// Maps the label results of getUnsupportedEnvironments() to EnvironmentWithGroups. We can't
// have that method just return EnvironmentWithGroups because it also collects group defaults,
// which we only have labels for.
Map<Label, EnvironmentWithGroup> labelsToEnvironments = new HashMap<>();
for (EnvironmentWithGroup envWithGroup : staticEnvironments.getGroupedEnvironments()) {
labelsToEnvironments.put(envWithGroup.environment(), envWithGroup);
}
DepsToCheck depsToCheck = getConstraintCheckedDependencies(ruleContext);
for (TransitiveInfoCollection dep : depsToCheck.allDeps()) {
SupportedEnvironmentsProvider depEnvironments = dep.getProvider(SupportedEnvironmentsProvider.class);
if (!depsToCheck.isSelectOnly(dep)) {
// TODO(bazel-team): support static constraint checking for selects. A selectable constraint
// is valid if the union of all deps in the select includes all of this rule's static
// environments. Determining that requires following the select paths that don't get chosen,
// which means we won't have ConfiguredTargets for those deps and need to find another
// way to get their environments.
Collection<Label> unsupportedEnvironments = getUnsupportedEnvironments(depEnvironments.getStaticEnvironments(), staticEnvironments);
if (!unsupportedEnvironments.isEmpty()) {
ruleContext.ruleError("dependency " + dep.getLabel() + " doesn't support expected environment" + (unsupportedEnvironments.size() == 1 ? "" : "s") + ": " + Joiner.on(", ").join(unsupportedEnvironments));
}
}
// Refine this rule's environments by intersecting with the dep's refined environments:
for (Label refinedEnvironmentToPrune : getUnsupportedEnvironments(depEnvironments.getRefinedEnvironments(), staticEnvironments)) {
EnvironmentWithGroup envToPrune = labelsToEnvironments.get(refinedEnvironmentToPrune);
if (envToPrune == null) {
// set before trying to remove specific items.
for (EnvironmentWithGroup defaultEnv : getDefaults(refinedEnvironmentToPrune, depEnvironments.getRefinedEnvironments())) {
refinedEnvironmentsSoFar.add(defaultEnv);
labelsToEnvironments.put(defaultEnv.environment(), defaultEnv);
}
envToPrune = Verify.verifyNotNull(labelsToEnvironments.get(refinedEnvironmentToPrune));
}
refinedEnvironmentsSoFar.remove(envToPrune);
groupsWithEnvironmentsRemoved.add(envToPrune.group());
removedEnvironmentCulprits.put(envToPrune.environment(), findOriginalRefiner(ruleContext, depEnvironments, envToPrune));
}
}
checkRefinedEnvironmentConstraints(ruleContext, groupsWithEnvironmentsRemoved, refinedEnvironmentsSoFar, refinedEnvironments, removedEnvironmentCulprits);
}
use of com.google.devtools.build.lib.packages.EnvironmentGroup in project bazel by bazelbuild.
the class ConstraintSemantics method getUnsupportedEnvironments.
/**
* Given a collection of environments and a collection of expected environments, returns the
* missing environments that would cause constraint expectations to be violated. Includes
* the effects of environment group defaults.
*/
public static Collection<Label> getUnsupportedEnvironments(EnvironmentCollection actualEnvironments, EnvironmentCollection expectedEnvironments) {
Set<Label> missingEnvironments = new LinkedHashSet<>();
Collection<Label> actualEnvironmentLabels = actualEnvironments.getEnvironments();
// Check if each explicitly expected environment is satisfied.
for (EnvironmentWithGroup expectedEnv : expectedEnvironments.getGroupedEnvironments()) {
EnvironmentGroup group = expectedEnv.group();
Label environment = expectedEnv.environment();
boolean isSatisfied = false;
if (actualEnvironments.getGroups().contains(group)) {
// need to either find the environment itself or another one that transitively fulfills it.
if (actualEnvironmentLabels.contains(environment) || intersect(actualEnvironmentLabels, group.getFulfillers(environment))) {
isSatisfied = true;
}
} else {
// either the expected environment or another environment that transitively fulfills it.
if (group.isDefault(environment) || intersect(group.getFulfillers(environment), group.getDefaults())) {
isSatisfied = true;
}
}
if (!isSatisfied) {
missingEnvironments.add(environment);
}
}
// group (since in that case the same defaults apply), otherwise we have to check.
for (EnvironmentGroup group : actualEnvironments.getGroups()) {
if (!expectedEnvironments.getGroups().contains(group)) {
for (Label expectedDefault : group.getDefaults()) {
if (!actualEnvironmentLabels.contains(expectedDefault) && !intersect(actualEnvironmentLabels, group.getFulfillers(expectedDefault))) {
missingEnvironments.add(expectedDefault);
}
}
}
}
return missingEnvironments;
}
use of com.google.devtools.build.lib.packages.EnvironmentGroup in project bazel by bazelbuild.
the class ConstraintSemantics method addUnknownGroupsToCollection.
/**
* Adds environments to an {@link EnvironmentCollection} from groups that aren't already
* a part of that collection.
*
* @param environments the collection to add to
* @param toAdd the collection to add. All environments in this collection in groups
* that aren't represented in {@code environments} are added to {@code environments}.
* @return the expanded collection.
*/
private static EnvironmentCollection addUnknownGroupsToCollection(EnvironmentCollection environments, EnvironmentCollection toAdd) {
EnvironmentCollection.Builder builder = new EnvironmentCollection.Builder();
builder.putAll(environments);
for (EnvironmentGroup candidateGroup : toAdd.getGroups()) {
if (!environments.getGroups().contains(candidateGroup)) {
builder.putAll(candidateGroup, toAdd.getEnvironments(candidateGroup));
}
}
return builder.build();
}
use of com.google.devtools.build.lib.packages.EnvironmentGroup in project bazel by bazelbuild.
the class ConstraintSemantics method getDefaults.
/**
* Finds the given environment in the given set and returns the default environments for its
* group.
*/
private static Collection<EnvironmentWithGroup> getDefaults(Label env, EnvironmentCollection allEnvironments) {
EnvironmentGroup group = null;
for (EnvironmentGroup candidateGroup : allEnvironments.getGroups()) {
if (candidateGroup.getDefaults().contains(env)) {
group = candidateGroup;
break;
}
}
Verify.verifyNotNull(group);
ImmutableSet.Builder<EnvironmentWithGroup> builder = ImmutableSet.builder();
for (Label defaultEnv : group.getDefaults()) {
builder.add(EnvironmentWithGroup.create(defaultEnv, group));
}
return builder.build();
}
Aggregations