Search in sources :

Example 1 with AndroidCompilerMessageKind

use of org.jetbrains.android.util.AndroidCompilerMessageKind in project android by JetBrains.

the class AndroidApt method doCompile.

private static Map<AndroidCompilerMessageKind, List<String>> doCompile(@NotNull IAndroidTarget target, @NotNull String manifestFileOsPath, @NotNull String outDirOsPath, @NotNull String[] resourceDirsOsPaths, @NotNull List<Pair<String, String>> libRTxtFilesAndPackages, @Nullable String customPackage, boolean nonConstantIds, @Nullable String proguardCfgOutputFileOsPath, @Nullable String rTxtOutDirOsPath, boolean optimizeRFile) throws IOException {
    final List<String> args = new ArrayList<String>();
    BuildToolInfo buildToolInfo = target.getBuildToolInfo();
    if (buildToolInfo == null) {
        return Collections.singletonMap(AndroidCompilerMessageKind.ERROR, Collections.singletonList("No Build Tools in the Android SDK."));
    }
    args.add(buildToolInfo.getPath(BuildToolInfo.PathId.AAPT));
    args.add("package");
    args.add("-m");
    if (nonConstantIds) {
        args.add("--non-constant-id");
    }
    if (resourceDirsOsPaths.length > 1) {
        args.add("--auto-add-overlay");
    }
    final Set<String> extraPackages = new HashSet<String>();
    for (Pair<String, String> pair : libRTxtFilesAndPackages) {
        extraPackages.add(pair.getSecond());
    }
    if (extraPackages.size() > 0) {
        args.add("--extra-packages");
        args.add(toPackagesString(ArrayUtil.toStringArray(extraPackages)));
    }
    if (customPackage != null) {
        args.add("--custom-package");
        args.add(customPackage);
    }
    if (rTxtOutDirOsPath != null) {
        args.add("--output-text-symbols");
        args.add(rTxtOutDirOsPath);
    }
    args.add("-J");
    args.add(outDirOsPath);
    args.add("-M");
    args.add(manifestFileOsPath);
    for (String libResFolderOsPath : resourceDirsOsPaths) {
        args.add("-S");
        args.add(libResFolderOsPath);
    }
    args.add("-I");
    args.add(target.getPath(IAndroidTarget.ANDROID_JAR));
    if (proguardCfgOutputFileOsPath != null) {
        args.add("-G");
        args.add(proguardCfgOutputFileOsPath);
    }
    final Map<AndroidCompilerMessageKind, List<String>> messages = AndroidExecutionUtil.doExecute(ArrayUtil.toStringArray(args));
    LOG.info(AndroidCommonUtils.command2string(args));
    if (messages.get(AndroidCompilerMessageKind.ERROR).size() > 0) {
        return messages;
    }
    if (optimizeRFile && !libRTxtFilesAndPackages.isEmpty() && rTxtOutDirOsPath != null) {
        final File rFile = new File(rTxtOutDirOsPath, SdkConstants.FN_RESOURCE_TEXT);
        // if the project has no resources the file could not exist.
        if (rFile.isFile()) {
            final SymbolLoader fullSymbolValues = new SymbolLoader(rFile);
            fullSymbolValues.load();
            final MultiMap<String, SymbolLoader> libMap = new MultiMap<String, SymbolLoader>();
            for (Pair<String, String> pair : libRTxtFilesAndPackages) {
                final File rTextFile = new File(pair.getFirst());
                final String libPackage = pair.getSecond();
                if (rTextFile.isFile()) {
                    final SymbolLoader libSymbols = new SymbolLoader(rTextFile);
                    libSymbols.load();
                    libMap.putValue(libPackage, libSymbols);
                }
            }
            for (Map.Entry<String, Collection<SymbolLoader>> entry : libMap.entrySet()) {
                final String libPackage = entry.getKey();
                final Collection<SymbolLoader> symbols = entry.getValue();
                final SymbolWriter writer = new SymbolWriter(outDirOsPath, libPackage, fullSymbolValues);
                for (SymbolLoader symbolLoader : symbols) {
                    writer.addSymbolsToWrite(symbolLoader);
                }
                writer.write();
            }
        }
    }
    return messages;
}
Also used : BuildToolInfo(com.android.sdklib.BuildToolInfo) AndroidCompilerMessageKind(org.jetbrains.android.util.AndroidCompilerMessageKind) SymbolLoader(com.android.sdklib.internal.build.SymbolLoader) MultiMap(com.intellij.util.containers.MultiMap) SymbolWriter(com.android.sdklib.internal.build.SymbolWriter) File(java.io.File) HashMap(com.intellij.util.containers.HashMap) MultiMap(com.intellij.util.containers.MultiMap) HashSet(com.intellij.util.containers.HashSet)

