blob: b724f57838f6f8c6dab667f4b87d94429566c77c [file] [log] [blame]
Cole Faustb85d1a12022-11-08 18:14:01 -08001package bp2build
2
3import (
Cole Faustf8231dd2023-04-21 17:37:11 -07004 "encoding/json"
Cole Faustb85d1a12022-11-08 18:14:01 -08005 "fmt"
6 "os"
7 "path/filepath"
Cole Faustf055db62023-07-24 15:17:03 -07008 "reflect"
Cole Faustb85d1a12022-11-08 18:14:01 -08009 "strings"
Cole Faustf8231dd2023-04-21 17:37:11 -070010
Yu Liub6a15da2023-08-31 14:14:01 -070011 "android/soong/android"
12 "android/soong/android/soongconfig"
13 "android/soong/starlark_import"
14
Cole Faustf8231dd2023-04-21 17:37:11 -070015 "github.com/google/blueprint/proptools"
16 "go.starlark.net/starlark"
Cole Faustb85d1a12022-11-08 18:14:01 -080017)
18
Cole Faust6054cdf2023-09-12 10:07:07 -070019type createProductConfigFilesResult struct {
20 injectionFiles []BazelFile
21 bp2buildFiles []BazelFile
22 bp2buildTargets map[string]BazelTargets
23}
24
Cole Faustcb193ec2023-09-20 16:01:18 -070025type bazelLabel struct {
26 repo string
27 pkg string
28 target string
29}
30
31func (l *bazelLabel) String() string {
32 return fmt.Sprintf("@%s//%s:%s", l.repo, l.pkg, l.target)
33}
34
Cole Faust6054cdf2023-09-12 10:07:07 -070035func createProductConfigFiles(
Cole Faust946d02c2023-08-03 16:08:09 -070036 ctx *CodegenContext,
Cole Faust6054cdf2023-09-12 10:07:07 -070037 metrics CodegenMetrics) (createProductConfigFilesResult, error) {
Cole Faustb85d1a12022-11-08 18:14:01 -080038 cfg := &ctx.config
39 targetProduct := "unknown"
40 if cfg.HasDeviceProduct() {
41 targetProduct = cfg.DeviceProduct()
42 }
43 targetBuildVariant := "user"
44 if cfg.Eng() {
45 targetBuildVariant = "eng"
46 } else if cfg.Debuggable() {
47 targetBuildVariant = "userdebug"
48 }
49
Cole Faust6054cdf2023-09-12 10:07:07 -070050 var res createProductConfigFilesResult
51
Cole Faustb85d1a12022-11-08 18:14:01 -080052 productVariablesFileName := cfg.ProductVariablesFileName
53 if !strings.HasPrefix(productVariablesFileName, "/") {
54 productVariablesFileName = filepath.Join(ctx.topDir, productVariablesFileName)
55 }
Cole Faustf8231dd2023-04-21 17:37:11 -070056 productVariablesBytes, err := os.ReadFile(productVariablesFileName)
Cole Faustb85d1a12022-11-08 18:14:01 -080057 if err != nil {
Cole Faust6054cdf2023-09-12 10:07:07 -070058 return res, err
Cole Faustf8231dd2023-04-21 17:37:11 -070059 }
60 productVariables := android.ProductVariables{}
61 err = json.Unmarshal(productVariablesBytes, &productVariables)
62 if err != nil {
Cole Faust6054cdf2023-09-12 10:07:07 -070063 return res, err
Cole Faustb85d1a12022-11-08 18:14:01 -080064 }
65
Cole Faustf3cf34e2023-09-20 17:02:40 -070066 currentProductFolder := fmt.Sprintf("build/bazel/products/%s", targetProduct)
Cole Faustcb193ec2023-09-20 16:01:18 -070067 if len(productVariables.PartitionVarsForBazelMigrationOnlyDoNotUse.ProductDirectory) > 0 {
68 currentProductFolder = fmt.Sprintf("%s%s", productVariables.PartitionVarsForBazelMigrationOnlyDoNotUse.ProductDirectory, targetProduct)
Cole Faustb4cb0c82023-09-14 15:16:58 -070069 }
Cole Faustb85d1a12022-11-08 18:14:01 -080070
71 productReplacer := strings.NewReplacer(
72 "{PRODUCT}", targetProduct,
73 "{VARIANT}", targetBuildVariant,
74 "{PRODUCT_FOLDER}", currentProductFolder)
75
Cole Faust946d02c2023-08-03 16:08:09 -070076 productsForTestingMap, err := starlark_import.GetStarlarkValue[map[string]map[string]starlark.Value]("products_for_testing")
77 if err != nil {
Cole Faust6054cdf2023-09-12 10:07:07 -070078 return res, err
Cole Faust946d02c2023-08-03 16:08:09 -070079 }
80 productsForTesting := android.SortedKeys(productsForTestingMap)
81 for i := range productsForTesting {
82 productsForTesting[i] = fmt.Sprintf(" \"@//build/bazel/tests/products:%s\",", productsForTesting[i])
83 }
84
Cole Faustcb193ec2023-09-20 16:01:18 -070085 productLabelsToVariables := make(map[bazelLabel]*android.ProductVariables)
86 productLabelsToVariables[bazelLabel{
87 repo: "",
88 pkg: currentProductFolder,
89 target: targetProduct,
90 }] = &productVariables
Cole Faust6054cdf2023-09-12 10:07:07 -070091 for product, productVariablesStarlark := range productsForTestingMap {
92 productVariables, err := starlarkMapToProductVariables(productVariablesStarlark)
93 if err != nil {
94 return res, err
95 }
Cole Faustcb193ec2023-09-20 16:01:18 -070096 productLabelsToVariables[bazelLabel{
97 repo: "",
98 pkg: "build/bazel/tests/products",
99 target: product,
100 }] = &productVariables
Cole Faust6054cdf2023-09-12 10:07:07 -0700101 }
102
Cole Faustb4cb0c82023-09-14 15:16:58 -0700103 res.bp2buildTargets = make(map[string]BazelTargets)
104 res.bp2buildTargets[currentProductFolder] = append(res.bp2buildTargets[currentProductFolder], BazelTarget{
Cole Faustf3cf34e2023-09-20 17:02:40 -0700105 name: productReplacer.Replace("{PRODUCT}"),
Cole Faustb4cb0c82023-09-14 15:16:58 -0700106 packageName: currentProductFolder,
107 content: productReplacer.Replace(`android_product(
Cole Faustf3cf34e2023-09-20 17:02:40 -0700108 name = "{PRODUCT}",
Cole Faustb4cb0c82023-09-14 15:16:58 -0700109 soong_variables = _soong_variables,
110)`),
111 ruleClass: "android_product",
112 loads: []BazelLoad{
113 {
114 file: ":soong.variables.bzl",
115 symbols: []BazelLoadSymbol{{
116 symbol: "variables",
117 alias: "_soong_variables",
118 }},
119 },
120 {
121 file: "//build/bazel/product_config:android_product.bzl",
122 symbols: []BazelLoadSymbol{{symbol: "android_product"}},
123 },
124 },
125 })
126 createTargets(productLabelsToVariables, res.bp2buildTargets)
Cole Faust6054cdf2023-09-12 10:07:07 -0700127
128 platformMappingContent, err := platformMappingContent(
129 productLabelsToVariables,
130 ctx.Config().Bp2buildSoongConfigDefinitions,
131 metrics.convertedModulePathMap)
132 if err != nil {
133 return res, err
134 }
135
136 res.injectionFiles = []BazelFile{
Cole Faustb85d1a12022-11-08 18:14:01 -0800137 newFile(
Cole Faustb85d1a12022-11-08 18:14:01 -0800138 "product_config_platforms",
139 "BUILD.bazel",
140 productReplacer.Replace(`
141package(default_visibility = [
142 "@//build/bazel/product_config:__subpackages__",
143 "@soong_injection//product_config_platforms:__subpackages__",
144])
Jingwen Chen583ab212023-05-30 09:45:23 +0000145
Cole Faustb4cb0c82023-09-14 15:16:58 -0700146load("@//{PRODUCT_FOLDER}:soong.variables.bzl", _soong_variables = "variables")
Jingwen Chen583ab212023-05-30 09:45:23 +0000147load("@//build/bazel/product_config:android_product.bzl", "android_product")
148
Cole Faust319abae2023-06-06 15:12:49 -0700149# Bazel will qualify its outputs by the platform name. When switching between products, this
150# means that soong-built files that depend on bazel-built files will suddenly get different
151# dependency files, because the path changes, and they will be rebuilt. In order to avoid this
152# extra rebuilding, make mixed builds always use a single platform so that the bazel artifacts
153# are always under the same path.
Jingwen Chen583ab212023-05-30 09:45:23 +0000154android_product(
Cole Faustf3cf34e2023-09-20 17:02:40 -0700155 name = "mixed_builds_product",
Jingwen Chen583ab212023-05-30 09:45:23 +0000156 soong_variables = _soong_variables,
Cole Faustbc65a3f2023-08-01 16:38:55 +0000157 extra_constraints = ["@//build/bazel/platforms:mixed_builds"],
Jingwen Chen583ab212023-05-30 09:45:23 +0000158)
Cole Faust117bb742023-03-29 14:46:20 -0700159`)),
160 newFile(
161 "product_config_platforms",
162 "product_labels.bzl",
163 productReplacer.Replace(`
164# This file keeps a list of all the products in the android source tree, because they're
165# discovered as part of a preprocessing step before bazel runs.
166# TODO: When we start generating the platforms for more than just the
167# currently lunched product, they should all be listed here
168product_labels = [
Cole Faustf3cf34e2023-09-20 17:02:40 -0700169 "@soong_injection//product_config_platforms:mixed_builds_product",
170 "@//{PRODUCT_FOLDER}:{PRODUCT}",
Cole Faust946d02c2023-08-03 16:08:09 -0700171`)+strings.Join(productsForTesting, "\n")+"\n]\n"),
Cole Faustb85d1a12022-11-08 18:14:01 -0800172 newFile(
173 "product_config_platforms",
174 "common.bazelrc",
175 productReplacer.Replace(`
Cole Faustf8231dd2023-04-21 17:37:11 -0700176build --platform_mappings=platform_mappings
Cole Faustf3cf34e2023-09-20 17:02:40 -0700177build --platforms @//{PRODUCT_FOLDER}:{PRODUCT}_linux_x86_64
178build --//build/bazel/product_config:target_build_variant={VARIANT}
Cole Faustb85d1a12022-11-08 18:14:01 -0800179
Cole Faustf3cf34e2023-09-20 17:02:40 -0700180build:android --platforms=@//{PRODUCT_FOLDER}:{PRODUCT}
181build:linux_x86 --platforms=@//{PRODUCT_FOLDER}:{PRODUCT}_linux_x86
182build:linux_x86_64 --platforms=@//{PRODUCT_FOLDER}:{PRODUCT}_linux_x86_64
183build:linux_bionic_x86_64 --platforms=@//{PRODUCT_FOLDER}:{PRODUCT}_linux_bionic_x86_64
184build:linux_musl_x86 --platforms=@//{PRODUCT_FOLDER}:{PRODUCT}_linux_musl_x86
185build:linux_musl_x86_64 --platforms=@//{PRODUCT_FOLDER}:{PRODUCT}_linux_musl_x86_64
Cole Faustb85d1a12022-11-08 18:14:01 -0800186`)),
187 newFile(
188 "product_config_platforms",
189 "linux.bazelrc",
190 productReplacer.Replace(`
Cole Faustf3cf34e2023-09-20 17:02:40 -0700191build --host_platform @//{PRODUCT_FOLDER}:{PRODUCT}_linux_x86_64
Cole Faustb85d1a12022-11-08 18:14:01 -0800192`)),
193 newFile(
194 "product_config_platforms",
195 "darwin.bazelrc",
196 productReplacer.Replace(`
Cole Faustf3cf34e2023-09-20 17:02:40 -0700197build --host_platform @//{PRODUCT_FOLDER}:{PRODUCT}_darwin_x86_64
Cole Faustb85d1a12022-11-08 18:14:01 -0800198`)),
199 }
Cole Faust6054cdf2023-09-12 10:07:07 -0700200 res.bp2buildFiles = []BazelFile{
Cole Faustf8231dd2023-04-21 17:37:11 -0700201 newFile(
202 "",
203 "platform_mappings",
204 platformMappingContent),
Cole Faustb4cb0c82023-09-14 15:16:58 -0700205 newFile(
206 currentProductFolder,
207 "soong.variables.bzl",
208 `variables = json.decode("""`+strings.ReplaceAll(string(productVariablesBytes), "\\", "\\\\")+`""")`),
Cole Faustf8231dd2023-04-21 17:37:11 -0700209 }
Cole Faust6054cdf2023-09-12 10:07:07 -0700210
211 return res, nil
Cole Faustf8231dd2023-04-21 17:37:11 -0700212}
Cole Faustb85d1a12022-11-08 18:14:01 -0800213
Cole Faust946d02c2023-08-03 16:08:09 -0700214func platformMappingContent(
Cole Faustcb193ec2023-09-20 16:01:18 -0700215 productLabelToVariables map[bazelLabel]*android.ProductVariables,
Cole Faust946d02c2023-08-03 16:08:09 -0700216 soongConfigDefinitions soongconfig.Bp2BuildSoongConfigDefinitions,
217 convertedModulePathMap map[string]string) (string, error) {
Cole Faustf055db62023-07-24 15:17:03 -0700218 var result strings.Builder
Cole Faust946d02c2023-08-03 16:08:09 -0700219
220 mergedConvertedModulePathMap := make(map[string]string)
221 for k, v := range convertedModulePathMap {
222 mergedConvertedModulePathMap[k] = v
223 }
224 additionalModuleNamesToPackages, err := starlark_import.GetStarlarkValue[map[string]string]("additional_module_names_to_packages")
225 if err != nil {
226 return "", err
227 }
228 for k, v := range additionalModuleNamesToPackages {
229 mergedConvertedModulePathMap[k] = v
230 }
231
Cole Faustf055db62023-07-24 15:17:03 -0700232 result.WriteString("platforms:\n")
Cole Faust6054cdf2023-09-12 10:07:07 -0700233 for productLabel, productVariables := range productLabelToVariables {
234 platformMappingSingleProduct(productLabel, productVariables, soongConfigDefinitions, mergedConvertedModulePathMap, &result)
Cole Faustf8231dd2023-04-21 17:37:11 -0700235 }
Cole Faustf055db62023-07-24 15:17:03 -0700236 return result.String(), nil
Cole Faustf8231dd2023-04-21 17:37:11 -0700237}
238
Cole Faust88c8efb2023-07-18 11:05:16 -0700239var bazelPlatformSuffixes = []string{
240 "",
241 "_darwin_arm64",
242 "_darwin_x86_64",
243 "_linux_bionic_arm64",
244 "_linux_bionic_x86_64",
245 "_linux_musl_x86",
246 "_linux_musl_x86_64",
247 "_linux_x86",
248 "_linux_x86_64",
249 "_windows_x86",
250 "_windows_x86_64",
251}
252
Cole Faust946d02c2023-08-03 16:08:09 -0700253func platformMappingSingleProduct(
Cole Faustcb193ec2023-09-20 16:01:18 -0700254 label bazelLabel,
Cole Faust946d02c2023-08-03 16:08:09 -0700255 productVariables *android.ProductVariables,
256 soongConfigDefinitions soongconfig.Bp2BuildSoongConfigDefinitions,
257 convertedModulePathMap map[string]string,
258 result *strings.Builder) {
Cole Faustf055db62023-07-24 15:17:03 -0700259
Cole Faust95c5cf82023-08-03 13:49:27 -0700260 platform_sdk_version := -1
261 if productVariables.Platform_sdk_version != nil {
262 platform_sdk_version = *productVariables.Platform_sdk_version
263 }
264
Cole Faust946d02c2023-08-03 16:08:09 -0700265 defaultAppCertificateFilegroup := "//build/bazel/utils:empty_filegroup"
266 if proptools.String(productVariables.DefaultAppCertificate) != "" {
Cole Faust6054cdf2023-09-12 10:07:07 -0700267 defaultAppCertificateFilegroup = "@//" + filepath.Dir(proptools.String(productVariables.DefaultAppCertificate)) + ":generated_android_certificate_directory"
Cole Faust946d02c2023-08-03 16:08:09 -0700268 }
269
Cole Faustf055db62023-07-24 15:17:03 -0700270 for _, suffix := range bazelPlatformSuffixes {
271 result.WriteString(" ")
Cole Faustcb193ec2023-09-20 16:01:18 -0700272 result.WriteString(label.String())
Cole Faustf055db62023-07-24 15:17:03 -0700273 result.WriteString(suffix)
274 result.WriteString("\n")
275 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:always_use_prebuilt_sdks=%t\n", proptools.Bool(productVariables.Always_use_prebuilt_sdks)))
Cole Faust87c0c332023-07-31 12:10:12 -0700276 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:arc=%t\n", proptools.Bool(productVariables.Arc)))
Cole Faustf055db62023-07-24 15:17:03 -0700277 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:apex_global_min_sdk_version_override=%s\n", proptools.String(productVariables.ApexGlobalMinSdkVersionOverride)))
Cole Faust87c0c332023-07-31 12:10:12 -0700278 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:binder32bit=%t\n", proptools.Bool(productVariables.Binder32bit)))
279 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:build_from_text_stub=%t\n", proptools.Bool(productVariables.Build_from_text_stub)))
Cole Faustded79602023-09-05 17:48:11 -0700280 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:build_broken_incorrect_partition_images=%t\n", productVariables.BuildBrokenIncorrectPartitionImages))
Cole Faustf055db62023-07-24 15:17:03 -0700281 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:build_id=%s\n", proptools.String(productVariables.BuildId)))
282 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:build_version_tags=%s\n", strings.Join(productVariables.BuildVersionTags, ",")))
Cole Faustf055db62023-07-24 15:17:03 -0700283 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:cfi_exclude_paths=%s\n", strings.Join(productVariables.CFIExcludePaths, ",")))
284 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:cfi_include_paths=%s\n", strings.Join(productVariables.CFIIncludePaths, ",")))
285 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:compressed_apex=%t\n", proptools.Bool(productVariables.CompressedApex)))
286 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:default_app_certificate=%s\n", proptools.String(productVariables.DefaultAppCertificate)))
Cole Faust946d02c2023-08-03 16:08:09 -0700287 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:default_app_certificate_filegroup=%s\n", defaultAppCertificateFilegroup))
Cole Faustf055db62023-07-24 15:17:03 -0700288 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:device_abi=%s\n", strings.Join(productVariables.DeviceAbi, ",")))
289 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:device_max_page_size_supported=%s\n", proptools.String(productVariables.DeviceMaxPageSizeSupported)))
290 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:device_name=%s\n", proptools.String(productVariables.DeviceName)))
Juan Yescas01065602023-08-09 08:34:37 -0700291 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:device_page_size_agnostic=%t\n", proptools.Bool(productVariables.DevicePageSizeAgnostic)))
Cole Faustf055db62023-07-24 15:17:03 -0700292 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:device_product=%s\n", proptools.String(productVariables.DeviceProduct)))
Cole Faustcb193ec2023-09-20 16:01:18 -0700293 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:device_platform=%s\n", label.String()))
Cole Faustf055db62023-07-24 15:17:03 -0700294 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:enable_cfi=%t\n", proptools.BoolDefault(productVariables.EnableCFI, true)))
Cole Faust87c0c332023-07-31 12:10:12 -0700295 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:enforce_vintf_manifest=%t\n", proptools.Bool(productVariables.Enforce_vintf_manifest)))
Cole Faust87c0c332023-07-31 12:10:12 -0700296 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:malloc_not_svelte=%t\n", proptools.Bool(productVariables.Malloc_not_svelte)))
297 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:malloc_pattern_fill_contents=%t\n", proptools.Bool(productVariables.Malloc_pattern_fill_contents)))
298 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:malloc_zero_contents=%t\n", proptools.Bool(productVariables.Malloc_zero_contents)))
Yu Liub6a15da2023-08-31 14:14:01 -0700299 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:memtag_heap_exclude_paths=%s\n", strings.Join(productVariables.MemtagHeapExcludePaths, ",")))
300 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:memtag_heap_async_include_paths=%s\n", strings.Join(productVariables.MemtagHeapAsyncIncludePaths, ",")))
301 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:memtag_heap_sync_include_paths=%s\n", strings.Join(productVariables.MemtagHeapSyncIncludePaths, ",")))
Cole Faustf055db62023-07-24 15:17:03 -0700302 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:manifest_package_name_overrides=%s\n", strings.Join(productVariables.ManifestPackageNameOverrides, ",")))
Cole Faust87c0c332023-07-31 12:10:12 -0700303 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:native_coverage=%t\n", proptools.Bool(productVariables.Native_coverage)))
Romain Jobredeaux3132f842023-09-15 10:06:16 -0400304 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:platform_sdk_final=%t\n", proptools.Bool(productVariables.Platform_sdk_final)))
Cole Faustf055db62023-07-24 15:17:03 -0700305 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:platform_version_name=%s\n", proptools.String(productVariables.Platform_version_name)))
306 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:product_brand=%s\n", productVariables.ProductBrand))
307 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:product_manufacturer=%s\n", productVariables.ProductManufacturer))
Yu Liu2cc802a2023-09-05 17:19:45 -0700308 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:release_aconfig_flag_default_permission=%s\n", productVariables.ReleaseAconfigFlagDefaultPermission))
309 // Empty string can't be used as label_flag on the bazel side
310 if len(productVariables.ReleaseAconfigValueSets) > 0 {
311 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:release_aconfig_value_sets=%s\n", productVariables.ReleaseAconfigValueSets))
312 }
313 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:release_version=%s\n", productVariables.ReleaseVersion))
Cole Faust95c5cf82023-08-03 13:49:27 -0700314 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:platform_sdk_version=%d\n", platform_sdk_version))
Cole Faust87c0c332023-07-31 12:10:12 -0700315 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:safestack=%t\n", proptools.Bool(productVariables.Safestack)))
Cole Faust87c0c332023-07-31 12:10:12 -0700316 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:treble_linker_namespaces=%t\n", proptools.Bool(productVariables.Treble_linker_namespaces)))
Cole Faustf055db62023-07-24 15:17:03 -0700317 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:tidy_checks=%s\n", proptools.String(productVariables.TidyChecks)))
Cole Faust87c0c332023-07-31 12:10:12 -0700318 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:uml=%t\n", proptools.Bool(productVariables.Uml)))
Cole Faustf055db62023-07-24 15:17:03 -0700319 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:unbundled_build=%t\n", proptools.Bool(productVariables.Unbundled_build)))
320 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:unbundled_build_apps=%s\n", strings.Join(productVariables.Unbundled_build_apps, ",")))
Cole Faust946d02c2023-08-03 16:08:09 -0700321
322 for _, override := range productVariables.CertificateOverrides {
323 parts := strings.SplitN(override, ":", 2)
324 if apexPath, ok := convertedModulePathMap[parts[0]]; ok {
325 if overrideCertPath, ok := convertedModulePathMap[parts[1]]; ok {
326 result.WriteString(fmt.Sprintf(" --%s:%s_certificate_override=%s:%s\n", apexPath, parts[0], overrideCertPath, parts[1]))
327 }
328 }
329 }
330
Cole Faust87c0c332023-07-31 12:10:12 -0700331 for namespace, namespaceContents := range productVariables.VendorVars {
332 for variable, value := range namespaceContents {
333 key := namespace + "__" + variable
334 _, hasBool := soongConfigDefinitions.BoolVars[key]
335 _, hasString := soongConfigDefinitions.StringVars[key]
336 _, hasValue := soongConfigDefinitions.ValueVars[key]
337 if !hasBool && !hasString && !hasValue {
338 // Not all soong config variables are defined in Android.bp files. For example,
339 // prebuilt_bootclasspath_fragment uses soong config variables in a nonstandard
340 // way, that causes them to be present in the soong.variables file but not
341 // defined in an Android.bp file. There's also nothing stopping you from setting
342 // a variable in make that doesn't exist in soong. We only generate build
343 // settings for the ones that exist in soong, so skip all others.
344 continue
345 }
346 if hasBool && hasString || hasBool && hasValue || hasString && hasValue {
347 panic(fmt.Sprintf("Soong config variable %s:%s appears to be of multiple types. bool? %t, string? %t, value? %t", namespace, variable, hasBool, hasString, hasValue))
348 }
349 if hasBool {
350 // Logic copied from soongConfig.Bool()
351 value = strings.ToLower(value)
352 if value == "1" || value == "y" || value == "yes" || value == "on" || value == "true" {
353 value = "true"
354 } else {
355 value = "false"
356 }
357 }
358 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config/soong_config_variables:%s=%s\n", strings.ToLower(key), value))
359 }
360 }
Cole Faustf055db62023-07-24 15:17:03 -0700361 }
Cole Faustf8231dd2023-04-21 17:37:11 -0700362}
363
364func starlarkMapToProductVariables(in map[string]starlark.Value) (android.ProductVariables, error) {
Cole Faustf8231dd2023-04-21 17:37:11 -0700365 result := android.ProductVariables{}
Cole Faustf055db62023-07-24 15:17:03 -0700366 productVarsReflect := reflect.ValueOf(&result).Elem()
367 for i := 0; i < productVarsReflect.NumField(); i++ {
368 field := productVarsReflect.Field(i)
369 fieldType := productVarsReflect.Type().Field(i)
370 name := fieldType.Name
Cole Faust87c0c332023-07-31 12:10:12 -0700371 if name == "BootJars" || name == "ApexBootJars" || name == "VendorSnapshotModules" ||
372 name == "RecoverySnapshotModules" {
Cole Faustf055db62023-07-24 15:17:03 -0700373 // These variables have more complicated types, and we don't need them right now
374 continue
375 }
376 if _, ok := in[name]; ok {
Cole Faust87c0c332023-07-31 12:10:12 -0700377 if name == "VendorVars" {
378 vendorVars, err := starlark_import.Unmarshal[map[string]map[string]string](in[name])
379 if err != nil {
380 return result, err
381 }
382 field.Set(reflect.ValueOf(vendorVars))
383 continue
384 }
Cole Faustf055db62023-07-24 15:17:03 -0700385 switch field.Type().Kind() {
386 case reflect.Bool:
387 val, err := starlark_import.Unmarshal[bool](in[name])
388 if err != nil {
389 return result, err
390 }
391 field.SetBool(val)
392 case reflect.String:
393 val, err := starlark_import.Unmarshal[string](in[name])
394 if err != nil {
395 return result, err
396 }
397 field.SetString(val)
398 case reflect.Slice:
399 if field.Type().Elem().Kind() != reflect.String {
400 return result, fmt.Errorf("slices of types other than strings are unimplemented")
401 }
402 val, err := starlark_import.UnmarshalReflect(in[name], field.Type())
403 if err != nil {
404 return result, err
405 }
406 field.Set(val)
407 case reflect.Pointer:
408 switch field.Type().Elem().Kind() {
409 case reflect.Bool:
410 val, err := starlark_import.UnmarshalNoneable[bool](in[name])
411 if err != nil {
412 return result, err
413 }
414 field.Set(reflect.ValueOf(val))
415 case reflect.String:
416 val, err := starlark_import.UnmarshalNoneable[string](in[name])
417 if err != nil {
418 return result, err
419 }
420 field.Set(reflect.ValueOf(val))
421 case reflect.Int:
422 val, err := starlark_import.UnmarshalNoneable[int](in[name])
423 if err != nil {
424 return result, err
425 }
426 field.Set(reflect.ValueOf(val))
427 default:
428 return result, fmt.Errorf("pointers of types other than strings/bools are unimplemented: %s", field.Type().Elem().Kind().String())
429 }
430 default:
431 return result, fmt.Errorf("unimplemented type: %s", field.Type().String())
432 }
433 }
Cole Faust88c8efb2023-07-18 11:05:16 -0700434 }
Cole Faustf055db62023-07-24 15:17:03 -0700435
Cole Faust87c0c332023-07-31 12:10:12 -0700436 result.Native_coverage = proptools.BoolPtr(
437 proptools.Bool(result.GcovCoverage) ||
438 proptools.Bool(result.ClangCoverage))
439
Cole Faustb85d1a12022-11-08 18:14:01 -0800440 return result, nil
441}
Cole Faust6054cdf2023-09-12 10:07:07 -0700442
Cole Faustcb193ec2023-09-20 16:01:18 -0700443func createTargets(productLabelsToVariables map[bazelLabel]*android.ProductVariables, res map[string]BazelTargets) {
Cole Faustb4cb0c82023-09-14 15:16:58 -0700444 createGeneratedAndroidCertificateDirectories(productLabelsToVariables, res)
Cole Faustcb193ec2023-09-20 16:01:18 -0700445 for label, variables := range productLabelsToVariables {
446 createSystemPartition(label, &variables.PartitionVarsForBazelMigrationOnlyDoNotUse, res)
447 }
Cole Faustb4cb0c82023-09-14 15:16:58 -0700448}
449
Cole Faustcb193ec2023-09-20 16:01:18 -0700450func createGeneratedAndroidCertificateDirectories(productLabelsToVariables map[bazelLabel]*android.ProductVariables, targets map[string]BazelTargets) {
Cole Faust6054cdf2023-09-12 10:07:07 -0700451 var allDefaultAppCertificateDirs []string
452 for _, productVariables := range productLabelsToVariables {
453 if proptools.String(productVariables.DefaultAppCertificate) != "" {
454 d := filepath.Dir(proptools.String(productVariables.DefaultAppCertificate))
455 if !android.InList(d, allDefaultAppCertificateDirs) {
456 allDefaultAppCertificateDirs = append(allDefaultAppCertificateDirs, d)
457 }
458 }
459 }
460 for _, dir := range allDefaultAppCertificateDirs {
Cole Faustb4cb0c82023-09-14 15:16:58 -0700461 content := `filegroup(
462 name = "generated_android_certificate_directory",
463 srcs = glob([
Cole Faust6054cdf2023-09-12 10:07:07 -0700464 "*.pk8",
465 "*.pem",
466 "*.avbpubkey",
Cole Faustb4cb0c82023-09-14 15:16:58 -0700467 ]),
468 visibility = ["//visibility:public"],
469)`
470 targets[dir] = append(targets[dir], BazelTarget{
Cole Faust6054cdf2023-09-12 10:07:07 -0700471 name: "generated_android_certificate_directory",
472 packageName: dir,
473 content: content,
474 ruleClass: "filegroup",
475 })
476 }
Cole Faust6054cdf2023-09-12 10:07:07 -0700477}
Cole Faustcb193ec2023-09-20 16:01:18 -0700478
479func createSystemPartition(platformLabel bazelLabel, variables *android.PartitionVariables, targets map[string]BazelTargets) {
480 if !variables.PartitionQualifiedVariables["system"].BuildingImage {
481 return
482 }
483
484 imageProps := generateImagePropDictionary(variables, "system")
485 imageProps["skip_fsck"] = "true"
486
487 var properties strings.Builder
488 for _, prop := range android.SortedKeys(imageProps) {
489 properties.WriteString(prop)
490 properties.WriteRune('=')
491 properties.WriteString(imageProps[prop])
492 properties.WriteRune('\n')
493 }
494
495 targets[platformLabel.pkg] = append(targets[platformLabel.pkg], BazelTarget{
496 name: "system_image",
497 packageName: platformLabel.pkg,
498 content: fmt.Sprintf(`partition(
499 name = "system_image",
500 base_staging_dir = "//build/bazel/bazel_sandwich:system_staging_dir",
501 base_staging_dir_file_list = "//build/bazel/bazel_sandwich:system_staging_dir_file_list",
502 root_dir = "//build/bazel/bazel_sandwich:root_staging_dir",
503 image_properties = """
504%s
505""",
506 type = "system",
507)`, properties.String()),
508 ruleClass: "partition",
509 loads: []BazelLoad{{
510 file: "//build/bazel/rules/partitions:partition.bzl",
511 symbols: []BazelLoadSymbol{{
512 symbol: "partition",
513 }},
514 }},
515 }, BazelTarget{
516 name: "system_image_test",
517 packageName: platformLabel.pkg,
518 content: `partition_diff_test(
519 name = "system_image_test",
520 partition1 = "//build/bazel/bazel_sandwich:make_system_image",
521 partition2 = ":system_image",
522)`,
523 ruleClass: "partition_diff_test",
524 loads: []BazelLoad{{
525 file: "//build/bazel/rules/partitions/diff:partition_diff.bzl",
526 symbols: []BazelLoadSymbol{{
527 symbol: "partition_diff_test",
528 }},
529 }},
530 }, BazelTarget{
531 name: "run_system_image_test",
532 packageName: platformLabel.pkg,
533 content: `run_test_in_build(
534 name = "run_system_image_test",
535 test = ":system_image_test",
536)`,
537 ruleClass: "run_test_in_build",
538 loads: []BazelLoad{{
539 file: "//build/bazel/bazel_sandwich:run_test_in_build.bzl",
540 symbols: []BazelLoadSymbol{{
541 symbol: "run_test_in_build",
542 }},
543 }},
544 })
545}
546
547var allPartitionTypes = []string{
548 "system",
549 "vendor",
550 "cache",
551 "userdata",
552 "product",
553 "system_ext",
554 "oem",
555 "odm",
556 "vendor_dlkm",
557 "odm_dlkm",
558 "system_dlkm",
559}
560
561// An equivalent of make's generate-image-prop-dictionary function
562func generateImagePropDictionary(variables *android.PartitionVariables, partitionType string) map[string]string {
563 partitionQualifiedVariables, ok := variables.PartitionQualifiedVariables[partitionType]
564 if !ok {
565 panic("Unknown partitionType: " + partitionType)
566 }
567 ret := map[string]string{}
568 if partitionType == "system" {
569 if len(variables.PartitionQualifiedVariables["system_other"].BoardPartitionSize) > 0 {
570 ret["system_other_size"] = variables.PartitionQualifiedVariables["system_other"].BoardPartitionSize
571 }
572 if len(partitionQualifiedVariables.ProductHeadroom) > 0 {
573 ret["system_headroom"] = partitionQualifiedVariables.ProductHeadroom
574 }
575 addCommonRoFlagsToImageProps(variables, partitionType, ret)
576 }
577 // TODO: other partition-specific logic
578 if variables.TargetUserimagesUseExt2 {
579 ret["fs_type"] = "ext2"
580 } else if variables.TargetUserimagesUseExt3 {
581 ret["fs_type"] = "ext3"
582 } else if variables.TargetUserimagesUseExt4 {
583 ret["fs_type"] = "ext4"
584 }
585
586 if !variables.TargetUserimagesSparseExtDisabled {
587 ret["extfs_sparse_flag"] = "-s"
588 }
589 if !variables.TargetUserimagesSparseErofsDisabled {
590 ret["erofs_sparse_flag"] = "-s"
591 }
592 if !variables.TargetUserimagesSparseSquashfsDisabled {
593 ret["squashfs_sparse_flag"] = "-s"
594 }
595 if !variables.TargetUserimagesSparseF2fsDisabled {
596 ret["f2fs_sparse_flag"] = "-S"
597 }
598 erofsCompressor := variables.BoardErofsCompressor
599 if len(erofsCompressor) == 0 && hasErofsPartition(variables) {
600 if len(variables.BoardErofsUseLegacyCompression) > 0 {
601 erofsCompressor = "lz4"
602 } else {
603 erofsCompressor = "lz4hc,9"
604 }
605 }
606 if len(erofsCompressor) > 0 {
607 ret["erofs_default_compressor"] = erofsCompressor
608 }
609 if len(variables.BoardErofsCompressorHints) > 0 {
610 ret["erofs_default_compress_hints"] = variables.BoardErofsCompressorHints
611 }
612 if len(variables.BoardErofsCompressorHints) > 0 {
613 ret["erofs_default_compress_hints"] = variables.BoardErofsCompressorHints
614 }
615 if len(variables.BoardErofsPclusterSize) > 0 {
616 ret["erofs_pcluster_size"] = variables.BoardErofsPclusterSize
617 }
618 if len(variables.BoardErofsShareDupBlocks) > 0 {
619 ret["erofs_share_dup_blocks"] = variables.BoardErofsShareDupBlocks
620 }
621 if len(variables.BoardErofsUseLegacyCompression) > 0 {
622 ret["erofs_use_legacy_compression"] = variables.BoardErofsUseLegacyCompression
623 }
624 if len(variables.BoardExt4ShareDupBlocks) > 0 {
625 ret["ext4_share_dup_blocks"] = variables.BoardExt4ShareDupBlocks
626 }
627 if len(variables.BoardFlashLogicalBlockSize) > 0 {
628 ret["flash_logical_block_size"] = variables.BoardFlashLogicalBlockSize
629 }
630 if len(variables.BoardFlashEraseBlockSize) > 0 {
631 ret["flash_erase_block_size"] = variables.BoardFlashEraseBlockSize
632 }
633 if len(variables.BoardExt4ShareDupBlocks) > 0 {
634 ret["ext4_share_dup_blocks"] = variables.BoardExt4ShareDupBlocks
635 }
636 if len(variables.BoardExt4ShareDupBlocks) > 0 {
637 ret["ext4_share_dup_blocks"] = variables.BoardExt4ShareDupBlocks
638 }
639 for _, partitionType := range allPartitionTypes {
640 if qualifiedVariables, ok := variables.PartitionQualifiedVariables[partitionType]; ok && len(qualifiedVariables.ProductVerityPartition) > 0 {
641 ret[partitionType+"_verity_block_device"] = qualifiedVariables.ProductVerityPartition
642 }
643 }
644 // TODO: Vboot
645 // TODO: AVB
646 if variables.BoardUsesRecoveryAsBoot {
647 ret["recovery_as_boot"] = "true"
648 }
649 if variables.BoardBuildGkiBootImageWithoutRamdisk {
650 ret["gki_boot_image_without_ramdisk"] = "true"
651 }
652 if variables.ProductUseDynamicPartitionSize {
653 ret["use_dynamic_partition_size"] = "true"
654 }
655 if variables.CopyImagesForTargetFilesZip {
656 ret["use_fixed_timestamp"] = "true"
657 }
658 return ret
659}
660
661// Soong equivalent of make's add-common-ro-flags-to-image-props
662func addCommonRoFlagsToImageProps(variables *android.PartitionVariables, partitionType string, ret map[string]string) {
663 partitionQualifiedVariables, ok := variables.PartitionQualifiedVariables[partitionType]
664 if !ok {
665 panic("Unknown partitionType: " + partitionType)
666 }
667 if len(partitionQualifiedVariables.BoardErofsCompressor) > 0 {
668 ret[partitionType+"_erofs_compressor"] = partitionQualifiedVariables.BoardErofsCompressor
669 }
670 if len(partitionQualifiedVariables.BoardErofsCompressHints) > 0 {
671 ret[partitionType+"_erofs_compress_hints"] = partitionQualifiedVariables.BoardErofsCompressHints
672 }
673 if len(partitionQualifiedVariables.BoardErofsPclusterSize) > 0 {
674 ret[partitionType+"_erofs_pcluster_size"] = partitionQualifiedVariables.BoardErofsPclusterSize
675 }
676 if len(partitionQualifiedVariables.BoardExtfsRsvPct) > 0 {
677 ret[partitionType+"_extfs_rsv_pct"] = partitionQualifiedVariables.BoardExtfsRsvPct
678 }
679 if len(partitionQualifiedVariables.BoardF2fsSloadCompressFlags) > 0 {
680 ret[partitionType+"_f2fs_sldc_flags"] = partitionQualifiedVariables.BoardF2fsSloadCompressFlags
681 }
682 if len(partitionQualifiedVariables.BoardFileSystemCompress) > 0 {
683 ret[partitionType+"_f2fs_compress"] = partitionQualifiedVariables.BoardFileSystemCompress
684 }
685 if len(partitionQualifiedVariables.BoardFileSystemType) > 0 {
686 ret[partitionType+"_fs_type"] = partitionQualifiedVariables.BoardFileSystemType
687 }
688 if len(partitionQualifiedVariables.BoardJournalSize) > 0 {
689 ret[partitionType+"_journal_size"] = partitionQualifiedVariables.BoardJournalSize
690 }
691 if len(partitionQualifiedVariables.BoardPartitionReservedSize) > 0 {
692 ret[partitionType+"_reserved_size"] = partitionQualifiedVariables.BoardPartitionReservedSize
693 }
694 if len(partitionQualifiedVariables.BoardPartitionSize) > 0 {
695 ret[partitionType+"_size"] = partitionQualifiedVariables.BoardPartitionSize
696 }
697 if len(partitionQualifiedVariables.BoardSquashfsBlockSize) > 0 {
698 ret[partitionType+"_squashfs_block_size"] = partitionQualifiedVariables.BoardSquashfsBlockSize
699 }
700 if len(partitionQualifiedVariables.BoardSquashfsCompressor) > 0 {
701 ret[partitionType+"_squashfs_compressor"] = partitionQualifiedVariables.BoardSquashfsCompressor
702 }
703 if len(partitionQualifiedVariables.BoardSquashfsCompressorOpt) > 0 {
704 ret[partitionType+"_squashfs_compressor_opt"] = partitionQualifiedVariables.BoardSquashfsCompressorOpt
705 }
706 if len(partitionQualifiedVariables.BoardSquashfsDisable4kAlign) > 0 {
707 ret[partitionType+"_squashfs_disable_4k_align"] = partitionQualifiedVariables.BoardSquashfsDisable4kAlign
708 }
709 if len(partitionQualifiedVariables.BoardPartitionSize) == 0 && len(partitionQualifiedVariables.BoardPartitionReservedSize) == 0 && len(partitionQualifiedVariables.ProductHeadroom) == 0 {
710 ret[partitionType+"_disable_sparse"] = "true"
711 }
712 addCommonFlagsToImageProps(variables, partitionType, ret)
713}
714
715func hasErofsPartition(variables *android.PartitionVariables) bool {
716 return variables.PartitionQualifiedVariables["product"].BoardFileSystemType == "erofs" ||
717 variables.PartitionQualifiedVariables["system_ext"].BoardFileSystemType == "erofs" ||
718 variables.PartitionQualifiedVariables["odm"].BoardFileSystemType == "erofs" ||
719 variables.PartitionQualifiedVariables["vendor"].BoardFileSystemType == "erofs" ||
720 variables.PartitionQualifiedVariables["system"].BoardFileSystemType == "erofs" ||
721 variables.PartitionQualifiedVariables["vendor_dlkm"].BoardFileSystemType == "erofs" ||
722 variables.PartitionQualifiedVariables["odm_dlkm"].BoardFileSystemType == "erofs" ||
723 variables.PartitionQualifiedVariables["system_dlkm"].BoardFileSystemType == "erofs"
724}
725
726// Soong equivalent of make's add-common-flags-to-image-props
727func addCommonFlagsToImageProps(variables *android.PartitionVariables, partitionType string, ret map[string]string) {
728 // The selinux_fc will be handled separately
729 partitionQualifiedVariables, ok := variables.PartitionQualifiedVariables[partitionType]
730 if !ok {
731 panic("Unknown partitionType: " + partitionType)
732 }
733 ret["building_"+partitionType+"_image"] = boolToMakeString(partitionQualifiedVariables.BuildingImage)
734}
735
736func boolToMakeString(b bool) string {
737 if b {
738 return "true"
739 }
740 return ""
741}