Example #1
0
  public ImmutableSet<TargetNode<?>> getAllTargetNodes(
      final BuckEventBus eventBus,
      final Cell cell,
      ProjectBuildFileParser parser,
      final Path buildFile,
      final TargetNodeListener nodeListener)
      throws BuildFileParseException, InterruptedException {
    Preconditions.checkState(buildFile.isAbsolute());
    invalidateIfProjectBuildFileParserStateChanged(cell);
    try {
      List<Map<String, Object>> allRawNodes = loadRawNodes(cell, buildFile, parser);

      ImmutableSet.Builder<TargetNode<?>> nodes = ImmutableSet.builder();
      for (final Map<String, Object> rawNode : allRawNodes) {
        UnflavoredBuildTarget unflavored = parseBuildTargetFromRawRule(cell.getRoot(), rawNode);
        final BuildTarget target = BuildTarget.of(unflavored);

        TargetNode<?> node =
            allTargetNodes.get(
                target,
                new Callable<TargetNode<?>>() {
                  @Override
                  public TargetNode<?> call() throws Exception {
                    return createTargetNode(
                        eventBus, cell, buildFile, target, rawNode, nodeListener);
                  }
                });

        nodes.add(node);
      }
      return nodes.build();
    } catch (UncheckedExecutionException | ExecutionException e) {
      throw propagate(e);
    }
  }
  @Test
  public void coerceCrossRepoBuildTarget() throws CoerceFailedException, IOException {
    final Path helloRoot = Paths.get("/opt/src/hello");

    cellRoots =
        new Function<Optional<String>, Path>() {
          @Override
          public Path apply(Optional<String> input) {
            if (!input.isPresent()) {
              return projectFilesystem.getRootPath();
            }

            if ("hello".equals(input.get())) {
              return helloRoot;
            }

            throw new RuntimeException("Boom!");
          }
        };

    SourcePath sourcePath =
        sourcePathTypeCoercer.coerce(
            cellRoots, projectFilesystem, pathRelativeToProjectRoot, "@hello//:hello");

    assertEquals(
        new BuildTargetSourcePath(
            BuildTarget.of(
                UnflavoredBuildTarget.of(helloRoot, Optional.of("hello"), "//", "hello"),
                ImmutableSortedSet.<Flavor>of())),
        sourcePath);
  }
  @Test
  public void coerceRelativeBuildTarget() throws CoerceFailedException, IOException {
    SourcePath sourcePath =
        sourcePathTypeCoercer.coerce(
            cellRoots, projectFilesystem, pathRelativeToProjectRoot, ":hello");

    assertEquals(
        new BuildTargetSourcePath(
            BuildTarget.of(
                UnflavoredBuildTarget.of(
                    projectFilesystem.getRootPath(), Optional.<String>absent(), "//", "hello"),
                ImmutableSortedSet.<Flavor>of())),
        sourcePath);
  }
  @Test
  public void createLexYaccBuildRules() throws IOException {
    BuildRuleResolver resolver = new BuildRuleResolver();

    // Setup our C++ buck config with the paths to the lex/yacc binaries.
    FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
    Path lexPath = Paths.get("lex");
    filesystem.touch(lexPath);
    Path yaccPath = Paths.get("yacc");
    filesystem.touch(yaccPath);
    BuckConfig buckConfig =
        FakeBuckConfig.builder()
            .setSections(
                ImmutableMap.of(
                    "cxx",
                    ImmutableMap.of(
                        "lex", lexPath.toString(),
                        "yacc", yaccPath.toString())))
            .setFilesystem(filesystem)
            .build();
    CxxPlatform cxxBuckConfig = DefaultCxxPlatforms.build(new CxxBuckConfig(buckConfig));

    // Setup the target name and build params.
    UnflavoredBuildTarget target =
        BuildTargetFactory.newInstance("//:test").getUnflavoredBuildTarget();
    BuildRuleParams params = new FakeBuildRuleParamsBuilder(BuildTarget.of(target)).build();

    // Setup a genrule that generates our lex source.
    String lexSourceName = "test.ll";
    BuildTarget genruleTarget = BuildTargetFactory.newInstance("//:genrule_lex");
    Genrule genrule =
        (Genrule)
            GenruleBuilder.newGenruleBuilder(genruleTarget).setOut(lexSourceName).build(resolver);
    SourcePath lexSource = new BuildTargetSourcePath(genrule.getBuildTarget());

    // Use a regular path for our yacc source.
    String yaccSourceName = "test.yy";
    SourcePath yaccSource = new TestSourcePath(yaccSourceName);

    // Build the rules.
    CxxHeaderSourceSpec actual =
        CxxDescriptionEnhancer.createLexYaccBuildRules(
            params,
            resolver,
            cxxBuckConfig,
            ImmutableList.<String>of(),
            ImmutableMap.of(lexSourceName, lexSource),
            ImmutableList.<String>of(),
            ImmutableMap.of(yaccSourceName, yaccSource));

    // Grab the generated lex rule and verify it has the genrule as a dep.
    Lex lex =
        (Lex) resolver.getRule(CxxDescriptionEnhancer.createLexBuildTarget(target, lexSourceName));
    assertNotNull(lex);
    assertEquals(ImmutableSortedSet.<BuildRule>of(genrule), lex.getDeps());

    // Grab the generated yacc rule and verify it has no deps.
    Yacc yacc =
        (Yacc)
            resolver.getRule(CxxDescriptionEnhancer.createYaccBuildTarget(target, yaccSourceName));
    assertNotNull(yacc);
    assertEquals(ImmutableSortedSet.<BuildRule>of(), yacc.getDeps());

    // Check the header/source spec is correct.
    Path lexOutputSource = CxxDescriptionEnhancer.getLexSourceOutputPath(target, lexSourceName);
    Path lexOutputHeader = CxxDescriptionEnhancer.getLexHeaderOutputPath(target, lexSourceName);
    Path yaccOutputPrefix =
        CxxDescriptionEnhancer.getYaccOutputPrefix(
            target, Files.getNameWithoutExtension(yaccSourceName));
    Path yaccOutputSource = Yacc.getSourceOutputPath(yaccOutputPrefix);
    Path yaccOutputHeader = Yacc.getHeaderOutputPath(yaccOutputPrefix);
    CxxHeaderSourceSpec expected =
        CxxHeaderSourceSpec.of(
            ImmutableMap.<Path, SourcePath>of(
                target.getBasePath().resolve(lexSourceName + ".h"),
                new BuildTargetSourcePath(lex.getBuildTarget(), lexOutputHeader),
                target.getBasePath().resolve(yaccSourceName + ".h"),
                new BuildTargetSourcePath(yacc.getBuildTarget(), yaccOutputHeader)),
            ImmutableMap.of(
                lexSourceName + ".cc",
                CxxSource.of(
                    CxxSource.Type.CXX,
                    new BuildTargetSourcePath(lex.getBuildTarget(), lexOutputSource),
                    ImmutableList.<String>of()),
                yaccSourceName + ".cc",
                CxxSource.of(
                    CxxSource.Type.CXX,
                    new BuildTargetSourcePath(yacc.getBuildTarget(), yaccOutputSource),
                    ImmutableList.<String>of())));
    assertEquals(expected, actual);
  }
  public static ImmutableList<CxxPreprocessorInput> collectCxxPreprocessorInput(
      TargetGraph targetGraph,
      BuildRuleParams params,
      CxxPlatform cxxPlatform,
      ImmutableMultimap<CxxSource.Type, String> preprocessorFlags,
      ImmutableList<HeaderSymlinkTree> headerSymlinkTrees,
      ImmutableSet<Path> frameworkSearchPaths,
      Iterable<CxxPreprocessorInput> cxxPreprocessorInputFromDeps) {

    // Add the private includes of any rules which list this rule as a test.
    BuildTarget targetWithoutFlavor =
        BuildTarget.of(params.getBuildTarget().getUnflavoredBuildTarget());
    ImmutableList.Builder<CxxPreprocessorInput> cxxPreprocessorInputFromTestedRulesBuilder =
        ImmutableList.builder();
    for (BuildRule rule : params.getDeps()) {
      if (rule instanceof NativeTestable) {
        NativeTestable testable = (NativeTestable) rule;
        if (testable.isTestedBy(targetWithoutFlavor)) {
          LOG.debug(
              "Adding private includes of tested rule %s to testing rule %s",
              rule.getBuildTarget(), params.getBuildTarget());
          cxxPreprocessorInputFromTestedRulesBuilder.add(
              testable.getCxxPreprocessorInput(targetGraph, cxxPlatform, HeaderVisibility.PRIVATE));
        }
      }
    }

    ImmutableList<CxxPreprocessorInput> cxxPreprocessorInputFromTestedRules =
        cxxPreprocessorInputFromTestedRulesBuilder.build();
    LOG.verbose(
        "Rules tested by target %s added private includes %s",
        params.getBuildTarget(), cxxPreprocessorInputFromTestedRules);

    ImmutableMap.Builder<Path, SourcePath> allLinks = ImmutableMap.builder();
    ImmutableMap.Builder<Path, SourcePath> allFullLinks = ImmutableMap.builder();
    ImmutableList.Builder<Path> allIncludeRoots = ImmutableList.builder();
    ImmutableSet.Builder<Path> allHeaderMaps = ImmutableSet.builder();
    for (HeaderSymlinkTree headerSymlinkTree : headerSymlinkTrees) {
      allLinks.putAll(headerSymlinkTree.getLinks());
      allFullLinks.putAll(headerSymlinkTree.getFullLinks());
      allIncludeRoots.add(headerSymlinkTree.getIncludePath());
      allHeaderMaps.addAll(headerSymlinkTree.getHeaderMap().asSet());
    }

    CxxPreprocessorInput localPreprocessorInput =
        CxxPreprocessorInput.builder()
            .addAllRules(Iterables.transform(headerSymlinkTrees, HasBuildTarget.TO_TARGET))
            .putAllPreprocessorFlags(preprocessorFlags)
            .setIncludes(
                CxxHeaders.builder()
                    .putAllNameToPathMap(allLinks.build())
                    .putAllFullNameToPathMap(allFullLinks.build())
                    .build())
            .addAllIncludeRoots(allIncludeRoots.build())
            .addAllHeaderMaps(allHeaderMaps.build())
            .addAllFrameworkRoots(frameworkSearchPaths)
            .build();

    return ImmutableList.<CxxPreprocessorInput>builder()
        .add(localPreprocessorInput)
        .addAll(cxxPreprocessorInputFromDeps)
        .addAll(cxxPreprocessorInputFromTestedRules)
        .build();
  }