Search in sources :

Example 36 with Artifact

use of com.google.devtools.build.lib.actions.Artifact in project bazel by bazelbuild.

the class CppCompileAction method validateInclusions.

/**
   * Enforce that the includes actually visited during the compile were properly
   * declared in the rules.
   *
   * <p>The technique is to walk through all of the reported includes that gcc
   * emits into the .d file, and verify that they came from acceptable
   * relative include directories. This is done in two steps:
   *
   * <p>First, each included file is stripped of any include path prefix from
   * {@code quoteIncludeDirs} to produce an effective relative include dir+name.
   *
   * <p>Second, the remaining directory is looked up in {@code declaredIncludeDirs},
   * a list of acceptable dirs. This list contains a set of dir fragments that
   * have been calculated by the configured target to be allowable for inclusion
   * by this source. If no match is found, an error is reported and an exception
   * is thrown.
   *
   * @throws ActionExecutionException iff there was an undeclared dependency
   */
@VisibleForTesting
public void validateInclusions(Iterable<Artifact> inputsForValidation, ArtifactExpander artifactExpander, EventHandler eventHandler) throws ActionExecutionException {
    IncludeProblems errors = new IncludeProblems();
    IncludeProblems warnings = new IncludeProblems();
    Set<Artifact> allowedIncludes = new HashSet<>();
    for (Artifact input : Iterables.concat(mandatoryInputs, prunableInputs)) {
        if (input.isMiddlemanArtifact() || input.isTreeArtifact()) {
            artifactExpander.expand(input, allowedIncludes);
        }
        allowedIncludes.add(input);
    }
    allowedIncludes.addAll(resolvedInputs);
    if (optionalSourceFile != null) {
        allowedIncludes.add(optionalSourceFile);
    }
    Iterable<PathFragment> ignoreDirs = cppConfiguration.isStrictSystemIncludes() ? cppConfiguration.getBuiltInIncludeDirectories() : getValidationIgnoredDirs();
    // Copy the sets to hash sets for fast contains checking.
    // Avoid immutable sets here to limit memory churn.
    Set<PathFragment> declaredIncludeDirs = Sets.newHashSet(context.getDeclaredIncludeDirs());
    Set<PathFragment> warnIncludeDirs = Sets.newHashSet(context.getDeclaredIncludeWarnDirs());
    Set<Artifact> declaredIncludeSrcs = Sets.newHashSet(getDeclaredIncludeSrcs());
    Set<Artifact> transitiveModules = Sets.newHashSet(context.getTransitiveModules(usePic));
    for (Artifact input : inputsForValidation) {
        if (context.getTransitiveCompilationPrerequisites().contains(input) || transitiveModules.contains(input) || allowedIncludes.contains(input)) {
            // ignore our fixed source in mandatoryInput: we just want includes
            continue;
        }
        // Ignore headers from built-in include directories.
        if (FileSystemUtils.startsWithAny(input.getExecPath(), ignoreDirs)) {
            continue;
        }
        if (!isDeclaredIn(input, declaredIncludeDirs, declaredIncludeSrcs)) {
            // There are no declared include sources we need to warn about, so use an empty set here.
            if (isDeclaredIn(input, warnIncludeDirs, ImmutableSet.<Artifact>of())) {
                warnings.add(input.getPath().toString());
            } else {
                errors.add(input.getPath().toString());
            }
        }
    }
    if (VALIDATION_DEBUG_WARN) {
        synchronized (System.err) {
            if (VALIDATION_DEBUG >= 2 || errors.hasProblems() || warnings.hasProblems()) {
                if (errors.hasProblems()) {
                    System.err.println("ERROR: Include(s) were not in declared srcs:");
                } else if (warnings.hasProblems()) {
                    System.err.println("WARN: Include(s) were not in declared srcs:");
                } else {
                    System.err.println("INFO: Include(s) were OK for '" + getSourceFile() + "', declared srcs:");
                }
                for (Artifact a : context.getDeclaredIncludeSrcs()) {
                    System.err.println("  '" + a.toDetailString() + "'");
                }
                System.err.println(" or under declared dirs:");
                for (PathFragment f : Sets.newTreeSet(context.getDeclaredIncludeDirs())) {
                    System.err.println("  '" + f + "'");
                }
                System.err.println(" or under declared warn dirs:");
                for (PathFragment f : Sets.newTreeSet(context.getDeclaredIncludeWarnDirs())) {
                    System.err.println("  '" + f + "'");
                }
                System.err.println(" with prefixes:");
                for (PathFragment dirpath : context.getQuoteIncludeDirs()) {
                    System.err.println("  '" + dirpath + "'");
                }
            }
        }
    }
    if (warnings.hasProblems()) {
        eventHandler.handle(Event.warn(getOwner().getLocation(), warnings.getMessage(this, getSourceFile())).withTag(Label.print(getOwner().getLabel())));
    }
    errors.assertProblemFree(this, getSourceFile());
}
Also used : PathFragment(com.google.devtools.build.lib.vfs.PathFragment) Artifact(com.google.devtools.build.lib.actions.Artifact) HashSet(java.util.HashSet) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 37 with Artifact

