private LicensesProvider initializeLicensesProvider() {
    if (!ruleContext.getConfiguration().checkLicenses()) {
      return LicensesProviderImpl.EMPTY;
    }

    NestedSetBuilder<TargetLicense> builder = NestedSetBuilder.linkOrder();
    BuildConfiguration configuration = ruleContext.getConfiguration();
    Rule rule = ruleContext.getRule();
    License toolOutputLicense = rule.getToolOutputLicense(ruleContext.attributes());
    if (configuration.isHostConfiguration() && toolOutputLicense != null) {
      if (toolOutputLicense != License.NO_LICENSE) {
        builder.add(new TargetLicense(rule.getLabel(), toolOutputLicense));
      }
    } else {
      if (rule.getLicense() != License.NO_LICENSE) {
        builder.add(new TargetLicense(rule.getLabel(), rule.getLicense()));
      }

      for (TransitiveInfoCollection dep : ruleContext.getConfiguredTargetMap().values()) {
        LicensesProvider provider = dep.getProvider(LicensesProvider.class);
        if (provider != null) {
          builder.addTransitive(provider.getTransitiveLicenses());
        }
      }
    }

    return new LicensesProviderImpl(builder.build());
  }
Beispiel #2
0
  private void visitRule(
      Rule rule,
      AspectDefinition aspect,
      AspectParameters aspectParameters,
      ListMultimap<Attribute, LabelAndConfiguration> labelMap,
      ListMultimap<Attribute, Dependency> outgoingEdges) {
    Preconditions.checkNotNull(labelMap);
    for (Map.Entry<Attribute, Collection<LabelAndConfiguration>> entry :
        labelMap.asMap().entrySet()) {
      Attribute attribute = entry.getKey();
      for (LabelAndConfiguration dep : entry.getValue()) {
        Label label = dep.getLabel();
        BuildConfiguration config = dep.getConfiguration();

        Target toTarget;
        try {
          toTarget = getTarget(label);
        } catch (NoSuchThingException e) {
          throw new IllegalStateException(
              "not found: " + label + " from " + rule + " in " + attribute.getName());
        }
        if (toTarget == null) {
          continue;
        }
        BuildConfiguration.TransitionApplier transitionApplier = config.getTransitionApplier();
        if (config.useDynamicConfigurations()
            && config.isHostConfiguration()
            && !BuildConfiguration.usesNullConfiguration(toTarget)) {
          // This condition is needed because resolveLateBoundAttributes may switch config to
          // the host configuration, which is the only case DependencyResolver applies a
          // configuration transition outside of this method. We need to reflect that
          // transition in the results of this method, but config.evaluateTransition is hard-set
          // to return a NONE transition when the input is a host config. Since the outside
          // caller originally passed the *original* value of config (before the possible
          // switch), it can mistakenly interpret the result as a NONE transition from the
          // original value of config. This condition fixes that. Another fix would be to have
          // config.evaluateTransition return a HOST transition when the input config is a host,
          // but since this blemish is specific to DependencyResolver it seems best to keep the
          // fix here.
          // TODO(bazel-team): eliminate this special case by passing transitionApplier to
          // resolveLateBoundAttributes, so that method uses the same interface for transitions.
          transitionApplier.applyTransition(Attribute.ConfigurationTransition.HOST);
        } else {
          config.evaluateTransition(rule, attribute, toTarget, transitionApplier);
        }
        for (Dependency dependency :
            transitionApplier.getDependencies(
                label, requiredAspects(aspect, aspectParameters, attribute, toTarget, rule))) {
          outgoingEdges.put(entry.getKey(), dependency);
        }
      }
    }
  }
  /**
   * Scans {@code action_listeners} associated with this build to see if any {@code extra_actions}
   * should be added to this configured target. If any action_listeners are present, a partial visit
   * of the artifact/action graph is performed (for as long as actions found are owned by this
   * {@link ConfiguredTarget}). Any actions that match the {@code action_listener} get an {@code
   * extra_action} associated. The output artifacts of the extra_action are reported to the {@link
   * AnalysisEnvironment} for bookkeeping.
   */
  private ExtraActionArtifactsProvider initializeExtraActions() {
    BuildConfiguration configuration = ruleContext.getConfiguration();
    if (configuration.isHostConfiguration()) {
      return ExtraActionArtifactsProvider.EMPTY;
    }

    ImmutableList<Artifact> extraActionArtifacts = ImmutableList.of();
    NestedSetBuilder<ExtraArtifactSet> builder = NestedSetBuilder.stableOrder();

    List<Label> actionListenerLabels = configuration.getActionListeners();
    if (!actionListenerLabels.isEmpty()
        && ruleContext.getRule().getAttributeDefinition(":action_listener") != null) {
      ExtraActionsVisitor visitor =
          new ExtraActionsVisitor(ruleContext, computeMnemonicsToExtraActionMap());

      // The action list is modified within the body of the loop by the addExtraAction() call,
      // thus the copy
      for (Action action :
          ImmutableList.copyOf(ruleContext.getAnalysisEnvironment().getRegisteredActions())) {
        if (!actionsWithoutExtraAction.contains(action)) {
          visitor.addExtraAction(action);
        }
      }

      extraActionArtifacts = visitor.getAndResetExtraArtifacts();
      if (!extraActionArtifacts.isEmpty()) {
        builder.add(ExtraArtifactSet.of(ruleContext.getLabel(), extraActionArtifacts));
      }
    }

    // Add extra action artifacts from dependencies
    for (TransitiveInfoCollection dep : ruleContext.getConfiguredTargetMap().values()) {
      ExtraActionArtifactsProvider provider = dep.getProvider(ExtraActionArtifactsProvider.class);
      if (provider != null) {
        builder.addTransitive(provider.getTransitiveExtraActionArtifacts());
      }
    }

    if (mandatoryStampFiles != null && !mandatoryStampFiles.isEmpty()) {
      builder.add(ExtraArtifactSet.of(ruleContext.getLabel(), mandatoryStampFiles));
    }

    if (extraActionArtifacts.isEmpty() && builder.isEmpty()) {
      return ExtraActionArtifactsProvider.EMPTY;
    }
    return new ExtraActionArtifactsProvider(extraActionArtifacts, builder.build());
  }
  static BuildConfiguration setupTransitions(
      BuildConfiguration targetConfiguration,
      BuildConfiguration dataConfiguration,
      BuildConfiguration hostConfiguration,
      ListMultimap<SplitTransition<?>, BuildConfiguration> splitTransitionsTable) {
    Set<BuildConfiguration> allConfigurations = new LinkedHashSet<>();
    allConfigurations.add(targetConfiguration);
    allConfigurations.add(dataConfiguration);
    allConfigurations.add(hostConfiguration);
    allConfigurations.addAll(splitTransitionsTable.values());

    Table<BuildConfiguration, Transition, ConfigurationHolder> transitionBuilder =
        HashBasedTable.create();
    for (BuildConfiguration from : allConfigurations) {
      for (ConfigurationTransition transition : ConfigurationTransition.values()) {
        BuildConfiguration to;
        if (transition == ConfigurationTransition.HOST) {
          to = hostConfiguration;
        } else if (transition == ConfigurationTransition.DATA && from == targetConfiguration) {
          to = dataConfiguration;
        } else {
          to = from;
        }
        transitionBuilder.put(from, transition, new ConfigurationHolder(to));
      }
    }

    // TODO(bazel-team): This makes LIPO totally not work. Just a band-aid until we get around to
    // implementing a way for the C++ rules to contribute this transition to the configuration
    // collection.
    for (BuildConfiguration config : allConfigurations) {
      transitionBuilder.put(config, CppTransition.LIPO_COLLECTOR, new ConfigurationHolder(config));
      transitionBuilder.put(
          config,
          CppTransition.TARGET_CONFIG_FOR_LIPO,
          new ConfigurationHolder(config.isHostConfiguration() ? null : config));
    }

    for (BuildConfiguration config : allConfigurations) {
      Transitions outgoingTransitions =
          new BazelTransitions(
              config,
              transitionBuilder.row(config),
              // Split transitions must not have their own split transitions because then they
              // would be applied twice due to a quirk in DependencyResolver. See the comment in
              // DependencyResolver.resolveLateBoundAttributes().
              splitTransitionsTable.values().contains(config)
                  ? ImmutableListMultimap.<SplitTransition<?>, BuildConfiguration>of()
                  : splitTransitionsTable);
      // We allow host configurations to be shared between target configurations. In that case, the
      // transitions may already be set.
      // TODO(bazel-team): Check that the transitions are identical, or even better, change the
      // code to set the host configuration transitions before we even create the target
      // configuration.
      if (config.isHostConfiguration() && config.getTransitions() != null) {
        continue;
      }
      config.setConfigurationTransitions(outgoingTransitions);
    }

    return targetConfiguration;
  }