Search in sources :

Example 31 with PathFragment

use of com.google.devtools.build.lib.vfs.PathFragment 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 32 with PathFragment

use of com.google.devtools.build.lib.vfs.PathFragment in project bazel by bazelbuild.

the class RecursivePkgFunctionTest method testExcludedSubdirectoryGettingPassedDown.

@Test
public void testExcludedSubdirectoryGettingPassedDown() throws Exception {
    // Given a package "a" with two packages below a directory below it, "a/b/c" and "a/b/d",
    scratch.file("a/BUILD");
    scratch.file("a/b/c/BUILD");
    scratch.file("a/b/d/BUILD");
    // When the top package is evaluated for recursive package values, and "a/b/c" is excluded,
    ImmutableSet<PathFragment> excludedPaths = ImmutableSet.of(new PathFragment("a/b/c"));
    SkyKey key = buildRecursivePkgKey(rootDirectory, new PathFragment("a"), excludedPaths);
    EvaluationResult<RecursivePkgValue> evaluationResult = getEvaluationResult(key);
    RecursivePkgValue value = evaluationResult.get(key);
    // Then the package corresponding to the excluded subdirectory is not present in the result,
    assertThat(value.getPackages()).doesNotContain("a/b/c");
    // And the top package and other subsubdirectory package are.
    assertThat(value.getPackages()).contains("a");
    assertThat(value.getPackages()).contains("a/b/d");
    // Also, the computation graph contains a cached value for "a/b" with "a/b/c" excluded, because
    // "a/b/c" does live underneath "a/b".
    WalkableGraph graph = Preconditions.checkNotNull(evaluationResult.getWalkableGraph());
    assertTrue(exists(buildRecursivePkgKey(rootDirectory, new PathFragment("a/b"), excludedPaths), graph));
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) WalkableGraph(com.google.devtools.build.skyframe.WalkableGraph) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) Test(org.junit.Test)

Example 33 with PathFragment

use of com.google.devtools.build.lib.vfs.PathFragment in project bazel by bazelbuild.

the class RecursivePkgKeyTest method testInvalidRecursivePkgKeys.

@Test
public void testInvalidRecursivePkgKeys() throws Exception {
    invalidHelper(new PathFragment(""), ImmutableSet.of(new PathFragment("")));
    invalidHelper(new PathFragment("a"), ImmutableSet.of(new PathFragment("a")));
    invalidHelper(new PathFragment("a"), ImmutableSet.of(new PathFragment("b")));
    invalidHelper(new PathFragment("a/b"), ImmutableSet.of(new PathFragment("a")));
}
Also used : PathFragment(com.google.devtools.build.lib.vfs.PathFragment) Test(org.junit.Test)

Example 34 with PathFragment

use of com.google.devtools.build.lib.vfs.PathFragment in project bazel by bazelbuild.

the class SkyframeLabelVisitorTest method testSubpackageBoundarySubincludes.

// Regression test for: "package loading ignores subincludes for purposes of checking for
// subpackages cutting of labels"
//
// Indirectly tests that there are dependencies between a package and other packages that could
// potentially cutoff its subincludes.
@Test
public void testSubpackageBoundarySubincludes() throws Exception {
    // This test uses the python preprocessor.
    preprocessorFactorySupplier.inject(new SubincludePreprocessor(scratch.getFileSystem(), getSkyframeExecutor().getPackageManager()));
    PackageCacheOptions packageCacheOptions = Options.getDefaults(PackageCacheOptions.class);
    packageCacheOptions.defaultVisibility = ConstantRuleVisibility.PRIVATE;
    packageCacheOptions.showLoadingProgress = true;
    packageCacheOptions.globbingThreads = 7;
    getSkyframeExecutor().preparePackageLoading(new PathPackageLocator(outputBase, ImmutableList.of(rootDirectory)), packageCacheOptions, loadingMock.getDefaultsPackageContent(), UUID.randomUUID(), ImmutableMap.<String, String>of(), ImmutableMap.<String, String>of(), new TimestampGranularityMonitor(BlazeClock.instance()));
    this.visitor = getSkyframeExecutor().pkgLoader();
    scratch.file("a/BUILD", "subinclude('//b:c/d/foo')");
    scratch.file("b/BUILD", "exports_files(['c/d/foo'])");
    scratch.file("b/c/d/foo", "sh_library(name = 'a')");
    assertLabelsVisited(ImmutableSet.of("//a:a"), ImmutableSet.of("//a:a"), !EXPECT_ERROR, !KEEP_GOING);
    Path subpackageBuildFile = scratch.file("b/c/BUILD", "exports_files(['foo'])");
    syncPackages(ModifiedFileSet.builder().modify(new PathFragment("b/c/BUILD")).build());
    // expect errors
    reporter.removeHandler(failFastHandler);
    assertLabelsVisitedWithErrors(ImmutableSet.of("//a:a"), ImmutableSet.of("//a:a"));
    assertContainsEvent("Label '//b:c/d/foo' crosses boundary of subpackage 'b/c'");
    subpackageBuildFile.delete();
    syncPackages(ModifiedFileSet.builder().modify(new PathFragment("b/c/BUILD")).build());
    assertLabelsVisited(ImmutableSet.of("//a:a"), ImmutableSet.of("//a:a"), !EXPECT_ERROR, !KEEP_GOING);
}
Also used : PathPackageLocator(com.google.devtools.build.lib.pkgcache.PathPackageLocator) Path(com.google.devtools.build.lib.vfs.Path) SubincludePreprocessor(com.google.devtools.build.lib.packages.util.SubincludePreprocessor) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) PackageCacheOptions(com.google.devtools.build.lib.pkgcache.PackageCacheOptions) TimestampGranularityMonitor(com.google.devtools.build.lib.util.io.TimestampGranularityMonitor) Test(org.junit.Test)

Example 35 with PathFragment

use of com.google.devtools.build.lib.vfs.PathFragment 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)

Aggregations

PathFragment (com.google.devtools.build.lib.vfs.PathFragment)512 Test (org.junit.Test)208 Artifact (com.google.devtools.build.lib.actions.Artifact)184 Path (com.google.devtools.build.lib.vfs.Path)111 RootedPath (com.google.devtools.build.lib.vfs.RootedPath)65 SkyKey (com.google.devtools.build.skyframe.SkyKey)56 IOException (java.io.IOException)38 ArrayList (java.util.ArrayList)35 ImmutableList (com.google.common.collect.ImmutableList)32 Root (com.google.devtools.build.lib.actions.Root)32 HashMap (java.util.HashMap)27 Label (com.google.devtools.build.lib.cmdline.Label)26 LinkedHashMap (java.util.LinkedHashMap)26 TreeFileArtifact (com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact)23 ImmutableMap (com.google.common.collect.ImmutableMap)22 Map (java.util.Map)21 SpecialArtifact (com.google.devtools.build.lib.actions.Artifact.SpecialArtifact)20 FilesetTraversalParams (com.google.devtools.build.lib.actions.FilesetTraversalParams)16 PackageIdentifier (com.google.devtools.build.lib.cmdline.PackageIdentifier)16 NestedSetBuilder (com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder)16