use of com.google.devtools.build.lib.actions.Artifact in project bazel by bazelbuild.

the class SkyframeAwareActionTest method testActionWithNonChangingInputAndNonChangingSkyframeDeps.

@Test
public void testActionWithNonChangingInputAndNonChangingSkyframeDeps() throws Exception {
    final SkyKey skyframeDep = FileStateValue.key(createSkyframeDepOfAction());
    // Assert that an action-cache-check-bypassing action is executed only once if neither its input
    // nor its Skyframe dependency changes between builds.
    assertActionExecutions(new ExecutionCountingActionFactory() {

        @Override
        public ExecutionCountingAction create(Artifact input, Artifact output, AtomicInteger executionCounter) {
            return new SkyframeAwareExecutionCountingAction(input, output, executionCounter, skyframeDep);
        }
    }, ChangeArtifact.DONT_CHANGE, new Callable<Void>() {

        @Override
        public Void call() throws Exception {
            // Invalidate the dependency but leave its value up-to-date, so the action should not
            // be rebuilt.
            differencer.invalidate(ImmutableList.of(skyframeDep));
            return null;
        }
    }, ExpectActionIs.DIRTIED_BUT_VERIFIED_CLEAN);
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Artifact(com.google.devtools.build.lib.actions.Artifact) ActionExecutionException(com.google.devtools.build.lib.actions.ActionExecutionException) IOException(java.io.IOException) Test(org.junit.Test)

Example 38 with Artifact

use of com.google.devtools.build.lib.actions.Artifact in project bazel by bazelbuild.

the class SkyframeAwareActionTest method assertActionExecutions.

private void assertActionExecutions(ExecutionCountingActionFactory actionFactory, ChangeArtifact changeActionInput, Callable<Void> betweenBuilds, ExpectActionIs expectActionIs) throws Exception {
    // Set up the action's input, output, owner and most importantly the execution counter.
    Artifact actionInput = createSourceArtifact("foo/action-input.txt");
    Artifact actionOutput = createDerivedArtifact("foo/action-output.txt");
    AtomicInteger executionCounter = new AtomicInteger(0);
    scratch.file(actionInput.getPath().getPathString(), "foo");
    // Generating actions of artifacts are found by looking them up in the graph. The lookup value
    // must be present in the graph before execution.
    Action action = actionFactory.create(actionInput, actionOutput, executionCounter);
    registerAction(action);
    // Build the output for the first time.
    builder.buildArtifacts(reporter, ImmutableSet.of(actionOutput), null, null, null, null, executor, null, false, null, null);
    // Sanity check that our invalidation receiver is working correctly. We'll rely on it again.
    SkyKey actionKey = ActionExecutionValue.key(action);
    TrackingEvaluationProgressReceiver.EvaluatedEntry evaluatedAction = progressReceiver.getEvalutedEntry(actionKey);
    assertThat(evaluatedAction).isNotNull();
    SkyValue actionValue = evaluatedAction.value;
    // Mutate the action input if requested.
    maybeChangeFile(actionInput, changeActionInput);
    // Execute user code before next build.
    betweenBuilds.call();
    // Rebuild the output.
    progressReceiver.reset();
    builder.buildArtifacts(reporter, ImmutableSet.of(actionOutput), null, null, null, null, executor, null, false, null, null);
    if (expectActionIs.dirtied()) {
        assertThat(progressReceiver.wasInvalidated(actionKey)).isTrue();
        TrackingEvaluationProgressReceiver.EvaluatedEntry newEntry = progressReceiver.getEvalutedEntry(actionKey);
        assertThat(newEntry).isNotNull();
        if (expectActionIs.actuallyClean()) {
            // Action was dirtied but verified clean.
            assertThat(newEntry.state).isEqualTo(EvaluationState.CLEAN);
            assertThat(newEntry.value).isEqualTo(actionValue);
        } else {
            // Action was dirtied and rebuilt. It was either reexecuted or was an action cache hit,
            // doesn't matter here.
            assertThat(newEntry.state).isEqualTo(EvaluationState.BUILT);
            assertThat(newEntry.value).isNotEqualTo(actionValue);
        }
    } else {
        // Action was not dirtied.
        assertThat(progressReceiver.wasInvalidated(actionKey)).isFalse();
    }
    // Assert that the action was executed the right number of times. Whether the action execution
    // function was called again is up for the test method to verify.
    assertThat(executionCounter.get()).isEqualTo(expectActionIs.reexecuted() ? 2 : 1);
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) SkyValue(com.google.devtools.build.skyframe.SkyValue) AbstractAction(com.google.devtools.build.lib.actions.AbstractAction) Action(com.google.devtools.build.lib.actions.Action) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Artifact(com.google.devtools.build.lib.actions.Artifact)

Example 39 with Artifact

use of com.google.devtools.build.lib.actions.Artifact in project bazel by bazelbuild.

the class TreeArtifactBuildTest method testOneExpandedActionThrowsInActionTemplate.

@Test
public void testOneExpandedActionThrowsInActionTemplate() throws Throwable {
    // expect errors
    reporter.removeHandler(failFastHandler);
    // artifact1 is a tree artifact generated by a TouchingTestAction.
    Artifact artifact1 = createTreeArtifact("treeArtifact1");
    TreeFileArtifact treeFileArtifactA = ActionInputHelper.treeFileArtifact(artifact1, new PathFragment("child1"));
    TreeFileArtifact treeFileArtifactB = ActionInputHelper.treeFileArtifact(artifact1, new PathFragment("child2"));
    registerAction(new TouchingTestAction(treeFileArtifactA, treeFileArtifactB));
    // artifact2 is a tree artifact generated by an action template.
    Artifact artifact2 = createTreeArtifact("treeArtifact2");
    SpawnActionTemplate actionTemplate = ActionsTestUtil.createDummySpawnActionTemplate(artifact1, artifact2);
    registerAction(actionTemplate);
    // We mock out the action template function to expand into two actions:
    // One Action that touches the output file.
    // The other action that just throws when executed.
    TreeFileArtifact expectedOutputTreeFileArtifact1 = ActionInputHelper.treeFileArtifact(artifact2, new PathFragment("child1"));
    TreeFileArtifact expectedOutputTreeFileArtifact2 = ActionInputHelper.treeFileArtifact(artifact2, new PathFragment("child2"));
    Action generateOutputAction = new DummyAction(ImmutableList.<Artifact>of(treeFileArtifactA), expectedOutputTreeFileArtifact1);
    Action throwingAction = new ThrowingDummyAction(ImmutableList.<Artifact>of(treeFileArtifactB), ImmutableList.<Artifact>of(expectedOutputTreeFileArtifact2));
    actionTemplateExpansionFunction = new DummyActionTemplateExpansionFunction(ImmutableMultimap.<ActionTemplate<?>, Action>of(actionTemplate, generateOutputAction, actionTemplate, throwingAction));
    try {
        buildArtifact(artifact2);
        fail("Expected BuildFailedException");
    } catch (BuildFailedException e) {
        assertThat(e.getMessage()).contains("Throwing dummy action");
    }
}
Also used : TreeFileArtifact(com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact) Action(com.google.devtools.build.lib.actions.Action) TestAction(com.google.devtools.build.lib.actions.util.TestAction) DummyAction(com.google.devtools.build.lib.actions.util.TestAction.DummyAction) BuildFailedException(com.google.devtools.build.lib.actions.BuildFailedException) DummyAction(com.google.devtools.build.lib.actions.util.TestAction.DummyAction) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) SpawnActionTemplate(com.google.devtools.build.lib.analysis.actions.SpawnActionTemplate) ActionTemplate(com.google.devtools.build.lib.analysis.actions.ActionTemplate) SpawnActionTemplate(com.google.devtools.build.lib.analysis.actions.SpawnActionTemplate) SpecialArtifact(com.google.devtools.build.lib.actions.Artifact.SpecialArtifact) Artifact(com.google.devtools.build.lib.actions.Artifact) ActionInputHelper.treeFileArtifact(com.google.devtools.build.lib.actions.ActionInputHelper.treeFileArtifact) TreeFileArtifact(com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact) Test(org.junit.Test)

