blob: 3f6a01d1b871ed234b87c68c0c3dcb426cec8c35 [file] [log] [blame]
Hao Chen1c8ea5b2023-10-20 23:03:45 +00001// Copyright 2024 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 (
Hao Chen1c8ea5b2023-10-20 23:03:45 +000018 "bytes"
19 _ "embed"
20 "fmt"
21 "path/filepath"
22 "slices"
23 "sort"
24 "strings"
25 "text/template"
26
mrziwangf95cfa62024-06-18 10:11:39 -070027 "android/soong/android"
28
Hao Chen1c8ea5b2023-10-20 23:03:45 +000029 "github.com/google/blueprint"
30 "github.com/google/blueprint/proptools"
31)
32
33const veryVerbose bool = false
34
35//go:embed cmake_main.txt
36var templateCmakeMainRaw string
37var templateCmakeMain *template.Template = parseTemplate(templateCmakeMainRaw)
38
39//go:embed cmake_module_cc.txt
40var templateCmakeModuleCcRaw string
41var templateCmakeModuleCc *template.Template = parseTemplate(templateCmakeModuleCcRaw)
42
43//go:embed cmake_module_aidl.txt
44var templateCmakeModuleAidlRaw string
45var templateCmakeModuleAidl *template.Template = parseTemplate(templateCmakeModuleAidlRaw)
46
47//go:embed cmake_ext_add_aidl_library.txt
48var cmakeExtAddAidlLibrary string
49
50//go:embed cmake_ext_append_flags.txt
51var cmakeExtAppendFlags string
52
53var defaultUnportableFlags []string = []string{
Tomasz Wasilczykcd674732024-06-25 10:30:30 -070054 "-Wno-c99-designator",
Hao Chen1c8ea5b2023-10-20 23:03:45 +000055 "-Wno-class-memaccess",
56 "-Wno-exit-time-destructors",
Tomasz Wasilczykcd674732024-06-25 10:30:30 -070057 "-Winconsistent-missing-override",
Hao Chen1c8ea5b2023-10-20 23:03:45 +000058 "-Wno-inconsistent-missing-override",
59 "-Wreorder-init-list",
60 "-Wno-reorder-init-list",
61 "-Wno-restrict",
62 "-Wno-stringop-overread",
63 "-Wno-subobject-linkage",
64}
65
66var ignoredSystemLibs []string = []string{
Tomasz Wasilczyk2493fcc2024-06-20 15:29:09 -070067 "crtbegin_dynamic",
68 "crtend_android",
69 "libc",
Hao Chen1c8ea5b2023-10-20 23:03:45 +000070 "libc++",
71 "libc++_static",
Tomasz Wasilczykbd83c742024-06-27 10:47:40 -070072 "libc++demangle",
Tomasz Wasilczyk7cec7e62024-07-01 11:31:47 -070073 "libc_musl",
74 "libc_musl_crtbegin_so",
75 "libc_musl_crtbegin_static",
76 "libc_musl_crtend",
77 "libc_musl_crtend_so",
Tomasz Wasilczyk2493fcc2024-06-20 15:29:09 -070078 "libdl",
79 "libm",
Hao Chen1c8ea5b2023-10-20 23:03:45 +000080 "prebuilt_libclang_rt.builtins",
81 "prebuilt_libclang_rt.ubsan_minimal",
82}
83
84// Mapping entry between Android's library name and the one used when building outside Android tree.
85type LibraryMappingProperty struct {
86 // Android library name.
87 Android_name string
88
89 // Library name used when building outside Android.
90 Mapped_name string
91
92 // If the make file is already present in Android source tree, specify its location.
93 Package_pregenerated string
94
95 // If the package is expected to be installed on the build host OS, specify its name.
96 Package_system string
97}
98
99type CmakeSnapshotProperties struct {
Tomasz Wasilczykd38d1402024-06-27 10:41:55 -0700100 // Host modules to add to the snapshot package. Their dependencies are pulled in automatically.
101 Modules_host []string
102
103 // System modules to add to the snapshot package. Their dependencies are pulled in automatically.
104 Modules_system []string
105
106 // Vendor modules to add to the snapshot package. Their dependencies are pulled in automatically.
107 Modules_vendor []string
108
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000109 // Host prebuilts to bundle with the snapshot. These are tools needed to build outside Android.
110 Prebuilts []string
111
112 // Global cflags to add when building outside Android.
113 Cflags []string
114
115 // Flags to skip when building outside Android.
116 Cflags_ignored []string
117
118 // Mapping between library names used in Android tree and externally.
119 Library_mapping []LibraryMappingProperty
120
121 // List of cflags that are not portable between compilers that could potentially be used to
122 // build a generated package. If left empty, it's initialized with a default list.
123 Unportable_flags []string
124
125 // Whether to include source code as part of the snapshot package.
126 Include_sources bool
127}
128
129var cmakeSnapshotSourcesProvider = blueprint.NewProvider[android.Paths]()
130
131type CmakeSnapshot struct {
132 android.ModuleBase
133
134 Properties CmakeSnapshotProperties
135
136 zipPath android.WritablePath
137}
138
139type cmakeProcessedProperties struct {
140 LibraryMapping map[string]LibraryMappingProperty
141 PregeneratedPackages []string
142 SystemPackages []string
143}
144
145type cmakeSnapshotDependencyTag struct {
146 blueprint.BaseDependencyTag
147 name string
148}
149
150var (
151 cmakeSnapshotModuleTag = cmakeSnapshotDependencyTag{name: "cmake-snapshot-module"}
152 cmakeSnapshotPrebuiltTag = cmakeSnapshotDependencyTag{name: "cmake-snapshot-prebuilt"}
153)
154
155func parseTemplate(templateContents string) *template.Template {
156 funcMap := template.FuncMap{
157 "setList": func(name string, nameSuffix string, itemPrefix string, items []string) string {
158 var list strings.Builder
159 list.WriteString("set(" + name + nameSuffix)
160 templateListBuilder(&list, itemPrefix, items)
161 return list.String()
162 },
163 "toStrings": func(files android.Paths) []string {
Colin Cross7de1db72024-06-25 14:36:24 -0700164 return files.Strings()
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000165 },
166 "concat5": func(list1 []string, list2 []string, list3 []string, list4 []string, list5 []string) []string {
167 return append(append(append(append(list1, list2...), list3...), list4...), list5...)
168 },
169 "cflagsList": func(name string, nameSuffix string, flags []string,
170 unportableFlags []string, ignoredFlags []string) string {
171 if len(unportableFlags) == 0 {
172 unportableFlags = defaultUnportableFlags
173 }
174
175 var filteredPortable []string
176 var filteredUnportable []string
177 for _, flag := range flags {
178 if slices.Contains(ignoredFlags, flag) {
179 continue
180 } else if slices.Contains(unportableFlags, flag) {
181 filteredUnportable = append(filteredUnportable, flag)
182 } else {
183 filteredPortable = append(filteredPortable, flag)
184 }
185 }
186
187 var list strings.Builder
188
189 list.WriteString("set(" + name + nameSuffix)
190 templateListBuilder(&list, "", filteredPortable)
191
192 if len(filteredUnportable) > 0 {
193 list.WriteString("\nappend_cxx_flags_if_supported(" + name + nameSuffix)
194 templateListBuilder(&list, "", filteredUnportable)
195 }
196
197 return list.String()
198 },
Yu Liu323d77a2024-12-16 23:13:57 +0000199 "getSources": func(ctx android.ModuleContext, info *CcInfo) android.Paths {
200 return info.CompilerInfo.Srcs
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000201 },
202 "getModuleType": getModuleType,
Yu Liu323d77a2024-12-16 23:13:57 +0000203 "getAidlInterface": func(info *CcInfo) AidlInterfaceInfo {
204 return info.CompilerInfo.AidlInterfaceInfo
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000205 },
Yu Liu323d77a2024-12-16 23:13:57 +0000206 "getCflagsProperty": func(ctx android.ModuleContext, info *CcInfo) []string {
Cole Faustc9b88c92025-02-06 17:58:26 -0800207 return info.CompilerInfo.Cflags
Cole Fauste96c16a2024-06-13 14:51:14 -0700208 },
Yu Liu323d77a2024-12-16 23:13:57 +0000209 "getWholeStaticLibsProperty": func(ctx android.ModuleContext, info *CcInfo) []string {
Cole Faustc9b88c92025-02-06 17:58:26 -0800210 return info.LinkerInfo.WholeStaticLibs
Cole Faustf0006e72024-08-19 14:39:19 -0700211 },
Yu Liu323d77a2024-12-16 23:13:57 +0000212 "getStaticLibsProperty": func(ctx android.ModuleContext, info *CcInfo) []string {
Cole Faustc9b88c92025-02-06 17:58:26 -0800213 return info.LinkerInfo.StaticLibs
Cole Faustf0006e72024-08-19 14:39:19 -0700214 },
Yu Liu323d77a2024-12-16 23:13:57 +0000215 "getSharedLibsProperty": func(ctx android.ModuleContext, info *CcInfo) []string {
Cole Faustc9b88c92025-02-06 17:58:26 -0800216 return info.LinkerInfo.SharedLibs
Cole Faustf0006e72024-08-19 14:39:19 -0700217 },
Yu Liu323d77a2024-12-16 23:13:57 +0000218 "getHeaderLibsProperty": func(ctx android.ModuleContext, info *CcInfo) []string {
Cole Faustc9b88c92025-02-06 17:58:26 -0800219 return info.LinkerInfo.HeaderLibs
Cole Faustf0006e72024-08-19 14:39:19 -0700220 },
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000221 "getExtraLibs": getExtraLibs,
222 "getIncludeDirs": getIncludeDirs,
Yu Liu323d77a2024-12-16 23:13:57 +0000223 "mapLibraries": func(ctx android.ModuleContext, m android.ModuleProxy, libs []string, mapping map[string]LibraryMappingProperty) []string {
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000224 var mappedLibs []string
225 for _, lib := range libs {
226 mappedLib, exists := mapping[lib]
227 if exists {
228 lib = mappedLib.Mapped_name
229 } else {
Tomasz Wasilczyk1e831bf2024-05-10 15:15:21 -0700230 if !ctx.OtherModuleExists(lib) {
231 ctx.OtherModuleErrorf(m, "Dependency %s doesn't exist", lib)
232 }
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000233 lib = "android::" + lib
234 }
235 if lib == "" {
236 continue
237 }
238 mappedLibs = append(mappedLibs, lib)
239 }
240 sort.Strings(mappedLibs)
241 mappedLibs = slices.Compact(mappedLibs)
242 return mappedLibs
243 },
Yu Liu323d77a2024-12-16 23:13:57 +0000244 "getAidlSources": func(info *CcInfo) []string {
245 aidlInterface := info.CompilerInfo.AidlInterfaceInfo
Tomasz Wasilczyk1e831bf2024-05-10 15:15:21 -0700246 aidlRoot := aidlInterface.AidlRoot + string(filepath.Separator)
247 if aidlInterface.AidlRoot == "" {
248 aidlRoot = ""
249 }
250 var sources []string
251 for _, src := range aidlInterface.Sources {
252 if !strings.HasPrefix(src, aidlRoot) {
253 panic(fmt.Sprintf("Aidl source '%v' doesn't start with '%v'", src, aidlRoot))
254 }
255 sources = append(sources, src[len(aidlRoot):])
256 }
257 return sources
258 },
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000259 }
260
261 return template.Must(template.New("").Delims("<<", ">>").Funcs(funcMap).Parse(templateContents))
262}
263
264func sliceWithPrefix(prefix string, slice []string) []string {
265 output := make([]string, len(slice))
266 for i, elem := range slice {
267 output[i] = prefix + elem
268 }
269 return output
270}
271
272func templateListBuilder(builder *strings.Builder, itemPrefix string, items []string) {
273 if len(items) > 0 {
274 builder.WriteString("\n")
275 for _, item := range items {
276 builder.WriteString(" " + itemPrefix + item + "\n")
277 }
278 }
279 builder.WriteString(")")
280}
281
282func executeTemplate(templ *template.Template, buffer *bytes.Buffer, data any) string {
283 buffer.Reset()
284 if err := templ.Execute(buffer, data); err != nil {
285 panic(err)
286 }
287 output := strings.TrimSpace(buffer.String())
288 buffer.Reset()
289 return output
290}
291
292func (m *CmakeSnapshot) DepsMutator(ctx android.BottomUpMutatorContext) {
Tomasz Wasilczykd38d1402024-06-27 10:41:55 -0700293 deviceVariations := ctx.Config().AndroidFirstDeviceTarget.Variations()
294 deviceSystemVariations := append(deviceVariations, blueprint.Variation{"image", ""})
295 deviceVendorVariations := append(deviceVariations, blueprint.Variation{"image", "vendor"})
Tomasz Wasilczyk9288b512024-06-27 09:22:12 -0700296 hostVariations := ctx.Config().BuildOSTarget.Variations()
Tomasz Wasilczykd38d1402024-06-27 10:41:55 -0700297
Tomasz Wasilczykd38d1402024-06-27 10:41:55 -0700298 ctx.AddVariationDependencies(hostVariations, cmakeSnapshotModuleTag, m.Properties.Modules_host...)
299 ctx.AddVariationDependencies(deviceSystemVariations, cmakeSnapshotModuleTag, m.Properties.Modules_system...)
300 ctx.AddVariationDependencies(deviceVendorVariations, cmakeSnapshotModuleTag, m.Properties.Modules_vendor...)
Tomasz Wasilczyk2493fcc2024-06-20 15:29:09 -0700301
302 if len(m.Properties.Prebuilts) > 0 {
303 prebuilts := append(m.Properties.Prebuilts, "libc++")
Tomasz Wasilczyk9288b512024-06-27 09:22:12 -0700304 ctx.AddVariationDependencies(hostVariations, cmakeSnapshotPrebuiltTag, prebuilts...)
Tomasz Wasilczyk2493fcc2024-06-20 15:29:09 -0700305 }
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000306}
307
308func (m *CmakeSnapshot) GenerateAndroidBuildActions(ctx android.ModuleContext) {
309 var templateBuffer bytes.Buffer
310 var pprop cmakeProcessedProperties
311 m.zipPath = android.PathForModuleOut(ctx, ctx.ModuleName()+".zip")
312
313 // Process Library_mapping for more efficient lookups
314 pprop.LibraryMapping = map[string]LibraryMappingProperty{}
315 for _, elem := range m.Properties.Library_mapping {
316 pprop.LibraryMapping[elem.Android_name] = elem
317
318 if elem.Package_pregenerated != "" {
319 pprop.PregeneratedPackages = append(pprop.PregeneratedPackages, elem.Package_pregenerated)
320 }
321 sort.Strings(pprop.PregeneratedPackages)
322 pprop.PregeneratedPackages = slices.Compact(pprop.PregeneratedPackages)
323
324 if elem.Package_system != "" {
325 pprop.SystemPackages = append(pprop.SystemPackages, elem.Package_system)
326 }
327 sort.Strings(pprop.SystemPackages)
328 pprop.SystemPackages = slices.Compact(pprop.SystemPackages)
329 }
330
331 // Generating CMakeLists.txt rules for all modules in dependency tree
332 moduleDirs := map[string][]string{}
333 sourceFiles := map[string]android.Path{}
334 visitedModules := map[string]bool{}
Yu Liu323d77a2024-12-16 23:13:57 +0000335 var pregeneratedModules []android.ModuleProxy
336 ctx.WalkDepsProxy(func(dep, parent android.ModuleProxy) bool {
337 moduleName := ctx.OtherModuleName(dep)
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000338 if visited := visitedModules[moduleName]; visited {
339 return false // visit only once
340 }
341 visitedModules[moduleName] = true
Yu Liu323d77a2024-12-16 23:13:57 +0000342 ccInfo, ok := android.OtherModuleProvider(ctx, dep, CcInfoProvider)
Tomasz Wasilczyk1e831bf2024-05-10 15:15:21 -0700343 if !ok {
344 return false // not a cc module
345 }
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000346 if mapping, ok := pprop.LibraryMapping[moduleName]; ok {
347 if mapping.Package_pregenerated != "" {
348 pregeneratedModules = append(pregeneratedModules, dep)
349 }
350 return false // mapped to system or pregenerated (we'll handle these later)
351 }
352 if ctx.OtherModuleDependencyTag(dep) == cmakeSnapshotPrebuiltTag {
353 return false // we'll handle cmakeSnapshotPrebuiltTag later
354 }
355 if slices.Contains(ignoredSystemLibs, moduleName) {
356 return false // system libs built in-tree for Android
357 }
Yu Liu323d77a2024-12-16 23:13:57 +0000358 if ccInfo.IsPrebuilt {
Spandan Das1f229392024-07-23 22:31:50 +0000359 return false // prebuilts are not supported
360 }
Yu Liu323d77a2024-12-16 23:13:57 +0000361 if ccInfo.CompilerInfo == nil {
Spandan Das1f229392024-07-23 22:31:50 +0000362 return false // unsupported module type
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000363 }
Yu Liu323d77a2024-12-16 23:13:57 +0000364 isAidlModule := ccInfo.CompilerInfo.AidlInterfaceInfo.Lang != ""
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000365
Yu Liu323d77a2024-12-16 23:13:57 +0000366 if !ccInfo.CmakeSnapshotSupported {
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000367 ctx.OtherModulePropertyErrorf(dep, "cmake_snapshot_supported",
368 "CMake snapshots not supported, despite being a dependency for %s",
369 ctx.OtherModuleName(parent))
370 return false
371 }
372
373 if veryVerbose {
374 fmt.Println("WalkDeps: " + ctx.OtherModuleName(parent) + " -> " + moduleName)
375 }
376
377 // Generate CMakeLists.txt fragment for this module
378 templateToUse := templateCmakeModuleCc
379 if isAidlModule {
380 templateToUse = templateCmakeModuleAidl
381 }
382 moduleFragment := executeTemplate(templateToUse, &templateBuffer, struct {
383 Ctx *android.ModuleContext
Yu Liu323d77a2024-12-16 23:13:57 +0000384 M android.ModuleProxy
385 CcInfo *CcInfo
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000386 Snapshot *CmakeSnapshot
387 Pprop *cmakeProcessedProperties
388 }{
389 &ctx,
390 dep,
Yu Liu8024b922024-12-20 23:31:32 +0000391 ccInfo,
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000392 m,
393 &pprop,
394 })
395 moduleDir := ctx.OtherModuleDir(dep)
396 moduleDirs[moduleDir] = append(moduleDirs[moduleDir], moduleFragment)
397
398 if m.Properties.Include_sources {
399 files, _ := android.OtherModuleProvider(ctx, dep, cmakeSnapshotSourcesProvider)
400 for _, file := range files {
401 sourceFiles[file.String()] = file
402 }
403 }
404
405 // if it's AIDL module, no need to dive into their dependencies
406 return !isAidlModule
407 })
408
409 // Enumerate sources for pregenerated modules
410 if m.Properties.Include_sources {
411 for _, dep := range pregeneratedModules {
Yu Liu323d77a2024-12-16 23:13:57 +0000412 if !android.OtherModuleProviderOrDefault(ctx, dep, CcInfoProvider).CmakeSnapshotSupported {
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000413 ctx.OtherModulePropertyErrorf(dep, "cmake_snapshot_supported",
414 "Pregenerated CMake snapshots not supported, despite being requested for %s",
415 ctx.ModuleName())
416 continue
417 }
418
419 files, _ := android.OtherModuleProvider(ctx, dep, cmakeSnapshotSourcesProvider)
420 for _, file := range files {
421 sourceFiles[file.String()] = file
422 }
423 }
424 }
425
426 // Merging CMakeLists.txt contents for every module directory
427 var makefilesList android.Paths
Colin Cross7de1db72024-06-25 14:36:24 -0700428 for _, moduleDir := range android.SortedKeys(moduleDirs) {
429 fragments := moduleDirs[moduleDir]
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000430 moduleCmakePath := android.PathForModuleGen(ctx, moduleDir, "CMakeLists.txt")
431 makefilesList = append(makefilesList, moduleCmakePath)
432 sort.Strings(fragments)
433 android.WriteFileRule(ctx, moduleCmakePath, strings.Join(fragments, "\n\n\n"))
434 }
435
436 // Generating top-level CMakeLists.txt
437 mainCmakePath := android.PathForModuleGen(ctx, "CMakeLists.txt")
438 makefilesList = append(makefilesList, mainCmakePath)
439 mainContents := executeTemplate(templateCmakeMain, &templateBuffer, struct {
440 Ctx *android.ModuleContext
441 M *CmakeSnapshot
442 ModuleDirs map[string][]string
443 Pprop *cmakeProcessedProperties
444 }{
445 &ctx,
446 m,
447 moduleDirs,
448 &pprop,
449 })
450 android.WriteFileRule(ctx, mainCmakePath, mainContents)
451
452 // Generating CMake extensions
453 extPath := android.PathForModuleGen(ctx, "cmake", "AppendCxxFlagsIfSupported.cmake")
454 makefilesList = append(makefilesList, extPath)
455 android.WriteFileRuleVerbatim(ctx, extPath, cmakeExtAppendFlags)
456 extPath = android.PathForModuleGen(ctx, "cmake", "AddAidlLibrary.cmake")
457 makefilesList = append(makefilesList, extPath)
458 android.WriteFileRuleVerbatim(ctx, extPath, cmakeExtAddAidlLibrary)
459
460 // Generating the final zip file
461 zipRule := android.NewRuleBuilder(pctx, ctx)
462 zipCmd := zipRule.Command().
463 BuiltTool("soong_zip").
464 FlagWithOutput("-o ", m.zipPath)
465
466 // Packaging all sources into the zip file
467 if m.Properties.Include_sources {
468 var sourcesList android.Paths
Colin Cross7de1db72024-06-25 14:36:24 -0700469 for _, file := range android.SortedKeys(sourceFiles) {
470 path := sourceFiles[file]
471 sourcesList = append(sourcesList, path)
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000472 }
473
474 sourcesRspFile := android.PathForModuleObj(ctx, ctx.ModuleName()+"_sources.rsp")
475 zipCmd.FlagWithRspFileInputList("-r ", sourcesRspFile, sourcesList)
476 }
477
478 // Packaging all make files into the zip file
479 makefilesRspFile := android.PathForModuleObj(ctx, ctx.ModuleName()+"_makefiles.rsp")
480 zipCmd.
Cole Faust4e9f5922024-11-13 16:09:23 -0800481 FlagWithArg("-C ", android.PathForModuleGen(ctx).String()).
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000482 FlagWithRspFileInputList("-r ", makefilesRspFile, makefilesList)
483
484 // Packaging all prebuilts into the zip file
485 if len(m.Properties.Prebuilts) > 0 {
486 var prebuiltsList android.Paths
487
Yu Liu323d77a2024-12-16 23:13:57 +0000488 ctx.VisitDirectDepsProxyWithTag(cmakeSnapshotPrebuiltTag, func(dep android.ModuleProxy) {
Yu Liud46e5ae2024-08-15 18:46:17 +0000489 for _, file := range android.OtherModuleProviderOrDefault(
490 ctx, dep, android.InstallFilesProvider).InstallFiles {
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000491 prebuiltsList = append(prebuiltsList, file)
492 }
493 })
494
495 prebuiltsRspFile := android.PathForModuleObj(ctx, ctx.ModuleName()+"_prebuilts.rsp")
496 zipCmd.
497 FlagWithArg("-C ", android.PathForArbitraryOutput(ctx).String()).
498 FlagWithArg("-P ", "prebuilts").
499 FlagWithRspFileInputList("-r ", prebuiltsRspFile, prebuiltsList)
500 }
501
502 // Finish generating the final zip file
503 zipRule.Build(m.zipPath.String(), "archiving "+ctx.ModuleName())
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000504
mrziwangf95cfa62024-06-18 10:11:39 -0700505 ctx.SetOutputFiles(android.Paths{m.zipPath}, "")
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000506}
507
508func (m *CmakeSnapshot) AndroidMkEntries() []android.AndroidMkEntries {
509 return []android.AndroidMkEntries{{
510 Class: "DATA",
511 OutputFile: android.OptionalPathForPath(m.zipPath),
512 ExtraEntries: []android.AndroidMkExtraEntriesFunc{
513 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
514 entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
515 },
516 },
517 }}
518}
519
Yu Liu323d77a2024-12-16 23:13:57 +0000520func getModuleType(info *CcInfo) string {
521 if info.LinkerInfo.BinaryDecoratorInfo != nil {
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000522 return "executable"
Yu Liu323d77a2024-12-16 23:13:57 +0000523 } else if info.LinkerInfo.LibraryDecoratorInfo != nil {
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000524 return "library"
Yu Liu323d77a2024-12-16 23:13:57 +0000525 } else if info.LinkerInfo.TestBinaryInfo != nil || info.LinkerInfo.BenchmarkDecoratorInfo != nil {
Tomasz Wasilczykc3177e02024-06-10 14:38:45 -0700526 return "test"
Yu Liu323d77a2024-12-16 23:13:57 +0000527 } else if info.LinkerInfo.ObjectLinkerInfo != nil {
Colin Crossf6742af2024-09-12 14:10:36 -0700528 return "object"
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000529 }
Yu Liu323d77a2024-12-16 23:13:57 +0000530 panic(fmt.Sprintf("Unexpected module type for LinkerInfo"))
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000531}
532
Yu Liu323d77a2024-12-16 23:13:57 +0000533func getExtraLibs(info *CcInfo) []string {
534 if info.LinkerInfo.TestBinaryInfo != nil {
535 if info.LinkerInfo.TestBinaryInfo.Gtest {
Tomasz Wasilczyk6e2b8c02024-05-30 07:48:40 -0700536 return []string{
537 "libgtest",
538 "libgtest_main",
539 }
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000540 }
Yu Liu323d77a2024-12-16 23:13:57 +0000541 } else if info.LinkerInfo.BenchmarkDecoratorInfo != nil {
Tomasz Wasilczyk6e2b8c02024-05-30 07:48:40 -0700542 return []string{"libgoogle-benchmark"}
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000543 }
544 return nil
545}
546
Yu Liu323d77a2024-12-16 23:13:57 +0000547func getIncludeDirs(ctx android.ModuleContext, m android.ModuleProxy, info *CcInfo) []string {
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000548 moduleDir := ctx.OtherModuleDir(m) + string(filepath.Separator)
Yu Liu323d77a2024-12-16 23:13:57 +0000549 if info.CompilerInfo.LibraryDecoratorInfo != nil {
Cole Faustc9b88c92025-02-06 17:58:26 -0800550 return sliceWithPrefix(moduleDir, info.CompilerInfo.LibraryDecoratorInfo.ExportIncludeDirs)
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000551 }
552 return nil
553}
554
Tomasz Wasilczykd848dcc2024-05-10 09:16:37 -0700555func cmakeSnapshotLoadHook(ctx android.LoadHookContext) {
556 props := struct {
557 Target struct {
558 Darwin struct {
559 Enabled *bool
560 }
561 Windows struct {
562 Enabled *bool
563 }
564 }
565 }{}
566 props.Target.Darwin.Enabled = proptools.BoolPtr(false)
567 props.Target.Windows.Enabled = proptools.BoolPtr(false)
568 ctx.AppendProperties(&props)
569}
570
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000571// cmake_snapshot allows defining source packages for release outside of Android build tree.
572// As a result of cmake_snapshot module build, a zip file is generated with CMake build definitions
573// for selected source modules, their dependencies and optionally also the source code itself.
574func CmakeSnapshotFactory() android.Module {
575 module := &CmakeSnapshot{}
576 module.AddProperties(&module.Properties)
Tomasz Wasilczykd848dcc2024-05-10 09:16:37 -0700577 android.AddLoadHook(module, cmakeSnapshotLoadHook)
578 android.InitAndroidArchModule(module, android.HostSupported, android.MultilibFirst)
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000579 return module
580}
581
582func init() {
583 android.InitRegistrationContext.RegisterModuleType("cc_cmake_snapshot", CmakeSnapshotFactory)
584}