use of org.jetbrains.jps.android.model.JpsAndroidModuleExtension in project android by JetBrains.
the class AndroidPackagingBuilder method doPackagingForModule.
private static boolean doPackagingForModule(@NotNull CompileContext context, @NotNull JpsModule module, @NotNull AndroidApkBuilderConfigStateStorage apkBuilderConfigStateStorage, @NotNull AndroidPackagingStateStorage packagingStateStorage, boolean release, boolean hasDirtyFiles, @NotNull BuildOutputConsumer outputConsumer) throws IOException {
final JpsAndroidModuleExtension extension = AndroidJpsUtil.getExtension(module);
if (extension == null || extension.isLibrary()) {
return true;
}
final String[] resourceRoots = AndroidJpsUtil.toPaths(AndroidJpsUtil.getJavaOutputRootsForModuleAndDependencies(module));
Arrays.sort(resourceRoots);
final File moduleOutputDir = ProjectPaths.getModuleOutputDir(module, false);
if (moduleOutputDir == null) {
context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, AndroidJpsBundle.message("android.jps.errors.output.dir.not.specified", module.getName())));
return false;
}
final AndroidPlatform platform = AndroidJpsUtil.getAndroidPlatform(module, context, BUILDER_NAME);
if (platform == null) {
return false;
}
final Set<String> externalJarsSet = new HashSet<String>();
for (String jarPath : AndroidJpsUtil.getExternalLibraries(context, module, platform)) {
if (new File(jarPath).exists()) {
externalJarsSet.add(jarPath);
}
}
final BuildDataPaths dataPaths = context.getProjectDescriptor().dataManager.getDataPaths();
final File resPackage = AndroidResourcePackagingBuildTarget.getOutputFile(dataPaths, module);
final File classesDexFile = AndroidDexBuildTarget.getOutputFile(dataPaths, module);
final String sdkPath = platform.getSdk().getHomePath();
final String outputPath = AndroidJpsUtil.getApkPath(extension, moduleOutputDir);
if (outputPath == null) {
context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, AndroidJpsBundle.message("android.jps.errors.cannot.compute.output.apk", module.getName())));
return false;
}
final String customKeyStorePath = FileUtil.toSystemDependentName(extension.getCustomDebugKeyStorePath());
final String[] nativeLibDirs = AndroidPackagingBuildTarget.collectNativeLibsFolders(extension, true);
final String resPackagePath = resPackage.getPath();
final String classesDexFilePath = classesDexFile.getPath();
final String[] externalJars = ArrayUtil.toStringArray(externalJarsSet);
Arrays.sort(externalJars);
final List<AndroidNativeLibData> additionalNativeLibs = extension.getAdditionalNativeLibs();
final AndroidApkBuilderConfigState currentApkBuilderConfigState = new AndroidApkBuilderConfigState(outputPath, customKeyStorePath, additionalNativeLibs);
if (!hasDirtyFiles) {
final AndroidApkBuilderConfigState savedApkBuilderConfigState = apkBuilderConfigStateStorage.getState(module.getName());
final AndroidPackagingStateStorage.MyState packagingState = packagingStateStorage.read();
if (currentApkBuilderConfigState.equalsTo(savedApkBuilderConfigState) && packagingState != null && packagingState.isRelease() == release) {
return true;
}
}
context.processMessage(new ProgressMessage(AndroidJpsBundle.message("android.jps.progress.packaging", AndroidJpsUtil.getApkName(module))));
final Map<AndroidCompilerMessageKind, List<String>> messages = AndroidApkBuilder.execute(resPackagePath, classesDexFilePath, resourceRoots, externalJars, nativeLibDirs, additionalNativeLibs, outputPath, release, sdkPath, platform.getTarget(), customKeyStorePath, new MyExcludedSourcesFilter(context.getProjectDescriptor().getProject()));
if (messages.get(AndroidCompilerMessageKind.ERROR).size() == 0) {
final List<String> srcFiles = new ArrayList<String>();
srcFiles.add(resPackagePath);
srcFiles.add(classesDexFilePath);
for (String resourceRoot : resourceRoots) {
FileUtil.processFilesRecursively(new File(resourceRoot), new Processor<File>() {
@Override
public boolean process(File file) {
if (file.isFile() && AndroidApkBuilder.checkFileForPackaging(file)) {
srcFiles.add(file.getPath());
}
return true;
}
});
}
Collections.addAll(srcFiles, externalJars);
for (String nativeLibDir : nativeLibDirs) {
FileUtil.processFilesRecursively(new File(nativeLibDir), new Processor<File>() {
@Override
public boolean process(File file) {
if (file.isFile()) {
srcFiles.add(file.getPath());
}
return true;
}
});
}
outputConsumer.registerOutputFile(new File(outputPath), srcFiles);
}
AndroidJpsUtil.addMessages(context, messages, BUILDER_NAME, module.getName());
final boolean success = messages.get(AndroidCompilerMessageKind.ERROR).isEmpty();
apkBuilderConfigStateStorage.update(module.getName(), success ? currentApkBuilderConfigState : null);
packagingStateStorage.saveState(new AndroidPackagingStateStorage.MyState(release));
return success;
}
use of org.jetbrains.jps.android.model.JpsAndroidModuleExtension in project android by JetBrains.
the class AndroidDexBuilder method doDexBuild.
private static boolean doDexBuild(@NotNull AndroidDexBuildTarget target, @NotNull CompileContext context, boolean hasDirtyFiles, @NotNull BuildOutputConsumer outputConsumer) throws IOException {
final JpsModule module = target.getModule();
final JpsAndroidModuleExtension extension = AndroidJpsUtil.getExtension(module);
assert extension != null;
assert !extension.isLibrary();
final AndroidPlatform platform = AndroidJpsUtil.getAndroidPlatform(module, context, DEX_BUILDER_NAME);
if (platform == null) {
return false;
}
File dexOutputDir = AndroidJpsUtil.getDirectoryForIntermediateArtifacts(context, module);
dexOutputDir = AndroidJpsUtil.createDirIfNotExist(dexOutputDir, context, DEX_BUILDER_NAME);
if (dexOutputDir == null) {
return false;
}
final ProGuardOptions proGuardOptions = AndroidJpsUtil.getProGuardConfigIfShouldRun(context, extension);
if (proGuardOptions != null) {
if (proGuardOptions.getCfgFiles() == null) {
context.processMessage(new CompilerMessage(DEX_BUILDER_NAME, BuildMessage.Kind.ERROR, AndroidJpsBundle.message("android.jps.errors.cannot.find.proguard.cfg", module.getName())));
return false;
}
}
final File proguardCfgOutputFile = new File(dexOutputDir, AndroidCommonUtils.PROGUARD_CFG_OUTPUT_FILE_NAME);
final AndroidProGuardStateStorage proGuardOptionsStorage = context.getProjectDescriptor().dataManager.getStorage(target, AndroidProGuardOptionsStorageProvider.INSTANCE);
final AndroidProGuardStateStorage.MyState oldProGuardState = proGuardOptionsStorage.read();
final Set<String> fileSet;
AndroidProGuardStateStorage.MyState newProGuardState = null;
try {
if (proGuardOptions != null) {
final List<String> proguardCfgFilePathsList = new ArrayList<String>();
for (File file : proGuardOptions.getCfgFiles()) {
proguardCfgFilePathsList.add(file.getAbsolutePath());
}
proguardCfgFilePathsList.add(proguardCfgOutputFile.getPath());
final String[] proguardCfgFilePaths = ArrayUtil.toStringArray(proguardCfgFilePathsList);
final String outputJarPath = FileUtil.toSystemDependentName(dexOutputDir.getPath() + '/' + AndroidCommonUtils.PROGUARD_OUTPUT_JAR_NAME);
final Pair<Boolean, AndroidProGuardStateStorage.MyState> pair = runProguardIfNecessary(extension, target, platform, context, outputJarPath, proguardCfgFilePaths, hasDirtyFiles, oldProGuardState);
if (pair == null) {
// error reported
return false;
}
if (!pair.getFirst()) {
// nothing changed
return true;
}
newProGuardState = pair.getSecond();
assert newProGuardState != null;
fileSet = Collections.singleton(outputJarPath);
} else {
if (!hasDirtyFiles && oldProGuardState == null) {
return true;
}
final List<BuildRootDescriptor> roots = context.getProjectDescriptor().getBuildRootIndex().getTargetRoots(target, context);
fileSet = new HashSet<String>();
final boolean predexingEnabled = extension.isPreDexingEnabled() && isPredexingInScope(context);
for (BuildRootDescriptor root : roots) {
final File rootFile = root.getRootFile();
if (!rootFile.exists()) {
continue;
}
if (root instanceof AndroidDexBuildTarget.MyClassesDirBuildRootDescriptor) {
final AndroidDexBuildTarget.ClassesDirType type = ((AndroidDexBuildTarget.MyClassesDirBuildRootDescriptor) root).getClassesDirType();
if (type == AndroidDexBuildTarget.ClassesDirType.JAVA) {
fileSet.add(rootFile.getPath());
} else if (type == AndroidDexBuildTarget.ClassesDirType.ANDROID_APP) {
AndroidJpsUtil.addSubdirectories(rootFile, fileSet);
}
} else if (root instanceof AndroidDexBuildTarget.MyJarBuildRootDescriptor) {
if (((AndroidDexBuildTarget.MyJarBuildRootDescriptor) root).isPreDexed() == predexingEnabled) {
fileSet.add(rootFile.getPath());
}
}
}
}
final boolean success;
if (fileSet.size() > 0) {
final String[] files = new String[fileSet.size()];
int i = 0;
for (String filePath : fileSet) {
files[i++] = FileUtil.toSystemDependentName(filePath);
}
context.processMessage(new ProgressMessage(AndroidJpsBundle.message("android.jps.progress.dex", module.getName())));
Arrays.sort(files);
success = runDex(platform, dexOutputDir.getPath(), files, context, module, outputConsumer);
} else {
success = true;
}
if (success) {
proGuardOptionsStorage.update(newProGuardState);
}
return success;
} catch (IOException e) {
AndroidJpsUtil.reportExceptionError(context, null, e, DEX_BUILDER_NAME);
return false;
}
}
use of org.jetbrains.jps.android.model.JpsAndroidModuleExtension in project android by JetBrains.
the class AndroidManifestMergingBuilder method doManifestMerging.
private static boolean doManifestMerging(AndroidManifestMergingTarget target, CompileContext context, BuildOutputConsumer outputConsumer) throws IOException {
final JpsModule module = target.getModule();
final JpsAndroidModuleExtension extension = AndroidJpsUtil.getExtension(module);
assert extension != null;
assert !extension.isLibrary();
assert extension.isManifestMergingEnabled();
final File outputDir = target.getOutputDirectory(context);
if (!outputDir.exists() && !outputDir.mkdirs()) {
context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, AndroidJpsBundle.message("android.jps.cannot.create.directory", outputDir.getPath())));
return false;
}
File manifestFile = null;
final List<File> libManifests = new ArrayList<File>();
final List<AndroidManifestMergingTarget.MyRootDescriptor> roots = context.getProjectDescriptor().getBuildRootIndex().getTargetRoots(target, context);
for (AndroidManifestMergingTarget.MyRootDescriptor root : roots) {
if (root.isLibManifestRoot()) {
libManifests.add(root.getRootFile());
} else {
manifestFile = root.getRootFile();
}
}
if (manifestFile == null) {
context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, AndroidJpsBundle.message("android.jps.errors.manifest.not.found", module.getName())));
return false;
}
final File outputFile = new File(outputDir, SdkConstants.FN_ANDROID_MANIFEST_XML);
if (!doMergeManifests(context, manifestFile, libManifests, outputFile)) {
context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, "[" + module.getName() + "] Cannot perform manifest merging"));
return false;
}
final List<String> srcPaths = new ArrayList<String>();
srcPaths.add(manifestFile.getPath());
for (File libManifest : libManifests) {
srcPaths.add(libManifest.getPath());
}
outputConsumer.registerOutputFile(outputFile, srcPaths);
return true;
}
use of org.jetbrains.jps.android.model.JpsAndroidModuleExtension in project android by JetBrains.
the class AndroidDexBuildTarget method doComputeRootDescriptors.
@NotNull
@Override
protected List<BuildRootDescriptor> doComputeRootDescriptors(JpsModel model, ModuleExcludeIndex index, IgnoredFileIndex ignoredFileIndex, BuildDataPaths dataPaths) {
final JpsAndroidModuleExtension extension = AndroidJpsUtil.getExtension(myModule);
assert extension != null;
if (extension.isLibrary()) {
return Collections.emptyList();
}
final Map<String, String> libPackage2ModuleName = new THashMap<String, String>(FileUtil.PATH_HASHING_STRATEGY);
final Set<String> appClassesDirs = new THashSet<String>(FileUtil.PATH_HASHING_STRATEGY);
final Set<String> javaClassesDirs = new THashSet<String>(FileUtil.PATH_HASHING_STRATEGY);
final Set<String> libClassesDirs = new THashSet<String>(FileUtil.PATH_HASHING_STRATEGY);
final File moduleClassesDir = new ModuleBuildTarget(myModule, JavaModuleBuildTargetType.PRODUCTION).getOutputDir();
if (moduleClassesDir != null) {
appClassesDirs.add(moduleClassesDir.getPath());
}
AndroidJpsUtil.processClasspath(dataPaths, myModule, new AndroidDependencyProcessor() {
@Override
public void processAndroidLibraryPackage(@NotNull File file, @NotNull JpsModule depModule) {
libPackage2ModuleName.put(file.getPath(), depModule.getName());
}
@Override
public void processAndroidLibraryOutputDirectory(@NotNull File dir) {
libClassesDirs.add(dir.getPath());
}
@Override
public void processJavaModuleOutputDirectory(@NotNull File dir) {
javaClassesDirs.add(dir.getPath());
}
@Override
public boolean isToProcess(@NotNull AndroidDependencyType type) {
return type == AndroidDependencyType.ANDROID_LIBRARY_PACKAGE || type == AndroidDependencyType.ANDROID_LIBRARY_OUTPUT_DIRECTORY || type == AndroidDependencyType.JAVA_MODULE_OUTPUT_DIR;
}
}, false, false);
if (extension.isPackTestCode()) {
final File testModuleClassesDir = new ModuleBuildTarget(myModule, JavaModuleBuildTargetType.TEST).getOutputDir();
if (testModuleClassesDir != null) {
appClassesDirs.add(testModuleClassesDir.getPath());
}
}
final List<BuildRootDescriptor> result = new ArrayList<BuildRootDescriptor>();
for (String classesDir : appClassesDirs) {
result.add(new MyClassesDirBuildRootDescriptor(this, new File(classesDir), ClassesDirType.ANDROID_APP));
}
for (String classesDir : libClassesDirs) {
result.add(new MyClassesDirBuildRootDescriptor(this, new File(classesDir), ClassesDirType.ANDROID_LIB));
}
for (String classesDir : javaClassesDirs) {
result.add(new MyClassesDirBuildRootDescriptor(this, new File(classesDir), ClassesDirType.JAVA));
}
final File preDexOutputDir = AndroidPreDexBuildTarget.getOutputDir(dataPaths);
for (Map.Entry<String, String> entry : libPackage2ModuleName.entrySet()) {
final String libPackage = entry.getKey();
final String moduleName = entry.getValue();
final File libPackageJarFile = new File(libPackage);
assert AndroidPreDexBuilder.canBePreDexed(libPackageJarFile);
result.add(new MyJarBuildRootDescriptor(this, libPackageJarFile, true, false));
result.add(new MyJarBuildRootDescriptor(this, new File(new File(preDexOutputDir, moduleName), libPackageJarFile.getName()), true, true));
}
final AndroidPlatform platform = AndroidJpsUtil.getAndroidPlatform(myModule, null, null);
if (platform != null) {
for (String jarOrLibDir : AndroidJpsUtil.getExternalLibraries(dataPaths, myModule, platform, false, false, true)) {
File file = new File(jarOrLibDir);
File preDexedFile = file;
if (AndroidPreDexBuilder.canBePreDexed(file)) {
final String preDexedFileName = AndroidPreDexBuilder.getOutputFileNameForExternalJar(file);
if (preDexedFileName != null) {
preDexedFile = new File(preDexOutputDir, preDexedFileName);
}
}
result.add(new MyJarBuildRootDescriptor(this, file, false, false));
result.add(new MyJarBuildRootDescriptor(this, preDexedFile, false, true));
}
}
for (String path : AndroidJpsUtil.getProvidedLibraries(dataPaths, myModule)) {
result.add(new MyProvidedJarBuildRootDescriptor(this, new File(path)));
}
return result;
}
use of org.jetbrains.jps.android.model.JpsAndroidModuleExtension in project android by JetBrains.
the class AndroidPackagingBuildTarget method doComputeRootDescriptors.
@NotNull
@Override
protected List<BuildRootDescriptor> doComputeRootDescriptors(JpsModel model, ModuleExcludeIndex index, IgnoredFileIndex ignoredFileIndex, BuildDataPaths dataPaths) {
final File resPackage = AndroidResourcePackagingBuildTarget.getOutputFile(dataPaths, myModule);
final File classesDexFile = AndroidDexBuildTarget.getOutputFile(dataPaths, myModule);
final List<BuildRootDescriptor> roots = new ArrayList<BuildRootDescriptor>();
roots.add(new BuildRootDescriptorImpl(this, resPackage));
roots.add(new BuildRootDescriptorImpl(this, classesDexFile));
final AndroidPlatform platform = AndroidJpsUtil.getAndroidPlatform(myModule, null, null);
if (platform != null) {
for (String jarOrLibDir : AndroidJpsUtil.getExternalLibraries(dataPaths, myModule, platform, false, true, false)) {
roots.add(new BuildRootDescriptorImpl(this, new File(jarOrLibDir), false));
}
}
for (File resourceRoot : AndroidJpsUtil.getJavaOutputRootsForModuleAndDependencies(myModule)) {
roots.add(new MyResourceRootDescriptor(this, resourceRoot));
}
final JpsAndroidModuleExtension extension = AndroidJpsUtil.getExtension(myModule);
assert extension != null;
for (String nativeLibDir : collectNativeLibsFolders(extension, false)) {
roots.add(new BuildRootDescriptorImpl(this, new File(nativeLibDir)));
}
return roots;
}
Aggregations