Search in sources :

Example 41 with Rule

use of com.google.devtools.build.lib.packages.Rule in project bazel by bazelbuild.

the class BuildView method getDirectPrerequisiteDependenciesForTesting.

@VisibleForTesting
public OrderedSetMultimap<Attribute, Dependency> getDirectPrerequisiteDependenciesForTesting(final ExtendedEventHandler eventHandler, final ConfiguredTarget ct, BuildConfigurationCollection configurations) throws EvalException, InvalidConfigurationException, InterruptedException, InconsistentAspectOrderException {
    if (!(ct.getTarget() instanceof Rule)) {
        return OrderedSetMultimap.create();
    }
    class SilentDependencyResolver extends DependencyResolver {

        @Override
        protected void invalidVisibilityReferenceHook(TargetAndConfiguration node, Label label) {
            throw new RuntimeException("bad visibility on " + label + " during testing unexpected");
        }

        @Override
        protected void invalidPackageGroupReferenceHook(TargetAndConfiguration node, Label label) {
            throw new RuntimeException("bad package group on " + label + " during testing unexpected");
        }

        @Override
        protected void missingEdgeHook(Target from, Label to, NoSuchThingException e) {
            throw new RuntimeException("missing dependency from " + from.getLabel() + " to " + to + ": " + e.getMessage(), e);
        }

        @Override
        protected Target getTarget(Target from, Label label, NestedSetBuilder<Label> rootCauses) throws InterruptedException {
            try {
                return skyframeExecutor.getPackageManager().getTarget(eventHandler, label);
            } catch (NoSuchThingException e) {
                throw new IllegalStateException(e);
            }
        }

        @Override
        protected List<BuildConfiguration> getConfigurations(Set<Class<? extends BuildConfiguration.Fragment>> fragments, Iterable<BuildOptions> buildOptions) {
            Preconditions.checkArgument(ct.getConfiguration().fragmentClasses().equals(fragments));
            Dependency asDep = Dependency.withTransitionAndAspects(ct.getLabel(), Attribute.ConfigurationTransition.NONE, AspectCollection.EMPTY);
            ImmutableList.Builder<BuildConfiguration> builder = ImmutableList.builder();
            for (BuildOptions options : buildOptions) {
                builder.add(Iterables.getOnlyElement(skyframeExecutor.getConfigurations(eventHandler, options, ImmutableList.<Dependency>of(asDep)).values()));
            }
            return builder.build();
        }
    }
    DependencyResolver dependencyResolver = new SilentDependencyResolver();
    TargetAndConfiguration ctgNode = new TargetAndConfiguration(ct.getTarget(), ct.getConfiguration());
    return dependencyResolver.dependentNodeMap(ctgNode, configurations.getHostConfiguration(), /*aspect=*/
    null, getConfigurableAttributeKeysForTesting(eventHandler, ctgNode));
}
Also used : ImmutableSet(com.google.common.collect.ImmutableSet) Set(java.util.Set) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) NestedSet(com.google.devtools.build.lib.collect.nestedset.NestedSet) ImmutableList(com.google.common.collect.ImmutableList) Label(com.google.devtools.build.lib.cmdline.Label) BuildConfiguration(com.google.devtools.build.lib.analysis.config.BuildConfiguration) Target(com.google.devtools.build.lib.packages.Target) NoSuchThingException(com.google.devtools.build.lib.packages.NoSuchThingException) NestedSetBuilder(com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder) BuildOptions(com.google.devtools.build.lib.analysis.config.BuildOptions) Rule(com.google.devtools.build.lib.packages.Rule) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 42 with Rule

use of com.google.devtools.build.lib.packages.Rule in project bazel by bazelbuild.

the class BuildView method update.

