blob: 091a5f3acadd646fa04935ccdf1b39f83a8638f6 [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
Romain Jobredeaux9c06ef32023-08-21 18:05:29 -0400270 // TODO: b/301598690 - commas can't be escaped in a string-list passed in a platform mapping,
271 // so commas are switched for ":" here, and must be back-substituted into commas
272 // wherever the AAPTCharacteristics product config variable is used.
273 AAPTConfig := []string{}
274 for _, conf := range productVariables.AAPTConfig {
275 AAPTConfig = append(AAPTConfig, strings.Replace(conf, ",", ":", -1))
276 }
277
Cole Faustf055db62023-07-24 15:17:03 -0700278 for _, suffix := range bazelPlatformSuffixes {
279 result.WriteString(" ")
Cole Faustcb193ec2023-09-20 16:01:18 -0700280 result.WriteString(label.String())
Cole Faustf055db62023-07-24 15:17:03 -0700281 result.WriteString(suffix)
282 result.WriteString("\n")
Romain Jobredeaux9c06ef32023-08-21 18:05:29 -0400283 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:aapt_characteristics=%s\n", proptools.String(productVariables.AAPTCharacteristics)))
284 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:aapt_config=%s\n", strings.Join(AAPTConfig, ",")))
285 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:aapt_preferred_config=%s\n", proptools.String(productVariables.AAPTPreferredConfig)))
Cole Faustf055db62023-07-24 15:17:03 -0700286 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 -0700287 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:arc=%t\n", proptools.Bool(productVariables.Arc)))
Cole Faustf055db62023-07-24 15:17:03 -0700288 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 -0700289 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:binder32bit=%t\n", proptools.Bool(productVariables.Binder32bit)))
290 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 -0700291 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:build_broken_incorrect_partition_images=%t\n", productVariables.BuildBrokenIncorrectPartitionImages))
Cole Faustf055db62023-07-24 15:17:03 -0700292 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:build_id=%s\n", proptools.String(productVariables.BuildId)))
293 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:build_version_tags=%s\n", strings.Join(productVariables.BuildVersionTags, ",")))
Cole Faustf055db62023-07-24 15:17:03 -0700294 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:cfi_exclude_paths=%s\n", strings.Join(productVariables.CFIExcludePaths, ",")))
295 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:cfi_include_paths=%s\n", strings.Join(productVariables.CFIIncludePaths, ",")))
296 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:compressed_apex=%t\n", proptools.Bool(productVariables.CompressedApex)))
297 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:default_app_certificate=%s\n", proptools.String(productVariables.DefaultAppCertificate)))
Cole Faust946d02c2023-08-03 16:08:09 -0700298 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:default_app_certificate_filegroup=%s\n", defaultAppCertificateFilegroup))
Cole Faustf055db62023-07-24 15:17:03 -0700299 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:device_abi=%s\n", strings.Join(productVariables.DeviceAbi, ",")))
300 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:device_max_page_size_supported=%s\n", proptools.String(productVariables.DeviceMaxPageSizeSupported)))
301 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:device_name=%s\n", proptools.String(productVariables.DeviceName)))
Juan Yescas01065602023-08-09 08:34:37 -0700302 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 -0700303 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:device_product=%s\n", proptools.String(productVariables.DeviceProduct)))
Cole Faustcb193ec2023-09-20 16:01:18 -0700304 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:device_platform=%s\n", label.String()))
Cole Faustf055db62023-07-24 15:17:03 -0700305 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:enable_cfi=%t\n", proptools.BoolDefault(productVariables.EnableCFI, true)))
Cole Faust87c0c332023-07-31 12:10:12 -0700306 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 -0700307 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:malloc_not_svelte=%t\n", proptools.Bool(productVariables.Malloc_not_svelte)))
308 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:malloc_pattern_fill_contents=%t\n", proptools.Bool(productVariables.Malloc_pattern_fill_contents)))
309 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 -0700310 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:memtag_heap_exclude_paths=%s\n", strings.Join(productVariables.MemtagHeapExcludePaths, ",")))
311 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:memtag_heap_async_include_paths=%s\n", strings.Join(productVariables.MemtagHeapAsyncIncludePaths, ",")))
312 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 -0700313 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 -0700314 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:native_coverage=%t\n", proptools.Bool(productVariables.Native_coverage)))
Romain Jobredeaux3132f842023-09-15 10:06:16 -0400315 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 -0700316 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:platform_version_name=%s\n", proptools.String(productVariables.Platform_version_name)))
317 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:product_brand=%s\n", productVariables.ProductBrand))
318 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:product_manufacturer=%s\n", productVariables.ProductManufacturer))
Yu Liu2cc802a2023-09-05 17:19:45 -0700319 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:release_aconfig_flag_default_permission=%s\n", productVariables.ReleaseAconfigFlagDefaultPermission))
320 // Empty string can't be used as label_flag on the bazel side
321 if len(productVariables.ReleaseAconfigValueSets) > 0 {
322 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:release_aconfig_value_sets=%s\n", productVariables.ReleaseAconfigValueSets))
323 }
324 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:release_version=%s\n", productVariables.ReleaseVersion))
Cole Faust95c5cf82023-08-03 13:49:27 -0700325 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:platform_sdk_version=%d\n", platform_sdk_version))
Cole Faust87c0c332023-07-31 12:10:12 -0700326 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:safestack=%t\n", proptools.Bool(productVariables.Safestack)))
Cole Faust87c0c332023-07-31 12:10:12 -0700327 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 -0700328 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:tidy_checks=%s\n", proptools.String(productVariables.TidyChecks)))
Cole Faust87c0c332023-07-31 12:10:12 -0700329 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:uml=%t\n", proptools.Bool(productVariables.Uml)))
Cole Faustf055db62023-07-24 15:17:03 -0700330 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:unbundled_build=%t\n", proptools.Bool(productVariables.Unbundled_build)))
331 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 -0700332
333 for _, override := range productVariables.CertificateOverrides {
334 parts := strings.SplitN(override, ":", 2)
335 if apexPath, ok := convertedModulePathMap[parts[0]]; ok {
336 if overrideCertPath, ok := convertedModulePathMap[parts[1]]; ok {
337 result.WriteString(fmt.Sprintf(" --%s:%s_certificate_override=%s:%s\n", apexPath, parts[0], overrideCertPath, parts[1]))
338 }
339 }
340 }
341
Cole Faust87c0c332023-07-31 12:10:12 -0700342 for namespace, namespaceContents := range productVariables.VendorVars {
343 for variable, value := range namespaceContents {
344 key := namespace + "__" + variable
345 _, hasBool := soongConfigDefinitions.BoolVars[key]
346 _, hasString := soongConfigDefinitions.StringVars[key]
347 _, hasValue := soongConfigDefinitions.ValueVars[key]
348 if !hasBool && !hasString && !hasValue {
349 // Not all soong config variables are defined in Android.bp files. For example,
350 // prebuilt_bootclasspath_fragment uses soong config variables in a nonstandard
351 // way, that causes them to be present in the soong.variables file but not
352 // defined in an Android.bp file. There's also nothing stopping you from setting
353 // a variable in make that doesn't exist in soong. We only generate build
354 // settings for the ones that exist in soong, so skip all others.
355 continue
356 }
357 if hasBool && hasString || hasBool && hasValue || hasString && hasValue {
358 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))
359 }
360 if hasBool {
361 // Logic copied from soongConfig.Bool()
362 value = strings.ToLower(value)
363 if value == "1" || value == "y" || value == "yes" || value == "on" || value == "true" {
364 value = "true"
365 } else {
366 value = "false"
367 }
368 }
369 result.WriteString(fmt.Sprintf(" --//build/bazel/product_config/soong_config_variables:%s=%s\n", strings.ToLower(key), value))
370 }
371 }
Cole Faustf055db62023-07-24 15:17:03 -0700372 }
Cole Faustf8231dd2023-04-21 17:37:11 -0700373}
374
375func starlarkMapToProductVariables(in map[string]starlark.Value) (android.ProductVariables, error) {
Cole Faustf8231dd2023-04-21 17:37:11 -0700376 result := android.ProductVariables{}
Cole Faustf055db62023-07-24 15:17:03 -0700377 productVarsReflect := reflect.ValueOf(&result).Elem()
378 for i := 0; i < productVarsReflect.NumField(); i++ {
379 field := productVarsReflect.Field(i)
380 fieldType := productVarsReflect.Type().Field(i)
381 name := fieldType.Name
Cole Faust87c0c332023-07-31 12:10:12 -0700382 if name == "BootJars" || name == "ApexBootJars" || name == "VendorSnapshotModules" ||
383 name == "RecoverySnapshotModules" {
Cole Faustf055db62023-07-24 15:17:03 -0700384 // These variables have more complicated types, and we don't need them right now
385 continue
386 }
387 if _, ok := in[name]; ok {
Cole Faust87c0c332023-07-31 12:10:12 -0700388 if name == "VendorVars" {
389 vendorVars, err := starlark_import.Unmarshal[map[string]map[string]string](in[name])
390 if err != nil {
391 return result, err
392 }
393 field.Set(reflect.ValueOf(vendorVars))
394 continue
395 }
Cole Faustf055db62023-07-24 15:17:03 -0700396 switch field.Type().Kind() {
397 case reflect.Bool:
398 val, err := starlark_import.Unmarshal[bool](in[name])
399 if err != nil {
400 return result, err
401 }
402 field.SetBool(val)
403 case reflect.String:
404 val, err := starlark_import.Unmarshal[string](in[name])
405 if err != nil {
406 return result, err
407 }
408 field.SetString(val)
409 case reflect.Slice:
410 if field.Type().Elem().Kind() != reflect.String {
411 return result, fmt.Errorf("slices of types other than strings are unimplemented")
412 }
413 val, err := starlark_import.UnmarshalReflect(in[name], field.Type())
414 if err != nil {
415 return result, err
416 }
417 field.Set(val)
418 case reflect.Pointer:
419 switch field.Type().Elem().Kind() {
420 case reflect.Bool:
421 val, err := starlark_import.UnmarshalNoneable[bool](in[name])
422 if err != nil {
423 return result, err
424 }
425 field.Set(reflect.ValueOf(val))
426 case reflect.String:
427 val, err := starlark_import.UnmarshalNoneable[string](in[name])
428 if err != nil {
429 return result, err
430 }
431 field.Set(reflect.ValueOf(val))
432 case reflect.Int:
433 val, err := starlark_import.UnmarshalNoneable[int](in[name])
434 if err != nil {
435 return result, err
436 }
437 field.Set(reflect.ValueOf(val))
438 default:
439 return result, fmt.Errorf("pointers of types other than strings/bools are unimplemented: %s", field.Type().Elem().Kind().String())
440 }
441 default:
442 return result, fmt.Errorf("unimplemented type: %s", field.Type().String())
443 }
444 }
Cole Faust88c8efb2023-07-18 11:05:16 -0700445 }
Cole Faustf055db62023-07-24 15:17:03 -0700446
Cole Faust87c0c332023-07-31 12:10:12 -0700447 result.Native_coverage = proptools.BoolPtr(
448 proptools.Bool(result.GcovCoverage) ||
449 proptools.Bool(result.ClangCoverage))
450
Cole Faustb85d1a12022-11-08 18:14:01 -0800451 return result, nil
452}
Cole Faust6054cdf2023-09-12 10:07:07 -0700453
Cole Faustcb193ec2023-09-20 16:01:18 -0700454func createTargets(productLabelsToVariables map[bazelLabel]*android.ProductVariables, res map[string]BazelTargets) {
Cole Faustb4cb0c82023-09-14 15:16:58 -0700455 createGeneratedAndroidCertificateDirectories(productLabelsToVariables, res)
Cole Faustcb193ec2023-09-20 16:01:18 -0700456 for label, variables := range productLabelsToVariables {
457 createSystemPartition(label, &variables.PartitionVarsForBazelMigrationOnlyDoNotUse, res)
458 }
Cole Faustb4cb0c82023-09-14 15:16:58 -0700459}
460
Cole Faustcb193ec2023-09-20 16:01:18 -0700461func createGeneratedAndroidCertificateDirectories(productLabelsToVariables map[bazelLabel]*android.ProductVariables, targets map[string]BazelTargets) {
Cole Faust6054cdf2023-09-12 10:07:07 -0700462 var allDefaultAppCertificateDirs []string
463 for _, productVariables := range productLabelsToVariables {
464 if proptools.String(productVariables.DefaultAppCertificate) != "" {
465 d := filepath.Dir(proptools.String(productVariables.DefaultAppCertificate))
466 if !android.InList(d, allDefaultAppCertificateDirs) {
467 allDefaultAppCertificateDirs = append(allDefaultAppCertificateDirs, d)
468 }
469 }
470 }
471 for _, dir := range allDefaultAppCertificateDirs {
Cole Faustb4cb0c82023-09-14 15:16:58 -0700472 content := `filegroup(
473 name = "generated_android_certificate_directory",
474 srcs = glob([
Cole Faust6054cdf2023-09-12 10:07:07 -0700475 "*.pk8",
476 "*.pem",
477 "*.avbpubkey",
Cole Faustb4cb0c82023-09-14 15:16:58 -0700478 ]),
479 visibility = ["//visibility:public"],
480)`
481 targets[dir] = append(targets[dir], BazelTarget{
Cole Faust6054cdf2023-09-12 10:07:07 -0700482 name: "generated_android_certificate_directory",
483 packageName: dir,
484 content: content,
485 ruleClass: "filegroup",
486 })
487 }
Cole Faust6054cdf2023-09-12 10:07:07 -0700488}
Cole Faustcb193ec2023-09-20 16:01:18 -0700489
490func createSystemPartition(platformLabel bazelLabel, variables *android.PartitionVariables, targets map[string]BazelTargets) {
491 if !variables.PartitionQualifiedVariables["system"].BuildingImage {
492 return
493 }
494
495 imageProps := generateImagePropDictionary(variables, "system")
496 imageProps["skip_fsck"] = "true"
497
498 var properties strings.Builder
499 for _, prop := range android.SortedKeys(imageProps) {
500 properties.WriteString(prop)
501 properties.WriteRune('=')
502 properties.WriteString(imageProps[prop])
503 properties.WriteRune('\n')
504 }
505
506 targets[platformLabel.pkg] = append(targets[platformLabel.pkg], BazelTarget{
507 name: "system_image",
508 packageName: platformLabel.pkg,
509 content: fmt.Sprintf(`partition(
510 name = "system_image",
511 base_staging_dir = "//build/bazel/bazel_sandwich:system_staging_dir",
512 base_staging_dir_file_list = "//build/bazel/bazel_sandwich:system_staging_dir_file_list",
513 root_dir = "//build/bazel/bazel_sandwich:root_staging_dir",
514 image_properties = """
515%s
516""",
517 type = "system",
518)`, properties.String()),
519 ruleClass: "partition",
520 loads: []BazelLoad{{
521 file: "//build/bazel/rules/partitions:partition.bzl",
522 symbols: []BazelLoadSymbol{{
523 symbol: "partition",
524 }},
525 }},
526 }, BazelTarget{
527 name: "system_image_test",
528 packageName: platformLabel.pkg,
529 content: `partition_diff_test(
530 name = "system_image_test",
531 partition1 = "//build/bazel/bazel_sandwich:make_system_image",
532 partition2 = ":system_image",
533)`,
534 ruleClass: "partition_diff_test",
535 loads: []BazelLoad{{
536 file: "//build/bazel/rules/partitions/diff:partition_diff.bzl",
537 symbols: []BazelLoadSymbol{{
538 symbol: "partition_diff_test",
539 }},
540 }},
541 }, BazelTarget{
542 name: "run_system_image_test",
543 packageName: platformLabel.pkg,
544 content: `run_test_in_build(
545 name = "run_system_image_test",
546 test = ":system_image_test",
547)`,
548 ruleClass: "run_test_in_build",
549 loads: []BazelLoad{{
550 file: "//build/bazel/bazel_sandwich:run_test_in_build.bzl",
551 symbols: []BazelLoadSymbol{{
552 symbol: "run_test_in_build",
553 }},
554 }},
555 })
556}
557
558var allPartitionTypes = []string{
559 "system",
560 "vendor",
561 "cache",
562 "userdata",
563 "product",
564 "system_ext",
565 "oem",
566 "odm",
567 "vendor_dlkm",
568 "odm_dlkm",
569 "system_dlkm",
570}
571
572// An equivalent of make's generate-image-prop-dictionary function
573func generateImagePropDictionary(variables *android.PartitionVariables, partitionType string) map[string]string {
574 partitionQualifiedVariables, ok := variables.PartitionQualifiedVariables[partitionType]
575 if !ok {
576 panic("Unknown partitionType: " + partitionType)
577 }
578 ret := map[string]string{}
579 if partitionType == "system" {
580 if len(variables.PartitionQualifiedVariables["system_other"].BoardPartitionSize) > 0 {
581 ret["system_other_size"] = variables.PartitionQualifiedVariables["system_other"].BoardPartitionSize
582 }
583 if len(partitionQualifiedVariables.ProductHeadroom) > 0 {
584 ret["system_headroom"] = partitionQualifiedVariables.ProductHeadroom
585 }
586 addCommonRoFlagsToImageProps(variables, partitionType, ret)
587 }
588 // TODO: other partition-specific logic
589 if variables.TargetUserimagesUseExt2 {
590 ret["fs_type"] = "ext2"
591 } else if variables.TargetUserimagesUseExt3 {
592 ret["fs_type"] = "ext3"
593 } else if variables.TargetUserimagesUseExt4 {
594 ret["fs_type"] = "ext4"
595 }
596
597 if !variables.TargetUserimagesSparseExtDisabled {
598 ret["extfs_sparse_flag"] = "-s"
599 }
600 if !variables.TargetUserimagesSparseErofsDisabled {
601 ret["erofs_sparse_flag"] = "-s"
602 }
603 if !variables.TargetUserimagesSparseSquashfsDisabled {
604 ret["squashfs_sparse_flag"] = "-s"
605 }
606 if !variables.TargetUserimagesSparseF2fsDisabled {
607 ret["f2fs_sparse_flag"] = "-S"
608 }
609 erofsCompressor := variables.BoardErofsCompressor
610 if len(erofsCompressor) == 0 && hasErofsPartition(variables) {
611 if len(variables.BoardErofsUseLegacyCompression) > 0 {
612 erofsCompressor = "lz4"
613 } else {
614 erofsCompressor = "lz4hc,9"
615 }
616 }
617 if len(erofsCompressor) > 0 {
618 ret["erofs_default_compressor"] = erofsCompressor
619 }
620 if len(variables.BoardErofsCompressorHints) > 0 {
621 ret["erofs_default_compress_hints"] = variables.BoardErofsCompressorHints
622 }
623 if len(variables.BoardErofsCompressorHints) > 0 {
624 ret["erofs_default_compress_hints"] = variables.BoardErofsCompressorHints
625 }
626 if len(variables.BoardErofsPclusterSize) > 0 {
627 ret["erofs_pcluster_size"] = variables.BoardErofsPclusterSize
628 }
629 if len(variables.BoardErofsShareDupBlocks) > 0 {
630 ret["erofs_share_dup_blocks"] = variables.BoardErofsShareDupBlocks
631 }
632 if len(variables.BoardErofsUseLegacyCompression) > 0 {
633 ret["erofs_use_legacy_compression"] = variables.BoardErofsUseLegacyCompression
634 }
635 if len(variables.BoardExt4ShareDupBlocks) > 0 {
636 ret["ext4_share_dup_blocks"] = variables.BoardExt4ShareDupBlocks
637 }
638 if len(variables.BoardFlashLogicalBlockSize) > 0 {
639 ret["flash_logical_block_size"] = variables.BoardFlashLogicalBlockSize
640 }
641 if len(variables.BoardFlashEraseBlockSize) > 0 {
642 ret["flash_erase_block_size"] = variables.BoardFlashEraseBlockSize
643 }
644 if len(variables.BoardExt4ShareDupBlocks) > 0 {
645 ret["ext4_share_dup_blocks"] = variables.BoardExt4ShareDupBlocks
646 }
647 if len(variables.BoardExt4ShareDupBlocks) > 0 {
648 ret["ext4_share_dup_blocks"] = variables.BoardExt4ShareDupBlocks
649 }
650 for _, partitionType := range allPartitionTypes {
651 if qualifiedVariables, ok := variables.PartitionQualifiedVariables[partitionType]; ok && len(qualifiedVariables.ProductVerityPartition) > 0 {
652 ret[partitionType+"_verity_block_device"] = qualifiedVariables.ProductVerityPartition
653 }
654 }
655 // TODO: Vboot
656 // TODO: AVB
657 if variables.BoardUsesRecoveryAsBoot {
658 ret["recovery_as_boot"] = "true"
659 }
660 if variables.BoardBuildGkiBootImageWithoutRamdisk {
661 ret["gki_boot_image_without_ramdisk"] = "true"
662 }
663 if variables.ProductUseDynamicPartitionSize {
664 ret["use_dynamic_partition_size"] = "true"
665 }
666 if variables.CopyImagesForTargetFilesZip {
667 ret["use_fixed_timestamp"] = "true"
668 }
669 return ret
670}
671
672// Soong equivalent of make's add-common-ro-flags-to-image-props
673func addCommonRoFlagsToImageProps(variables *android.PartitionVariables, partitionType string, ret map[string]string) {
674 partitionQualifiedVariables, ok := variables.PartitionQualifiedVariables[partitionType]
675 if !ok {
676 panic("Unknown partitionType: " + partitionType)
677 }
678 if len(partitionQualifiedVariables.BoardErofsCompressor) > 0 {
679 ret[partitionType+"_erofs_compressor"] = partitionQualifiedVariables.BoardErofsCompressor
680 }
681 if len(partitionQualifiedVariables.BoardErofsCompressHints) > 0 {
682 ret[partitionType+"_erofs_compress_hints"] = partitionQualifiedVariables.BoardErofsCompressHints
683 }
684 if len(partitionQualifiedVariables.BoardErofsPclusterSize) > 0 {
685 ret[partitionType+"_erofs_pcluster_size"] = partitionQualifiedVariables.BoardErofsPclusterSize
686 }
687 if len(partitionQualifiedVariables.BoardExtfsRsvPct) > 0 {
688 ret[partitionType+"_extfs_rsv_pct"] = partitionQualifiedVariables.BoardExtfsRsvPct
689 }
690 if len(partitionQualifiedVariables.BoardF2fsSloadCompressFlags) > 0 {
691 ret[partitionType+"_f2fs_sldc_flags"] = partitionQualifiedVariables.BoardF2fsSloadCompressFlags
692 }
693 if len(partitionQualifiedVariables.BoardFileSystemCompress) > 0 {
694 ret[partitionType+"_f2fs_compress"] = partitionQualifiedVariables.BoardFileSystemCompress
695 }
696 if len(partitionQualifiedVariables.BoardFileSystemType) > 0 {
697 ret[partitionType+"_fs_type"] = partitionQualifiedVariables.BoardFileSystemType
698 }
699 if len(partitionQualifiedVariables.BoardJournalSize) > 0 {
700 ret[partitionType+"_journal_size"] = partitionQualifiedVariables.BoardJournalSize
701 }
702 if len(partitionQualifiedVariables.BoardPartitionReservedSize) > 0 {
703 ret[partitionType+"_reserved_size"] = partitionQualifiedVariables.BoardPartitionReservedSize
704 }
705 if len(partitionQualifiedVariables.BoardPartitionSize) > 0 {
706 ret[partitionType+"_size"] = partitionQualifiedVariables.BoardPartitionSize
707 }
708 if len(partitionQualifiedVariables.BoardSquashfsBlockSize) > 0 {
709 ret[partitionType+"_squashfs_block_size"] = partitionQualifiedVariables.BoardSquashfsBlockSize
710 }
711 if len(partitionQualifiedVariables.BoardSquashfsCompressor) > 0 {
712 ret[partitionType+"_squashfs_compressor"] = partitionQualifiedVariables.BoardSquashfsCompressor
713 }
714 if len(partitionQualifiedVariables.BoardSquashfsCompressorOpt) > 0 {
715 ret[partitionType+"_squashfs_compressor_opt"] = partitionQualifiedVariables.BoardSquashfsCompressorOpt
716 }
717 if len(partitionQualifiedVariables.BoardSquashfsDisable4kAlign) > 0 {
718 ret[partitionType+"_squashfs_disable_4k_align"] = partitionQualifiedVariables.BoardSquashfsDisable4kAlign
719 }
720 if len(partitionQualifiedVariables.BoardPartitionSize) == 0 && len(partitionQualifiedVariables.BoardPartitionReservedSize) == 0 && len(partitionQualifiedVariables.ProductHeadroom) == 0 {
721 ret[partitionType+"_disable_sparse"] = "true"
722 }
723 addCommonFlagsToImageProps(variables, partitionType, ret)
724}
725
726func hasErofsPartition(variables *android.PartitionVariables) bool {
727 return variables.PartitionQualifiedVariables["product"].BoardFileSystemType == "erofs" ||
728 variables.PartitionQualifiedVariables["system_ext"].BoardFileSystemType == "erofs" ||
729 variables.PartitionQualifiedVariables["odm"].BoardFileSystemType == "erofs" ||
730 variables.PartitionQualifiedVariables["vendor"].BoardFileSystemType == "erofs" ||
731 variables.PartitionQualifiedVariables["system"].BoardFileSystemType == "erofs" ||
732 variables.PartitionQualifiedVariables["vendor_dlkm"].BoardFileSystemType == "erofs" ||
733 variables.PartitionQualifiedVariables["odm_dlkm"].BoardFileSystemType == "erofs" ||
734 variables.PartitionQualifiedVariables["system_dlkm"].BoardFileSystemType == "erofs"
735}
736
737// Soong equivalent of make's add-common-flags-to-image-props
738func addCommonFlagsToImageProps(variables *android.PartitionVariables, partitionType string, ret map[string]string) {
739 // The selinux_fc will be handled separately
740 partitionQualifiedVariables, ok := variables.PartitionQualifiedVariables[partitionType]
741 if !ok {
742 panic("Unknown partitionType: " + partitionType)
743 }
744 ret["building_"+partitionType+"_image"] = boolToMakeString(partitionQualifiedVariables.BuildingImage)
745}
746
747func boolToMakeString(b bool) string {
748 if b {
749 return "true"
750 }
751 return ""
752}