/** * If the source paths specified are from the new unified source tmp then we should return the * correct source tmp corresponding to the unified source path. */ @Test public void testUnifiedSourceFile() { Path pathToNonGenFile = Paths.get("java/package/SourceFile1.java"); assertFalse(MorePaths.isGeneratedFile(pathToNonGenFile)); ImmutableSortedSet<Path> javaSrcs = ImmutableSortedSet.of(pathToNonGenFile); JavaLibrary javaLibrary = new FakeJavaLibrary( BuildTarget.builder("//foo", "bar").build(), new SourcePathResolver(new BuildRuleResolver())) .setJavaSrcs(javaSrcs); DefaultJavaPackageFinder defaultJavaPackageFinder = createMock(DefaultJavaPackageFinder.class); expect(defaultJavaPackageFinder.getPathsFromRoot()).andReturn(pathsFromRoot); Object[] mocks = new Object[] {defaultJavaPackageFinder}; replay(mocks); ImmutableSet<String> result = TestRunning.getPathToSourceFolders( javaLibrary, Optional.of(defaultJavaPackageFinder), new FakeProjectFilesystem()); assertEquals( "All non-generated source files are under one source tmp.", ImmutableSet.of("java/"), result); verify(mocks); }
/** * @param values Collection whose entries identify fields for the generated {@code BuildConfig} * class. The values for fields can be overridden by values from the {@code valuesFile} file, * if present. * @param valuesFile Path to a file with values to override those in {@code values}. */ static AndroidBuildConfigJavaLibrary createBuildRule( BuildRuleParams params, String javaPackage, BuildConfigFields values, Optional<SourcePath> valuesFile, boolean useConstantExpressions) { // Create one build rule to generate BuildConfig.java. BuildRuleParams buildConfigParams = params.copyWithChanges( GEN_JAVA_TYPE, BuildTarget.builder(params.getBuildTarget()).setFlavor(GEN_JAVA_FLAVOR).build(), params.getDeclaredDeps(), params.getExtraDeps()); AndroidBuildConfig androidBuildConfig = new AndroidBuildConfig( buildConfigParams, javaPackage, values, valuesFile, useConstantExpressions); // Create a second build rule to compile BuildConfig.java and expose it as a JavaLibrary. BuildRuleParams javaLibraryParams = params.copyWithChanges( TYPE, params.getBuildTarget(), /* declaredDeps */ ImmutableSortedSet.<BuildRule>of(androidBuildConfig), /* extraDeps */ ImmutableSortedSet.<BuildRule>of()); return new AndroidBuildConfigJavaLibrary(javaLibraryParams, androidBuildConfig); }
public static BuildTarget createStaticLibraryBuildTarget( BuildTarget target, Flavor platform, CxxSourceRuleFactory.PicType pic) { return BuildTarget.builder(target) .addFlavors(platform) .addFlavors(pic == CxxSourceRuleFactory.PicType.PDC ? STATIC_FLAVOR : STATIC_PIC_FLAVOR) .build(); }
/** * @return the {@link BuildTarget} to use for the {@link BuildRule} generating the symlink tree of * headers. */ public static BuildTarget createHeaderSymlinkTreeTarget( BuildTarget target, Flavor platform, HeaderVisibility headerVisibility) { return BuildTarget.builder(target) .addFlavors(platform) .addFlavors(getHeaderSymlinkTreeFlavor(headerVisibility)) .build(); }
@Test public void testAppleLibraryBuildsFramework() throws Exception { assumeTrue(Platform.detect() == Platform.MACOS); assumeTrue(AppleNativeIntegrationTestUtils.isApplePlatformAvailable(ApplePlatform.MACOSX)); ProjectWorkspace workspace = TestDataHelper.createProjectWorkspaceForScenario( this, "apple_library_builds_something", tmp); workspace.setUp(); ProjectFilesystem filesystem = new ProjectFilesystem(workspace.getDestPath()); BuildTarget target = BuildTargetFactory.newInstance( "//Libraries/TestLibrary:TestLibrary#framework,macosx-x86_64,no-debug"); ProjectWorkspace.ProcessResult result = workspace.runBuckCommand("build", target.getFullyQualifiedName()); result.assertSuccess(); Path frameworkPath = workspace.getPath( BuildTargets.getGenPath( filesystem, BuildTarget.builder(target) .addFlavors(AppleDescriptions.INCLUDE_FRAMEWORKS_FLAVOR) .build(), "%s") .resolve("TestLibrary.framework")); assertThat(Files.exists(frameworkPath), is(true)); assertThat(Files.exists(frameworkPath.resolve("Resources/Info.plist")), is(true)); Path libraryPath = frameworkPath.resolve("TestLibrary"); assertThat(Files.exists(libraryPath), is(true)); assertThat( workspace.runCommand("file", libraryPath.toString()).getStdout().get(), containsString("dynamically linked shared library")); }
@Test public void frameworkDependenciesDoNotContainTransitiveDependencies() throws Exception { assumeTrue(Platform.detect() == Platform.MACOS); assumeTrue(AppleNativeIntegrationTestUtils.isApplePlatformAvailable(ApplePlatform.MACOSX)); ProjectWorkspace workspace = TestDataHelper.createProjectWorkspaceForScenario( this, "apple_library_with_library_dependencies", tmp); workspace.setUp(); ProjectFilesystem filesystem = new ProjectFilesystem(workspace.getDestPath()); BuildTarget target = BuildTargetFactory.newInstance( "//Libraries/TestLibrary:TestLibrary#framework,macosx-x86_64"); ProjectWorkspace.ProcessResult result = workspace.runBuckCommand("build", target.getFullyQualifiedName()); result.assertSuccess(); Path frameworkPath = workspace.getPath( BuildTargets.getGenPath( filesystem, BuildTarget.builder(target) .addFlavors(AppleDebugFormat.DWARF.getFlavor()) .addFlavors(AppleDescriptions.INCLUDE_FRAMEWORKS_FLAVOR) .build(), "%s") .resolve("TestLibrary.framework")); assertThat(Files.exists(frameworkPath), is(true)); Path frameworksPath = frameworkPath.resolve("Frameworks"); assertThat(Files.exists(frameworksPath), is(true)); Path depFrameworksPath = frameworksPath.resolve("TestLibraryDep.framework/Frameworks"); assertThat(Files.exists(depFrameworksPath), is(false)); }
/** * If the source paths specified contains one source path to a non-generated file then we should * return the correct source tmp corresponding to that non-generated source path. Especially when * the generated file comes first in the ordered set. */ @Test public void testMixedSourceFile() { Path pathToGenFile = GEN_PATH.resolve("com/facebook/GeneratedFile.java"); Path pathToNonGenFile1 = Paths.get("package/src/SourceFile1.java"); Path pathToNonGenFile2 = Paths.get("package/src-gen/SourceFile2.java"); ImmutableSortedSet<Path> javaSrcs = ImmutableSortedSet.of(pathToGenFile, pathToNonGenFile1, pathToNonGenFile2); DefaultJavaPackageFinder defaultJavaPackageFinder = createMock(DefaultJavaPackageFinder.class); expect(defaultJavaPackageFinder.getPathsFromRoot()).andReturn(pathsFromRoot).times(2); expect(defaultJavaPackageFinder.getPathElements()).andReturn(pathElements).times(2); JavaLibrary javaLibrary = new FakeJavaLibrary( BuildTarget.builder("//foo", "bar").build(), new SourcePathResolver(new BuildRuleResolver())) .setJavaSrcs(javaSrcs); replay(defaultJavaPackageFinder); ImmutableSet<String> result = TestRunning.getPathToSourceFolders( javaLibrary, Optional.of(defaultJavaPackageFinder), new FakeProjectFilesystem()); assertEquals( "The non-generated source files are under two different source folders.", ImmutableSet.of("./package/src-gen/", "./package/src/"), result); verify(defaultJavaPackageFinder); }
/** * @return the {@link BuildTarget} to use for the {@link BuildRule} generating the symlink tree of * shared libraries. */ public static BuildTarget createSharedLibrarySymlinkTreeTarget( BuildTarget target, Flavor platform) { return BuildTarget.builder(target) .addFlavors(SHARED_LIBRARY_SYMLINK_TREE_FLAVOR) .addFlavors(platform) .build(); }
/** * If the source paths specified are all generated files, then our path to source tmp should be * absent. */ @Test public void testGeneratedSourceFile() { Path pathToGenFile = GEN_PATH.resolve("GeneratedFile.java"); assertTrue(MorePaths.isGeneratedFile(pathToGenFile)); ImmutableSortedSet<Path> javaSrcs = ImmutableSortedSet.of(pathToGenFile); JavaLibrary javaLibrary = new FakeJavaLibrary( BuildTarget.builder("//foo", "bar").build(), new SourcePathResolver(new BuildRuleResolver())) .setJavaSrcs(javaSrcs); DefaultJavaPackageFinder defaultJavaPackageFinder = createMock(DefaultJavaPackageFinder.class); Object[] mocks = new Object[] {defaultJavaPackageFinder}; replay(mocks); ImmutableSet<String> result = TestRunning.getPathToSourceFolders( javaLibrary, Optional.of(defaultJavaPackageFinder), new FakeProjectFilesystem()); assertTrue( "No path should be returned if the library contains only generated files.", result.isEmpty()); verify(mocks); }
public BuildTarget createInferCaptureBuildTarget(String name) { String outputName = Flavor.replaceInvalidCharacters(getCompileOutputName(name)); return BuildTarget.builder(getParams().getBuildTarget()) .addAllFlavors(getParams().getBuildTarget().getFlavors()) .addFlavors(getCxxPlatform().getFlavor()) .addFlavors(ImmutableFlavor.of(String.format("infer-capture-%s", outputName))) .build(); }
@VisibleForTesting protected static BuildTarget createYaccBuildTarget(UnflavoredBuildTarget target, String name) { return BuildTarget.builder(target) .addFlavors( ImmutableFlavor.of( String.format( "yacc-%s", name.replace('/', '-').replace('.', '-').replace('+', '-').replace(' ', '-')))) .build(); }
private static AndroidBuildConfig createSimpleBuildConfigRule() { // First, create the BuildConfig object. BuildTarget buildTarget = BuildTarget.builder("//java/com/example", "build_config").build(); BuildRuleParams params = new FakeBuildRuleParamsBuilder(buildTarget).build(); return new AndroidBuildConfig( params, new SourcePathResolver(new BuildRuleResolver()), /* javaPackage */ "com.example", /* values */ BuildConfigFields.empty(), /* valuesFile */ Optional.<SourcePath>absent(), /* useConstantExpressions */ false); }
/** * @return a {@link BuildTarget} used for the rule that preprocesses the source by the given name * and type. */ @VisibleForTesting public BuildTarget createPreprocessBuildTarget(String name, CxxSource.Type type) { String outputName = Flavor.replaceInvalidCharacters(getPreprocessOutputName(type, name)); return BuildTarget.builder(getParams().getBuildTarget()) .addFlavors(getCxxPlatform().getFlavor()) .addFlavors( ImmutableFlavor.of( String.format( PREPROCESS_FLAVOR_PREFIX + "%s%s", getPicType() == PicType.PIC ? "pic-" : "", outputName))) .build(); }
public static BuildTarget createMLBytecodeCompileBuildTarget(BuildTarget target, String name) { return BuildTarget.builder(target) .addFlavors( ImmutableFlavor.of( String.format( "ml-bytecode-compile-%s", getMLBytecodeOutputName(name) .replace('/', '-') .replace('.', '-') .replace('+', '-') .replace(' ', '-')))) .build(); }
/** * @return a build target for a {@link CxxPreprocessAndCompile} rule for the source with the given * name. */ @VisibleForTesting public BuildTarget createCompileBuildTarget(String name) { String outputName = Flavor.replaceInvalidCharacters(getCompileOutputName(name)); return BuildTarget.builder(getParams().getBuildTarget()) .addFlavors(getCxxPlatform().getFlavor()) .addFlavors( ImmutableFlavor.of( String.format( COMPILE_FLAVOR_PREFIX + "%s%s", getPicType() == PicType.PIC ? "pic-" : "", outputName))) .build(); }
private static <T> BuildRule createBuildRule( TargetGraph targetGraph, BuildRuleParams params, BuildRuleResolver ruleResolver, TargetNode<T> node, Flavor... flavors) { BuildTarget target = BuildTarget.builder(params.getBuildTarget()).addFlavors(flavors).build(); Description<T> description = node.getDescription(); T args = node.getConstructorArg(); return description.createBuildRule( targetGraph, params.copyWithChanges(target, params.getDeclaredDeps(), params.getExtraDeps()), ruleResolver, args); }
/** * Ensure that the build rule generated by the given {@link BuildRuleParams} had been generated by * it's corresponding {@link Description} and added to the {@link BuildRuleResolver}. If not, call * into it's associated {@link Description} to generate it's {@link BuildRule}. * * @return the {@link BuildRule} generated by the description corresponding to the supplied {@link * BuildRuleParams}. */ public static BuildRule requireBuildRule( TargetGraph targetGraph, BuildRuleParams params, BuildRuleResolver ruleResolver, Flavor... flavors) { BuildTarget target = BuildTarget.builder(params.getBuildTarget()).addFlavors(flavors).build(); Optional<BuildRule> rule = ruleResolver.getRuleOptional(target); if (!rule.isPresent()) { TargetNode<?> node = targetGraph.get(params.getBuildTarget()); Preconditions.checkNotNull( node, String.format("%s not in target graph", params.getBuildTarget())); rule = Optional.of(createBuildRule(targetGraph, params, ruleResolver, node, flavors)); ruleResolver.addToIndex(rule.get()); } return rule.get(); }
/** * @return adds a the header {@link SymlinkTree} for the given rule to the {@link * CxxPreprocessorInput}. */ public static CxxPreprocessorInput.Builder addHeaderSymlinkTree( CxxPreprocessorInput.Builder builder, BuildTarget target, BuildRuleResolver ruleResolver, Flavor flavor, HeaderVisibility headerVisibility, IncludeType includeType) throws NoSuchBuildTargetException { BuildRule rule = ruleResolver.requireRule( BuildTarget.builder(target) .addFlavors( flavor, CxxDescriptionEnhancer.getHeaderSymlinkTreeFlavor(headerVisibility)) .build()); Preconditions.checkState( rule instanceof HeaderSymlinkTree, "Attempt to add %s of type %s and class %s to %s", rule.getFullyQualifiedName(), rule.getType(), rule.getClass(), target); HeaderSymlinkTree symlinkTree = (HeaderSymlinkTree) rule; builder .addRules(symlinkTree.getBuildTarget()) .setIncludes( CxxHeaders.builder() .setNameToPathMap(ImmutableSortedMap.copyOf(symlinkTree.getLinks())) .setFullNameToPathMap(ImmutableSortedMap.copyOf(symlinkTree.getFullLinks())) .build()); switch (includeType) { case LOCAL: builder.addIncludeRoots(symlinkTree.getIncludePath()); builder.addAllHeaderMaps(symlinkTree.getHeaderMap().asSet()); break; case SYSTEM: builder.addSystemIncludeRoots(symlinkTree.getSystemIncludePath()); break; } return builder; }
@Override public <A extends Arg> BuildRule createBuildRule( TargetGraph targetGraph, BuildRuleParams params, BuildRuleResolver resolver, A args) { BuildTarget libraryTarget = BuildTarget.builder(params.getBuildTarget()) .addFlavors(ImmutableFlavor.of("compile")) .build(); GoLibrary library = GoDescriptors.createGoLibraryRule( params.copyWithBuildTarget(libraryTarget), resolver, goBuckConfig, Paths.get("main"), args.srcs, args.compilerFlags.or(ImmutableList.<String>of())); resolver.addToIndex(library); BuildRuleParams binaryParams = params.copyWithDeps( Suppliers.ofInstance(ImmutableSortedSet.<BuildRule>of(library)), Suppliers.ofInstance(ImmutableSortedSet.<BuildRule>of())); GoSymlinkTree symlinkTree = GoDescriptors.requireTransitiveSymlinkTreeRule(binaryParams, resolver); return new GoBinary( params.copyWithDeps( Suppliers.ofInstance(ImmutableSortedSet.<BuildRule>of(symlinkTree, library)), Suppliers.ofInstance(ImmutableSortedSet.<BuildRule>of())), new SourcePathResolver(resolver), cxxPlatform.getLd(), symlinkTree, library, goBuckConfig.getGoLinker().get(), ImmutableList.<String>builder() .addAll(goBuckConfig.getLinkerFlags()) .addAll(args.linkerFlags.or(ImmutableList.<String>of())) .build()); }
@Test public void createThriftCompilerBuildRulesHasCorrectDeps() throws IOException { BuildRuleResolver resolver = new BuildRuleResolver(); SourcePathResolver pathResolver = new SourcePathResolver(resolver); FakeProjectFilesystem filesystem = new FakeProjectFilesystem(); String language = "fake"; Flavor flavor = ImmutableFlavor.of("fake"); ImmutableSet<String> options = ImmutableSet.of(); // Setup the default values returned by the language specific enhancer. BuildTarget unflavoredTarget = BuildTargetFactory.newInstance("//:thrift"); BuildRuleParams unflavoredParams = new FakeBuildRuleParamsBuilder(BuildTarget.builder(unflavoredTarget).build()) .setProjectFilesystem(filesystem) .build(); // Setup a thrift source file generated by a genrule. BuildTarget flavoredTarget = BuildTargets.createFlavoredBuildTarget(unflavoredTarget.checkUnflavored(), flavor); BuildRuleParams flavoredParams = new FakeBuildRuleParamsBuilder(flavoredTarget).setProjectFilesystem(filesystem).build(); // Create a path for the thrift compiler. Path thriftPath = Paths.get("thrift_path"); filesystem.touch(thriftPath); // Setup an thrift buck config, with the path to the thrift compiler set. FakeBuckConfig buckConfig = new FakeBuckConfig( ImmutableMap.of("thrift", ImmutableMap.of("compiler", thriftPath.toString())), filesystem); ThriftBuckConfig thriftBuckConfig = new ThriftBuckConfig(buckConfig); ThriftLibraryDescription desc = new ThriftLibraryDescription( thriftBuckConfig, ImmutableList.<ThriftLanguageSpecificEnhancer>of()); // Setup a simple thrift source. String sourceName = "test.thrift"; SourcePath sourcePath = new TestSourcePath(sourceName); // Generate these rules using no deps. ImmutableMap<String, ThriftCompiler> rules = desc.createThriftCompilerBuildRules( flavoredParams, resolver, ThriftLibraryDescription.CompilerType.THRIFT, ImmutableList.<String>of(), language, options, ImmutableMap.of(sourceName, sourcePath), ImmutableSortedSet.<ThriftLibrary>of()); // Now verify that the generated rule had no associated deps. assertSame(rules.size(), 1); ThriftCompiler rule = rules.get(sourceName); assertNotNull(rule); assertEquals(ImmutableSortedSet.<BuildRule>of(), rule.getDeps()); // Lets do this again, but pass in a ThriftLibrary deps, wrapping some includes we need. Path includeRoot = desc.getIncludeRoot(unflavoredTarget); HeaderSymlinkTree thriftIncludeSymlinkTree = createFakeSymlinkTree( desc.createThriftIncludeSymlinkTreeTarget(unflavoredTarget), pathResolver, includeRoot); ThriftLibrary lib = new ThriftLibrary( unflavoredParams, pathResolver, ImmutableSortedSet.<ThriftLibrary>of(), thriftIncludeSymlinkTree, ImmutableMap.<Path, SourcePath>of()); // Generate these rules using no deps. rules = desc.createThriftCompilerBuildRules( flavoredParams, resolver, ThriftLibraryDescription.CompilerType.THRIFT, ImmutableList.<String>of(), language, options, ImmutableMap.of(sourceName, sourcePath), ImmutableSortedSet.of(lib)); // Now verify that the generated rule has all the deps from the passed in thrift library. assertSame(rules.size(), 1); rule = rules.get(sourceName); assertNotNull(rule); assertEquals(ImmutableSortedSet.<BuildRule>of(thriftIncludeSymlinkTree), rule.getDeps()); // Setup a simple genrule that creates the thrift source and verify its dep is propagated. Genrule genrule = (Genrule) GenruleBuilder.newGenruleBuilder(BuildTargetFactory.newInstance("//:genrule")) .setOut(sourceName) .build(resolver); SourcePath ruleSourcePath = new BuildTargetSourcePath(genrule.getBuildTarget()); // Generate these rules using no deps and the genrule generated source. rules = desc.createThriftCompilerBuildRules( flavoredParams, resolver, ThriftLibraryDescription.CompilerType.THRIFT, ImmutableList.<String>of(), language, options, ImmutableMap.of(sourceName, ruleSourcePath), ImmutableSortedSet.<ThriftLibrary>of()); // Now verify that the generated rule had no associated deps. assertSame(rules.size(), 1); rule = rules.get(sourceName); assertNotNull(rule); assertEquals(ImmutableSortedSet.<BuildRule>of(genrule), rule.getDeps()); // Create a build rule that represents the thrift rule. FakeBuildRule thriftRule = createFakeBuildRule("//thrift:target", pathResolver); resolver.addToIndex(thriftRule); filesystem.mkdirs(thriftRule.getBuildTarget().getBasePath()); filesystem.touch(thriftRule.getBuildTarget().getBasePath().resolve("BUCK")); // Setup an empty thrift buck config, and set compiler target. buckConfig = new FakeBuckConfig( ImmutableMap.of( "thrift", ImmutableMap.of("compiler", thriftRule.getBuildTarget().toString())), filesystem); thriftBuckConfig = new ThriftBuckConfig(buckConfig); desc = new ThriftLibraryDescription( thriftBuckConfig, ImmutableList.<ThriftLanguageSpecificEnhancer>of()); // Generate these rules using no deps with a compiler target. rules = desc.createThriftCompilerBuildRules( flavoredParams, resolver, ThriftLibraryDescription.CompilerType.THRIFT, ImmutableList.<String>of(), language, options, ImmutableMap.of(sourceName, sourcePath), ImmutableSortedSet.<ThriftLibrary>of()); // Now verify that the generated rule only has deps from the compiler target. assertSame(rules.size(), 1); rule = rules.get(sourceName); assertNotNull(rule); assertEquals(ImmutableSortedSet.<BuildRule>of(thriftRule), rule.getDeps()); }
private QueryTarget createQueryBuildTarget(String baseName, String shortName) { return QueryBuildTarget.of(BuildTarget.builder(cellRoot, baseName, shortName).build()); }
@Before public void createFixtures() { target = BuildTarget.builder("//", "example.html").build(); context = getBuildContext(); }
public static BuildTarget addBytecodeFlavor(BuildTarget target) { return BuildTarget.builder(target).addFlavors(BYTECODE_FLAVOR).build(); }
public static BuildTarget addDebugFlavor(BuildTarget target) { return BuildTarget.builder(target).addFlavors(DEBUG_FLAVOR).build(); }
public static BuildTarget createSharedLibraryBuildTarget(BuildTarget target, Flavor platform) { return BuildTarget.builder(target).addFlavors(platform).addFlavors(SHARED_FLAVOR).build(); }
private void runCombinedTest( CxxPreprocessMode strategy, ImmutableList<String> expectedArguments) { BuildTarget testBuildTarget = BuildTarget.builder(BuildTargetFactory.newInstance("//foo:baz")) .addAllFlavors(ImmutableSet.of(CxxCompilationDatabase.COMPILATION_DATABASE)) .build(); final String root = "/Users/user/src"; final Path fakeRoot = Paths.get(root); ProjectFilesystem filesystem = new FakeProjectFilesystem() { @Override public Path getRootPath() { return fakeRoot; } @Override public Path resolve(Path relativePath) { return fakeRoot.resolve(relativePath); } }; BuildRuleParams testBuildRuleParams = new FakeBuildRuleParamsBuilder(testBuildTarget).setProjectFilesystem(filesystem).build(); BuildRuleResolver testBuildRuleResolver = new BuildRuleResolver(); SourcePathResolver testSourcePathResolver = new SourcePathResolver(testBuildRuleResolver); BuildTarget preprocessTarget = BuildTarget.builder(testBuildRuleParams.getBuildTarget().getUnflavoredBuildTarget()) .addFlavors(ImmutableFlavor.of("preprocess-test.cpp")) .build(); BuildTarget compileTarget = BuildTarget.builder(testBuildRuleParams.getBuildTarget().getUnflavoredBuildTarget()) .addFlavors(ImmutableFlavor.of("compile-test.cpp")) .build(); ImmutableSortedSet.Builder<CxxPreprocessAndCompile> rules = ImmutableSortedSet.naturalOrder(); CxxPreprocessAndCompileStep.Operation operation; BuildRuleParams compileBuildRuleParams; switch (strategy) { case SEPARATE: operation = CxxPreprocessAndCompileStep.Operation.COMPILE; CxxPreprocessAndCompile preprocessRule = new CxxPreprocessAndCompile( new FakeBuildRuleParamsBuilder(preprocessTarget) .setProjectFilesystem(filesystem) .build(), testSourcePathResolver, operation, Optional.<Preprocessor>of( new DefaultPreprocessor(new HashedFileTool(Paths.get("preprocessor")))), Optional.of(ImmutableList.<String>of()), Optional.of(ImmutableList.<String>of()), Optional.<Compiler>absent(), Optional.<ImmutableList<String>>absent(), Optional.<ImmutableList<String>>absent(), Paths.get("test.o"), new TestSourcePath("test.cpp"), CxxSource.Type.CXX, ImmutableSet.of(Paths.get("foo/bar"), Paths.get("test")), ImmutableSet.<Path>of(), ImmutableSet.<Path>of(), ImmutableSet.<Path>of(), Optional.<SourcePath>absent(), ImmutableList.<CxxHeaders>of(), CxxPlatforms.DEFAULT_DEBUG_PATH_SANITIZER); rules.add(preprocessRule); compileBuildRuleParams = new FakeBuildRuleParamsBuilder(compileTarget) .setProjectFilesystem(filesystem) .setDeclaredDeps(ImmutableSortedSet.<BuildRule>of(preprocessRule)) .build(); break; case COMBINED: operation = CxxPreprocessAndCompileStep.Operation.COMPILE_MUNGE_DEBUGINFO; compileBuildRuleParams = new FakeBuildRuleParamsBuilder(compileTarget).setProjectFilesystem(filesystem).build(); break; case PIPED: operation = CxxPreprocessAndCompileStep.Operation.PIPED_PREPROCESS_AND_COMPILE; compileBuildRuleParams = new FakeBuildRuleParamsBuilder(compileTarget).setProjectFilesystem(filesystem).build(); break; default: throw new RuntimeException("Invalid strategy"); } rules.add( new CxxPreprocessAndCompile( compileBuildRuleParams, testSourcePathResolver, operation, Optional.<Preprocessor>of( new DefaultPreprocessor(new HashedFileTool(Paths.get("preprocessor")))), Optional.of(ImmutableList.<String>of()), Optional.of(ImmutableList.<String>of()), Optional.<Compiler>of(new DefaultCompiler(new HashedFileTool(Paths.get("compiler")))), Optional.of(ImmutableList.<String>of()), Optional.of(ImmutableList.<String>of()), Paths.get("test.o"), new TestSourcePath("test.cpp"), CxxSource.Type.CXX, ImmutableSet.of(Paths.get("foo/bar"), Paths.get("test")), ImmutableSet.<Path>of(), ImmutableSet.<Path>of(), ImmutableSet.<Path>of(), Optional.<SourcePath>absent(), ImmutableList.<CxxHeaders>of(), CxxPlatforms.DEFAULT_DEBUG_PATH_SANITIZER)); CxxCompilationDatabase compilationDatabase = CxxCompilationDatabase.createCompilationDatabase( testBuildRuleParams, testSourcePathResolver, strategy, rules.build()); assertEquals( "getPathToOutput() should be a function of the build target.", Paths.get("buck-out/gen/foo/__baz#compilation-database.json"), compilationDatabase.getPathToOutput()); BuildContext buildContext = FakeBuildContext.NOOP_CONTEXT; BuildableContext buildableContext = new FakeBuildableContext(); List<Step> buildSteps = compilationDatabase.getPostBuildSteps(buildContext, buildableContext); assertEquals(2, buildSteps.size()); assertTrue(buildSteps.get(0) instanceof MkdirStep); assertTrue(buildSteps.get(1) instanceof CxxCompilationDatabase.GenerateCompilationCommandsJson); CxxCompilationDatabase.GenerateCompilationCommandsJson step = (CxxCompilationDatabase.GenerateCompilationCommandsJson) buildSteps.get(1); Iterable<CxxCompilationDatabaseEntry> observedEntries = step.createEntries(); Iterable<CxxCompilationDatabaseEntry> expectedEntries = ImmutableList.of( CxxCompilationDatabaseEntry.of(root, root + "/test.cpp", expectedArguments)); MoreAsserts.assertIterablesEquals(expectedEntries, observedEntries); }
@VisibleForTesting protected static BuildTarget createCxxLinkTarget(BuildTarget target) { return BuildTarget.builder(target).addFlavors(CXX_LINK_BINARY_FLAVOR).build(); }
private static BuildTarget createLexYaccSourcesBuildTarget(BuildTarget target) { return BuildTarget.builder(target).addFlavors(LEX_YACC_SOURCE_FLAVOR).build(); }
/** Propagate the bundle's platform flavors to its dependents. */ @Override public ImmutableSet<BuildTarget> findDepsForTargetFromConstructorArgs( BuildTarget buildTarget, Function<Optional<String>, Path> cellRoots, AppleBundleDescription.Arg constructorArg) { if (!constructorArg.deps.isPresent()) { return ImmutableSet.of(); } if (!cxxPlatformFlavorDomain.containsAnyOf(buildTarget.getFlavors())) { buildTarget = BuildTarget.builder(buildTarget) .addAllFlavors(ImmutableSet.of(defaultCxxPlatform.getFlavor())) .build(); } Optional<FatBinaryInfo> fatBinaryInfo = FatBinaryInfo.create(platformFlavorsToAppleCxxPlatforms, buildTarget); CxxPlatform cxxPlatform; if (fatBinaryInfo.isPresent()) { AppleCxxPlatform appleCxxPlatform = fatBinaryInfo.get().getRepresentativePlatform(); cxxPlatform = appleCxxPlatform.getCxxPlatform(); } else { cxxPlatform = getCxxPlatformForBuildTarget(buildTarget); } String platformName = cxxPlatform.getFlavor().getName(); final Flavor actualWatchFlavor; if (ApplePlatform.isSimulator(platformName)) { actualWatchFlavor = ImmutableFlavor.builder().name("watchsimulator-i386").build(); } else if (platformName.startsWith(ApplePlatform.Name.IPHONEOS) || platformName.startsWith(ApplePlatform.Name.WATCHOS)) { actualWatchFlavor = ImmutableFlavor.builder().name("watchos-armv7k").build(); } else { actualWatchFlavor = ImmutableFlavor.builder().name(platformName).build(); } FluentIterable<BuildTarget> depsExcludingBinary = FluentIterable.from(constructorArg.deps.get()) .filter(Predicates.not(Predicates.equalTo(constructorArg.binary))); FluentIterable<BuildTarget> targetsWithPlatformFlavors = depsExcludingBinary.filter(BuildTargets.containsFlavors(cxxPlatformFlavorDomain)); FluentIterable<BuildTarget> targetsWithoutPlatformFlavors = depsExcludingBinary.filter( Predicates.not(BuildTargets.containsFlavors(cxxPlatformFlavorDomain))); FluentIterable<BuildTarget> watchTargets = targetsWithoutPlatformFlavors .filter(BuildTargets.containsFlavor(WATCH)) .transform( new Function<BuildTarget, BuildTarget>() { @Override public BuildTarget apply(BuildTarget input) { return BuildTarget.builder(input.withoutFlavors(ImmutableSet.of(WATCH))) .addFlavors(actualWatchFlavor) .build(); } }); targetsWithoutPlatformFlavors = targetsWithoutPlatformFlavors.filter(Predicates.not(BuildTargets.containsFlavor(WATCH))); return ImmutableSet.<BuildTarget>builder() .addAll(targetsWithPlatformFlavors) .addAll(watchTargets) .addAll( BuildTargets.propagateFlavorDomains( buildTarget, ImmutableSet.<FlavorDomain<?>>of(cxxPlatformFlavorDomain), targetsWithoutPlatformFlavors)) .build(); }
@Test public void testCompilationDatabseWithSeperatedPreprocessAndCompileStrategy() { String root = "/Users/user/src"; final Path fakeRoot = Paths.get(root); ProjectFilesystem filesystem = new FakeProjectFilesystem() { @Override public Path getRootPath() { return fakeRoot; } @Override public Path resolve(Path relativePath) { return fakeRoot.resolve(relativePath); } }; BuildTarget testBuildTarget = BuildTarget.builder(BuildTargetFactory.newInstance("//foo:baz")) .addAllFlavors(ImmutableSet.of(CxxCompilationDatabase.COMPILATION_DATABASE)) .build(); BuildRuleParams testBuildRuleParams = new FakeBuildRuleParamsBuilder(testBuildTarget).setProjectFilesystem(filesystem).build(); BuildRuleResolver testBuildRuleResolver = new BuildRuleResolver(); SourcePathResolver testSourcePathResolver = new SourcePathResolver(testBuildRuleResolver); BuildTarget preprocessTarget = BuildTarget.builder(testBuildRuleParams.getBuildTarget().getUnflavoredBuildTarget()) .addFlavors(ImmutableFlavor.of("preprocess-test.cpp")) .build(); BuildRuleParams preprocessBuildRuleParams = new FakeBuildRuleParamsBuilder(preprocessTarget).setProjectFilesystem(filesystem).build(); CxxPreprocessAndCompile testPreprocessRule = new CxxPreprocessAndCompile( preprocessBuildRuleParams, testSourcePathResolver, CxxPreprocessAndCompileStep.Operation.PREPROCESS, Optional.<Preprocessor>of( new DefaultPreprocessor(new HashedFileTool(Paths.get("compiler")))), Optional.of(ImmutableList.<String>of()), Optional.of(ImmutableList.<String>of()), Optional.<Compiler>absent(), Optional.<ImmutableList<String>>absent(), Optional.<ImmutableList<String>>absent(), Paths.get("test.ii"), new TestSourcePath("test.cpp"), CxxSource.Type.CXX_CPP_OUTPUT, ImmutableSet.of(Paths.get("foo/bar"), Paths.get("test")), ImmutableSet.<Path>of(), ImmutableSet.<Path>of(), ImmutableSet.<Path>of(), Optional.<SourcePath>absent(), ImmutableList.<CxxHeaders>of(), CxxPlatforms.DEFAULT_DEBUG_PATH_SANITIZER); BuildTarget compileTarget = BuildTarget.builder(testBuildRuleParams.getBuildTarget().getUnflavoredBuildTarget()) .addFlavors(ImmutableFlavor.of("compile-test.cpp")) .build(); BuildRuleParams compileBuildRuleParams = new FakeBuildRuleParamsBuilder(compileTarget) .setProjectFilesystem(filesystem) .setDeclaredDeps(ImmutableSortedSet.<BuildRule>of(testPreprocessRule)) .build(); CxxPreprocessAndCompile testCompileRule = new CxxPreprocessAndCompile( compileBuildRuleParams, testSourcePathResolver, CxxPreprocessAndCompileStep.Operation.COMPILE, Optional.<Preprocessor>absent(), Optional.<ImmutableList<String>>absent(), Optional.<ImmutableList<String>>absent(), Optional.<Compiler>of(new DefaultCompiler(new HashedFileTool(Paths.get("compiler")))), Optional.of(ImmutableList.<String>of()), Optional.of(ImmutableList.<String>of()), Paths.get("test.o"), new TestSourcePath("test.ii"), CxxSource.Type.CXX_CPP_OUTPUT, ImmutableSet.<Path>of(), ImmutableSet.<Path>of(), ImmutableSet.<Path>of(), ImmutableSet.<Path>of(), Optional.<SourcePath>absent(), ImmutableList.<CxxHeaders>of(), CxxPlatforms.DEFAULT_DEBUG_PATH_SANITIZER); CxxCompilationDatabase compilationDatabase = CxxCompilationDatabase.createCompilationDatabase( testBuildRuleParams, testSourcePathResolver, CxxPreprocessMode.SEPARATE, ImmutableSortedSet.of(testPreprocessRule, testCompileRule)); assertEquals( "getPathToOutput() should be a function of the build target.", Paths.get("buck-out/gen/foo/__baz#compilation-database.json"), compilationDatabase.getPathToOutput()); BuildContext buildContext = FakeBuildContext.NOOP_CONTEXT; BuildableContext buildableContext = new FakeBuildableContext(); List<Step> buildSteps = compilationDatabase.getPostBuildSteps(buildContext, buildableContext); assertEquals(2, buildSteps.size()); assertTrue(buildSteps.get(0) instanceof MkdirStep); assertTrue(buildSteps.get(1) instanceof CxxCompilationDatabase.GenerateCompilationCommandsJson); CxxCompilationDatabase.GenerateCompilationCommandsJson step = (CxxCompilationDatabase.GenerateCompilationCommandsJson) buildSteps.get(1); Iterable<CxxCompilationDatabaseEntry> observedEntries = step.createEntries(); Iterable<CxxCompilationDatabaseEntry> expectedEntries = ImmutableList.of( CxxCompilationDatabaseEntry.of( root, root + "/test.cpp", ImmutableList.of( "compiler", "-I", "foo/bar", "-I", "test", "-x", "c++-cpp-output", "-c", "-o", "test.o", "test.cpp"))); MoreAsserts.assertIterablesEquals(expectedEntries, observedEntries); }