@Test public void testUberCompilationDatabase() throws IOException { ProjectWorkspace workspace = TestDataHelper.createProjectWorkspaceForScenario(this, "compilation_database", tmp); workspace.setUp(); BuildTarget target = BuildTargetFactory.newInstance("//:test#default,uber-compilation-database"); ProjectFilesystem filesystem = new FakeProjectFilesystem(); Path compilationDatabase = workspace.buildAndReturnOutput(target.getFullyQualifiedName()); Path rootPath = tmp.getRoot(); assertEquals( BuildTargets.getGenPath( filesystem, target, "uber-compilation-database-%s/compile_commands.json"), rootPath.relativize(compilationDatabase)); Path binaryHeaderSymlinkTreeFolder = BuildTargets.getGenPath( filesystem, target.withFlavors( ImmutableFlavor.of("default"), CxxDescriptionEnhancer.HEADER_SYMLINK_TREE_FLAVOR), "%s"); Path binaryExportedHeaderSymlinkTreeFolder = BuildTargets.getGenPath( filesystem, target.withFlavors( ImmutableFlavor.of("default"), CxxDescriptionEnhancer.EXPORTED_HEADER_SYMLINK_TREE_FLAVOR), "%s"); Map<String, CxxCompilationDatabaseEntry> fileToEntry = CxxCompilationDatabaseUtils.parseCompilationDatabaseJsonFile(compilationDatabase); assertEquals(1, fileToEntry.size()); assertHasEntry( fileToEntry, "test.cpp", new ImmutableList.Builder<String>() .add(COMPILER_PATH) .add("-fPIC") .add("-fPIC") .add("-I") .add(headerSymlinkTreePath(binaryHeaderSymlinkTreeFolder).toString()) .add("-I") .add(headerSymlinkTreePath(binaryExportedHeaderSymlinkTreeFolder).toString()) .addAll(getExtraFlagsForHeaderMaps(filesystem)) .addAll(COMPILER_SPECIFIC_FLAGS) .add("-x") .add("c++") .add("-c") .add("-o") .add( BuildTargets.getGenPath( filesystem, target.withFlavors( ImmutableFlavor.of("default"), ImmutableFlavor.of("compile-pic-" + sanitize("test.cpp.o"))), "%s/test.cpp.o") .toString()) .add(rootPath.resolve(Paths.get("test.cpp")).toRealPath().toString()) .build()); }
@Test public void compilationDatabaseFetchedFromCacheAlsoFetchesSymlinkTreeOrHeaderMap() throws IOException { ProjectWorkspace workspace = TestDataHelper.createProjectWorkspaceForScenario(this, "compilation_database", tmp); workspace.setUp(); ProjectFilesystem filesystem = new FakeProjectFilesystem(); // This test only fails if the directory cache is enabled and we don't update // the header map/symlink tree correctly when fetching from the cache. workspace.enableDirCache(); addLibraryHeaderFiles(workspace); BuildTarget target = BuildTargetFactory.newInstance("//:library_with_header#default,compilation-database"); // Populate the cache with the built rule workspace.buildAndReturnOutput(target.getFullyQualifiedName()); Path headerSymlinkTreeFolder = BuildTargets.getGenPath( filesystem, target.withFlavors( ImmutableFlavor.of("default"), CxxDescriptionEnhancer.HEADER_SYMLINK_TREE_FLAVOR), "%s"); Path exportedHeaderSymlinkTreeFolder = BuildTargets.getGenPath( filesystem, target.withFlavors( ImmutableFlavor.of("default"), CxxDescriptionEnhancer.EXPORTED_HEADER_SYMLINK_TREE_FLAVOR), "%s"); // Validate the symlink tree/header maps verifyHeaders(workspace, headerSymlinkTreeFolder, "bar.h", "baz.h", "blech_private.h"); verifyHeaders(workspace, exportedHeaderSymlinkTreeFolder, "bar.h", "baz.h"); // Delete the newly-added files and build again Files.delete(workspace.getPath("baz.h")); Files.delete(workspace.getPath("blech_private.h")); workspace.buildAndReturnOutput(target.getFullyQualifiedName()); verifyHeaders(workspace, headerSymlinkTreeFolder, "bar.h"); verifyHeaders(workspace, exportedHeaderSymlinkTreeFolder, "bar.h"); // Restore the headers, build again, and check the symlink tree/header maps addLibraryHeaderFiles(workspace); workspace.buildAndReturnOutput(target.getFullyQualifiedName()); verifyHeaders(workspace, headerSymlinkTreeFolder, "bar.h", "baz.h", "blech_private.h"); verifyHeaders(workspace, exportedHeaderSymlinkTreeFolder, "bar.h", "baz.h"); }
@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)); }
@Test public void testAppleLibraryExportedHeaderSymlinkTree() throws IOException { assumeTrue(Platform.detect() == Platform.MACOS); ProjectWorkspace workspace = TestDataHelper.createProjectWorkspaceForScenario( this, "apple_library_header_symlink_tree", tmp); workspace.setUp(); ProjectFilesystem filesystem = new ProjectFilesystem(workspace.getDestPath()); BuildTarget buildTarget = BuildTargetFactory.newInstance( "//Libraries/TestLibrary:TestLibrary#" + "default," + CxxDescriptionEnhancer.EXPORTED_HEADER_SYMLINK_TREE_FLAVOR); ProjectWorkspace.ProcessResult result = workspace.runBuckCommand("build", buildTarget.getFullyQualifiedName()); result.assertSuccess(); Path inputPath = workspace.getPath(buildTarget.getBasePath()).toRealPath(); Path outputPath = workspace.getPath(BuildTargets.getGenPath(filesystem, buildTarget, "%s")).toRealPath(); assertIsSymbolicLink( outputPath.resolve("TestLibrary/PublicHeader.h"), inputPath.resolve("PublicHeader.h")); }
@VisibleForTesting protected Path getExtensionPath( ProjectFilesystem filesystem, BuildTarget target, Flavor pythonPlatform, Flavor platform) { return BuildTargets.getGenPath( filesystem, getExtensionTarget(target, pythonPlatform, platform), "%s") .resolve(getExtensionName(target)); }
@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 noIncludeFrameworksDoesntContainFrameworkDependencies() 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#" + "dwarf-and-dsym,framework,macosx-x86_64,no-include-frameworks"); ProjectWorkspace.ProcessResult result = workspace.runBuckCommand("build", target.getFullyQualifiedName()); result.assertSuccess(); Path frameworkPath = workspace.getPath( BuildTargets.getGenPath(filesystem, target, "%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")); Path frameworksPath = frameworkPath.resolve("Contents/Frameworks"); assertThat(Files.exists(frameworksPath), is(false)); }
@Test public void compilationDatabaseWithDepsFetchedFromCacheAlsoFetchesSymlinkTreeOrHeaderMapOfDeps() throws IOException { ProjectWorkspace workspace = TestDataHelper.createProjectWorkspaceForScenario( this, "compilation_database_with_deps", tmp); workspace.setUp(); ProjectFilesystem filesystem = new FakeProjectFilesystem(); // This test only fails if the directory cache is enabled and we don't update // the header map/symlink tree correctly when fetching from the cache. workspace.enableDirCache(); addDepLibraryHeaderFiles(workspace); BuildTarget target = BuildTargetFactory.newInstance("//:library_with_header#default,compilation-database"); // Populate the cache with the built rule workspace.buildAndReturnOutput(target.getFullyQualifiedName()); Path dep1ExportedSymlinkTreeFolder = BuildTargets.getGenPath( filesystem, BuildTargetFactory.newInstance("//dep1:dep1#default,headers"), "%s"); Path dep2ExportedSymlinkTreeFolder = BuildTargets.getGenPath( filesystem, BuildTargetFactory.newInstance("//dep2:dep2#default,headers"), "%s"); // Validate the deps' symlink tree/header maps verifyHeaders(workspace, dep1ExportedSymlinkTreeFolder, "dep1/dep1.h", "dep1/dep1_new.h"); verifyHeaders(workspace, dep2ExportedSymlinkTreeFolder, "dep2/dep2.h", "dep2/dep2_new.h"); // Delete the newly-added files and build again Files.delete(workspace.getPath("dep1/dep1_new.h")); Files.delete(workspace.getPath("dep2/dep2_new.h")); workspace.buildAndReturnOutput(target.getFullyQualifiedName()); verifyHeaders(workspace, dep1ExportedSymlinkTreeFolder, "dep1/dep1.h"); verifyHeaders(workspace, dep2ExportedSymlinkTreeFolder, "dep2/dep2.h"); // Restore the headers, build again, and check the deps' symlink tree/header maps addDepLibraryHeaderFiles(workspace); workspace.buildAndReturnOutput(target.getFullyQualifiedName()); verifyHeaders(workspace, dep1ExportedSymlinkTreeFolder, "dep1/dep1.h", "dep1/dep1_new.h"); verifyHeaders(workspace, dep2ExportedSymlinkTreeFolder, "dep2/dep2.h", "dep2/dep2_new.h"); }
@Test public void testCreateBuildRule() throws Exception { // Set up a #halide-compiler rule, then set up a halide_library rule, and // check that the library rule depends on the compiler rule. BuildTarget compilerTarget = BuildTargetFactory.newInstance("//:rule") .withFlavors(HalideLibraryDescription.HALIDE_COMPILER_FLAVOR); BuildTarget libTarget = BuildTargetFactory.newInstance("//:rule"); ProjectFilesystem filesystem = new FakeProjectFilesystem(); HalideLibraryBuilder compilerBuilder = new HalideLibraryBuilder(compilerTarget); compilerBuilder.setSrcs( ImmutableSortedSet.of(SourceWithFlags.of(new FakeSourcePath("main.cpp")))); HalideLibraryBuilder libBuilder = new HalideLibraryBuilder(libTarget); TargetGraph targetGraph = TargetGraphFactory.newInstance(compilerBuilder.build(), libBuilder.build()); BuildRuleResolver resolver = new BuildRuleResolver(targetGraph, new BuildTargetNodeToBuildRuleTransformer()); CxxBinary compiler = (CxxBinary) compilerBuilder.build(resolver, filesystem, targetGraph); HalideLibrary lib = (HalideLibrary) libBuilder.build(resolver, filesystem, targetGraph); // Check that we picked up the implicit dependency on the #halide-compiler // version of the rule. assertEquals(lib.getDeps(), ImmutableSortedSet.<BuildRule>of(compiler)); // Check that the library rule has the correct preprocessor input. CxxPlatform cxxPlatform = CxxLibraryBuilder.createDefaultPlatform(); String headerName = "rule.h"; Path headerPath = BuildTargets.getGenPath(libTarget, "%s/" + headerName); Path headerRoot = CxxDescriptionEnhancer.getHeaderSymlinkTreePath( libTarget, cxxPlatform.getFlavor(), HeaderVisibility.PUBLIC); assertEquals( CxxPreprocessorInput.builder() .addRules( CxxDescriptionEnhancer.createHeaderSymlinkTreeTarget( libTarget, cxxPlatform.getFlavor(), HeaderVisibility.PUBLIC)) .setIncludes( CxxHeaders.builder() .putNameToPathMap( Paths.get(headerName), new BuildTargetSourcePath(libTarget, headerPath)) .putFullNameToPathMap( headerRoot.resolve(headerName), new BuildTargetSourcePath(libTarget, headerPath)) .build()) .addSystemIncludeRoots(headerRoot) .build(), lib.getCxxPreprocessorInput(cxxPlatform, HeaderVisibility.PUBLIC)); // Check that the library rule has the correct native linkable input. NativeLinkableInput input = lib.getNativeLinkableInput(cxxPlatform, Linker.LinkableDepType.STATIC); BuildRule buildRule = FluentIterable.from(input.getArgs()) .transformAndConcat(Arg.getDepsFunction(new SourcePathResolver(resolver))) .get(0); assertTrue(buildRule instanceof HalideLibrary); }
public AndroidAar( BuildRuleParams params, SourcePathResolver resolver, AndroidManifest manifest, AndroidResource androidResource, Path assembledResourceDirectory, Path assembledAssetsDirectory, Optional<Path> assembledNativeLibs, ImmutableSet<SourcePath> nativeLibAssetsDirectories) { super(params, resolver); BuildTarget buildTarget = params.getBuildTarget(); this.pathToOutputFile = BuildTargets.getGenPath(buildTarget, "%s.aar"); this.temp = BuildTargets.getScratchPath(buildTarget, "__temp__%s"); this.manifest = manifest; this.androidResource = androidResource; this.assembledAssetsDirectory = assembledAssetsDirectory; this.assembledResourceDirectory = assembledResourceDirectory; this.assembledNativeLibs = assembledNativeLibs; this.nativeLibAssetsDirectories = nativeLibAssetsDirectories; }
GenAidl( BuildRuleParams params, SourcePathResolver resolver, Path aidlFilePath, String importPath) { super(params, resolver); this.aidlFilePath = aidlFilePath; this.importPath = importPath; BuildTarget buildTarget = params.getBuildTarget(); this.genPath = BuildTargets.getGenPath(buildTarget, "%s"); this.output = genPath.resolve( String.format("lib%s%s", buildTarget.getShortNameAndFlavorPostfix(), SRC_ZIP)); }
@Test public void testDexExopackageHasNoSecondary() throws IOException { ZipInspector zipInspector = new ZipInspector( workspace.getPath( BuildTargets.getGenPath( filesystem, BuildTargetFactory.newInstance(DEX_EXOPACKAGE_TARGET), "%s.apk"))); zipInspector.assertFileDoesNotExist("assets/secondary-program-dex-jars/metadata.txt"); zipInspector.assertFileDoesNotExist("assets/secondary-program-dex-jars/secondary-1.dex.jar"); zipInspector.assertFileDoesNotExist("classes2.dex"); zipInspector.assertFileExists("classes.dex"); zipInspector.assertFileExists("lib/armeabi/libfakenative.so"); // It would be better if we could call getExopackageInfo on the app rule. Path secondaryDir = workspace.resolve( BuildTargets.getScratchPath( filesystem, BuildTargetFactory.newInstance(DEX_EXOPACKAGE_TARGET) .withFlavors(ImmutableFlavor.of("dex_merge")), "_%s_output/jarfiles/assets/secondary-program-dex-jars")); try (DirectoryStream<Path> stream = Files.newDirectoryStream(secondaryDir)) { List<Path> files = Lists.newArrayList(stream); assertEquals(2, files.size()); Collections.sort(files); Path secondaryJar = files.get(0); ZipInspector zi = new ZipInspector(secondaryJar); zi.assertFileExists("classes.dex"); long jarSize = Files.size(secondaryJar); long classesDexSize = zi.getSize("classes.dex"); Path dexMeta = files.get(1); assertEquals( String.format("jar:%s dex:%s", jarSize, classesDexSize), new String(Files.readAllBytes(dexMeta), "US-ASCII")); } }
@Test public void testAppleLibraryIsHermetic() throws IOException { assumeTrue(Platform.detect() == Platform.MACOS); ProjectWorkspace workspace = TestDataHelper.createProjectWorkspaceForScenario(this, "apple_library_is_hermetic", tmp); workspace.setUp(); ProjectFilesystem filesystem = new ProjectFilesystem(workspace.getDestPath()); BuildTarget target = BuildTargetFactory.newInstance( "//Libraries/TestLibrary:TestLibrary#static,iphonesimulator-x86_64"); ProjectWorkspace.ProcessResult first = workspace.runBuckCommand( workspace.getPath("first"), "build", target.getFullyQualifiedName()); first.assertSuccess(); ProjectWorkspace.ProcessResult second = workspace.runBuckCommand( workspace.getPath("second"), "build", target.getFullyQualifiedName()); second.assertSuccess(); Path objectPath = BuildTargets.getGenPath( filesystem, target.withFlavors( ImmutableFlavor.of("compile-" + sanitize("TestClass.m.o")), ImmutableFlavor.of("iphonesimulator-x86_64")), "%s") .resolve("TestClass.m.o"); MoreAsserts.assertContentsEqual( workspace.getPath(Paths.get("first").resolve(objectPath)), workspace.getPath(Paths.get("second").resolve(objectPath))); Path libraryPath = BuildTargets.getGenPath(filesystem, target, "%s").resolve("libTestLibrary.a"); MoreAsserts.assertContentsEqual( workspace.getPath(Paths.get("first").resolve(libraryPath)), workspace.getPath(Paths.get("second").resolve(libraryPath))); }
CxxInferAnalyze( BuildRuleParams buildRuleParams, SourcePathResolver pathResolver, InferBuckConfig inferConfig, CxxInferCaptureAndAggregatingRules<CxxInferAnalyze> captureAndAnalyzeRules) { super(buildRuleParams, pathResolver); this.captureAndAnalyzeRules = captureAndAnalyzeRules; this.resultsDir = BuildTargets.getGenPath(getProjectFilesystem(), this.getBuildTarget(), "infer-analysis-%s"); this.reportFile = this.resultsDir.resolve("report.json"); this.specsDir = this.resultsDir.resolve("specs"); this.specsPathList = this.resultsDir.resolve("specs_path_list.txt"); this.inferConfig = inferConfig; }
@Override public ImmutableList<Step> getBuildSteps( BuildContext context, BuildableContext buildableContext) { ImmutableList.Builder<Step> commands = ImmutableList.builder(); commands.add(new MakeCleanDirectoryStep(getProjectFilesystem(), genPath)); BuildTarget target = getBuildTarget(); Path outputDirectory = BuildTargets.getScratchPath(target, "__%s.aidl"); commands.add(new MakeCleanDirectoryStep(getProjectFilesystem(), outputDirectory)); AidlStep command = new AidlStep( getProjectFilesystem(), target, getResolver().getAbsolutePath(aidlFilePath), ImmutableSet.of(importPath), outputDirectory); commands.add(command); // Files must ultimately be written to GEN_DIR to be used as source paths. Path genDirectory = Paths.get(BuckConstant.GEN_DIR, importPath); // Warn the user if the genDirectory is not under the output directory. if (!importPath.startsWith(target.getBasePath().toString())) { // TODO(shs96c): Make this fatal. Give people some time to clean up their rules. context .getEventBus() .post( ConsoleEvent.warning( "%s, gen_aidl import path (%s) should be a child of %s", target, importPath, target.getBasePath())); } commands.add(new MkdirStep(getProjectFilesystem(), genDirectory)); commands.add( new JarDirectoryStep( getProjectFilesystem(), output, ImmutableSortedSet.of(outputDirectory), /* main class */ null, /* manifest */ null)); buildableContext.recordArtifact(output); return commands.build(); }
@Test public void testBuildEmptySourceAppleLibrary() throws Exception { assumeTrue(Platform.detect() == Platform.MACOS); ProjectWorkspace workspace = TestDataHelper.createProjectWorkspaceForScenario(this, "empty_source_targets", tmp); workspace.setUp(); BuildTarget target = workspace.newBuildTarget("//:real-none#iphonesimulator-x86_64,shared"); ProjectWorkspace.ProcessResult result = workspace.runBuckCommand("build", target.getFullyQualifiedName()); result.assertSuccess(); ProjectFilesystem filesystem = new ProjectFilesystem(workspace.getDestPath()); Path binaryOutput = workspace.getPath(BuildTargets.getGenPath(filesystem, target, "%s/libreal-none.dylib")); assertThat(Files.exists(binaryOutput), is(true)); }
@Test public void testAppleLibraryBuildsSomething() throws IOException { assumeTrue(Platform.detect() == Platform.MACOS); 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#static,default"); ProjectWorkspace.ProcessResult result = workspace.runBuckCommand("build", target.getFullyQualifiedName()); result.assertSuccess(); assertTrue(Files.exists(workspace.getPath(BuildTargets.getGenPath(filesystem, target, "%s")))); }
@Test public void testAllExopackageHasNeitherSecondaryNorNativeLibraries() throws IOException { ZipInspector zipInspector = new ZipInspector( workspace.getPath( BuildTargets.getGenPath( filesystem, BuildTargetFactory.newInstance(DEX_AND_NATIVE_EXOPACKAGE_TARGET), "%s.apk"))); zipInspector.assertFileDoesNotExist("assets/secondary-program-dex-jars/metadata.txt"); zipInspector.assertFileDoesNotExist("classes2.dex"); zipInspector.assertFileExists("classes.dex"); assertNativeLibrariesDontExist(zipInspector); }
@Test public void testAppleLibraryBuildsForWatchOS() throws IOException { assumeTrue(AppleNativeIntegrationTestUtils.isApplePlatformAvailable(ApplePlatform.WATCHOS)); 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#watchos-armv7k,static"); ProjectWorkspace.ProcessResult result = workspace.runBuckCommand("build", target.getFullyQualifiedName()); result.assertSuccess(); assertTrue(Files.exists(workspace.getPath(BuildTargets.getGenPath(filesystem, target, "%s")))); }
@Override public ImmutableList<Step> getBuildSteps( BuildContext context, BuildableContext buildableContext) { ImmutableList.Builder<Step> steps = ImmutableList.builder(); // Setup the scratch dir. Path scratchDir = BuildTargets.getScratchPath(getProjectFilesystem(), getBuildTarget(), "%s"); steps.add(new MakeCleanDirectoryStep(getProjectFilesystem(), scratchDir)); // Setup the package DB directory. final Path packageDb = getPackageDb(); steps.add(new RmStep(getProjectFilesystem(), packageDb, true, true)); buildableContext.recordArtifact(packageDb); // Create the registration file. Path registrationFile = scratchDir.resolve("registration-file"); steps.add(getWriteRegistrationFileStep(registrationFile, packageDb)); // Build the the package DB. steps.add(new GhcPkgStep(ImmutableList.of("init", packageDb.toString()), ImmutableMap.of())); steps.add( new GhcPkgStep( ImmutableList.of( "-v0", "register", "--package-conf=" + packageDb, "--no-expand-pkgroot", registrationFile.toString()), ImmutableMap.of( "GHC_PACKAGE_PATH", Joiner.on(':') .join( FluentIterable.from(depPackages.values()) .transform( input -> getResolver() .getAbsolutePath(input.getPackageDb()) .toString()))))); return steps.build(); }
@Test public void testAppleLibraryWithDefaultsInRuleBuildsSomething() throws IOException { assumeTrue(Platform.detect() == Platform.MACOS); ProjectWorkspace workspace = TestDataHelper.createProjectWorkspaceForScenario( this, "apple_library_with_platform_and_type", tmp); workspace.setUp(); ProjectFilesystem filesystem = new ProjectFilesystem(workspace.getDestPath()); BuildTarget target = BuildTargetFactory.newInstance("//Libraries/TestLibrary:TestLibrary"); ProjectWorkspace.ProcessResult result = workspace.runBuckCommand("build", target.getFullyQualifiedName()); result.assertSuccess(); BuildTarget implicitTarget = target.withAppendedFlavors( ImmutableFlavor.of("shared"), ImmutableFlavor.of("iphoneos-arm64")); Path outputPath = workspace.getPath(BuildTargets.getGenPath(filesystem, implicitTarget, "%s")); assertTrue(Files.exists(outputPath)); }
@Test public void testBuildAppleLibraryThatHasSwift() throws Exception { assumeTrue(Platform.detect() == Platform.MACOS); ProjectWorkspace workspace = TestDataHelper.createProjectWorkspaceForScenario(this, "empty_source_targets", tmp); workspace.setUp(); BuildTarget target = workspace.newBuildTarget("//:none-swift#iphonesimulator-x86_64,shared"); ProjectWorkspace.ProcessResult result = workspace.runBuckCommand("build", target.getFullyQualifiedName()); result.assertSuccess(); ProjectFilesystem filesystem = new ProjectFilesystem(workspace.getDestPath()); Path binaryOutput = workspace.getPath(BuildTargets.getGenPath(filesystem, target, "%s/libnone-swift.dylib")); assertThat(Files.exists(binaryOutput), is(true)); assertThat( workspace.runCommand("otool", "-L", binaryOutput.toString()).getStdout().get(), containsString("libswiftCore.dylib")); }
@Test public void findDepsFromParamsSetsUpDepsForFlavoredTarget() { // Create the thrift target and implicit dep. BuildTarget thriftTarget = BuildTargetFactory.newInstance("//bar:thrift_compiler"); FakeBuildRule implicitDep = createFakeBuildRule("//foo:implicit_dep", new SourcePathResolver(new BuildRuleResolver())); // Setup the default values returned by the language specific enhancer. String language = "fake"; Flavor flavor = ImmutableFlavor.of("fake"); ImmutableSet<String> options = ImmutableSet.of(); ImmutableSet<BuildTarget> implicitDeps = ImmutableSet.of(implicitDep.getBuildTarget()); BuildTarget unflavoredTarget = BuildTargetFactory.newInstance("//:thrift"); BuildTarget flavoredTarget = BuildTargets.createFlavoredBuildTarget(unflavoredTarget.checkUnflavored(), flavor); // Setup an empty thrift buck config and description. FakeBuckConfig buckConfig = new FakeBuckConfig( ImmutableMap.of("thrift", ImmutableMap.of("compiler", thriftTarget.toString()))); ThriftBuckConfig thriftBuckConfig = new ThriftBuckConfig(buckConfig); ThriftLanguageSpecificEnhancer enhancer = new FakeThriftLanguageSpecificEnhancer(language, flavor, implicitDeps, options); ThriftLibraryDescription desc = new ThriftLibraryDescription(thriftBuckConfig, ImmutableList.of(enhancer)); ThriftConstructorArg constructorArg = desc.createUnpopulatedConstructorArg(); constructorArg.deps = Optional.of(ImmutableSortedSet.<BuildTarget>of()); // Now call the find deps methods and verify it returns nothing. Iterable<BuildTarget> results = desc.findDepsForTargetFromConstructorArgs(flavoredTarget, constructorArg); assertEquals( ImmutableSet.<BuildTarget>builder() .add(unflavoredTarget) .add(thriftTarget) .addAll(implicitDeps) .build(), ImmutableSet.copyOf(results)); }
@Test public void testAppleLibraryWithDefaultsInConfigBuildsSomething() throws IOException { assumeTrue(Platform.detect() == Platform.MACOS); ProjectWorkspace workspace = TestDataHelper.createProjectWorkspaceForScenario( this, "apple_library_builds_something", tmp); workspace.setUp(); ProjectFilesystem filesystem = new ProjectFilesystem(workspace.getDestPath()); workspace.writeContentsToPath( "[defaults.apple_library]\n platform = iphonesimulator-x86_64\n type = shared\n", ".buckconfig.local"); BuildTarget target = BuildTargetFactory.newInstance("//Libraries/TestLibrary:TestLibrary"); ProjectWorkspace.ProcessResult result = workspace.runBuckCommand("build", target.getFullyQualifiedName()); result.assertSuccess(); BuildTarget implicitTarget = target.withAppendedFlavors( ImmutableFlavor.of("shared"), ImmutableFlavor.of("iphonesimulator-x86_64")); assertTrue( Files.exists(workspace.getPath(BuildTargets.getGenPath(filesystem, implicitTarget, "%s")))); }
@Override public Path getPathToTestOutputDirectory() { return BuildTargets.getGenPath(getProjectFilesystem(), getBuildTarget(), "__test_%s_output__"); }
@Test public void createBuildRuleWithFlavoredTargetCallsEnhancerCorrectly() throws IOException { BuildRuleResolver resolver = new BuildRuleResolver(); SourcePathResolver pathResolver = new SourcePathResolver(resolver); FakeProjectFilesystem filesystem = new FakeProjectFilesystem(); // Setup the default values returned by the language specific enhancer. String language = "fake"; Flavor flavor = ImmutableFlavor.of("fake"); final BuildRule implicitDep = createFakeBuildRule("//implicit:dep", pathResolver); resolver.addToIndex(implicitDep); filesystem.mkdirs(implicitDep.getBuildTarget().getBasePath()); filesystem.touch(implicitDep.getBuildTarget().getBasePath().resolve("BUCK")); ImmutableSet<BuildTarget> implicitDeps = ImmutableSet.of(implicitDep.getBuildTarget()); ImmutableSet<String> options = ImmutableSet.of(); // Create the build targets and params. BuildTarget unflavoredTarget = BuildTargetFactory.newInstance("//:thrift"); BuildRuleParams unflavoredParams = new FakeBuildRuleParamsBuilder(unflavoredTarget).setProjectFilesystem(filesystem).build(); BuildTarget flavoredTarget = BuildTargets.createFlavoredBuildTarget(unflavoredTarget.checkUnflavored(), flavor); BuildRuleParams flavoredParams = new FakeBuildRuleParamsBuilder(flavoredTarget).setProjectFilesystem(filesystem).build(); // Setup a thrift source file generated by a genrule. final String thriftSourceName1 = "foo.thrift"; BuildTarget genruleTarget = BuildTargetFactory.newInstance("//:genrule"); final Genrule genrule = (Genrule) GenruleBuilder.newGenruleBuilder(genruleTarget) .setOut(thriftSourceName1) .build(resolver); SourcePath thriftSource1 = new BuildTargetSourcePath(genrule.getBuildTarget()); final ImmutableList<String> thriftServices1 = ImmutableList.of(); // Setup a normal thrift source file. final String thriftSourceName2 = "bar.thrift"; SourcePath thriftSource2 = new TestSourcePath(thriftSourceName2); final ImmutableList<String> thriftServices2 = ImmutableList.of(); // Create a build rule that represents the thrift rule. final FakeBuildRule thriftRule = createFakeBuildRule("//thrift:target", pathResolver); resolver.addToIndex(thriftRule); filesystem.mkdirs(thriftRule.getBuildTarget().getBasePath()); filesystem.touch(thriftRule.getBuildTarget().getBasePath().resolve("BUCK")); // Setup a simple description with an empty config. FakeBuckConfig buckConfig = new FakeBuckConfig( ImmutableMap.of( "thrift", ImmutableMap.of("compiler", thriftRule.getBuildTarget().toString()))); ThriftBuckConfig thriftBuckConfig = new ThriftBuckConfig(buckConfig); ThriftLibraryDescription desc = new ThriftLibraryDescription( thriftBuckConfig, ImmutableList.<ThriftLanguageSpecificEnhancer>of()); // Setup the include rules. final BuildRule thriftIncludeSymlinkTree = createFakeBuildRule( desc.createThriftIncludeSymlinkTreeTarget(unflavoredTarget), pathResolver); // Setup our language enhancer FakeThriftLanguageSpecificEnhancer enhancer = new FakeThriftLanguageSpecificEnhancer(language, flavor, implicitDeps, options) { @Override public void checkCreateBuildRuleInputs( ImmutableMap<String, ThriftSource> sources, ImmutableSortedSet<BuildRule> deps) { // Verify both thrift sources are present in the list. assertEquals(2, sources.size()); ThriftSource src1 = sources.get(thriftSourceName1); assertNotNull(src1); ThriftSource src2 = sources.get(thriftSourceName2); assertNotNull(src2); // Verify the services are listed correctly for both sources. assertEquals(thriftServices1, src1.getServices()); assertEquals(thriftServices2, src2.getServices()); // Verify dependencies are setup correctly. assertEquals( ImmutableSortedSet.of(genrule, thriftRule, thriftIncludeSymlinkTree), src1.getCompileRule().getDeps()); assertEquals( ImmutableSortedSet.of(genrule, thriftRule, thriftIncludeSymlinkTree), src2.getCompileRule().getDeps()); // Verify the language specific implicit rules are added correctly. assertEquals( ImmutableSortedSet.<BuildRule>naturalOrder().add(implicitDep).build(), deps); } }; // Recreate the description with the enhancer we setup above. desc = new ThriftLibraryDescription( thriftBuckConfig, ImmutableList.<ThriftLanguageSpecificEnhancer>of(enhancer)); // Setup the internal structure indicating that the thrift target was set in the // buck config. // desc.setCompilerTarget(thriftRule.getBuildTarget()); // Setup the implicit deps for the flavored build target. // desc.setImplicitDeps(flavoredTarget, ImmutableList.of(implicitDep.getBuildTarget())); // Build up the constructor arg. ThriftConstructorArg arg = desc.createUnpopulatedConstructorArg(); arg.name = "thrift"; arg.srcs = ImmutableMap.of( thriftSource1, thriftServices1, thriftSource2, thriftServices2); arg.deps = Optional.absent(); arg.flags = Optional.absent(); // Setup the unflavored target, which should just produce a ThriftInclude, SymlinkTree, and // ThriftLibrary rule. BuildRule rule = desc.createBuildRule(TargetGraph.EMPTY, unflavoredParams, resolver, arg); resolver.addToIndex(rule); // Now attempt to create the flavored thrift library. desc.createBuildRule(TargetGraph.EMPTY, flavoredParams, resolver, arg); }
@Override public <A extends Arg> BuildRule createBuildRule( TargetGraph targetGraph, BuildRuleParams originalBuildRuleParams, BuildRuleResolver resolver, A args) { UnflavoredBuildTarget originalBuildTarget = originalBuildRuleParams.getBuildTarget().checkUnflavored(); SourcePathResolver pathResolver = new SourcePathResolver(resolver); ImmutableList.Builder<BuildRule> aarExtraDepsBuilder = ImmutableList.<BuildRule>builder().addAll(originalBuildRuleParams.getExtraDeps().get()); /* android_manifest */ AndroidManifestDescription.Arg androidManifestArgs = androidManifestDescription.createUnpopulatedConstructorArg(); androidManifestArgs.skeleton = args.manifestSkeleton; androidManifestArgs.deps = args.deps; BuildRuleParams androidManifestParams = originalBuildRuleParams.copyWithChanges( BuildTargets.createFlavoredBuildTarget( originalBuildTarget, AAR_ANDROID_MANIFEST_FLAVOR), originalBuildRuleParams.getDeclaredDeps(), originalBuildRuleParams.getExtraDeps()); AndroidManifest manifest = androidManifestDescription.createBuildRule( targetGraph, androidManifestParams, resolver, androidManifestArgs); aarExtraDepsBuilder.add(resolver.addToIndex(manifest)); /* assemble dirs */ AndroidPackageableCollector collector = new AndroidPackageableCollector( originalBuildRuleParams.getBuildTarget(), /* buildTargetsToExcludeFromDex */ ImmutableSet.<BuildTarget>of(), /* resourcesToExclude */ ImmutableSet.<BuildTarget>of()); collector.addPackageables( AndroidPackageableCollector.getPackageableRules(originalBuildRuleParams.getDeps())); AndroidPackageableCollection packageableCollection = collector.build(); ImmutableSortedSet<BuildRule> androidResourceDeclaredDeps = AndroidResourceHelper.androidResOnly(originalBuildRuleParams.getDeclaredDeps().get()); ImmutableSortedSet<BuildRule> androidResourceExtraDeps = AndroidResourceHelper.androidResOnly(originalBuildRuleParams.getExtraDeps().get()); BuildRuleParams assembleAssetsParams = originalBuildRuleParams.copyWithChanges( BuildTargets.createFlavoredBuildTarget(originalBuildTarget, AAR_ASSEMBLE_ASSETS_FLAVOR), Suppliers.ofInstance(androidResourceDeclaredDeps), Suppliers.ofInstance(androidResourceExtraDeps)); ImmutableCollection<SourcePath> assetsDirectories = packageableCollection.getAssetsDirectories(); AssembleDirectories assembleAssetsDirectories = new AssembleDirectories(assembleAssetsParams, pathResolver, assetsDirectories); aarExtraDepsBuilder.add(resolver.addToIndex(assembleAssetsDirectories)); BuildRuleParams assembleResourceParams = originalBuildRuleParams.copyWithChanges( BuildTargets.createFlavoredBuildTarget( originalBuildTarget, AAR_ASSEMBLE_RESOURCE_FLAVOR), Suppliers.ofInstance(androidResourceDeclaredDeps), Suppliers.ofInstance(androidResourceExtraDeps)); ImmutableCollection<SourcePath> resDirectories = packageableCollection.getResourceDetails().getResourceDirectories(); MergeAndroidResourceSources assembleResourceDirectories = new MergeAndroidResourceSources(assembleResourceParams, pathResolver, resDirectories); aarExtraDepsBuilder.add(resolver.addToIndex(assembleResourceDirectories)); /* android_resource */ BuildRuleParams androidResourceParams = originalBuildRuleParams.copyWithChanges( BuildTargets.createFlavoredBuildTarget( originalBuildTarget, AAR_ANDROID_RESOURCE_FLAVOR), Suppliers.ofInstance( ImmutableSortedSet.<BuildRule>of( manifest, assembleAssetsDirectories, assembleResourceDirectories)), Suppliers.ofInstance(ImmutableSortedSet.<BuildRule>of())); AndroidResource androidResource = new AndroidResource( androidResourceParams, pathResolver, /* deps */ ImmutableSortedSet.<BuildRule>naturalOrder() .add(assembleAssetsDirectories) .add(assembleResourceDirectories) .addAll(originalBuildRuleParams.getDeclaredDeps().get()) .build(), new BuildTargetSourcePath(assembleResourceDirectories.getBuildTarget()), /* resSrcs */ ImmutableSortedSet.<SourcePath>of(), Optional.<SourcePath>absent(), /* rDotJavaPackage */ null, new BuildTargetSourcePath(assembleAssetsDirectories.getBuildTarget()), /* assetsSrcs */ ImmutableSortedSet.<SourcePath>of(), Optional.<SourcePath>absent(), new BuildTargetSourcePath(manifest.getBuildTarget()), /* hasWhitelistedStrings */ false); aarExtraDepsBuilder.add(resolver.addToIndex(androidResource)); /* native_libraries */ AndroidNativeLibsPackageableGraphEnhancer packageableGraphEnhancer = new AndroidNativeLibsPackageableGraphEnhancer( resolver, originalBuildRuleParams, nativePlatforms, ImmutableSet.<NdkCxxPlatforms.TargetCpuType>of()); Optional<CopyNativeLibraries> nativeLibrariesOptional = packageableGraphEnhancer.getCopyNativeLibraries(targetGraph, packageableCollection); if (nativeLibrariesOptional.isPresent()) { aarExtraDepsBuilder.add(resolver.addToIndex(nativeLibrariesOptional.get())); } Optional<Path> assembledNativeLibsDir = nativeLibrariesOptional.transform( new Function<CopyNativeLibraries, Path>() { @Override public Path apply(CopyNativeLibraries input) { return input.getPathToNativeLibsDir(); } }); BuildRuleParams androidAarParams = originalBuildRuleParams.copyWithExtraDeps( Suppliers.ofInstance(ImmutableSortedSet.copyOf(aarExtraDepsBuilder.build()))); return new AndroidAar( androidAarParams, pathResolver, manifest, androidResource, assembleResourceDirectories.getPathToOutput(), assembleAssetsDirectories.getPathToOutput(), assembledNativeLibsDir, packageableCollection.getNativeLibAssetsDirectories()); }
@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()); }
/** 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(); }
@Override public Path getPathToTestOutputDirectory() { return BuildTargets.getGenPath(getBuildTarget(), "__java_test_%s_output__"); }