Example 2 with AndroidCompilerMessageKind

use of org.jetbrains.android.util.AndroidCompilerMessageKind in project android by JetBrains.

the class AndroidApkBuilder method execute.

public static Map<AndroidCompilerMessageKind, List<String>> execute(@NotNull String resPackagePath, @NotNull String dexPath, @NotNull String[] resourceRoots, @NotNull String[] externalJars, @NotNull String[] nativeLibsFolders, @NotNull Collection<AndroidNativeLibData> additionalNativeLibs, @NotNull String finalApk, boolean unsigned, @NotNull String sdkPath, @NotNull IAndroidTarget target, @Nullable String customKeystorePath, @NotNull Condition<File> resourceFilter) throws IOException {
    final AndroidBuildTestingManager testingManager = AndroidBuildTestingManager.getTestingManager();
    if (testingManager != null) {
        testingManager.getCommandExecutor().log(StringUtil.join(new String[] { "apk_builder", resPackagePath, dexPath, AndroidBuildTestingManager.arrayToString(resourceRoots), AndroidBuildTestingManager.arrayToString(externalJars), AndroidBuildTestingManager.arrayToString(nativeLibsFolders), additionalNativeLibs.toString(), finalApk, Boolean.toString(unsigned), sdkPath, customKeystorePath }, "\n"));
    }
    final Map<AndroidCompilerMessageKind, List<String>> map = new HashMap<AndroidCompilerMessageKind, List<String>>();
    map.put(ERROR, new ArrayList<String>());
    map.put(WARNING, new ArrayList<String>());
    final File outputDir = new File(finalApk).getParentFile();
    if (!outputDir.exists() && !outputDir.mkdirs()) {
        map.get(ERROR).add("Cannot create directory " + outputDir.getPath());
        return map;
    }
    File additionalLibsDir = null;
    try {
        if (additionalNativeLibs.size() > 0) {
            additionalLibsDir = FileUtil.createTempDirectory("android_additional_libs", "tmp");
            if (!copyNativeLibs(additionalNativeLibs, additionalLibsDir, map)) {
                return map;
            }
            nativeLibsFolders = ArrayUtil.append(nativeLibsFolders, additionalLibsDir.getPath());
        }
        if (unsigned) {
            return filterUsingKeystoreMessages(finalPackage(dexPath, resourceRoots, externalJars, nativeLibsFolders, finalApk, resPackagePath, customKeystorePath, false, resourceFilter));
        }
        final String zipAlignPath = AndroidCommonUtils.getZipAlign(sdkPath, target);
        boolean withAlignment = new File(zipAlignPath).exists();
        String unalignedApk = AndroidCommonUtils.addSuffixToFileName(finalApk, UNALIGNED_SUFFIX);
        Map<AndroidCompilerMessageKind, List<String>> map2 = filterUsingKeystoreMessages(finalPackage(dexPath, resourceRoots, externalJars, nativeLibsFolders, withAlignment ? unalignedApk : finalApk, resPackagePath, customKeystorePath, true, resourceFilter));
        map.putAll(map2);
        if (withAlignment && map.get(ERROR).size() == 0) {
            map2 = AndroidExecutionUtil.doExecute(zipAlignPath, "-f", "4", unalignedApk, finalApk);
            map.putAll(map2);
        }
        return map;
    } finally {
        if (additionalLibsDir != null) {
            FileUtil.delete(additionalLibsDir);
        }
    }
}
Also used : HashMap(com.intellij.util.containers.HashMap) AndroidCompilerMessageKind(org.jetbrains.android.util.AndroidCompilerMessageKind) File(java.io.File)

Example 3 with AndroidCompilerMessageKind

use of org.jetbrains.android.util.AndroidCompilerMessageKind in project android by JetBrains.

the class AndroidDexBuilder method runDex.

