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());
}
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));
}
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")));
}
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);
}
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");
}
}
Aggregations