use of org.jetbrains.jps.incremental.messages.CompilerMessage in project android by JetBrains.
the class AndroidSourceGeneratingBuilder method copyGeneratedSources.
@NotNull
private static MyExitStatus copyGeneratedSources(@NotNull Map<JpsModule, MyModuleData> moduleDataMap, @NotNull BuildDataManager dataManager, @NotNull final CompileContext context) throws IOException {
final Ref<Boolean> didSomething = Ref.create(false);
final Ref<Boolean> success = Ref.create(true);
for (Map.Entry<JpsModule, MyModuleData> entry : moduleDataMap.entrySet()) {
final JpsModule module = entry.getKey();
final MyModuleData data = entry.getValue();
if (!data.getAndroidExtension().isCopyCustomGeneratedSources()) {
continue;
}
final ModuleBuildTarget moduleTarget = new ModuleBuildTarget(module, JavaModuleBuildTargetType.PRODUCTION);
final AndroidGenSourcesCopyingStorage storage = context.getProjectDescriptor().dataManager.getStorage(moduleTarget, AndroidGenSourcesCopyingStorage.PROVIDER);
final Set<String> genDirs = AndroidJpsUtil.getGenDirs(data.getAndroidExtension());
final List<String> filteredGenDirs = filterExcludedByOtherProviders(module, genDirs);
final Set<String> forciblyExcludedDirs = new HashSet<String>(genDirs);
forciblyExcludedDirs.removeAll(filteredGenDirs);
warnUserAboutForciblyExcludedRoots(forciblyExcludedDirs, context);
final AndroidFileSetState savedState = storage.read();
final AndroidFileSetState currentState = new AndroidFileSetState(filteredGenDirs, new Condition<File>() {
@Override
public boolean value(File file) {
try {
return shouldBeCopied(file);
} catch (IOException e) {
return false;
}
}
}, true);
if (currentState.equalsTo(savedState)) {
continue;
}
final File outDir = AndroidJpsUtil.getCopiedSourcesStorage(module, dataManager.getDataPaths());
clearDirectoryIfNotEmpty(outDir, context, ANDROID_GENERATED_SOURCES_PROCESSOR);
final List<Pair<String, String>> copiedFiles = new ArrayList<Pair<String, String>>();
for (String path : filteredGenDirs) {
final File dir = new File(path);
if (dir.isDirectory()) {
FileUtil.processFilesRecursively(dir, new Processor<File>() {
@Override
public boolean process(File file) {
try {
if (!shouldBeCopied(file)) {
return true;
}
final String relPath = FileUtil.getRelativePath(dir, file);
final File dstFile = new File(outDir.getPath() + "/" + relPath);
final File dstDir = dstFile.getParentFile();
if (!dstDir.exists() && !dstDir.mkdirs()) {
context.processMessage(new CompilerMessage(ANDROID_GENERATED_SOURCES_PROCESSOR, BuildMessage.Kind.ERROR, AndroidJpsBundle.message("android.jps.cannot.create.directory", dstDir.getPath())));
return true;
}
FileUtil.copy(file, dstFile);
copiedFiles.add(Pair.create(file.getPath(), dstFile.getPath()));
didSomething.set(true);
} catch (IOException e) {
AndroidJpsUtil.reportExceptionError(context, null, e, ANDROID_GENERATED_SOURCES_PROCESSOR);
success.set(false);
return true;
}
return true;
}
});
}
}
final File generatedSourcesDir = AndroidJpsUtil.getGeneratedSourcesStorage(module, dataManager.getDataPaths());
final List<String> deletedFiles = new ArrayList<String>();
if (!removeCopiedFilesDuplicatingGeneratedFiles(context, outDir, generatedSourcesDir, deletedFiles)) {
success.set(false);
continue;
}
final AndroidBuildTestingManager testingManager = AndroidBuildTestingManager.getTestingManager();
if (testingManager != null) {
logGeneratedSourcesProcessing(testingManager, copiedFiles, deletedFiles);
}
markDirtyRecursively(outDir, context, ANDROID_GENERATED_SOURCES_PROCESSOR, false);
storage.saveState(currentState);
}
if (didSomething.get()) {
return success.get() ? MyExitStatus.OK : MyExitStatus.FAIL;
} else {
return MyExitStatus.NOTHING_CHANGED;
}
}
use of org.jetbrains.jps.incremental.messages.CompilerMessage in project android by JetBrains.
the class AndroidSourceGeneratingBuilder method runAidlCompiler.
private static boolean runAidlCompiler(@NotNull final CompileContext context, @NotNull Map<File, ModuleBuildTarget> files, @NotNull Map<JpsModule, MyModuleData> moduleDataMap) {
if (files.size() > 0) {
context.processMessage(new ProgressMessage(AndroidJpsBundle.message("android.jps.progress.aidl")));
}
boolean success = true;
for (Map.Entry<File, ModuleBuildTarget> entry : files.entrySet()) {
final File file = entry.getKey();
final ModuleBuildTarget buildTarget = entry.getValue();
final String filePath = file.getPath();
final MyModuleData moduleData = moduleDataMap.get(buildTarget.getModule());
if (!LOG.assertTrue(moduleData != null)) {
context.processMessage(new CompilerMessage(ANDROID_IDL_COMPILER, BuildMessage.Kind.ERROR, AndroidJpsBundle.message("android.jps.internal.error")));
success = false;
continue;
}
final File generatedSourcesDir = AndroidJpsUtil.getGeneratedSourcesStorage(buildTarget.getModule(), context.getProjectDescriptor().dataManager);
final File aidlOutputDirectory = new File(generatedSourcesDir, AndroidJpsUtil.AIDL_GENERATED_SOURCE_ROOT_NAME);
if (!aidlOutputDirectory.exists() && !aidlOutputDirectory.mkdirs()) {
context.processMessage(new CompilerMessage(ANDROID_IDL_COMPILER, BuildMessage.Kind.ERROR, AndroidJpsBundle.message("android.jps.cannot.create.directory", aidlOutputDirectory.getPath())));
success = false;
continue;
}
final IAndroidTarget target = moduleData.getPlatform().getTarget();
try {
final File[] sourceRoots = AndroidJpsUtil.getSourceRootsForModuleAndDependencies(buildTarget.getModule());
final String[] sourceRootPaths = AndroidJpsUtil.toPaths(sourceRoots);
final String packageName = computePackageForFile(context, file);
if (packageName == null) {
context.processMessage(new CompilerMessage(ANDROID_IDL_COMPILER, BuildMessage.Kind.ERROR, AndroidJpsBundle.message("android.jps.errors.cannot.compute.package", filePath)));
success = false;
continue;
}
final File outputFile = new File(aidlOutputDirectory, packageName.replace('.', File.separatorChar) + File.separator + FileUtil.getNameWithoutExtension(file) + ".java");
final String outputFilePath = outputFile.getPath();
final Map<AndroidCompilerMessageKind, List<String>> messages = AndroidIdl.execute(target, filePath, outputFilePath, sourceRootPaths);
addMessages(context, messages, filePath, ANDROID_IDL_COMPILER);
if (messages.get(AndroidCompilerMessageKind.ERROR).size() > 0) {
success = false;
} else if (outputFile.exists()) {
final SourceToOutputMapping sourceToOutputMap = context.getProjectDescriptor().dataManager.getSourceToOutputMap(buildTarget);
sourceToOutputMap.setOutput(filePath, outputFilePath);
FSOperations.markDirty(context, CompilationRound.CURRENT, outputFile);
}
} catch (final IOException e) {
AndroidJpsUtil.reportExceptionError(context, filePath, e, ANDROID_IDL_COMPILER);
success = false;
}
}
return success;
}
use of org.jetbrains.jps.incremental.messages.CompilerMessage in project android by JetBrains.
the class AndroidSourceGeneratingBuilder method runAaptCompiler.
private static MyExitStatus runAaptCompiler(@NotNull final CompileContext context, @NotNull Map<JpsModule, MyModuleData> moduleDataMap) throws IOException {
boolean success = true;
boolean didSomething = false;
for (Map.Entry<JpsModule, MyModuleData> entry : moduleDataMap.entrySet()) {
final JpsModule module = entry.getKey();
final ModuleBuildTarget moduleTarget = new ModuleBuildTarget(module, JavaModuleBuildTargetType.PRODUCTION);
final AndroidAptStateStorage storage = context.getProjectDescriptor().dataManager.getStorage(moduleTarget, AndroidAptStateStorage.PROVIDER);
final MyModuleData moduleData = entry.getValue();
final JpsAndroidModuleExtension extension = moduleData.getAndroidExtension();
final File generatedSourcesDir = AndroidJpsUtil.getGeneratedSourcesStorage(module, context.getProjectDescriptor().dataManager);
final File aptOutputDirectory = new File(generatedSourcesDir, AndroidJpsUtil.AAPT_GENERATED_SOURCE_ROOT_NAME);
final IAndroidTarget target = moduleData.getPlatform().getTarget();
try {
final String[] resPaths = AndroidJpsUtil.collectResourceDirsForCompilation(extension, false, context, true);
if (resPaths.length == 0) {
// there is no resources in the module
if (!clearDirectoryIfNotEmpty(aptOutputDirectory, context, ANDROID_APT_COMPILER)) {
success = false;
}
continue;
}
final String packageName = moduleData.getPackage();
final File manifestFile;
if (extension.isLibrary() || !extension.isManifestMergingEnabled()) {
manifestFile = moduleData.getManifestFileForCompiler();
} else {
manifestFile = new File(AndroidJpsUtil.getPreprocessedManifestDirectory(module, context.getProjectDescriptor().dataManager.getDataPaths()), SdkConstants.FN_ANDROID_MANIFEST_XML);
}
if (isLibraryWithBadCircularDependency(extension)) {
if (!clearDirectoryIfNotEmpty(aptOutputDirectory, context, ANDROID_APT_COMPILER)) {
success = false;
}
continue;
}
final Map<JpsModule, String> packageMap = getDepLibPackages(module);
packageMap.put(module, packageName);
final JpsModule circularDepLibWithSamePackage = findCircularDependencyOnLibraryWithSamePackage(extension, packageMap);
if (circularDepLibWithSamePackage != null && !extension.isLibrary()) {
final String message = "Generated fields in " + packageName + ".R class in module '" + module.getName() + "' won't be final, because of circular dependency on module '" + circularDepLibWithSamePackage.getName() + "'";
context.processMessage(new CompilerMessage(ANDROID_APT_COMPILER, BuildMessage.Kind.WARNING, message));
}
final boolean generateNonFinalFields = extension.isLibrary() || circularDepLibWithSamePackage != null;
AndroidAptValidityState oldState;
try {
oldState = storage.getState(module.getName());
} catch (IOException e) {
LOG.info(e);
oldState = null;
}
final Map<String, ResourceFileData> resources = new HashMap<String, ResourceFileData>();
final TObjectLongHashMap<String> valueResFilesTimestamps = new TObjectLongHashMap<String>();
collectResources(resPaths, resources, valueResFilesTimestamps, oldState);
final List<ResourceEntry> manifestElements = collectManifestElements(manifestFile);
final List<Pair<String, String>> libRTextFilesAndPackages = new ArrayList<Pair<String, String>>(packageMap.size());
for (Map.Entry<JpsModule, String> entry1 : packageMap.entrySet()) {
final String libPackage = entry1.getValue();
if (!packageName.equals(libPackage)) {
final String libRTxtFilePath = new File(new File(AndroidJpsUtil.getDirectoryForIntermediateArtifacts(context, entry1.getKey()), R_TXT_OUTPUT_DIR_NAME), SdkConstants.FN_RESOURCE_TEXT).getPath();
libRTextFilesAndPackages.add(Pair.create(libRTxtFilePath, libPackage));
}
}
AndroidJpsUtil.collectRTextFilesFromAarDeps(module, libRTextFilesAndPackages);
final File outputDirForArtifacts = AndroidJpsUtil.getDirectoryForIntermediateArtifacts(context, module);
final String proguardOutputCfgFilePath;
if (AndroidJpsUtil.getProGuardConfigIfShouldRun(context, extension) != null) {
if (AndroidJpsUtil.createDirIfNotExist(outputDirForArtifacts, context, BUILDER_NAME) == null) {
success = false;
continue;
}
proguardOutputCfgFilePath = new File(outputDirForArtifacts, AndroidCommonUtils.PROGUARD_CFG_OUTPUT_FILE_NAME).getPath();
} else {
proguardOutputCfgFilePath = null;
}
String rTxtOutDirOsPath = null;
if (extension.isLibrary() || libRTextFilesAndPackages.size() > 0) {
final File rTxtOutDir = new File(outputDirForArtifacts, R_TXT_OUTPUT_DIR_NAME);
if (AndroidJpsUtil.createDirIfNotExist(rTxtOutDir, context, BUILDER_NAME) == null) {
success = false;
continue;
}
rTxtOutDirOsPath = rTxtOutDir.getPath();
}
final AndroidAptValidityState newState = new AndroidAptValidityState(resources, valueResFilesTimestamps, manifestElements, libRTextFilesAndPackages, packageName, proguardOutputCfgFilePath, rTxtOutDirOsPath, extension.isLibrary());
if (newState.equalsTo(oldState)) {
// we need to update state, because it also contains myValueResFilesTimestamps not taking into account by equalsTo()
storage.update(module.getName(), newState);
continue;
}
didSomething = true;
context.processMessage(new ProgressMessage(AndroidJpsBundle.message("android.jps.progress.aapt", module.getName())));
File tmpOutputDir = null;
try {
tmpOutputDir = FileUtil.createTempDirectory("android_apt_output", "tmp");
final Map<AndroidCompilerMessageKind, List<String>> messages = AndroidApt.compile(target, -1, manifestFile.getPath(), packageName, tmpOutputDir.getPath(), resPaths, libRTextFilesAndPackages, generateNonFinalFields, proguardOutputCfgFilePath, rTxtOutDirOsPath, !extension.isLibrary());
AndroidJpsUtil.addMessages(context, messages, ANDROID_APT_COMPILER, module.getName());
if (messages.get(AndroidCompilerMessageKind.ERROR).size() > 0) {
success = false;
storage.update(module.getName(), null);
} else {
if (!AndroidCommonUtils.directoriesContainSameContent(tmpOutputDir, aptOutputDirectory, JAVA_FILE_FILTER)) {
if (!deleteAndMarkRecursively(aptOutputDirectory, context, ANDROID_APT_COMPILER)) {
success = false;
continue;
}
final File parent = aptOutputDirectory.getParentFile();
if (parent != null && !parent.exists() && !parent.mkdirs()) {
context.processMessage(new CompilerMessage(ANDROID_APT_COMPILER, BuildMessage.Kind.ERROR, AndroidJpsBundle.message("android.jps.cannot.create.directory", parent.getPath())));
success = false;
continue;
}
// we use copyDir instead of moveDirWithContent here, because tmp directory may be located on other disk and
// moveDirWithContent doesn't work for such case
FileUtil.copyDir(tmpOutputDir, aptOutputDirectory);
markDirtyRecursively(aptOutputDirectory, context, ANDROID_APT_COMPILER, true);
}
storage.update(module.getName(), newState);
}
} finally {
if (tmpOutputDir != null) {
FileUtil.delete(tmpOutputDir);
}
}
} catch (IOException e) {
AndroidJpsUtil.reportExceptionError(context, null, e, ANDROID_APT_COMPILER);
success = false;
}
}
if (!success) {
return MyExitStatus.FAIL;
} else if (didSomething) {
return MyExitStatus.OK;
}
return MyExitStatus.NOTHING_CHANGED;
}
use of org.jetbrains.jps.incremental.messages.CompilerMessage 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;
}
use of org.jetbrains.jps.incremental.messages.CompilerMessage in project android by JetBrains.
the class AndroidJpsUtil method getAndroidPlatform.
@Nullable
public static AndroidPlatform getAndroidPlatform(@NotNull JpsModule module, @Nullable CompileContext context, String builderName) {
final JpsSdk<JpsSimpleElement<JpsAndroidSdkProperties>> sdk = module.getSdk(JpsAndroidSdkType.INSTANCE);
if (sdk == null) {
if (context != null) {
context.processMessage(new CompilerMessage(builderName, BuildMessage.Kind.ERROR, AndroidJpsBundle.message("android.jps.errors.sdk.not.specified", module.getName())));
}
return null;
}
final Pair<IAndroidTarget, AndroidSdkHandler> pair = getAndroidTarget(sdk, context, builderName);
if (pair == null) {
if (context != null) {
context.processMessage(new CompilerMessage(builderName, BuildMessage.Kind.ERROR, AndroidJpsBundle.message("android.jps.errors.sdk.invalid", module.getName())));
}
return null;
}
return new AndroidPlatform(sdk, pair.getFirst(), pair.getSecond());
}
Aggregations