Example 40 with Artifact

use of com.google.devtools.build.lib.actions.Artifact in project bazel by bazelbuild.

the class TreeArtifactBuildTest method testInputTreeArtifactPerActionFileCache.

@Test
public void testInputTreeArtifactPerActionFileCache() throws Exception {
    TouchingTestAction actionOne = new TouchingTestAction(outOneFileOne, outOneFileTwo);
    registerAction(actionOne);
    final Artifact normalOutput = createDerivedArtifact("normal/out");
    Action testAction = new TestAction(TestAction.NO_EFFECT, ImmutableList.of(outOne), ImmutableList.of(normalOutput)) {

        @Override
        public void execute(ActionExecutionContext actionExecutionContext) {
            try {
                // Check the file cache for input TreeFileArtifacts.
                ActionInputFileCache fileCache = actionExecutionContext.getActionInputFileCache();
                assertThat(fileCache.getDigest(outOneFileOne)).isNotNull();
                assertThat(fileCache.getDigest(outOneFileTwo)).isNotNull();
                // Touch the action output.
                touchFile(normalOutput);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    };
    registerAction(testAction);
    buildArtifact(normalOutput);
}
Also used : ActionInputFileCache(com.google.devtools.build.lib.actions.ActionInputFileCache) Action(com.google.devtools.build.lib.actions.Action) TestAction(com.google.devtools.build.lib.actions.util.TestAction) DummyAction(com.google.devtools.build.lib.actions.util.TestAction.DummyAction) ActionExecutionContext(com.google.devtools.build.lib.actions.ActionExecutionContext) SpecialArtifact(com.google.devtools.build.lib.actions.Artifact.SpecialArtifact) Artifact(com.google.devtools.build.lib.actions.Artifact) ActionInputHelper.treeFileArtifact(com.google.devtools.build.lib.actions.ActionInputHelper.treeFileArtifact) TreeFileArtifact(com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact) ActionExecutionException(com.google.devtools.build.lib.actions.ActionExecutionException) BuildFailedException(com.google.devtools.build.lib.actions.BuildFailedException) IOException(java.io.IOException) TestAction(com.google.devtools.build.lib.actions.util.TestAction) Test(org.junit.Test)

Aggregations

Artifact (com.google.devtools.build.lib.actions.Artifact)659 Test (org.junit.Test)242 PathFragment (com.google.devtools.build.lib.vfs.PathFragment)184 TreeFileArtifact (com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact)83 SpecialArtifact (com.google.devtools.build.lib.actions.Artifact.SpecialArtifact)65 NestedSetBuilder (com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder)64 ConfiguredTarget (com.google.devtools.build.lib.analysis.ConfiguredTarget)51 RuleConfiguredTargetBuilder (com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder)50 ImmutableList (com.google.common.collect.ImmutableList)46 Action (com.google.devtools.build.lib.actions.Action)42 IOException (java.io.IOException)42 ArrayList (java.util.ArrayList)40 SpawnAction (com.google.devtools.build.lib.analysis.actions.SpawnAction)38 Path (com.google.devtools.build.lib.vfs.Path)37 HashMap (java.util.HashMap)37 Map (java.util.Map)36 Root (com.google.devtools.build.lib.actions.Root)31 LinkedHashMap (java.util.LinkedHashMap)31 ImmutableMap (com.google.common.collect.ImmutableMap)28 TransitiveInfoCollection (com.google.devtools.build.lib.analysis.TransitiveInfoCollection)28