@ThreadCompatible
public AnalysisResult update(LoadingResult loadingResult, BuildConfigurationCollection configurations, List<String> aspects, Options viewOptions, TopLevelArtifactContext topLevelOptions, ExtendedEventHandler eventHandler, EventBus eventBus) throws ViewCreationFailedException, InterruptedException {
    LOG.info("Starting analysis");
    pollInterruptedStatus();
    skyframeBuildView.resetEvaluatedConfiguredTargetKeysSet();
    Collection<Target> targets = loadingResult.getTargets();
    eventBus.post(new AnalysisPhaseStartedEvent(targets));
    skyframeBuildView.setConfigurations(configurations);
    // Determine the configurations.
    List<TargetAndConfiguration> topLevelTargetsWithConfigs = nodesForTopLevelTargets(configurations, targets, eventHandler);
    List<ConfiguredTargetKey> topLevelCtKeys = Lists.transform(topLevelTargetsWithConfigs, new Function<TargetAndConfiguration, ConfiguredTargetKey>() {

        @Override
        public ConfiguredTargetKey apply(TargetAndConfiguration node) {
            return new ConfiguredTargetKey(node.getLabel(), node.getConfiguration());
        }
    });
    List<AspectValueKey> aspectKeys = new ArrayList<>();
    for (String aspect : aspects) {
        // Syntax: label%aspect
        int delimiterPosition = aspect.indexOf('%');
        if (delimiterPosition >= 0) {
            // TODO(jfield): For consistency with Skylark loads, the aspect should be specified
            // as an absolute path. Also, we probably need to do at least basic validation of
            // path well-formedness here.
            String bzlFileLoadLikeString = aspect.substring(0, delimiterPosition);
            if (!bzlFileLoadLikeString.startsWith("//") && !bzlFileLoadLikeString.startsWith("@")) {
                // "Legacy" behavior of '--aspects' parameter.
                bzlFileLoadLikeString = new PathFragment("/" + bzlFileLoadLikeString).toString();
                if (bzlFileLoadLikeString.endsWith(".bzl")) {
                    bzlFileLoadLikeString = bzlFileLoadLikeString.substring(0, bzlFileLoadLikeString.length() - ".bzl".length());
                }
            }
            SkylarkImport skylarkImport;
            try {
                skylarkImport = SkylarkImports.create(bzlFileLoadLikeString);
            } catch (SkylarkImportSyntaxException e) {
                throw new ViewCreationFailedException(String.format("Invalid aspect '%s': %s", aspect, e.getMessage()), e);
            }
            String skylarkFunctionName = aspect.substring(delimiterPosition + 1);
            for (TargetAndConfiguration targetSpec : topLevelTargetsWithConfigs) {
                if (!(targetSpec.getTarget() instanceof Rule)) {
                    continue;
                }
                aspectKeys.add(AspectValue.createSkylarkAspectKey(targetSpec.getLabel(), // aspect and the base target while the top-level configuration is untrimmed.
                targetSpec.getConfiguration(), targetSpec.getConfiguration(), skylarkImport, skylarkFunctionName));
            }
        } else {
            final NativeAspectClass aspectFactoryClass = ruleClassProvider.getNativeAspectClassMap().get(aspect);
            if (aspectFactoryClass != null) {
                for (TargetAndConfiguration targetSpec : topLevelTargetsWithConfigs) {
                    if (!(targetSpec.getTarget() instanceof Rule)) {
                        continue;
                    }
                    // For invoking top-level aspects, use the top-level configuration for both the
                    // aspect and the base target while the top-level configuration is untrimmed.
                    BuildConfiguration configuration = targetSpec.getConfiguration();
                    aspectKeys.add(AspectValue.createAspectKey(targetSpec.getLabel(), configuration, new AspectDescriptor(aspectFactoryClass, AspectParameters.EMPTY), configuration));
                }
            } else {
                throw new ViewCreationFailedException("Aspect '" + aspect + "' is unknown");
            }
        }
    }
    skyframeExecutor.injectWorkspaceStatusData(loadingResult.getWorkspaceName());
    SkyframeAnalysisResult skyframeAnalysisResult;
    try {
        skyframeAnalysisResult = skyframeBuildView.configureTargets(eventHandler, topLevelCtKeys, aspectKeys, eventBus, viewOptions.keepGoing, viewOptions.loadingPhaseThreads);
        setArtifactRoots(skyframeAnalysisResult.getPackageRoots());
    } finally {
        skyframeBuildView.clearInvalidatedConfiguredTargets();
    }
    int numTargetsToAnalyze = topLevelTargetsWithConfigs.size();
    int numSuccessful = skyframeAnalysisResult.getConfiguredTargets().size();
    if (0 < numSuccessful && numSuccessful < numTargetsToAnalyze) {
        String msg = String.format("Analysis succeeded for only %d of %d top-level targets", numSuccessful, numTargetsToAnalyze);
        eventHandler.handle(Event.info(msg));
        LOG.info(msg);
    }
    AnalysisResult result = createResult(eventHandler, loadingResult, topLevelOptions, viewOptions, skyframeAnalysisResult);
    LOG.info("Finished analysis");
    return result;
}
Also used : SkylarkImportSyntaxException(com.google.devtools.build.lib.syntax.SkylarkImports.SkylarkImportSyntaxException) SkyframeAnalysisResult(com.google.devtools.build.lib.skyframe.SkyframeAnalysisResult) ArrayList(java.util.ArrayList) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) SkyframeAnalysisResult(com.google.devtools.build.lib.skyframe.SkyframeAnalysisResult) SkylarkImport(com.google.devtools.build.lib.syntax.SkylarkImport) BuildConfiguration(com.google.devtools.build.lib.analysis.config.BuildConfiguration) Target(com.google.devtools.build.lib.packages.Target) AspectValueKey(com.google.devtools.build.lib.skyframe.AspectValue.AspectValueKey) NativeAspectClass(com.google.devtools.build.lib.packages.NativeAspectClass) AspectDescriptor(com.google.devtools.build.lib.packages.AspectDescriptor) Rule(com.google.devtools.build.lib.packages.Rule) ConfiguredTargetKey(com.google.devtools.build.lib.skyframe.ConfiguredTargetKey) ThreadCompatible(com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadCompatible)

