aboutsummaryrefslogtreecommitdiffstats
path: root/anttasks/src/com/android/ant/SetupTask.java
diff options
context:
space:
mode:
Diffstat (limited to 'anttasks/src/com/android/ant/SetupTask.java')
-rw-r--r--anttasks/src/com/android/ant/SetupTask.java208
1 files changed, 208 insertions, 0 deletions
diff --git a/anttasks/src/com/android/ant/SetupTask.java b/anttasks/src/com/android/ant/SetupTask.java
new file mode 100644
index 0000000..d425a2f
--- /dev/null
+++ b/anttasks/src/com/android/ant/SetupTask.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ant;
+
+import com.android.sdklib.IAndroidTarget;
+import com.android.sdklib.ISdkLog;
+import com.android.sdklib.SdkManager;
+import com.android.sdklib.IAndroidTarget.IOptionalLibrary;
+import com.android.sdklib.project.ProjectProperties;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.ImportTask;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Path.PathElement;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashSet;
+
+/**
+ * Setup/Import Ant task. This task accomplishes:
+ * <ul>
+ * <li>Gets the project target hash string from {@link ProjectProperties#PROPERTY_TARGET},
+ * and resolves it to get the project's {@link IAndroidTarget}.</li>
+ * <li>Sets up properties so that aapt can find the android.jar in the resolved target.</li>
+ * <li>Sets up the boot classpath ref so that the <code>javac</code> task knows where to find
+ * the libraries. This includes the default android.jar from the resolved target but also optional
+ * libraries provided by the target (if any, when the target is an add-on).</li>
+ * <li>Imports the build rules located in the resolved target so that the build actually does
+ * something. This can be disabled with the attribute <var>import</var> set to <code>false</code>
+ * </li></ul>
+ *
+ * This is used in build.xml/template.
+ *
+ */
+public final class SetupTask extends ImportTask {
+ private final static String ANDROID_RULES = "android_rules.xml";
+
+ // ant property with the path to the android.jar
+ private final static String PROPERTY_ANDROID_JAR = "android-jar";
+ // ant property with the path to the framework.jar
+ private final static String PROPERTY_ANDROID_AIDL = "android-aidl";
+ // ant property with the path to the aapt tool
+ private final static String PROPERTY_AAPT = "aapt";
+ // ant property with the path to the aidl tool
+ private final static String PROPERTY_AIDL = "aidl";
+ // ant property with the path to the dx tool
+ private final static String PROPERTY_DX = "dx";
+ // ref id to the <path> object containing all the boot classpaths.
+ private final static String REF_CLASSPATH = "android.target.classpath";
+
+ private boolean mDoImport = true;
+
+ @Override
+ public void execute() throws BuildException {
+ Project antProject = getProject();
+
+ // get the SDK location
+ String sdkLocation = antProject.getProperty(ProjectProperties.PROPERTY_SDK);
+
+ // check if it's valid and exists
+ if (sdkLocation == null || sdkLocation.length() == 0) {
+ throw new BuildException("SDK Location is not set.");
+ }
+
+ File sdk = new File(sdkLocation);
+ if (sdk.isDirectory() == false) {
+ throw new BuildException(String.format("SDK Location '%s' is not valid.", sdkLocation));
+ }
+
+ // get the target property value
+ String targetHashString = antProject.getProperty(ProjectProperties.PROPERTY_TARGET);
+ if (targetHashString == null) {
+ throw new BuildException("Android Target is not set.");
+ }
+
+ // load up the sdk targets.
+ final ArrayList<String> messages = new ArrayList<String>();
+ SdkManager manager = SdkManager.createManager(sdkLocation, new ISdkLog() {
+ public void error(Throwable t, String errorFormat, Object... args) {
+ if (errorFormat != null) {
+ messages.add(String.format("Error: " + errorFormat, args));
+ }
+ if (t != null) {
+ messages.add("Error: " + t.getMessage());
+ }
+ }
+
+ public void printf(String msgFormat, Object... args) {
+ messages.add(String.format(msgFormat, args));
+ }
+
+ public void warning(String warningFormat, Object... args) {
+ messages.add(String.format("Warning: " + warningFormat, args));
+ }
+ });
+
+ if (manager == null) {
+ // since we failed to parse the SDK, lets display the parsing output.
+ for (String msg : messages) {
+ System.out.println(msg);
+ }
+ throw new BuildException("Failed to parse SDK content.");
+ }
+
+ // resolve it
+ IAndroidTarget androidTarget = manager.getTargetFromHashString(targetHashString);
+
+ if (androidTarget == null) {
+ throw new BuildException(String.format(
+ "Unable to resolve target '%s'", targetHashString));
+ }
+
+ // display it
+ System.out.println("Project Target: " + androidTarget.getName());
+ if (androidTarget.isPlatform() == false) {
+ System.out.println("Vendor: " + androidTarget.getVendor());
+ System.out.println("Platform Version: " + androidTarget.getApiVersionName());
+ }
+ System.out.println("API level: " + androidTarget.getApiVersionNumber());
+
+ // sets up the properties to find android.jar/framework.aidl/target tools
+ String androidJar = androidTarget.getPath(IAndroidTarget.ANDROID_JAR);
+ antProject.setProperty(PROPERTY_ANDROID_JAR, androidJar);
+
+ antProject.setProperty(PROPERTY_ANDROID_AIDL,
+ androidTarget.getPath(IAndroidTarget.ANDROID_AIDL));
+ antProject.setProperty(PROPERTY_AAPT, androidTarget.getPath(IAndroidTarget.AAPT));
+ antProject.setProperty(PROPERTY_AIDL, androidTarget.getPath(IAndroidTarget.AIDL));
+ antProject.setProperty(PROPERTY_DX, androidTarget.getPath(IAndroidTarget.DX));
+
+ // sets up the boot classpath
+
+ // create the Path object
+ Path bootclasspath = new Path(antProject);
+
+ // create a PathElement for the framework jar
+ PathElement element = bootclasspath.createPathElement();
+ element.setPath(androidJar);
+
+ // create PathElement for each optional library.
+ IOptionalLibrary[] libraries = androidTarget.getOptionalLibraries();
+ if (libraries != null) {
+ HashSet<String> visitedJars = new HashSet<String>();
+ for (IOptionalLibrary library : libraries) {
+ String jarPath = library.getJarPath();
+ if (visitedJars.contains(jarPath) == false) {
+ visitedJars.add(jarPath);
+
+ element = bootclasspath.createPathElement();
+ element.setPath(library.getJarPath());
+ }
+ }
+ }
+
+ // finally sets the path in the project with a reference
+ antProject.addReference(REF_CLASSPATH, bootclasspath);
+
+ // find the file to import, and import it.
+ String templateFolder = androidTarget.getPath(IAndroidTarget.TEMPLATES);
+
+ // Now the import section. This is only executed if the task actually has to import a file.
+ if (mDoImport) {
+ // make sure the file exists.
+ File templates = new File(templateFolder);
+ if (templates.isDirectory() == false) {
+ throw new BuildException(String.format("Template directory '%s' is missing.",
+ templateFolder));
+ }
+
+ // now check the rules file exists.
+ File rules = new File(templateFolder, ANDROID_RULES);
+ if (rules.isFile() == false) {
+ throw new BuildException(String.format("Build rules file '%s' is missing.",
+ templateFolder));
+ }
+
+ // set the file location to import
+ setFile(rules.getAbsolutePath());
+
+ // and import
+ super.execute();
+ }
+ }
+
+ /**
+ * Sets the value of the "import" attribute.
+ * @param value the value.
+ */
+ public void setImport(boolean value) {
+ mDoImport = value;
+ }
+}