1 /*
<lambda>null2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package androidx.build
18
19 import java.io.File
20 import java.util.Properties
21 import org.gradle.api.GradleException
22 import org.gradle.api.Project
23 import org.gradle.api.file.FileTree
24
25 /** Writes the appropriate SDK path to local.properties file in specified location. */
26 fun Project.writeSdkPathToLocalPropertiesFile() {
27 val sdkPath = project.getSdkPath()
28 if (sdkPath.exists()) {
29 val props = File(project.rootDir, "local.properties")
30 // Gradle always separates directories with '/' regardless of the OS, so convert here.
31 val gradlePath = sdkPath.absolutePath.replace(File.separator, "/")
32 val contents = "sdk.dir=$gradlePath\ncmake.dir=$gradlePath/native-build-tools"
33 props.printWriter().use { out -> out.println(contents) }
34 } else {
35 throw Exception(
36 "Unable to find SDK prebuilts at $sdkPath. If you are not using a " +
37 "standard repo-based checkout, please follow the checkout instructions at " +
38 "go/androidx-onboarding."
39 )
40 }
41 }
42
43 /** Returns a file tree representing the platform SDK suitable for use as a dependency. */
Projectnull44 fun Project.getSdkDependency(): FileTree =
45 fileTree("${getSdkPath()}/platforms/android-${project.defaultAndroidConfig.compileSdk}/") {
46 it.include("android.jar")
47 }
48
49 /** Returns the root project's platform-specific SDK path as a file. */
Projectnull50 fun Project.getSdkPath(): File {
51 if (
52 ProjectLayoutType.from(project) == ProjectLayoutType.PLAYGROUND ||
53 System.getenv("COMPOSE_DESKTOP_GITHUB_BUILD") != null
54 ) {
55 // This is not full checkout, use local settings instead.
56 // https://developer.android.com/studio/command-line/variables
57 // check for local.properties first
58 val localPropsFile = rootProject.projectDir.resolve("local.properties")
59 if (localPropsFile.exists()) {
60 val localProps = Properties()
61 localPropsFile.inputStream().use { localProps.load(it) }
62 val localSdkDir = localProps["sdk.dir"]?.toString()
63 if (localSdkDir != null) {
64 val sdkDirectory = File(localSdkDir)
65 if (sdkDirectory.isDirectory) {
66 return sdkDirectory
67 }
68 }
69 }
70 return getSdkPathFromEnvironmentVariable()
71 }
72 val os = getOperatingSystem()
73 return if (os == OperatingSystem.WINDOWS) {
74 getSdkPathFromEnvironmentVariable()
75 } else {
76 val platform = if (os == OperatingSystem.MAC) "darwin" else "linux"
77
78 // By convention, the SDK prebuilts live under the root checkout directory.
79 File(project.getCheckoutRoot(), "prebuilts/fullsdk-$platform")
80 }
81 }
82
getSdkPathFromEnvironmentVariablenull83 private fun getSdkPathFromEnvironmentVariable(): File {
84 // check for environment variables, in the order AGP checks
85 listOf("ANDROID_HOME", "ANDROID_SDK_ROOT").forEach {
86 val envValue = System.getenv(it)
87 if (envValue != null) {
88 val sdkDirectory = File(envValue)
89 if (sdkDirectory.isDirectory) {
90 return sdkDirectory
91 }
92 }
93 }
94 // only print the error for SDK ROOT since ANDROID_HOME is deprecated but we first check
95 // it because it is prioritized according to the documentation
96 throw GradleException("ANDROID_SDK_ROOT environment variable is not set")
97 }
98
99 /** Sets the path to the canonical root project directory, e.g. {@code frameworks/support}. */
Projectnull100 fun Project.setSupportRootFolder(rootDir: File?) {
101 val extension = project.extensions.extraProperties
102 return extension.set("supportRootFolder", rootDir)
103 }
104
105 /**
106 * Returns the path to the canonical root project directory, e.g. {@code frameworks/support}.
107 *
108 * Note: This method of accessing the frameworks/support path is preferred over Project.rootDir
109 * because it is generalized to also work for the "ui" project and playground projects.
110 */
Projectnull111 fun Project.getSupportRootFolder(): File {
112 val extension = project.extensions.extraProperties
113 return extension.get("supportRootFolder") as File
114 }
115
116 /**
117 * Returns the path to the checkout's root directory, e.g. where {@code repo init} was run.
118 *
119 * <p>
120 * This method assumes that the canonical root project directory is {@code frameworks/support}.
121 */
Projectnull122 fun Project.getCheckoutRoot(): File {
123 return project.getSupportRootFolder().parentFile.parentFile
124 }
125
126 /** Returns the path to the konan prebuilts folder (e.g. <root>/prebuilts/androidx/konan). */
Projectnull127 fun Project.getKonanPrebuiltsFolder(): File {
128 return getPrebuiltsRoot().resolve("androidx/konan")
129 }
130