Example 43 with Rule

use of com.google.devtools.build.lib.packages.Rule in project bazel by bazelbuild.

the class BuildView method getConfigurableAttributeKeysForTesting.

/**
   * Returns ConfigMatchingProvider instances corresponding to the configurable attribute keys
   * present in this rule's attributes.
   */
private ImmutableMap<Label, ConfigMatchingProvider> getConfigurableAttributeKeysForTesting(ExtendedEventHandler eventHandler, TargetAndConfiguration ctg) {
    if (!(ctg.getTarget() instanceof Rule)) {
        return ImmutableMap.of();
    }
    Rule rule = (Rule) ctg.getTarget();
    Map<Label, ConfigMatchingProvider> keys = new LinkedHashMap<>();
    RawAttributeMapper mapper = RawAttributeMapper.of(rule);
    for (Attribute attribute : rule.getAttributes()) {
        for (Label label : mapper.getConfigurabilityKeys(attribute.getName(), attribute.getType())) {
            if (BuildType.Selector.isReservedLabel(label)) {
                continue;
            }
            ConfiguredTarget ct = getConfiguredTargetForTesting(eventHandler, label, ctg.getConfiguration());
            keys.put(label, Preconditions.checkNotNull(ct.getProvider(ConfigMatchingProvider.class)));
        }
    }
    return ImmutableMap.copyOf(keys);
}
Also used : RawAttributeMapper(com.google.devtools.build.lib.packages.RawAttributeMapper) Attribute(com.google.devtools.build.lib.packages.Attribute) Label(com.google.devtools.build.lib.cmdline.Label) ConfigMatchingProvider(com.google.devtools.build.lib.analysis.config.ConfigMatchingProvider) Rule(com.google.devtools.build.lib.packages.Rule) LinkedHashMap(java.util.LinkedHashMap)

Example 44 with Rule

use of com.google.devtools.build.lib.packages.Rule in project bazel by bazelbuild.

the class ConfiguredTargetFactory method getOutputArtifact.

private Artifact getOutputArtifact(OutputFile outputFile, BuildConfiguration configuration, boolean isFileset, ArtifactFactory artifactFactory) {
    Rule rule = outputFile.getAssociatedRule();
    Root root = rule.hasBinaryOutput() ? configuration.getBinDirectory(rule.getRepository()) : configuration.getGenfilesDirectory(rule.getRepository());
    ArtifactOwner owner = new ConfiguredTargetKey(rule.getLabel(), configuration.getArtifactOwnerConfiguration());
    PathFragment rootRelativePath = outputFile.getLabel().getPackageIdentifier().getSourceRoot().getRelative(outputFile.getLabel().getName());
    Artifact result = isFileset ? artifactFactory.getFilesetArtifact(rootRelativePath, root, owner) : artifactFactory.getDerivedArtifact(rootRelativePath, root, owner);
    // The associated rule should have created the artifact.
    Preconditions.checkNotNull(result, "no artifact for %s", rootRelativePath);
    return result;
}
Also used : ArtifactOwner(com.google.devtools.build.lib.actions.ArtifactOwner) Root(com.google.devtools.build.lib.actions.Root) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) Rule(com.google.devtools.build.lib.packages.Rule) ConfiguredTargetKey(com.google.devtools.build.lib.skyframe.ConfiguredTargetKey) Artifact(com.google.devtools.build.lib.actions.Artifact)

Example 45 with Rule

use of com.google.devtools.build.lib.packages.Rule in project bazel by bazelbuild.

the class DependencyResolver method dependentNodeMap.

