diff options
author | Fisher Jomo <jomof@google.com> | 2022-08-08 12:20:08 -0700 |
---|---|---|
committer | Jomo Fisher <jomof@google.com> | 2022-08-12 16:09:48 +0000 |
commit | 8090bf0678955633c7a814c4692d465c4bb5e107 (patch) | |
tree | 974fbf0fd806dc9d9fa8751f140601cbbdfdd62f | |
parent | 85fd94b00a0683d918639857264fd71e94243ce7 (diff) | |
download | base-8090bf0678955633c7a814c4692d465c4bb5e107.tar.gz |
Unblock AndroidX integration: add prefab exportLibraries
AndroidX build has been using a hack to modify Prefab module.json
in-flight to add linker flags. That hack doesn't work after recent
changes to fix order-of-configure issues.
This CL adds an experimental flag that users can use to properly
set export libraries:
android
.externalNativeBuild
.experimentalProperties["prefab.foo.exportLibraries"] =
["-lfoo"]
This would eventually map to this DSL during the actual work for
b/214034366:
prefab {
foo {
exportLibraries = ["-lfoo"]
}
}
Bug: 214034366
Test: Added integration test
Change-Id: I4bbd5ff9711f2a25c386bee5d7b390091aad4fe4
5 files changed, 69 insertions, 5 deletions
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/cxx/configure/ExperimentalPropertyExtensions.kt b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/cxx/configure/ExperimentalPropertyExtensions.kt index 696e515ba3..2783c47390 100644 --- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/cxx/configure/ExperimentalPropertyExtensions.kt +++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/cxx/configure/ExperimentalPropertyExtensions.kt @@ -121,9 +121,42 @@ private fun Map<String, Any>.propertyAsSet(name : String) : Set<String> { */ private fun Map<String, Any>.propertyAsList(name : String) : List<String> { val value = get(name) ?: return listOf() + return propertyValueAsList(value) +} + +/** + * Convert [Any] from Gradle DSL to a List<String>. + */ +private fun propertyValueAsList(value : Any) : List<String> { return when (value) { is List<*> -> value.map { "$it" } is Set<*> -> value.map { "$it" } - else -> error("${value.javaClass}") + else -> error("Could not convert from ${value.javaClass} to List<String>") + } +} + +/** + * This is the experimental flag analog of [com.android.build.api.dsl.PrefabPackagingOptions]. + */ +data class PrefabExperimentalPackagingOptions( + /** + * export_libraries may specify either literal arguments to be used as-is, intra-package + * references, or inter-package references. This field is optional. + */ + val exportLibraries : List<String>? +) + +/** + * Retrieve user's experimental settings for an individual Prefab publishing module. + */ +fun VariantCreationConfig.getPrefabExperimentalPackagingOptions(module : String) + : PrefabExperimentalPackagingOptions { + var exportLibraries : List<String>? = null + for((key, value) in externalNativeExperimentalProperties) { + if (key != "prefab.${module}.exportLibraries") continue + exportLibraries = propertyValueAsList(value) } + return PrefabExperimentalPackagingOptions( + exportLibraries = exportLibraries + ) } diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/cxx/prefab/CreatePublicationModel.kt b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/cxx/prefab/CreatePublicationModel.kt index 9230edb2fc..4dda257ecf 100644 --- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/cxx/prefab/CreatePublicationModel.kt +++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/cxx/prefab/CreatePublicationModel.kt @@ -17,6 +17,7 @@ package com.android.build.gradle.internal.cxx.prefab import com.android.build.gradle.internal.component.LibraryCreationConfig +import com.android.build.gradle.internal.cxx.configure.getPrefabExperimentalPackagingOptions import com.android.build.gradle.internal.cxx.gradle.generator.CxxConfigurationModel import com.android.build.gradle.internal.cxx.logging.errorln import com.android.build.gradle.internal.cxx.model.jsonFile @@ -37,6 +38,7 @@ fun createPrefabPublication( configurationModel: CxxConfigurationModel, libraryVariant : LibraryCreationConfig ) : PrefabPublication { + val abis = configurationModel.activeAbis.map { abi -> PrefabAbiPublication( abiName = abi.abi.tag, @@ -48,12 +50,15 @@ fun createPrefabPublication( ) } val modules = libraryVariant.global.prefab.map { options -> + val experimentalSettings = libraryVariant.getPrefabExperimentalPackagingOptions(options.name) + PrefabModulePublication( moduleName = options.name, moduleLibraryName = options.libraryName, moduleHeaders = options.headers?.let { headers -> libraryVariant.services.projectInfo.projectDirectory.dir(headers).asFile.absoluteFile }, + moduleExportLibraries = experimentalSettings.exportLibraries ?: listOf(), abis = abis ) } diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/cxx/prefab/PackageBuilder.kt b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/cxx/prefab/PackageBuilder.kt index c3d79f9d37..98acb5a911 100644 --- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/cxx/prefab/PackageBuilder.kt +++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/cxx/prefab/PackageBuilder.kt @@ -141,7 +141,7 @@ private class PrefabPackageBuilder( writeJsonFileIfDifferent( moduleDir.resolve("module.json"), ModuleMetadataV1( - exportLibraries = emptyList(), + exportLibraries = module.moduleExportLibraries, libraryName = module.moduleLibraryName ) ) diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/cxx/prefab/PublicationModel.kt b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/cxx/prefab/PublicationModel.kt index d3055f4d5a..bc21b41dd7 100644 --- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/cxx/prefab/PublicationModel.kt +++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/cxx/prefab/PublicationModel.kt @@ -68,6 +68,9 @@ data class PrefabModulePublication( val moduleHeaders : File?, @get:Input @get:Optional + val moduleExportLibraries : List<String>, + @get:Input + @get:Optional val moduleLibraryName : String?, @get:Nested val abis : List<PrefabAbiPublication> diff --git a/build-system/integration-test/native/src/test/java/com/android/build/gradle/integration/ndk/ModuleToModuleDepsTest.kt b/build-system/integration-test/native/src/test/java/com/android/build/gradle/integration/ndk/ModuleToModuleDepsTest.kt index b0d76e3f3c..ac70ef8940 100644 --- a/build-system/integration-test/native/src/test/java/com/android/build/gradle/integration/ndk/ModuleToModuleDepsTest.kt +++ b/build-system/integration-test/native/src/test/java/com/android/build/gradle/integration/ndk/ModuleToModuleDepsTest.kt @@ -31,9 +31,11 @@ import com.android.build.gradle.integration.ndk.ModuleToModuleDepsTest.BuildSyst import com.android.build.gradle.internal.core.Abi import com.android.build.gradle.internal.cxx.configure.CMakeVersion import com.android.build.gradle.internal.cxx.json.AndroidBuildGradleJsons +import com.android.build.gradle.internal.cxx.json.readJsonFile import com.android.build.gradle.internal.cxx.logging.LoggingMessage import com.android.build.gradle.internal.cxx.logging.decodeLoggingMessage import com.android.build.gradle.internal.cxx.logging.text +import com.android.build.gradle.internal.cxx.prefab.ModuleMetadataV1 import com.android.builder.model.v2.ide.SyncIssue import com.google.common.truth.Truth.assertThat import org.junit.Assume @@ -109,11 +111,18 @@ class ModuleToModuleDepsTest( .dependency(app, lib) .build() + private val appOutputRoot : File get() = + if (outputStructureType == OutputStructureType.Normal) project.getSubproject("app").buildDir.parentFile + else { + // The output folder for lib is at $PROJECT_ROOT/out/lib + project.getSubproject("app").buildDir.parentFile.parentFile.resolve("out/app") + } + private val libOutputRoot : File get() = if (outputStructureType == OutputStructureType.Normal) project.getSubproject("lib").buildDir.parentFile else { // The output folder for lib is at $PROJECT_ROOT/out/lib - project.getSubproject("lib").buildDir.parentFile.parentFile.parentFile.resolve("out/lib") + project.getSubproject("lib").buildDir.parentFile.parentFile.resolve("out/lib") } @get:Rule @@ -172,7 +181,6 @@ class ModuleToModuleDepsTest( .buildFile .parentFile .parentFile - .parentFile .absolutePath.replace("\\", "/") val appStructureStanza = if (outputStructureType == OutputStructureType.Normal) "" else when(appBuildSystem) { is CMake -> """ @@ -196,6 +204,8 @@ class ModuleToModuleDepsTest( """.trimIndent() else -> error("$appBuildSystem") } + val libExportLibrariesStanza = + "android.externalNativeBuild.experimentalProperties[\"prefab.foo.exportLibraries\"] = [\"-llog\"]" project.getSubproject(":app").buildFile.appendText( """ @@ -263,6 +273,7 @@ class ModuleToModuleDepsTest( $libStanza $libStlStanza $libStructureStanza + $libExportLibrariesStanza """) val header = project.getSubproject(":lib").buildFile.resolveSibling("src/main/cpp/include/foo.h") @@ -354,7 +365,6 @@ class ModuleToModuleDepsTest( int callFoo() { return foo(); } """.trimIndent()) } - enableCxxStructuredLogging(project) } @@ -470,6 +480,19 @@ class ModuleToModuleDepsTest( assertThat(libOutput.isFile) .named("$libOutput") .isFalse() + + // Check that export libraries informations winds up in the final prefab structure + var sawAtleastOneModule = false + appOutputRoot.walkTopDown().forEach { file -> + if (file.name == "module.json") { + val module = readJsonFile<ModuleMetadataV1>(file) + assertThat(module.exportLibraries).containsExactly("-llog") + sawAtleastOneModule = true + } + } + assertThat(sawAtleastOneModule) + .named("Expected at least one Prefab module") + .isTrue() } @Test |