public static boolean runDex(@NotNull AndroidPlatform platform, @NotNull String outFilePath, @NotNull String[] compileTargets, @NotNull CompileContext context, @NotNull JpsProject project, @NotNull BuildOutputConsumer outputConsumer, @NotNull String builderName, @NotNull String srcTargetName, @Nullable JpsModule module) throws IOException {
    BuildToolInfo buildToolInfo = platform.getTarget().getBuildToolInfo();
    if (buildToolInfo == null) {
        return false;
    }
    final String dxJarPath = FileUtil.toSystemDependentName(buildToolInfo.getPath(BuildToolInfo.PathId.DX_JAR));
    final AndroidBuildTestingManager testingManager = AndroidBuildTestingManager.getTestingManager();
    final File dxJar = new File(dxJarPath);
    if (testingManager == null && !dxJar.isFile()) {
        context.processMessage(new CompilerMessage(builderName, BuildMessage.Kind.ERROR, AndroidJpsBundle.message("android.jps.cannot.find.file", dxJarPath)));
        return false;
    }
    boolean multiDex = false;
    if (module != null) {
        JpsAndroidModuleExtension extension = AndroidJpsUtil.getExtension(module);
        if (extension != null && extension.isMultiDexEnabled()) {
            outFilePath = new File(outFilePath).getParent();
            multiDex = true;
        }
    }
    final List<String> programParamList = new ArrayList<String>();
    programParamList.add(dxJarPath);
    programParamList.add(outFilePath);
    final JpsAndroidDexCompilerConfiguration configuration = JpsAndroidExtensionService.getInstance().getDexCompilerConfiguration(project);
    final List<String> vmOptions;
    if (configuration != null) {
        vmOptions = new ArrayList<String>();
        vmOptions.addAll(ParametersListUtil.parse(configuration.getVmOptions()));
        if (!AndroidCommonUtils.hasXmxParam(vmOptions)) {
            vmOptions.add("-Xmx" + configuration.getMaxHeapSize() + "M");
        }
        programParamList.addAll(Arrays.asList("--optimize", Boolean.toString(configuration.isOptimize())));
        if (configuration.isForceJumbo()) {
            programParamList.addAll(Arrays.asList("--forceJumbo", Boolean.TRUE.toString()));
        }
        if (configuration.isCoreLibrary()) {
            programParamList.add("--coreLibrary");
        }
    } else {
        vmOptions = Collections.singletonList("-Xmx1024M");
    }
    if (multiDex) {
        JpsAndroidModuleExtension extension = AndroidJpsUtil.getExtension(module);
        if (extension != null) {
            programParamList.add("--multi-dex");
            if (!StringUtil.isEmpty(extension.getMainDexList())) {
                programParamList.add("--main-dex-list");
                programParamList.add(extension.getMainDexList());
            }
            if (extension.isMinimalMainDex()) {
                programParamList.add("--minimal-main-dex");
            }
        }
    }
    programParamList.addAll(Arrays.asList(compileTargets));
    programParamList.add("--exclude");
    final List<String> classPath = new ArrayList<String>();
    classPath.add(ClasspathBootstrap.getResourcePath(AndroidDxRunner.class));
    classPath.add(ClasspathBootstrap.getResourcePath(FileUtilRt.class));
    final File outFile = new File(outFilePath);
    if (outFile.exists() && !outFile.isDirectory() && !outFile.delete()) {
        context.processMessage(new CompilerMessage(builderName, BuildMessage.Kind.WARNING, AndroidJpsBundle.message("android.jps.cannot.delete.file", outFilePath)));
    }
    final String javaExecutable = getJavaExecutable(platform, context, builderName);
    if (javaExecutable == null) {
        return false;
    }
    final List<String> commandLine = ExternalProcessUtil.buildJavaCommandLine(javaExecutable, AndroidDxRunner.class.getName(), Collections.<String>emptyList(), classPath, vmOptions, programParamList);
    LOG.info(AndroidCommonUtils.command2string(commandLine));
    final String[] commands = ArrayUtil.toStringArray(commandLine);
    final Process process;
    if (testingManager != null) {
        process = testingManager.getCommandExecutor().createProcess(commands, Collections.<String, String>emptyMap());
    } else {
        process = Runtime.getRuntime().exec(commands);
    }
    final HashMap<AndroidCompilerMessageKind, List<String>> messages = new HashMap<AndroidCompilerMessageKind, List<String>>(3);
    messages.put(AndroidCompilerMessageKind.ERROR, new ArrayList<String>());
    messages.put(AndroidCompilerMessageKind.WARNING, new ArrayList<String>());
    messages.put(AndroidCompilerMessageKind.INFORMATION, new ArrayList<String>());
    AndroidCommonUtils.handleDexCompilationResult(process, StringUtil.join(commandLine, " "), outFilePath, messages, multiDex);
    AndroidJpsUtil.addMessages(context, messages, builderName, srcTargetName);
    final boolean success = messages.get(AndroidCompilerMessageKind.ERROR).size() == 0;
    if (success) {
        final List<String> srcFiles = new ArrayList<String>();
        for (String compileTargetPath : compileTargets) {
            final File compileTarget = new File(compileTargetPath);
            if (compileTarget.isFile()) {
                srcFiles.add(compileTargetPath);
            } else if (compileTarget.isDirectory()) {
                AndroidJpsUtil.processClassFilesAndJarsRecursively(compileTarget, new Processor<File>() {

                    @Override
                    public boolean process(File file) {
                        if (file.isFile()) {
                            srcFiles.add(file.getPath());
                        }
                        return true;
                    }
                });
            }
        }
        outputConsumer.registerOutputFile(outFile, srcFiles);
    }
    return success;
}
Also used : AndroidBuildTestingManager(org.jetbrains.android.util.AndroidBuildTestingManager) CompilerMessage(org.jetbrains.jps.incremental.messages.CompilerMessage) Processor(com.intellij.util.Processor) BuildToolInfo(com.android.sdklib.BuildToolInfo) HashMap(com.intellij.util.containers.HashMap) AndroidCompilerMessageKind(org.jetbrains.android.util.AndroidCompilerMessageKind) AndroidDxRunner(org.jetbrains.android.compiler.tools.AndroidDxRunner) JpsAndroidDexCompilerConfiguration(org.jetbrains.jps.android.model.JpsAndroidDexCompilerConfiguration) JpsAndroidModuleExtension(org.jetbrains.jps.android.model.JpsAndroidModuleExtension) FileUtilRt(com.intellij.openapi.util.io.FileUtilRt) File(java.io.File)