/**
   * Returns ids for dependent nodes of a given node, sorted by attribute. Note that some
   * dependencies do not have a corresponding attribute here, and we use the null attribute to
   * represent those edges.
   *
   * <p>If {@code aspects} is empty, returns the dependent nodes of the configured target node
   * representing the given target and configuration.
   *
   * Otherwise {@code aspects} represents an aspect path. The function returns dependent nodes
   * of the entire path applied to given target and configuration. These are the depenent nodes
   * of the last aspect in the path.
   *
   * <p>This also implements the first step of applying
   * configuration transitions, namely, split transitions. This needs to be done before the labels
   * are resolved because late bound attributes depend on the configuration. A good example for this
   * is @{code :cc_toolchain}.
   *
   * <p>The long-term goal is that most configuration transitions be applied here. However, in order
   * to do that, we first have to eliminate transitions that depend on the rule class of the
   * dependency.
   *
   * @param node the target/configuration being evaluated
   * @param hostConfig the configuration this target would use if it was evaluated as a host tool.
   *     This is needed to support {@link LateBoundDefault#useHostConfiguration()}.
   * @param aspects the aspects applied to this target (if any)
   * @param configConditions resolver for config_setting labels
   * @param rootCauses collector for dep labels that can't be (loading phase) loaded
   * @return a mapping of each attribute in this rule or aspects to its dependent nodes
   */
public final OrderedSetMultimap<Attribute, Dependency> dependentNodeMap(TargetAndConfiguration node, BuildConfiguration hostConfig, Iterable<Aspect> aspects, ImmutableMap<Label, ConfigMatchingProvider> configConditions, NestedSetBuilder<Label> rootCauses) throws EvalException, InvalidConfigurationException, InterruptedException, InconsistentAspectOrderException {
    Target target = node.getTarget();
    BuildConfiguration config = node.getConfiguration();
    OrderedSetMultimap<Attribute, Dependency> outgoingEdges = OrderedSetMultimap.create();
    if (target instanceof OutputFile) {
        Preconditions.checkNotNull(config);
        visitTargetVisibility(node, rootCauses, outgoingEdges.get(null));
        Rule rule = ((OutputFile) target).getGeneratingRule();
        outgoingEdges.put(null, Dependency.withConfiguration(rule.getLabel(), config));
    } else if (target instanceof InputFile) {
        visitTargetVisibility(node, rootCauses, outgoingEdges.get(null));
    } else if (target instanceof EnvironmentGroup) {
        visitTargetVisibility(node, rootCauses, outgoingEdges.get(null));
    } else if (target instanceof Rule) {
        visitRule(node, hostConfig, aspects, configConditions, rootCauses, outgoingEdges);
    } else if (target instanceof PackageGroup) {
        visitPackageGroup(node, (PackageGroup) target, rootCauses, outgoingEdges.get(null));
    } else {
        throw new IllegalStateException(target.getLabel().toString());
    }
    return outgoingEdges;
}
Also used : BuildConfiguration(com.google.devtools.build.lib.analysis.config.BuildConfiguration) OutputFile(com.google.devtools.build.lib.packages.OutputFile) EnvironmentGroup(com.google.devtools.build.lib.packages.EnvironmentGroup) Target(com.google.devtools.build.lib.packages.Target) Attribute(com.google.devtools.build.lib.packages.Attribute) Rule(com.google.devtools.build.lib.packages.Rule) PackageGroup(com.google.devtools.build.lib.packages.PackageGroup) InputFile(com.google.devtools.build.lib.packages.InputFile)

Aggregations

Rule (com.google.devtools.build.lib.packages.Rule)79 Test (org.junit.Test)27 Label (com.google.devtools.build.lib.cmdline.Label)26 Attribute (com.google.devtools.build.lib.packages.Attribute)20 Target (com.google.devtools.build.lib.packages.Target)19 Nullable (javax.annotation.Nullable)10 RawAttributeMapper (com.google.devtools.build.lib.packages.RawAttributeMapper)9 PathFragment (com.google.devtools.build.lib.vfs.PathFragment)9 OutputFile (com.google.devtools.build.lib.packages.OutputFile)8 BuildConfiguration (com.google.devtools.build.lib.analysis.config.BuildConfiguration)7 NoSuchThingException (com.google.devtools.build.lib.packages.NoSuchThingException)7 SkyKey (com.google.devtools.build.skyframe.SkyKey)7 ImmutableList (com.google.common.collect.ImmutableList)6 InputFile (com.google.devtools.build.lib.packages.InputFile)6 IOException (java.io.IOException)6 LinkedHashSet (java.util.LinkedHashSet)6 AggregatingAttributeMapper (com.google.devtools.build.lib.packages.AggregatingAttributeMapper)5 Package (com.google.devtools.build.lib.packages.Package)5 Artifact (com.google.devtools.build.lib.actions.Artifact)4 ConfiguredTarget (com.google.devtools.build.lib.analysis.ConfiguredTarget)4