@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);
  }
Example #10
0
 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;
 }
Example #11
0
 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)));
  }
Example #14
0
 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;
 }
Example #15
0
  @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"))));
  }
Example #20
0
  @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"))));
  }
Example #25
0
 @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();
  }
Example #30
0
 @Override
 public Path getPathToTestOutputDirectory() {
   return BuildTargets.getGenPath(getBuildTarget(), "__java_test_%s_output__");
 }