@@ -11,7 +11,8 @@ import java.util.Properties
11
11
const val RUST_TASK_GROUP = " rust"
12
12
13
13
enum class ToolchainType {
14
- ANDROID ,
14
+ ANDROID_PREBUILT ,
15
+ ANDROID_GENERATED ,
15
16
DESKTOP ,
16
17
}
17
18
@@ -20,67 +21,104 @@ val toolchains = listOf(
20
21
Toolchain (" linux-x86-64" ,
21
22
ToolchainType .DESKTOP ,
22
23
" x86_64-unknown-linux-gnu" ,
23
- " <cc >" ,
24
- " <ar >" ,
24
+ " <compilerTriple >" ,
25
+ " <binutilsTriple >" ,
25
26
" desktop/linux-x86-64" ),
26
27
Toolchain (" darwin" ,
27
28
ToolchainType .DESKTOP ,
28
29
" x86_64-apple-darwin" ,
29
- " <cc >" ,
30
- " <ar >" ,
30
+ " <compilerTriple >" ,
31
+ " <binutilsTriple >" ,
31
32
" desktop/darwin" ),
32
33
Toolchain (" win32-x86-64-msvc" ,
33
34
ToolchainType .DESKTOP ,
34
35
" x86_64-pc-windows-msvc" ,
35
- " <cc >" ,
36
- " <ar >" ,
36
+ " <compilerTriple >" ,
37
+ " <binutilsTriple >" ,
37
38
" desktop/win32-x86-64" ),
38
39
Toolchain (" win32-x86-64-gnu" ,
39
40
ToolchainType .DESKTOP ,
40
41
" x86_64-pc-windows-gnu" ,
41
- " <cc >" ,
42
- " <ar >" ,
42
+ " <compilerTriple >" ,
43
+ " <binutilsTriple >" ,
43
44
" desktop/win32-x86-64" ),
44
45
Toolchain (" arm" ,
45
- ToolchainType .ANDROID ,
46
+ ToolchainType .ANDROID_GENERATED ,
46
47
" armv7-linux-androideabi" ,
47
- " bin/ arm-linux-androideabi-clang " ,
48
- " bin/ arm-linux-androideabi-ar " ,
48
+ " arm-linux-androideabi" ,
49
+ " arm-linux-androideabi" ,
49
50
" android/armeabi-v7a" ),
50
51
Toolchain (" arm64" ,
51
- ToolchainType .ANDROID ,
52
+ ToolchainType .ANDROID_GENERATED ,
53
+ " aarch64-linux-android" ,
54
+ " aarch64-linux-android" ,
52
55
" aarch64-linux-android" ,
53
- " bin/aarch64-linux-android-clang" ,
54
- " bin/aarch64-linux-android-ar" ,
55
56
" android/arm64-v8a" ),
56
57
Toolchain (" x86" ,
57
- ToolchainType .ANDROID ,
58
+ ToolchainType .ANDROID_GENERATED ,
59
+ " i686-linux-android" ,
60
+ " i686-linux-android" ,
58
61
" i686-linux-android" ,
59
- " bin/i686-linux-android-clang" ,
60
- " bin/i686-linux-android-ar" ,
61
62
" android/x86" ),
62
63
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" ,
64
91
" x86_64-linux-android" ,
65
- " bin/x86_64-linux-android-clang" ,
66
- " bin/x86_64-linux-android-ar" ,
67
92
" android/x86_64" )
68
93
)
69
94
70
95
data class Toolchain (val platform : String ,
71
96
val type : ToolchainType ,
72
97
val target : String ,
73
- val cc : String ,
74
- val ar : String ,
98
+ val compilerTriple : String ,
99
+ val binutilsTriple : String ,
75
100
val folder : String ) {
76
101
fun cc (apiLevel : Int ): File =
77
102
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
+ }
79
108
} 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
+ }
81
114
}
82
115
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
+ }
84
122
}
85
123
86
124
@Suppress(" unused" )
@@ -136,10 +174,33 @@ open class RustAndroidPlugin : Plugin<Project> {
136
174
sourceSets.getByName(" test" ).resources.srcDir(File (" $buildDir /rustJniLibs/desktop" ))
137
175
}
138
176
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
143
204
}
144
205
145
206
// Fish linker wrapper scripts from our Java resources.
@@ -167,7 +228,15 @@ open class RustAndroidPlugin : Plugin<Project> {
167
228
}
168
229
169
230
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 }
171
240
if (theToolchain == null ) {
172
241
throw GradleException (" Target ${target} is not recognized (recognized targets: ${toolchains.map { it.platform }.sorted()} ). Check `local.properties` and `build.gradle`." )
173
242
}
@@ -179,7 +248,9 @@ open class RustAndroidPlugin : Plugin<Project> {
179
248
toolchain = theToolchain
180
249
}
181
250
182
- targetBuildTask.dependsOn(generateToolchain)
251
+ if (! usePrebuilt) {
252
+ targetBuildTask.dependsOn(generateToolchain!! )
253
+ }
183
254
targetBuildTask.dependsOn(generateLinkerWrapper)
184
255
buildTask.dependsOn(targetBuildTask)
185
256
}
0 commit comments