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