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()); }
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); } } }