xref: /aosp_15_r20/build/soong/android/variable.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
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 android
16
17import (
18	"fmt"
19	"reflect"
20	"runtime"
21	"strings"
22
23	"github.com/google/blueprint/proptools"
24)
25
26func init() {
27	registerVariableBuildComponents(InitRegistrationContext)
28}
29
30func registerVariableBuildComponents(ctx RegistrationContext) {
31	ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) {
32		ctx.BottomUp("variable", VariableMutator)
33	})
34}
35
36var PrepareForTestWithVariables = FixtureRegisterWithContext(registerVariableBuildComponents)
37
38type variableProperties struct {
39	Product_variables struct {
40		Platform_sdk_version struct {
41			Asflags []string
42			Cflags  []string
43			Cmd     *string
44		}
45
46		Platform_sdk_version_or_codename struct {
47			Java_resource_dirs []string
48		}
49
50		Platform_sdk_extension_version struct {
51			Cmd *string
52		}
53
54		Platform_version_name struct {
55			Base_dir *string
56		}
57
58		Shipping_api_level struct {
59			Cflags []string
60		}
61
62		// unbundled_build is a catch-all property to annotate modules that don't build in one or
63		// more unbundled branches, usually due to dependencies missing from the manifest.
64		Unbundled_build struct {
65			Enabled proptools.Configurable[bool] `android:"arch_variant,replace_instead_of_append"`
66		} `android:"arch_variant"`
67
68		// similar to `Unbundled_build`, but `Always_use_prebuilt_sdks` means that it uses prebuilt
69		// sdk specifically.
70		Always_use_prebuilt_sdks struct {
71			Enabled proptools.Configurable[bool] `android:"arch_variant,replace_instead_of_append"`
72		} `android:"arch_variant"`
73
74		Malloc_low_memory struct {
75			Cflags              []string `android:"arch_variant"`
76			Shared_libs         []string `android:"arch_variant"`
77			Whole_static_libs   []string `android:"arch_variant"`
78			Static_libs         []string `android:"arch_variant"`
79			Exclude_static_libs []string `android:"arch_variant"`
80			Srcs                []string `android:"arch_variant"`
81			Header_libs         []string `android:"arch_variant"`
82		} `android:"arch_variant"`
83
84		Malloc_zero_contents struct {
85			Cflags []string `android:"arch_variant"`
86		} `android:"arch_variant"`
87
88		Malloc_pattern_fill_contents struct {
89			Cflags []string `android:"arch_variant"`
90		} `android:"arch_variant"`
91
92		Safestack struct {
93			Cflags []string `android:"arch_variant"`
94		} `android:"arch_variant"`
95
96		Binder32bit struct {
97			Cflags []string
98		}
99
100		Override_rs_driver struct {
101			Cflags []string
102		}
103
104		// treble_linker_namespaces is true when the system/vendor linker namespace separation is
105		// enabled.
106		Treble_linker_namespaces struct {
107			Cflags []string
108		}
109		// enforce_vintf_manifest is true when a device is required to have a vintf manifest.
110		Enforce_vintf_manifest struct {
111			Cflags []string
112		}
113
114		Build_from_text_stub struct {
115			Static_libs         []string
116			Exclude_static_libs []string
117		}
118
119		// debuggable is true for eng and userdebug builds, and can be used to turn on additional
120		// debugging features that don't significantly impact runtime behavior.  userdebug builds
121		// are used for dogfooding and performance testing, and should be as similar to user builds
122		// as possible.
123		Debuggable struct {
124			Apk             *string
125			Cflags          []string
126			Cppflags        []string
127			Init_rc         []string
128			Required        []string
129			Host_required   []string
130			Target_required []string
131			Strip           struct {
132				All                          *bool
133				Keep_symbols                 *bool
134				Keep_symbols_and_debug_frame *bool
135			}
136			Static_libs         []string
137			Exclude_static_libs []string
138			Whole_static_libs   []string
139			Shared_libs         []string
140			Jni_libs            []string
141
142			Cmdline []string
143
144			Srcs         []string
145			Exclude_srcs []string
146			Cmd          *string
147
148			Deps []string
149		}
150
151		// eng is true for -eng builds, and can be used to turn on additional heavyweight debugging
152		// features.
153		Eng struct {
154			Cflags   []string
155			Cppflags []string
156			Lto      struct {
157				Never *bool
158			}
159			Sanitize struct {
160				Address *bool
161			}
162			Optimize struct {
163				Enabled *bool
164			}
165		}
166
167		Uml struct {
168			Cppflags []string
169		}
170
171		Arc struct {
172			Cflags            []string `android:"arch_variant"`
173			Exclude_srcs      []string `android:"arch_variant"`
174			Header_libs       []string `android:"arch_variant"`
175			Include_dirs      []string `android:"arch_variant"`
176			Shared_libs       []string `android:"arch_variant"`
177			Static_libs       []string `android:"arch_variant"`
178			Srcs              []string `android:"arch_variant"`
179			Whole_static_libs []string `android:"arch_variant"`
180		} `android:"arch_variant"`
181
182		Native_coverage struct {
183			Src          *string  `android:"arch_variant"`
184			Srcs         []string `android:"arch_variant"`
185			Exclude_srcs []string `android:"arch_variant"`
186		} `android:"arch_variant"`
187
188		// release_aidl_use_unfrozen is "true" when a device can
189		// use the unfrozen versions of AIDL interfaces.
190		Release_aidl_use_unfrozen struct {
191			Cflags                 []string
192			Cmd                    *string
193			Required               []string
194			Vintf_fragment_modules []string
195		}
196		SelinuxIgnoreNeverallows struct {
197			Required []string
198		}
199	} `android:"arch_variant"`
200}
201
202var defaultProductVariables interface{} = variableProperties{}
203
204type ProductVariables struct {
205	// Suffix to add to generated Makefiles
206	Make_suffix *string `json:",omitempty"`
207
208	BuildId              *string `json:",omitempty"`
209	BuildFingerprintFile *string `json:",omitempty"`
210	BuildNumberFile      *string `json:",omitempty"`
211	BuildHostnameFile    *string `json:",omitempty"`
212	BuildThumbprintFile  *string `json:",omitempty"`
213	DisplayBuildNumber   *bool   `json:",omitempty"`
214
215	Platform_display_version_name          *string  `json:",omitempty"`
216	Platform_version_name                  *string  `json:",omitempty"`
217	Platform_sdk_version                   *int     `json:",omitempty"`
218	Platform_sdk_minor_version             *int     `json:",omitempty"`
219	Platform_sdk_codename                  *string  `json:",omitempty"`
220	Platform_sdk_version_or_codename       *string  `json:",omitempty"`
221	Platform_sdk_final                     *bool    `json:",omitempty"`
222	Platform_sdk_extension_version         *int     `json:",omitempty"`
223	Platform_base_sdk_extension_version    *int     `json:",omitempty"`
224	Platform_version_active_codenames      []string `json:",omitempty"`
225	Platform_version_all_preview_codenames []string `json:",omitempty"`
226	Platform_systemsdk_versions            []string `json:",omitempty"`
227	Platform_security_patch                *string  `json:",omitempty"`
228	Platform_preview_sdk_version           *string  `json:",omitempty"`
229	Platform_base_os                       *string  `json:",omitempty"`
230	Platform_version_last_stable           *string  `json:",omitempty"`
231	Platform_version_known_codenames       *string  `json:",omitempty"`
232
233	DeviceName                            *string  `json:",omitempty"`
234	DeviceProduct                         *string  `json:",omitempty"`
235	DeviceArch                            *string  `json:",omitempty"`
236	DeviceArchVariant                     *string  `json:",omitempty"`
237	DeviceCpuVariant                      *string  `json:",omitempty"`
238	DeviceAbi                             []string `json:",omitempty"`
239	DeviceVndkVersion                     *string  `json:",omitempty"`
240	DeviceCurrentApiLevelForVendorModules *string  `json:",omitempty"`
241	DeviceSystemSdkVersions               []string `json:",omitempty"`
242	DeviceMaxPageSizeSupported            *string  `json:",omitempty"`
243	DeviceNoBionicPageSizeMacro           *bool    `json:",omitempty"`
244
245	VendorApiLevel             *string `json:",omitempty"`
246	VendorApiLevelPropOverride *string `json:",omitempty"`
247
248	DeviceSecondaryArch        *string  `json:",omitempty"`
249	DeviceSecondaryArchVariant *string  `json:",omitempty"`
250	DeviceSecondaryCpuVariant  *string  `json:",omitempty"`
251	DeviceSecondaryAbi         []string `json:",omitempty"`
252
253	NativeBridgeArch         *string  `json:",omitempty"`
254	NativeBridgeArchVariant  *string  `json:",omitempty"`
255	NativeBridgeCpuVariant   *string  `json:",omitempty"`
256	NativeBridgeAbi          []string `json:",omitempty"`
257	NativeBridgeRelativePath *string  `json:",omitempty"`
258
259	NativeBridgeSecondaryArch         *string  `json:",omitempty"`
260	NativeBridgeSecondaryArchVariant  *string  `json:",omitempty"`
261	NativeBridgeSecondaryCpuVariant   *string  `json:",omitempty"`
262	NativeBridgeSecondaryAbi          []string `json:",omitempty"`
263	NativeBridgeSecondaryRelativePath *string  `json:",omitempty"`
264
265	HostArch          *string `json:",omitempty"`
266	HostSecondaryArch *string `json:",omitempty"`
267	HostMusl          *bool   `json:",omitempty"`
268
269	CrossHost              *string `json:",omitempty"`
270	CrossHostArch          *string `json:",omitempty"`
271	CrossHostSecondaryArch *string `json:",omitempty"`
272
273	DeviceResourceOverlays     []string `json:",omitempty"`
274	ProductResourceOverlays    []string `json:",omitempty"`
275	EnforceRROTargets          []string `json:",omitempty"`
276	EnforceRROExcludedOverlays []string `json:",omitempty"`
277
278	AAPTCharacteristics *string  `json:",omitempty"`
279	AAPTConfig          []string `json:",omitempty"`
280	AAPTPreferredConfig *string  `json:",omitempty"`
281	AAPTPrebuiltDPI     []string `json:",omitempty"`
282
283	DefaultAppCertificate           *string  `json:",omitempty"`
284	ExtraOtaKeys                    []string `json:",omitempty"`
285	ExtraOtaRecoveryKeys            []string `json:",omitempty"`
286	MainlineSepolicyDevCertificates *string  `json:",omitempty"`
287
288	AppsDefaultVersionName *string `json:",omitempty"`
289
290	Allow_missing_dependencies   *bool    `json:",omitempty"`
291	Unbundled_build              *bool    `json:",omitempty"`
292	Unbundled_build_apps         []string `json:",omitempty"`
293	Unbundled_build_image        *bool    `json:",omitempty"`
294	Always_use_prebuilt_sdks     *bool    `json:",omitempty"`
295	Skip_boot_jars_check         *bool    `json:",omitempty"`
296	Malloc_low_memory            *bool    `json:",omitempty"`
297	Malloc_zero_contents         *bool    `json:",omitempty"`
298	Malloc_pattern_fill_contents *bool    `json:",omitempty"`
299	Safestack                    *bool    `json:",omitempty"`
300	HostStaticBinaries           *bool    `json:",omitempty"`
301	Binder32bit                  *bool    `json:",omitempty"`
302	UseGoma                      *bool    `json:",omitempty"`
303	UseABFS                      *bool    `json:",omitempty"`
304	UseRBE                       *bool    `json:",omitempty"`
305	UseRBEJAVAC                  *bool    `json:",omitempty"`
306	UseRBER8                     *bool    `json:",omitempty"`
307	UseRBED8                     *bool    `json:",omitempty"`
308	Debuggable                   *bool    `json:",omitempty"`
309	Eng                          *bool    `json:",omitempty"`
310	Treble_linker_namespaces     *bool    `json:",omitempty"`
311	Enforce_vintf_manifest       *bool    `json:",omitempty"`
312	Uml                          *bool    `json:",omitempty"`
313	Arc                          *bool    `json:",omitempty"`
314	MinimizeJavaDebugInfo        *bool    `json:",omitempty"`
315	Build_from_text_stub         *bool    `json:",omitempty"`
316
317	BuildType *string `json:",omitempty"`
318
319	Check_elf_files *bool `json:",omitempty"`
320
321	UncompressPrivAppDex             *bool    `json:",omitempty"`
322	ModulesLoadedByPrivilegedModules []string `json:",omitempty"`
323
324	BootJars     ConfiguredJarList `json:",omitempty"`
325	ApexBootJars ConfiguredJarList `json:",omitempty"`
326
327	IntegerOverflowExcludePaths []string `json:",omitempty"`
328
329	EnableCFI       *bool    `json:",omitempty"`
330	CFIExcludePaths []string `json:",omitempty"`
331	CFIIncludePaths []string `json:",omitempty"`
332
333	DisableScudo *bool `json:",omitempty"`
334
335	MemtagHeapExcludePaths      []string `json:",omitempty"`
336	MemtagHeapAsyncIncludePaths []string `json:",omitempty"`
337	MemtagHeapSyncIncludePaths  []string `json:",omitempty"`
338
339	HWASanIncludePaths []string `json:",omitempty"`
340	HWASanExcludePaths []string `json:",omitempty"`
341
342	VendorPath            *string `json:",omitempty"`
343	VendorDlkmPath        *string `json:",omitempty"`
344	BuildingVendorImage   *bool   `json:",omitempty"`
345	OdmPath               *string `json:",omitempty"`
346	BuildingOdmImage      *bool   `json:",omitempty"`
347	OdmDlkmPath           *string `json:",omitempty"`
348	ProductPath           *string `json:",omitempty"`
349	BuildingProductImage  *bool   `json:",omitempty"`
350	SystemExtPath         *string `json:",omitempty"`
351	SystemDlkmPath        *string `json:",omitempty"`
352	OemPath               *string `json:",omitempty"`
353	UserdataPath          *string `json:",omitempty"`
354	BuildingUserdataImage *bool   `json:",omitempty"`
355	RecoveryPath          *string `json:",omitempty"`
356	BuildingRecoveryImage *bool   `json:",omitempty"`
357
358	ClangTidy  *bool   `json:",omitempty"`
359	TidyChecks *string `json:",omitempty"`
360
361	JavaCoveragePaths        []string `json:",omitempty"`
362	JavaCoverageExcludePaths []string `json:",omitempty"`
363
364	GcovCoverage                *bool    `json:",omitempty"`
365	ClangCoverage               *bool    `json:",omitempty"`
366	NativeCoveragePaths         []string `json:",omitempty"`
367	NativeCoverageExcludePaths  []string `json:",omitempty"`
368	ClangCoverageContinuousMode *bool    `json:",omitempty"`
369
370	// Set by NewConfig
371	Native_coverage *bool `json:",omitempty"`
372
373	SanitizeHost       []string `json:",omitempty"`
374	SanitizeDevice     []string `json:",omitempty"`
375	SanitizeDeviceDiag []string `json:",omitempty"`
376	SanitizeDeviceArch []string `json:",omitempty"`
377
378	ArtUseReadBarrier *bool `json:",omitempty"`
379
380	BtConfigIncludeDir *string `json:",omitempty"`
381
382	Override_rs_driver *string `json:",omitempty"`
383
384	DeviceKernelHeaders []string `json:",omitempty"`
385
386	ExtraVndkVersions []string `json:",omitempty"`
387
388	NamespacesToExport []string `json:",omitempty"`
389
390	PgoAdditionalProfileDirs []string `json:",omitempty"`
391
392	MultitreeUpdateMeta bool `json:",omitempty"`
393
394	BoardVendorSepolicyDirs      []string `json:",omitempty"`
395	BoardOdmSepolicyDirs         []string `json:",omitempty"`
396	SystemExtPublicSepolicyDirs  []string `json:",omitempty"`
397	SystemExtPrivateSepolicyDirs []string `json:",omitempty"`
398	BoardSepolicyM4Defs          []string `json:",omitempty"`
399
400	BoardPlatform           *string `json:",omitempty"`
401	BoardSepolicyVers       *string `json:",omitempty"`
402	PlatformSepolicyVersion *string `json:",omitempty"`
403
404	SystemExtSepolicyPrebuiltApiDir *string `json:",omitempty"`
405	ProductSepolicyPrebuiltApiDir   *string `json:",omitempty"`
406
407	PlatformSepolicyCompatVersions []string `json:",omitempty"`
408
409	VendorVars     map[string]map[string]string `json:",omitempty"`
410	VendorVarTypes map[string]map[string]string `json:",omitempty"`
411
412	Ndk_abis *bool `json:",omitempty"`
413
414	ForceApexSymlinkOptimization *bool   `json:",omitempty"`
415	CompressedApex               *bool   `json:",omitempty"`
416	DefaultApexPayloadType       *string `json:",omitempty"`
417	Aml_abis                     *bool   `json:",omitempty"`
418
419	DexpreoptGlobalConfig *string `json:",omitempty"`
420
421	WithDexpreopt bool `json:",omitempty"`
422
423	ManifestPackageNameOverrides   []string `json:",omitempty"`
424	CertificateOverrides           []string `json:",omitempty"`
425	PackageNameOverrides           []string `json:",omitempty"`
426	ConfiguredJarLocationOverrides []string `json:",omitempty"`
427
428	ApexGlobalMinSdkVersionOverride *string `json:",omitempty"`
429
430	EnforceSystemCertificate          *bool    `json:",omitempty"`
431	EnforceSystemCertificateAllowList []string `json:",omitempty"`
432
433	ProductHiddenAPIStubs       []string `json:",omitempty"`
434	ProductHiddenAPIStubsSystem []string `json:",omitempty"`
435	ProductHiddenAPIStubsTest   []string `json:",omitempty"`
436
437	ProductPublicSepolicyDirs  []string `json:",omitempty"`
438	ProductPrivateSepolicyDirs []string `json:",omitempty"`
439
440	TargetFSConfigGen []string `json:",omitempty"`
441
442	UseSoongSystemImage            *bool   `json:",omitempty"`
443	ProductSoongDefinedSystemImage *string `json:",omitempty"`
444
445	EnforceProductPartitionInterface *bool `json:",omitempty"`
446
447	BoardUsesRecoveryAsBoot *bool `json:",omitempty"`
448
449	BoardKernelBinaries                []string `json:",omitempty"`
450	BoardKernelModuleInterfaceVersions []string `json:",omitempty"`
451
452	BoardMoveRecoveryResourcesToVendorBoot *bool `json:",omitempty"`
453
454	PrebuiltHiddenApiDir *string `json:",omitempty"`
455
456	Shipping_api_level *string `json:",omitempty"`
457
458	BuildBrokenPluginValidation         []string `json:",omitempty"`
459	BuildBrokenClangAsFlags             bool     `json:",omitempty"`
460	BuildBrokenClangCFlags              bool     `json:",omitempty"`
461	BuildBrokenClangProperty            bool     `json:",omitempty"`
462	GenruleSandboxing                   *bool    `json:",omitempty"`
463	BuildBrokenEnforceSyspropOwner      bool     `json:",omitempty"`
464	BuildBrokenTrebleSyspropNeverallow  bool     `json:",omitempty"`
465	BuildBrokenVendorPropertyNamespace  bool     `json:",omitempty"`
466	BuildBrokenIncorrectPartitionImages bool     `json:",omitempty"`
467	BuildBrokenInputDirModules          []string `json:",omitempty"`
468	BuildBrokenDontCheckSystemSdk       bool     `json:",omitempty"`
469	BuildBrokenDupSysprop               bool     `json:",omitempty"`
470
471	BuildWarningBadOptionalUsesLibsAllowlist []string `json:",omitempty"`
472
473	BuildDebugfsRestrictionsEnabled bool `json:",omitempty"`
474
475	RequiresInsecureExecmemForSwiftshader bool `json:",omitempty"`
476
477	SelinuxIgnoreNeverallows bool `json:",omitempty"`
478
479	Release_aidl_use_unfrozen *bool `json:",omitempty"`
480
481	SepolicyFreezeTestExtraDirs         []string `json:",omitempty"`
482	SepolicyFreezeTestExtraPrebuiltDirs []string `json:",omitempty"`
483
484	GenerateAidlNdkPlatformBackend bool `json:",omitempty"`
485
486	IgnorePrefer32OnDevice bool `json:",omitempty"`
487
488	SourceRootDirs []string `json:",omitempty"`
489
490	AfdoProfiles []string `json:",omitempty"`
491
492	ProductManufacturer string `json:",omitempty"`
493	ProductBrand        string `json:",omitempty"`
494	ProductDevice       string `json:",omitempty"`
495	ProductModel        string `json:",omitempty"`
496
497	ReleaseVersion          string   `json:",omitempty"`
498	ReleaseAconfigValueSets []string `json:",omitempty"`
499
500	ReleaseAconfigFlagDefaultPermission string `json:",omitempty"`
501
502	ReleaseDefaultModuleBuildFromSource *bool `json:",omitempty"`
503
504	CheckVendorSeappViolations *bool `json:",omitempty"`
505
506	BuildFlags map[string]string `json:",omitempty"`
507
508	BuildFlagTypes map[string]string `json:",omitempty"`
509
510	BuildFromSourceStub *bool `json:",omitempty"`
511
512	BuildIgnoreApexContributionContents *bool `json:",omitempty"`
513
514	HiddenapiExportableStubs *bool `json:",omitempty"`
515
516	ExportRuntimeApis *bool `json:",omitempty"`
517
518	AconfigContainerValidation string `json:",omitempty"`
519
520	ProductLocales []string `json:",omitempty"`
521
522	ProductDefaultWifiChannels []string `json:",omitempty"`
523
524	BoardUseVbmetaDigestInFingerprint *bool `json:",omitempty"`
525
526	OemProperties []string `json:",omitempty"`
527
528	ArtTargetIncludeDebugBuild *bool `json:",omitempty"`
529
530	SystemPropFiles    []string `json:",omitempty"`
531	SystemExtPropFiles []string `json:",omitempty"`
532	ProductPropFiles   []string `json:",omitempty"`
533	OdmPropFiles       []string `json:",omitempty"`
534	VendorPropFiles    []string `json:",omitempty"`
535
536	EnableUffdGc *string `json:",omitempty"`
537
538	BoardAvbEnable                         *bool    `json:",omitempty"`
539	BoardAvbSystemAddHashtreeFooterArgs    []string `json:",omitempty"`
540	DeviceFrameworkCompatibilityMatrixFile []string `json:",omitempty"`
541	DeviceProductCompatibilityMatrixFile   []string `json:",omitempty"`
542
543	PartitionVarsForSoongMigrationOnlyDoNotUse PartitionVariables
544
545	ExtraAllowedDepsTxt *string `json:",omitempty"`
546
547	AdbKeys *string `json:",omitempty"`
548
549	DeviceMatrixFile       []string `json:",omitempty"`
550	ProductManifestFiles   []string `json:",omitempty"`
551	SystemManifestFile     []string `json:",omitempty"`
552	SystemExtManifestFiles []string `json:",omitempty"`
553	DeviceManifestFiles    []string `json:",omitempty"`
554	OdmManifestFiles       []string `json:",omitempty"`
555}
556
557type PartitionQualifiedVariablesType struct {
558	BuildingImage               bool   `json:",omitempty"`
559	BoardErofsCompressor        string `json:",omitempty"`
560	BoardErofsCompressHints     string `json:",omitempty"`
561	BoardErofsPclusterSize      string `json:",omitempty"`
562	BoardExtfsInodeCount        string `json:",omitempty"`
563	BoardExtfsRsvPct            string `json:",omitempty"`
564	BoardF2fsSloadCompressFlags string `json:",omitempty"`
565	BoardFileSystemCompress     string `json:",omitempty"`
566	BoardFileSystemType         string `json:",omitempty"`
567	BoardJournalSize            string `json:",omitempty"`
568	BoardPartitionReservedSize  string `json:",omitempty"`
569	BoardPartitionSize          string `json:",omitempty"`
570	BoardSquashfsBlockSize      string `json:",omitempty"`
571	BoardSquashfsCompressor     string `json:",omitempty"`
572	BoardSquashfsCompressorOpt  string `json:",omitempty"`
573	BoardSquashfsDisable4kAlign string `json:",omitempty"`
574	ProductBaseFsPath           string `json:",omitempty"`
575	ProductHeadroom             string `json:",omitempty"`
576	ProductVerityPartition      string `json:",omitempty"`
577
578	BoardAvbAddHashtreeFooterArgs string `json:",omitempty"`
579	BoardAvbKeyPath               string `json:",omitempty"`
580	BoardAvbAlgorithm             string `json:",omitempty"`
581	BoardAvbRollbackIndex         string `json:",omitempty"`
582	BoardAvbRollbackIndexLocation string `json:",omitempty"`
583}
584
585type BoardSuperPartitionGroupProps struct {
586	GroupSize     string   `json:",omitempty"`
587	PartitionList []string `json:",omitempty"`
588}
589
590type ChainedAvbPartitionProps struct {
591	Partitions            []string `json:",omitempty"`
592	Key                   string   `json:",omitempty"`
593	Algorithm             string   `json:",omitempty"`
594	RollbackIndex         string   `json:",omitempty"`
595	RollbackIndexLocation string   `json:",omitempty"`
596}
597
598type PartitionVariables struct {
599	ProductDirectory            string `json:",omitempty"`
600	PartitionQualifiedVariables map[string]PartitionQualifiedVariablesType
601	TargetUserimagesUseExt2     bool `json:",omitempty"`
602	TargetUserimagesUseExt3     bool `json:",omitempty"`
603	TargetUserimagesUseExt4     bool `json:",omitempty"`
604
605	TargetUserimagesSparseExtDisabled      bool `json:",omitempty"`
606	TargetUserimagesSparseErofsDisabled    bool `json:",omitempty"`
607	TargetUserimagesSparseSquashfsDisabled bool `json:",omitempty"`
608	TargetUserimagesSparseF2fsDisabled     bool `json:",omitempty"`
609
610	BoardErofsCompressor           string `json:",omitempty"`
611	BoardErofsCompressorHints      string `json:",omitempty"`
612	BoardErofsPclusterSize         string `json:",omitempty"`
613	BoardErofsShareDupBlocks       string `json:",omitempty"`
614	BoardErofsUseLegacyCompression string `json:",omitempty"`
615	BoardExt4ShareDupBlocks        string `json:",omitempty"`
616	BoardFlashLogicalBlockSize     string `json:",omitempty"`
617	BoardFlashEraseBlockSize       string `json:",omitempty"`
618	ProductUseDynamicPartitionSize bool   `json:",omitempty"`
619	CopyImagesForTargetFilesZip    bool   `json:",omitempty"`
620
621	VendorSecurityPatch string `json:",omitempty"`
622
623	// Boot image stuff
624	BuildingRamdiskImage            bool     `json:",omitempty"`
625	ProductBuildBootImage           bool     `json:",omitempty"`
626	ProductBuildVendorBootImage     string   `json:",omitempty"`
627	ProductBuildInitBootImage       bool     `json:",omitempty"`
628	BoardUsesRecoveryAsBoot         bool     `json:",omitempty"`
629	BoardPrebuiltBootimage          string   `json:",omitempty"`
630	BoardPrebuiltInitBootimage      string   `json:",omitempty"`
631	BoardBootimagePartitionSize     string   `json:",omitempty"`
632	BoardInitBootimagePartitionSize string   `json:",omitempty"`
633	BoardBootHeaderVersion          string   `json:",omitempty"`
634	TargetKernelPath                string   `json:",omitempty"`
635	BoardUsesGenericKernelImage     bool     `json:",omitempty"`
636	BootSecurityPatch               string   `json:",omitempty"`
637	InitBootSecurityPatch           string   `json:",omitempty"`
638	BoardIncludeDtbInBootimg        bool     `json:",omitempty"`
639	InternalKernelCmdline           []string `json:",omitempty"`
640	InternalBootconfig              []string `json:",omitempty"`
641	InternalBootconfigFile          string   `json:",omitempty"`
642
643	// Super image stuff
644	ProductUseDynamicPartitions       bool                                     `json:",omitempty"`
645	ProductRetrofitDynamicPartitions  bool                                     `json:",omitempty"`
646	ProductBuildSuperPartition        bool                                     `json:",omitempty"`
647	BoardSuperPartitionSize           string                                   `json:",omitempty"`
648	BoardSuperPartitionMetadataDevice string                                   `json:",omitempty"`
649	BoardSuperPartitionBlockDevices   []string                                 `json:",omitempty"`
650	BoardSuperPartitionGroups         map[string]BoardSuperPartitionGroupProps `json:",omitempty"`
651	ProductVirtualAbOta               bool                                     `json:",omitempty"`
652	ProductVirtualAbOtaRetrofit       bool                                     `json:",omitempty"`
653	AbOtaUpdater                      bool                                     `json:",omitempty"`
654
655	// Avb (android verified boot) stuff
656	BoardAvbEnable          bool                                `json:",omitempty"`
657	BoardAvbAlgorithm       string                              `json:",omitempty"`
658	BoardAvbKeyPath         string                              `json:",omitempty"`
659	BoardAvbRollbackIndex   string                              `json:",omitempty"`
660	BuildingVbmetaImage     bool                                `json:",omitempty"`
661	ChainedVbmetaPartitions map[string]ChainedAvbPartitionProps `json:",omitempty"`
662
663	ProductPackages         []string `json:",omitempty"`
664	ProductPackagesDebug    []string `json:",omitempty"`
665	VendorLinkerConfigSrcs  []string `json:",omitempty"`
666	ProductLinkerConfigSrcs []string `json:",omitempty"`
667
668	BoardInfoFiles      []string `json:",omitempty"`
669	BootLoaderBoardName string   `json:",omitempty"`
670
671	ProductCopyFiles []string `json:",omitempty"`
672
673	BuildingSystemDlkmImage   bool     `json:",omitempty"`
674	SystemKernelModules       []string `json:",omitempty"`
675	SystemKernelBlocklistFile string   `json:",omitempty"`
676	SystemKernelLoadModules   []string `json:",omitempty"`
677	BuildingVendorDlkmImage   bool     `json:",omitempty"`
678	VendorKernelModules       []string `json:",omitempty"`
679	VendorKernelBlocklistFile string   `json:",omitempty"`
680	BuildingOdmDlkmImage      bool     `json:",omitempty"`
681	OdmKernelModules          []string `json:",omitempty"`
682	OdmKernelBlocklistFile    string   `json:",omitempty"`
683
684	VendorRamdiskKernelModules       []string `json:",omitempty"`
685	VendorRamdiskKernelBlocklistFile string   `json:",omitempty"`
686	VendorRamdiskKernelLoadModules   []string `json:",omitempty"`
687	VendorRamdiskKernelOptionsFile   string   `json:",omitempty"`
688
689	ProductFsverityGenerateMetadata bool `json:",omitempty"`
690
691	TargetScreenDensity string `json:",omitempty"`
692}
693
694func boolPtr(v bool) *bool {
695	return &v
696}
697
698func intPtr(v int) *int {
699	return &v
700}
701
702func stringPtr(v string) *string {
703	return &v
704}
705
706func (v *ProductVariables) SetDefaultConfig() {
707	*v = ProductVariables{
708		BuildNumberFile: stringPtr("build_number.txt"),
709
710		Platform_version_name:                  stringPtr("S"),
711		Platform_base_sdk_extension_version:    intPtr(30),
712		Platform_sdk_version:                   intPtr(30),
713		Platform_sdk_codename:                  stringPtr("S"),
714		Platform_sdk_final:                     boolPtr(false),
715		Platform_version_active_codenames:      []string{"S"},
716		Platform_version_all_preview_codenames: []string{"S"},
717
718		HostArch:                    stringPtr("x86_64"),
719		HostSecondaryArch:           stringPtr("x86"),
720		DeviceName:                  stringPtr("generic_arm64"),
721		DeviceProduct:               stringPtr("aosp_arm-eng"),
722		DeviceArch:                  stringPtr("arm64"),
723		DeviceArchVariant:           stringPtr("armv8-a"),
724		DeviceCpuVariant:            stringPtr("generic"),
725		DeviceAbi:                   []string{"arm64-v8a"},
726		DeviceSecondaryArch:         stringPtr("arm"),
727		DeviceSecondaryArchVariant:  stringPtr("armv8-a"),
728		DeviceSecondaryCpuVariant:   stringPtr("generic"),
729		DeviceSecondaryAbi:          []string{"armeabi-v7a", "armeabi"},
730		DeviceMaxPageSizeSupported:  stringPtr("4096"),
731		DeviceNoBionicPageSizeMacro: boolPtr(false),
732
733		AAPTConfig:          []string{"normal", "large", "xlarge", "hdpi", "xhdpi", "xxhdpi"},
734		AAPTPreferredConfig: stringPtr("xhdpi"),
735		AAPTCharacteristics: stringPtr("nosdcard"),
736		AAPTPrebuiltDPI:     []string{"xhdpi", "xxhdpi"},
737
738		Malloc_low_memory:            boolPtr(false),
739		Malloc_zero_contents:         boolPtr(true),
740		Malloc_pattern_fill_contents: boolPtr(false),
741		Safestack:                    boolPtr(false),
742		Build_from_text_stub:         boolPtr(false),
743
744		BootJars:     ConfiguredJarList{apexes: []string{}, jars: []string{}},
745		ApexBootJars: ConfiguredJarList{apexes: []string{}, jars: []string{}},
746	}
747
748	if runtime.GOOS == "linux" {
749		v.CrossHost = stringPtr("windows")
750		v.CrossHostArch = stringPtr("x86")
751		v.CrossHostSecondaryArch = stringPtr("x86_64")
752	}
753}
754
755func (this *ProductVariables) GetBuildFlagBool(flag string) bool {
756	val, ok := this.BuildFlags[flag]
757	if !ok {
758		return false
759	}
760	return val == "true"
761}
762
763func VariableMutator(mctx BottomUpMutatorContext) {
764	var module Module
765	var ok bool
766	if module, ok = mctx.Module().(Module); !ok {
767		return
768	}
769
770	// TODO: depend on config variable, create variants, propagate variants up tree
771	a := module.base()
772
773	if a.variableProperties == nil {
774		return
775	}
776
777	variableValues := reflect.ValueOf(a.variableProperties).Elem().FieldByName("Product_variables")
778
779	productVariables := reflect.ValueOf(mctx.Config().productVariables)
780
781	for i := 0; i < variableValues.NumField(); i++ {
782		variableValue := variableValues.Field(i)
783		name := variableValues.Type().Field(i).Name
784		property := "product_variables." + proptools.PropertyNameForField(name)
785
786		// Check that the variable was set for the product
787		val := productVariables.FieldByName(name)
788		if !val.IsValid() || val.Kind() != reflect.Ptr || val.IsNil() {
789			continue
790		}
791
792		val = val.Elem()
793
794		// For bools, check that the value is true
795		if val.Kind() == reflect.Bool && val.Bool() == false {
796			continue
797		}
798
799		// Check if any properties were set for the module
800		if variableValue.IsZero() {
801			continue
802		}
803		a.setVariableProperties(mctx, property, variableValue, val.Interface())
804	}
805}
806
807func (m *ModuleBase) setVariableProperties(ctx BottomUpMutatorContext,
808	prefix string, productVariablePropertyValue reflect.Value, variableValue interface{}) {
809
810	printfIntoProperties(ctx, prefix, productVariablePropertyValue, variableValue)
811
812	err := proptools.AppendMatchingProperties(m.GetProperties(),
813		productVariablePropertyValue.Addr().Interface(), nil)
814	if err != nil {
815		if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok {
816			ctx.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error())
817		} else {
818			panic(err)
819		}
820	}
821}
822
823func printfIntoPropertiesError(ctx BottomUpMutatorContext, prefix string,
824	productVariablePropertyValue reflect.Value, i int, err error) {
825
826	field := productVariablePropertyValue.Type().Field(i).Name
827	property := prefix + "." + proptools.PropertyNameForField(field)
828	ctx.PropertyErrorf(property, "%s", err)
829}
830
831func printfIntoProperties(ctx BottomUpMutatorContext, prefix string,
832	productVariablePropertyValue reflect.Value, variableValue interface{}) {
833
834	for i := 0; i < productVariablePropertyValue.NumField(); i++ {
835		propertyValue := productVariablePropertyValue.Field(i)
836		kind := propertyValue.Kind()
837		if kind == reflect.Ptr {
838			if propertyValue.IsNil() {
839				continue
840			}
841			propertyValue = propertyValue.Elem()
842		}
843		switch propertyValue.Kind() {
844		case reflect.String:
845			err := printfIntoProperty(propertyValue, variableValue)
846			if err != nil {
847				printfIntoPropertiesError(ctx, prefix, productVariablePropertyValue, i, err)
848			}
849		case reflect.Slice:
850			for j := 0; j < propertyValue.Len(); j++ {
851				err := printfIntoProperty(propertyValue.Index(j), variableValue)
852				if err != nil {
853					printfIntoPropertiesError(ctx, prefix, productVariablePropertyValue, i, err)
854				}
855			}
856		case reflect.Bool:
857			// Nothing
858		case reflect.Struct:
859			printfIntoProperties(ctx, prefix, propertyValue, variableValue)
860		default:
861			panic(fmt.Errorf("unsupported field kind %q", propertyValue.Kind()))
862		}
863	}
864}
865
866func printfIntoProperty(propertyValue reflect.Value, variableValue interface{}) error {
867	s := propertyValue.String()
868
869	count := strings.Count(s, "%")
870	if count == 0 {
871		return nil
872	}
873
874	if count > 1 {
875		return fmt.Errorf("product variable properties only support a single '%%'")
876	}
877
878	if strings.Contains(s, "%d") {
879		switch v := variableValue.(type) {
880		case int:
881			// Nothing
882		case bool:
883			if v {
884				variableValue = 1
885			} else {
886				variableValue = 0
887			}
888		default:
889			return fmt.Errorf("unsupported type %T for %%d", variableValue)
890		}
891	} else if strings.Contains(s, "%s") {
892		switch variableValue.(type) {
893		case string:
894			// Nothing
895		default:
896			return fmt.Errorf("unsupported type %T for %%s", variableValue)
897		}
898	} else {
899		return fmt.Errorf("unsupported %% in product variable property")
900	}
901
902	propertyValue.Set(reflect.ValueOf(fmt.Sprintf(s, variableValue)))
903
904	return nil
905}
906
907var variablePropTypeMap OncePer
908
909// sliceToTypeArray takes a slice of property structs and returns a reflection created array containing the
910// reflect.Types of each property struct.  The result can be used as a key in a map.
911func sliceToTypeArray(s []interface{}) interface{} {
912	// Create an array using reflection whose length is the length of the input slice
913	ret := reflect.New(reflect.ArrayOf(len(s), reflect.TypeOf(reflect.TypeOf(0)))).Elem()
914	for i, e := range s {
915		ret.Index(i).Set(reflect.ValueOf(reflect.TypeOf(e)))
916	}
917	return ret.Interface()
918}
919
920func initProductVariableModule(m Module) {
921	base := m.base()
922
923	// Allow tests to override the default product variables
924	if base.variableProperties == nil {
925		base.variableProperties = defaultProductVariables
926	}
927	// Filter the product variables properties to the ones that exist on this module
928	base.variableProperties = createVariableProperties(m.GetProperties(), base.variableProperties)
929	if base.variableProperties != nil {
930		m.AddProperties(base.variableProperties)
931	}
932}
933
934// createVariableProperties takes the list of property structs for a module and returns a property struct that
935// contains the product variable properties that exist in the property structs, or nil if there are none.  It
936// caches the result.
937func createVariableProperties(moduleTypeProps []interface{}, productVariables interface{}) interface{} {
938	// Convert the moduleTypeProps to an array of reflect.Types that can be used as a key in the OncePer.
939	key := sliceToTypeArray(moduleTypeProps)
940
941	// Use the variablePropTypeMap OncePer to cache the result for each set of property struct types.
942	typ, _ := variablePropTypeMap.Once(NewCustomOnceKey(key), func() interface{} {
943		// Compute the filtered property struct type.
944		return createVariablePropertiesType(moduleTypeProps, productVariables)
945	}).(reflect.Type)
946
947	if typ == nil {
948		return nil
949	}
950
951	// Create a new pointer to a filtered property struct.
952	return reflect.New(typ).Interface()
953}
954
955// createVariablePropertiesType creates a new type that contains only the product variable properties that exist in
956// a list of property structs.
957func createVariablePropertiesType(moduleTypeProps []interface{}, productVariables interface{}) reflect.Type {
958	typ, _ := proptools.FilterPropertyStruct(reflect.TypeOf(productVariables),
959		func(field reflect.StructField, prefix string) (bool, reflect.StructField) {
960			// Filter function, returns true if the field should be in the resulting struct
961			if prefix == "" {
962				// Keep the top level Product_variables field
963				return true, field
964			}
965			_, rest := splitPrefix(prefix)
966			if rest == "" {
967				// Keep the 2nd level field (i.e. Product_variables.Eng)
968				return true, field
969			}
970
971			// Strip off the first 2 levels of the prefix
972			_, prefix = splitPrefix(rest)
973
974			for _, p := range moduleTypeProps {
975				if fieldExistsByNameRecursive(reflect.TypeOf(p).Elem(), prefix, field.Name) {
976					// Keep any fields that exist in one of the property structs
977					return true, field
978				}
979			}
980
981			return false, field
982		})
983	return typ
984}
985
986func splitPrefix(prefix string) (first, rest string) {
987	index := strings.IndexByte(prefix, '.')
988	if index == -1 {
989		return prefix, ""
990	}
991	return prefix[:index], prefix[index+1:]
992}
993
994func fieldExistsByNameRecursive(t reflect.Type, prefix, name string) bool {
995	if t.Kind() != reflect.Struct {
996		panic(fmt.Errorf("fieldExistsByNameRecursive can only be called on a reflect.Struct"))
997	}
998
999	if prefix != "" {
1000		split := strings.SplitN(prefix, ".", 2)
1001		firstPrefix := split[0]
1002		rest := ""
1003		if len(split) > 1 {
1004			rest = split[1]
1005		}
1006		f, exists := t.FieldByName(firstPrefix)
1007		if !exists {
1008			return false
1009		}
1010		ft := f.Type
1011		if ft.Kind() == reflect.Ptr {
1012			ft = ft.Elem()
1013		}
1014		if ft.Kind() != reflect.Struct {
1015			panic(fmt.Errorf("field %q in %q is not a struct", firstPrefix, t))
1016		}
1017		return fieldExistsByNameRecursive(ft, rest, name)
1018	} else {
1019		_, exists := t.FieldByName(name)
1020		return exists
1021	}
1022}
1023