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 library.androidMkWriteExportedFlags(entries) 248 library.androidMkEntriesWriteAdditionalDependenciesForSourceAbiDiff(entries) 249 250 if entries.OutputFile.Valid() { 251 _, _, ext := android.SplitFileExt(entries.OutputFile.Path().Base()) 252 entries.SetString("LOCAL_BUILT_MODULE_STEM", "$(LOCAL_MODULE)"+ext) 253 } 254 255 if library.coverageOutputFile.Valid() { 256 entries.SetString("LOCAL_PREBUILT_COVERAGE_ARCHIVE", library.coverageOutputFile.String()) 257 } 258 259 if library.shared() && !library.BuildStubs() { 260 ctx.subAndroidMk(config, entries, library.baseInstaller) 261 } else { 262 if library.BuildStubs() && library.StubsVersion() != "" { 263 entries.SubName = "." + library.StubsVersion() 264 } 265 // library.makeUninstallable() depends on this to bypass HideFromMake() for 266 // static libraries. 267 entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true) 268 if library.BuildStubs() { 269 entries.SetBool("LOCAL_NO_NOTICE_FILE", true) 270 } 271 } 272 // If a library providing a stub is included in an APEX, the private APIs of the library 273 // is accessible only inside the APEX. From outside of the APEX, clients can only use the 274 // public APIs via the stub. To enforce this, the (latest version of the) stub gets the 275 // name of the library. The impl library instead gets the `.bootstrap` suffix to so that 276 // they can be exceptionally used directly when APEXes are not available (e.g. during the 277 // very early stage in the boot process). 278 if len(library.Properties.Stubs.Versions) > 0 && !ctx.Host() && ctx.NotInPlatform() && 279 !ctx.InRamdisk() && !ctx.InVendorRamdisk() && !ctx.InRecovery() && !ctx.InVendorOrProduct() && !ctx.static() { 280 if library.BuildStubs() && library.isLatestStubVersion() { 281 entries.SubName = "" 282 } 283 if !library.BuildStubs() { 284 entries.SubName = ".bootstrap" 285 } 286 } 287} 288 289func (object *objectLinker) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) { 290 entries.Class = "STATIC_LIBRARIES" 291} 292 293func (object *objectLinker) prepareAndroidMKFooterInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) { 294 out := entries.OutputFile.Path() 295 name := ctx.BaseModuleName() 296 if entries.OverrideName != "" { 297 name = entries.OverrideName 298 } 299 300 prefix := "" 301 if ctx.ArchSpecific() { 302 switch ctx.Os().Class { 303 case android.Host: 304 if ctx.Target().HostCross { 305 prefix = "HOST_CROSS_" 306 } else { 307 prefix = "HOST_" 308 } 309 case android.Device: 310 prefix = "TARGET_" 311 312 } 313 314 if ctx.Arch().ArchType != config.Targets[ctx.Os()][0].Arch.ArchType { 315 prefix = "2ND_" + prefix 316 } 317 } 318 319 varname := fmt.Sprintf("SOONG_%sOBJECT_%s%s", prefix, name, entries.SubName) 320 321 entries.FooterStrings = append(entries.FooterStrings, 322 fmt.Sprintf("\n%s := %s\n.KATI_READONLY: %s", varname, out.String(), varname)) 323} 324 325func (test *testDecorator) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) { 326 if len(test.InstallerProperties.Test_suites) > 0 { 327 entries.AddCompatibilityTestSuites(test.InstallerProperties.Test_suites...) 328 } 329} 330 331func (binary *binaryDecorator) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) { 332 ctx.subAndroidMk(config, entries, binary.baseInstaller) 333 334 entries.Class = "EXECUTABLES" 335 entries.SetString("LOCAL_SOONG_UNSTRIPPED_BINARY", binary.unstrippedOutputFile.String()) 336 if len(binary.symlinks) > 0 { 337 entries.AddStrings("LOCAL_MODULE_SYMLINKS", binary.symlinks...) 338 } 339 340 if binary.coverageOutputFile.Valid() { 341 entries.SetString("LOCAL_PREBUILT_COVERAGE_ARCHIVE", binary.coverageOutputFile.String()) 342 } 343 344 if len(binary.Properties.Overrides) > 0 { 345 entries.SetString("LOCAL_OVERRIDES_MODULES", strings.Join(makeOverrideModuleNames(ctx, binary.Properties.Overrides), " ")) 346 } 347 if len(binary.postInstallCmds) > 0 { 348 entries.SetString("LOCAL_POST_INSTALL_CMD", strings.Join(binary.postInstallCmds, "&& ")) 349 } 350} 351 352func (benchmark *benchmarkDecorator) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) { 353 ctx.subAndroidMk(config, entries, benchmark.binaryDecorator) 354 entries.Class = "NATIVE_TESTS" 355 if len(benchmark.Properties.Test_suites) > 0 { 356 entries.AddCompatibilityTestSuites(benchmark.Properties.Test_suites...) 357 } 358 if benchmark.testConfig != nil { 359 entries.SetString("LOCAL_FULL_TEST_CONFIG", benchmark.testConfig.String()) 360 } 361 entries.SetBool("LOCAL_NATIVE_BENCHMARK", true) 362 if !BoolDefault(benchmark.Properties.Auto_gen_config, true) { 363 entries.SetBool("LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG", true) 364 } 365} 366 367func (test *testBinary) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) { 368 ctx.subAndroidMk(config, entries, test.binaryDecorator) 369 ctx.subAndroidMk(config, entries, test.testDecorator) 370 371 entries.Class = "NATIVE_TESTS" 372 if test.testConfig != nil { 373 entries.SetString("LOCAL_FULL_TEST_CONFIG", test.testConfig.String()) 374 } 375 if !BoolDefault(test.Properties.Auto_gen_config, true) { 376 entries.SetBool("LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG", true) 377 } 378 entries.AddStrings("LOCAL_TEST_MAINLINE_MODULES", test.Properties.Test_mainline_modules...) 379 380 entries.SetBoolIfTrue("LOCAL_COMPATIBILITY_PER_TESTCASE_DIRECTORY", Bool(test.Properties.Per_testcase_directory)) 381 if len(test.Properties.Data_bins) > 0 { 382 entries.AddStrings("LOCAL_TEST_DATA_BINS", test.Properties.Data_bins...) 383 } 384 385 test.Properties.Test_options.CommonTestOptions.SetAndroidMkInfoEntries(entries) 386 387 androidMkWriteExtraTestConfigs(test.extraTestConfigs, entries) 388} 389 390func (fuzz *fuzzBinary) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) { 391 ctx.subAndroidMk(config, entries, fuzz.binaryDecorator) 392 393 entries.SetBool("LOCAL_IS_FUZZ_TARGET", true) 394 if fuzz.installedSharedDeps != nil { 395 // TOOD: move to install dep 396 entries.AddStrings("LOCAL_FUZZ_INSTALLED_SHARED_DEPS", fuzz.installedSharedDeps...) 397 } 398} 399 400func (test *testLibrary) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) { 401 ctx.subAndroidMk(config, entries, test.libraryDecorator) 402 ctx.subAndroidMk(config, entries, test.testDecorator) 403} 404 405func (installer *baseInstaller) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) { 406 if installer.path == (android.InstallPath{}) { 407 return 408 } 409 410 path, file := filepath.Split(installer.path.String()) 411 stem, suffix, _ := android.SplitFileExt(file) 412 entries.SetString("LOCAL_MODULE_SUFFIX", suffix) 413 entries.SetString("LOCAL_MODULE_PATH", path) 414 entries.SetString("LOCAL_MODULE_STEM", stem) 415} 416 417func (c *stubDecorator) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) { 418 entries.SubName = ndkLibrarySuffix + "." + c.apiLevel.String() 419 entries.Class = "SHARED_LIBRARIES" 420 421 if !c.BuildStubs() { 422 entries.Disabled = true 423 return 424 } 425 426 path, file := filepath.Split(c.installPath.String()) 427 stem, suffix, _ := android.SplitFileExt(file) 428 entries.SetString("LOCAL_MODULE_SUFFIX", suffix) 429 entries.SetString("LOCAL_MODULE_PATH", path) 430 entries.SetString("LOCAL_MODULE_STEM", stem) 431 entries.SetBool("LOCAL_NO_NOTICE_FILE", true) 432 if c.parsedCoverageXmlPath.String() != "" { 433 entries.SetString("SOONG_NDK_API_XML", "$(SOONG_NDK_API_XML) "+c.parsedCoverageXmlPath.String()) 434 } 435 entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true) // Stubs should not be installed 436} 437 438func (c *vndkPrebuiltLibraryDecorator) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) { 439 entries.Class = "SHARED_LIBRARIES" 440 441 entries.SubName = c.androidMkSuffix 442 443 c.libraryDecorator.androidMkWriteExportedFlags(entries) 444 445 // Specifying stem is to pass check_elf_files when vendor modules link against vndk prebuilt. 446 // We can't use install path because VNDKs are not installed. Instead, Srcs is directly used. 447 _, file := filepath.Split(c.properties.Srcs[0]) 448 stem, suffix, ext := android.SplitFileExt(file) 449 entries.SetString("LOCAL_BUILT_MODULE_STEM", "$(LOCAL_MODULE)"+ext) 450 entries.SetString("LOCAL_MODULE_SUFFIX", suffix) 451 entries.SetString("LOCAL_MODULE_STEM", stem) 452 453 if c.tocFile.Valid() { 454 entries.SetString("LOCAL_SOONG_TOC", c.tocFile.String()) 455 } 456 457 // VNDK libraries available to vendor are not installed because 458 // they are packaged in VNDK APEX and installed by APEX packages (apex/apex.go) 459 entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true) 460} 461 462func (p *prebuiltLinker) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) { 463 if p.properties.Check_elf_files != nil { 464 entries.SetBool("LOCAL_CHECK_ELF_FILES", *p.properties.Check_elf_files) 465 } else { 466 // soong_cc_rust_prebuilt.mk does not include check_elf_file.mk by default 467 // because cc_library_shared and cc_binary use soong_cc_rust_prebuilt.mk as well. 468 // In order to turn on prebuilt ABI checker, set `LOCAL_CHECK_ELF_FILES` to 469 // true if `p.properties.Check_elf_files` is not specified. 470 entries.SetBool("LOCAL_CHECK_ELF_FILES", true) 471 } 472} 473 474func (p *prebuiltLibraryLinker) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) { 475 ctx.subAndroidMk(config, entries, p.libraryDecorator) 476 if p.shared() { 477 ctx.subAndroidMk(config, entries, &p.prebuiltLinker) 478 androidMkWritePrebuiltOptions(p.baseLinker, entries) 479 } 480} 481 482func (p *prebuiltBinaryLinker) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) { 483 ctx.subAndroidMk(config, entries, p.binaryDecorator) 484 ctx.subAndroidMk(config, entries, &p.prebuiltLinker) 485 androidMkWritePrebuiltOptions(p.baseLinker, entries) 486} 487 488func androidMkWritePrebuiltOptions(linker *baseLinker, entries *android.AndroidMkInfo) { 489 allow := linker.Properties.Allow_undefined_symbols 490 if allow != nil { 491 entries.SetBool("LOCAL_ALLOW_UNDEFINED_SYMBOLS", *allow) 492 } 493 ignore := linker.Properties.Ignore_max_page_size 494 if ignore != nil { 495 entries.SetBool("LOCAL_IGNORE_MAX_PAGE_SIZE", *ignore) 496 } 497} 498