From 3a25a0154669d868b1994de25bbbcadb6232f67a Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Tue, 30 Oct 2012 14:19:39 +0400 Subject: [PATCH] android-jps: read dex compiler settings --- .../android/util/AndroidCommonUtils.java | 9 ++ ...s.android.model.JpsAndroidExtensionService | 1 + .../jps/android/AndroidDexBuilder.java | 30 ++++-- .../JpsAndroidDexCompilerConfiguration.java | 20 ++++ .../model/JpsAndroidExtensionService.java | 20 ++++ ...psAndroidDexCompilerConfigurationImpl.java | 91 +++++++++++++++++++ .../impl/JpsAndroidDexSettingsSerializer.java | 44 +++++++++ .../impl/JpsAndroidExtensionServiceImpl.java | 24 +++++ .../JpsAndroidModelSerializerExtension.java | 8 ++ .../compiler/tools/AndroidDxWrapper.java | 11 +-- 10 files changed, 241 insertions(+), 17 deletions(-) create mode 100644 plugins/android/jps-plugin/src/META-INF/services/org.jetbrains.jps.android.model.JpsAndroidExtensionService create mode 100644 plugins/android/jps-plugin/src/org/jetbrains/jps/android/model/JpsAndroidDexCompilerConfiguration.java create mode 100644 plugins/android/jps-plugin/src/org/jetbrains/jps/android/model/JpsAndroidExtensionService.java create mode 100644 plugins/android/jps-plugin/src/org/jetbrains/jps/android/model/impl/JpsAndroidDexCompilerConfigurationImpl.java create mode 100644 plugins/android/jps-plugin/src/org/jetbrains/jps/android/model/impl/JpsAndroidDexSettingsSerializer.java create mode 100644 plugins/android/jps-plugin/src/org/jetbrains/jps/android/model/impl/JpsAndroidExtensionServiceImpl.java diff --git a/plugins/android/common/src/org/jetbrains/android/util/AndroidCommonUtils.java b/plugins/android/common/src/org/jetbrains/android/util/AndroidCommonUtils.java index 46bf04c4b616..57ce57dd3af7 100644 --- a/plugins/android/common/src/org/jetbrains/android/util/AndroidCommonUtils.java +++ b/plugins/android/common/src/org/jetbrains/android/util/AndroidCommonUtils.java @@ -597,4 +597,13 @@ public class AndroidCommonUtils { writer.close(); } } + + public static boolean hasXmxParam(@NotNull List parameters) { + for (String param : parameters) { + if (param.startsWith("-Xmx")) { + return true; + } + } + return false; + } } diff --git a/plugins/android/jps-plugin/src/META-INF/services/org.jetbrains.jps.android.model.JpsAndroidExtensionService b/plugins/android/jps-plugin/src/META-INF/services/org.jetbrains.jps.android.model.JpsAndroidExtensionService new file mode 100644 index 000000000000..9ba4c63a5a05 --- /dev/null +++ b/plugins/android/jps-plugin/src/META-INF/services/org.jetbrains.jps.android.model.JpsAndroidExtensionService @@ -0,0 +1 @@ +org.jetbrains.jps.android.model.impl.JpsAndroidExtensionServiceImpl diff --git a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidDexBuilder.java b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidDexBuilder.java index 03ceadc03349..026c848115e6 100644 --- a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidDexBuilder.java +++ b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/AndroidDexBuilder.java @@ -24,6 +24,7 @@ import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.util.ArrayUtil; import com.intellij.util.containers.HashMap; import com.intellij.util.containers.HashSet; +import com.intellij.util.execution.ParametersListUtil; import org.jetbrains.android.compiler.tools.AndroidDxRunner; import org.jetbrains.android.util.AndroidCommonUtils; import org.jetbrains.android.util.AndroidCompilerMessageKind; @@ -31,6 +32,8 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.ProjectPaths; import org.jetbrains.jps.android.builder.AndroidBuildTarget; +import org.jetbrains.jps.android.model.JpsAndroidDexCompilerConfiguration; +import org.jetbrains.jps.android.model.JpsAndroidExtensionService; import org.jetbrains.jps.android.model.JpsAndroidModuleExtension; import org.jetbrains.jps.android.model.JpsAndroidSdkProperties; import org.jetbrains.jps.builders.BuildOutputConsumer; @@ -322,12 +325,28 @@ public class AndroidDexBuilder extends TargetBuilder programParamList = new ArrayList(); programParamList.add(dxJarPath); programParamList.add(outFilePath); + + final JpsAndroidDexCompilerConfiguration configuration = + JpsAndroidExtensionService.getInstance().getDexCompilerConfiguration(module.getProject()); + final List vmOptions; + + if (configuration != null) { + vmOptions = new ArrayList(); + 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()))); + } + else { + vmOptions = Collections.singletonList("-Xmx1024M"); + } programParamList.addAll(Arrays.asList(compileTargets)); programParamList.add("--exclude"); @@ -350,12 +369,9 @@ public class AndroidDexBuilder extends TargetBuilder commandLine = ExternalProcessUtil.buildJavaCommandLine(JpsJavaSdkType.getJavaExecutable((JpsSdk)javaSdk.getProperties()), - AndroidDxRunner.class.getName(), - Collections.emptyList(), classPath, - Arrays.asList("-Xmx1024M"), programParamList); + final List commandLine = ExternalProcessUtil + .buildJavaCommandLine(JpsJavaSdkType.getJavaExecutable((JpsSdk)javaSdk.getProperties()), AndroidDxRunner.class.getName(), + Collections.emptyList(), classPath, vmOptions, programParamList); LOG.info(AndroidCommonUtils.command2string(commandLine)); diff --git a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/model/JpsAndroidDexCompilerConfiguration.java b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/model/JpsAndroidDexCompilerConfiguration.java new file mode 100644 index 000000000000..6ce6676fb6b0 --- /dev/null +++ b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/model/JpsAndroidDexCompilerConfiguration.java @@ -0,0 +1,20 @@ +package org.jetbrains.jps.android.model; + +import org.jetbrains.jps.model.JpsElement; + +/** + * @author Eugene.Kudelevsky + */ +public interface JpsAndroidDexCompilerConfiguration extends JpsElement { + String getVmOptions(); + + void setVmOptions(String value); + + int getMaxHeapSize(); + + void setMaxHeapSize(int value); + + boolean isOptimize(); + + void setOptimize(boolean value); +} diff --git a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/model/JpsAndroidExtensionService.java b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/model/JpsAndroidExtensionService.java new file mode 100644 index 000000000000..2368f405c9a6 --- /dev/null +++ b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/model/JpsAndroidExtensionService.java @@ -0,0 +1,20 @@ +package org.jetbrains.jps.android.model; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.JpsProject; +import org.jetbrains.jps.service.JpsServiceManager; + +/** + * @author Eugene.Kudelevsky + */ +public abstract class JpsAndroidExtensionService { + public static JpsAndroidExtensionService getInstance() { + return JpsServiceManager.getInstance().getService(JpsAndroidExtensionService.class); + } + + @Nullable + public abstract JpsAndroidDexCompilerConfiguration getDexCompilerConfiguration(@NotNull JpsProject project); + + public abstract void setDexCompilerConfiguration(@NotNull JpsProject project, @NotNull JpsAndroidDexCompilerConfiguration configuration); +} diff --git a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/model/impl/JpsAndroidDexCompilerConfigurationImpl.java b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/model/impl/JpsAndroidDexCompilerConfigurationImpl.java new file mode 100644 index 000000000000..d1aa55116ca5 --- /dev/null +++ b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/model/impl/JpsAndroidDexCompilerConfigurationImpl.java @@ -0,0 +1,91 @@ +package org.jetbrains.jps.android.model.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.android.model.JpsAndroidDexCompilerConfiguration; +import org.jetbrains.jps.model.JpsElementChildRole; +import org.jetbrains.jps.model.ex.JpsElementBase; +import org.jetbrains.jps.model.ex.JpsElementChildRoleBase; + +/** + * @author Eugene.Kudelevsky + */ +public class JpsAndroidDexCompilerConfigurationImpl extends JpsElementBase + implements JpsAndroidDexCompilerConfiguration { + + public static final JpsElementChildRole ROLE = + JpsElementChildRoleBase.create("android dex compiler configuration"); + + private final MyState myState = new MyState(); + + public JpsAndroidDexCompilerConfigurationImpl() { + } + + public JpsAndroidDexCompilerConfigurationImpl(@NotNull MyState state) { + myState.MAX_HEAP_SIZE = state.MAX_HEAP_SIZE; + myState.OPTIMIZE = state.OPTIMIZE; + myState.VM_OPTIONS = state.VM_OPTIONS; + } + + @Override + public String getVmOptions() { + return myState.VM_OPTIONS; + } + + @Override + public void setVmOptions(String value) { + if (!myState.VM_OPTIONS.equals(value)) { + myState.VM_OPTIONS = value; + fireElementChanged(); + } + } + + @Override + public int getMaxHeapSize() { + return myState.MAX_HEAP_SIZE; + } + + @Override + public void setMaxHeapSize(int value) { + if (myState.MAX_HEAP_SIZE != value) { + myState.MAX_HEAP_SIZE = value; + fireElementChanged(); + } + } + + @Override + public boolean isOptimize() { + return myState.OPTIMIZE; + } + + @Override + public void setOptimize(boolean value) { + if (myState.OPTIMIZE != value) { + myState.OPTIMIZE = value; + fireElementChanged(); + } + } + + @NotNull + @Override + public JpsAndroidDexCompilerConfigurationImpl createCopy() { + return new JpsAndroidDexCompilerConfigurationImpl(myState); + } + + @Override + public void applyChanges(@NotNull JpsAndroidDexCompilerConfigurationImpl modified) { + setVmOptions(modified.getVmOptions()); + setMaxHeapSize(modified.getMaxHeapSize()); + setOptimize(modified.isOptimize()); + } + + @NotNull + public MyState getState() { + return myState; + } + + public static class MyState { + public String VM_OPTIONS = ""; + public int MAX_HEAP_SIZE = 1024; + public boolean OPTIMIZE = true; + } +} diff --git a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/model/impl/JpsAndroidDexSettingsSerializer.java b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/model/impl/JpsAndroidDexSettingsSerializer.java new file mode 100644 index 000000000000..abf3cd33c6a2 --- /dev/null +++ b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/model/impl/JpsAndroidDexSettingsSerializer.java @@ -0,0 +1,44 @@ +package org.jetbrains.jps.android.model.impl; + +import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters; +import com.intellij.util.xmlb.XmlSerializer; +import org.jdom.Element; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.android.model.JpsAndroidDexCompilerConfiguration; +import org.jetbrains.jps.android.model.JpsAndroidExtensionService; +import org.jetbrains.jps.model.JpsProject; +import org.jetbrains.jps.model.serialization.JpsProjectExtensionSerializer; + +/** + * @author Eugene.Kudelevsky + */ +public class JpsAndroidDexSettingsSerializer extends JpsProjectExtensionSerializer { + + private static final SkipDefaultValuesSerializationFilters FILTERS = new SkipDefaultValuesSerializationFilters(); + + public JpsAndroidDexSettingsSerializer() { + super("androidDexCompiler.xml", "AndroidDexCompilerConfiguration"); + } + + @Override + public void loadExtension(@NotNull JpsProject element, @NotNull Element componentTag) { + JpsAndroidDexCompilerConfigurationImpl.MyState state = XmlSerializer.deserialize( + componentTag, JpsAndroidDexCompilerConfigurationImpl.MyState.class); + + if (state == null) { + state = new JpsAndroidDexCompilerConfigurationImpl.MyState(); + } + JpsAndroidExtensionService.getInstance().setDexCompilerConfiguration(element, new JpsAndroidDexCompilerConfigurationImpl(state)); + } + + @Override + public void saveExtension(@NotNull JpsProject element, @NotNull Element componentTag) { + final JpsAndroidDexCompilerConfiguration configuration = + JpsAndroidExtensionService.getInstance().getDexCompilerConfiguration(element); + + if (configuration != null) { + XmlSerializer.serializeInto(((JpsAndroidDexCompilerConfigurationImpl)configuration).getState(), + componentTag, FILTERS); + } + } +} diff --git a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/model/impl/JpsAndroidExtensionServiceImpl.java b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/model/impl/JpsAndroidExtensionServiceImpl.java new file mode 100644 index 000000000000..df284e0745d5 --- /dev/null +++ b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/model/impl/JpsAndroidExtensionServiceImpl.java @@ -0,0 +1,24 @@ +package org.jetbrains.jps.android.model.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.android.model.JpsAndroidDexCompilerConfiguration; +import org.jetbrains.jps.android.model.JpsAndroidExtensionService; +import org.jetbrains.jps.model.JpsProject; + +/** + * @author Eugene.Kudelevsky + */ +public class JpsAndroidExtensionServiceImpl extends JpsAndroidExtensionService { + @Nullable + @Override + public JpsAndroidDexCompilerConfiguration getDexCompilerConfiguration(@NotNull JpsProject project) { + final JpsAndroidDexCompilerConfiguration config = project.getContainer().getChild(JpsAndroidDexCompilerConfigurationImpl.ROLE); + return config != null ? config : new JpsAndroidDexCompilerConfigurationImpl(); + } + + @Override + public void setDexCompilerConfiguration(@NotNull JpsProject project, @NotNull JpsAndroidDexCompilerConfiguration configuration) { + project.getContainer().setChild(JpsAndroidDexCompilerConfigurationImpl.ROLE, configuration); + } +} diff --git a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/model/impl/JpsAndroidModelSerializerExtension.java b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/model/impl/JpsAndroidModelSerializerExtension.java index 0cf75632b609..366d3ce8991d 100644 --- a/plugins/android/jps-plugin/src/org/jetbrains/jps/android/model/impl/JpsAndroidModelSerializerExtension.java +++ b/plugins/android/jps-plugin/src/org/jetbrains/jps/android/model/impl/JpsAndroidModelSerializerExtension.java @@ -27,10 +27,12 @@ import org.jetbrains.jps.model.JpsElementFactory; import org.jetbrains.jps.model.JpsSimpleElement; import org.jetbrains.jps.model.module.JpsModule; import org.jetbrains.jps.model.serialization.JpsModelSerializerExtension; +import org.jetbrains.jps.model.serialization.JpsProjectExtensionSerializer; import org.jetbrains.jps.model.serialization.library.JpsSdkPropertiesSerializer; import org.jetbrains.jps.model.serialization.facet.JpsFacetConfigurationSerializer; import java.util.Arrays; +import java.util.Collections; import java.util.List; /** @@ -88,6 +90,12 @@ public class JpsAndroidModelSerializerExtension extends JpsModelSerializerExtens return FACET_PROPERTIES_LOADERS; } + @NotNull + @Override + public List getProjectExtensionSerializers() { + return Collections.singletonList(new JpsAndroidDexSettingsSerializer()); + } + @NotNull @Override public List> getSdkPropertiesSerializers() { diff --git a/plugins/android/src/org/jetbrains/android/compiler/tools/AndroidDxWrapper.java b/plugins/android/src/org/jetbrains/android/compiler/tools/AndroidDxWrapper.java index 3456dac64a94..37fcbace865b 100644 --- a/plugins/android/src/org/jetbrains/android/compiler/tools/AndroidDxWrapper.java +++ b/plugins/android/src/org/jetbrains/android/compiler/tools/AndroidDxWrapper.java @@ -93,7 +93,7 @@ public class AndroidDxWrapper { if (additionalVmParams.length() > 0) { vmParamList.addParametersString(additionalVmParams); } - if (!hasXmxParam(vmParamList)) { + if (!AndroidCommonUtils.hasXmxParam(vmParamList.getParameters())) { vmParamList.add("-Xmx" + maxHeapSize + "M"); } final PathsList classPath = parameters.getClassPath(); @@ -121,13 +121,4 @@ public class AndroidDxWrapper { return messages; } - - private static boolean hasXmxParam(ParametersList paramList) { - for (String param : paramList.getParameters()) { - if (param.startsWith("-Xmx")) { - return true; - } - } - return false; - } }