blob: b7977645384f54e5c9d9cbeb23b4a33bb0a6c8f2 [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 Wasilczyk7cec7e62024-07-01 11:31:47 -070072 "libc_musl",
73 "libc_musl_crtbegin_so",
74 "libc_musl_crtbegin_static",
75 "libc_musl_crtend",
76 "libc_musl_crtend_so",
Tomasz Wasilczyk2493fcc2024-06-20 15:29:09 -070077 "libdl",
78 "libm",
Hao Chen1c8ea5b2023-10-20 23:03:45 +000079 "prebuilt_libclang_rt.builtins",
80 "prebuilt_libclang_rt.ubsan_minimal",
81}
82
83// Mapping entry between Android's library name and the one used when building outside Android tree.
84type LibraryMappingProperty struct {
85 // Android library name.
86 Android_name string
87
88 // Library name used when building outside Android.
89 Mapped_name string
90
91 // If the make file is already present in Android source tree, specify its location.
92 Package_pregenerated string
93
94 // If the package is expected to be installed on the build host OS, specify its name.
95 Package_system string
96}
97
98type CmakeSnapshotProperties struct {
Tomasz Wasilczykd38d1402024-06-27 10:41:55 -070099 // TODO: remove
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000100 Modules []string
101
Tomasz Wasilczykd38d1402024-06-27 10:41:55 -0700102 // Host modules to add to the snapshot package. Their dependencies are pulled in automatically.
103 Modules_host []string
104
105 // System modules to add to the snapshot package. Their dependencies are pulled in automatically.
106 Modules_system []string
107
108 // Vendor modules to add to the snapshot package. Their dependencies are pulled in automatically.
109 Modules_vendor []string
110
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000111 // Host prebuilts to bundle with the snapshot. These are tools needed to build outside Android.
112 Prebuilts []string
113
114 // Global cflags to add when building outside Android.
115 Cflags []string
116
117 // Flags to skip when building outside Android.
118 Cflags_ignored []string
119
120 // Mapping between library names used in Android tree and externally.
121 Library_mapping []LibraryMappingProperty
122
123 // List of cflags that are not portable between compilers that could potentially be used to
124 // build a generated package. If left empty, it's initialized with a default list.
125 Unportable_flags []string
126
127 // Whether to include source code as part of the snapshot package.
128 Include_sources bool
129}
130
131var cmakeSnapshotSourcesProvider = blueprint.NewProvider[android.Paths]()
132
133type CmakeSnapshot struct {
134 android.ModuleBase
135
136 Properties CmakeSnapshotProperties
137
138 zipPath android.WritablePath
139}
140
141type cmakeProcessedProperties struct {
142 LibraryMapping map[string]LibraryMappingProperty
143 PregeneratedPackages []string
144 SystemPackages []string
145}
146
147type cmakeSnapshotDependencyTag struct {
148 blueprint.BaseDependencyTag
149 name string
150}
151
152var (
153 cmakeSnapshotModuleTag = cmakeSnapshotDependencyTag{name: "cmake-snapshot-module"}
154 cmakeSnapshotPrebuiltTag = cmakeSnapshotDependencyTag{name: "cmake-snapshot-prebuilt"}
155)
156
157func parseTemplate(templateContents string) *template.Template {
158 funcMap := template.FuncMap{
159 "setList": func(name string, nameSuffix string, itemPrefix string, items []string) string {
160 var list strings.Builder
161 list.WriteString("set(" + name + nameSuffix)
162 templateListBuilder(&list, itemPrefix, items)
163 return list.String()
164 },
165 "toStrings": func(files android.Paths) []string {
Colin Cross7de1db72024-06-25 14:36:24 -0700166 return files.Strings()
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000167 },
168 "concat5": func(list1 []string, list2 []string, list3 []string, list4 []string, list5 []string) []string {
169 return append(append(append(append(list1, list2...), list3...), list4...), list5...)
170 },
171 "cflagsList": func(name string, nameSuffix string, flags []string,
172 unportableFlags []string, ignoredFlags []string) string {
173 if len(unportableFlags) == 0 {
174 unportableFlags = defaultUnportableFlags
175 }
176
177 var filteredPortable []string
178 var filteredUnportable []string
179 for _, flag := range flags {
180 if slices.Contains(ignoredFlags, flag) {
181 continue
182 } else if slices.Contains(unportableFlags, flag) {
183 filteredUnportable = append(filteredUnportable, flag)
184 } else {
185 filteredPortable = append(filteredPortable, flag)
186 }
187 }
188
189 var list strings.Builder
190
191 list.WriteString("set(" + name + nameSuffix)
192 templateListBuilder(&list, "", filteredPortable)
193
194 if len(filteredUnportable) > 0 {
195 list.WriteString("\nappend_cxx_flags_if_supported(" + name + nameSuffix)
196 templateListBuilder(&list, "", filteredUnportable)
197 }
198
199 return list.String()
200 },
201 "getSources": func(m *Module) android.Paths {
202 return m.compiler.(CompiledInterface).Srcs()
203 },
204 "getModuleType": getModuleType,
205 "getCompilerProperties": func(m *Module) BaseCompilerProperties {
206 return m.compiler.baseCompilerProps()
207 },
Cole Fauste96c16a2024-06-13 14:51:14 -0700208 "getCflagsProperty": func(ctx android.ModuleContext, m *Module) []string {
209 cflags := m.compiler.baseCompilerProps().Cflags
210 return cflags.GetOrDefault(ctx, nil)
211 },
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000212 "getLinkerProperties": func(m *Module) BaseLinkerProperties {
213 return m.linker.baseLinkerProps()
214 },
215 "getExtraLibs": getExtraLibs,
216 "getIncludeDirs": getIncludeDirs,
Tomasz Wasilczyk1e831bf2024-05-10 15:15:21 -0700217 "mapLibraries": func(ctx android.ModuleContext, m *Module, libs []string, mapping map[string]LibraryMappingProperty) []string {
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000218 var mappedLibs []string
219 for _, lib := range libs {
220 mappedLib, exists := mapping[lib]
221 if exists {
222 lib = mappedLib.Mapped_name
223 } else {
Tomasz Wasilczyk1e831bf2024-05-10 15:15:21 -0700224 if !ctx.OtherModuleExists(lib) {
225 ctx.OtherModuleErrorf(m, "Dependency %s doesn't exist", lib)
226 }
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000227 lib = "android::" + lib
228 }
229 if lib == "" {
230 continue
231 }
232 mappedLibs = append(mappedLibs, lib)
233 }
234 sort.Strings(mappedLibs)
235 mappedLibs = slices.Compact(mappedLibs)
236 return mappedLibs
237 },
Tomasz Wasilczyk1e831bf2024-05-10 15:15:21 -0700238 "getAidlSources": func(m *Module) []string {
239 aidlInterface := m.compiler.baseCompilerProps().AidlInterface
240 aidlRoot := aidlInterface.AidlRoot + string(filepath.Separator)
241 if aidlInterface.AidlRoot == "" {
242 aidlRoot = ""
243 }
244 var sources []string
245 for _, src := range aidlInterface.Sources {
246 if !strings.HasPrefix(src, aidlRoot) {
247 panic(fmt.Sprintf("Aidl source '%v' doesn't start with '%v'", src, aidlRoot))
248 }
249 sources = append(sources, src[len(aidlRoot):])
250 }
251 return sources
252 },
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000253 }
254
255 return template.Must(template.New("").Delims("<<", ">>").Funcs(funcMap).Parse(templateContents))
256}
257
258func sliceWithPrefix(prefix string, slice []string) []string {
259 output := make([]string, len(slice))
260 for i, elem := range slice {
261 output[i] = prefix + elem
262 }
263 return output
264}
265
266func templateListBuilder(builder *strings.Builder, itemPrefix string, items []string) {
267 if len(items) > 0 {
268 builder.WriteString("\n")
269 for _, item := range items {
270 builder.WriteString(" " + itemPrefix + item + "\n")
271 }
272 }
273 builder.WriteString(")")
274}
275
276func executeTemplate(templ *template.Template, buffer *bytes.Buffer, data any) string {
277 buffer.Reset()
278 if err := templ.Execute(buffer, data); err != nil {
279 panic(err)
280 }
281 output := strings.TrimSpace(buffer.String())
282 buffer.Reset()
283 return output
284}
285
286func (m *CmakeSnapshot) DepsMutator(ctx android.BottomUpMutatorContext) {
Tomasz Wasilczykd38d1402024-06-27 10:41:55 -0700287 deviceVariations := ctx.Config().AndroidFirstDeviceTarget.Variations()
288 deviceSystemVariations := append(deviceVariations, blueprint.Variation{"image", ""})
289 deviceVendorVariations := append(deviceVariations, blueprint.Variation{"image", "vendor"})
Tomasz Wasilczyk9288b512024-06-27 09:22:12 -0700290 hostVariations := ctx.Config().BuildOSTarget.Variations()
Tomasz Wasilczykd38d1402024-06-27 10:41:55 -0700291
Tomasz Wasilczyk9288b512024-06-27 09:22:12 -0700292 ctx.AddVariationDependencies(hostVariations, cmakeSnapshotModuleTag, m.Properties.Modules...)
Tomasz Wasilczykd38d1402024-06-27 10:41:55 -0700293 ctx.AddVariationDependencies(hostVariations, cmakeSnapshotModuleTag, m.Properties.Modules_host...)
294 ctx.AddVariationDependencies(deviceSystemVariations, cmakeSnapshotModuleTag, m.Properties.Modules_system...)
295 ctx.AddVariationDependencies(deviceVendorVariations, cmakeSnapshotModuleTag, m.Properties.Modules_vendor...)
Tomasz Wasilczyk2493fcc2024-06-20 15:29:09 -0700296
297 if len(m.Properties.Prebuilts) > 0 {
298 prebuilts := append(m.Properties.Prebuilts, "libc++")
Tomasz Wasilczyk9288b512024-06-27 09:22:12 -0700299 ctx.AddVariationDependencies(hostVariations, cmakeSnapshotPrebuiltTag, prebuilts...)
Tomasz Wasilczyk2493fcc2024-06-20 15:29:09 -0700300 }
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000301}
302
303func (m *CmakeSnapshot) GenerateAndroidBuildActions(ctx android.ModuleContext) {
304 var templateBuffer bytes.Buffer
305 var pprop cmakeProcessedProperties
306 m.zipPath = android.PathForModuleOut(ctx, ctx.ModuleName()+".zip")
307
308 // Process Library_mapping for more efficient lookups
309 pprop.LibraryMapping = map[string]LibraryMappingProperty{}
310 for _, elem := range m.Properties.Library_mapping {
311 pprop.LibraryMapping[elem.Android_name] = elem
312
313 if elem.Package_pregenerated != "" {
314 pprop.PregeneratedPackages = append(pprop.PregeneratedPackages, elem.Package_pregenerated)
315 }
316 sort.Strings(pprop.PregeneratedPackages)
317 pprop.PregeneratedPackages = slices.Compact(pprop.PregeneratedPackages)
318
319 if elem.Package_system != "" {
320 pprop.SystemPackages = append(pprop.SystemPackages, elem.Package_system)
321 }
322 sort.Strings(pprop.SystemPackages)
323 pprop.SystemPackages = slices.Compact(pprop.SystemPackages)
324 }
325
326 // Generating CMakeLists.txt rules for all modules in dependency tree
327 moduleDirs := map[string][]string{}
328 sourceFiles := map[string]android.Path{}
329 visitedModules := map[string]bool{}
330 var pregeneratedModules []*Module
331 ctx.WalkDeps(func(dep_a android.Module, parent android.Module) bool {
332 moduleName := ctx.OtherModuleName(dep_a)
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000333 if visited := visitedModules[moduleName]; visited {
334 return false // visit only once
335 }
336 visitedModules[moduleName] = true
Tomasz Wasilczyk1e831bf2024-05-10 15:15:21 -0700337 dep, ok := dep_a.(*Module)
338 if !ok {
339 return false // not a cc module
340 }
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000341 if mapping, ok := pprop.LibraryMapping[moduleName]; ok {
342 if mapping.Package_pregenerated != "" {
343 pregeneratedModules = append(pregeneratedModules, dep)
344 }
345 return false // mapped to system or pregenerated (we'll handle these later)
346 }
347 if ctx.OtherModuleDependencyTag(dep) == cmakeSnapshotPrebuiltTag {
348 return false // we'll handle cmakeSnapshotPrebuiltTag later
349 }
350 if slices.Contains(ignoredSystemLibs, moduleName) {
351 return false // system libs built in-tree for Android
352 }
353 if dep.compiler == nil {
354 return false // unsupported module type (e.g. prebuilt)
355 }
356 isAidlModule := dep.compiler.baseCompilerProps().AidlInterface.Lang != ""
357
358 if !proptools.Bool(dep.Properties.Cmake_snapshot_supported) {
359 ctx.OtherModulePropertyErrorf(dep, "cmake_snapshot_supported",
360 "CMake snapshots not supported, despite being a dependency for %s",
361 ctx.OtherModuleName(parent))
362 return false
363 }
364
365 if veryVerbose {
366 fmt.Println("WalkDeps: " + ctx.OtherModuleName(parent) + " -> " + moduleName)
367 }
368
369 // Generate CMakeLists.txt fragment for this module
370 templateToUse := templateCmakeModuleCc
371 if isAidlModule {
372 templateToUse = templateCmakeModuleAidl
373 }
374 moduleFragment := executeTemplate(templateToUse, &templateBuffer, struct {
375 Ctx *android.ModuleContext
376 M *Module
377 Snapshot *CmakeSnapshot
378 Pprop *cmakeProcessedProperties
379 }{
380 &ctx,
381 dep,
382 m,
383 &pprop,
384 })
385 moduleDir := ctx.OtherModuleDir(dep)
386 moduleDirs[moduleDir] = append(moduleDirs[moduleDir], moduleFragment)
387
388 if m.Properties.Include_sources {
389 files, _ := android.OtherModuleProvider(ctx, dep, cmakeSnapshotSourcesProvider)
390 for _, file := range files {
391 sourceFiles[file.String()] = file
392 }
393 }
394
395 // if it's AIDL module, no need to dive into their dependencies
396 return !isAidlModule
397 })
398
399 // Enumerate sources for pregenerated modules
400 if m.Properties.Include_sources {
401 for _, dep := range pregeneratedModules {
402 if !proptools.Bool(dep.Properties.Cmake_snapshot_supported) {
403 ctx.OtherModulePropertyErrorf(dep, "cmake_snapshot_supported",
404 "Pregenerated CMake snapshots not supported, despite being requested for %s",
405 ctx.ModuleName())
406 continue
407 }
408
409 files, _ := android.OtherModuleProvider(ctx, dep, cmakeSnapshotSourcesProvider)
410 for _, file := range files {
411 sourceFiles[file.String()] = file
412 }
413 }
414 }
415
416 // Merging CMakeLists.txt contents for every module directory
417 var makefilesList android.Paths
Colin Cross7de1db72024-06-25 14:36:24 -0700418 for _, moduleDir := range android.SortedKeys(moduleDirs) {
419 fragments := moduleDirs[moduleDir]
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000420 moduleCmakePath := android.PathForModuleGen(ctx, moduleDir, "CMakeLists.txt")
421 makefilesList = append(makefilesList, moduleCmakePath)
422 sort.Strings(fragments)
423 android.WriteFileRule(ctx, moduleCmakePath, strings.Join(fragments, "\n\n\n"))
424 }
425
426 // Generating top-level CMakeLists.txt
427 mainCmakePath := android.PathForModuleGen(ctx, "CMakeLists.txt")
428 makefilesList = append(makefilesList, mainCmakePath)
429 mainContents := executeTemplate(templateCmakeMain, &templateBuffer, struct {
430 Ctx *android.ModuleContext
431 M *CmakeSnapshot
432 ModuleDirs map[string][]string
433 Pprop *cmakeProcessedProperties
434 }{
435 &ctx,
436 m,
437 moduleDirs,
438 &pprop,
439 })
440 android.WriteFileRule(ctx, mainCmakePath, mainContents)
441
442 // Generating CMake extensions
443 extPath := android.PathForModuleGen(ctx, "cmake", "AppendCxxFlagsIfSupported.cmake")
444 makefilesList = append(makefilesList, extPath)
445 android.WriteFileRuleVerbatim(ctx, extPath, cmakeExtAppendFlags)
446 extPath = android.PathForModuleGen(ctx, "cmake", "AddAidlLibrary.cmake")
447 makefilesList = append(makefilesList, extPath)
448 android.WriteFileRuleVerbatim(ctx, extPath, cmakeExtAddAidlLibrary)
449
450 // Generating the final zip file
451 zipRule := android.NewRuleBuilder(pctx, ctx)
452 zipCmd := zipRule.Command().
453 BuiltTool("soong_zip").
454 FlagWithOutput("-o ", m.zipPath)
455
456 // Packaging all sources into the zip file
457 if m.Properties.Include_sources {
458 var sourcesList android.Paths
Colin Cross7de1db72024-06-25 14:36:24 -0700459 for _, file := range android.SortedKeys(sourceFiles) {
460 path := sourceFiles[file]
461 sourcesList = append(sourcesList, path)
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000462 }
463
464 sourcesRspFile := android.PathForModuleObj(ctx, ctx.ModuleName()+"_sources.rsp")
465 zipCmd.FlagWithRspFileInputList("-r ", sourcesRspFile, sourcesList)
466 }
467
468 // Packaging all make files into the zip file
469 makefilesRspFile := android.PathForModuleObj(ctx, ctx.ModuleName()+"_makefiles.rsp")
470 zipCmd.
471 FlagWithArg("-C ", android.PathForModuleGen(ctx).OutputPath.String()).
472 FlagWithRspFileInputList("-r ", makefilesRspFile, makefilesList)
473
474 // Packaging all prebuilts into the zip file
475 if len(m.Properties.Prebuilts) > 0 {
476 var prebuiltsList android.Paths
477
478 ctx.VisitDirectDepsWithTag(cmakeSnapshotPrebuiltTag, func(dep android.Module) {
479 for _, file := range dep.FilesToInstall() {
480 prebuiltsList = append(prebuiltsList, file)
481 }
482 })
483
484 prebuiltsRspFile := android.PathForModuleObj(ctx, ctx.ModuleName()+"_prebuilts.rsp")
485 zipCmd.
486 FlagWithArg("-C ", android.PathForArbitraryOutput(ctx).String()).
487 FlagWithArg("-P ", "prebuilts").
488 FlagWithRspFileInputList("-r ", prebuiltsRspFile, prebuiltsList)
489 }
490
491 // Finish generating the final zip file
492 zipRule.Build(m.zipPath.String(), "archiving "+ctx.ModuleName())
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000493
mrziwangf95cfa62024-06-18 10:11:39 -0700494 ctx.SetOutputFiles(android.Paths{m.zipPath}, "")
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000495}
496
497func (m *CmakeSnapshot) AndroidMkEntries() []android.AndroidMkEntries {
498 return []android.AndroidMkEntries{{
499 Class: "DATA",
500 OutputFile: android.OptionalPathForPath(m.zipPath),
501 ExtraEntries: []android.AndroidMkExtraEntriesFunc{
502 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
503 entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
504 },
505 },
506 }}
507}
508
509func getModuleType(m *Module) string {
510 switch m.linker.(type) {
511 case *binaryDecorator:
512 return "executable"
513 case *libraryDecorator:
514 return "library"
515 case *testBinary:
Tomasz Wasilczykc3177e02024-06-10 14:38:45 -0700516 return "test"
Tomasz Wasilczyk6e2b8c02024-05-30 07:48:40 -0700517 case *benchmarkDecorator:
Tomasz Wasilczykc3177e02024-06-10 14:38:45 -0700518 return "test"
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000519 }
Tomasz Wasilczyk6e2b8c02024-05-30 07:48:40 -0700520 panic(fmt.Sprintf("Unexpected module type: %T", m.linker))
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000521}
522
523func getExtraLibs(m *Module) []string {
524 switch decorator := m.linker.(type) {
525 case *testBinary:
526 if decorator.testDecorator.gtest() {
Tomasz Wasilczyk6e2b8c02024-05-30 07:48:40 -0700527 return []string{
528 "libgtest",
529 "libgtest_main",
530 }
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000531 }
Tomasz Wasilczyk6e2b8c02024-05-30 07:48:40 -0700532 case *benchmarkDecorator:
533 return []string{"libgoogle-benchmark"}
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000534 }
535 return nil
536}
537
538func getIncludeDirs(ctx android.ModuleContext, m *Module) []string {
539 moduleDir := ctx.OtherModuleDir(m) + string(filepath.Separator)
540 switch decorator := m.compiler.(type) {
541 case *libraryDecorator:
Aleks Todorovc9becde2024-06-10 12:51:53 +0100542 return sliceWithPrefix(moduleDir, decorator.flagExporter.Properties.Export_include_dirs.GetOrDefault(ctx, nil))
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000543 }
544 return nil
545}
546
Tomasz Wasilczykd848dcc2024-05-10 09:16:37 -0700547func cmakeSnapshotLoadHook(ctx android.LoadHookContext) {
548 props := struct {
549 Target struct {
550 Darwin struct {
551 Enabled *bool
552 }
553 Windows struct {
554 Enabled *bool
555 }
556 }
557 }{}
558 props.Target.Darwin.Enabled = proptools.BoolPtr(false)
559 props.Target.Windows.Enabled = proptools.BoolPtr(false)
560 ctx.AppendProperties(&props)
561}
562
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000563// cmake_snapshot allows defining source packages for release outside of Android build tree.
564// As a result of cmake_snapshot module build, a zip file is generated with CMake build definitions
565// for selected source modules, their dependencies and optionally also the source code itself.
566func CmakeSnapshotFactory() android.Module {
567 module := &CmakeSnapshot{}
568 module.AddProperties(&module.Properties)
Tomasz Wasilczykd848dcc2024-05-10 09:16:37 -0700569 android.AddLoadHook(module, cmakeSnapshotLoadHook)
570 android.InitAndroidArchModule(module, android.HostSupported, android.MultilibFirst)
Hao Chen1c8ea5b2023-10-20 23:03:45 +0000571 return module
572}
573
574func init() {
575 android.InitRegistrationContext.RegisterModuleType("cc_cmake_snapshot", CmakeSnapshotFactory)
576}