|
7 | 7 | // apply from: "$rootDir/build-scripts/component-common.gradle" |
8 | 8 | // ``` |
9 | 9 |
|
| 10 | +import javax.inject.Inject |
10 | 11 |
|
11 | 12 | apply plugin: 'com.android.library' |
12 | 13 | apply plugin: 'kotlin-android' |
13 | 14 |
|
| 15 | +// Typed Exec subclass used in the moz-central build, where the embedded |
| 16 | +// uniffi-bindgen tool and the native megazord library are already built before |
| 17 | +// gradle runs. Exposes outputDir as a DirectoryProperty so the generated |
| 18 | +// sources can be wired into the variant via addGeneratedSourceDirectory. |
| 19 | +abstract class GenerateUniffiBindingsEmbedded extends Exec { |
| 20 | + @OutputDirectory |
| 21 | + abstract DirectoryProperty getOutputDir() |
| 22 | +} |
| 23 | + |
| 24 | +// Typed task used in the standalone app-services build, where the megazord |
| 25 | +// dynamic library is produced by a separate gradle task and only exists when |
| 26 | +// generateUniffiBindings runs (not at configuration time). |
| 27 | +abstract class GenerateUniffiBindingsCargo extends DefaultTask { |
| 28 | + @InputFiles |
| 29 | + abstract ConfigurableFileCollection getMegazordNativeFiles() |
| 30 | + |
| 31 | + @InputDirectory |
| 32 | + abstract DirectoryProperty getBindgenToolDir() |
| 33 | + |
| 34 | + @Input |
| 35 | + abstract Property<String> getCrateName() |
| 36 | + |
| 37 | + @Input |
| 38 | + abstract Property<String> getNativeRustTarget() |
| 39 | + |
| 40 | + @Internal |
| 41 | + abstract DirectoryProperty getWorkingDirectory() |
| 42 | + |
| 43 | + @OutputDirectory |
| 44 | + abstract DirectoryProperty getOutputDir() |
| 45 | + |
| 46 | + @Inject |
| 47 | + abstract ExecOperations getExecOperations() |
| 48 | + |
| 49 | + @TaskAction |
| 50 | + void run() { |
| 51 | + def libraryPath = megazordNativeFiles.asFileTree.matching { |
| 52 | + include "${nativeRustTarget.get()}/libmegazord.*" |
| 53 | + }.singleFile |
| 54 | + |
| 55 | + if (libraryPath == null) { |
| 56 | + throw new GradleException("libmegazord dynamic library path not found") |
| 57 | + } |
| 58 | + |
| 59 | + execOperations.exec { |
| 60 | + workingDir workingDirectory.get().asFile |
| 61 | + commandLine '/usr/bin/env', 'cargo', 'uniffi-bindgen', 'generate', |
| 62 | + '--crate', crateName.get(), '--language', 'kotlin', |
| 63 | + '--out-dir', outputDir.get().asFile, |
| 64 | + '--no-format', libraryPath |
| 65 | + } |
| 66 | + } |
| 67 | +} |
| 68 | + |
14 | 69 | android { |
15 | 70 | compileSdk { version = release(config.compileSdkMajorVersion) { minorApiLevel = config.compileSdkMinorVersion } } |
16 | 71 |
|
@@ -100,62 +155,41 @@ ext.configureUniFFIBindgen = { crateName -> |
100 | 155 | // This will store the uniffi-bindgen generated files for our component |
101 | 156 | def uniffiOutDir = layout.buildDirectory.dir("generated/uniffi/") |
102 | 157 |
|
103 | | - android { |
104 | | - sourceSets.main.kotlin.srcDirs += uniffiOutDir |
105 | | - } |
106 | | - |
107 | 158 | def generateUniffiBindings |
108 | 159 | // Call `uniffi-bindgen` to generate the Kotlin bindings |
109 | 160 | if (gradle.hasProperty("mozconfig")) { |
110 | 161 | // in moz-central we can use an `Exec` task because we can assume the bindgen tool has already been built. |
111 | | - generateUniffiBindings = tasks.register("generateUniffiBindings", Exec) { |
| 162 | + generateUniffiBindings = tasks.register("generateUniffiBindings", GenerateUniffiBindingsEmbedded) { |
112 | 163 | def libraryPath = "${gradle.mozconfig.topobjdir}/dist/bin/libmegazord.so" |
113 | 164 | def bindgen = gradle.ext.mozconfig.substs.EMBEDDED_UNIFFI_BINDGEN |
114 | 165 |
|
| 166 | + outputDir.set(uniffiOutDir) |
| 167 | + |
115 | 168 | workingDir project.rootDir |
116 | 169 | commandLine bindgen |
117 | | - args 'generate', "--crate", crateName, '--language', 'kotlin', '--out-dir', uniffiOutDir.get(), '--no-format', libraryPath |
| 170 | + args 'generate', "--crate", crateName, '--language', 'kotlin', '--out-dir', outputDir.get().asFile, '--no-format', libraryPath |
118 | 171 |
|
119 | | - outputs.dir uniffiOutDir |
120 | 172 | // Re-generate when the native megazord library is rebuilt |
121 | 173 | inputs.files libraryPath |
122 | 174 | // Re-generate if our uniffi-bindgen tooling changes. |
123 | 175 | inputs.files bindgen |
124 | 176 | } |
125 | 177 | } else { |
126 | | - // In app-services we can't use `Exec` because the megazord target isn't built yet, which we force via `doFirst` |
127 | | - generateUniffiBindings = tasks.register("generateUniffiBindings") { |
128 | | - def megazordNative = configurations.getByName("megazordNative") |
129 | | - doFirst { |
130 | | - def libraryPath = megazordNative.asFileTree.matching { |
131 | | - include "${nativeRustTarget}/libmegazord.*" |
132 | | - }.singleFile |
133 | | - |
134 | | - if (libraryPath == null) { |
135 | | - throw new GradleException("libmegazord dynamic library path not found") |
136 | | - } |
137 | | - exec { |
138 | | - workingDir project.rootDir |
139 | | - commandLine '/usr/bin/env', 'cargo', 'uniffi-bindgen', 'generate', "--crate", crateName, '--language', 'kotlin', '--out-dir', uniffiOutDir.get(), '--no-format', libraryPath |
140 | | - } |
141 | | - } |
142 | | - |
143 | | - outputs.dir uniffiOutDir |
144 | | - // Re-generate when the native megazord library is rebuilt |
145 | | - inputs.files megazordNative |
146 | | - // Re-generate if our uniffi-bindgen tooling changes. |
147 | | - inputs.dir "${project.appServicesRootDir}/tools/embedded-uniffi-bindgen/" |
| 178 | + // In app-services we can't use `Exec` because the megazord target isn't built yet; the task |
| 179 | + // resolves the library path from the megazordNative configuration when it runs. |
| 180 | + generateUniffiBindings = tasks.register("generateUniffiBindings", GenerateUniffiBindingsCargo) { |
| 181 | + // Qualify every property with `it.` because the `crateName` closure parameter shadows the |
| 182 | + // task's crateName property; a bare `crateName.set(...)` would target the String, not the task. |
| 183 | + it.megazordNativeFiles.from configurations.getByName("megazordNative") |
| 184 | + it.bindgenToolDir.set(file("${project.appServicesRootDir}/tools/embedded-uniffi-bindgen/")) |
| 185 | + it.crateName.set(crateName) |
| 186 | + it.nativeRustTarget.set(rootProject.ext.nativeRustTarget) |
| 187 | + it.workingDirectory.set(project.rootDir) |
| 188 | + it.outputDir.set(uniffiOutDir) |
148 | 189 | } |
149 | 190 | } |
150 | 191 |
|
151 | | - afterEvaluate { |
152 | | - def megazordNative = configurations.getByName("megazordNative") |
153 | | - android.libraryVariants.all { variant -> |
154 | | - def compileTask = tasks["compile${variant.name.capitalize()}Kotlin"] |
155 | | - compileTask.dependsOn(generateUniffiBindings) |
156 | | - if (!gradle.hasProperty("mozconfig")) { |
157 | | - variant.registerJavaGeneratingTask(generateUniffiBindings, megazordNative.singleFile) |
158 | | - } |
159 | | - } |
| 192 | + androidComponents.onVariants(androidComponents.selector().all()) { variant -> |
| 193 | + variant.sources.java.addGeneratedSourceDirectory(generateUniffiBindings) { it.outputDir } |
160 | 194 | } |
161 | 195 | } |
0 commit comments