/* * Copyright (C) 2013 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.build.gradle.internal import com.android.annotations.NonNull import com.android.build.gradle.BaseExtension import com.android.builder.DefaultSdkParser import com.android.builder.PlatformSdkParser import com.android.builder.SdkParser import com.android.sdklib.repository.FullRevision import com.android.utils.ILogger import org.gradle.api.Project import static com.android.SdkConstants.FN_LOCAL_PROPERTIES import static com.android.build.gradle.BasePlugin.TEST_SDK_DIR import static com.google.common.base.Preconditions.checkNotNull /** * Encapsulate finding, parsing, and initializing the SdkParser lazily. */ public class Sdk { @NonNull private final Project project @NonNull private final ILogger logger @NonNull private SdkParser parser private boolean isSdkParserInitialized = false private File androidSdkDir private File androidNdkDir private boolean isPlatformSdk = false private BaseExtension extension public Sdk(@NonNull Project project, @NonNull ILogger logger) { this.project = project this.logger = logger findLocation() } public void setExtension(@NonNull BaseExtension extension) { this.extension = extension parser = initParser() } public SdkParser getParser() { return parser } /** * Returns the parser, creating it if needed. This does not load it if it's not been loaded yet. * * @return the parser. * * @see #loadParser() */ @NonNull private SdkParser initParser() { checkLocation() SdkParser parser; //noinspection GroovyIfStatementWithIdenticalBranches if (isPlatformSdk) { parser = new PlatformSdkParser(androidSdkDir.absolutePath) } else { parser = new DefaultSdkParser(androidSdkDir.absolutePath, androidNdkDir) } List repositories = parser.repositories for (File file : repositories) { project.repositories.maven { url = file.toURI() } } return parser } /** * Loads and returns the parser. If it's not been created yet, this will do it too. * * {@link #setExtension(BaseExtension)} must have been called before. * * For more light weight usage, consider {@link #getParser()} * * @return the loaded parser. * * @see #getParser() */ @NonNull public SdkParser loadParser() { checkNotNull(extension, "Extension has not been set") // call getParser to ensure it's created. SdkParser theParser = getParser() if (!isSdkParserInitialized) { String target = extension.getCompileSdkVersion() if (target == null) { throw new IllegalArgumentException("android.compileSdkVersion is missing!") } FullRevision buildToolsRevision = extension.buildToolsRevision if (buildToolsRevision == null) { throw new IllegalArgumentException("android.buildToolsVersion is missing!") } theParser.initParser(target, buildToolsRevision, logger) isSdkParserInitialized = true } return theParser } public File getSdkDirectory() { checkLocation() return androidSdkDir } public File getNdkDirectory() { checkLocation() return androidNdkDir } private void checkLocation() { // don't complain in test mode if (TEST_SDK_DIR != null) { return } if (androidSdkDir == null) { throw new RuntimeException( "SDK location not found. Define location with sdk.dir in the local.properties file or with an ANDROID_HOME environment variable.") } if (!androidSdkDir.isDirectory()) { throw new RuntimeException( "The SDK directory '$androidSdkDir.absolutePath' does not exist.") } } private void findLocation() { if (TEST_SDK_DIR != null) { androidSdkDir = TEST_SDK_DIR return } def rootDir = project.rootDir def localProperties = new File(rootDir, FN_LOCAL_PROPERTIES) if (localProperties.exists()) { Properties properties = new Properties() localProperties.withInputStream { instr -> properties.load(instr) } def sdkDirProp = properties.getProperty('sdk.dir') if (sdkDirProp != null) { androidSdkDir = new File(sdkDirProp) } else { sdkDirProp = properties.getProperty('android.dir') if (sdkDirProp != null) { androidSdkDir = new File(rootDir, sdkDirProp) isPlatformSdk = true } else { throw new RuntimeException( "No sdk.dir property defined in local.properties file.") } } def ndkDirProp = properties.getProperty('ndk.dir') if (ndkDirProp != null) { androidNdkDir = new File(ndkDirProp) } } else { String envVar = System.getenv("ANDROID_HOME") if (envVar != null) { androidSdkDir = new File(envVar) } else { String property = System.getProperty("android.home") if (property != null) { androidSdkDir = new File(property) } } envVar = System.getenv("ANDROID_NDK_HOME") if (envVar != null) { androidNdkDir = new File(envVar) } } } }