Search in sources :

Example 1 with AndroidDexBuildTarget

use of org.jetbrains.jps.android.builder.AndroidDexBuildTarget in project android by JetBrains.

the class AndroidDexBuilder method runProguardIfNecessary.

private static Pair<Boolean, AndroidProGuardStateStorage.MyState> runProguardIfNecessary(@NotNull JpsAndroidModuleExtension extension, @NotNull AndroidDexBuildTarget target, @NotNull AndroidPlatform platform, @NotNull CompileContext context, @NotNull String outputJarPath, @NotNull String[] proguardCfgPaths, boolean hasDirtyFiles, @Nullable AndroidProGuardStateStorage.MyState oldState) throws IOException {
    final JpsModule module = extension.getModule();
    final File[] proguardCfgFiles = new File[proguardCfgPaths.length];
    for (int i = 0; i < proguardCfgFiles.length; i++) {
        proguardCfgFiles[i] = new File(proguardCfgPaths[i]);
        if (!proguardCfgFiles[i].exists()) {
            context.processMessage(new CompilerMessage(PRO_GUARD_BUILDER_NAME, BuildMessage.Kind.ERROR, AndroidJpsBundle.message("android.jps.cannot.find.file", proguardCfgPaths[i])));
            return null;
        }
    }
    final File mainContentRoot = AndroidJpsUtil.getMainContentRoot(extension);
    if (mainContentRoot == null) {
        context.processMessage(new CompilerMessage(PRO_GUARD_BUILDER_NAME, BuildMessage.Kind.ERROR, AndroidJpsBundle.message("android.jps.errors.main.content.root.not.found", module.getName())));
        return null;
    }
    final String javaExecutable = getJavaExecutable(platform, context, PRO_GUARD_BUILDER_NAME);
    if (javaExecutable == null) {
        return null;
    }
    final File proguardLogsDir = extension.getProguardLogsDir();
    final File logsDir;
    if (proguardLogsDir != null) {
        logsDir = proguardLogsDir;
    } else {
        logsDir = new File(mainContentRoot.getPath() + '/' + AndroidCommonUtils.DIRECTORY_FOR_LOGS_NAME);
    }
    final AndroidProGuardStateStorage.MyState newState = new AndroidProGuardStateStorage.MyState(proguardCfgFiles);
    if (!hasDirtyFiles && newState.equals(oldState)) {
        return Pair.create(false, null);
    }
    final List<String> classesDirs = new ArrayList<String>();
    final List<String> libClassesDirs = new ArrayList<String>();
    final List<String> externalJars = new ArrayList<String>();
    final List<String> providedJars = new ArrayList<String>();
    final List<BuildRootDescriptor> roots = context.getProjectDescriptor().getBuildRootIndex().getTargetRoots(target, 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 || type == AndroidDexBuildTarget.ClassesDirType.ANDROID_APP) {
                AndroidJpsUtil.addSubdirectories(rootFile, classesDirs);
            } else {
                AndroidJpsUtil.addSubdirectories(rootFile, libClassesDirs);
            }
        } else if (root instanceof AndroidDexBuildTarget.MyJarBuildRootDescriptor) {
            final AndroidDexBuildTarget.MyJarBuildRootDescriptor jarRoot = (AndroidDexBuildTarget.MyJarBuildRootDescriptor) root;
            if (!jarRoot.isLibPackage() && !jarRoot.isPreDexed()) {
                externalJars.add(rootFile.getPath());
            }
        } else if (root instanceof AndroidDexBuildTarget.MyProvidedJarBuildRootDescriptor) {
            providedJars.add(rootFile.getPath());
        }
    }
    final String[] classFilesDirOsPaths = ArrayUtil.toStringArray(classesDirs);
    final String[] libClassFilesDirOsPaths = ArrayUtil.toStringArray(libClassesDirs);
    final String[] externalJarOsPaths = ArrayUtil.toStringArray(externalJars);
    final String[] providedJarOsPaths = ArrayUtil.toStringArray(providedJars);
    final String inputJarOsPath = AndroidCommonUtils.buildTempInputJar(classFilesDirOsPaths, libClassFilesDirOsPaths);
    final AndroidBuildTestingManager testingManager = AndroidBuildTestingManager.getTestingManager();
    if (testingManager != null) {
        testingManager.getCommandExecutor().checkJarContent("proguard_input_jar", inputJarOsPath);
    }
    if (!logsDir.exists()) {
        if (!logsDir.mkdirs()) {
            context.processMessage(new CompilerMessage(PRO_GUARD_BUILDER_NAME, BuildMessage.Kind.ERROR, AndroidJpsBundle.message("android.jps.cannot.create.directory", FileUtil.toSystemDependentName(logsDir.getPath()))));
            return null;
        }
    }
    final JpsAndroidDexCompilerConfiguration configuration = JpsAndroidExtensionService.getInstance().getDexCompilerConfiguration(module.getProject());
    String proguardVmOptions = configuration != null ? configuration.getProguardVmOptions() : null;
    if (proguardVmOptions == null) {
        proguardVmOptions = "";
    }
    context.processMessage(new ProgressMessage(AndroidJpsBundle.message("android.jps.progress.proguard", module.getName())));
    final Map<AndroidCompilerMessageKind, List<String>> messages = AndroidCommonUtils.launchProguard(platform.getTarget(), platform.getSdkToolsRevision(), platform.getSdk().getHomePath(), javaExecutable, proguardVmOptions, proguardCfgPaths, inputJarOsPath, externalJarOsPaths, providedJarOsPaths, outputJarPath, logsDir.getPath());
    AndroidJpsUtil.addMessages(context, messages, PRO_GUARD_BUILDER_NAME, module.getName());
    return messages.get(AndroidCompilerMessageKind.ERROR).isEmpty() ? Pair.create(true, newState) : null;
}
Also used : ProgressMessage(org.jetbrains.jps.incremental.messages.ProgressMessage) CompilerMessage(org.jetbrains.jps.incremental.messages.CompilerMessage) AndroidCompilerMessageKind(org.jetbrains.android.util.AndroidCompilerMessageKind) JpsAndroidDexCompilerConfiguration(org.jetbrains.jps.android.model.JpsAndroidDexCompilerConfiguration) AndroidDexBuildTarget(org.jetbrains.jps.android.builder.AndroidDexBuildTarget) BuildRootDescriptor(org.jetbrains.jps.builders.BuildRootDescriptor) AndroidBuildTestingManager(org.jetbrains.android.util.AndroidBuildTestingManager) JpsModule(org.jetbrains.jps.model.module.JpsModule) File(java.io.File)

