| Inseob Kim | 5eb7ee9 | 2022-04-27 10:30:34 +0900 | [diff] [blame] | 1 | // Copyright 2021 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 cc | 
|  | 16 |  | 
|  | 17 | import ( | 
| Kiyoung Kim | d5d1ab1 | 2022-11-28 16:47:10 +0900 | [diff] [blame] | 18 | "regexp" | 
| Kiyoung Kim | ee58c93 | 2022-10-25 22:59:41 +0900 | [diff] [blame] | 19 | "strings" | 
|  | 20 |  | 
| Inseob Kim | 5eb7ee9 | 2022-04-27 10:30:34 +0900 | [diff] [blame] | 21 | "android/soong/android" | 
|  | 22 | "android/soong/multitree" | 
|  | 23 | ) | 
|  | 24 |  | 
| Kiyoung Kim | d5d1ab1 | 2022-11-28 16:47:10 +0900 | [diff] [blame] | 25 | var ( | 
| Kiyoung Kim | 76b06f3 | 2023-02-06 22:08:13 +0900 | [diff] [blame] | 26 | ndkVariantRegex  = regexp.MustCompile("ndk\\.([a-zA-Z0-9]+)") | 
|  | 27 | stubVariantRegex = regexp.MustCompile("apex\\.([a-zA-Z0-9]+)") | 
| Kiyoung Kim | d5d1ab1 | 2022-11-28 16:47:10 +0900 | [diff] [blame] | 28 | ) | 
|  | 29 |  | 
| Inseob Kim | 5eb7ee9 | 2022-04-27 10:30:34 +0900 | [diff] [blame] | 30 | func init() { | 
|  | 31 | RegisterLibraryStubBuildComponents(android.InitRegistrationContext) | 
|  | 32 | } | 
|  | 33 |  | 
|  | 34 | func RegisterLibraryStubBuildComponents(ctx android.RegistrationContext) { | 
| Kiyoung Kim | 487689e | 2022-07-26 09:48:22 +0900 | [diff] [blame] | 35 | ctx.RegisterModuleType("cc_api_library", CcApiLibraryFactory) | 
| Kiyoung Kim | 51279d3 | 2022-08-24 14:10:46 +0900 | [diff] [blame] | 36 | ctx.RegisterModuleType("cc_api_headers", CcApiHeadersFactory) | 
| Kiyoung Kim | ee58c93 | 2022-10-25 22:59:41 +0900 | [diff] [blame] | 37 | ctx.RegisterModuleType("cc_api_variant", CcApiVariantFactory) | 
|  | 38 | } | 
|  | 39 |  | 
|  | 40 | func updateImportedLibraryDependency(ctx android.BottomUpMutatorContext) { | 
|  | 41 | m, ok := ctx.Module().(*Module) | 
|  | 42 | if !ok { | 
|  | 43 | return | 
|  | 44 | } | 
|  | 45 |  | 
|  | 46 | apiLibrary, ok := m.linker.(*apiLibraryDecorator) | 
|  | 47 | if !ok { | 
|  | 48 | return | 
|  | 49 | } | 
|  | 50 |  | 
|  | 51 | if m.UseVndk() && apiLibrary.hasLLNDKStubs() { | 
| Kiyoung Kim | d5d1ab1 | 2022-11-28 16:47:10 +0900 | [diff] [blame] | 52 | // Add LLNDK variant dependency | 
|  | 53 | if inList("llndk", apiLibrary.properties.Variants) { | 
|  | 54 | variantName := BuildApiVariantName(m.BaseModuleName(), "llndk", "") | 
|  | 55 | ctx.AddDependency(m, nil, variantName) | 
|  | 56 | } | 
|  | 57 | } else if m.IsSdkVariant() { | 
|  | 58 | // Add NDK variant dependencies | 
|  | 59 | targetVariant := "ndk." + m.StubsVersion() | 
|  | 60 | if inList(targetVariant, apiLibrary.properties.Variants) { | 
|  | 61 | variantName := BuildApiVariantName(m.BaseModuleName(), targetVariant, "") | 
|  | 62 | ctx.AddDependency(m, nil, variantName) | 
| Kiyoung Kim | ee58c93 | 2022-10-25 22:59:41 +0900 | [diff] [blame] | 63 | } | 
| Kiyoung Kim | 76b06f3 | 2023-02-06 22:08:13 +0900 | [diff] [blame] | 64 | } else if m.IsStubs() { | 
|  | 65 | targetVariant := "apex." + m.StubsVersion() | 
|  | 66 | if inList(targetVariant, apiLibrary.properties.Variants) { | 
|  | 67 | variantName := BuildApiVariantName(m.BaseModuleName(), targetVariant, "") | 
|  | 68 | ctx.AddDependency(m, nil, variantName) | 
|  | 69 | } | 
| Kiyoung Kim | ee58c93 | 2022-10-25 22:59:41 +0900 | [diff] [blame] | 70 | } | 
| Inseob Kim | 5eb7ee9 | 2022-04-27 10:30:34 +0900 | [diff] [blame] | 71 | } | 
|  | 72 |  | 
| Kiyoung Kim | 487689e | 2022-07-26 09:48:22 +0900 | [diff] [blame] | 73 | // 'cc_api_library' is a module type which is from the exported API surface | 
|  | 74 | // with C shared library type. The module will replace original module, and | 
|  | 75 | // offer a link to the module that generates shared library object from the | 
|  | 76 | // map file. | 
|  | 77 | type apiLibraryProperties struct { | 
| Kiyoung Kim | ee58c93 | 2022-10-25 22:59:41 +0900 | [diff] [blame] | 78 | Src      *string `android:"arch_variant"` | 
|  | 79 | Variants []string | 
| Kiyoung Kim | 487689e | 2022-07-26 09:48:22 +0900 | [diff] [blame] | 80 | } | 
|  | 81 |  | 
|  | 82 | type apiLibraryDecorator struct { | 
|  | 83 | *libraryDecorator | 
|  | 84 | properties apiLibraryProperties | 
|  | 85 | } | 
|  | 86 |  | 
|  | 87 | func CcApiLibraryFactory() android.Module { | 
|  | 88 | module, decorator := NewLibrary(android.DeviceSupported) | 
|  | 89 | apiLibraryDecorator := &apiLibraryDecorator{ | 
|  | 90 | libraryDecorator: decorator, | 
|  | 91 | } | 
|  | 92 | apiLibraryDecorator.BuildOnlyShared() | 
|  | 93 |  | 
|  | 94 | module.stl = nil | 
|  | 95 | module.sanitize = nil | 
|  | 96 | decorator.disableStripping() | 
|  | 97 |  | 
|  | 98 | module.compiler = nil | 
|  | 99 | module.linker = apiLibraryDecorator | 
|  | 100 | module.installer = nil | 
| Kiyoung Kim | ee58c93 | 2022-10-25 22:59:41 +0900 | [diff] [blame] | 101 | module.library = apiLibraryDecorator | 
| Kiyoung Kim | 487689e | 2022-07-26 09:48:22 +0900 | [diff] [blame] | 102 | module.AddProperties(&module.Properties, &apiLibraryDecorator.properties) | 
|  | 103 |  | 
| Kiyoung Kim | 487689e | 2022-07-26 09:48:22 +0900 | [diff] [blame] | 104 | // Prevent default system libs (libc, libm, and libdl) from being linked | 
|  | 105 | if apiLibraryDecorator.baseLinker.Properties.System_shared_libs == nil { | 
|  | 106 | apiLibraryDecorator.baseLinker.Properties.System_shared_libs = []string{} | 
|  | 107 | } | 
|  | 108 |  | 
| Kiyoung Kim | 835c589 | 2022-08-17 16:40:16 +0900 | [diff] [blame] | 109 | apiLibraryDecorator.baseLinker.Properties.No_libcrt = BoolPtr(true) | 
|  | 110 | apiLibraryDecorator.baseLinker.Properties.Nocrt = BoolPtr(true) | 
|  | 111 |  | 
| Kiyoung Kim | 487689e | 2022-07-26 09:48:22 +0900 | [diff] [blame] | 112 | module.Init() | 
|  | 113 |  | 
|  | 114 | return module | 
|  | 115 | } | 
|  | 116 |  | 
|  | 117 | func (d *apiLibraryDecorator) Name(basename string) string { | 
|  | 118 | return basename + multitree.GetApiImportSuffix() | 
|  | 119 | } | 
|  | 120 |  | 
| Spandan Das | f0beebc | 2022-10-18 18:23:28 +0000 | [diff] [blame] | 121 | // Export include dirs without checking for existence. | 
|  | 122 | // The directories are not guaranteed to exist during Soong analysis. | 
|  | 123 | func (d *apiLibraryDecorator) exportIncludes(ctx ModuleContext) { | 
|  | 124 | exporterProps := d.flagExporter.Properties | 
|  | 125 | for _, dir := range exporterProps.Export_include_dirs { | 
| Spandan Das | c6c10fa | 2022-10-21 21:52:13 +0000 | [diff] [blame] | 126 | d.dirs = append(d.dirs, android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), dir)) | 
| Spandan Das | f0beebc | 2022-10-18 18:23:28 +0000 | [diff] [blame] | 127 | } | 
|  | 128 | // system headers | 
|  | 129 | for _, dir := range exporterProps.Export_system_include_dirs { | 
| Spandan Das | c6c10fa | 2022-10-21 21:52:13 +0000 | [diff] [blame] | 130 | d.systemDirs = append(d.systemDirs, android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), dir)) | 
| Spandan Das | f0beebc | 2022-10-18 18:23:28 +0000 | [diff] [blame] | 131 | } | 
|  | 132 | } | 
|  | 133 |  | 
| Kiyoung Kim | d5d1ab1 | 2022-11-28 16:47:10 +0900 | [diff] [blame] | 134 | func (d *apiLibraryDecorator) linkerInit(ctx BaseModuleContext) { | 
|  | 135 | d.baseLinker.linkerInit(ctx) | 
|  | 136 |  | 
|  | 137 | if d.hasNDKStubs() { | 
|  | 138 | // Set SDK version of module as current | 
|  | 139 | ctx.Module().(*Module).Properties.Sdk_version = StringPtr("current") | 
|  | 140 |  | 
|  | 141 | // Add NDK stub as NDK known libs | 
|  | 142 | name := ctx.ModuleName() | 
|  | 143 |  | 
|  | 144 | ndkKnownLibsLock.Lock() | 
|  | 145 | ndkKnownLibs := getNDKKnownLibs(ctx.Config()) | 
|  | 146 | if !inList(name, *ndkKnownLibs) { | 
|  | 147 | *ndkKnownLibs = append(*ndkKnownLibs, name) | 
|  | 148 | } | 
|  | 149 | ndkKnownLibsLock.Unlock() | 
|  | 150 | } | 
|  | 151 | } | 
|  | 152 |  | 
| Kiyoung Kim | 487689e | 2022-07-26 09:48:22 +0900 | [diff] [blame] | 153 | func (d *apiLibraryDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, objects Objects) android.Path { | 
| Kiyoung Kim | ee58c93 | 2022-10-25 22:59:41 +0900 | [diff] [blame] | 154 | m, _ := ctx.Module().(*Module) | 
|  | 155 |  | 
|  | 156 | var in android.Path | 
|  | 157 |  | 
| Spandan Das | 6830f6b | 2022-12-02 23:26:38 +0000 | [diff] [blame] | 158 | // src might not exist during the beginning of soong analysis in Multi-tree | 
| Kiyoung Kim | d5d1ab1 | 2022-11-28 16:47:10 +0900 | [diff] [blame] | 159 | if src := String(d.properties.Src); src != "" { | 
| Spandan Das | 6830f6b | 2022-12-02 23:26:38 +0000 | [diff] [blame] | 160 | in = android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), src) | 
| Kiyoung Kim | ee58c93 | 2022-10-25 22:59:41 +0900 | [diff] [blame] | 161 | } | 
|  | 162 |  | 
| Kiyoung Kim | 76b06f3 | 2023-02-06 22:08:13 +0900 | [diff] [blame] | 163 | libName := m.BaseModuleName() + multitree.GetApiImportSuffix() | 
| Kiyoung Kim | ee58c93 | 2022-10-25 22:59:41 +0900 | [diff] [blame] | 164 |  | 
| Kiyoung Kim | 76b06f3 | 2023-02-06 22:08:13 +0900 | [diff] [blame] | 165 | load_cc_variant := func(apiVariantModule string) { | 
| Kiyoung Kim | ee58c93 | 2022-10-25 22:59:41 +0900 | [diff] [blame] | 166 | var mod android.Module | 
|  | 167 |  | 
|  | 168 | ctx.VisitDirectDeps(func(depMod android.Module) { | 
|  | 169 | if depMod.Name() == apiVariantModule { | 
|  | 170 | mod = depMod | 
| Kiyoung Kim | 76b06f3 | 2023-02-06 22:08:13 +0900 | [diff] [blame] | 171 | libName = apiVariantModule | 
| Kiyoung Kim | ee58c93 | 2022-10-25 22:59:41 +0900 | [diff] [blame] | 172 | } | 
|  | 173 | }) | 
|  | 174 |  | 
|  | 175 | if mod != nil { | 
|  | 176 | variantMod, ok := mod.(*CcApiVariant) | 
|  | 177 | if ok { | 
|  | 178 | in = variantMod.Src() | 
|  | 179 |  | 
|  | 180 | // Copy LLDNK properties to cc_api_library module | 
|  | 181 | d.libraryDecorator.flagExporter.Properties.Export_include_dirs = append( | 
|  | 182 | d.libraryDecorator.flagExporter.Properties.Export_include_dirs, | 
| Kiyoung Kim | 62ed3dd | 2022-12-02 10:20:55 +0900 | [diff] [blame] | 183 | variantMod.exportProperties.Export_include_dirs...) | 
| Kiyoung Kim | ee58c93 | 2022-10-25 22:59:41 +0900 | [diff] [blame] | 184 |  | 
|  | 185 | // Export headers as system include dirs if specified. Mostly for libc | 
| Kiyoung Kim | d5d1ab1 | 2022-11-28 16:47:10 +0900 | [diff] [blame] | 186 | if Bool(variantMod.exportProperties.Export_headers_as_system) { | 
| Kiyoung Kim | ee58c93 | 2022-10-25 22:59:41 +0900 | [diff] [blame] | 187 | d.libraryDecorator.flagExporter.Properties.Export_system_include_dirs = append( | 
|  | 188 | d.libraryDecorator.flagExporter.Properties.Export_system_include_dirs, | 
|  | 189 | d.libraryDecorator.flagExporter.Properties.Export_include_dirs...) | 
|  | 190 | d.libraryDecorator.flagExporter.Properties.Export_include_dirs = nil | 
|  | 191 | } | 
|  | 192 | } | 
|  | 193 | } | 
| Kiyoung Kim | 76b06f3 | 2023-02-06 22:08:13 +0900 | [diff] [blame] | 194 | } | 
|  | 195 |  | 
|  | 196 | if m.UseVndk() && d.hasLLNDKStubs() { | 
|  | 197 | // LLNDK variant | 
|  | 198 | load_cc_variant(BuildApiVariantName(m.BaseModuleName(), "llndk", "")) | 
| Kiyoung Kim | d5d1ab1 | 2022-11-28 16:47:10 +0900 | [diff] [blame] | 199 | } else if m.IsSdkVariant() { | 
|  | 200 | // NDK Variant | 
| Kiyoung Kim | 76b06f3 | 2023-02-06 22:08:13 +0900 | [diff] [blame] | 201 | load_cc_variant(BuildApiVariantName(m.BaseModuleName(), "ndk", m.StubsVersion())) | 
|  | 202 | } else if m.IsStubs() { | 
|  | 203 | // APEX Variant | 
|  | 204 | load_cc_variant(BuildApiVariantName(m.BaseModuleName(), "apex", m.StubsVersion())) | 
| Kiyoung Kim | 51279d3 | 2022-08-24 14:10:46 +0900 | [diff] [blame] | 205 | } | 
|  | 206 |  | 
| Kiyoung Kim | 487689e | 2022-07-26 09:48:22 +0900 | [diff] [blame] | 207 | // Flags reexported from dependencies. (e.g. vndk_prebuilt_shared) | 
| Spandan Das | f0beebc | 2022-10-18 18:23:28 +0000 | [diff] [blame] | 208 | d.exportIncludes(ctx) | 
| Kiyoung Kim | 487689e | 2022-07-26 09:48:22 +0900 | [diff] [blame] | 209 | d.libraryDecorator.reexportDirs(deps.ReexportedDirs...) | 
|  | 210 | d.libraryDecorator.reexportSystemDirs(deps.ReexportedSystemDirs...) | 
|  | 211 | d.libraryDecorator.reexportFlags(deps.ReexportedFlags...) | 
|  | 212 | d.libraryDecorator.reexportDeps(deps.ReexportedDeps...) | 
|  | 213 | d.libraryDecorator.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...) | 
| Kiyoung Kim | 487689e | 2022-07-26 09:48:22 +0900 | [diff] [blame] | 214 |  | 
| Kiyoung Kim | ee58c93 | 2022-10-25 22:59:41 +0900 | [diff] [blame] | 215 | if in == nil { | 
|  | 216 | ctx.PropertyErrorf("src", "Unable to locate source property") | 
|  | 217 | return nil | 
| Spandan Das | f0beebc | 2022-10-18 18:23:28 +0000 | [diff] [blame] | 218 | } | 
| Kiyoung Kim | 487689e | 2022-07-26 09:48:22 +0900 | [diff] [blame] | 219 |  | 
| Spandan Das | a3c8a17 | 2022-10-26 20:54:32 +0000 | [diff] [blame] | 220 | // Make the _compilation_ of rdeps have an order-only dep on cc_api_library.src (an .so file) | 
|  | 221 | // The .so file itself has an order-only dependency on the headers contributed by this library. | 
|  | 222 | // Creating this dependency ensures that the headers are assembled before compilation of rdeps begins. | 
|  | 223 | d.libraryDecorator.reexportDeps(in) | 
|  | 224 | d.libraryDecorator.flagExporter.setProvider(ctx) | 
|  | 225 |  | 
| Kiyoung Kim | 487689e | 2022-07-26 09:48:22 +0900 | [diff] [blame] | 226 | d.unstrippedOutputFile = in | 
| Kiyoung Kim | 76b06f3 | 2023-02-06 22:08:13 +0900 | [diff] [blame] | 227 | libName += flags.Toolchain.ShlibSuffix() | 
| Kiyoung Kim | 487689e | 2022-07-26 09:48:22 +0900 | [diff] [blame] | 228 |  | 
|  | 229 | tocFile := android.PathForModuleOut(ctx, libName+".toc") | 
|  | 230 | d.tocFile = android.OptionalPathForPath(tocFile) | 
|  | 231 | TransformSharedObjectToToc(ctx, in, tocFile) | 
|  | 232 |  | 
| Kiyoung Kim | 76b06f3 | 2023-02-06 22:08:13 +0900 | [diff] [blame] | 233 | outputFile := android.PathForModuleOut(ctx, libName) | 
|  | 234 |  | 
|  | 235 | // TODO(b/270485584) This copies with a new name, just to avoid conflict with prebuilts. | 
|  | 236 | // We can just use original input if there is any way to avoid name conflict without copy. | 
|  | 237 | ctx.Build(pctx, android.BuildParams{ | 
|  | 238 | Rule:        android.Cp, | 
|  | 239 | Description: "API surface imported library", | 
|  | 240 | Input:       in, | 
|  | 241 | Output:      outputFile, | 
|  | 242 | Args: map[string]string{ | 
|  | 243 | "cpFlags": "-L", | 
|  | 244 | }, | 
|  | 245 | }) | 
|  | 246 |  | 
| Kiyoung Kim | 487689e | 2022-07-26 09:48:22 +0900 | [diff] [blame] | 247 | ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{ | 
| Kiyoung Kim | 76b06f3 | 2023-02-06 22:08:13 +0900 | [diff] [blame] | 248 | SharedLibrary: outputFile, | 
| Kiyoung Kim | 487689e | 2022-07-26 09:48:22 +0900 | [diff] [blame] | 249 | Target:        ctx.Target(), | 
|  | 250 |  | 
|  | 251 | TableOfContents: d.tocFile, | 
|  | 252 | }) | 
|  | 253 |  | 
| Kiyoung Kim | 76b06f3 | 2023-02-06 22:08:13 +0900 | [diff] [blame] | 254 | d.shareStubs(ctx) | 
|  | 255 |  | 
|  | 256 | return outputFile | 
|  | 257 | } | 
|  | 258 |  | 
|  | 259 | // Share additional information about stub libraries with provider | 
|  | 260 | func (d *apiLibraryDecorator) shareStubs(ctx ModuleContext) { | 
|  | 261 | stubs := ctx.GetDirectDepsWithTag(stubImplDepTag) | 
|  | 262 | if len(stubs) > 0 { | 
|  | 263 | var stubsInfo []SharedStubLibrary | 
|  | 264 | for _, stub := range stubs { | 
|  | 265 | stubInfo := ctx.OtherModuleProvider(stub, SharedLibraryInfoProvider).(SharedLibraryInfo) | 
|  | 266 | flagInfo := ctx.OtherModuleProvider(stub, FlagExporterInfoProvider).(FlagExporterInfo) | 
|  | 267 | stubsInfo = append(stubsInfo, SharedStubLibrary{ | 
|  | 268 | Version:           moduleLibraryInterface(stub).stubsVersion(), | 
|  | 269 | SharedLibraryInfo: stubInfo, | 
|  | 270 | FlagExporterInfo:  flagInfo, | 
|  | 271 | }) | 
|  | 272 | } | 
|  | 273 | ctx.SetProvider(SharedLibraryStubsProvider, SharedLibraryStubsInfo{ | 
|  | 274 | SharedStubLibraries: stubsInfo, | 
|  | 275 |  | 
|  | 276 | IsLLNDK: ctx.IsLlndk(), | 
|  | 277 | }) | 
|  | 278 | } | 
| Kiyoung Kim | 487689e | 2022-07-26 09:48:22 +0900 | [diff] [blame] | 279 | } | 
|  | 280 |  | 
|  | 281 | func (d *apiLibraryDecorator) availableFor(what string) bool { | 
|  | 282 | // Stub from API surface should be available for any APEX. | 
|  | 283 | return true | 
|  | 284 | } | 
|  | 285 |  | 
| Kiyoung Kim | 76b06f3 | 2023-02-06 22:08:13 +0900 | [diff] [blame] | 286 | func (d *apiLibraryDecorator) hasApexStubs() bool { | 
|  | 287 | for _, variant := range d.properties.Variants { | 
|  | 288 | if strings.HasPrefix(variant, "apex") { | 
|  | 289 | return true | 
|  | 290 | } | 
|  | 291 | } | 
|  | 292 | return false | 
|  | 293 | } | 
|  | 294 |  | 
|  | 295 | func (d *apiLibraryDecorator) hasStubsVariants() bool { | 
|  | 296 | return d.hasApexStubs() | 
|  | 297 | } | 
|  | 298 |  | 
| Kiyoung Kim | ee58c93 | 2022-10-25 22:59:41 +0900 | [diff] [blame] | 299 | func (d *apiLibraryDecorator) stubsVersions(ctx android.BaseMutatorContext) []string { | 
|  | 300 | m, ok := ctx.Module().(*Module) | 
|  | 301 |  | 
|  | 302 | if !ok { | 
|  | 303 | return nil | 
|  | 304 | } | 
|  | 305 |  | 
| Kiyoung Kim | ee58c93 | 2022-10-25 22:59:41 +0900 | [diff] [blame] | 306 | // TODO(b/244244438) Create more version information for NDK and APEX variations | 
|  | 307 | // NDK variants | 
| Kiyoung Kim | d5d1ab1 | 2022-11-28 16:47:10 +0900 | [diff] [blame] | 308 | if m.IsSdkVariant() { | 
|  | 309 | // TODO(b/249193999) Do not check if module has NDK stubs once all NDK cc_api_library contains ndk variant of cc_api_variant. | 
|  | 310 | if d.hasNDKStubs() { | 
|  | 311 | return d.getNdkVersions() | 
|  | 312 | } | 
|  | 313 | } | 
|  | 314 |  | 
| Kiyoung Kim | 76b06f3 | 2023-02-06 22:08:13 +0900 | [diff] [blame] | 315 | if d.hasLLNDKStubs() && m.UseVndk() { | 
|  | 316 | // LLNDK libraries only need a single stubs variant. | 
|  | 317 | return []string{android.FutureApiLevel.String()} | 
|  | 318 | } | 
|  | 319 |  | 
|  | 320 | stubsVersions := d.getStubVersions() | 
|  | 321 |  | 
|  | 322 | if len(stubsVersions) != 0 { | 
|  | 323 | return stubsVersions | 
|  | 324 | } | 
|  | 325 |  | 
| Kiyoung Kim | ee58c93 | 2022-10-25 22:59:41 +0900 | [diff] [blame] | 326 | if m.MinSdkVersion() == "" { | 
|  | 327 | return nil | 
|  | 328 | } | 
|  | 329 |  | 
|  | 330 | firstVersion, err := nativeApiLevelFromUser(ctx, | 
|  | 331 | m.MinSdkVersion()) | 
|  | 332 |  | 
|  | 333 | if err != nil { | 
|  | 334 | return nil | 
|  | 335 | } | 
|  | 336 |  | 
|  | 337 | return ndkLibraryVersions(ctx, firstVersion) | 
|  | 338 | } | 
|  | 339 |  | 
|  | 340 | func (d *apiLibraryDecorator) hasLLNDKStubs() bool { | 
| Kiyoung Kim | d5d1ab1 | 2022-11-28 16:47:10 +0900 | [diff] [blame] | 341 | return inList("llndk", d.properties.Variants) | 
|  | 342 | } | 
|  | 343 |  | 
|  | 344 | func (d *apiLibraryDecorator) hasNDKStubs() bool { | 
| Kiyoung Kim | ee58c93 | 2022-10-25 22:59:41 +0900 | [diff] [blame] | 345 | for _, variant := range d.properties.Variants { | 
| Kiyoung Kim | d5d1ab1 | 2022-11-28 16:47:10 +0900 | [diff] [blame] | 346 | if ndkVariantRegex.MatchString(variant) { | 
| Kiyoung Kim | ee58c93 | 2022-10-25 22:59:41 +0900 | [diff] [blame] | 347 | return true | 
|  | 348 | } | 
|  | 349 | } | 
|  | 350 | return false | 
|  | 351 | } | 
|  | 352 |  | 
| Kiyoung Kim | d5d1ab1 | 2022-11-28 16:47:10 +0900 | [diff] [blame] | 353 | func (d *apiLibraryDecorator) getNdkVersions() []string { | 
|  | 354 | ndkVersions := []string{} | 
|  | 355 |  | 
|  | 356 | for _, variant := range d.properties.Variants { | 
|  | 357 | if match := ndkVariantRegex.FindStringSubmatch(variant); len(match) == 2 { | 
|  | 358 | ndkVersions = append(ndkVersions, match[1]) | 
|  | 359 | } | 
|  | 360 | } | 
|  | 361 |  | 
|  | 362 | return ndkVersions | 
|  | 363 | } | 
|  | 364 |  | 
| Kiyoung Kim | 76b06f3 | 2023-02-06 22:08:13 +0900 | [diff] [blame] | 365 | func (d *apiLibraryDecorator) getStubVersions() []string { | 
|  | 366 | stubVersions := []string{} | 
|  | 367 |  | 
|  | 368 | for _, variant := range d.properties.Variants { | 
|  | 369 | if match := stubVariantRegex.FindStringSubmatch(variant); len(match) == 2 { | 
|  | 370 | stubVersions = append(stubVersions, match[1]) | 
|  | 371 | } | 
|  | 372 | } | 
|  | 373 |  | 
|  | 374 | return stubVersions | 
|  | 375 | } | 
|  | 376 |  | 
| Kiyoung Kim | 51279d3 | 2022-08-24 14:10:46 +0900 | [diff] [blame] | 377 | // 'cc_api_headers' is similar with 'cc_api_library', but which replaces | 
|  | 378 | // header libraries. The module will replace any dependencies to existing | 
|  | 379 | // original header libraries. | 
|  | 380 | type apiHeadersDecorator struct { | 
|  | 381 | *libraryDecorator | 
|  | 382 | } | 
|  | 383 |  | 
|  | 384 | func CcApiHeadersFactory() android.Module { | 
|  | 385 | module, decorator := NewLibrary(android.DeviceSupported) | 
|  | 386 | apiHeadersDecorator := &apiHeadersDecorator{ | 
|  | 387 | libraryDecorator: decorator, | 
|  | 388 | } | 
|  | 389 | apiHeadersDecorator.HeaderOnly() | 
|  | 390 |  | 
|  | 391 | module.stl = nil | 
|  | 392 | module.sanitize = nil | 
|  | 393 | decorator.disableStripping() | 
|  | 394 |  | 
|  | 395 | module.compiler = nil | 
|  | 396 | module.linker = apiHeadersDecorator | 
|  | 397 | module.installer = nil | 
|  | 398 |  | 
| Kiyoung Kim | 51279d3 | 2022-08-24 14:10:46 +0900 | [diff] [blame] | 399 | // Prevent default system libs (libc, libm, and libdl) from being linked | 
|  | 400 | if apiHeadersDecorator.baseLinker.Properties.System_shared_libs == nil { | 
|  | 401 | apiHeadersDecorator.baseLinker.Properties.System_shared_libs = []string{} | 
|  | 402 | } | 
|  | 403 |  | 
|  | 404 | apiHeadersDecorator.baseLinker.Properties.No_libcrt = BoolPtr(true) | 
|  | 405 | apiHeadersDecorator.baseLinker.Properties.Nocrt = BoolPtr(true) | 
|  | 406 |  | 
|  | 407 | module.Init() | 
|  | 408 |  | 
|  | 409 | return module | 
|  | 410 | } | 
|  | 411 |  | 
|  | 412 | func (d *apiHeadersDecorator) Name(basename string) string { | 
|  | 413 | return basename + multitree.GetApiImportSuffix() | 
|  | 414 | } | 
|  | 415 |  | 
|  | 416 | func (d *apiHeadersDecorator) availableFor(what string) bool { | 
|  | 417 | // Stub from API surface should be available for any APEX. | 
|  | 418 | return true | 
| Kiyoung Kim | 487689e | 2022-07-26 09:48:22 +0900 | [diff] [blame] | 419 | } | 
| Kiyoung Kim | ee58c93 | 2022-10-25 22:59:41 +0900 | [diff] [blame] | 420 |  | 
|  | 421 | type ccApiexportProperties struct { | 
|  | 422 | Src     *string `android:"arch_variant"` | 
|  | 423 | Variant *string | 
|  | 424 | Version *string | 
|  | 425 | } | 
|  | 426 |  | 
|  | 427 | type variantExporterProperties struct { | 
| Kiyoung Kim | 3d776f4 | 2022-11-11 12:35:01 +0900 | [diff] [blame] | 428 | // Header directory to export | 
| Kiyoung Kim | 62ed3dd | 2022-12-02 10:20:55 +0900 | [diff] [blame] | 429 | Export_include_dirs []string `android:"arch_variant"` | 
| Kiyoung Kim | ee58c93 | 2022-10-25 22:59:41 +0900 | [diff] [blame] | 430 |  | 
|  | 431 | // Export all headers as system include | 
|  | 432 | Export_headers_as_system *bool | 
|  | 433 | } | 
|  | 434 |  | 
|  | 435 | type CcApiVariant struct { | 
|  | 436 | android.ModuleBase | 
|  | 437 |  | 
|  | 438 | properties       ccApiexportProperties | 
|  | 439 | exportProperties variantExporterProperties | 
|  | 440 |  | 
|  | 441 | src android.Path | 
|  | 442 | } | 
|  | 443 |  | 
|  | 444 | var _ android.Module = (*CcApiVariant)(nil) | 
|  | 445 | var _ android.ImageInterface = (*CcApiVariant)(nil) | 
|  | 446 |  | 
|  | 447 | func CcApiVariantFactory() android.Module { | 
|  | 448 | module := &CcApiVariant{} | 
|  | 449 |  | 
|  | 450 | module.AddProperties(&module.properties) | 
|  | 451 | module.AddProperties(&module.exportProperties) | 
|  | 452 |  | 
|  | 453 | android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibBoth) | 
|  | 454 | return module | 
|  | 455 | } | 
|  | 456 |  | 
|  | 457 | func (v *CcApiVariant) GenerateAndroidBuildActions(ctx android.ModuleContext) { | 
|  | 458 | // No need to build | 
|  | 459 |  | 
| Kiyoung Kim | d5d1ab1 | 2022-11-28 16:47:10 +0900 | [diff] [blame] | 460 | if String(v.properties.Src) == "" { | 
| Kiyoung Kim | ee58c93 | 2022-10-25 22:59:41 +0900 | [diff] [blame] | 461 | ctx.PropertyErrorf("src", "src is a required property") | 
|  | 462 | } | 
|  | 463 |  | 
|  | 464 | // Skip the existence check of the stub prebuilt file. | 
|  | 465 | // The file is not guaranteed to exist during Soong analysis. | 
|  | 466 | // Build orchestrator will be responsible for creating a connected ninja graph. | 
| Kiyoung Kim | d5d1ab1 | 2022-11-28 16:47:10 +0900 | [diff] [blame] | 467 | v.src = android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), String(v.properties.Src)) | 
| Kiyoung Kim | ee58c93 | 2022-10-25 22:59:41 +0900 | [diff] [blame] | 468 | } | 
|  | 469 |  | 
|  | 470 | func (v *CcApiVariant) Name() string { | 
| Kiyoung Kim | d5d1ab1 | 2022-11-28 16:47:10 +0900 | [diff] [blame] | 471 | version := String(v.properties.Version) | 
| Kiyoung Kim | ee58c93 | 2022-10-25 22:59:41 +0900 | [diff] [blame] | 472 | return BuildApiVariantName(v.BaseModuleName(), *v.properties.Variant, version) | 
|  | 473 | } | 
|  | 474 |  | 
|  | 475 | func (v *CcApiVariant) Src() android.Path { | 
|  | 476 | return v.src | 
|  | 477 | } | 
|  | 478 |  | 
|  | 479 | func BuildApiVariantName(baseName string, variant string, version string) string { | 
|  | 480 | names := []string{baseName, variant} | 
|  | 481 | if version != "" { | 
|  | 482 | names = append(names, version) | 
|  | 483 | } | 
|  | 484 |  | 
|  | 485 | return strings.Join(names[:], ".") + multitree.GetApiImportSuffix() | 
|  | 486 | } | 
|  | 487 |  | 
|  | 488 | // Implement ImageInterface to generate image variants | 
| Kiyoung Kim | d5d1ab1 | 2022-11-28 16:47:10 +0900 | [diff] [blame] | 489 | func (v *CcApiVariant) ImageMutatorBegin(ctx android.BaseModuleContext) {} | 
|  | 490 | func (v *CcApiVariant) CoreVariantNeeded(ctx android.BaseModuleContext) bool { | 
| Kiyoung Kim | 76b06f3 | 2023-02-06 22:08:13 +0900 | [diff] [blame] | 491 | return inList(String(v.properties.Variant), []string{"ndk", "apex"}) | 
| Kiyoung Kim | d5d1ab1 | 2022-11-28 16:47:10 +0900 | [diff] [blame] | 492 | } | 
| Kiyoung Kim | ee58c93 | 2022-10-25 22:59:41 +0900 | [diff] [blame] | 493 | func (v *CcApiVariant) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool       { return false } | 
|  | 494 | func (v *CcApiVariant) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { return false } | 
|  | 495 | func (v *CcApiVariant) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool  { return false } | 
|  | 496 | func (v *CcApiVariant) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool      { return false } | 
|  | 497 | func (v *CcApiVariant) ExtraImageVariations(ctx android.BaseModuleContext) []string { | 
|  | 498 | var variations []string | 
|  | 499 | platformVndkVersion := ctx.DeviceConfig().PlatformVndkVersion() | 
|  | 500 |  | 
| Kiyoung Kim | d5d1ab1 | 2022-11-28 16:47:10 +0900 | [diff] [blame] | 501 | if String(v.properties.Variant) == "llndk" { | 
| Kiyoung Kim | ee58c93 | 2022-10-25 22:59:41 +0900 | [diff] [blame] | 502 | variations = append(variations, VendorVariationPrefix+platformVndkVersion) | 
|  | 503 | variations = append(variations, ProductVariationPrefix+platformVndkVersion) | 
|  | 504 | } | 
|  | 505 |  | 
|  | 506 | return variations | 
|  | 507 | } | 
|  | 508 | func (v *CcApiVariant) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) { | 
|  | 509 | } |