private void generateR() throws MojoExecutionException {
    getLog().info("Generating R file for " + project.getArtifact());

    genDirectory.mkdirs();

    final File[] overlayDirectories = getResourceOverlayDirectories();
    getLog().debug("Resource overlay folders : " + Arrays.asList(overlayDirectories));

    final CommandExecutor executor = CommandExecutor.Factory.createDefaultCommmandExecutor();
    executor.setLogger(this.getLog());

    final List<String> commands = new ArrayList<String>();
    commands.add("package");

    commands.add("-f");
    commands.add("--no-crunch");

    // inputs
    commands.add("-I");
    commands.add(getAndroidSdk().getAndroidJar().getAbsolutePath());

    commands.add("-M");
    commands.add(androidManifestFile.getAbsolutePath());

    // NB AndroidBuilder only adds a single folder - presumably it contains a merge of all
    // resources.
    for (File resOverlayDir : overlayDirectories) {
      if (resOverlayDir != null && resOverlayDir.exists()) {
        getLog().debug("Adding resource overlay folder : " + resOverlayDir);
        commands.add("-S");
        commands.add(resOverlayDir.getAbsolutePath());
      }
    }
    if (resourceDirectory.exists()) {
      getLog().debug("Adding resource folder : " + resourceDirectory);
      commands.add("-S");
      commands.add(resourceDirectory.getAbsolutePath());
    }

    // Need to include any AAR or APKLIB dependencies when generating R because if any local
    // resources directly reference dependent resources then R generation will crash.
    addLibraryResourceFolders(commands);

    // NB aapt only accepts a single assets parameter - combinedAssets is a merge of all assets
    if (combinedAssets.exists()) {
      getLog().debug("Adding assets folder : " + combinedAssets);
      commands.add("-A");
      commands.add(combinedAssets.getAbsolutePath());
    }

    // outputs
    commands.add("-m");
    commands.add("-J");
    commands.add(genDirectory.getAbsolutePath());

    // Write the output to an optional location
    // Used by AndroidBuilder but not by us.
    // final File optionalOutputLocation = some file;
    // getLog().debug( "Using default package : " + optionalOutputLocation );
    // commands.add( "-F" );
    // commands.add( optionalOutputLocation.getAbsolutePath() );

    // If a proguard file is defined then output Proguard options to it.
    if (proguardFile != null) {
      final File parentFolder = proguardFile.getParentFile();
      if (parentFolder != null) {
        parentFolder.mkdirs();
      }
      getLog().debug("Adding proguard file : " + proguardFile);
      commands.add("-G");
      commands.add(proguardFile.getAbsolutePath());
    }

    if (StringUtils.isNotBlank(customPackage)) {
      getLog().debug("Adding custom-package : " + customPackage);
      commands.add("--custom-package");
      commands.add(customPackage);
    }

    if (AAR.equals(project.getArtifact().getType())) {
      getLog().debug("Adding non-constant-id");
      commands.add("--non-constant-id");
    }

    for (String aaptExtraArg : aaptExtraArgs) {
      getLog().debug("Adding aapt arg : " + aaptExtraArg);
      commands.add(aaptExtraArg);
    }

    if (StringUtils.isNotBlank(configurations)) {
      // Should be comma separated list of locales etc.
      getLog().debug("Adding resource configurations : " + configurations);
      commands.add("-c");
      commands.add(configurations);
    }

    if (aaptVerbose) {
      commands.add("-v");
    }

    // We need to generate R.txt for all projects as it needs to be consumed when generating R
    // class.
    // It also needs to be consumed when packaging aar.
    commands.add("--output-text-symbols");
    commands.add(targetDirectory.getAbsolutePath());

    // Allows us to supply multiple -S arguments.
    commands.add("--auto-add-overlay");

    getLog().debug(getAndroidSdk().getAaptPath() + " " + commands.toString());
    try {
      targetDirectory.mkdirs();
      executor.setCaptureStdOut(true);
      executor.executeCommand(getAndroidSdk().getAaptPath(), commands, project.getBasedir(), false);
    } catch (ExecutionException e) {
      throw new MojoExecutionException("", e);
    }

    ResourceClassGenerator resourceGenerator =
        new ResourceClassGenerator(this, targetDirectory, genDirectory);

    generateCorrectRJavaForApklibDependencies(resourceGenerator);
    generateCorrectRJavaForAarDependencies(resourceGenerator);

    getLog().info("Adding R gen folder to compile classpath: " + genDirectory);
    project.addCompileSourceRoot(genDirectory.getAbsolutePath());
  }
Ejemplo n.º 2
0
  private void processNativeLibraries(final List<File> natives, String ndkArchitecture)
      throws MojoExecutionException {
    // Examine the native libraries directory for content. This will only be true if:
    // a) the directory exists
    // b) it contains at least 1 file
    final boolean hasValidNativeLibrariesDirectory = hasValidNativeLibrariesDirectory();
    final boolean hasValidBuildNativeLibrariesDirectory = hasValidBuildNativeLibrariesDirectory();
    final Set<Artifact> artifacts = getNativeLibraryArtifacts();

    if (artifacts.isEmpty()
        && hasValidNativeLibrariesDirectory
        && !hasValidBuildNativeLibrariesDirectory) {

      getLog()
          .debug(
              "No native library dependencies detected, will point directly to "
                  + nativeLibrariesDirectory);

      // Point directly to the directory in this case - no need to copy files around
      addNativeDirectory(natives, nativeLibrariesDirectory);

      // FIXME: This would pollute a libs folder which is under source control
      // FIXME: Would be better to not support this case?
      optionallyCopyGdbServer(nativeLibrariesDirectory, ndkArchitecture);

    } else {
      if (!artifacts.isEmpty() || hasValidNativeLibrariesDirectory) {
        // In this case, we may have both .so files in it's normal location
        // as well as .so dependencies

        final File destinationDirectory = makeNativeLibrariesOutputDirectory();

        // Point directly to the directory
        addNativeDirectory(natives, destinationDirectory);

        // If we have a valid native libs, copy those files - these already come in the structure
        // required
        if (hasValidNativeLibrariesDirectory) {
          copyLocalNativeLibraries(nativeLibrariesDirectory, destinationDirectory);
        }

        if (!artifacts.isEmpty()) {
          for (Artifact resolvedArtifact : artifacts) {
            if (NativeHelper.artifactHasHardwareArchitecture(
                resolvedArtifact,
                ndkArchitecture,
                nativeLibrariesDependenciesHardwareArchitectureDefault)) {
              copyNativeLibraryArtifactFileToDirectory(
                  resolvedArtifact, destinationDirectory, ndkArchitecture);
            } else if (APKLIB.equals(resolvedArtifact.getType())
                || AAR.equals(resolvedArtifact.getType())) {
              addNativeDirectory(natives, getUnpackedLibNativesFolder(resolvedArtifact));
            }
          }
        }

        // Finally, think about copying the gdbserver binary into the APK output as well
        optionallyCopyGdbServer(destinationDirectory, ndkArchitecture);
      }
    }
  }