Esempio n. 1
0
 private static AndroidBuildConfig createSimpleBuildConfigRule() {
   // First, create the BuildConfig object.
   BuildTarget buildTarget = BuildTarget.builder("//java/com/example", "build_config").build();
   BuildRuleParams params = new FakeBuildRuleParamsBuilder(buildTarget).build();
   return new AndroidBuildConfig(
       params,
       new SourcePathResolver(new BuildRuleResolver()),
       /* javaPackage */ "com.example",
       /* values */ BuildConfigFields.empty(),
       /* valuesFile */ Optional.<SourcePath>absent(),
       /* useConstantExpressions */ false);
 }
Esempio n. 2
0
 @Test
 public void testBuildInternal() throws IOException {
   AndroidBuildConfig buildConfig = createSimpleBuildConfigRule();
   List<Step> steps =
       buildConfig.getBuildSteps(FakeBuildContext.NOOP_CONTEXT, new FakeBuildableContext());
   Step generateBuildConfigStep = steps.get(1);
   GenerateBuildConfigStep expectedStep =
       new GenerateBuildConfigStep(
           new FakeProjectFilesystem(),
           /* source */ BuildTargetFactory.newInstance("//java/com/example:build_config"),
           /* javaPackage */ "com.example",
           /* useConstantExpressions */ false,
           /* constants */ Suppliers.ofInstance(BuildConfigFields.empty()),
           BuckConstant.GEN_PATH.resolve("java/com/example/__build_config__/BuildConfig.java"));
   assertEquals(expectedStep, generateBuildConfigStep);
 }
