Add support for build-tools.
Xavier Ducrohet [Tue, 12 Mar 2013 20:56:13 +0000 (13:56 -0700)]
Change-Id: I6c355e2e2459987224e4fac3fdd8c02d2f4fc905

54 files changed:
builder/src/main/java/com/android/builder/AndroidBuilder.java
builder/src/main/java/com/android/builder/DefaultSdkParser.java
builder/src/main/java/com/android/builder/PlatformSdkParser.java
builder/src/main/java/com/android/builder/SdkParser.java
builder/src/main/java/com/android/builder/internal/FakeAndroidTarget.java
gradle/src/main/groovy/com/android/build/gradle/AppPlugin.groovy
gradle/src/main/groovy/com/android/build/gradle/BaseExtension.groovy
gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy
gradle/src/main/groovy/com/android/build/gradle/LibraryPlugin.groovy
gradle/src/main/groovy/com/android/build/gradle/internal/ApplicationVariant.groovy
gradle/src/main/groovy/com/android/build/gradle/internal/ProductionAppVariant.groovy
gradle/src/main/groovy/com/android/build/gradle/internal/TestAppVariant.groovy
tests/aidl/build.gradle
tests/api/app/build.gradle
tests/api/lib/build.gradle
tests/applibtest/app/build.gradle
tests/applibtest/lib/build.gradle
tests/assets/app/build.gradle
tests/assets/lib/build.gradle
tests/basic/build.gradle
tests/dependencies/build.gradle
tests/flavored/build.gradle
tests/flavorlib/app/build.gradle
tests/flavorlib/lib1/build.gradle
tests/flavorlib/lib2/build.gradle
tests/flavorlibWithFailedTests/app/build.gradle
tests/flavorlibWithFailedTests/lib1/build.gradle
tests/flavorlibWithFailedTests/lib2/build.gradle
tests/flavors/build.gradle
tests/libsTest/app/build.gradle
tests/libsTest/lib1/build.gradle
tests/libsTest/lib2/build.gradle
tests/libsTest/lib2b/build.gradle
tests/libsTest/libapp/build.gradle
tests/localJars/app/build.gradle
tests/localJars/baseLibrary/build.gradle
tests/localJars/library/build.gradle
tests/migrated/build.gradle
tests/multiproject/app/build.gradle
tests/multiproject/baseLibrary/build.gradle
tests/multiproject/library/build.gradle
tests/multires/build.gradle
tests/overlay1/build.gradle
tests/overlay2/build.gradle
tests/pkgOverride/build.gradle
tests/renderscript/build.gradle
tests/renderscriptInLib/app/build.gradle
tests/renderscriptInLib/lib/build.gradle
tests/renderscriptMultiSrc/build.gradle
tests/repo/app/build.gradle
tests/repo/baseLibrary/build.gradle
tests/repo/library/build.gradle
tests/tictactoe/app/build.gradle
tests/tictactoe/lib/build.gradle

index a3574f0..7545c17 100644 (file)
@@ -44,6 +44,7 @@ import com.android.builder.signing.KeytoolException;
 import com.android.builder.signing.SigningConfig;
 import com.android.manifmerger.ManifestMerger;
 import com.android.manifmerger.MergerLog;
+import com.android.sdklib.BuildToolInfo;
 import com.android.sdklib.IAndroidTarget;
 import com.android.sdklib.IAndroidTarget.IOptionalLibrary;
 import com.android.sdklib.repository.FullRevision;
