Search in sources :

Example 1 with EnvironmentGroup

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;
}
Also used : OutputFile(com.google.devtools.build.lib.packages.OutputFile) Attribute(com.google.devtools.build.lib.packages.Attribute) Element(org.w3c.dom.Element) Label(com.google.devtools.build.lib.cmdline.Label) PackageGroup(com.google.devtools.build.lib.packages.PackageGroup) InputFile(com.google.devtools.build.lib.packages.InputFile) EnvironmentGroup(com.google.devtools.build.lib.packages.EnvironmentGroup) FakeSubincludeTarget(com.google.devtools.build.lib.query2.FakeSubincludeTarget) Rule(com.google.devtools.build.lib.packages.Rule)

Example 2 with EnvironmentGroup

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);
}
Also used : LinkedHashSet(java.util.LinkedHashSet) EnvironmentGroup(com.google.devtools.build.lib.packages.EnvironmentGroup) EnvironmentWithGroup(com.google.devtools.build.lib.analysis.constraints.EnvironmentCollection.EnvironmentWithGroup) HashMap(java.util.HashMap) Label(com.google.devtools.build.lib.cmdline.Label) TransitiveInfoCollection(com.google.devtools.build.lib.analysis.TransitiveInfoCollection)

Example 3 with EnvironmentGroup

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;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) EnvironmentGroup(com.google.devtools.build.lib.packages.EnvironmentGroup) EnvironmentWithGroup(com.google.devtools.build.lib.analysis.constraints.EnvironmentCollection.EnvironmentWithGroup) Label(com.google.devtools.build.lib.cmdline.Label)

Example 4 with EnvironmentGroup

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();
}
Also used : EnvironmentGroup(com.google.devtools.build.lib.packages.EnvironmentGroup)

Example 5 with EnvironmentGroup

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();
}
Also used : EnvironmentGroup(com.google.devtools.build.lib.packages.EnvironmentGroup) EnvironmentWithGroup(com.google.devtools.build.lib.analysis.constraints.EnvironmentCollection.EnvironmentWithGroup) ImmutableSet(com.google.common.collect.ImmutableSet) Label(com.google.devtools.build.lib.cmdline.Label)

Aggregations

EnvironmentGroup (com.google.devtools.build.lib.packages.EnvironmentGroup)10 Label (com.google.devtools.build.lib.cmdline.Label)6 EnvironmentWithGroup (com.google.devtools.build.lib.analysis.constraints.EnvironmentCollection.EnvironmentWithGroup)4 InputFile (com.google.devtools.build.lib.packages.InputFile)4 OutputFile (com.google.devtools.build.lib.packages.OutputFile)4 PackageGroup (com.google.devtools.build.lib.packages.PackageGroup)4 Rule (com.google.devtools.build.lib.packages.Rule)4 LinkedHashSet (java.util.LinkedHashSet)4 Attribute (com.google.devtools.build.lib.packages.Attribute)3 Target (com.google.devtools.build.lib.packages.Target)3 FakeSubincludeTarget (com.google.devtools.build.lib.query2.FakeSubincludeTarget)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 ImmutableSet (com.google.common.collect.ImmutableSet)1 Artifact (com.google.devtools.build.lib.actions.Artifact)1 ConfiguredTarget (com.google.devtools.build.lib.analysis.ConfiguredTarget)1 FilesToRunProvider (com.google.devtools.build.lib.analysis.FilesToRunProvider)1 RuleConfiguredTargetBuilder (com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder)1 RunfilesProvider (com.google.devtools.build.lib.analysis.RunfilesProvider)1 TransitiveInfoCollection (com.google.devtools.build.lib.analysis.TransitiveInfoCollection)1 BuildConfiguration (com.google.devtools.build.lib.analysis.config.BuildConfiguration)1