Esempio n. 3
0
  @Test
  @SuppressWarnings("PMD.UseAssertTrueInsteadOfAssertEquals") // PMD has a bad heuristic here.
  public void testReadValuesStep() throws IOException {
    Path pathToValues = Paths.get("src/values.txt");

    ProjectFilesystem projectFilesystem = EasyMock.createMock(ProjectFilesystem.class);
    EasyMock.expect(projectFilesystem.readLines(pathToValues))
        .andReturn(ImmutableList.of("boolean DEBUG = false", "String FOO = \"BAR\""));
    EasyMock.replay(projectFilesystem);

    ReadValuesStep step = new ReadValuesStep(projectFilesystem, pathToValues);
    ExecutionContext context = TestExecutionContext.newBuilder().build();
    int exitCode = step.execute(context);
    assertEquals(0, exitCode);
    assertEquals(
        BuildConfigFields.fromFields(
            ImmutableList.of(
                BuildConfigFields.Field.of("boolean", "DEBUG", "false"),
                BuildConfigFields.Field.of("String", "FOO", "\"BAR\""))),
        step.get());

    EasyMock.verify(projectFilesystem);
  }
  @Override
  public <A extends Arg> BuildRule createBuildRule(
      TargetGraph targetGraph, BuildRuleParams params, BuildRuleResolver resolver, A args) {
    BuildRule installableApk = resolver.getRule(args.apk);
    if (!(installableApk instanceof InstallableApk)) {
      throw new HumanReadableException(
          "In %s, apk='%s' must be an android_binary() or apk_genrule() but was %s().",
          params.getBuildTarget(),
          installableApk.getFullyQualifiedName(),
          installableApk.getType());
    }
    AndroidBinary apkUnderTest = getUnderlyingApk((InstallableApk) installableApk);

    ImmutableSortedSet<JavaLibrary> rulesToExcludeFromDex =
        FluentIterable.from(
                ImmutableSet.<JavaLibrary>builder()
                    .addAll(apkUnderTest.getRulesToExcludeFromDex())
                    .addAll(
                        Classpaths.getClasspathEntries(apkUnderTest.getClasspathDeps()).keySet())
                    .build())
            .toSortedSet(HasBuildTarget.BUILD_TARGET_COMPARATOR);

    // TODO(natthu): Instrumentation APKs should also exclude native libraries and assets from the
    // apk under test.
    AndroidPackageableCollection.ResourceDetails resourceDetails =
        apkUnderTest.getAndroidPackageableCollection().getResourceDetails();
    ImmutableSet<BuildTarget> resourcesToExclude =
        ImmutableSet.copyOf(
            Iterables.concat(
                resourceDetails.getResourcesWithNonEmptyResDir(),
                resourceDetails.getResourcesWithEmptyResButNonEmptyAssetsDir()));

    Path primaryDexPath = AndroidBinary.getPrimaryDexPath(params.getBuildTarget());
    AndroidBinaryGraphEnhancer graphEnhancer =
        new AndroidBinaryGraphEnhancer(
            targetGraph,
            params,
            resolver,
            ResourceCompressionMode.DISABLED,
            FilterResourcesStep.ResourceFilter.EMPTY_FILTER,
            /* resourceUnionPackage */ Optional.<String>absent(),
            /* locales */ ImmutableSet.<String>of(),
            args.manifest,
            PackageType.INSTRUMENTED,
            apkUnderTest.getCpuFilters(),
            /* shouldBuildStringSourceMap */ false,
            /* shouldPreDex */ false,
            primaryDexPath,
            DexSplitMode.NO_SPLIT,
            FluentIterable.from(rulesToExcludeFromDex).transform(TO_TARGET).toSet(),
            resourcesToExclude,
            /* skipCrunchPngs */ false,
            javacOptions,
            EnumSet.noneOf(ExopackageMode.class),
            apkUnderTest.getKeystore(),
            /* buildConfigValues */ BuildConfigFields.empty(),
            /* buildConfigValuesFile */ Optional.<SourcePath>absent(),
            /* xzCompressionLevel */ Optional.<Integer>absent(),
            nativePlatforms,
            dxExecutorService);

    AndroidGraphEnhancementResult enhancementResult = graphEnhancer.createAdditionalBuildables();

    return new AndroidInstrumentationApk(
        params
            .copyWithExtraDeps(Suppliers.ofInstance(enhancementResult.getFinalDeps()))
            .appendExtraDeps(rulesToExcludeFromDex),
        new SourcePathResolver(resolver),
        proGuardConfig.getProguardJarOverride(),
        proGuardConfig.getProguardMaxHeapSize(),
        apkUnderTest,
        rulesToExcludeFromDex,
        enhancementResult,
        dxExecutorService);
  }
  /**
   * If the user specified any android_build_config() rules, then we must add some build rules to
   * generate the production {@code BuildConfig.class} files and ensure that they are included in
   * the list of {@link AndroidPackageableCollection#getClasspathEntriesToDex}.
   */
  private void addBuildConfigDeps(
      boolean shouldPreDex,
      AndroidPackageableCollection packageableCollection,
      ImmutableSortedSet.Builder<BuildRule> enhancedDeps,
      ImmutableList.Builder<DexProducedFromJavaLibrary> preDexRules,
      ImmutableList.Builder<Path> buildConfigJarFilesBuilder) {
    BuildConfigFields buildConfigConstants =
        BuildConfigFields.fromFields(
            ImmutableList.<BuildConfigFields.Field>of(
                BuildConfigFields.Field.of(
                    "boolean",
                    BuildConfigs.DEBUG_CONSTANT,
                    String.valueOf(packageType != AndroidBinary.PackageType.RELEASE)),
                BuildConfigFields.Field.of(
                    "boolean",
                    BuildConfigs.IS_EXO_CONSTANT,
                    String.valueOf(!exopackageModes.isEmpty())),
                BuildConfigFields.Field.of(
                    "int",
                    BuildConfigs.EXOPACKAGE_FLAGS,
                    String.valueOf(ExopackageMode.toBitmask(exopackageModes)))));
    for (Map.Entry<String, BuildConfigFields> entry :
        packageableCollection.getBuildConfigs().entrySet()) {
      // Merge the user-defined constants with the APK-specific overrides.
      BuildConfigFields totalBuildConfigValues =
          BuildConfigFields.empty()
              .putAll(entry.getValue())
              .putAll(buildConfigValues)
              .putAll(buildConfigConstants);

      // Each enhanced dep needs a unique build target, so we parameterize the build target by the
      // Java package.
      String javaPackage = entry.getKey();
      Flavor flavor = ImmutableFlavor.of("buildconfig_" + javaPackage.replace('.', '_'));
      BuildRuleParams buildConfigParams =
          new BuildRuleParams(
              createBuildTargetWithFlavor(flavor),
              /* declaredDeps */ Suppliers.ofInstance(ImmutableSortedSet.<BuildRule>of()),
              /* extraDeps */ Suppliers.ofInstance(ImmutableSortedSet.<BuildRule>of()),
              buildRuleParams.getProjectFilesystem(),
              buildRuleParams.getRuleKeyBuilderFactory());
      JavaLibrary buildConfigJavaLibrary =
          AndroidBuildConfigDescription.createBuildRule(
              buildConfigParams,
              javaPackage,
              totalBuildConfigValues,
              buildConfigValuesFile,
              /* useConstantExpressions */ true,
              javacOptions,
              ruleResolver);
      ruleResolver.addToIndex(buildConfigJavaLibrary);

      enhancedDeps.add(buildConfigJavaLibrary);
      Path buildConfigJar = buildConfigJavaLibrary.getPathToOutput();
      Preconditions.checkNotNull(
          buildConfigJar, "%s must have an output file.", buildConfigJavaLibrary);
      buildConfigJarFilesBuilder.add(buildConfigJar);

      if (shouldPreDex) {
        DexProducedFromJavaLibrary buildConfigDex =
            new DexProducedFromJavaLibrary(
                buildConfigParams.copyWithChanges(
                    createBuildTargetWithFlavor(ImmutableFlavor.of("dex_" + flavor.getName())),
                    Suppliers.ofInstance(ImmutableSortedSet.<BuildRule>of(buildConfigJavaLibrary)),
                    /* extraDeps */ Suppliers.ofInstance(ImmutableSortedSet.<BuildRule>of())),
                pathResolver,
                buildConfigJavaLibrary);
        ruleResolver.addToIndex(buildConfigDex);
        enhancedDeps.add(buildConfigDex);
        preDexRules.add(buildConfigDex);
      }
    }
  }