Example 4 with AndroidCompilerMessageKind

use of org.jetbrains.android.util.AndroidCompilerMessageKind 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 5 with AndroidCompilerMessageKind

use of org.jetbrains.android.util.AndroidCompilerMessageKind in project android by JetBrains.

the class AndroidJpsUtil method addMessages.

public static void addMessages(@NotNull CompileContext context, @NotNull Map<AndroidCompilerMessageKind, List<String>> messages, @NotNull String builderName, @NotNull String entryName) {
    for (Map.Entry<AndroidCompilerMessageKind, List<String>> entry : messages.entrySet()) {
        for (String message : entry.getValue()) {
            String filePath = null;
            int line = -1;
            final Matcher matcher = AndroidCommonUtils.COMPILER_MESSAGE_PATTERN.matcher(message);
            if (matcher.matches()) {
                filePath = matcher.group(1);
                line = Integer.parseInt(matcher.group(2));
            }
            final BuildMessage.Kind category = toBuildMessageKind(entry.getKey());
            if (category != null) {
                context.processMessage(new CompilerMessage(builderName, category, '[' + entryName + "] " + message, filePath, -1L, -1L, -1L, line, -1L));
            }
        }
    }
}
Also used : BuildMessage(org.jetbrains.jps.incremental.messages.BuildMessage) CompilerMessage(org.jetbrains.jps.incremental.messages.CompilerMessage) Matcher(java.util.regex.Matcher) AndroidCompilerMessageKind(org.jetbrains.android.util.AndroidCompilerMessageKind)

Aggregations

AndroidCompilerMessageKind (org.jetbrains.android.util.AndroidCompilerMessageKind)12 File (java.io.File)10 HashMap (com.intellij.util.containers.HashMap)7 CompilerMessage (org.jetbrains.jps.incremental.messages.CompilerMessage)5 ArrayList (java.util.ArrayList)4 List (java.util.List)4 BuildToolInfo (com.android.sdklib.BuildToolInfo)3 HashSet (com.intellij.util.containers.HashSet)3 IOException (java.io.IOException)3 JpsAndroidModuleExtension (org.jetbrains.jps.android.model.JpsAndroidModuleExtension)3 FileUtilRt (com.intellij.openapi.util.io.FileUtilRt)2 AndroidBuildTestingManager (org.jetbrains.android.util.AndroidBuildTestingManager)2 JpsAndroidDexCompilerConfiguration (org.jetbrains.jps.android.model.JpsAndroidDexCompilerConfiguration)2 BuildRootDescriptor (org.jetbrains.jps.builders.BuildRootDescriptor)2 ProgressMessage (org.jetbrains.jps.incremental.messages.ProgressMessage)2 JpsModule (org.jetbrains.jps.model.module.JpsModule)2 DebugKeyProvider (com.android.jarutils.DebugKeyProvider)1 SignedJarBuilder (com.android.jarutils.SignedJarBuilder)1 AndroidLocation (com.android.prefs.AndroidLocation)1 IAndroidTarget (com.android.sdklib.IAndroidTarget)1