Example 2 with AndroidDexBuildTarget

use of org.jetbrains.jps.android.builder.AndroidDexBuildTarget 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;
    }
}
Also used : ProgressMessage(org.jetbrains.jps.incremental.messages.ProgressMessage) CompilerMessage(org.jetbrains.jps.incremental.messages.CompilerMessage) AndroidDexBuildTarget(org.jetbrains.jps.android.builder.AndroidDexBuildTarget) BuildRootDescriptor(org.jetbrains.jps.builders.BuildRootDescriptor) IOException(java.io.IOException) JpsModule(org.jetbrains.jps.model.module.JpsModule) JpsAndroidModuleExtension(org.jetbrains.jps.android.model.JpsAndroidModuleExtension) File(java.io.File)

Aggregations

File (java.io.File)2 AndroidDexBuildTarget (org.jetbrains.jps.android.builder.AndroidDexBuildTarget)2 BuildRootDescriptor (org.jetbrains.jps.builders.BuildRootDescriptor)2 CompilerMessage (org.jetbrains.jps.incremental.messages.CompilerMessage)2 ProgressMessage (org.jetbrains.jps.incremental.messages.ProgressMessage)2 JpsModule (org.jetbrains.jps.model.module.JpsModule)2 IOException (java.io.IOException)1 AndroidBuildTestingManager (org.jetbrains.android.util.AndroidBuildTestingManager)1 AndroidCompilerMessageKind (org.jetbrains.android.util.AndroidCompilerMessageKind)1 JpsAndroidDexCompilerConfiguration (org.jetbrains.jps.android.model.JpsAndroidDexCompilerConfiguration)1 JpsAndroidModuleExtension (org.jetbrains.jps.android.model.JpsAndroidModuleExtension)1