github.com/westcoastroms/westcoastroms-build@v0.0.0-20190928114312-2350e5a73030/build/soong/java/aar.go (about) 1 // Copyright 2018 Google Inc. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package java 16 17 import ( 18 "android/soong/android" 19 "strings" 20 21 "github.com/google/blueprint" 22 "github.com/google/blueprint/proptools" 23 ) 24 25 type AndroidLibraryDependency interface { 26 Dependency 27 ExportPackage() android.Path 28 ExportedProguardFlagFiles() android.Paths 29 ExportedStaticPackages() android.Paths 30 } 31 32 func init() { 33 android.RegisterModuleType("android_library_import", AARImportFactory) 34 android.RegisterModuleType("android_library", AndroidLibraryFactory) 35 } 36 37 // 38 // AAR (android library) 39 // 40 41 type androidLibraryProperties struct { 42 BuildAAR bool `blueprint:"mutated"` 43 } 44 45 type aaptProperties struct { 46 // flags passed to aapt when creating the apk 47 Aaptflags []string 48 49 // list of directories relative to the Blueprints file containing assets. 50 // Defaults to "assets" 51 Asset_dirs []string 52 53 // list of directories relative to the Blueprints file containing 54 // Android resources 55 Resource_dirs []string 56 57 // path to AndroidManifest.xml. If unset, defaults to "AndroidManifest.xml". 58 Manifest *string 59 } 60 61 type aapt struct { 62 aaptSrcJar android.Path 63 exportPackage android.Path 64 manifestPath android.Path 65 proguardOptionsFile android.Path 66 rroDirs android.Paths 67 rTxt android.Path 68 extraAaptPackagesFile android.Path 69 70 aaptProperties aaptProperties 71 } 72 73 func (a *aapt) ExportPackage() android.Path { 74 return a.exportPackage 75 } 76 77 func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkVersion string) (flags []string, deps android.Paths, 78 resDirs, overlayDirs []globbedResourceDir, overlayFiles, rroDirs android.Paths, manifestPath android.Path) { 79 80 hasVersionCode := false 81 hasVersionName := false 82 for _, f := range a.aaptProperties.Aaptflags { 83 if strings.HasPrefix(f, "--version-code") { 84 hasVersionCode = true 85 } else if strings.HasPrefix(f, "--version-name") { 86 hasVersionName = true 87 } 88 } 89 90 var linkFlags []string 91 92 // Flags specified in Android.bp 93 linkFlags = append(linkFlags, a.aaptProperties.Aaptflags...) 94 95 linkFlags = append(linkFlags, "--no-static-lib-packages") 96 97 // Find implicit or explicit asset and resource dirs 98 assetDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Asset_dirs, "assets") 99 resourceDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Resource_dirs, "res") 100 101 var linkDeps android.Paths 102 103 // Glob directories into lists of paths 104 for _, dir := range resourceDirs { 105 resDirs = append(resDirs, globbedResourceDir{ 106 dir: dir, 107 files: androidResourceGlob(ctx, dir), 108 }) 109 resOverlayDirs, resRRODirs := overlayResourceGlob(ctx, dir) 110 overlayDirs = append(overlayDirs, resOverlayDirs...) 111 rroDirs = append(rroDirs, resRRODirs...) 112 } 113 114 var assetFiles android.Paths 115 for _, dir := range assetDirs { 116 assetFiles = append(assetFiles, androidResourceGlob(ctx, dir)...) 117 } 118 119 // App manifest file 120 manifestFile := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml") 121 manifestPath = android.PathForModuleSrc(ctx, manifestFile) 122 linkFlags = append(linkFlags, "--manifest "+manifestPath.String()) 123 linkDeps = append(linkDeps, manifestPath) 124 125 linkFlags = append(linkFlags, android.JoinWithPrefix(assetDirs.Strings(), "-A ")) 126 linkDeps = append(linkDeps, assetFiles...) 127 128 transitiveStaticLibs, libDeps, libFlags := aaptLibs(ctx, sdkVersion) 129 130 overlayFiles = append(overlayFiles, transitiveStaticLibs...) 131 linkDeps = append(linkDeps, libDeps...) 132 linkFlags = append(linkFlags, libFlags...) 133 134 // SDK version flags 135 switch sdkVersion { 136 case "", "current", "system_current", "test_current": 137 sdkVersion = proptools.NinjaEscape([]string{ctx.Config().DefaultAppTargetSdk()})[0] 138 } 139 140 linkFlags = append(linkFlags, "--min-sdk-version "+sdkVersion) 141 linkFlags = append(linkFlags, "--target-sdk-version "+sdkVersion) 142 143 // Version code 144 if !hasVersionCode { 145 linkFlags = append(linkFlags, "--version-code", ctx.Config().PlatformSdkVersion()) 146 } 147 148 if !hasVersionName { 149 var versionName string 150 if ctx.ModuleName() == "framework-res" { 151 // Some builds set AppsDefaultVersionName() to include the build number ("O-123456"). aapt2 copies the 152 // version name of framework-res into app manifests as compileSdkVersionCodename, which confuses things 153 // if it contains the build number. Use the PlatformVersionName instead. 154 versionName = ctx.Config().PlatformVersionName() 155 } else { 156 versionName = ctx.Config().AppsDefaultVersionName() 157 } 158 versionName = proptools.NinjaEscape([]string{versionName})[0] 159 linkFlags = append(linkFlags, "--version-name ", versionName) 160 } 161 162 return linkFlags, linkDeps, resDirs, overlayDirs, overlayFiles, rroDirs, manifestPath 163 } 164 165 func (a *aapt) deps(ctx android.BottomUpMutatorContext, sdkVersion string) { 166 if !ctx.Config().UnbundledBuild() { 167 sdkDep := decodeSdkDep(ctx, sdkVersion) 168 if sdkDep.frameworkResModule != "" { 169 ctx.AddDependency(ctx.Module(), frameworkResTag, sdkDep.frameworkResModule) 170 } 171 } 172 } 173 174 func (a *aapt) buildActions(ctx android.ModuleContext, sdkVersion string, extraLinkFlags ...string) { 175 linkFlags, linkDeps, resDirs, overlayDirs, overlayFiles, rroDirs, manifestPath := a.aapt2Flags(ctx, sdkVersion) 176 177 linkFlags = append(linkFlags, extraLinkFlags...) 178 179 packageRes := android.PathForModuleOut(ctx, "package-res.apk") 180 srcJar := android.PathForModuleGen(ctx, "R.jar") 181 proguardOptionsFile := android.PathForModuleGen(ctx, "proguard.options") 182 rTxt := android.PathForModuleOut(ctx, "R.txt") 183 // This file isn't used by Soong, but is generated for exporting 184 extraPackages := android.PathForModuleOut(ctx, "extra_packages") 185 186 var compiledRes, compiledOverlay android.Paths 187 for _, dir := range resDirs { 188 compiledRes = append(compiledRes, aapt2Compile(ctx, dir.dir, dir.files).Paths()...) 189 } 190 for _, dir := range overlayDirs { 191 compiledOverlay = append(compiledOverlay, aapt2Compile(ctx, dir.dir, dir.files).Paths()...) 192 } 193 194 compiledOverlay = append(compiledOverlay, overlayFiles...) 195 196 aapt2Link(ctx, packageRes, srcJar, proguardOptionsFile, rTxt, extraPackages, 197 linkFlags, linkDeps, compiledRes, compiledOverlay) 198 199 a.aaptSrcJar = srcJar 200 a.exportPackage = packageRes 201 a.manifestPath = manifestPath 202 a.proguardOptionsFile = proguardOptionsFile 203 a.rroDirs = rroDirs 204 a.extraAaptPackagesFile = extraPackages 205 a.rTxt = rTxt 206 } 207 208 // aaptLibs collects libraries from dependencies and sdk_version and converts them into paths 209 func aaptLibs(ctx android.ModuleContext, sdkVersion string) (transitiveStaticLibs, deps android.Paths, 210 flags []string) { 211 212 var sharedLibs android.Paths 213 214 sdkDep := decodeSdkDep(ctx, sdkVersion) 215 if sdkDep.useFiles { 216 sharedLibs = append(sharedLibs, sdkDep.jar) 217 } 218 219 ctx.VisitDirectDeps(func(module android.Module) { 220 var exportPackage android.Path 221 aarDep, _ := module.(AndroidLibraryDependency) 222 if aarDep != nil { 223 exportPackage = aarDep.ExportPackage() 224 } 225 226 switch ctx.OtherModuleDependencyTag(module) { 227 case libTag, frameworkResTag: 228 if exportPackage != nil { 229 sharedLibs = append(sharedLibs, exportPackage) 230 } 231 case staticLibTag: 232 if exportPackage != nil { 233 transitiveStaticLibs = append(transitiveStaticLibs, exportPackage) 234 transitiveStaticLibs = append(transitiveStaticLibs, aarDep.ExportedStaticPackages()...) 235 } 236 } 237 }) 238 239 deps = append(deps, sharedLibs...) 240 deps = append(deps, transitiveStaticLibs...) 241 242 if len(transitiveStaticLibs) > 0 { 243 flags = append(flags, "--auto-add-overlay") 244 } 245 246 for _, sharedLib := range sharedLibs { 247 flags = append(flags, "-I "+sharedLib.String()) 248 } 249 250 transitiveStaticLibs = android.FirstUniquePaths(transitiveStaticLibs) 251 252 return transitiveStaticLibs, deps, flags 253 } 254 255 type AndroidLibrary struct { 256 Library 257 aapt 258 259 androidLibraryProperties androidLibraryProperties 260 261 aarFile android.WritablePath 262 263 exportedProguardFlagFiles android.Paths 264 exportedStaticPackages android.Paths 265 } 266 267 func (a *AndroidLibrary) ExportedProguardFlagFiles() android.Paths { 268 return a.exportedProguardFlagFiles 269 } 270 271 func (a *AndroidLibrary) ExportedStaticPackages() android.Paths { 272 return a.exportedStaticPackages 273 } 274 275 var _ AndroidLibraryDependency = (*AndroidLibrary)(nil) 276 277 func (a *AndroidLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { 278 a.Module.deps(ctx) 279 if !Bool(a.properties.No_framework_libs) && !Bool(a.properties.No_standard_libs) { 280 a.aapt.deps(ctx, String(a.deviceProperties.Sdk_version)) 281 } 282 } 283 284 func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { 285 a.aapt.buildActions(ctx, String(a.deviceProperties.Sdk_version), "--static-lib") 286 287 ctx.CheckbuildFile(a.proguardOptionsFile) 288 ctx.CheckbuildFile(a.exportPackage) 289 ctx.CheckbuildFile(a.aaptSrcJar) 290 291 // apps manifests are handled by aapt, don't let Module see them 292 a.properties.Manifest = nil 293 294 a.Module.extraProguardFlagFiles = append(a.Module.extraProguardFlagFiles, 295 a.proguardOptionsFile) 296 297 a.Module.compile(ctx, a.aaptSrcJar) 298 299 a.aarFile = android.PathForOutput(ctx, ctx.ModuleName()+".aar") 300 var res android.Paths 301 if a.androidLibraryProperties.BuildAAR { 302 BuildAAR(ctx, a.aarFile, a.outputFile, a.manifestPath, a.rTxt, res) 303 ctx.CheckbuildFile(a.aarFile) 304 } 305 306 ctx.VisitDirectDeps(func(m android.Module) { 307 if lib, ok := m.(AndroidLibraryDependency); ok && ctx.OtherModuleDependencyTag(m) == staticLibTag { 308 a.exportedProguardFlagFiles = append(a.exportedProguardFlagFiles, lib.ExportedProguardFlagFiles()...) 309 a.exportedStaticPackages = append(a.exportedStaticPackages, lib.ExportPackage()) 310 a.exportedStaticPackages = append(a.exportedStaticPackages, lib.ExportedStaticPackages()...) 311 } 312 }) 313 314 a.exportedProguardFlagFiles = android.FirstUniquePaths(a.exportedProguardFlagFiles) 315 a.exportedStaticPackages = android.FirstUniquePaths(a.exportedStaticPackages) 316 } 317 318 func AndroidLibraryFactory() android.Module { 319 module := &AndroidLibrary{} 320 321 module.AddProperties( 322 &module.Module.properties, 323 &module.Module.deviceProperties, 324 &module.Module.protoProperties, 325 &module.aaptProperties, 326 &module.androidLibraryProperties) 327 328 module.androidLibraryProperties.BuildAAR = true 329 330 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon) 331 return module 332 } 333 334 // 335 // AAR (android library) prebuilts 336 // 337 338 type AARImportProperties struct { 339 Aars []string 340 341 Sdk_version *string 342 343 Static_libs []string 344 Libs []string 345 } 346 347 type AARImport struct { 348 android.ModuleBase 349 prebuilt android.Prebuilt 350 351 properties AARImportProperties 352 353 classpathFile android.WritablePath 354 proguardFlags android.WritablePath 355 exportPackage android.WritablePath 356 extraAaptPackagesFile android.WritablePath 357 358 exportedStaticPackages android.Paths 359 } 360 361 var _ AndroidLibraryDependency = (*AARImport)(nil) 362 363 func (a *AARImport) ExportPackage() android.Path { 364 return a.exportPackage 365 } 366 367 func (a *AARImport) ExportedProguardFlagFiles() android.Paths { 368 return android.Paths{a.proguardFlags} 369 } 370 371 func (a *AARImport) ExportedStaticPackages() android.Paths { 372 return a.exportedStaticPackages 373 } 374 375 func (a *AARImport) Prebuilt() *android.Prebuilt { 376 return &a.prebuilt 377 } 378 379 func (a *AARImport) Name() string { 380 return a.prebuilt.Name(a.ModuleBase.Name()) 381 } 382 383 func (a *AARImport) DepsMutator(ctx android.BottomUpMutatorContext) { 384 if !ctx.Config().UnbundledBuild() { 385 sdkDep := decodeSdkDep(ctx, String(a.properties.Sdk_version)) 386 if sdkDep.useModule && sdkDep.frameworkResModule != "" { 387 ctx.AddDependency(ctx.Module(), frameworkResTag, sdkDep.frameworkResModule) 388 } 389 } 390 391 ctx.AddDependency(ctx.Module(), libTag, a.properties.Libs...) 392 ctx.AddDependency(ctx.Module(), staticLibTag, a.properties.Static_libs...) 393 } 394 395 // Unzip an AAR into its constituent files and directories. Any files in Outputs that don't exist in the AAR will be 396 // touched to create an empty file, and any directories in $expectedDirs will be created. 397 var unzipAAR = pctx.AndroidStaticRule("unzipAAR", 398 blueprint.RuleParams{ 399 Command: `rm -rf $outDir && mkdir -p $outDir $expectedDirs && ` + 400 `unzip -qo -d $outDir $in && touch $out`, 401 }, 402 "expectedDirs", "outDir") 403 404 func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { 405 if len(a.properties.Aars) != 1 { 406 ctx.PropertyErrorf("aars", "exactly one aar is required") 407 return 408 } 409 410 aar := android.PathForModuleSrc(ctx, a.properties.Aars[0]) 411 412 extractedAARDir := android.PathForModuleOut(ctx, "aar") 413 extractedResDir := extractedAARDir.Join(ctx, "res") 414 a.classpathFile = extractedAARDir.Join(ctx, "classes.jar") 415 a.proguardFlags = extractedAARDir.Join(ctx, "proguard.txt") 416 manifest := extractedAARDir.Join(ctx, "AndroidManifest.xml") 417 418 ctx.Build(pctx, android.BuildParams{ 419 Rule: unzipAAR, 420 Input: aar, 421 Outputs: android.WritablePaths{a.classpathFile, a.proguardFlags, manifest}, 422 Description: "unzip AAR", 423 Args: map[string]string{ 424 "expectedDirs": extractedResDir.String(), 425 "outDir": extractedAARDir.String(), 426 }, 427 }) 428 429 compiledResDir := android.PathForModuleOut(ctx, "flat-res") 430 aaptCompileDeps := android.Paths{a.classpathFile} 431 aaptCompileDirs := android.Paths{extractedResDir} 432 flata := compiledResDir.Join(ctx, "gen_res.flata") 433 aapt2CompileDirs(ctx, flata, aaptCompileDirs, aaptCompileDeps) 434 435 a.exportPackage = android.PathForModuleOut(ctx, "package-res.apk") 436 srcJar := android.PathForModuleGen(ctx, "R.jar") 437 proguardOptionsFile := android.PathForModuleGen(ctx, "proguard.options") 438 rTxt := android.PathForModuleOut(ctx, "R.txt") 439 a.extraAaptPackagesFile = android.PathForModuleOut(ctx, "extra_packages") 440 441 var linkDeps android.Paths 442 443 linkFlags := []string{ 444 "--static-lib", 445 "--no-static-lib-packages", 446 "--auto-add-overlay", 447 } 448 449 linkFlags = append(linkFlags, "--manifest "+manifest.String()) 450 linkDeps = append(linkDeps, manifest) 451 452 transitiveStaticLibs, libDeps, libFlags := aaptLibs(ctx, String(a.properties.Sdk_version)) 453 454 linkDeps = append(linkDeps, libDeps...) 455 linkFlags = append(linkFlags, libFlags...) 456 457 overlayRes := append(android.Paths{flata}, transitiveStaticLibs...) 458 459 aapt2Link(ctx, a.exportPackage, srcJar, proguardOptionsFile, rTxt, a.extraAaptPackagesFile, 460 linkFlags, linkDeps, nil, overlayRes) 461 } 462 463 var _ Dependency = (*AARImport)(nil) 464 465 func (a *AARImport) HeaderJars() android.Paths { 466 return android.Paths{a.classpathFile} 467 } 468 469 func (a *AARImport) ImplementationJars() android.Paths { 470 return android.Paths{a.classpathFile} 471 } 472 473 func (a *AARImport) AidlIncludeDirs() android.Paths { 474 return nil 475 } 476 477 var _ android.PrebuiltInterface = (*Import)(nil) 478 479 func AARImportFactory() android.Module { 480 module := &AARImport{} 481 482 module.AddProperties(&module.properties) 483 484 android.InitPrebuiltModule(module, &module.properties.Aars) 485 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon) 486 return module 487 }