1// Copyright 2015 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 15package cc 16 17import ( 18 "fmt" 19 "io" 20 "path/filepath" 21 "strings" 22 23 "android/soong/android" 24) 25 26var ( 27 NativeBridgeSuffix = ".native_bridge" 28 ProductSuffix = ".product" 29 VendorSuffix = ".vendor" 30 RamdiskSuffix = ".ramdisk" 31 VendorRamdiskSuffix = ".vendor_ramdisk" 32 RecoverySuffix = ".recovery" 33 sdkSuffix = ".sdk" 34) 35 36type AndroidMkContext interface { 37 BaseModuleName() string 38 Target() android.Target 39 subAndroidMk(android.Config, *android.AndroidMkInfo, interface{}) 40 Arch() android.Arch 41 Os() android.OsType 42 Host() bool 43 UseVndk() bool 44 VndkVersion() string 45 static() bool 46 InRamdisk() bool 47 InVendorRamdisk() bool 48 InRecovery() bool 49 NotInPlatform() bool 50 InVendorOrProduct() bool 51 ArchSpecific() bool 52} 53 54type subAndroidMkProviderInfoProducer interface { 55 prepareAndroidMKProviderInfo(android.Config, AndroidMkContext, *android.AndroidMkInfo) 56} 57 58type subAndroidMkFooterInfoProducer interface { 59 prepareAndroidMKFooterInfo(android.Config, AndroidMkContext, *android.AndroidMkInfo) 60} 61 62func (c *Module) subAndroidMk(config android.Config, entries *android.AndroidMkInfo, obj interface{}) { 63 if c.subAndroidMkOnce == nil { 64 c.subAndroidMkOnce = make(map[subAndroidMkProviderInfoProducer]bool) 65 } 66 if androidmk, ok := obj.(subAndroidMkProviderInfoProducer); ok { 67 if !c.subAndroidMkOnce[androidmk] { 68 c.subAndroidMkOnce[androidmk] = true 69 androidmk.prepareAndroidMKProviderInfo(config, c, entries) 70 } 71 } 72} 73 74var _ android.AndroidMkProviderInfoProducer = (*Module)(nil) 75 76func (c *Module) PrepareAndroidMKProviderInfo(config android.Config) *android.AndroidMkProviderInfo { 77 if c.hideApexVariantFromMake || c.Properties.HideFromMake { 78 return &android.AndroidMkProviderInfo{ 79 PrimaryInfo: android.AndroidMkInfo{ 80 Disabled: true, 81 }, 82 } 83 } 84 85 providerData := android.AndroidMkProviderInfo{ 86 PrimaryInfo: android.AndroidMkInfo{ 87 OutputFile: c.outputFile, 88 Required: c.Properties.AndroidMkRuntimeLibs, 89 OverrideName: c.BaseModuleName(), 90 Include: "$(BUILD_SYSTEM)/soong_cc_rust_prebuilt.mk", 91 EntryMap: make(map[string][]string), 92 }, 93 } 94 95 entries := &providerData.PrimaryInfo 96 if len(c.Properties.Logtags) > 0 { 97 entries.AddStrings("LOCAL_SOONG_LOGTAGS_FILES", c.logtagsPaths.Strings()...) 98 } 99 // Note: Pass the exact value of AndroidMkSystemSharedLibs to the Make 100 // world, even if it is an empty list. In the Make world, 101 // LOCAL_SYSTEM_SHARED_LIBRARIES defaults to "none", which is expanded 102 // to the default list of system shared libs by the build system. 103 // Soong computes the exact list of system shared libs, so we have to 104 // override the default value when the list of libs is actually empty. 105 entries.SetString("LOCAL_SYSTEM_SHARED_LIBRARIES", strings.Join(c.Properties.AndroidMkSystemSharedLibs, " ")) 106 if len(c.Properties.AndroidMkSharedLibs) > 0 { 107 entries.AddStrings("LOCAL_SHARED_LIBRARIES", c.Properties.AndroidMkSharedLibs...) 108 } 109 if len(c.Properties.AndroidMkRuntimeLibs) > 0 { 110 entries.AddStrings("LOCAL_RUNTIME_LIBRARIES", c.Properties.AndroidMkRuntimeLibs...) 111 } 112 entries.SetString("LOCAL_SOONG_LINK_TYPE", c.makeLinkType) 113 if c.InVendor() { 114 entries.SetBool("LOCAL_IN_VENDOR", true) 115 } else if c.InProduct() { 116 entries.SetBool("LOCAL_IN_PRODUCT", true) 117 } 118 if c.Properties.SdkAndPlatformVariantVisibleToMake { 119 // Add the unsuffixed name to SOONG_SDK_VARIANT_MODULES so that Make can rewrite 120 // dependencies to the .sdk suffix when building a module that uses the SDK. 121 entries.SetString("SOONG_SDK_VARIANT_MODULES", 122 "$(SOONG_SDK_VARIANT_MODULES) $(patsubst %.sdk,%,$(LOCAL_MODULE))") 123 } 124 entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", c.IsSkipInstall()) 125 126 for _, feature := range c.features { 127 c.subAndroidMk(config, entries, feature) 128 } 129 130 c.subAndroidMk(config, entries, c.compiler) 131 c.subAndroidMk(config, entries, c.linker) 132 if c.sanitize != nil { 133 c.subAndroidMk(config, entries, c.sanitize) 134 } 135 c.subAndroidMk(config, entries, c.installer) 136 137 entries.SubName += c.Properties.SubName 138 139 // The footer info comes at the last step, previously it was achieved by 140 // calling some extra footer function that were added earlier. Because we no 141 // longer use these extra footer functions, we need to put this step at the 142 // last one. 143 if c.Properties.IsSdkVariant && c.Properties.SdkAndPlatformVariantVisibleToMake && 144 c.CcLibraryInterface() && c.Shared() { 145 // Using the SDK variant as a JNI library needs a copy of the .so that 146 // is not named .sdk.so so that it can be packaged into the APK with 147 // the right name. 148 entries.FooterStrings = []string{ 149 fmt.Sprintf("%s %s %s", "$(eval $(call copy-one-file,", 150 "$(LOCAL_BUILT_MODULE),", 151 "$(patsubst %.sdk.so,%.so,$(LOCAL_BUILT_MODULE))))")} 152 } 153 154 for _, obj := range []interface{}{c.compiler, c.linker, c.sanitize, c.installer} { 155 if obj == nil { 156 continue 157 } 158 if p, ok := obj.(subAndroidMkFooterInfoProducer); ok { 159 p.prepareAndroidMKFooterInfo(config, c, entries) 160 } 161 } 162 163 return &providerData 164} 165 166func androidMkWriteExtraTestConfigs(extraTestConfigs android.Paths, entries *android.AndroidMkInfo) { 167 if len(extraTestConfigs) > 0 { 168 entries.AddStrings("LOCAL_EXTRA_FULL_TEST_CONFIGS", extraTestConfigs.Strings()...) 169 } 170} 171 172func makeOverrideModuleNames(ctx AndroidMkContext, overrides []string) []string { 173 if ctx.Target().NativeBridge == android.NativeBridgeEnabled { 174 var result []string 175 for _, override := range overrides { 176 result = append(result, override+NativeBridgeSuffix) 177 } 178 return result 179 } 180 181 return overrides 182} 183 184func (library *libraryDecorator) androidMkWriteExportedFlags(entries *android.AndroidMkInfo) { 185 var exportedFlags []string 186 var includeDirs android.Paths 187 var systemIncludeDirs android.Paths 188 var exportedDeps android.Paths 189 190 if library.flagExporterInfo != nil { 191 exportedFlags = library.flagExporterInfo.Flags 192 includeDirs = library.flagExporterInfo.IncludeDirs 193 systemIncludeDirs = library.flagExporterInfo.SystemIncludeDirs 194 exportedDeps = library.flagExporterInfo.Deps 195 } else { 196 exportedFlags = library.flagExporter.flags 197 includeDirs = library.flagExporter.dirs 198 systemIncludeDirs = library.flagExporter.systemDirs 199 exportedDeps = library.flagExporter.deps 200 } 201 for _, dir := range includeDirs { 202 exportedFlags = append(exportedFlags, "-I"+dir.String()) 203 } 204 for _, dir := range systemIncludeDirs { 205 exportedFlags = append(exportedFlags, "-isystem "+dir.String()) 206 } 207 if len(exportedFlags) > 0 { 208 entries.AddStrings("LOCAL_EXPORT_CFLAGS", exportedFlags...) 209 } 210 if len(exportedDeps) > 0 { 211 entries.AddStrings("LOCAL_EXPORT_C_INCLUDE_DEPS", exportedDeps.Strings()...) 212 } 213} 214 215func (library *libraryDecorator) androidMkEntriesWriteAdditionalDependenciesForSourceAbiDiff(entries *android.AndroidMkInfo) { 216 if !library.static() { 217 entries.AddPaths("LOCAL_ADDITIONAL_DEPENDENCIES", library.sAbiDiff) 218 } 219} 220 221// TODO(ccross): remove this once apex/androidmk.go is converted to AndroidMkEntries 222func (library *libraryDecorator) androidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer) { 223 if !library.static() { 224 fmt.Fprintln(w, "LOCAL_ADDITIONAL_DEPENDENCIES +=", strings.Join(library.sAbiDiff.Strings(), " ")) 225 } 226} 227 228func (library *libraryDecorator) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) { 229 if library.static() { 230 entries.Class = "STATIC_LIBRARIES" 231 } else if library.shared() { 232 entries.Class = "SHARED_LIBRARIES" 233 entries.SetString("LOCAL_SOONG_TOC", library.toc().String()) 234 if !library.buildStubs() && library.unstrippedOutputFile != nil { 235 entries.SetString("LOCAL_SOONG_UNSTRIPPED_BINARY", library.unstrippedOutputFile.String()) 236 } 237 if len(library.Properties.Overrides) > 0 { 238 entries.SetString("LOCAL_OVERRIDES_MODULES", strings.Join(makeOverrideModuleNames(ctx, library.Properties.Overrides), " ")) 239 } 240 if len(library.postInstallCmds) > 0 { 241 entries.SetString("LOCAL_POST_INSTALL_CMD", strings.Join(library.postInstallCmds, "&& ")) 242 } 243 } else if library.header() { 244 entries.Class = "HEADER_LIBRARIES" 245 } 246 247 if library.distFile != nil { 248 entries.DistFiles = android.MakeDefaultDistFiles(library.distFile) 249 } 250 251 library.androidMkWriteExportedFlags(entries) 252 library.androidMkEntriesWriteAdditionalDependenciesForSourceAbiDiff(entries) 253 254 if entries.OutputFile.Valid() { 255 _, _, ext := android.SplitFileExt(entries.OutputFile.Path().Base()) 256 entries.SetString("LOCAL_BUILT_MODULE_STEM", "$(LOCAL_MODULE)"+ext) 257 } 258 259 if library.coverageOutputFile.Valid() { 260 entries.SetString("LOCAL_PREBUILT_COVERAGE_ARCHIVE", library.coverageOutputFile.String()) 261 } 262 263 if library.shared() && !library.buildStubs() { 264 ctx.subAndroidMk(config, entries, library.baseInstaller) 265 } else { 266 if library.buildStubs() && library.stubsVersion() != "" { 267 entries.SubName = "." + library.stubsVersion() 268 } 269 // library.makeUninstallable() depends on this to bypass HideFromMake() for 270 // static libraries. 271 entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true) 272 if library.buildStubs() { 273 entries.SetBool("LOCAL_NO_NOTICE_FILE", true) 274 } 275 } 276 // If a library providing a stub is included in an APEX, the private APIs of the library 277 // is accessible only inside the APEX. From outside of the APEX, clients can only use the 278 // public APIs via the stub. To enforce this, the (latest version of the) stub gets the 279 // name of the library. The impl library instead gets the `.bootstrap` suffix to so that 280 // they can be exceptionally used directly when APEXes are not available (e.g. during the 281 // very early stage in the boot process). 282 if len(library.Properties.Stubs.Versions) > 0 && !ctx.Host() && ctx.NotInPlatform() && 283 !ctx.InRamdisk() && !ctx.InVendorRamdisk() && !ctx.InRecovery() && !ctx.InVendorOrProduct() && !ctx.static() { 284 if library.buildStubs() && library.isLatestStubVersion() { 285 entries.SubName = "" 286 } 287 if !library.buildStubs() { 288 entries.SubName = ".bootstrap" 289 } 290 } 291} 292 293func (object *objectLinker) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) { 294 entries.Class = "STATIC_LIBRARIES" 295} 296 297func (object *objectLinker) prepareAndroidMKFooterInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) { 298 out := entries.OutputFile.Path() 299 name := ctx.BaseModuleName() 300 if entries.OverrideName != "" { 301 name = entries.OverrideName 302 } 303 304 prefix := "" 305 if ctx.ArchSpecific() { 306 switch ctx.Os().Class { 307 case android.Host: 308 if ctx.Target().HostCross { 309 prefix = "HOST_CROSS_" 310 } else { 311 prefix = "HOST_" 312 } 313 case android.Device: 314 prefix = "TARGET_" 315 316 } 317 318 if ctx.Arch().ArchType != config.Targets[ctx.Os()][0].Arch.ArchType { 319 prefix = "2ND_" + prefix 320 } 321 } 322 323 varname := fmt.Sprintf("SOONG_%sOBJECT_%s%s", prefix, name, entries.SubName) 324 325 entries.FooterStrings = append(entries.FooterStrings, 326 fmt.Sprintf("\n%s := %s\n.KATI_READONLY: %s", varname, out.String(), varname)) 327} 328 329func (test *testDecorator) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) { 330 if len(test.InstallerProperties.Test_suites) > 0 { 331 entries.AddCompatibilityTestSuites(test.InstallerProperties.Test_suites...) 332 } 333} 334 335func (binary *binaryDecorator) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) { 336 ctx.subAndroidMk(config, entries, binary.baseInstaller) 337 338 entries.Class = "EXECUTABLES" 339 entries.DistFiles = binary.distFiles 340 entries.SetString("LOCAL_SOONG_UNSTRIPPED_BINARY", binary.unstrippedOutputFile.String()) 341 if len(binary.symlinks) > 0 { 342 entries.AddStrings("LOCAL_MODULE_SYMLINKS", binary.symlinks...) 343 } 344 345 if binary.coverageOutputFile.Valid() { 346 entries.SetString("LOCAL_PREBUILT_COVERAGE_ARCHIVE", binary.coverageOutputFile.String()) 347 } 348 349 if len(binary.Properties.Overrides) > 0 { 350 entries.SetString("LOCAL_OVERRIDES_MODULES", strings.Join(makeOverrideModuleNames(ctx, binary.Properties.Overrides), " ")) 351 } 352 if len(binary.postInstallCmds) > 0 { 353 entries.SetString("LOCAL_POST_INSTALL_CMD", strings.Join(binary.postInstallCmds, "&& ")) 354 } 355} 356 357func (benchmark *benchmarkDecorator) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) { 358 ctx.subAndroidMk(config, entries, benchmark.binaryDecorator) 359 entries.Class = "NATIVE_TESTS" 360 if len(benchmark.Properties.Test_suites) > 0 { 361 entries.AddCompatibilityTestSuites(benchmark.Properties.Test_suites...) 362 } 363 if benchmark.testConfig != nil { 364 entries.SetString("LOCAL_FULL_TEST_CONFIG", benchmark.testConfig.String()) 365 } 366 entries.SetBool("LOCAL_NATIVE_BENCHMARK", true) 367 if !BoolDefault(benchmark.Properties.Auto_gen_config, true) { 368 entries.SetBool("LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG", true) 369 } 370} 371 372func (test *testBinary) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) { 373 ctx.subAndroidMk(config, entries, test.binaryDecorator) 374 ctx.subAndroidMk(config, entries, test.testDecorator) 375 376 entries.Class = "NATIVE_TESTS" 377 if test.testConfig != nil { 378 entries.SetString("LOCAL_FULL_TEST_CONFIG", test.testConfig.String()) 379 } 380 if !BoolDefault(test.Properties.Auto_gen_config, true) { 381 entries.SetBool("LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG", true) 382 } 383 entries.AddStrings("LOCAL_TEST_MAINLINE_MODULES", test.Properties.Test_mainline_modules...) 384 385 entries.SetBoolIfTrue("LOCAL_COMPATIBILITY_PER_TESTCASE_DIRECTORY", Bool(test.Properties.Per_testcase_directory)) 386 if len(test.Properties.Data_bins) > 0 { 387 entries.AddStrings("LOCAL_TEST_DATA_BINS", test.Properties.Data_bins...) 388 } 389 390 test.Properties.Test_options.CommonTestOptions.SetAndroidMkInfoEntries(entries) 391 392 androidMkWriteExtraTestConfigs(test.extraTestConfigs, entries) 393} 394 395func (fuzz *fuzzBinary) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) { 396 ctx.subAndroidMk(config, entries, fuzz.binaryDecorator) 397 398 entries.SetBool("LOCAL_IS_FUZZ_TARGET", true) 399 if fuzz.installedSharedDeps != nil { 400 // TOOD: move to install dep 401 entries.AddStrings("LOCAL_FUZZ_INSTALLED_SHARED_DEPS", fuzz.installedSharedDeps...) 402 } 403} 404 405func (test *testLibrary) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) { 406 ctx.subAndroidMk(config, entries, test.libraryDecorator) 407 ctx.subAndroidMk(config, entries, test.testDecorator) 408} 409 410func (installer *baseInstaller) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) { 411 if installer.path == (android.InstallPath{}) { 412 return 413 } 414 415 path, file := filepath.Split(installer.path.String()) 416 stem, suffix, _ := android.SplitFileExt(file) 417 entries.SetString("LOCAL_MODULE_SUFFIX", suffix) 418 entries.SetString("LOCAL_MODULE_PATH", path) 419 entries.SetString("LOCAL_MODULE_STEM", stem) 420} 421 422func (c *stubDecorator) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) { 423 entries.SubName = ndkLibrarySuffix + "." + c.apiLevel.String() 424 entries.Class = "SHARED_LIBRARIES" 425 426 if !c.buildStubs() { 427 entries.Disabled = true 428 return 429 } 430 431 path, file := filepath.Split(c.installPath.String()) 432 stem, suffix, _ := android.SplitFileExt(file) 433 entries.SetString("LOCAL_MODULE_SUFFIX", suffix) 434 entries.SetString("LOCAL_MODULE_PATH", path) 435 entries.SetString("LOCAL_MODULE_STEM", stem) 436 entries.SetBool("LOCAL_NO_NOTICE_FILE", true) 437 if c.parsedCoverageXmlPath.String() != "" { 438 entries.SetString("SOONG_NDK_API_XML", "$(SOONG_NDK_API_XML) "+c.parsedCoverageXmlPath.String()) 439 } 440 entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true) // Stubs should not be installed 441} 442 443func (c *vndkPrebuiltLibraryDecorator) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) { 444 entries.Class = "SHARED_LIBRARIES" 445 446 entries.SubName = c.androidMkSuffix 447 448 c.libraryDecorator.androidMkWriteExportedFlags(entries) 449 450 // Specifying stem is to pass check_elf_files when vendor modules link against vndk prebuilt. 451 // We can't use install path because VNDKs are not installed. Instead, Srcs is directly used. 452 _, file := filepath.Split(c.properties.Srcs[0]) 453 stem, suffix, ext := android.SplitFileExt(file) 454 entries.SetString("LOCAL_BUILT_MODULE_STEM", "$(LOCAL_MODULE)"+ext) 455 entries.SetString("LOCAL_MODULE_SUFFIX", suffix) 456 entries.SetString("LOCAL_MODULE_STEM", stem) 457 458 if c.tocFile.Valid() { 459 entries.SetString("LOCAL_SOONG_TOC", c.tocFile.String()) 460 } 461 462 // VNDK libraries available to vendor are not installed because 463 // they are packaged in VNDK APEX and installed by APEX packages (apex/apex.go) 464 entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true) 465} 466 467func (p *prebuiltLinker) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) { 468 if p.properties.Check_elf_files != nil { 469 entries.SetBool("LOCAL_CHECK_ELF_FILES", *p.properties.Check_elf_files) 470 } else { 471 // soong_cc_rust_prebuilt.mk does not include check_elf_file.mk by default 472 // because cc_library_shared and cc_binary use soong_cc_rust_prebuilt.mk as well. 473 // In order to turn on prebuilt ABI checker, set `LOCAL_CHECK_ELF_FILES` to 474 // true if `p.properties.Check_elf_files` is not specified. 475 entries.SetBool("LOCAL_CHECK_ELF_FILES", true) 476 } 477} 478 479func (p *prebuiltLibraryLinker) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) { 480 ctx.subAndroidMk(config, entries, p.libraryDecorator) 481 if p.shared() { 482 ctx.subAndroidMk(config, entries, &p.prebuiltLinker) 483 androidMkWritePrebuiltOptions(p.baseLinker, entries) 484 } 485} 486 487func (p *prebuiltBinaryLinker) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) { 488 ctx.subAndroidMk(config, entries, p.binaryDecorator) 489 ctx.subAndroidMk(config, entries, &p.prebuiltLinker) 490 androidMkWritePrebuiltOptions(p.baseLinker, entries) 491} 492 493func androidMkWritePrebuiltOptions(linker *baseLinker, entries *android.AndroidMkInfo) { 494 allow := linker.Properties.Allow_undefined_symbols 495 if allow != nil { 496 entries.SetBool("LOCAL_ALLOW_UNDEFINED_SYMBOLS", *allow) 497 } 498 ignore := linker.Properties.Ignore_max_page_size 499 if ignore != nil { 500 entries.SetBool("LOCAL_IGNORE_MAX_PAGE_SIZE", *ignore) 501 } 502} 503