@@ -66,7 +67,6 @@ import java.util.concurrent.ExecutionException;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
 
 /**
  * This is the main builder class. It is given all the data to process the build (such as
@@ -74,8 +74,7 @@ import static com.google.common.base.Preconditions.checkState;
  * build steps.
  *
  * To use:
- * create a builder with {@link #AndroidBuilder(SdkParser, ILogger, boolean)},
- * configure compile target with {@link #setTarget(String)}
+ * create a builder with {@link #AndroidBuilder(SdkParser, ILogger, boolean)}
  *
  * then build steps can be done with
  * {@link #generateBuildConfig(String, boolean, java.util.List, String)}
@@ -105,7 +104,10 @@ public class AndroidBuilder {
     private final CommandLineRunner mCmdLineRunner;
     private final boolean mVerboseExec;
 
-    private IAndroidTarget mTarget;
+    @NonNull
+    private final IAndroidTarget mTarget;
+    @NonNull
+    private final BuildToolInfo mBuildTools;
 
     /**
      * Creates an AndroidBuilder
@@ -140,6 +142,9 @@ public class AndroidBuilder {
                     platformToolsRevision, MIN_PLATFORM_TOOLS_REV));
 
         }
+
+        mTarget = mSdkParser.getTarget();
+        mBuildTools = mSdkParser.getBuildTools();
     }
 
     @VisibleForTesting
@@ -152,36 +157,15 @@ public class AndroidBuilder {
         mCmdLineRunner = checkNotNull(cmdLineRunner);
         mLogger = checkNotNull(logger);
         mVerboseExec = verboseExec;
-    }
-
-    /**
-     * Sets the compilation target hash string.
-     *
-     * @param target the compilation target
-     *
-     * @see IAndroidTarget#hashString()
-     */
-    public void setTarget(@NonNull String target) {
-        checkNotNull(target, "target cannot be null.");
 
-        mTarget = mSdkParser.resolveTarget(target, mLogger);
-
-        if (mTarget == null) {
-            throw new RuntimeException("Unknown target: " + target);
-        }
-    }
-
-    public int getTargetApiLevel() {
-        checkState(mTarget != null, "Target not set.");
-
-        return mTarget.getVersion().getApiLevel();
+        mTarget = mSdkParser.getTarget();
+        mBuildTools = mSdkParser.getBuildTools();
     }
 
     /**
      * Returns the runtime classpath to be used during compilation.
      */
     public List<String> getRuntimeClasspath() {
-        checkState(mTarget != null, "Target not set.");
 
         List<String> classpath = Lists.newArrayList();
 
@@ -208,7 +192,9 @@ public class AndroidBuilder {
      * @return an AaptRunner object
      */
     public AaptRunner getAaptRunner() {
-        return new AaptRunner(mSdkParser.getAapt().getAbsolutePath(), mCmdLineRunner);
+        return new AaptRunner(
+                mBuildTools.getPath(BuildToolInfo.PathId.AAPT),
+                mCmdLineRunner);
     }
 
     /**
@@ -225,7 +211,6 @@ public class AndroidBuilder {
                      boolean debuggable,
             @NonNull List<String> javaLines,
             @NonNull String sourceOutputDir) throws IOException {
-        checkState(mTarget != null, "Target not set.");
 
         BuildConfigGenerator generator = new BuildConfigGenerator(
                 sourceOutputDir, packageName, debuggable);
@@ -264,7 +249,6 @@ public class AndroidBuilder {
                      int minSdkVersion,
                      int targetSdkVersion,
             @NonNull String outManifestLocation) {
-        checkState(mTarget != null, "Target not set.");
         checkNotNull(mainManifest, "mainManifest cannot be null.");
         checkNotNull(manifestOverlays, "manifestOverlays cannot be null.");
         checkNotNull(libraries, "libraries cannot be null.");
@@ -344,7 +328,6 @@ public class AndroidBuilder {
             @NonNull String instrumentationRunner,
             @NonNull List<? extends ManifestDependency> libraries,
             @NonNull String outManifestLocation) {
-        checkState(mTarget != null, "Target not set.");
         checkNotNull(testPackageName, "testPackageName cannot be null.");
         checkNotNull(testedPackageName, "testedPackageName cannot be null.");
         checkNotNull(instrumentationRunner, "instrumentationRunner cannot be null.");
@@ -518,7 +501,6 @@ public class AndroidBuilder {
             @NonNull  AaptOptions options)
             throws IOException, InterruptedException {
 
-        checkState(mTarget != null, "Target not set.");
         checkNotNull(manifestFile, "manifestFile cannot be null.");
         checkNotNull(resFolder, "resFolder cannot be null.");
         checkNotNull(libraries, "libraries cannot be null.");
@@ -530,12 +512,12 @@ public class AndroidBuilder {
         // launch aapt: create the command line
         ArrayList<String> command = Lists.newArrayList();
 
-        File aapt = mSdkParser.getAapt();
-        if (aapt == null || !aapt.isFile()) {
+        String aapt = mBuildTools.getPath(BuildToolInfo.PathId.AAPT);
+        if (aapt == null || !new File(aapt).isFile()) {
             throw new IllegalStateException("aapt is missing");
         }
 
-        command.add(aapt.getAbsolutePath());
+        command.add(aapt);
         command.add("package");
 
         if (mVerboseExec) {
@@ -698,13 +680,12 @@ public class AndroidBuilder {
                                     @NonNull List<File> importFolders,
                                     @Nullable DependencyFileProcessor dependencyFileProcessor)
             throws IOException, InterruptedException, ExecutionException {
-        checkState(mTarget != null, "Target not set.");
         checkNotNull(sourceFolders, "sourceFolders cannot be null.");
         checkNotNull(sourceOutputDir, "sourceOutputDir cannot be null.");
         checkNotNull(importFolders, "importFolders cannot be null.");
 
-        File aidl = mSdkParser.getAidlCompiler();
-        if (aidl == null || !aidl.isFile()) {
+        String aidl = mBuildTools.getPath(BuildToolInfo.PathId.AIDL);
+        if (aidl == null || !new File(aidl).isFile()) {
             throw new IllegalStateException("aidl is missing");
         }
 
@@ -714,7 +695,7 @@ public class AndroidBuilder {
         fullImportList.addAll(importFolders);
 
         AidlProcessor processor = new AidlProcessor(
-                aidl.getAbsolutePath(),
+                aidl,
                 mTarget.getPath(IAndroidTarget.ANDROID_AIDL),
                 fullImportList,
                 sourceOutputDir,
@@ -743,18 +724,17 @@ public class AndroidBuilder {
                                 @NonNull List<File> importFolders,
                                 @Nullable DependencyFileProcessor dependencyFileProcessor)
             throws IOException, InterruptedException {
-        checkState(mTarget != null, "Target not set.");
         checkNotNull(aidlFile, "aidlFile cannot be null.");
         checkNotNull(sourceOutputDir, "sourceOutputDir cannot be null.");
         checkNotNull(importFolders, "importFolders cannot be null.");
 
-        File aidl = mSdkParser.getAidlCompiler();
-        if (aidl == null || !aidl.isFile()) {
+        String aidl = mBuildTools.getPath(BuildToolInfo.PathId.AIDL);
+        if (aidl == null || !new File(aidl).isFile()) {
             throw new IllegalStateException("aidl is missing");
         }
 
         AidlProcessor processor = new AidlProcessor(
-                aidl.getAbsolutePath(),
+                aidl,
                 mTarget.getPath(IAndroidTarget.ANDROID_AIDL),
                 importFolders,
                 sourceOutputDir,
@@ -791,14 +771,13 @@ public class AndroidBuilder {
                                             boolean debugBuild,
                                             int optimLevel)
             throws IOException, InterruptedException, ExecutionException {
-        checkState(mTarget != null, "Target not set.");
         checkNotNull(sourceFolders, "sourceFolders cannot be null.");
         checkNotNull(importFolders, "importFolders cannot be null.");
         checkNotNull(sourceOutputDir, "sourceOutputDir cannot be null.");
         checkNotNull(resOutputDir, "resOutputDir cannot be null.");
 
-        File renderscript = mSdkParser.getRenderscriptCompiler();
-        if (renderscript == null || !renderscript.isFile()) {
+        String renderscript = mBuildTools.getPath(BuildToolInfo.PathId.LLVM_RS_CC);
+        if (renderscript == null || !new File(renderscript).isFile()) {
             throw new IllegalStateException("llvm-rs-cc is missing");
         }
 
@@ -814,21 +793,17 @@ public class AndroidBuilder {
             return;
         }
 
-        @SuppressWarnings("deprecation")
-        String rsPath = mTarget.getPath(IAndroidTarget.ANDROID_RS);
-
-        @SuppressWarnings("deprecation")
-        String rsClangPath = mTarget.getPath(IAndroidTarget.ANDROID_RS_CLANG);
+        String rsPath = mBuildTools.getPath(BuildToolInfo.PathId.ANDROID_RS);
+        String rsClangPath = mBuildTools.getPath(BuildToolInfo.PathId.ANDROID_RS_CLANG);
 
         // the renderscript compiler doesn't expect the top res folder,
         // but the raw folder directly.
         File rawFolder = new File(resOutputDir, SdkConstants.FD_RES_RAW);
 
-
         // compile all the files in a single pass
         ArrayList<String> command = Lists.newArrayList();
 
-        command.add(renderscript.getAbsolutePath());
+        command.add(renderscript);
 
         if (debugBuild) {
             command.add("-g");
@@ -925,7 +900,6 @@ public class AndroidBuilder {
             @NonNull String outDexFile,
             @NonNull DexOptions dexOptions,
             boolean incremental) throws IOException, InterruptedException {
-        checkState(mTarget != null, "Target not set.");
         checkNotNull(classesLocation, "classesLocation cannot be null.");
         checkNotNull(libraries, "libraries cannot be null.");
         checkNotNull(outDexFile, "outDexFile cannot be null.");
@@ -934,12 +908,12 @@ public class AndroidBuilder {
         // launch dx: create the command line
         ArrayList<String> command = Lists.newArrayList();
 
-        File dx = mSdkParser.getDx();
-        if (dx == null || !dx.isFile()) {
+        String dx = mBuildTools.getPath(BuildToolInfo.PathId.DX);
+        if (dx == null || !new File(dx).isFile()) {
             throw new IllegalStateException("dx is missing");
         }
 
-        command.add(dx.getAbsolutePath());
+        command.add(dx);
 
         command.add("--dex");
 
@@ -1016,7 +990,6 @@ public class AndroidBuilder {
             @Nullable SigningConfig signingConfig,
             @NonNull String outApkLocation) throws DuplicateFileException, FileNotFoundException,
             KeytoolException, PackagerException, SigningException {
-        checkState(mTarget != null, "Target not set.");
         checkNotNull(androidResPkgLocation, "androidResPkgLocation cannot be null.");
         checkNotNull(classesDexLocation, "classesDexLocation cannot be null.");
         checkNotNull(outApkLocation, "outApkLocation cannot be null.");
index fbc2896..5ac4150 100644 (file)
@@ -18,13 +18,13 @@ package com.android.builder;
 
 import com.android.SdkConstants;
 import com.android.annotations.NonNull;
+import com.android.sdklib.BuildToolInfo;
 import com.android.sdklib.IAndroidTarget;
 import com.android.sdklib.SdkManager;
 import com.android.sdklib.repository.FullRevision;
 import com.android.sdklib.repository.PkgProps;
 import com.android.utils.ILogger;
 import com.google.common.base.Charsets;
-import com.google.common.collect.Maps;
 import com.google.common.io.Closeables;
 
 import java.io.File;
@@ -33,7 +33,6 @@ import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.Reader;
-import java.util.Map;
 import java.util.Properties;
 
 import static com.android.SdkConstants.FD_PLATFORM_TOOLS;
@@ -50,9 +49,13 @@ public class DefaultSdkParser implements SdkParser {
     private final String mSdkLocation;
     private SdkManager mManager;
 
+    private IAndroidTarget mTarget;
+    private BuildToolInfo mBuildToolInfo;
+
     private File mTools;
     private File mPlatformTools;
-    private final Map<String, File> mToolsMap = Maps.newHashMapWithExpectedSize(6);
+    private File mAdb;
+    private File mZipAlign;
 
     public DefaultSdkParser(@NonNull String sdkLocation) {
         if (!sdkLocation.endsWith(File.separator)) {
@@ -63,15 +66,44 @@ public class DefaultSdkParser implements SdkParser {
     }
 
     @Override
-    public IAndroidTarget resolveTarget(@NonNull String target, @NonNull ILogger logger) {
+    public void initParser(@NonNull String target,
+                           @NonNull FullRevision buildToolRevision,
+                           @NonNull ILogger logger) {
         if (mManager == null) {
             mManager = SdkManager.createManager(mSdkLocation, logger);
             if (mManager == null) {
-                throw new RuntimeException("failed to parse SDK!");
+                throw new IllegalStateException("failed to parse SDK!");
+            }
+
+            mTarget = mManager.getTargetFromHashString(target);
+            if (mTarget == null) {
+                throw new IllegalStateException("failed to find target " + target);
+            }
+
+            mBuildToolInfo = mManager.getBuildTool(buildToolRevision);
+            if (mBuildToolInfo == null) {
+                throw new IllegalStateException("failed to find Build Tools revision "
+                        + buildToolRevision.toString());
             }
         }
+    }
+
+    @NonNull
+    @Override
+    public IAndroidTarget getTarget() {
+        if (mManager == null) {
+            throw new IllegalStateException("SdkParser was not initialized.");
+        }
+        return mTarget;
+    }
 
-        return mManager.getTargetFromHashString(target);
+    @NonNull
+    @Override
+    public BuildToolInfo getBuildTools() {
+        if (mManager == null) {
+            throw new IllegalStateException("SdkParser was not initialized.");
+        }
+        return mBuildToolInfo;
     }
 
     @Override
@@ -114,76 +146,42 @@ public class DefaultSdkParser implements SdkParser {
     }
 
     @Override
-    public File getAapt() {
-        return getPlatformTool(SdkConstants.FN_AAPT);
-    }
-
-    @Override
-    public File getAidlCompiler() {
-        return getPlatformTool(SdkConstants.FN_AIDL);
-    }
-
-    @Override
-    public File getRenderscriptCompiler() {
-        return getPlatformTool(SdkConstants.FN_RENDERSCRIPT);
-    }
-
-    @Override
-    public File getDx() {
-        return getPlatformTool(SdkConstants.FN_DX);
-    }
-
-    @Override
     public File getZipAlign() {
-        return getTool(SdkConstants.FN_ZIPALIGN);
+        if (mZipAlign == null) {
+            mZipAlign = new File(getToolsFolder(), SdkConstants.FN_ZIPALIGN);
+        }
+        return mZipAlign;
     }
 
     @Override
     public File getAdb() {
-        return getPlatformTool(SdkConstants.FN_ADB);
-    }
-
-    private File getPlatformTool(String filename) {
-        File f = mToolsMap.get(filename);
-        if (f == null) {
-            File platformTools = getPlatformToolsFolder();
-            if (!platformTools.isDirectory()) {
-                return null;
-            }
-
-            f = new File(platformTools, filename);
-            mToolsMap.put(filename, f);
-        }
-
-        return f;
-    }
-
-    private File getTool(String filename) {
-        File f = mToolsMap.get(filename);
-        if (f == null) {
-            File platformTools = getToolsFolder();
-            if (!platformTools.isDirectory()) {
-                return null;
-            }
-
-            f = new File(platformTools, filename);
-            mToolsMap.put(filename, f);
+        if (mAdb == null) {
+            mAdb = new File(getPlatformToolsFolder(), SdkConstants.FN_ADB);
         }
-
-        return f;
+        return mAdb;
     }
 
+    @NonNull
     private File getPlatformToolsFolder() {
         if (mPlatformTools == null) {
             mPlatformTools = new File(mSdkLocation, FD_PLATFORM_TOOLS);
+            if (!mPlatformTools.isDirectory()) {
+                throw new IllegalStateException("Platform-tools folder missing: " +
+                        mPlatformTools.getAbsolutePath());
+            }
         }
 
         return mPlatformTools;
     }
 
+    @NonNull
     private File getToolsFolder() {
         if (mTools == null) {
             mTools = new File(mSdkLocation, FD_TOOLS);
+            if (!mTools.isDirectory()) {
+                throw new IllegalStateException("Platform-tools folder missing: " +
+                        mTools.getAbsolutePath());
+            }
         }
 
         return mTools;
index 5cfb1f4..7cd8eb8 100644 (file)
@@ -19,13 +19,12 @@ package com.android.builder;
 import com.android.SdkConstants;
 import com.android.annotations.NonNull;
 import com.android.builder.internal.FakeAndroidTarget;
+import com.android.sdklib.BuildToolInfo;
 import com.android.sdklib.IAndroidTarget;
 import com.android.sdklib.repository.FullRevision;
 import com.android.utils.ILogger;
-import com.google.common.collect.Maps;
 
 import java.io.File;
-import java.util.Map;
 
 /**
  * Implementation of {@link SdkParser} for the SDK prebuilds in the Android source tree.
@@ -33,9 +32,12 @@ import java.util.Map;
 public class PlatformSdkParser implements SdkParser {
     private final String mPlatformRootFolder;
 
+    private boolean mInitialized = false;
+    private IAndroidTarget mTarget;
+    private BuildToolInfo mBuildToolInfo;
+
     private File mHostTools;
-    private final Map<String, File> mToolsMap = Maps.newHashMapWithExpectedSize(6);
-    private File mDx;
+    private File mZipAlign;
     private File mAdb;
 
     PlatformSdkParser(@NonNull String sdkLocation) {
@@ -43,8 +45,39 @@ public class PlatformSdkParser implements SdkParser {
     }
 
     @Override
-    public IAndroidTarget resolveTarget(String target, ILogger logger) {
-        return new FakeAndroidTarget(mPlatformRootFolder, target);
+    public void initParser(@NonNull String target,
+                           @NonNull FullRevision buildToolRevision,
+                           @NonNull ILogger logger) {
+        if (!mInitialized) {
+            mTarget = new FakeAndroidTarget(mPlatformRootFolder, target);
+
+            mBuildToolInfo = new BuildToolInfo(buildToolRevision, new File(mPlatformRootFolder),
+                    new File(getHostToolsFolder(), SdkConstants.FN_AAPT),
+                    new File(getHostToolsFolder(), SdkConstants.FN_AIDL),
+                    new File(mPlatformRootFolder, "prebuilts/sdk/tools/dx"),
+                    new File(mPlatformRootFolder, "prebuilts/sdk/tools/lib/dx.jar"),
+                    new File(getHostToolsFolder(), SdkConstants.FN_RENDERSCRIPT),
+                    new File(mPlatformRootFolder, "prebuilts/sdk/renderscript/include"),
+                    new File(mPlatformRootFolder, "prebuilts/sdk/renderscript/clang-include"));
+        }
+    }
+
+    @NonNull
+    @Override
+    public IAndroidTarget getTarget() {
+        if (!mInitialized) {
+            throw new IllegalStateException("SdkParser was not initialized.");
+        }
+        return mTarget;
+    }
+
+    @NonNull
+    @Override
+    public BuildToolInfo getBuildTools() {
+        if (!mInitialized) {
+            throw new IllegalStateException("SdkParser was not initialized.");
+        }
+        return mBuildToolInfo;
     }
 
     @Override
@@ -67,32 +100,12 @@ public class PlatformSdkParser implements SdkParser {
     }
 
     @Override
-    public File getAapt() {
-        return getTool(SdkConstants.FN_AAPT);
-    }
-
-    @Override
-    public File getAidlCompiler() {
-        return getTool(SdkConstants.FN_AIDL);
-    }
-
-    @Override
-    public File getRenderscriptCompiler() {
-        return getTool(SdkConstants.FN_RENDERSCRIPT);
-    }
-
-    @Override
-    public File getDx() {
-        if (mDx == null) {
-            mDx =  new File(mPlatformRootFolder, "prebuilts/sdk/tools/dx");
+    public File getZipAlign() {
+        if (mZipAlign == null) {
+            mZipAlign = new File(getHostToolsFolder(), SdkConstants.FN_ZIPALIGN);
         }
 
-        return mDx;
-    }
-
-    @Override
-    public File getZipAlign() {
-        return getTool(SdkConstants.FN_ZIPALIGN);
+        return mZipAlign;
     }
 
     @Override
@@ -104,28 +117,15 @@ public class PlatformSdkParser implements SdkParser {
             } else if (SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_LINUX) {
                 mAdb = new File(mPlatformRootFolder, "out/host/linux-x86/bin/adb");
             } else {
-                throw new IllegalStateException("Windows is not supported for platform development");
+                throw new IllegalStateException(
+                        "Windows is not supported for platform development");
             }
         }
 
         return mAdb;
     }
 
-    private File getTool(String filename) {
-        File f = mToolsMap.get(filename);
-        if (f == null) {
-            File platformTools = getHostToolsFolder();
-            if (!platformTools.isDirectory()) {
-                return null;
-            }
-
-            f = new File(platformTools, filename);
-            mToolsMap.put(filename, f);
-        }
-
-        return f;
-    }
-
+    @NonNull
     private File getHostToolsFolder() {
         if (mHostTools == null) {
             File tools = new File(mPlatformRootFolder, "prebuilts/sdk/tools");
@@ -134,7 +134,13 @@ public class PlatformSdkParser implements SdkParser {
             } else if (SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_LINUX) {
                 mHostTools = new File(tools, "linux");
             } else {
-                throw new IllegalStateException("Windows is not supported for platform development");
+                throw new IllegalStateException(
+                        "Windows is not supported for platform development");
+            }
+
+            if (!mHostTools.isDirectory()) {
+                throw new IllegalStateException("Host tools folder missing: " +
+                        mHostTools.getAbsolutePath());
             }
         }
         return mHostTools;
index efabc48..4e07593 100644 (file)
@@ -17,6 +17,7 @@
 package com.android.builder;
 
 import com.android.annotations.NonNull;
+import com.android.sdklib.BuildToolInfo;
 import com.android.sdklib.IAndroidTarget;
 import com.android.sdklib.repository.FullRevision;
 import com.android.utils.ILogger;
@@ -30,48 +31,52 @@ import java.io.File;
 public interface SdkParser {
 
     /**
-     * Resolves a target hash string and returns the corresponding {@link IAndroidTarget}
+     * Inits the parser with a target hash string and a build tools FullRevision.
+     *
+     * Note that this may be called several times on the same object, though it will always
+     * be with the same values. Extra calls can be ignored.
+     *
      * @param target the target hash string.
+     * @param buildToolRevision the build tools revision
      * @param logger a logger object.
-     * @return the target or null if no match is found.
      *
-     * @throws RuntimeException if the SDK cannot parsed.
+     * @throws IllegalStateException if the SDK cannot parsed.
      *
      * @see IAndroidTarget#hashString()
      */
-    IAndroidTarget resolveTarget(@NonNull String target, @NonNull ILogger logger);
-
-    /**
-     * Returns the location of the annotations jar for compilation targets that are <= 15.
-     */
-    String getAnnotationsJar();
+    public void initParser(@NonNull String target,
+                           @NonNull FullRevision buildToolRevision,
+                           @NonNull ILogger logger);
 
     /**
-     * Returns the revision of the installed platform tools component.
+     * Returns the compilation target
+     * @return the target.
      *
-     * @return the FullRevision or null if the revision couldn't not be found
+     * @throws IllegalStateException if the sdk was not initialized.
      */
-    FullRevision getPlatformToolsRevision();
+    @NonNull
+    IAndroidTarget getTarget();
 
     /**
-     * Returns the location of the aapt tool.
-     */
-    File getAapt();
-
-    /**
-     * Returns the location of the aidl compiler.
+     * Returns the BuildToolInfo
+     * @return the build tool info
+     *
+     * @throws IllegalStateException if the sdk was not initialized.
      */
-    File getAidlCompiler();
+    @NonNull
+    BuildToolInfo getBuildTools();
 
     /**
-     * Returns the location of the renderscript compiler.
-     */
-    File getRenderscriptCompiler();
+      * Returns the location of the annotations jar for compilation targets that are <= 15.
+      */
+    String getAnnotationsJar();
 
     /**
-     * Returns the location of the dx tool.
+     * Returns the revision of the installed platform tools component.
+     *
+     * @return the FullRevision or null if the revision couldn't not be found
      */
-    File getDx();
+    FullRevision getPlatformToolsRevision();
 
     /**
      * Returns the location of the zip align tool.
index 6a67e89..ff8acb4 100644 (file)
@@ -66,11 +66,6 @@ public class FakeAndroidTarget implements IAndroidTarget {
             mPaths.put(ANDROID_JAR, apiPrebuilts + SdkConstants.FN_FRAMEWORK_LIBRARY);
             mPaths.put(ANDROID_AIDL, apiPrebuilts + SdkConstants.FN_FRAMEWORK_AIDL);
         }
-
-        // location of the renderscript imports.
-        String rsPrebuilts = mSdkLocation + "/prebuilts/sdk/renderscript/";
-        mPaths.put(ANDROID_RS, rsPrebuilts + SdkConstants.OS_FRAMEWORK_RS);
-        mPaths.put(ANDROID_RS_CLANG, rsPrebuilts + SdkConstants.OS_FRAMEWORK_RS_CLANG);
     }
 
     private int getApiLevel(String target) {
index 71a0f04..0f7618e 100644 (file)
@@ -73,6 +73,11 @@ class AppPlugin extends com.android.build.gradle.BasePlugin implements org.gradl
     }
 
     @Override
+    protected BaseExtension getAndroidExtension() {
+        return extension;
+    }
+
+    @Override
     void apply(Project project) {
         super.apply(project)
 
@@ -530,9 +535,4 @@ class AppPlugin extends com.android.build.gradle.BasePlugin implements org.gradl
 
         return variant;
     }
-
-    @Override
-    protected String getTarget() {
-        return extension.compileSdkVersion;
-    }
 }
index 0230396..7d37602 100644 (file)
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 package com.android.build.gradle
+
 import com.android.build.gradle.internal.CompileOptions
 import com.android.build.gradle.internal.dsl.AaptOptionsImpl
 import com.android.build.gradle.internal.dsl.AndroidSourceSetFactory
@@ -22,6 +23,7 @@ import com.android.build.gradle.internal.dsl.ProductFlavorDsl
 import com.android.build.gradle.internal.test.TestOptions
 import com.android.builder.BuilderConstants
 import com.android.builder.ProductFlavor
+import com.android.sdklib.repository.FullRevision
 import org.gradle.api.Action
 import org.gradle.api.NamedDomainObjectContainer
 import org.gradle.api.artifacts.Configuration
@@ -35,6 +37,7 @@ import org.gradle.internal.reflect.Instantiator
 public abstract class BaseExtension {
 
     private String target
+    private FullRevision buildToolsRevision
 
     final ProductFlavor defaultConfig
     final AaptOptionsImpl aaptOptions
@@ -110,6 +113,14 @@ public abstract class BaseExtension {
         compileSdkVersion(target)
     }
 
+    void buildToolsVersion(String version) {
+        buildToolsRevision = FullRevision.parseRevision(version)
+    }
+
+    void setBuildToolsVersion(String version) {
+        buildToolsVersion(version)
+    }
+
     void sourceSets(Action<NamedDomainObjectContainer<AndroidSourceSet>> action) {
         action.execute(sourceSetsContainer)
     }
@@ -147,4 +158,8 @@ public abstract class BaseExtension {
     public String getCompileSdkVersion() {
         return target
     }
+
+    public FullRevision getBuildToolsRevision() {
+        return buildToolsRevision
+    }
 }
index d6defef..c1f6d75 100644 (file)
@@ -59,6 +59,7 @@ import com.android.builder.VariantConfiguration
 import com.android.builder.dependency.AndroidDependency
 import com.android.builder.dependency.JarDependency
 import com.android.builder.signing.SigningConfig
+import com.android.sdklib.repository.FullRevision
 import com.android.utils.ILogger
 import com.google.common.collect.ArrayListMultimap
 import com.google.common.collect.Lists
@@ -123,7 +124,7 @@ public abstract class BasePlugin {
     protected Task assembleTest
     protected Task deviceCheck
 
-    protected abstract String getTarget()
+    protected abstract BaseExtension getAndroidExtension()
 
     protected BasePlugin(Instantiator instantiator) {
         this.instantiator = instantiator
@@ -224,7 +225,20 @@ public abstract class BasePlugin {
         AndroidBuilder androidBuilder = builders.get(variant)
 
         if (androidBuilder == null) {
-            androidBuilder = variant.createBuilder(this)
+            String target = androidExtension.getCompileSdkVersion()
+            if (target == null) {
+                throw new IllegalArgumentException("android.compileSdkVersion is missing!")
+            }
+
+            FullRevision buildToolsRevision = androidExtension.buildToolsRevision
+            if (buildToolsRevision == null) {
+                throw new IllegalArgumentException("android.buildToolsVersion is missing!")
+
+            }
+
+            sdkParser.initParser(target, buildToolsRevision, logger)
+            androidBuilder = new AndroidBuilder(sdkParser, logger, verbose)
+
             builders.put(variant, androidBuilder)
         }
 
index 3be6c08..fa1de59 100644 (file)
@@ -57,6 +57,11 @@ public class LibraryPlugin extends BasePlugin implements Plugin<Project> {
     }
 
     @Override
+    protected BaseExtension getAndroidExtension() {
+        return extension;
+    }
+
+    @Override
     void apply(Project project) {
         super.apply(project)
 
@@ -293,9 +298,4 @@ public class LibraryPlugin extends BasePlugin implements Plugin<Project> {
 
         return testVariant
     }
-
-    @Override
-    protected String getTarget() {
-        return extension.compileSdkVersion
-    }
 }
index d902211..4b520df 100644 (file)
@@ -114,8 +114,6 @@ public abstract class ApplicationVariant {
         return config.getPackageName()
     }
 
-    abstract AndroidBuilder createBuilder(BasePlugin androidBasePlugin)
-
     protected String getFlavoredName(boolean capitalized) {
         StringBuilder builder = new StringBuilder()
         for (ProductFlavor flavor : config.flavorConfigs) {
index fa36606..9e75822 100644 (file)
@@ -15,8 +15,6 @@
  */
 package com.android.build.gradle.internal
 
-import com.android.build.gradle.BasePlugin
-import com.android.builder.AndroidBuilder
 import com.android.builder.VariantConfiguration
 
 class ProductionAppVariant extends ApplicationVariant {
@@ -64,16 +62,4 @@ class ProductionAppVariant extends ApplicationVariant {
     boolean getRunProguard() {
         return config.buildType.runProguard
     }
-
-    @Override
-    AndroidBuilder createBuilder(BasePlugin androidBasePlugin) {
-        AndroidBuilder androidBuilder = new AndroidBuilder(
-                androidBasePlugin.sdkParser,
-                androidBasePlugin.logger,
-                androidBasePlugin.verbose)
-
-        androidBuilder.setTarget(androidBasePlugin.target)
-
-        return androidBuilder
-    }
 }
index dc8cf8e..ce7ece6 100644 (file)
@@ -15,8 +15,6 @@
  */
 package com.android.build.gradle.internal
 
-import com.android.build.gradle.BasePlugin
-import com.android.builder.AndroidBuilder
 import com.android.builder.VariantConfiguration
 
 class TestAppVariant extends ApplicationVariant {
@@ -65,16 +63,4 @@ class TestAppVariant extends ApplicationVariant {
     boolean getRunProguard() {
         return false
     }
-
-    @Override
-    AndroidBuilder createBuilder(BasePlugin androidBasePlugin) {
-        AndroidBuilder androidBuilder = new AndroidBuilder(
-                androidBasePlugin.sdkParser,
-                androidBasePlugin.logger,
-                androidBasePlugin.verbose)
-
-        androidBuilder.setTarget(androidBasePlugin.target)
-
-        return androidBuilder
-    }
 }
index c9c9275..be67004 100644 (file)
@@ -11,5 +11,6 @@ apply plugin: 'android'
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 
 }
\ No newline at end of file
index 85e4c9d..1a67ff4 100644 (file)
@@ -2,6 +2,7 @@ apply plugin: 'android'
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 }
 
 // query for all (non-test) variants and inject a new step in the builds
index 50837f7..72889e4 100644 (file)
@@ -2,6 +2,7 @@ apply plugin: 'android-library'
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 }
 
 // query for all (non-test) variants and inject a new step in the builds
index 8d1c513..5b76f9b 100644 (file)
@@ -2,6 +2,7 @@ apply plugin: 'android'
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 }
 
 //
