@@ -11,7 +11,8 @@ import java.util.Properties
1111const val RUST_TASK_GROUP = " rust"
1212
1313enum class ToolchainType {
14- ANDROID ,
14+ ANDROID_PREBUILT ,
15+ ANDROID_GENERATED ,
1516 DESKTOP ,
1617}
1718
@@ -20,67 +21,104 @@ val toolchains = listOf(
2021 Toolchain (" linux-x86-64" ,
2122 ToolchainType .DESKTOP ,
2223 " x86_64-unknown-linux-gnu" ,
23- " <cc >" ,
24- " <ar >" ,
24+ " <compilerTriple >" ,
25+ " <binutilsTriple >" ,
2526 " desktop/linux-x86-64" ),
2627 Toolchain (" darwin" ,
2728 ToolchainType .DESKTOP ,
2829 " x86_64-apple-darwin" ,
29- " <cc >" ,
30- " <ar >" ,
30+ " <compilerTriple >" ,
31+ " <binutilsTriple >" ,
3132 " desktop/darwin" ),
3233 Toolchain (" win32-x86-64-msvc" ,
3334 ToolchainType .DESKTOP ,
3435 " x86_64-pc-windows-msvc" ,
35- " <cc >" ,
36- " <ar >" ,
36+ " <compilerTriple >" ,
37+ " <binutilsTriple >" ,
3738 " desktop/win32-x86-64" ),
3839 Toolchain (" win32-x86-64-gnu" ,
3940 ToolchainType .DESKTOP ,
4041 " x86_64-pc-windows-gnu" ,
41- " <cc >" ,
42- " <ar >" ,
42+ " <compilerTriple >" ,
43+ " <binutilsTriple >" ,
4344 " desktop/win32-x86-64" ),
4445 Toolchain (" arm" ,
45- ToolchainType .ANDROID ,
46+ ToolchainType .ANDROID_GENERATED ,
4647 " armv7-linux-androideabi" ,
47- " bin/ arm-linux-androideabi-clang " ,
48- " bin/ arm-linux-androideabi-ar " ,
48+ " arm-linux-androideabi" ,
49+ " arm-linux-androideabi" ,
4950 " android/armeabi-v7a" ),
5051 Toolchain (" arm64" ,
51- ToolchainType .ANDROID ,
52+ ToolchainType .ANDROID_GENERATED ,
53+ " aarch64-linux-android" ,
54+ " aarch64-linux-android" ,
5255 " aarch64-linux-android" ,
53- " bin/aarch64-linux-android-clang" ,
54- " bin/aarch64-linux-android-ar" ,
5556 " android/arm64-v8a" ),
5657 Toolchain (" x86" ,
57- ToolchainType .ANDROID ,
58+ ToolchainType .ANDROID_GENERATED ,
59+ " i686-linux-android" ,
60+ " i686-linux-android" ,
5861 " i686-linux-android" ,
59- " bin/i686-linux-android-clang" ,
60- " bin/i686-linux-android-ar" ,
6162 " android/x86" ),
6263 Toolchain (" x86_64" ,
63- ToolchainType .ANDROID ,
64+ ToolchainType .ANDROID_GENERATED ,
65+ " x86_64-linux-android" ,
66+ " x86_64-linux-android" ,
67+ " x86_64-linux-android" ,
68+ " android/x86_64" ),
69+ Toolchain (" arm" ,
70+ ToolchainType .ANDROID_PREBUILT ,
71+ " armv7-linux-androideabi" , // This is correct. "Note: For 32-bit ARM, the compiler is prefixed with
72+ " armv7a-linux-androideabi" , // armv7a-linux-androideabi, but the binutils tools are prefixed with
73+ " arm-linux-androideabi" , // arm-linux-androideabi. For other architectures, the prefixes are the same
74+ " android/armeabi-v7a" ), // for all tools." (Ref: https://developer.android.com/ndk/guides/other_build_systems#overview )
75+ Toolchain (" arm64" ,
76+ ToolchainType .ANDROID_PREBUILT ,
77+ " aarch64-linux-android" ,
78+ " aarch64-linux-android" ,
79+ " aarch64-linux-android" ,
80+ " android/arm64-v8a" ),
81+ Toolchain (" x86" ,
82+ ToolchainType .ANDROID_PREBUILT ,
83+ " i686-linux-android" ,
84+ " i686-linux-android" ,
85+ " i686-linux-android" ,
86+ " android/x86" ),
87+ Toolchain (" x86_64" ,
88+ ToolchainType .ANDROID_PREBUILT ,
89+ " x86_64-linux-android" ,
90+ " x86_64-linux-android" ,
6491 " x86_64-linux-android" ,
65- " bin/x86_64-linux-android-clang" ,
66- " bin/x86_64-linux-android-ar" ,
6792 " android/x86_64" )
6893)
6994
7095data class Toolchain (val platform : String ,
7196 val type : ToolchainType ,
7297 val target : String ,
73- val cc : String ,
74- val ar : String ,
98+ val compilerTriple : String ,
99+ val binutilsTriple : String ,
75100 val folder : String ) {
76101 fun cc (apiLevel : Int ): File =
77102 if (System .getProperty(" os.name" ).startsWith(" Windows" )) {
78- File (" $platform -$apiLevel " , " $cc .cmd" )
103+ if (type == ToolchainType .ANDROID_PREBUILT ) {
104+ File (" bin" , " $compilerTriple$apiLevel -clang.cmd" )
105+ } else {
106+ File (" $platform -$apiLevel /bin" , " $compilerTriple -clang.cmd" )
107+ }
79108 } else {
80- File (" $platform -$apiLevel " , " $cc " )
109+ if (type == ToolchainType .ANDROID_PREBUILT ) {
110+ File (" bin" , " $compilerTriple$apiLevel -clang" )
111+ } else {
112+ File (" $platform -$apiLevel /bin" , " $compilerTriple -clang" )
113+ }
81114 }
82115
83- fun ar (apiLevel : Int ): File = File (" $platform -$apiLevel " , " $ar " )
116+ fun ar (apiLevel : Int ): File =
117+ if (type == ToolchainType .ANDROID_PREBUILT ) {
118+ File (" bin" , " $binutilsTriple -ar" )
119+ } else {
120+ File (" $platform -$apiLevel /bin" , " $binutilsTriple -ar" )
121+ }
84122}
85123
86124@Suppress(" unused" )
@@ -136,10 +174,33 @@ open class RustAndroidPlugin : Plugin<Project> {
136174 sourceSets.getByName(" test" ).resources.srcDir(File (" $buildDir /rustJniLibs/desktop" ))
137175 }
138176
139- val generateToolchain = tasks.maybeCreate(" generateToolchains" ,
140- GenerateToolchainsTask ::class .java).apply {
141- group = RUST_TASK_GROUP
142- description = " Generate standard toolchain for given architectures"
177+ // Determine the NDK version, if present
178+ val ndkSourceProperties = Properties ()
179+ val ndkSourcePropertiesFile = File (extensions[T ::class ].ndkDirectory, " source.properties" )
180+ if (ndkSourcePropertiesFile.exists()) {
181+ ndkSourceProperties.load(ndkSourcePropertiesFile.inputStream())
182+ }
183+ val ndkVersion = ndkSourceProperties.getProperty(" Pkg.Revision" , " 0.0" )
184+ val ndkVersionMajor = ndkVersion.split(" ." ).first().toInt()
185+
186+ // Determine whether to use prebuilt or generated toolchains
187+ val usePrebuilt =
188+ cargoExtension.localProperties.getProperty(" rust.prebuiltToolchains" )?.equals(" true" ) ? :
189+ cargoExtension.prebuiltToolchains ? :
190+ (ndkVersionMajor >= 19 );
191+
192+ if (usePrebuilt && ndkVersionMajor < 19 ) {
193+ throw GradleException (" usePrebuilt = true requires NDK version 19+" )
194+ }
195+
196+ val generateToolchain = if (! usePrebuilt) {
197+ tasks.maybeCreate(" generateToolchains" ,
198+ GenerateToolchainsTask ::class .java).apply {
199+ group = RUST_TASK_GROUP
200+ description = " Generate standard toolchain for given architectures"
201+ }
202+ } else {
203+ null
143204 }
144205
145206 // Fish linker wrapper scripts from our Java resources.
@@ -167,7 +228,15 @@ open class RustAndroidPlugin : Plugin<Project> {
167228 }
168229
169230 cargoExtension.targets!! .forEach { target ->
170- val theToolchain = toolchains.find { it.platform == target }
231+ val theToolchain = toolchains
232+ .filter {
233+ if (usePrebuilt) {
234+ it.type != ToolchainType .ANDROID_GENERATED
235+ } else {
236+ it.type != ToolchainType .ANDROID_PREBUILT
237+ }
238+ }
239+ .find { it.platform == target }
171240 if (theToolchain == null ) {
172241 throw GradleException (" Target ${target} is not recognized (recognized targets: ${toolchains.map { it.platform }.sorted()} ). Check `local.properties` and `build.gradle`." )
173242 }
@@ -179,7 +248,9 @@ open class RustAndroidPlugin : Plugin<Project> {
179248 toolchain = theToolchain
180249 }
181250
182- targetBuildTask.dependsOn(generateToolchain)
251+ if (! usePrebuilt) {
252+ targetBuildTask.dependsOn(generateToolchain!! )
253+ }
183254 targetBuildTask.dependsOn(generateLinkerWrapper)
184255 buildTask.dependsOn(targetBuildTask)
185256 }
0 commit comments