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