index 99ff711..6aca68e 100644 (file)
@@ -2,8 +2,9 @@ apply plugin: 'android-library'
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 
-       defaultConfig {
-               testPackageName = "com.android.tests.testprojecttest.testlib"
-       }
+    defaultConfig {
+        testPackageName = "com.android.tests.testprojecttest.testlib"
+    }
 }
\ No newline at end of file
index f71301e..d078f0c 100644 (file)
@@ -2,6 +2,7 @@ apply plugin: 'android'
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 }
 
 dependencies {
index 182f845..f63ed4d 100644 (file)
@@ -2,4 +2,5 @@ apply plugin: 'android-library'
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 }
\ No newline at end of file
index 4b355f3..3b1a559 100644 (file)
@@ -14,6 +14,8 @@ apply plugin: 'android'
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
+
     testBuildType "debug"
 
     signingConfigs {
index dd2281c..c6ba30d 100644 (file)
@@ -24,6 +24,8 @@ dependencies {
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
+
     testBuildType "blah"
 
     defaultConfig {
index 891d191..724d786 100644 (file)
@@ -14,6 +14,8 @@ apply plugin: 'android'
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
+
     testBuildType = "staging"
 
     defaultConfig {
index c3111bf..727cf15 100644 (file)
@@ -2,6 +2,7 @@ apply plugin: 'android'
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 
     productFlavors {
         flavor1 {
index 182f845..f63ed4d 100644 (file)
@@ -2,4 +2,5 @@ apply plugin: 'android-library'
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 }
\ No newline at end of file
index 182f845..f63ed4d 100644 (file)
@@ -2,4 +2,5 @@ apply plugin: 'android-library'
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 }
\ No newline at end of file
index 485c953..00ff3fe 100644 (file)
@@ -2,6 +2,7 @@ apply plugin: 'android'
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 
     productFlavors {
         flavor1 {
index 182f845..f63ed4d 100644 (file)
@@ -2,4 +2,5 @@ apply plugin: 'android-library'
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 }
\ No newline at end of file
index 182f845..f63ed4d 100644 (file)
@@ -2,4 +2,5 @@ apply plugin: 'android-library'
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 }
\ No newline at end of file
index 8e91be9..65fbfc3 100644 (file)
@@ -11,6 +11,8 @@ apply plugin: 'android'
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
+
     flavorGroups   "group1", "group2"
 
     productFlavors {
index 2506b09..4da2f26 100644 (file)
@@ -2,6 +2,7 @@ apply plugin: 'android'
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 }
 
 //
index f1e1e87..d404df3 100644 (file)
@@ -6,4 +6,5 @@ dependencies {
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 }
\ No newline at end of file
index 182f845..f63ed4d 100644 (file)
@@ -2,4 +2,5 @@ apply plugin: 'android-library'
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 }
\ No newline at end of file
index 182f845..f63ed4d 100644 (file)
@@ -2,4 +2,5 @@ apply plugin: 'android-library'
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 }
\ No newline at end of file
index 182f845..f63ed4d 100644 (file)
@@ -2,4 +2,5 @@ apply plugin: 'android-library'
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 }
\ No newline at end of file
index 362924a..ca47c8c 100644 (file)
@@ -2,7 +2,7 @@ apply plugin: 'android'
 
 android {
     compileSdkVersion 15
-//    buildToolsVersion "1.0"
+    buildToolsVersion "1.0"
 }
 
 dependencies {
index 4700d90..b21571a 100644 (file)
@@ -2,7 +2,7 @@ apply plugin: 'android-library'
 
 android {
     compileSdkVersion 15
-//    buildToolsVersion "1.0"
+    buildToolsVersion "1.0"
 }
 
 dependencies {
index 6d07c6a..e569164 100644 (file)
@@ -2,7 +2,7 @@ apply plugin: 'android-library'
 
 android {
     compileSdkVersion 15
-//    buildToolsVersion "1.0"
+    buildToolsVersion "1.0"
 }
 
 dependencies {
index 6120613..9ae056c 100644 (file)
@@ -12,6 +12,7 @@ apply plugin: 'android'
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 
     sourceSets {
         main {
index d6f8176..ca47c8c 100644 (file)
@@ -2,6 +2,7 @@ apply plugin: 'android'
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 }
 
 dependencies {
index 6c5b6a5..5660058 100644 (file)
@@ -2,6 +2,7 @@ apply plugin: 'android-library'
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 }
 
 dependencies {
index bcce608..50bcb3b 100644 (file)
@@ -2,6 +2,7 @@ apply plugin: 'android-library'
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 }
 
 dependencies {
index 1d688e8..351ada4 100644 (file)
@@ -11,6 +11,7 @@ apply plugin: 'android'
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 
     sourceSets {
         main {
index 93160af..a24fa6f 100644 (file)
@@ -12,4 +12,5 @@ apply plugin: 'android'
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 }
\ No newline at end of file
index e46b210..58a72c8 100644 (file)
@@ -12,6 +12,7 @@ apply plugin: 'android'
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 
     productFlavors {
         one {}
index 19ec8b6..dc7dcbc 100644 (file)
@@ -11,6 +11,7 @@ apply plugin: 'android'
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 
     defaultConfig {
         packageName "com.android.tests.basic.foo"
index 5ecec55..b16d4ca 100644 (file)
@@ -11,6 +11,7 @@ apply plugin: 'android'
 
 android {
     compileSdkVersion 17
+    buildToolsVersion "1.0"
 
     defaultConfig {
         renderscriptTargetApi = 17
index 982c831..e2cddb5 100644 (file)
@@ -2,6 +2,7 @@ apply plugin: 'android'
 
 android {
     compileSdkVersion 17
+    buildToolsVersion "1.0"
 
     defaultConfig {
         renderscriptTargetApi = 11
index 7b79c44..b64d513 100644 (file)
@@ -2,4 +2,5 @@ apply plugin: 'android-library'
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 }
index d707102..4566e47 100644 (file)
@@ -11,6 +11,7 @@ apply plugin: 'android'
 
 android {
     compileSdkVersion 17
+    buildToolsVersion "1.0"
 
     defaultConfig {
         renderscriptTargetApi = 11
index ac7ff81..eda0a7d 100644 (file)
@@ -22,5 +22,6 @@ dependencies {
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 }
 
index 07f40ab..34cb341 100644 (file)
@@ -23,6 +23,7 @@ dependencies {
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 }
 
 group = 'com.example.android.multiproject'
index 48dd920..a545df9 100644 (file)
@@ -22,6 +22,7 @@ dependencies {
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 }
 
 group = 'com.example.android.multiproject'
index 3566ad1..9a5c703 100644 (file)
@@ -6,4 +6,5 @@ dependencies {
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 }
index 182f845..f63ed4d 100644 (file)
@@ -2,4 +2,5 @@ apply plugin: 'android-library'
 
 android {
     compileSdkVersion 15
+    buildToolsVersion "1.0"
 }
\ No newline at end of file