Compare commits

...

56 commits

Author SHA1 Message Date
basamaryan
876f0bb0d9
gen_build_prop: Stop overriding ro.build.display.id for non-user builds
Change-Id: Ifc5b5fb23963a984f971ad0fda8c4cc3aec771ab
2024-10-24 19:42:40 +02:00
Michael Bestas
ac339f8e66
gen_build_prop: Set ro.tequila.device
Change-Id: I485d74642b869d7ac94ef2fd171cafd759965d41
2024-10-24 19:42:04 +02:00
Cole Faust
4c819d9401
Remove zeros from build number
The zeros were kept in place of the timestamp in case people were
parsing it. Let's try to remove the zeros now and see what breaks.

Test: Presubmits
Change-Id: Ic52168f6be05a74323d8e47935de5c6a5cf15516
2024-10-24 19:41:24 +02:00
Michael Bestas
3dccccee5e
gen_build_prop: Set ro.minui.default_touch_rotation
Change-Id: I18745292fadb8a8ff37d94e5603256997a3c1036
2024-10-24 19:41:24 +02:00
Michael Bestas
144754b153
gen_build_prop: Set ro.build.fingerprint
Change-Id: I0e40b6f8154f8bc9a7b8450ecb4af4c44ab3d46d
2024-10-24 19:41:24 +02:00
Luca Stefani
2e6152ee86
Add support for prop overrides
The format of the overrides is KEY=VALUE
Where KEY is one of the dict keys used in config
https://cs.android.com/android/platform/superproject/main/+/main:build/soong/scripts/gen_build_prop.py
And VALUE is the value you want take over.

An example:
PRODUCT_BUILD_PROP_OVERRIDES += \
    BuildDesc="jfltevzw-user 4.2.2 JDQ39 I545VRUAMDK release-keys" \
    BuildFingerprint=Verizon/jfltevzw/jfltevzw:4.2.2/JDQ39/I545VRUAMDK:user/release-keys \
    DeviceName=jfltevzw \
    DeviceProduct=jfltevzw \
    SystemDevice=jfltevzw \
    SystemName=jfltevzw

Change-Id: Ib44a3bb573d08d492acc092e104cb4f687f3b168
2024-10-24 19:41:24 +02:00
Inseob Kim
f9b8137457
Include TARGET_ODM_PROP to odm/etc/build.prop
It's missing in Soong's build_prop module.

Bug: 322090587
Bug: 361623560
Test: set TARGET_ODM_PROP and see odm/etc/build.prop
Change-Id: I447a64998f6ae0ba80201ab4ab6c0fd0ef22e3e5
2024-10-24 19:41:24 +02:00
Yi-Yo Chiang
08cb1af507
Fix build_prop module to use partition() instead of PartitionTag()
PartitionTag() returns the partition the module is installed in.
We don't want this because a system_ext_specific module could be
installed in the system partition if system_ext partition doesn't
exist.
Instead we want system_ext specific modules to always refer to
SystemExtPropFiles().

Bug: 359624775
Bug: 322090587
Test: build aosp_arm64 and verify system/system_ext/etc/build.prop
Change-Id: Ie67ec9c5e5a07e781515e0aafb42122f72447cf3
2024-10-24 19:41:23 +02:00
Inseob Kim
3448cf213b
Build product/odm build.prop with Soong
Bug: 322090587
Test: compare build.prop before and after, boot
Change-Id: I7a7dc785030a0c17e5c09b7f65c978fe9bbcb7a7
2024-10-24 19:41:23 +02:00
Inseob Kim
2900689117
Add system_ext support to build_prop module
As some partitions have build.prop under etc/, this change adds
relative_install_path property to build_prop module. Also this change
adds system_ext related Soong variables and system_ext support in
gen_build_prop.py.

Bug: 322090587
Test: build and compare system_ext/etc/build.prop
Change-Id: I416662b8bae09383af0cdd3d8444a5c300006b7b
2024-10-24 19:41:23 +02:00
Inseob Kim
ec12b7dc1e
Revert^6 "Use Soong-built system/build.prop"
d5a12721b5aab92122a0bfb979144affa9a2e62a

Change-Id: I6f4bf3043e73763b047bec3303f1547ec647d12b
2024-10-24 19:41:23 +02:00
Inseob Kim
831bbcdc38
Revert^6 "Sync gen_build_prop.py to sysprop.mk"
This reverts commit 7b7593968bfbddd16e461c44da7062e02db5ad7a.

Reason for revert: fixed breakage with aosp/3200730, verified with ABTD

Change-Id: I83a4cb1a39bce1a1da8fabd49c6c895862a6c686
2024-10-24 19:41:23 +02:00
Inseob Kim
e63689fec0
Revert^2 "Conditionally pass kernel version to build.prop"
This reverts commit 29fed1efe85cc07bb4311513e4acc1da73dfb298.

Reason for revert: Fixed breakage with aosp/3200730, verified with ABTD

Change-Id: I207abd188636673250eb9a070be95db0b82f39e7
2024-10-24 19:41:23 +02:00
Inseob Kim
ce0cfaaf3f
Revert^6 "Add TARGET_SYSTEM_PROP to system build.prop"
530c32acbee136ff3475192335cc7594589de096

Change-Id: I9dc817855e3db7b96320a977b24b84d72e762893
2024-10-24 19:41:23 +02:00
Inseob Kim
262fa746b8
Revert "Revert "Revert^2 "Set output for build_prop even on Soon..."
Revert submission 3200273-revert-3196490-revert-3195812-revert-3195644-revert-3195637-revert-3184480-system_build_prop_soong-BZIDUTEOOC-KRUETCBWUR-TUHZPHUVFJ-XYILSUPUOA-PCKYAVELZP

Reason for revert: fixed breakage with aosp/3200730, verified with ABTD

Reverted changes: /q/submissionid:3200273-revert-3196490-revert-3195812-revert-3195644-revert-3195637-revert-3184480-system_build_prop_soong-BZIDUTEOOC-KRUETCBWUR-TUHZPHUVFJ-XYILSUPUOA-PCKYAVELZP

Change-Id: If9e6841bb915a79d9817838a1657017ddee9c1a7
2024-10-24 19:41:23 +02:00
Kiyoung Kim
fb75ec2011
Add 'use_debug_art' to product_variable
Add 'use_debug_art' property to product_variable so it can be checked
from Android.bp whether ART debug APEX or ART APEX should be used.

Bug: 351698657
Test: AOSP CF eng build succeeded
Test: AOSP CF userdebug build succeeded
Change-Id: I01cd80f0d899c55828ecb05fdafdc9bb05fd8200
2024-10-24 19:41:23 +02:00
Inseob Kim
f2ef1a3447
Fix build thumbprint in gen_build_prop.py
Bug: 356297315
Test: TH and ABTD
Change-Id: I28bccbbafbf9bcdf45a58361e37435b8d74d7464
2024-10-24 19:41:23 +02:00
Inseob Kim
eebe034cc1
Fix DISPLAY_BUILD_NUMBER
The dot was accidentally removed.

Bug: 353425495
Test: build
Change-Id: Id0c08f3c98d5b2f56e49180baf98bb8847f6bebd
2024-10-24 19:41:23 +02:00
Justin Yun
7a3899f93f
Fix build error for gen_build_prop.py
Provided undefined constants and imports.

Bug: 346214958
Test: Define "PRODUCT_DEFAULT_DEV_CERTIFICATE := \
                 build/make/target/product/security/testkey" and
      m aosp_cf_system_x86_64
Change-Id: Ic65f059fe87a997a9be695ebf13dfde2d2c6f82c
2024-10-24 19:41:23 +02:00
Inseob Kim
3ea2ca1ede
Fix a bug that BUILD_VERSION_TAGS is ignored
Bug: 349046347
Test: set BUILD_VERSION_TAGS and build
Change-Id: Ib981d917435d23139ac0c5b0aba5b6893539d200
2024-10-24 19:41:23 +02:00
Inseob Kim
8cd40a7e3c
Add build_prop soong module
build_prop is a soong module generating {partition}/build.prop. It's
ported from build/make/core/sysprop.mk and will replace sysprop.mk in
the future. Currently used only by Android.bp cuttlefish system image.

Bug: 322090587
Bug: 346214958
Test: compare system/build.prop and aosp_cf_x86_64_system-build.prop for
      eng / user / userdebug
Change-Id: Iad76139fe86ec4f582218c185aa15baeacaa38dc
2024-10-24 19:41:23 +02:00
Inseob Kim
feb21547f9
Use product_config from buildinfo_prop module
Many parameters can be migrated to product_config module. This is also a
PoC, which is helpful for future build.prop migration.

Bug: 346214955
Test: compare buildinfo.prop before and after
Change-Id: I751220b3a09583e469ae721c0e49a1909b6428d7
2024-10-24 19:41:23 +02:00
Inseob Kim
26e9a73798
Add product_config module
product_config module will export productVariables struct (defined in
android/variable.go). Other modules can depend on product_Config module
to read product variables, without needing to update Soong.

Bug: 346214955
Test: build and see output of product_config module
Change-Id: I06e1d2716dc2a8b90984bb46c5fc901cd1ca5020
2024-10-24 19:41:23 +02:00
Cole Faust
4b2bb5e9ab
Cleanup configurable getter usages
You don't have to call module.ConfigurableEvaluator(ctx) if ctx is
already a ModuleContext, you only need to do that for more restricted
contexts like SingletonContext.

Bug: 323382414
Test: m nothing --no-skip-soong-tests
Change-Id: I7612290d43dae7decfae283a341882d9016c98a3
2024-10-24 19:41:23 +02:00
Aleks Todorov
24a3d377d8
cc: Enable select syntax for cppflags
Bug: 325444956
Test: m
Test: m [custom build target with select in cppflags]
Change-Id: I7d27096526ce5b37afe447f900613a6fbb639986
2024-10-24 19:41:23 +02:00
Inseob Kim
a79bbf3bdb
Make vbmeta Partitions property configurable
This allows using select statements.

Bug: 354824866
Test: boot
Change-Id: I6cb41177620f85697eeaa77d3aec79f21674e245
2024-10-24 19:41:23 +02:00
Nelson Li
4427aab6e3
Enable select syntax support for phony_deps in phony_rule
Previously, `phony_deps` in `phony_rule` was a simple []string type, so
the select syntax was not supported. This change modifies it to a
Configurable[[]string] type to enable select syntax support.

Bug: 354850153
Test: Add select syntax in the Andorid.bp
Change-Id: Ibc5e5ee5d8fb9c19dc45d744a71b625fe94c9d88
2024-10-24 19:41:23 +02:00
Inseob Kim
10ec15d67c
Make more apex properties configurable
This allows using select statements with these.

* apps
* binaries
* prebuilts

Bug: 354824866
Test: m --no-skip-soong-tests
Change-Id: I8e28937d2fa6514b41bd189f56f9f584a60d2c80
2024-10-24 19:41:23 +02:00
Inseob Kim
989266aaff
Make genrule's srcs property configurable
This allows using select statements with it.

Bug: 354824866
Test: m
Change-Id: If1d71ac177618ad3eb628cdec57469886ee27c88
2024-10-24 19:41:23 +02:00
Inseob Kim
7889cf45fa
Make some apex properties configurable
This allows using select statements with these.

* androidManifest
* canned_fs_config
* systemserverclasspath_fragments

Bug: 354824866
Test: m
Change-Id: I4c2182944ec14d99332f437c39a19ba0dc6b7731
2024-10-24 19:41:23 +02:00
Inseob Kim
3cc3ca4d62
Make the vintf_fragments property configurable
This allows using select statements with it.

Bug: 354824866
Test: m
Change-Id: I9080c14b8342868d842670c65386582552b32d46
2024-10-24 19:41:23 +02:00
Inseob Kim
bbf681deaf
Make the defaults property configurable
This allows using select statements with it.

Bug: 354824866
Test: m
Change-Id: I673df0869a68c2e79b19c577d0ae1ff2249388db
2024-10-24 19:41:23 +02:00
Cole Faust
1d86a7f5e8
Add tests for configurable PostProcessors
Bug: 362579941
Test: m nothing --no-skip-soong-tests
Change-Id: Iaaff66844ebe0b2fb19148bd07562785b12cd7e9
2024-10-24 19:41:23 +02:00
Cole Faust
77b84c1f56
Add tests for selects with bindings
Bug: 323382414
Test: m nothing --no-skip-soong-tests
Change-Id: I43f10ce21d777e94839c695cb7ca8dcbb968d1c3
2024-10-24 19:41:23 +02:00
Cole Faust
2dc6a269f1
Update selects_test for selects with deferred expressions
Bug: 323382414
Test: m nothing --no-skip-soong-tests
Change-Id: I18257ff586fb31d4e0b012a249726a925832cdac
2024-10-24 19:41:23 +02:00
Cole Faust
4be39f9509
Allow soong config variables to be boolean-typed
So that you can use `true` instead of `"true"` in select expressions.

Bug: 323382414
Test: m nothing --no-skip-soong-tests
Change-Id: I950bd8e04f8fab5187ea5075514d476227943f33
2024-10-24 19:39:05 +02:00
Cole Faust
5b91c24c11
Make required a configurable property
So that users can use select statements with it.

Fixes: 347605145
Bug: 342006386
Test: m nothing --no-skip-soong-tests
Change-Id: Ica0ca6d1725b000b3748c0293e5a9f9b38ed87f9
2024-10-24 19:38:47 +02:00
Cosmin Tanislav
8b82c0d750
soong: paths: Fix out of tree $OUT
Change-Id: Ia915a7fcb95c76272fff6d350dc69abacb7b9e00
2024-10-24 19:38:44 +02:00
Quallenauge
878adb61bf
Add ability to enable scudo-free 32-bit libc variant.
The default value is set to enable scudo with the
32-bit libc variant.

Change-Id: I9205da12eceadfe6245763a49c7208d30b82ad99
2024-10-24 19:38:41 +02:00
Alessandro Astone
90d46b8e4b
soong: Add equivalent for LOCAL_EXPORT_CFLAGS
Change-Id: Ieb3e5739b50789bdbaf41a7d5adb04b08f7b9ea2
2024-10-24 19:38:37 +02:00
Bruno Martins
ba53cd2aba
check_boot_jars: Add oplus packages to whitelist
Change-Id: I8e467e35f148cfae9b2cc4ae32a26ffbca1984b5
2024-10-24 19:38:30 +02:00
Michael Bestas
cd0f7bbd34
check_boot_jars: Add IFAA Manager to whitelist
Fixes:
Error: out/target/common/obj/JAVA_LIBRARIES/org.ifaa.android.manager_intermediates/classes.jar
  contains class file org/ifaa/android/manager/IFAAManager.class,
  whose package name org.ifaa.android.manager is not in the whitelist
  build/make/core/tasks/check_boot_jars/package_whitelist.txt
  of packages allowed on the bootclasspath.

(The error only pops up when using "make dist")

Change-Id: Ib17b935ca39de7f6e8e6b68aa81fbebe1d5a30a5
2024-10-24 19:38:10 +02:00
Scott Lobdell
9d618bc55f
Add qcom.fmradio and org.codeaurora.internal to allowlist
B58: Add org.codeaurora.ims to the list.

Bug: 192690464
Change-Id: I0837873f5bf4e3a8402d70e720d2b55ee4e0a991
(cherry picked from commit ef25c8777180f88650dad8bd2499e8c8c9d174b7)
2024-10-24 19:38:10 +02:00
daniml3
d44bc5b281
sandbox_linux: set CCACHE_DIR as a writable path
Fixes "Read-only file system" error when using ccache.

NOTE: This is only required when both ccache exec and dir are on the
same partition.

Change-Id: I99afe644c8ee0e0b881c1643fef0cb31b83bcd17
2024-10-24 19:38:10 +02:00
dianlujitao
243b54c46e
Add Init_rc to Product_variables.Eng
Change-Id: If490b64f3631ec0825ffa28964a3e65572a9bcb8
2024-10-24 19:38:10 +02:00
LuK1337
d00a3c6c93
Add exported-to-kati namespaces to root namespace
This lets us use boot jar modules that are hidden behind
soong_namespace.

Change-Id: If0068387efdeca5458b5b97ce6b993b10a268bd2
2024-10-24 19:38:10 +02:00
Chirayu Desai
d0ee341157
Replace {device,qti}_kernel_headers only when building inline
Change-Id: Ibbae77a92f5f96da92213d0a0078867ddeeeaf04
2024-10-24 19:38:10 +02:00
Nolen Johnson
87f74a3d2b
Replace qti_kernel_headers with generated_kernel_headers
* Further avoids edits in CAF repos.

Change-Id: I99f9773e3132de7816c921c9d6b09e3e62b68265
2024-10-24 19:38:10 +02:00
Chirayu Desai
17e9e9c0be
Replace device_kernel_headers with generated_kernel_headers
* For inline kernel building
* Avoids having to make edits to multiple repos, even
  if it's a quick replacement

Change-Id: I01d4a9b3e24315731efbc8d16882818d20e38e89
2024-10-24 19:38:10 +02:00
Jan Altensen
f5c73b4700
soong: allow overriding header files
Includes:

  Author: Jan Altensen <info@stricted.net>
  Date:   Sat Aug 7 19:41:59 2021 +0200

    soong: move header override to compiler.go

     * library.go only covers libraries

    Change-Id: I3374999d6b364dd1bbc2060996964ee7b04493e7

Change-Id: Ia9d2210605c5927b529fbe9485b0e5abd079f487
2024-10-24 19:38:10 +02:00
Sam Mortimer
34e34e8c1d
soong: Add PathForSourceRelaxed
Used by vendor/lineage generated kernel header module.

Partial pick from:
Author: Sam Mortimer <sam@mortimer.me.uk>
Date:   Fri Aug 17 11:25:08 2018 -0700
    soong: Add java sources overlay support
    Change-Id: I94143febb0a8afa6a165364d36a40d5120a4e7bc

Change-Id: I415af71458f2a7be8e256cb3c548994f09c5bebf
2024-10-24 19:38:10 +02:00
LuK1337
277672eab4
cleanbuild: Add install to installclean files
Change-Id: Ib46d9638a2b3648d5e2ade1dfa864bc4e2ae695c
2024-10-24 19:37:55 +02:00
Jarl-Penguin
7e2044fa35
cleanbuild: Add recovery_kernel to installclean files
Signed-off-by: Jarl-Penguin <jarlpenguin@outlook.com>
Change-Id: I89b7093be92cb22a223033f9a7269624f7293c35
2024-10-24 19:37:52 +02:00
Julian Veit
a7671f2808
cleanbuild: add *.zip.sha256sum to installclean_files
Change-Id: I91f92349423eeb99e7e4521f6239baabe8b1314c
2024-10-24 19:37:47 +02:00
HeroBuxx
fee41a1895
soong: ui: dumpvar: Apparently PRODUCT_SOONG_NAMESPACES is necessary
Bring back PRODUCT_SOONG_NAMESPACES after this change:
3690485a16

Change-Id: I1efa7620d79eb9c330f0f028a91e10d2a9ce49e8
Signed-off-by: HeroBuxx <me@herobuxx.me>
2024-10-24 19:37:38 +02:00
Rashed Abdel-Tawab
c4ec0f2daa
soong: Add TEQUILA_VERSION to dumpvars
Change-Id: I24b29442f041aec451a173db404f542060ac67d2
2024-10-24 19:36:20 +02:00
50 changed files with 1763 additions and 497 deletions

View file

@ -121,18 +121,50 @@ dexpreopt_systemserver_check {
name: "dexpreopt_systemserver_check",
}
// buildinfo.prop contains common properties for system/build.prop, like ro.build.version.*
buildinfo_prop {
name: "buildinfo.prop",
// not installable because this will be included to system/build.prop
installable: false,
// Currently, only microdroid can refer to buildinfo.prop
visibility: ["//packages/modules/Virtualization/microdroid"],
}
// container for apex_contributions selected using build flags
all_apex_contributions {
name: "all_apex_contributions",
}
product_config {
name: "product_config",
visibility: ["//device/google/cuttlefish/system_image"],
}
build_prop {
name: "system-build.prop",
stem: "build.prop",
product_config: ":product_config",
// Currently, only microdroid and cf system image can refer to system-build.prop
visibility: [
"//device/google/cuttlefish/system_image",
"//packages/modules/Virtualization/microdroid",
],
}
build_prop {
name: "system_ext-build.prop",
stem: "build.prop",
system_ext_specific: true,
product_config: ":product_config",
relative_install_path: "etc", // system_ext/etc/build.prop
visibility: ["//visibility:private"],
}
build_prop {
name: "product-build.prop",
stem: "build.prop",
product_specific: true,
product_config: ":product_config",
relative_install_path: "etc", // product/etc/build.prop
visibility: ["//visibility:private"],
}
build_prop {
name: "odm-build.prop",
stem: "build.prop",
device_specific: true,
product_config: ":product_config",
relative_install_path: "etc", // odm/etc/build.prop
visibility: ["//visibility:private"],
}

View file

@ -38,7 +38,7 @@ bootstrap_go_package {
"arch_list.go",
"arch_module_context.go",
"base_module_context.go",
"buildinfo_prop.go",
"build_prop.go",
"config.go",
"test_config.go",
"configurable_properties.go",
@ -83,6 +83,7 @@ bootstrap_go_package {
"plugin.go",
"prebuilt.go",
"prebuilt_build_tool.go",
"product_config.go",
"proto.go",
"provider.go",
"raw_files.go",
@ -110,6 +111,7 @@ bootstrap_go_package {
"androidmk_test.go",
"apex_test.go",
"arch_test.go",
"blueprint_e2e_test.go",
"config_test.go",
"configured_jars_test.go",
"csuite_config_test.go",

View file

@ -499,6 +499,7 @@ type fillInEntriesContext interface {
Config() Config
moduleProvider(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool)
ModuleType(module blueprint.Module) string
OtherModulePropertyErrorf(module Module, property string, fmt string, args ...interface{})
}
func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod blueprint.Module) {
@ -514,7 +515,7 @@ func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod blueprint
if a.Include == "" {
a.Include = "$(BUILD_PREBUILT)"
}
a.Required = append(a.Required, amod.RequiredModuleNames()...)
a.Required = append(a.Required, amod.RequiredModuleNames(ctx)...)
a.Host_required = append(a.Host_required, amod.HostRequiredModuleNames()...)
a.Target_required = append(a.Target_required, amod.TargetRequiredModuleNames()...)

View file

@ -0,0 +1,105 @@
// Copyright 2024 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package android
import (
"testing"
)
var testCases []struct {
name string
fs MockFS
expectedError string
} = []struct {
name string
fs MockFS
expectedError string
}{
{
name: "Can't reference variable before assignment",
fs: map[string][]byte{
"Android.bp": []byte(`
x = foo
foo = "hello"
`),
},
expectedError: "undefined variable foo",
},
{
name: "Can't append to variable before assigned to",
fs: map[string][]byte{
"Android.bp": []byte(`
foo += "world"
foo = "hello"
`),
},
expectedError: "modified non-existent variable \"foo\" with \\+=",
},
{
name: "Can't reassign variable",
fs: map[string][]byte{
"Android.bp": []byte(`
foo = "hello"
foo = "world"
`),
},
expectedError: "variable already set, previous assignment:",
},
{
name: "Can't reassign variable in inherited scope",
fs: map[string][]byte{
"Android.bp": []byte(`
foo = "hello"
`),
"foo/Android.bp": []byte(`
foo = "world"
`),
},
expectedError: "variable already set in inherited scope, previous assignment:",
},
{
name: "Can't modify variable in inherited scope",
fs: map[string][]byte{
"Android.bp": []byte(`
foo = "hello"
`),
"foo/Android.bp": []byte(`
foo += "world"
`),
},
expectedError: "modified non-local variable \"foo\" with \\+=",
},
{
name: "Can't modify variable after referencing",
fs: map[string][]byte{
"Android.bp": []byte(`
foo = "hello"
x = foo
foo += "world"
`),
},
expectedError: "modified variable \"foo\" with \\+= after referencing",
},
}
func TestBlueprintErrors(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
fixtures := FixtureMergeMockFs(tc.fs)
fixtures = fixtures.ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(tc.expectedError))
fixtures.RunTest(t)
})
}
}

195
android/build_prop.go Normal file
View file

@ -0,0 +1,195 @@
// Copyright 2024 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package android
import (
"github.com/google/blueprint/proptools"
)
func init() {
ctx := InitRegistrationContext
ctx.RegisterModuleType("build_prop", buildPropFactory)
}
type buildPropProperties struct {
// Output file name. Defaults to "build.prop"
Stem *string
// List of prop names to exclude. This affects not only common build properties but also
// properties in prop_files.
Block_list []string
// Files to be appended at the end of build.prop. These files are appended after
// post_process_props without any further checking.
Footer_files []string `android:"path"`
// Path to a JSON file containing product configs.
Product_config *string `android:"path"`
// Optional subdirectory under which this file is installed into
Relative_install_path *string
}
type buildPropModule struct {
ModuleBase
properties buildPropProperties
outputFilePath OutputPath
installPath InstallPath
}
func (p *buildPropModule) stem() string {
return proptools.StringDefault(p.properties.Stem, "build.prop")
}
func (p *buildPropModule) propFiles(ctx ModuleContext) Paths {
partition := p.partition(ctx.DeviceConfig())
if partition == "system" {
return ctx.Config().SystemPropFiles(ctx)
} else if partition == "system_ext" {
return ctx.Config().SystemExtPropFiles(ctx)
} else if partition == "product" {
return ctx.Config().ProductPropFiles(ctx)
} else if partition == "odm" {
return ctx.Config().OdmPropFiles(ctx)
}
return nil
}
func shouldAddBuildThumbprint(config Config) bool {
knownOemProperties := []string{
"ro.product.brand",
"ro.product.name",
"ro.product.device",
}
for _, knownProp := range knownOemProperties {
if InList(knownProp, config.OemProperties()) {
return true
}
}
return false
}
// Can't use PartitionTag() because PartitionTag() returns the partition this module is actually
// installed (e.g. odm module's partition tag can be either "odm" or "vendor")
func (p *buildPropModule) partition(config DeviceConfig) string {
if p.SocSpecific() {
return "vendor"
} else if p.DeviceSpecific() {
return "odm"
} else if p.ProductSpecific() {
return "product"
} else if p.SystemExtSpecific() {
return "system_ext"
}
return "system"
}
var validPartitions = []string{
"system",
"system_ext",
"product",
"odm",
}
func (p *buildPropModule) GenerateAndroidBuildActions(ctx ModuleContext) {
p.outputFilePath = PathForModuleOut(ctx, "build.prop").OutputPath
if !ctx.Config().KatiEnabled() {
WriteFileRule(ctx, p.outputFilePath, "# no build.prop if kati is disabled")
ctx.SetOutputFiles(Paths{p.outputFilePath}, "")
return
}
partition := p.partition(ctx.DeviceConfig())
if !InList(partition, validPartitions) {
ctx.PropertyErrorf("partition", "unsupported partition %q: only %q are supported", partition, validPartitions)
return
}
rule := NewRuleBuilder(pctx, ctx)
config := ctx.Config()
cmd := rule.Command().BuiltTool("gen_build_prop")
cmd.FlagWithInput("--build-hostname-file=", config.BuildHostnameFile(ctx))
cmd.FlagWithInput("--build-number-file=", config.BuildNumberFile(ctx))
// shouldn't depend on BuildFingerprintFile and BuildThumbprintFile to prevent from rebuilding
// on every incremental build.
cmd.FlagWithArg("--build-fingerprint-file=", config.BuildFingerprintFile(ctx).String())
// Export build thumbprint only if the product has specified at least one oem fingerprint property
// b/17888863
if shouldAddBuildThumbprint(config) {
// In the previous make implementation, a dependency was not added on the thumbprint file
cmd.FlagWithArg("--build-thumbprint-file=", config.BuildThumbprintFile(ctx).String())
}
cmd.FlagWithArg("--build-username=", config.Getenv("BUILD_USERNAME"))
// shouldn't depend on BUILD_DATETIME_FILE to prevent from rebuilding on every incremental
// build.
cmd.FlagWithArg("--date-file=", ctx.Config().Getenv("BUILD_DATETIME_FILE"))
cmd.FlagWithInput("--platform-preview-sdk-fingerprint-file=", ApiFingerprintPath(ctx))
cmd.FlagWithInput("--product-config=", PathForModuleSrc(ctx, proptools.String(p.properties.Product_config)))
cmd.FlagWithArg("--partition=", partition)
cmd.FlagForEachInput("--prop-files=", p.propFiles(ctx))
cmd.FlagWithOutput("--out=", p.outputFilePath)
postProcessCmd := rule.Command().BuiltTool("post_process_props")
if ctx.DeviceConfig().BuildBrokenDupSysprop() {
postProcessCmd.Flag("--allow-dup")
}
postProcessCmd.FlagWithArg("--sdk-version ", config.PlatformSdkVersion().String())
if ctx.Config().EnableUffdGc() == "default" {
postProcessCmd.FlagWithInput("--kernel-version-file-for-uffd-gc ", PathForOutput(ctx, "dexpreopt/kernel_version_for_uffd_gc.txt"))
} else {
// still need to pass an empty string to kernel-version-file-for-uffd-gc
postProcessCmd.FlagWithArg("--kernel-version-file-for-uffd-gc ", `""`)
}
postProcessCmd.Text(p.outputFilePath.String())
postProcessCmd.Flags(p.properties.Block_list)
rule.Command().Text("echo").Text(proptools.NinjaAndShellEscape("# end of file")).FlagWithArg(">> ", p.outputFilePath.String())
rule.Build(ctx.ModuleName(), "generating build.prop")
p.installPath = PathForModuleInstall(ctx, proptools.String(p.properties.Relative_install_path))
ctx.InstallFile(p.installPath, p.stem(), p.outputFilePath)
ctx.SetOutputFiles(Paths{p.outputFilePath}, "")
}
func (p *buildPropModule) AndroidMkEntries() []AndroidMkEntries {
return []AndroidMkEntries{{
Class: "ETC",
OutputFile: OptionalPathForPath(p.outputFilePath),
ExtraEntries: []AndroidMkExtraEntriesFunc{
func(ctx AndroidMkExtraEntriesContext, entries *AndroidMkEntries) {
entries.SetString("LOCAL_MODULE_PATH", p.installPath.String())
entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.outputFilePath.Base())
},
},
}}
}
// build_prop module generates {partition}/build.prop file. At first common build properties are
// printed based on Soong config variables. And then prop_files are printed as-is. Finally,
// post_process_props tool is run to check if the result build.prop is valid or not.
func buildPropFactory() Module {
module := &buildPropModule{}
module.AddProperties(&module.properties)
InitAndroidArchModule(module, DeviceSupported, MultilibCommon)
return module
}

View file

@ -1,195 +0,0 @@
// Copyright 2022 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package android
import (
"fmt"
"strings"
"github.com/google/blueprint/proptools"
)
func init() {
ctx := InitRegistrationContext
ctx.RegisterModuleType("buildinfo_prop", buildinfoPropFactory)
}
type buildinfoPropProperties struct {
// Whether this module is directly installable to one of the partitions. Default: true.
Installable *bool
}
type buildinfoPropModule struct {
ModuleBase
properties buildinfoPropProperties
outputFilePath OutputPath
installPath InstallPath
}
var _ OutputFileProducer = (*buildinfoPropModule)(nil)
func (p *buildinfoPropModule) installable() bool {
return proptools.BoolDefault(p.properties.Installable, true)
}
// OutputFileProducer
func (p *buildinfoPropModule) OutputFiles(tag string) (Paths, error) {
if tag != "" {
return nil, fmt.Errorf("unsupported tag %q", tag)
}
return Paths{p.outputFilePath}, nil
}
func getBuildVariant(config Config) string {
if config.Eng() {
return "eng"
} else if config.Debuggable() {
return "userdebug"
} else {
return "user"
}
}
func getBuildFlavor(config Config) string {
buildFlavor := config.DeviceProduct() + "-" + getBuildVariant(config)
if InList("address", config.SanitizeDevice()) && !strings.Contains(buildFlavor, "_asan") {
buildFlavor += "_asan"
}
return buildFlavor
}
func shouldAddBuildThumbprint(config Config) bool {
knownOemProperties := []string{
"ro.product.brand",
"ro.product.name",
"ro.product.device",
}
for _, knownProp := range knownOemProperties {
if InList(knownProp, config.OemProperties()) {
return true
}
}
return false
}
func (p *buildinfoPropModule) GenerateAndroidBuildActions(ctx ModuleContext) {
if ctx.ModuleName() != "buildinfo.prop" || ctx.ModuleDir() != "build/soong" {
ctx.ModuleErrorf("There can only be one buildinfo_prop module in build/soong")
return
}
p.outputFilePath = PathForModuleOut(ctx, p.Name()).OutputPath
if !ctx.Config().KatiEnabled() {
WriteFileRule(ctx, p.outputFilePath, "# no buildinfo.prop if kati is disabled")
return
}
rule := NewRuleBuilder(pctx, ctx)
config := ctx.Config()
buildVariant := getBuildVariant(config)
buildFlavor := getBuildFlavor(config)
cmd := rule.Command().BuiltTool("buildinfo")
if config.BoardUseVbmetaDigestInFingerprint() {
cmd.Flag("--use-vbmeta-digest-in-fingerprint")
}
cmd.FlagWithArg("--build-flavor=", buildFlavor)
cmd.FlagWithInput("--build-hostname-file=", config.BuildHostnameFile(ctx))
cmd.FlagWithArg("--build-id=", config.BuildId())
cmd.FlagWithArg("--build-keys=", config.BuildKeys())
// Note: depending on BuildNumberFile will cause the build.prop file to be rebuilt
// every build, but that's intentional.
cmd.FlagWithInput("--build-number-file=", config.BuildNumberFile(ctx))
if shouldAddBuildThumbprint(config) {
// In the previous make implementation, a dependency was not added on the thumbprint file
cmd.FlagWithArg("--build-thumbprint-file=", config.BuildThumbprintFile(ctx).String())
}
cmd.FlagWithArg("--build-type=", config.BuildType())
cmd.FlagWithArg("--build-username=", config.Getenv("BUILD_USERNAME"))
cmd.FlagWithArg("--build-variant=", buildVariant)
cmd.FlagForEachArg("--cpu-abis=", config.DeviceAbi())
// Technically we should also have a dependency on BUILD_DATETIME_FILE,
// but it can be either an absolute or relative path, which is hard to turn into
// a Path object. So just rely on the BuildNumberFile always changing to cause
// us to rebuild.
cmd.FlagWithArg("--date-file=", ctx.Config().Getenv("BUILD_DATETIME_FILE"))
if len(config.ProductLocales()) > 0 {
cmd.FlagWithArg("--default-locale=", config.ProductLocales()[0])
}
cmd.FlagForEachArg("--default-wifi-channels=", config.ProductDefaultWifiChannels())
cmd.FlagWithArg("--device=", config.DeviceName())
if config.DisplayBuildNumber() {
cmd.Flag("--display-build-number")
}
cmd.FlagWithArg("--platform-base-os=", config.PlatformBaseOS())
cmd.FlagWithArg("--platform-display-version=", config.PlatformDisplayVersionName())
cmd.FlagWithArg("--platform-min-supported-target-sdk-version=", config.PlatformMinSupportedTargetSdkVersion())
cmd.FlagWithInput("--platform-preview-sdk-fingerprint-file=", ApiFingerprintPath(ctx))
cmd.FlagWithArg("--platform-preview-sdk-version=", config.PlatformPreviewSdkVersion())
cmd.FlagWithArg("--platform-sdk-version=", config.PlatformSdkVersion().String())
cmd.FlagWithArg("--platform-security-patch=", config.PlatformSecurityPatch())
cmd.FlagWithArg("--platform-version=", config.PlatformVersionName())
cmd.FlagWithArg("--platform-version-codename=", config.PlatformSdkCodename())
cmd.FlagForEachArg("--platform-version-all-codenames=", config.PlatformVersionActiveCodenames())
cmd.FlagWithArg("--platform-version-known-codenames=", config.PlatformVersionKnownCodenames())
cmd.FlagWithArg("--platform-version-last-stable=", config.PlatformVersionLastStable())
cmd.FlagWithArg("--product=", config.DeviceProduct())
cmd.FlagWithOutput("--out=", p.outputFilePath)
rule.Build(ctx.ModuleName(), "generating buildinfo props")
if !p.installable() {
p.SkipInstall()
}
p.installPath = PathForModuleInstall(ctx)
ctx.InstallFile(p.installPath, p.Name(), p.outputFilePath)
}
func (p *buildinfoPropModule) AndroidMkEntries() []AndroidMkEntries {
return []AndroidMkEntries{{
Class: "ETC",
OutputFile: OptionalPathForPath(p.outputFilePath),
ExtraEntries: []AndroidMkExtraEntriesFunc{
func(ctx AndroidMkExtraEntriesContext, entries *AndroidMkEntries) {
entries.SetString("LOCAL_MODULE_PATH", p.installPath.String())
entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.outputFilePath.Base())
entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", !p.installable())
},
},
}}
}
// buildinfo_prop module generates a build.prop file, which contains a set of common
// system/build.prop properties, such as ro.build.version.*. Not all properties are implemented;
// currently this module is only for microdroid.
func buildinfoPropFactory() Module {
module := &buildinfoPropModule{}
module.AddProperties(&module.properties)
InitAndroidModule(module)
return module
}

View file

@ -784,6 +784,17 @@ func (c *config) DisplayBuildNumber() bool {
return Bool(c.productVariables.DisplayBuildNumber)
}
// BuildFingerprintFile returns the path to a text file containing metadata
// representing the current build's fingerprint.
//
// Rules that want to reference the build fingerprint should read from this file
// without depending on it. They will run whenever their other dependencies
// require them to run and get the current build fingerprint. This ensures they
// don't rebuild on every incremental build when the build number changes.
func (c *config) BuildFingerprintFile(ctx PathContext) Path {
return PathForArbitraryOutput(ctx, "target", "product", c.DeviceName(), String(c.productVariables.BuildFingerprintFile))
}
// BuildNumberFile returns the path to a text file containing metadata
// representing the current build's number.
//
@ -1423,6 +1434,10 @@ func (c *deviceConfig) DeviceKernelHeaderDirs() []string {
return c.config.productVariables.DeviceKernelHeaders
}
func (c *deviceConfig) TargetSpecificHeaderPath() string {
return String(c.config.productVariables.TargetSpecificHeaderPath)
}
// JavaCoverageEnabledForPath returns whether Java code coverage is enabled for
// path. Coverage is enabled by default when the product variable
// JavaCoveragePaths is empty. If JavaCoveragePaths is not empty, coverage is
@ -1883,6 +1898,10 @@ func (c *deviceConfig) BuildBrokenDontCheckSystemSdk() bool {
return c.config.productVariables.BuildBrokenDontCheckSystemSdk
}
func (c *deviceConfig) BuildBrokenDupSysprop() bool {
return c.config.productVariables.BuildBrokenDupSysprop
}
func (c *config) BuildWarningBadOptionalUsesLibsAllowlist() []string {
return c.productVariables.BuildWarningBadOptionalUsesLibsAllowlist
}
@ -2078,3 +2097,31 @@ func (c *config) BoardUseVbmetaDigestInFingerprint() bool {
func (c *config) OemProperties() []string {
return c.productVariables.OemProperties
}
func (c *config) UseDebugArt() bool {
if c.productVariables.ArtTargetIncludeDebugBuild != nil {
return Bool(c.productVariables.ArtTargetIncludeDebugBuild)
}
return Bool(c.productVariables.Eng)
}
func (c *config) SystemPropFiles(ctx PathContext) Paths {
return PathsForSource(ctx, c.productVariables.SystemPropFiles)
}
func (c *config) SystemExtPropFiles(ctx PathContext) Paths {
return PathsForSource(ctx, c.productVariables.SystemExtPropFiles)
}
func (c *config) ProductPropFiles(ctx PathContext) Paths {
return PathsForSource(ctx, c.productVariables.ProductPropFiles)
}
func (c *config) OdmPropFiles(ctx PathContext) Paths {
return PathsForSource(ctx, c.productVariables.OdmPropFiles)
}
func (c *config) EnableUffdGc() string {
return String(c.productVariables.EnableUffdGc)
}

View file

@ -28,7 +28,7 @@ type defaultsDependencyTag struct {
var DefaultsDepTag defaultsDependencyTag
type defaultsProperties struct {
Defaults []string
Defaults proptools.Configurable[[]string]
}
type DefaultableModuleBase struct {
@ -278,13 +278,14 @@ func RegisterDefaultsPreArchMutators(ctx RegisterMutatorsContext) {
func defaultsDepsMutator(ctx BottomUpMutatorContext) {
if defaultable, ok := ctx.Module().(Defaultable); ok {
ctx.AddDependency(ctx.Module(), DefaultsDepTag, defaultable.defaults().Defaults...)
ctx.AddDependency(ctx.Module(), DefaultsDepTag, defaultable.defaults().Defaults.GetOrDefault(ctx, nil)...)
}
}
func defaultsMutator(ctx TopDownMutatorContext) {
if defaultable, ok := ctx.Module().(Defaultable); ok {
if len(defaultable.defaults().Defaults) > 0 {
defaults := defaultable.defaults().Defaults.GetOrDefault(ctx, nil)
if len(defaults) > 0 {
var defaultsList []Defaults
seen := make(map[Defaults]bool)
@ -294,7 +295,7 @@ func defaultsMutator(ctx TopDownMutatorContext) {
if !seen[defaults] {
seen[defaults] = true
defaultsList = append(defaultsList, defaults)
return len(defaults.defaults().Defaults) > 0
return len(defaults.defaults().Defaults.GetOrDefault(ctx, nil)) > 0
}
} else {
ctx.PropertyErrorf("defaults", "module %s is not an defaults module",

View file

@ -113,7 +113,7 @@ type Module interface {
// Get information about the properties that can contain visibility rules.
visibilityProperties() []visibilityProperty
RequiredModuleNames() []string
RequiredModuleNames(ctx ConfigAndErrorContext) []string
HostRequiredModuleNames() []string
TargetRequiredModuleNames() []string
@ -419,10 +419,10 @@ type commonProperties struct {
Init_rc []string `android:"arch_variant,path"`
// VINTF manifest fragments to be installed if this module is installed
Vintf_fragments []string `android:"path"`
Vintf_fragments proptools.Configurable[[]string] `android:"path"`
// names of other modules to install if this module is installed
Required []string `android:"arch_variant"`
Required proptools.Configurable[[]string] `android:"arch_variant"`
// names of other modules to install on host if this module is installed
Host_required []string `android:"arch_variant"`
@ -1101,7 +1101,7 @@ func addRequiredDeps(ctx BottomUpMutatorContext) {
hostTargets = append(hostTargets, ctx.Config().BuildOSCommonTarget)
if ctx.Device() {
for _, depName := range ctx.Module().RequiredModuleNames() {
for _, depName := range ctx.Module().RequiredModuleNames(ctx) {
for _, target := range deviceTargets {
addDep(target, depName)
}
@ -1114,7 +1114,7 @@ func addRequiredDeps(ctx BottomUpMutatorContext) {
}
if ctx.Host() {
for _, depName := range ctx.Module().RequiredModuleNames() {
for _, depName := range ctx.Module().RequiredModuleNames(ctx) {
for _, target := range hostTargets {
// When a host module requires another host module, don't make a
// dependency if they have different OSes (i.e. hostcross).
@ -1619,8 +1619,8 @@ func (m *ModuleBase) InRecovery() bool {
return m.base().commonProperties.ImageVariation == RecoveryVariation
}
func (m *ModuleBase) RequiredModuleNames() []string {
return m.base().commonProperties.Required
func (m *ModuleBase) RequiredModuleNames(ctx ConfigAndErrorContext) []string {
return m.base().commonProperties.Required.GetOrDefault(m.ConfigurableEvaluator(ctx), nil)
}
func (m *ModuleBase) HostRequiredModuleNames() []string {
@ -1881,7 +1881,7 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext)
}
}
m.vintfFragmentsPaths = PathsForModuleSrc(ctx, m.commonProperties.Vintf_fragments)
m.vintfFragmentsPaths = PathsForModuleSrc(ctx, m.commonProperties.Vintf_fragments.GetOrDefault(ctx, nil))
vintfDir := PathForModuleInstall(ctx, "etc", "vintf", "manifest")
for _, src := range m.vintfFragmentsPaths {
installedVintfFragment := vintfDir.Join(ctx, src.Base())
@ -1992,7 +1992,7 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext)
TargetDependencies: targetRequired,
HostDependencies: hostRequired,
Data: data,
Required: m.RequiredModuleNames(),
Required: m.RequiredModuleNames(ctx),
}
SetProvider(ctx, ModuleInfoJSONProvider, m.moduleInfoJSON)
}
@ -2194,6 +2194,9 @@ func (e configurationEvalutor) EvaluateConfiguration(condition proptools.Configu
switch variable {
case "debuggable":
return proptools.ConfigurableValueBool(ctx.Config().Debuggable())
case "use_debug_art":
// TODO(b/234351700): Remove once ART does not have separated debug APEX
return proptools.ConfigurableValueBool(ctx.Config().UseDebugArt())
default:
// TODO(b/323382414): Might add these on a case-by-case basis
ctx.OtherModulePropertyErrorf(m, property, fmt.Sprintf("TODO(b/323382414): Product variable %q is not yet supported in selects", variable))
@ -2208,7 +2211,20 @@ func (e configurationEvalutor) EvaluateConfiguration(condition proptools.Configu
variable := condition.Arg(1)
if n, ok := ctx.Config().productVariables.VendorVars[namespace]; ok {
if v, ok := n[variable]; ok {
return proptools.ConfigurableValueString(v)
ty := ""
if namespaces, ok := ctx.Config().productVariables.VendorVarTypes[namespace]; ok {
ty = namespaces[variable]
}
switch ty {
case "":
// strings are the default, we don't bother writing them to the soong variables json file
return proptools.ConfigurableValueString(v)
case "bool":
return proptools.ConfigurableValueBool(v == "true")
default:
panic("unhandled soong config variable type: " + ty)
}
}
}
return proptools.ConfigurableValueUndefined()

View file

@ -183,7 +183,7 @@ type ModuleContext interface {
InstallInVendor() bool
InstallForceOS() (*OsType, *ArchType)
RequiredModuleNames() []string
RequiredModuleNames(ctx ConfigAndErrorContext) []string
HostRequiredModuleNames() []string
TargetRequiredModuleNames() []string
@ -755,8 +755,8 @@ func (m *moduleContext) ExpandOptionalSource(srcFile *string, _ string) Optional
return OptionalPath{}
}
func (m *moduleContext) RequiredModuleNames() []string {
return m.module.RequiredModuleNames()
func (m *moduleContext) RequiredModuleNames(ctx ConfigAndErrorContext) []string {
return m.module.RequiredModuleNames(ctx)
}
func (m *moduleContext) HostRequiredModuleNames() []string {

View file

@ -722,7 +722,6 @@ test {
propInfo{Name: "Arch.X86_64.A", Type: "string", Value: "x86_64 a"},
propInfo{Name: "B", Type: "bool", Value: "true"},
propInfo{Name: "C", Type: "string slice", Values: []string{"default_c", "c"}},
propInfo{Name: "Defaults", Type: "string slice", Values: []string{"foo_defaults"}},
propInfo{Name: "Embedded_prop", Type: "string", Value: "a"},
propInfo{Name: "Name", Type: "string", Value: "foo"},
propInfo{Name: "Nested.E", Type: "string", Value: "nested e"},
@ -746,7 +745,6 @@ test {
foo := result.ModuleForTests("foo", "").Module().base()
AssertDeepEquals(t, "foo ", tc.expectedProps, foo.propertiesWithValues())
})
}
}

View file

@ -156,6 +156,9 @@ func (r *NameResolver) addNamespace(namespace *Namespace) (err error) {
return fmt.Errorf("a namespace must be the first module in the file")
}
}
if (namespace.exportToKati) {
r.rootNamespace.visibleNamespaces = append(r.rootNamespace.visibleNamespaces, namespace)
}
r.sortedNamespaces.add(namespace)
r.namespacesByDir.Store(namespace.Path, namespace)

View file

@ -1145,6 +1145,31 @@ func pathForSource(ctx PathContext, pathComponents ...string) (SourcePath, error
return ret, nil
}
// pathForSourceRelaxed creates a SourcePath from pathComponents, but does not check that it exists.
// It differs from pathForSource in that the path is allowed to exist outside of the PathContext.
func pathForSourceRelaxed(ctx PathContext, pathComponents ...string) (SourcePath, error) {
p := filepath.Join(pathComponents...)
ret := SourcePath{basePath{p, ""}}
abs, err := filepath.Abs(ret.String())
if err != nil {
return ret, err
}
buildroot, err := filepath.Abs(ctx.Config().soongOutDir)
if err != nil {
return ret, err
}
if strings.HasPrefix(abs, buildroot) {
return ret, fmt.Errorf("source path %s is in output", abs)
}
if pathtools.IsGlob(ret.String()) {
return ret, fmt.Errorf("path may not contain a glob: %s", ret.String())
}
return ret, nil
}
// existsWithDependencies returns true if the path exists, and adds appropriate dependencies to rerun if the
// path does not exist.
func existsWithDependencies(ctx PathGlobContext, path SourcePath) (exists bool, err error) {
@ -1190,6 +1215,31 @@ func PathForSource(ctx PathContext, pathComponents ...string) SourcePath {
return path
}
// PathForSourceRelaxed joins the provided path components. Unlike PathForSource,
// the result is allowed to exist outside of the source dir.
// On error, it will return a usable, but invalid SourcePath, and report a ModuleError.
func PathForSourceRelaxed(ctx PathContext, pathComponents ...string) SourcePath {
path, err := pathForSourceRelaxed(ctx, pathComponents...)
if err != nil {
reportPathError(ctx, err)
}
if modCtx, ok := ctx.(ModuleContext); ok && ctx.Config().AllowMissingDependencies() {
exists, err := existsWithDependencies(modCtx, path)
if err != nil {
reportPathError(ctx, err)
}
if !exists {
modCtx.AddMissingDependencies([]string{path.String()})
}
} else if exists, _, err := ctx.Config().fs.Exists(path.String()); err != nil {
ReportPathErrorf(ctx, "%s: %s", path, err.Error())
} else if !exists {
ReportPathErrorf(ctx, "source path %s does not exist", path)
}
return path
}
// PathForArbitraryOutput creates a path for the given components. Unlike PathForOutput,
// the path is relative to the root of the output folder, not the out/soong folder.
func PathForArbitraryOutput(ctx PathContext, pathComponents ...string) Path {
@ -1970,7 +2020,7 @@ func validatePathInternal(allowNinjaVariables bool, pathComponents ...string) (s
}
path := filepath.Clean(path)
if path == ".." || strings.HasPrefix(path, "../") || strings.HasPrefix(path, "/") {
if path == ".." || strings.HasPrefix(path, "../") || i != initialEmpty && strings.HasPrefix(path, "/") {
return "", fmt.Errorf("Path is outside directory: %s", path)
}

58
android/product_config.go Normal file
View file

@ -0,0 +1,58 @@
// Copyright 2024 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package android
import "github.com/google/blueprint/proptools"
func init() {
ctx := InitRegistrationContext
ctx.RegisterModuleType("product_config", productConfigFactory)
}
type productConfigModule struct {
ModuleBase
}
func (p *productConfigModule) GenerateAndroidBuildActions(ctx ModuleContext) {
if ctx.ModuleName() != "product_config" || ctx.ModuleDir() != "build/soong" {
ctx.ModuleErrorf("There can only be one product_config module in build/soong")
return
}
outputFilePath := PathForModuleOut(ctx, p.Name()+".json").OutputPath
// DeviceProduct can be null so calling ctx.Config().DeviceProduct() may cause null dereference
targetProduct := proptools.String(ctx.Config().config.productVariables.DeviceProduct)
if targetProduct != "" {
targetProduct += "."
}
soongVariablesPath := PathForOutput(ctx, "soong."+targetProduct+"variables")
extraVariablesPath := PathForOutput(ctx, "soong."+targetProduct+"extra.variables")
rule := NewRuleBuilder(pctx, ctx)
rule.Command().BuiltTool("merge_json").
Output(outputFilePath).
Input(soongVariablesPath).
Input(extraVariablesPath).
rule.Build("product_config.json", "building product_config.json")
ctx.SetOutputFiles(Paths{outputFilePath}, "")
}
// product_config module exports product variables and extra variables as a JSON file.
func productConfigFactory() Module {
module := &productConfigModule{}
InitAndroidModule(module)
return module
}

View file

@ -25,12 +25,14 @@ import (
func TestSelects(t *testing.T) {
testCases := []struct {
name string
bp string
provider selectsTestProvider
providers map[string]selectsTestProvider
vendorVars map[string]map[string]string
expectedError string
name string
bp string
fs MockFS
provider selectsTestProvider
providers map[string]selectsTestProvider
vendorVars map[string]map[string]string
vendorVarTypes map[string]map[string]string
expectedError string
}{
{
name: "basic string list",
@ -96,6 +98,26 @@ func TestSelects(t *testing.T) {
my_paths: &[]string{"baz.txt"},
},
},
{
name: "Expression in select",
bp: `
my_module_type {
name: "foo",
my_string: select(soong_config_variable("my_namespace", "my_variable"), {
"a": "foo" + "bar",
default: "baz",
}),
}
`,
provider: selectsTestProvider{
my_string: proptools.StringPtr("foobar"),
},
vendorVars: map[string]map[string]string{
"my_namespace": {
"my_variable": "a",
},
},
},
{
name: "paths with module references",
bp: `
@ -110,20 +132,6 @@ func TestSelects(t *testing.T) {
`,
expectedError: `"foo" depends on undefined module "c"`,
},
{
name: "Differing types",
bp: `
my_module_type {
name: "foo",
my_string: select(soong_config_variable("my_namespace", "my_variable"), {
"a": "a.cpp",
"b": true,
default: "c.cpp",
}),
}
`,
expectedError: `Android.bp:8:5: Found select statement with differing types "string" and "bool" in its cases`,
},
{
name: "Select type doesn't match property type",
bp: `
@ -136,7 +144,7 @@ func TestSelects(t *testing.T) {
}),
}
`,
expectedError: `can't assign bool value to string property "my_string\[0\]"`,
expectedError: `can't assign bool value to string property`,
},
{
name: "String list non-default",
@ -583,6 +591,31 @@ func TestSelects(t *testing.T) {
my_string: proptools.StringPtr("t"),
},
},
{
name: "Select on boolean soong config variable",
bp: `
my_module_type {
name: "foo",
my_string: select(soong_config_variable("my_namespace", "my_variable"), {
true: "t",
false: "f",
}),
}
`,
vendorVars: map[string]map[string]string{
"my_namespace": {
"my_variable": "true",
},
},
vendorVarTypes: map[string]map[string]string{
"my_namespace": {
"my_variable": "bool",
},
},
provider: selectsTestProvider{
my_string: proptools.StringPtr("t"),
},
},
{
name: "Select on boolean false",
bp: `
@ -799,10 +832,216 @@ func TestSelects(t *testing.T) {
my_string_list: &[]string{"a.cpp", "c.cpp", "foo.cpp"},
},
},
{
name: "Arch variant bool",
bp: `
my_variable = ["b.cpp"]
my_module_type {
name: "foo",
arch_variant_configurable_bool: false,
target: {
bionic_arm64: {
enabled: true,
},
},
}
`,
provider: selectsTestProvider{
arch_variant_configurable_bool: proptools.BoolPtr(false),
},
},
{
name: "Simple string binding",
bp: `
my_module_type {
name: "foo",
my_string: select(soong_config_variable("my_namespace", "my_variable"), {
any @ my_binding: "hello " + my_binding,
default: "goodbye",
})
}
`,
vendorVars: map[string]map[string]string{
"my_namespace": {
"my_variable": "world!",
},
},
provider: selectsTestProvider{
my_string: proptools.StringPtr("hello world!"),
},
},
{
name: "Any branch with binding not taken",
bp: `
my_module_type {
name: "foo",
my_string: select(soong_config_variable("my_namespace", "my_variable"), {
any @ my_binding: "hello " + my_binding,
default: "goodbye",
})
}
`,
provider: selectsTestProvider{
my_string: proptools.StringPtr("goodbye"),
},
},
{
name: "Any branch without binding",
bp: `
my_module_type {
name: "foo",
my_string: select(soong_config_variable("my_namespace", "my_variable"), {
any: "hello",
default: "goodbye",
})
}
`,
vendorVars: map[string]map[string]string{
"my_namespace": {
"my_variable": "world!",
},
},
provider: selectsTestProvider{
my_string: proptools.StringPtr("hello"),
},
},
{
name: "Binding conflicts with file-level variable",
bp: `
my_binding = "asdf"
my_module_type {
name: "foo",
my_string: select(soong_config_variable("my_namespace", "my_variable"), {
any @ my_binding: "hello",
default: "goodbye",
})
}
`,
vendorVars: map[string]map[string]string{
"my_namespace": {
"my_variable": "world!",
},
},
expectedError: "variable already set in inherited scope, previous assignment",
},
{
name: "Binding in combination with file-level variable",
bp: `
my_var = " there "
my_module_type {
name: "foo",
my_string: select(soong_config_variable("my_namespace", "my_variable"), {
any @ my_binding: "hello" + my_var + my_binding,
default: "goodbye",
})
}
`,
vendorVars: map[string]map[string]string{
"my_namespace": {
"my_variable": "world!",
},
},
provider: selectsTestProvider{
my_string: proptools.StringPtr("hello there world!"),
},
},
{
name: "Bindings in subdirectory inherits variable",
fs: map[string][]byte{
"Android.bp": []byte(`
my_var = "abcd"
`),
"directoryB/Android.bp": []byte(`
my_module_type {
name: "foo",
my_string: select(soong_config_variable("my_namespace", "variable_a"), {
any @ my_binding: my_var + my_binding,
default: "",
}),
}
`),
},
vendorVars: map[string]map[string]string{
"my_namespace": {
"variable_a": "e",
},
},
provider: selectsTestProvider{
my_string: proptools.StringPtr("abcde"),
},
},
{
name: "Cannot modify variable after referenced by select",
bp: `
my_var = "foo"
my_module_type {
name: "foo",
my_string: select(soong_config_variable("my_namespace", "variable_a"), {
"a": my_var,
default: "",
}),
}
my_var += "bar"
`,
vendorVars: map[string]map[string]string{
"my_namespace": {
"variable_a": "b", // notably not the value that causes my_var to be referenced
},
},
expectedError: `modified variable "my_var" with \+= after referencing`,
},
{
name: "Cannot shadow variable with binding",
bp: `
my_var = "foo"
my_module_type {
name: "foo",
my_string: select(soong_config_variable("my_namespace", "variable_a"), {
any @ my_var: my_var,
default: "",
}),
}
`,
vendorVars: map[string]map[string]string{
"my_namespace": {
"variable_a": "a",
},
},
expectedError: `variable already set in inherited scope, previous assignment:`,
},
{
name: "Basic string list postprocessor",
bp: `
my_defaults {
name: "defaults_a",
my_string_list: ["a", "b", "c"],
string_list_postprocessor_add_to_elements: "1",
}
my_defaults {
name: "defaults_b",
my_string_list: ["d", "e", "f"],
string_list_postprocessor_add_to_elements: "2",
}
my_module_type {
name: "foo",
defaults: ["defaults_a", "defaults_b"],
}
`,
provider: selectsTestProvider{
my_string_list: &[]string{"d2", "e2", "f2", "a1", "b1", "c1"},
},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
fs := tc.fs
if fs == nil {
fs = make(MockFS)
}
if tc.bp != "" {
fs["Android.bp"] = []byte(tc.bp)
}
fixtures := GroupFixturePreparers(
PrepareForTestWithDefaults,
PrepareForTestWithArchMutator,
@ -813,12 +1052,14 @@ func TestSelects(t *testing.T) {
}),
FixtureModifyProductVariables(func(variables FixtureProductVariables) {
variables.VendorVars = tc.vendorVars
variables.VendorVarTypes = tc.vendorVarTypes
}),
FixtureMergeMockFs(fs),
)
if tc.expectedError != "" {
fixtures = fixtures.ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(tc.expectedError))
}
result := fixtures.RunTestWithBp(t, tc.bp)
result := fixtures.RunTest(t)
if tc.expectedError == "" {
if len(tc.providers) == 0 {
@ -846,6 +1087,7 @@ type selectsTestProvider struct {
my_string_list *[]string
my_paths *[]string
replacing_string_list *[]string
arch_variant_configurable_bool *bool
my_nonconfigurable_bool *bool
my_nonconfigurable_string *string
my_nonconfigurable_string_list []string
@ -870,6 +1112,7 @@ func (p *selectsTestProvider) String() string {
my_string_list: %s,
my_paths: %s,
replacing_string_list %s,
arch_variant_configurable_bool %v
my_nonconfigurable_bool: %v,
my_nonconfigurable_string: %s,
my_nonconfigurable_string_list: %s,
@ -879,6 +1122,7 @@ func (p *selectsTestProvider) String() string {
p.my_string_list,
p.my_paths,
p.replacing_string_list,
p.arch_variant_configurable_bool,
p.my_nonconfigurable_bool,
myNonconfigurableStringStr,
p.my_nonconfigurable_string_list,
@ -893,6 +1137,7 @@ type selectsMockModuleProperties struct {
My_string_list proptools.Configurable[[]string]
My_paths proptools.Configurable[[]string] `android:"path"`
Replacing_string_list proptools.Configurable[[]string] `android:"replace_instead_of_append,arch_variant"`
Arch_variant_configurable_bool proptools.Configurable[bool] `android:"replace_instead_of_append,arch_variant"`
My_nonconfigurable_bool *bool
My_nonconfigurable_string *string
My_nonconfigurable_string_list []string
@ -923,6 +1168,7 @@ func (p *selectsMockModule) GenerateAndroidBuildActions(ctx ModuleContext) {
my_string_list: optionalToPtr(p.properties.My_string_list.Get(ctx)),
my_paths: optionalToPtr(p.properties.My_paths.Get(ctx)),
replacing_string_list: optionalToPtr(p.properties.Replacing_string_list.Get(ctx)),
arch_variant_configurable_bool: optionalToPtr(p.properties.Arch_variant_configurable_bool.Get(ctx)),
my_nonconfigurable_bool: p.properties.My_nonconfigurable_bool,
my_nonconfigurable_string: p.properties.My_nonconfigurable_string,
my_nonconfigurable_string_list: p.properties.My_nonconfigurable_string_list,
@ -937,9 +1183,15 @@ func newSelectsMockModule() Module {
return m
}
type selectsMockDefaultsProperties struct {
String_list_postprocessor_add_to_elements string
}
type selectsMockModuleDefaults struct {
ModuleBase
DefaultsModuleBase
myProperties selectsMockModuleProperties
defaultsProperties selectsMockDefaultsProperties
}
func (d *selectsMockModuleDefaults) GenerateAndroidBuildActions(ctx ModuleContext) {
@ -949,10 +1201,22 @@ func newSelectsMockModuleDefaults() Module {
module := &selectsMockModuleDefaults{}
module.AddProperties(
&selectsMockModuleProperties{},
&module.myProperties,
&module.defaultsProperties,
)
InitDefaultsModule(module)
AddLoadHook(module, func(lhc LoadHookContext) {
if module.defaultsProperties.String_list_postprocessor_add_to_elements != "" {
module.myProperties.My_string_list.AddPostProcessor(func(x []string) []string {
for i := range x {
x[i] = x[i] + module.defaultsProperties.String_list_postprocessor_add_to_elements
}
return x
})
}
})
return module
}

View file

@ -824,11 +824,16 @@ func (s *listVariable) printfIntoPropertyRecursive(fieldName []string, propStruc
}
field.Set(newField)
case reflect.Struct:
fieldName = append(fieldName, propStruct.Type().Field(i).Name)
if err := s.printfIntoPropertyRecursive(fieldName, field, configValues); err != nil {
return err
if proptools.IsConfigurable(field.Type()) {
fieldName = append(fieldName, propStruct.Type().Field(i).Name)
return fmt.Errorf("soong_config_variables.%s.%s: list variables are not supported on configurable properties", s.variable, strings.Join(fieldName, "."))
} else {
fieldName = append(fieldName, propStruct.Type().Field(i).Name)
if err := s.printfIntoPropertyRecursive(fieldName, field, configValues); err != nil {
return err
}
fieldName = fieldName[:len(fieldName)-1]
}
fieldName = fieldName[:len(fieldName)-1]
default:
fieldName = append(fieldName, propStruct.Type().Field(i).Name)
return fmt.Errorf("soong_config_variables.%s.%s: unsupported property type %q", s.variable, strings.Join(fieldName, "."), kind)

View file

@ -224,6 +224,10 @@ func (ctx *TestContext) OtherModuleProviderAdaptor() OtherModuleProviderContext
})
}
func (ctx *TestContext) OtherModulePropertyErrorf(module Module, property string, fmt_ string, args ...interface{}) {
panic(fmt.Sprintf(fmt_, args...))
}
// registeredComponentOrder defines the order in which a sortableComponent type is registered at
// runtime and provides support for reordering the components registered for a test in the same
// way.

View file

@ -81,6 +81,16 @@ type variableProperties struct {
Header_libs []string `android:"arch_variant"`
} `android:"arch_variant"`
Malloc_low_memory_libc32 struct {
Cflags []string `android:"arch_variant"`
Shared_libs []string `android:"arch_variant"`
Whole_static_libs []string `android:"arch_variant"`
Static_libs []string `android:"arch_variant"`
Exclude_static_libs []string `android:"arch_variant"`
Srcs []string `android:"arch_variant"`
Header_libs []string `android:"arch_variant"`
} `android:"arch_variant"`
Malloc_zero_contents struct {
Cflags []string `android:"arch_variant"`
} `android:"arch_variant"`
@ -150,6 +160,7 @@ type variableProperties struct {
Eng struct {
Cflags []string
Cppflags []string
Init_rc []string
Lto struct {
Never *bool
}
@ -199,11 +210,12 @@ type ProductVariables struct {
// Suffix to add to generated Makefiles
Make_suffix *string `json:",omitempty"`
BuildId *string `json:",omitempty"`
BuildNumberFile *string `json:",omitempty"`
BuildHostnameFile *string `json:",omitempty"`
BuildThumbprintFile *string `json:",omitempty"`
DisplayBuildNumber *bool `json:",omitempty"`
BuildId *string `json:",omitempty"`
BuildFingerprintFile *string `json:",omitempty"`
BuildNumberFile *string `json:",omitempty"`
BuildHostnameFile *string `json:",omitempty"`
BuildThumbprintFile *string `json:",omitempty"`
DisplayBuildNumber *bool `json:",omitempty"`
Platform_display_version_name *string `json:",omitempty"`
Platform_version_name *string `json:",omitempty"`
@ -285,6 +297,7 @@ type ProductVariables struct {
Always_use_prebuilt_sdks *bool `json:",omitempty"`
Skip_boot_jars_check *bool `json:",omitempty"`
Malloc_low_memory *bool `json:",omitempty"`
Malloc_low_memory_libc32 *bool `json:",omitempty"`
Malloc_zero_contents *bool `json:",omitempty"`
Malloc_pattern_fill_contents *bool `json:",omitempty"`
Safestack *bool `json:",omitempty"`
@ -362,6 +375,8 @@ type ProductVariables struct {
DeviceKernelHeaders []string `json:",omitempty"`
TargetSpecificHeaderPath *string `json:",omitempty"`
ExtraVndkVersions []string `json:",omitempty"`
NamespacesToExport []string `json:",omitempty"`
@ -398,7 +413,8 @@ type ProductVariables struct {
PlatformSepolicyCompatVersions []string `json:",omitempty"`
VendorVars map[string]map[string]string `json:",omitempty"`
VendorVars map[string]map[string]string `json:",omitempty"`
VendorVarTypes map[string]map[string]string `json:",omitempty"`
Ndk_abis *bool `json:",omitempty"`
@ -458,6 +474,7 @@ type ProductVariables struct {
BuildBrokenIncorrectPartitionImages bool `json:",omitempty"`
BuildBrokenInputDirModules []string `json:",omitempty"`
BuildBrokenDontCheckSystemSdk bool `json:",omitempty"`
BuildBrokenDupSysprop bool `json:",omitempty"`
BuildWarningBadOptionalUsesLibsAllowlist []string `json:",omitempty"`
@ -513,6 +530,15 @@ type ProductVariables struct {
BoardUseVbmetaDigestInFingerprint *bool `json:",omitempty"`
OemProperties []string `json:",omitempty"`
ArtTargetIncludeDebugBuild *bool `json:",omitempty"`
SystemPropFiles []string `json:",omitempty"`
SystemExtPropFiles []string `json:",omitempty"`
ProductPropFiles []string `json:",omitempty"`
OdmPropFiles []string `json:",omitempty"`
EnableUffdGc *string `json:",omitempty"`
}
type PartitionQualifiedVariablesType struct {
@ -617,6 +643,7 @@ func (v *ProductVariables) SetDefaultConfig() {
AAPTPrebuiltDPI: []string{"xhdpi", "xxhdpi"},
Malloc_low_memory: boolPtr(false),
Malloc_low_memory_libc32: boolPtr(false),
Malloc_zero_contents: boolPtr(true),
Malloc_pattern_fill_contents: boolPtr(false),
Safestack: boolPtr(false),

View file

@ -341,9 +341,6 @@ func classifyLocalOrGlobalPath(value bpparser.Expression) (string, bpparser.Expr
firstOperand := v.Args[0]
secondOperand := v.Args[1]
if firstOperand.Type() != bpparser.StringType {
return "global", value, nil
}
if _, ok := firstOperand.(*bpparser.Operator); ok {
return "global", value, nil
@ -762,6 +759,13 @@ func cflags(ctx variableAssignmentContext) error {
return includeVariableNow(bpVariable{"cflags", bpparser.ListType}, ctx)
}
func exportCflags(ctx variableAssignmentContext) error {
// The Soong replacement for EXPORT_CFLAGS doesn't need the same extra escaped quotes that were present in Make
ctx.mkvalue = ctx.mkvalue.Clone()
ctx.mkvalue.ReplaceLiteral(`\"`, `"`)
return includeVariableNow(bpVariable{"export_cflags", bpparser.ListType}, ctx)
}
func protoOutputParams(ctx variableAssignmentContext) error {
// The Soong replacement for LOCAL_PROTO_JAVA_OUTPUT_PARAMS doesn't need ","
ctx.mkvalue = ctx.mkvalue.Clone()

View file

@ -493,7 +493,6 @@ func setVariable(file *bpFile, plusequals bool, prefix, name string, value bppar
Name: name,
NamePos: pos,
Value: value,
OrigValue: value,
EqualsPos: pos,
Assigner: "+=",
}
@ -506,7 +505,6 @@ func setVariable(file *bpFile, plusequals bool, prefix, name string, value bppar
Name: name,
NamePos: pos,
Value: value,
OrigValue: value,
EqualsPos: pos,
Assigner: "=",
}

View file

@ -81,7 +81,7 @@ func makeToStringExpression(ms *mkparser.MakeString, file *bpFile) (bpparser.Exp
}
tmp := &bpparser.Variable{
Name: name,
Value: &bpparser.String{},
Type_: bpparser.StringType,
}
if tmp.Name == "TOP" {
@ -150,7 +150,7 @@ func makeToListExpression(ms *mkparser.MakeString, file *bpFile) (bpparser.Expre
}
listOfListValues = append(listOfListValues, &bpparser.Variable{
Name: name,
Value: &bpparser.List{},
Type_: bpparser.ListType,
})
listValue = &bpparser.List{}
}
@ -215,7 +215,7 @@ func makeToBoolExpression(ms *mkparser.MakeString, file *bpFile) (bpparser.Expre
}
return &bpparser.Variable{
Name: name,
Value: &bpparser.Bool{},
Type_: bpparser.BoolType,
}, nil
} else {
return nil, fmt.Errorf("non-const bool expression %s", ms.Dump())

View file

@ -218,7 +218,7 @@ func (a *apexBundle) writeRequiredModules(w io.Writer, moduleNames []string) {
var required []string
var targetRequired []string
var hostRequired []string
required = append(required, a.RequiredModuleNames()...)
required = append(required, a.required...)
targetRequired = append(targetRequired, a.TargetRequiredModuleNames()...)
hostRequired = append(hostRequired, a.HostRequiredModuleNames()...)
for _, fi := range a.filesInfo {

View file

@ -86,7 +86,7 @@ type apexBundleProperties struct {
// AndroidManifest.xml file used for the zip container of this APEX bundle. If unspecified,
// a default one is automatically generated.
AndroidManifest *string `android:"path"`
AndroidManifest proptools.Configurable[string] `android:"path,replace_instead_of_append"`
// Determines the file contexts file for setting the security contexts to files in this APEX
// bundle. For platform APEXes, this should points to a file under /system/sepolicy Default:
@ -104,7 +104,7 @@ type apexBundleProperties struct {
// path_or_glob is a path or glob pattern for a file or set of files,
// uid/gid are numerial values of user ID and group ID, mode is octal value
// for the file mode, and cap is hexadecimal value for the capability.
Canned_fs_config *string `android:"path"`
Canned_fs_config proptools.Configurable[string] `android:"path,replace_instead_of_append"`
ApexNativeDependencies
@ -117,7 +117,8 @@ type apexBundleProperties struct {
Bootclasspath_fragments []string
// List of systemserverclasspath fragments that are embedded inside this APEX bundle.
Systemserverclasspath_fragments []string
Systemserverclasspath_fragments proptools.Configurable[[]string]
ResolvedSystemserverclasspathFragments []string `blueprint:"mutated"`
// List of java libraries that are embedded inside this APEX bundle.
Java_libs []string
@ -222,7 +223,8 @@ type ApexNativeDependencies struct {
Rust_dyn_libs []string
// List of native executables that are embedded inside this APEX.
Binaries []string
Binaries proptools.Configurable[[]string]
ResolvedBinaries []string `blueprint:"mutated"`
// List of native tests that are embedded inside this APEX.
Tests []string
@ -231,7 +233,8 @@ type ApexNativeDependencies struct {
Filesystems []string
// List of prebuilt_etcs that are embedded inside this APEX bundle.
Prebuilts []string
Prebuilts proptools.Configurable[[]string]
ResolvedPrebuilts []string `blueprint:"mutated"`
// List of native libraries to exclude from this APEX.
Exclude_native_shared_libs []string
@ -256,14 +259,14 @@ type ApexNativeDependencies struct {
}
// Merge combines another ApexNativeDependencies into this one
func (a *ApexNativeDependencies) Merge(b ApexNativeDependencies) {
func (a *ApexNativeDependencies) Merge(ctx android.BaseMutatorContext, b ApexNativeDependencies) {
a.Native_shared_libs = append(a.Native_shared_libs, b.Native_shared_libs...)
a.Jni_libs = append(a.Jni_libs, b.Jni_libs...)
a.Rust_dyn_libs = append(a.Rust_dyn_libs, b.Rust_dyn_libs...)
a.Binaries = append(a.Binaries, b.Binaries...)
a.ResolvedBinaries = append(a.ResolvedBinaries, b.Binaries.GetOrDefault(ctx, nil)...)
a.Tests = append(a.Tests, b.Tests...)
a.Filesystems = append(a.Filesystems, b.Filesystems...)
a.Prebuilts = append(a.Prebuilts, b.Prebuilts...)
a.ResolvedPrebuilts = append(a.ResolvedPrebuilts, b.Prebuilts.GetOrDefault(ctx, nil)...)
a.Exclude_native_shared_libs = append(a.Exclude_native_shared_libs, b.Exclude_native_shared_libs...)
a.Exclude_jni_libs = append(a.Exclude_jni_libs, b.Exclude_jni_libs...)
@ -339,10 +342,10 @@ type apexArchBundleProperties struct {
// base apex.
type overridableProperties struct {
// List of APKs that are embedded inside this APEX.
Apps []string
Apps proptools.Configurable[[]string]
// List of prebuilt files that are embedded inside this APEX bundle.
Prebuilts []string
Prebuilts proptools.Configurable[[]string]
// List of BPF programs inside this APEX bundle.
Bpfs []string
@ -489,6 +492,9 @@ type apexBundle struct {
javaApisUsedByModuleFile android.ModuleOutPath
aconfigFiles []android.Path
// Required modules, filled out during GenerateAndroidBuildActions and used in AndroidMk
required []string
}
// apexFileClass represents a type of file that can be included in APEX.
@ -567,7 +573,7 @@ func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidM
if module != nil {
ret.moduleDir = ctx.OtherModuleDir(module)
ret.partition = module.PartitionTag(ctx.DeviceConfig())
ret.requiredModuleNames = module.RequiredModuleNames()
ret.requiredModuleNames = module.RequiredModuleNames(ctx)
ret.targetRequiredModuleNames = module.TargetRequiredModuleNames()
ret.hostRequiredModuleNames = module.HostRequiredModuleNames()
ret.multilib = module.Target().Arch.ArchType.Multilib
@ -714,7 +720,7 @@ func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, nativeM
// this module. This is required since arch variant of an APEX bundle is 'common' but it is
// 'arm' or 'arm64' for native shared libs.
ctx.AddFarVariationDependencies(binVariations, executableTag,
android.RemoveListFromList(nativeModules.Binaries, nativeModules.Exclude_binaries)...)
android.RemoveListFromList(nativeModules.ResolvedBinaries, nativeModules.Exclude_binaries)...)
ctx.AddFarVariationDependencies(binVariations, testTag,
android.RemoveListFromList(nativeModules.Tests, nativeModules.Exclude_tests)...)
ctx.AddFarVariationDependencies(libVariations, jniLibTag,
@ -726,7 +732,7 @@ func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, nativeM
ctx.AddFarVariationDependencies(target.Variations(), fsTag,
android.RemoveListFromList(nativeModules.Filesystems, nativeModules.Exclude_filesystems)...)
ctx.AddFarVariationDependencies(target.Variations(), prebuiltTag,
android.RemoveListFromList(nativeModules.Prebuilts, nativeModules.Exclude_prebuilts)...)
android.RemoveListFromList(nativeModules.ResolvedPrebuilts, nativeModules.Exclude_prebuilts)...)
}
func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
@ -781,20 +787,19 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
// Add native modules targeting both ABIs. When multilib.* is omitted for
// native_shared_libs/jni_libs/tests, it implies multilib.both
deps.Merge(a.properties.Multilib.Both)
deps.Merge(ApexNativeDependencies{
deps.Merge(ctx, a.properties.Multilib.Both)
deps.Merge(ctx, ApexNativeDependencies{
Native_shared_libs: a.properties.Native_shared_libs,
Tests: a.properties.Tests,
Jni_libs: a.properties.Jni_libs,
Binaries: nil,
})
// Add native modules targeting the first ABI When multilib.* is omitted for
// binaries, it implies multilib.first
isPrimaryAbi := i == 0
if isPrimaryAbi {
deps.Merge(a.properties.Multilib.First)
deps.Merge(ApexNativeDependencies{
deps.Merge(ctx, a.properties.Multilib.First)
deps.Merge(ctx, ApexNativeDependencies{
Native_shared_libs: nil,
Tests: nil,
Jni_libs: nil,
@ -805,27 +810,27 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
// Add native modules targeting either 32-bit or 64-bit ABI
switch target.Arch.ArchType.Multilib {
case "lib32":
deps.Merge(a.properties.Multilib.Lib32)
deps.Merge(a.properties.Multilib.Prefer32)
deps.Merge(ctx, a.properties.Multilib.Lib32)
deps.Merge(ctx, a.properties.Multilib.Prefer32)
case "lib64":
deps.Merge(a.properties.Multilib.Lib64)
deps.Merge(ctx, a.properties.Multilib.Lib64)
if !has32BitTarget {
deps.Merge(a.properties.Multilib.Prefer32)
deps.Merge(ctx, a.properties.Multilib.Prefer32)
}
}
// Add native modules targeting a specific arch variant
switch target.Arch.ArchType {
case android.Arm:
deps.Merge(a.archProperties.Arch.Arm.ApexNativeDependencies)
deps.Merge(ctx, a.archProperties.Arch.Arm.ApexNativeDependencies)
case android.Arm64:
deps.Merge(a.archProperties.Arch.Arm64.ApexNativeDependencies)
deps.Merge(ctx, a.archProperties.Arch.Arm64.ApexNativeDependencies)
case android.Riscv64:
deps.Merge(a.archProperties.Arch.Riscv64.ApexNativeDependencies)
deps.Merge(ctx, a.archProperties.Arch.Riscv64.ApexNativeDependencies)
case android.X86:
deps.Merge(a.archProperties.Arch.X86.ApexNativeDependencies)
deps.Merge(ctx, a.archProperties.Arch.X86.ApexNativeDependencies)
case android.X86_64:
deps.Merge(a.archProperties.Arch.X86_64.ApexNativeDependencies)
deps.Merge(ctx, a.archProperties.Arch.X86_64.ApexNativeDependencies)
default:
panic(fmt.Errorf("unsupported arch %v\n", ctx.Arch().ArchType))
}
@ -839,11 +844,13 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
}
}
a.properties.ResolvedSystemserverclasspathFragments = a.properties.Systemserverclasspath_fragments.GetOrDefault(ctx, nil)
// Common-arch dependencies come next
commonVariation := ctx.Config().AndroidCommonTarget.Variations()
ctx.AddFarVariationDependencies(commonVariation, rroTag, a.properties.Rros...)
ctx.AddFarVariationDependencies(commonVariation, bcpfTag, a.properties.Bootclasspath_fragments...)
ctx.AddFarVariationDependencies(commonVariation, sscpfTag, a.properties.Systemserverclasspath_fragments...)
ctx.AddFarVariationDependencies(commonVariation, sscpfTag, a.properties.ResolvedSystemserverclasspathFragments...)
ctx.AddFarVariationDependencies(commonVariation, javaLibTag, a.properties.Java_libs...)
ctx.AddFarVariationDependencies(commonVariation, fsTag, a.properties.Filesystems...)
ctx.AddFarVariationDependencies(commonVariation, compatConfigTag, a.properties.Compat_configs...)
@ -856,9 +863,9 @@ func (a *apexBundle) OverridablePropertiesDepsMutator(ctx android.BottomUpMutato
}
commonVariation := ctx.Config().AndroidCommonTarget.Variations()
ctx.AddFarVariationDependencies(commonVariation, androidAppTag, a.overridableProperties.Apps...)
ctx.AddFarVariationDependencies(commonVariation, androidAppTag, a.overridableProperties.Apps.GetOrDefault(ctx, nil)...)
ctx.AddFarVariationDependencies(commonVariation, bpfTag, a.overridableProperties.Bpfs...)
if prebuilts := a.overridableProperties.Prebuilts; len(prebuilts) > 0 {
if prebuilts := a.overridableProperties.Prebuilts.GetOrDefault(ctx, nil); len(prebuilts) > 0 {
// For prebuilt_etc, use the first variant (64 on 64/32bit device, 32 on 32bit device)
// regardless of the TARGET_PREFER_* setting. See b/144532908
arches := ctx.DeviceConfig().Arches()
@ -1530,7 +1537,6 @@ func (a *apexBundle) AddSanitizerDependencies(ctx android.BottomUpMutatorContext
Native_shared_libs: []string{"libclang_rt.hwasan"},
Tests: nil,
Jni_libs: nil,
Binaries: nil,
}, target, imageVariation)
break
}
@ -2426,6 +2432,8 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.provideApexExportsInfo(ctx)
a.providePrebuiltInfo(ctx)
a.required = a.RequiredModuleNames(ctx)
}
// Set prebuiltInfoProvider. This will be used by `apex_prebuiltinfo_singleton` to print out a metadata file
@ -2851,7 +2859,7 @@ func isStaticExecutableAllowed(apex string, exec string) bool {
func (a *apexBundle) IDEInfo(dpInfo *android.IdeInfo) {
dpInfo.Deps = append(dpInfo.Deps, a.properties.Java_libs...)
dpInfo.Deps = append(dpInfo.Deps, a.properties.Bootclasspath_fragments...)
dpInfo.Deps = append(dpInfo.Deps, a.properties.Systemserverclasspath_fragments...)
dpInfo.Deps = append(dpInfo.Deps, a.properties.ResolvedSystemserverclasspathFragments...)
}
var (

View file

@ -704,8 +704,9 @@ func (a *apexBundle) buildApex(ctx android.ModuleContext) {
optFlags = append(optFlags, "--override_apk_package_name "+manifestPackageName)
}
if a.properties.AndroidManifest != nil {
androidManifestFile := android.PathForModuleSrc(ctx, proptools.String(a.properties.AndroidManifest))
androidManifest := a.properties.AndroidManifest.GetOrDefault(ctx, "")
if androidManifest != "" {
androidManifestFile := android.PathForModuleSrc(ctx, androidManifest)
if a.testApex {
androidManifestFile = markManifestTestOnly(ctx, androidManifestFile)
@ -1195,8 +1196,9 @@ func (a *apexBundle) buildCannedFsConfig(ctx android.ModuleContext, defaultReadO
}
// Custom fs_config is "appended" to the last so that entries from the file are preferred
// over default ones set above.
if a.properties.Canned_fs_config != nil {
cmd.Text("cat").Input(android.PathForModuleSrc(ctx, *a.properties.Canned_fs_config))
customFsConfig := a.properties.Canned_fs_config.GetOrDefault(ctx, "")
if customFsConfig != "" {
cmd.Text("cat").Input(android.PathForModuleSrc(ctx, customFsConfig))
}
cmd.Text(")").FlagWithOutput("> ", cannedFsConfig)
builder.Build("generateFsConfig", fmt.Sprintf("Generating canned fs config for %s", a.BaseModuleName()))

View file

@ -286,7 +286,7 @@ func (f *Fixer) reparse() ([]byte, error) {
}
func parse(name string, r io.Reader) (*parser.File, error) {
tree, errs := parser.Parse(name, r, parser.NewScope(nil))
tree, errs := parser.Parse(name, r)
if errs != nil {
s := "parse error: "
for _, err := range errs {

View file

@ -46,7 +46,7 @@ func buildTree(local_include_dirs []string, export_include_dirs []string) (file
}
`,
printListOfStrings(local_include_dirs), printListOfStrings(export_include_dirs))
tree, errs := parser.Parse("", strings.NewReader(input), parser.NewScope(nil))
tree, errs := parser.Parse("", strings.NewReader(input))
if len(errs) > 0 {
errs = append([]error{fmt.Errorf("failed to parse:\n%s", input)}, errs...)
}
@ -167,7 +167,7 @@ func preProcessIn(in string) (fixer *Fixer, err error) {
return fixer, err
}
tree, errs := parser.Parse("<testcase>", bytes.NewBufferString(in), parser.NewScope(nil))
tree, errs := parser.Parse("<testcase>", bytes.NewBufferString(in))
if errs != nil {
return fixer, err
}

View file

@ -66,7 +66,7 @@ func processFile(filename string, in io.Reader, out io.Writer, fixRequest bpfix.
return err
}
r := bytes.NewBuffer(append([]byte(nil), src...))
file, errs := parser.Parse(filename, r, parser.NewScope(nil))
file, errs := parser.Parse(filename, r)
if len(errs) > 0 {
for _, err := range errs {
fmt.Fprintln(os.Stderr, err)

View file

@ -981,8 +981,8 @@ func (c *Module) HiddenFromMake() bool {
return c.Properties.HideFromMake
}
func (c *Module) RequiredModuleNames() []string {
required := android.CopyOf(c.ModuleBase.RequiredModuleNames())
func (c *Module) RequiredModuleNames(ctx android.ConfigAndErrorContext) []string {
required := android.CopyOf(c.ModuleBase.RequiredModuleNames(ctx))
if c.ImageVariation().Variation == android.CoreVariation {
required = append(required, c.Properties.Target.Platform.Required...)
required = removeListFromList(required, c.Properties.Target.Platform.Exclude_required)
@ -2468,6 +2468,23 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
variantNdkLibs := []string{}
variantLateNdkLibs := []string{}
if ctx.Os() == android.Android {
rewriteHeaderLibs := func(list []string) (newHeaderLibs []string) {
newHeaderLibs = []string{}
for _, entry := range list {
// Replace device_kernel_headers with generated_kernel_headers
// for inline kernel building
if entry == "device_kernel_headers" || entry == "qti_kernel_headers" {
if (ctx.Config().Getenv("INLINE_KERNEL_BUILDING") == "true") {
newHeaderLibs = append(newHeaderLibs, "generated_kernel_headers")
continue
}
}
newHeaderLibs = append(newHeaderLibs, entry)
}
return newHeaderLibs
}
deps.HeaderLibs = rewriteHeaderLibs(deps.HeaderLibs)
deps.SharedLibs, variantNdkLibs = FilterNdkLibs(c, ctx.Config(), deps.SharedLibs)
deps.LateSharedLibs, variantLateNdkLibs = FilterNdkLibs(c, ctx.Config(), deps.LateSharedLibs)
deps.ReexportSharedLibHeaders, _ = FilterNdkLibs(c, ctx.Config(), deps.ReexportSharedLibHeaders)

View file

@ -53,7 +53,7 @@ type BaseCompilerProperties struct {
Cflags proptools.Configurable[[]string] `android:"arch_variant"`
// list of module-specific flags that will be used for C++ compiles
Cppflags []string `android:"arch_variant"`
Cppflags proptools.Configurable[[]string] `android:"arch_variant"`
// list of module-specific flags that will be used for C compiles
Conlyflags []string `android:"arch_variant"`
@ -363,12 +363,23 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps
tc := ctx.toolchain()
modulePath := ctx.ModuleDir()
additionalIncludeDirs := ctx.DeviceConfig().TargetSpecificHeaderPath()
if len(additionalIncludeDirs) > 0 {
// devices can have multiple paths in TARGET_SPECIFIC_HEADER_PATH
// add -I in front of all of them
if (strings.Contains(additionalIncludeDirs, " ")) {
additionalIncludeDirs = strings.ReplaceAll(additionalIncludeDirs, " ", " -I")
}
flags.Local.CommonFlags = append(flags.Local.CommonFlags, "-I" + additionalIncludeDirs)
}
compiler.srcsBeforeGen = android.PathsForModuleSrcExcludes(ctx, compiler.Properties.Srcs, compiler.Properties.Exclude_srcs)
compiler.srcsBeforeGen = append(compiler.srcsBeforeGen, deps.GeneratedSources...)
cflags := compiler.Properties.Cflags.GetOrDefault(ctx, nil)
cppflags := compiler.Properties.Cppflags.GetOrDefault(ctx, nil)
CheckBadCompilerFlags(ctx, "cflags", cflags)
CheckBadCompilerFlags(ctx, "cppflags", compiler.Properties.Cppflags)
CheckBadCompilerFlags(ctx, "cppflags", cppflags)
CheckBadCompilerFlags(ctx, "conlyflags", compiler.Properties.Conlyflags)
CheckBadCompilerFlags(ctx, "asflags", compiler.Properties.Asflags)
CheckBadCompilerFlags(ctx, "vendor.cflags", compiler.Properties.Target.Vendor.Cflags)
@ -381,7 +392,7 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps
esc := proptools.NinjaAndShellEscapeList
flags.Local.CFlags = append(flags.Local.CFlags, esc(cflags)...)
flags.Local.CppFlags = append(flags.Local.CppFlags, esc(compiler.Properties.Cppflags)...)
flags.Local.CppFlags = append(flags.Local.CppFlags, esc(cppflags)...)
flags.Local.ConlyFlags = append(flags.Local.ConlyFlags, esc(compiler.Properties.Conlyflags)...)
flags.Local.AsFlags = append(flags.Local.AsFlags, esc(compiler.Properties.Asflags)...)
flags.Local.YasmFlags = append(flags.Local.YasmFlags, esc(compiler.Properties.Asflags)...)
@ -813,7 +824,7 @@ type RustBindgenClangProperties struct {
// list of c++ specific clang flags required to correctly interpret the headers.
// This is provided primarily to make sure cppflags defined in cc_defaults are pulled in.
Cppflags []string `android:"arch_variant"`
Cppflags proptools.Configurable[[]string] `android:"arch_variant"`
// C standard version to use. Can be a specific version (such as "gnu11"),
// "experimental" (which will use draft versions like C1x when available),

View file

@ -196,6 +196,9 @@ type FlagExporterProperties struct {
// using -isystem for this module and any module that links against this module.
Export_system_include_dirs []string `android:"arch_variant,variant_prepend"`
// list of plain cc flags to be used for any module that links against this module.
Export_cflags []string `android:"arch_variant"`
Target struct {
Vendor, Product struct {
// list of exported include directories, like
@ -306,6 +309,10 @@ func (f *flagExporter) exportIncludes(ctx ModuleContext) {
f.systemDirs = append(f.systemDirs, android.PathsForModuleSrc(ctx, f.Properties.Export_system_include_dirs)...)
}
func (f *flagExporter) exportExtraFlags(ctx ModuleContext) {
f.flags = append(f.flags, f.Properties.Export_cflags...)
}
// exportIncludesAsSystem registers the include directories and system include directories to be
// exported transitively both as system include directories to modules depending on this module.
func (f *flagExporter) exportIncludesAsSystem(ctx ModuleContext) {
@ -1630,6 +1637,7 @@ func (library *libraryDecorator) link(ctx ModuleContext,
// Export include paths and flags to be propagated up the tree.
library.exportIncludes(ctx)
library.exportExtraFlags(ctx)
library.reexportDirs(deps.ReexportedDirs...)
library.reexportSystemDirs(deps.ReexportedSystemDirs...)
library.reexportFlags(deps.ReexportedFlags...)

View file

@ -59,7 +59,7 @@ type vbmetaProperties struct {
// List of filesystem modules that this vbmeta has descriptors for. The filesystem modules
// have to be signed (use_avb: true).
Partitions []string
Partitions proptools.Configurable[[]string]
// List of chained partitions that this vbmeta deletages the verification.
Chained_partitions []chainedPartitionProperties
@ -110,7 +110,7 @@ type vbmetaDep struct {
var vbmetaPartitionDep = vbmetaDep{kind: "partition"}
func (v *vbmeta) DepsMutator(ctx android.BottomUpMutatorContext) {
ctx.AddDependency(ctx.Module(), vbmetaPartitionDep, v.properties.Partitions...)
ctx.AddDependency(ctx.Module(), vbmetaPartitionDep, v.properties.Partitions.GetOrDefault(ctx, nil)...)
}
func (v *vbmeta) installFileName() string {

View file

@ -139,7 +139,8 @@ type generatorProperties struct {
Export_include_dirs []string
// list of input files
Srcs []string `android:"path,arch_variant"`
Srcs proptools.Configurable[[]string] `android:"path,arch_variant"`
ResolvedSrcs []string `blueprint:"mutated"`
// input files to exclude
Exclude_srcs []string `android:"path,arch_variant"`
@ -396,7 +397,8 @@ func (g *Module) generateCommonBuildActions(ctx android.ModuleContext) {
}
return srcFiles
}
srcFiles := addLabelsForInputs("srcs", g.properties.Srcs, g.properties.Exclude_srcs)
g.properties.ResolvedSrcs = g.properties.Srcs.GetOrDefault(ctx, nil)
srcFiles := addLabelsForInputs("srcs", g.properties.ResolvedSrcs, g.properties.Exclude_srcs)
android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: srcFiles.Strings()})
var copyFrom android.Paths
@ -590,7 +592,7 @@ func (g *Module) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// Collect information for opening IDE project files in java/jdeps.go.
func (g *Module) IDEInfo(dpInfo *android.IdeInfo) {
dpInfo.Srcs = append(dpInfo.Srcs, g.Srcs().Strings()...)
for _, src := range g.properties.Srcs {
for _, src := range g.properties.ResolvedSrcs {
if strings.HasPrefix(src, ":") {
src = strings.Trim(src, ":")
dpInfo.Deps = append(dpInfo.Deps, src)

View file

@ -694,7 +694,7 @@ func TestGenruleDefaults(t *testing.T) {
android.AssertStringEquals(t, "cmd", expectedCmd, gen.rawCommands[0])
expectedSrcs := []string{"in1"}
android.AssertDeepEquals(t, "srcs", expectedSrcs, gen.properties.Srcs)
android.AssertDeepEquals(t, "srcs", expectedSrcs, gen.properties.ResolvedSrcs)
}
func TestGenruleAllowMissingDependencies(t *testing.T) {

View file

@ -1501,7 +1501,7 @@ func (j *TestHost) GenerateAndroidBuildActions(ctx android.ModuleContext) {
InstalledFiles: j.data,
OutputFile: j.outputFile,
TestConfig: j.testConfig,
RequiredModuleNames: j.RequiredModuleNames(),
RequiredModuleNames: j.RequiredModuleNames(ctx),
TestSuites: j.testProperties.Test_suites,
IsHost: true,
LocalSdkVersion: j.sdkVersion.String(),

View file

@ -20,6 +20,8 @@ import (
"strings"
"android/soong/android"
"github.com/google/blueprint/proptools"
)
func init() {
@ -49,7 +51,7 @@ func PhonyFactory() android.Module {
}
func (p *phony) GenerateAndroidBuildActions(ctx android.ModuleContext) {
p.requiredModuleNames = ctx.RequiredModuleNames()
p.requiredModuleNames = ctx.RequiredModuleNames(ctx)
p.hostRequiredModuleNames = ctx.HostRequiredModuleNames()
p.targetRequiredModuleNames = ctx.TargetRequiredModuleNames()
}
@ -88,14 +90,15 @@ type PhonyRule struct {
android.ModuleBase
android.DefaultableModuleBase
properties PhonyProperties
phonyDepsModuleNames []string
properties PhonyProperties
}
type PhonyProperties struct {
// The Phony_deps is the set of all dependencies for this target,
// and it can function similarly to .PHONY in a makefile.
// Additionally, dependencies within it can even include genrule.
Phony_deps []string
Phony_deps proptools.Configurable[[]string]
}
// The phony_rule provides functionality similar to the .PHONY in a makefile.
@ -109,13 +112,14 @@ func PhonyRuleFactory() android.Module {
}
func (p *PhonyRule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
p.phonyDepsModuleNames = p.properties.Phony_deps.GetOrDefault(ctx, nil)
}
func (p *PhonyRule) AndroidMk() android.AndroidMkData {
return android.AndroidMkData{
Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
if len(p.properties.Phony_deps) > 0 {
depModulesStr := strings.Join(p.properties.Phony_deps, " ")
if len(p.phonyDepsModuleNames) > 0 {
depModulesStr := strings.Join(p.phonyDepsModuleNames, " ")
fmt.Fprintln(w, ".PHONY:", name)
fmt.Fprintln(w, name, ":", depModulesStr)
}

View file

@ -285,7 +285,7 @@ func (b *bindgenDecorator) GenerateSource(ctx ModuleContext, deps PathDeps) andr
if isCpp {
cflags = append(cflags, "-x c++")
// Add any C++ only flags.
cflags = append(cflags, esc(b.ClangProperties.Cppflags)...)
cflags = append(cflags, esc(b.ClangProperties.Cppflags.GetOrDefault(ctx, nil))...)
} else {
cflags = append(cflags, "-x c")
}

View file

@ -292,9 +292,17 @@ python_binary_host {
}
python_binary_host {
name: "buildinfo",
main: "buildinfo.py",
srcs: ["buildinfo.py"],
name: "merge_json",
main: "merge_json.py",
srcs: [
"merge_json.py",
],
}
python_binary_host {
name: "gen_build_prop",
main: "gen_build_prop.py",
srcs: ["gen_build_prop.py"],
}
python_binary_host {

View file

@ -1,156 +0,0 @@
#!/usr/bin/env python3
#
# Copyright (C) 2024 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""A tool for generating buildinfo.prop"""
import argparse
import contextlib
import subprocess
def parse_args():
"""Parse commandline arguments."""
parser = argparse.ArgumentParser()
parser.add_argument('--use-vbmeta-digest-in-fingerprint', action='store_true')
parser.add_argument('--build-flavor', required=True)
parser.add_argument('--build-hostname-file', required=True, type=argparse.FileType('r')),
parser.add_argument('--build-id', required=True)
parser.add_argument('--build-keys', required=True)
parser.add_argument('--build-number-file', required=True, type=argparse.FileType('r'))
parser.add_argument('--build-thumbprint-file', type=argparse.FileType('r'))
parser.add_argument('--build-type', required=True)
parser.add_argument('--build-username', required=True)
parser.add_argument('--build-variant', required=True)
parser.add_argument('--cpu-abis', action='append', required=True)
parser.add_argument('--date-file', required=True, type=argparse.FileType('r'))
parser.add_argument('--default-locale')
parser.add_argument('--default-wifi-channels', action='append', default=[])
parser.add_argument('--device', required=True)
parser.add_argument("--display-build-number", action='store_true')
parser.add_argument('--platform-base-os', required=True)
parser.add_argument('--platform-display-version', required=True)
parser.add_argument('--platform-min-supported-target-sdk-version', required=True)
parser.add_argument('--platform-preview-sdk-fingerprint-file',
required=True,
type=argparse.FileType('r'))
parser.add_argument('--platform-preview-sdk-version', required=True)
parser.add_argument('--platform-sdk-version', required=True)
parser.add_argument('--platform-security-patch', required=True)
parser.add_argument('--platform-version', required=True)
parser.add_argument('--platform-version-codename',required=True)
parser.add_argument('--platform-version-all-codenames', action='append', required=True)
parser.add_argument('--platform-version-known-codenames', required=True)
parser.add_argument('--platform-version-last-stable', required=True)
parser.add_argument('--product', required=True)
parser.add_argument('--out', required=True, type=argparse.FileType('w'))
return parser.parse_args()
def main():
option = parse_args()
build_hostname = option.build_hostname_file.read().strip()
build_number = option.build_number_file.read().strip()
build_version_tags = option.build_keys
if option.build_type == "debug":
build_version_tags = "debug," + build_version_tags
raw_date = option.date_file.read().strip()
date = subprocess.check_output(["date", "-d", f"@{raw_date}"], text=True).strip()
date_utc = subprocess.check_output(["date", "-d", f"@{raw_date}", "+%s"], text=True).strip()
# build_desc is human readable strings that describe this build. This has the same info as the
# build fingerprint.
# e.g. "aosp_cf_x86_64_phone-userdebug VanillaIceCream MAIN eng.20240319.143939 test-keys"
build_desc = f"{option.product}-{option.build_variant} {option.platform_version} " \
f"{option.build_id} {build_number} {build_version_tags}"
platform_preview_sdk_fingerprint = option.platform_preview_sdk_fingerprint_file.read().strip()
with contextlib.redirect_stdout(option.out):
print("# begin build properties")
print("# autogenerated by buildinfo.py")
# The ro.build.id will be set dynamically by init, by appending the unique vbmeta digest.
if option.use_vbmeta_digest_in_fingerprint:
print(f"ro.build.legacy.id={option.build_id}")
else:
print(f"ro.build.id?={option.build_id}")
# ro.build.display.id is shown under Settings -> About Phone
if option.build_variant == "user":
# User builds should show:
# release build number or branch.buld_number non-release builds
# Dev. branches should have DISPLAY_BUILD_NUMBER set
if option.display_build_number:
print(f"ro.build.display.id?={option.build_id}.{build_number} {option.build_keys}")
else:
print(f"ro.build.display.id?={option.build_id} {option.build_keys}")
else:
# Non-user builds should show detailed build information (See build desc above)
print(f"ro.build.display.id?={build_desc}")
print(f"ro.build.version.incremental={build_number}")
print(f"ro.build.version.sdk={option.platform_sdk_version}")
print(f"ro.build.version.preview_sdk={option.platform_preview_sdk_version}")
print(f"ro.build.version.preview_sdk_fingerprint={platform_preview_sdk_fingerprint}")
print(f"ro.build.version.codename={option.platform_version_codename}")
print(f"ro.build.version.all_codenames={','.join(option.platform_version_all_codenames)}")
print(f"ro.build.version.known_codenames={option.platform_version_known_codenames}")
print(f"ro.build.version.release={option.platform_version_last_stable}")
print(f"ro.build.version.release_or_codename={option.platform_version}")
print(f"ro.build.version.release_or_preview_display={option.platform_display_version}")
print(f"ro.build.version.security_patch={option.platform_security_patch}")
print(f"ro.build.version.base_os={option.platform_base_os}")
print(f"ro.build.version.min_supported_target_sdk={option.platform_min_supported_target_sdk_version}")
print(f"ro.build.date={date}")
print(f"ro.build.date.utc={date_utc}")
print(f"ro.build.type={option.build_variant}")
print(f"ro.build.user={option.build_username}")
print(f"ro.build.host={build_hostname}")
# TODO: Remove any tag-related optional property declarations once the goals
# from go/arc-android-sigprop-changes have been achieved.
print(f"ro.build.tags?={build_version_tags}")
# ro.build.flavor are used only by the test harness to distinguish builds.
# Only add _asan for a sanitized build if it isn't already a part of the
# flavor (via a dedicated lunch config for example).
print(f"ro.build.flavor={option.build_flavor}")
# These values are deprecated, use "ro.product.cpu.abilist"
# instead (see below).
print(f"# ro.product.cpu.abi and ro.product.cpu.abi2 are obsolete,")
print(f"# use ro.product.cpu.abilist instead.")
print(f"ro.product.cpu.abi={option.cpu_abis[0]}")
if len(option.cpu_abis) > 1:
print(f"ro.product.cpu.abi2={option.cpu_abis[1]}")
if option.default_locale:
print(f"ro.product.locale={option.default_locale}")
print(f"ro.wifi.channels={' '.join(option.default_wifi_channels)}")
print(f"# ro.build.product is obsolete; use ro.product.device")
print(f"ro.build.product={option.device}")
print(f"# Do not try to parse description or thumbprint")
print(f"ro.build.description?={build_desc}")
if option.build_thumbprint_file:
build_thumbprint = option.build_thumbprint_file.read().strip()
print(f"ro.build.thumbprint={build_thumbprint}")
print(f"# end build properties")
if __name__ == "__main__":
main()

View file

@ -258,3 +258,19 @@ com\.google\.i18n\.phonenumbers
# Packages used for Android in Chrome OS
org\.chromium\.arc
org\.chromium\.arc\..*
# OPLUS adds
com\.oplus\..*
# QC adds
com.qualcomm.qti
com.quicinc.tcmiface
com.qualcomm.wfd
com.qualcomm.wfd.service
org.codeaurora.ims
org.codeaurora.internal
qcom.fmradio
###################################################
# IFAA Manager used for Alipay and/or WeChat payment
org\.ifaa\.android\.manager.*

645
scripts/gen_build_prop.py Normal file
View file

@ -0,0 +1,645 @@
#!/usr/bin/env python3
#
# Copyright (C) 2024 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""A tool for generating {partition}/build.prop"""
import argparse
import contextlib
import json
import os
import subprocess
import sys
TEST_KEY_DIR = "build/make/target/product/security"
def get_build_variant(product_config):
if product_config["Eng"]:
return "eng"
elif product_config["Debuggable"]:
return "userdebug"
else:
return "user"
def get_build_flavor(product_config):
build_flavor = product_config["DeviceProduct"] + "-" + get_build_variant(product_config)
if "address" in product_config.get("SanitizeDevice", []) and "_asan" not in build_flavor:
build_flavor += "_asan"
return build_flavor
def get_build_keys(product_config):
default_cert = product_config.get("DefaultAppCertificate", "")
if default_cert == "" or default_cert == os.path.join(TEST_KEY_DIR, "testKey"):
return "test-keys"
return "dev-keys"
def override_config(config):
if "PRODUCT_BUILD_PROP_OVERRIDES" in config:
current_key = None
props_overrides = {}
for var in config["PRODUCT_BUILD_PROP_OVERRIDES"]:
if "=" in var:
current_key, value = var.split("=")
props_overrides[current_key] = value
else:
props_overrides[current_key] += f" {var}"
for key, value in props_overrides.items():
if key not in config:
print(f"Key \"{key}\" isn't a valid prop override", file=sys.stderr)
sys.exit(1)
config[key] = value
def parse_args():
"""Parse commandline arguments."""
parser = argparse.ArgumentParser()
parser.add_argument("--build-fingerprint-file", required=True, type=argparse.FileType("r"))
parser.add_argument("--build-hostname-file", required=True, type=argparse.FileType("r"))
parser.add_argument("--build-number-file", required=True, type=argparse.FileType("r"))
parser.add_argument("--build-thumbprint-file", type=argparse.FileType("r"))
parser.add_argument("--build-username", required=True)
parser.add_argument("--date-file", required=True, type=argparse.FileType("r"))
parser.add_argument("--platform-preview-sdk-fingerprint-file", required=True, type=argparse.FileType("r"))
parser.add_argument("--prop-files", action="append", type=argparse.FileType("r"), default=[])
parser.add_argument("--product-config", required=True, type=argparse.FileType("r"))
parser.add_argument("--partition", required=True)
parser.add_argument("--build-broken-dup-sysprop", action="store_true", default=False)
parser.add_argument("--out", required=True, type=argparse.FileType("w"))
args = parser.parse_args()
# post process parse_args requiring manual handling
args.config = json.load(args.product_config)
config = args.config
config["BuildFlavor"] = get_build_flavor(config)
config["BuildKeys"] = get_build_keys(config)
config["BuildVariant"] = get_build_variant(config)
config["BuildFingerprint"] = args.build_fingerprint_file.read().strip()
config["BuildHostname"] = args.build_hostname_file.read().strip()
config["BuildNumber"] = args.build_number_file.read().strip()
config["BuildUsername"] = args.build_username
build_version_tags_list = config["BuildVersionTags"]
if config["BuildType"] == "debug":
build_version_tags_list.append("debug")
build_version_tags_list.append(config["BuildKeys"])
build_version_tags = ",".join(sorted(set(build_version_tags_list)))
config["BuildVersionTags"] = build_version_tags
raw_date = args.date_file.read().strip()
config["Date"] = subprocess.check_output(["date", "-d", f"@{raw_date}"], text=True).strip()
config["DateUtc"] = subprocess.check_output(["date", "-d", f"@{raw_date}", "+%s"], text=True).strip()
# build_desc is human readable strings that describe this build. This has the same info as the
# build fingerprint.
# e.g. "aosp_cf_x86_64_phone-userdebug VanillaIceCream MAIN eng.20240319.143939 test-keys"
config["BuildDesc"] = f"{config['DeviceProduct']}-{config['BuildVariant']} " \
f"{config['Platform_version_name']} {config['BuildId']} " \
f"{config['BuildNumber']} {config['BuildVersionTags']}"
config["PlatformPreviewSdkFingerprint"] = args.platform_preview_sdk_fingerprint_file.read().strip()
if args.build_thumbprint_file:
config["BuildThumbprint"] = args.build_thumbprint_file.read().strip()
config["tequilaDesc"] = config["BuildDesc"]
config["tequilaDevice"] = config["DeviceName"]
override_config(config)
append_additional_system_props(args)
append_additional_vendor_props(args)
append_additional_product_props(args)
return args
def generate_common_build_props(args):
print("####################################")
print("# from generate_common_build_props")
print("# These properties identify this partition image.")
print("####################################")
config = args.config
partition = args.partition
if partition == "system":
print(f"ro.product.{partition}.brand={config['SystemBrand']}")
print(f"ro.product.{partition}.device={config['SystemDevice']}")
print(f"ro.product.{partition}.manufacturer={config['SystemManufacturer']}")
print(f"ro.product.{partition}.model={config['SystemModel']}")
print(f"ro.product.{partition}.name={config['SystemName']}")
else:
print(f"ro.product.{partition}.brand={config['ProductBrand']}")
print(f"ro.product.{partition}.device={config['DeviceName']}")
print(f"ro.product.{partition}.manufacturer={config['ProductManufacturer']}")
print(f"ro.product.{partition}.model={config['ProductModel']}")
print(f"ro.product.{partition}.name={config['DeviceProduct']}")
if partition != "system":
if config["ProductModelForAttestation"]:
print(f"ro.product.model_for_attestation={config['ProductModelForAttestation']}")
if config["ProductBrandForAttestation"]:
print(f"ro.product.brand_for_attestation={config['ProductBrandForAttestation']}")
if config["ProductNameForAttestation"]:
print(f"ro.product.name_for_attestation={config['ProductNameForAttestation']}")
if config["ProductDeviceForAttestation"]:
print(f"ro.product.device_for_attestation={config['ProductDeviceForAttestation']}")
if config["ProductManufacturerForAttestation"]:
print(f"ro.product.manufacturer_for_attestation={config['ProductManufacturerForAttestation']}")
if config["ZygoteForce64"]:
if partition == "vendor":
print(f"ro.{partition}.product.cpu.abilist={config['DeviceAbiList64']}")
print(f"ro.{partition}.product.cpu.abilist32=")
print(f"ro.{partition}.product.cpu.abilist64={config['DeviceAbiList64']}")
else:
if partition == "system" or partition == "vendor" or partition == "odm":
print(f"ro.{partition}.product.cpu.abilist={config['DeviceAbiList']}")
print(f"ro.{partition}.product.cpu.abilist32={config['DeviceAbiList32']}")
print(f"ro.{partition}.product.cpu.abilist64={config['DeviceAbiList64']}")
print(f"ro.{partition}.build.date={config['Date']}")
print(f"ro.{partition}.build.date.utc={config['DateUtc']}")
# Allow optional assignments for ARC forward-declarations (b/249168657)
# TODO: Remove any tag-related inconsistencies once the goals from
# go/arc-android-sigprop-changes have been achieved.
print(f"ro.{partition}.build.fingerprint?={config['BuildFingerprint']}")
print(f"ro.{partition}.build.id?={config['BuildId']}")
print(f"ro.{partition}.build.tags?={config['BuildVersionTags']}")
print(f"ro.{partition}.build.type={config['BuildVariant']}")
print(f"ro.{partition}.build.version.incremental={config['BuildNumber']}")
print(f"ro.{partition}.build.version.release={config['Platform_version_last_stable']}")
print(f"ro.{partition}.build.version.release_or_codename={config['Platform_version_name']}")
print(f"ro.{partition}.build.version.sdk={config['Platform_sdk_version']}")
def generate_build_info(args):
print()
print("####################################")
print("# from gen_build_prop.py:generate_build_info")
print("####################################")
print("# begin build properties")
config = args.config
build_flags = config["BuildFlags"]
print(f"ro.build.fingerprint?={config['BuildFingerprint']}")
# The ro.build.id will be set dynamically by init, by appending the unique vbmeta digest.
if config["BoardUseVbmetaDigestInFingerprint"]:
print(f"ro.build.legacy.id={config['BuildId']}")
else:
print(f"ro.build.id?={config['BuildId']}")
# ro.build.display.id is shown under Settings -> About Phone
if config["BuildVariant"] == "user":
# User builds should show:
# release build number or branch.buld_number non-release builds
# Dev. branches should have DISPLAY_BUILD_NUMBER set
if config["DisplayBuildNumber"]:
print(f"ro.build.display.id?={config['BuildId']}.{config['BuildNumber']} {config['BuildKeys']}")
else:
print(f"ro.build.display.id?={config['BuildId']} {config['BuildKeys']}")
else:
# Non-user builds should show detailed build information (See build desc above)
print(f"ro.build.display.id?={config['tequilaDesc']}")
print(f"ro.build.version.incremental={config['BuildNumber']}")
print(f"ro.build.version.sdk={config['Platform_sdk_version']}")
print(f"ro.build.version.preview_sdk={config['Platform_preview_sdk_version']}")
print(f"ro.build.version.preview_sdk_fingerprint={config['PlatformPreviewSdkFingerprint']}")
print(f"ro.build.version.codename={config['Platform_sdk_codename']}")
print(f"ro.build.version.all_codenames={','.join(config['Platform_version_active_codenames'])}")
print(f"ro.build.version.known_codenames={config['Platform_version_known_codenames']}")
print(f"ro.build.version.release={config['Platform_version_last_stable']}")
print(f"ro.build.version.release_or_codename={config['Platform_version_name']}")
print(f"ro.build.version.release_or_preview_display={config['Platform_display_version_name']}")
print(f"ro.build.version.security_patch={config['Platform_security_patch']}")
print(f"ro.build.version.base_os={config['Platform_base_os']}")
print(f"ro.build.version.min_supported_target_sdk={build_flags['RELEASE_PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION']}")
print(f"ro.build.date={config['Date']}")
print(f"ro.build.date.utc={config['DateUtc']}")
print(f"ro.build.type={config['BuildVariant']}")
print(f"ro.build.user={config['BuildUsername']}")
print(f"ro.build.host={config['BuildHostname']}")
# TODO: Remove any tag-related optional property declarations once the goals
# from go/arc-android-sigprop-changes have been achieved.
print(f"ro.build.tags?={config['BuildVersionTags']}")
# ro.build.flavor are used only by the test harness to distinguish builds.
# Only add _asan for a sanitized build if it isn't already a part of the
# flavor (via a dedicated lunch config for example).
print(f"ro.build.flavor={config['BuildFlavor']}")
print(f"ro.tequila.device={config['tequilaDevice']}")
# These values are deprecated, use "ro.product.cpu.abilist"
# instead (see below).
print(f"# ro.product.cpu.abi and ro.product.cpu.abi2 are obsolete,")
print(f"# use ro.product.cpu.abilist instead.")
print(f"ro.product.cpu.abi={config['DeviceAbi'][0]}")
if len(config["DeviceAbi"]) > 1:
print(f"ro.product.cpu.abi2={config['DeviceAbi'][1]}")
if config["ProductLocales"]:
print(f"ro.product.locale={config['ProductLocales'][0]}")
print(f"ro.wifi.channels={' '.join(config['ProductDefaultWifiChannels'])}")
print(f"# ro.build.product is obsolete; use ro.product.device")
print(f"ro.build.product={config['DeviceName']}")
print(f"# Do not try to parse description or thumbprint")
print(f"ro.build.description?={config['BuildDesc']}")
if "BuildThumbprint" in config:
print(f"ro.build.thumbprint={config['BuildThumbprint']}")
print(f"# end build properties")
def write_properties_from_file(file):
print()
print("####################################")
print(f"# from {file.name}")
print("####################################")
print(file.read(), end="")
def write_properties_from_variable(name, props, build_broken_dup_sysprop):
print()
print("####################################")
print(f"# from variable {name}")
print("####################################")
# Implement the legacy behavior when BUILD_BROKEN_DUP_SYSPROP is on.
# Optional assignments are all converted to normal assignments and
# when their duplicates the first one wins.
if build_broken_dup_sysprop:
processed_props = []
seen_props = set()
for line in props:
line = line.replace("?=", "=")
key, value = line.split("=", 1)
if key in seen_props:
continue
seen_props.add(key)
processed_props.append(line)
props = processed_props
for line in props:
print(line)
def append_additional_system_props(args):
props = []
config = args.config
# Add the product-defined properties to the build properties.
if not config["PropertySplitEnabled"] or not config["VendorImageFileSystemType"]:
if "PRODUCT_PROPERTY_OVERRIDES" in config:
props += config["PRODUCT_PROPERTY_OVERRIDES"]
props.append(f"ro.treble.enabled={'true' if config['FullTreble'] else 'false'}")
# Set ro.llndk.api_level to show the maximum vendor API level that the LLNDK
# in the system partition supports.
if config["VendorApiLevel"]:
props.append(f"ro.llndk.api_level={config['VendorApiLevel']}")
# Sets ro.actionable_compatible_property.enabled to know on runtime whether
# the allowed list of actionable compatible properties is enabled or not.
props.append("ro.actionable_compatible_property.enabled=true")
# Enable core platform API violation warnings on userdebug and eng builds.
if config["BuildVariant"] != "user":
props.append("persist.debug.dalvik.vm.core_platform_api_policy=just-warn")
# Define ro.sanitize.<name> properties for all global sanitizers.
for sanitize_target in config["SanitizeDevice"]:
props.append(f"ro.sanitize.{sanitize_target}=true")
# Sets the default value of ro.postinstall.fstab.prefix to /system.
# Device board config should override the value to /product when needed by:
#
# PRODUCT_PRODUCT_PROPERTIES += ro.postinstall.fstab.prefix=/product
#
# It then uses ${ro.postinstall.fstab.prefix}/etc/fstab.postinstall to
# mount system_other partition.
props.append("ro.postinstall.fstab.prefix=/system")
enable_target_debugging = True
enable_dalvik_lock_contention_logging = True
if config["BuildVariant"] == "user" or config["BuildVariant"] == "userdebug":
# Target is secure in user builds.
props.append("ro.secure=1")
props.append("security.perf_harden=1")
if config["BuildVariant"] == "user":
# Disable debugging in plain user builds.
props.append("ro.adb.secure=1")
enable_target_debugging = False
enable_dalvik_lock_contention_logging = False
else:
# Disable debugging in userdebug builds if PRODUCT_NOT_DEBUGGABLE_IN_USERDEBUG
# is set.
if config["ProductNotDebuggableInUserdebug"]:
enable_target_debugging = False
# Disallow mock locations by default for user builds
props.append("ro.allow.mock.location=0")
else:
# Turn on checkjni for non-user builds.
props.append("ro.kernel.android.checkjni=1")
# Set device insecure for non-user builds.
props.append("ro.secure=0")
# Allow mock locations by default for non user builds
props.append("ro.allow.mock.location=1")
if enable_dalvik_lock_contention_logging:
# Enable Dalvik lock contention logging.
props.append("dalvik.vm.lockprof.threshold=500")
if enable_target_debugging:
# Target is more debuggable and adbd is on by default
props.append("ro.debuggable=1")
else:
# Target is less debuggable and adbd is off by default
props.append("ro.debuggable=0")
if config["BuildVariant"] == "eng":
if "ro.setupwizard.mode=ENABLED" in props:
# Don't require the setup wizard on eng builds
props = list(filter(lambda x: not x.startswith("ro.setupwizard.mode="), props))
props.append("ro.setupwizard.mode=OPTIONAL")
if not config["SdkBuild"]:
# To speedup startup of non-preopted builds, don't verify or compile the boot image.
props.append("dalvik.vm.image-dex2oat-filter=extract")
# b/323566535
props.append("init.svc_debug.no_fatal.zygote=true")
if config["SdkBuild"]:
props.append("xmpp.auto-presence=true")
props.append("ro.config.nocheckin=yes")
props.append("net.bt.name=Android")
# This property is set by flashing debug boot image, so default to false.
props.append("ro.force.debuggable=0")
config["ADDITIONAL_SYSTEM_PROPERTIES"] = props
def append_additional_vendor_props(args):
props = []
config = args.config
build_flags = config["BuildFlags"]
# Add cpu properties for bionic and ART.
props.append(f"ro.bionic.arch={config['DeviceArch']}")
props.append(f"ro.bionic.cpu_variant={config['DeviceCpuVariantRuntime']}")
props.append(f"ro.bionic.2nd_arch={config['DeviceSecondaryArch']}")
props.append(f"ro.bionic.2nd_cpu_variant={config['DeviceSecondaryCpuVariantRuntime']}")
props.append(f"persist.sys.dalvik.vm.lib.2=libart.so")
props.append(f"dalvik.vm.isa.{config['DeviceArch']}.variant={config['Dex2oatTargetCpuVariantRuntime']}")
if config["Dex2oatTargetInstructionSetFeatures"]:
props.append(f"dalvik.vm.isa.{config['DeviceArch']}.features={config['Dex2oatTargetInstructionSetFeatures']}")
if config["DeviceSecondaryArch"]:
props.append(f"dalvik.vm.isa.{config['DeviceSecondaryArch']}.variant={config['SecondaryDex2oatCpuVariantRuntime']}")
if config["SecondaryDex2oatInstructionSetFeatures"]:
props.append(f"dalvik.vm.isa.{config['DeviceSecondaryArch']}.features={config['SecondaryDex2oatInstructionSetFeatures']}")
# Although these variables are prefixed with TARGET_RECOVERY_, they are also needed under charger
# mode (via libminui).
if config["RecoveryDefaultRotation"]:
props.append(f"ro.minui.default_rotation={config['RecoveryDefaultRotation']}")
if config["RecoveryDefaultTouchRotation"]:
props.append(f"ro.minui.default_touch_rotation={config['RecoveryDefaultTouchRotation']}")
if config["RecoveryOverscanPercent"]:
props.append(f"ro.minui.overscan_percent={config['RecoveryOverscanPercent']}")
if config["RecoveryPixelFormat"]:
props.append(f"ro.minui.pixel_format={config['RecoveryPixelFormat']}")
if "UseDynamicPartitions" in config:
props.append(f"ro.boot.dynamic_partitions={'true' if config['UseDynamicPartitions'] else 'false'}")
if "RetrofitDynamicPartitions" in config:
props.append(f"ro.boot.dynamic_partitions_retrofit={'true' if config['RetrofitDynamicPartitions'] else 'false'}")
if config["ShippingApiLevel"]:
props.append(f"ro.product.first_api_level={config['ShippingApiLevel']}")
if config["ShippingVendorApiLevel"]:
props.append(f"ro.vendor.api_level={config['ShippingVendorApiLevel']}")
if config["BuildVariant"] != "user" and config["BuildDebugfsRestrictionsEnabled"]:
props.append(f"ro.product.debugfs_restrictions.enabled=true")
# Vendors with GRF must define BOARD_SHIPPING_API_LEVEL for the vendor API level.
# This must not be defined for the non-GRF devices.
# The values of the GRF properties will be verified by post_process_props.py
if config["BoardShippingApiLevel"]:
props.append(f"ro.board.first_api_level={config['BoardShippingApiLevel']}")
# Build system set BOARD_API_LEVEL to show the api level of the vendor API surface.
# This must not be altered outside of build system.
if config["VendorApiLevel"]:
props.append(f"ro.board.api_level={config['VendorApiLevel']}")
# RELEASE_BOARD_API_LEVEL_FROZEN is true when the vendor API surface is frozen.
if build_flags["RELEASE_BOARD_API_LEVEL_FROZEN"]:
props.append(f"ro.board.api_frozen=true")
# Set build prop. This prop is read by ota_from_target_files when generating OTA,
# to decide if VABC should be disabled.
if config["DontUseVabcOta"]:
props.append(f"ro.vendor.build.dont_use_vabc=true")
# Set the flag in vendor. So VTS would know if the new fingerprint format is in use when
# the system images are replaced by GSI.
if config["BoardUseVbmetaDigestInFingerprint"]:
props.append(f"ro.vendor.build.fingerprint_has_digest=1")
props.append(f"ro.vendor.build.security_patch={config['VendorSecurityPatch']}")
props.append(f"ro.product.board={config['BootloaderBoardName']}")
props.append(f"ro.board.platform={config['BoardPlatform']}")
props.append(f"ro.hwui.use_vulkan={'true' if config['UsesVulkan'] else 'false'}")
if config["ScreenDensity"]:
props.append(f"ro.sf.lcd_density={config['ScreenDensity']}")
if "AbOtaUpdater" in config:
props.append(f"ro.build.ab_update={'true' if config['AbOtaUpdater'] else 'false'}")
if config["AbOtaUpdater"]:
props.append(f"ro.vendor.build.ab_ota_partitions={config['AbOtaPartitions']}")
config["ADDITIONAL_VENDOR_PROPERTIES"] = props
def append_additional_product_props(args):
props = []
config = args.config
# Add the system server compiler filter if they are specified for the product.
if config["SystemServerCompilerFilter"]:
props.append(f"dalvik.vm.systemservercompilerfilter={config['SystemServerCompilerFilter']}")
# Add the 16K developer args if it is defined for the product.
props.append(f"ro.product.build.16k_page.enabled={'true' if config['Product16KDeveloperOption'] else 'false'}")
props.append(f"ro.product.page_size={16384 if config['TargetBoots16K'] else 4096}")
props.append(f"ro.build.characteristics={config['AAPTCharacteristics']}")
if "AbOtaUpdater" in config and config["AbOtaUpdater"]:
props.append(f"ro.product.ab_ota_partitions={config['AbOtaPartitions']}")
# Set this property for VTS to skip large page size tests on unsupported devices.
props.append(f"ro.product.cpu.pagesize.max={config['DeviceMaxPageSizeSupported']}")
if config["NoBionicPageSizeMacro"]:
props.append(f"ro.product.build.no_bionic_page_size_macro=true")
# This is a temporary system property that controls the ART module. The plan is
# to remove it by Aug 2025, at which time Mainline updates of the ART module
# will ignore it as well.
# If the value is "default", it will be mangled by post_process_props.py.
props.append(f"ro.dalvik.vm.enable_uffd_gc={config['EnableUffdGc']}")
config["ADDITIONAL_PRODUCT_PROPERTIES"] = props
def build_system_prop(args):
config = args.config
# Order matters here. When there are duplicates, the last one wins.
# TODO(b/117892318): don't allow duplicates so that the ordering doesn't matter
variables = [
"ADDITIONAL_SYSTEM_PROPERTIES",
"PRODUCT_SYSTEM_PROPERTIES",
# TODO(b/117892318): deprecate this
"PRODUCT_SYSTEM_DEFAULT_PROPERTIES",
]
if not config["PropertySplitEnabled"]:
variables += [
"ADDITIONAL_VENDOR_PROPERTIES",
"PRODUCT_VENDOR_PROPERTIES",
]
build_prop(args, gen_build_info=True, gen_common_build_props=True, variables=variables)
def build_system_ext_prop(args):
config = args.config
# Order matters here. When there are duplicates, the last one wins.
# TODO(b/117892318): don't allow duplicates so that the ordering doesn't matter
variables = ["PRODUCT_SYSTEM_EXT_PROPERTIES"]
build_prop(args, gen_build_info=False, gen_common_build_props=True, variables=variables)
'''
def build_vendor_prop(args):
config = args.config
# Order matters here. When there are duplicates, the last one wins.
# TODO(b/117892318): don't allow duplicates so that the ordering doesn't matter
variables = []
if config["PropertySplitEnabled"]:
variables += [
"ADDITIONAL_VENDOR_PROPERTIES",
"PRODUCT_VENDOR_PROPERTIES",
# TODO(b/117892318): deprecate this
"PRODUCT_DEFAULT_PROPERTY_OVERRIDES",
"PRODUCT_PROPERTY_OVERRIDES",
]
build_prop(args, gen_build_info=False, gen_common_build_props=True, variables=variables)
'''
def build_product_prop(args):
config = args.config
# Order matters here. When there are duplicates, the last one wins.
# TODO(b/117892318): don't allow duplicates so that the ordering doesn't matter
variables = [
"ADDITIONAL_PRODUCT_PROPERTIES",
"PRODUCT_PRODUCT_PROPERTIES",
]
gen_common_build_props = True
# Skip common /product properties generation if device released before R and
# has no product partition. This is the first part of the check.
if config["Shipping_api_level"] and int(config["Shipping_api_level"]) < 30:
gen_common_build_props = False
# The second part of the check - always generate common properties for the
# devices with product partition regardless of shipping level.
if config["UsesProductImage"]:
gen_common_build_props = True
build_prop(args, gen_build_info=False, gen_common_build_props=True, variables=variables)
if config["OemProperties"]:
print("####################################")
print("# PRODUCT_OEM_PROPERTIES")
print("####################################")
for prop in config["OemProperties"]:
print(f"import /oem/oem.prop {prop}")
def build_odm_prop(args):
variables = ["ADDITIONAL_ODM_PROPERTIES", "PRODUCT_ODM_PROPERTIES"]
build_prop(args, gen_build_info=False, gen_common_build_props=True, variables=variables)
def build_prop(args, gen_build_info, gen_common_build_props, variables):
config = args.config
if gen_common_build_props:
generate_common_build_props(args)
if gen_build_info:
generate_build_info(args)
for prop_file in args.prop_files:
write_properties_from_file(prop_file)
for variable in variables:
if variable in config:
write_properties_from_variable(variable, config[variable], args.build_broken_dup_sysprop)
def main():
args = parse_args()
with contextlib.redirect_stdout(args.out):
match args.partition:
case "system":
build_system_prop(args)
case "system_ext":
build_system_ext_prop(args)
case "odm":
build_odm_prop(args)
case "product":
build_product_prop(args)
# case "vendor": # NOT IMPLEMENTED
# build_vendor_prop(args)
case _:
sys.exit(f"not supported partition {args.partition}")
if __name__ == "__main__":
main()

62
scripts/merge_json.py Normal file
View file

@ -0,0 +1,62 @@
#!/usr/bin/env python
#
# Copyright 2024 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""A tool for merging two or more JSON files."""
import argparse
import logging
import json
import sys
def parse_args():
"""Parse commandline arguments."""
parser = argparse.ArgumentParser()
parser.add_argument("output", help="output JSON file", type=argparse.FileType("w"))
parser.add_argument("input", help="input JSON files", nargs="+", type=argparse.FileType("r"))
return parser.parse_args()
def main():
"""Program entry point."""
args = parse_args()
merged_dict = {}
has_error = False
logger = logging.getLogger(__name__)
for json_file in args.input:
try:
data = json.load(json_file)
except json.JSONDecodeError as e:
logger.error(f"Error parsing JSON in file: {json_file.name}. Reason: {e}")
has_error = True
continue
for key, value in data.items():
if key not in merged_dict:
merged_dict[key] = value
elif merged_dict[key] == value:
logger.warning(f"Duplicate key '{key}' with identical values found.")
else:
logger.error(f"Conflicting values for key '{key}': {merged_dict[key]} != {value}")
has_error = True
if has_error:
sys.exit(1)
json.dump(merged_dict, args.output)
if __name__ == "__main__":
main()

View file

@ -129,12 +129,12 @@ func (c *hostFakeSingleton) GenerateBuildActions(ctx android.SingletonContext) {
if !seen[outFile] {
seen[outFile] = true
outputs = append(outputs, WriteStringToFileRule(ctx, "", outFile))
jsonData = append(jsonData, hostSnapshotFakeJsonFlags{*hostJsonDesc(module), false})
jsonData = append(jsonData, hostSnapshotFakeJsonFlags{*hostJsonDesc(ctx, module), false})
}
}
})
// Update any module prebuilt information
for idx, _ := range jsonData {
for idx := range jsonData {
if _, ok := prebuilts[jsonData[idx].ModuleName]; ok {
// Prebuilt exists for this module
jsonData[idx].Prebuilt = true

View file

@ -101,7 +101,7 @@ func (f *hostSnapshot) CreateMetaData(ctx android.ModuleContext, fileName string
// Create JSON file based on the direct dependencies
ctx.VisitDirectDeps(func(dep android.Module) {
desc := hostJsonDesc(dep)
desc := hostJsonDesc(ctx, dep)
if desc != nil {
jsonData = append(jsonData, *desc)
}
@ -209,7 +209,7 @@ func hostRelativePathString(m android.Module) string {
// Create JSON description for given module, only create descriptions for binary modules
// and rust_proc_macro modules which provide a valid HostToolPath
func hostJsonDesc(m android.Module) *SnapshotJsonFlags {
func hostJsonDesc(ctx android.ConfigAndErrorContext, m android.Module) *SnapshotJsonFlags {
path := hostToolPath(m)
relPath := hostRelativePathString(m)
procMacro := false
@ -226,7 +226,7 @@ func hostJsonDesc(m android.Module) *SnapshotJsonFlags {
props := &SnapshotJsonFlags{
ModuleStemName: moduleStem,
Filename: path.String(),
Required: append(m.HostRequiredModuleNames(), m.RequiredModuleNames()...),
Required: append(m.HostRequiredModuleNames(), m.RequiredModuleNames(ctx)...),
RelativeInstallPath: relPath,
RustProcMacro: procMacro,
CrateName: crateName,

View file

@ -79,7 +79,7 @@ func SetupOutDir(ctx Context, config Config) {
if username, ok = config.environ.Get("BUILD_USERNAME"); !ok {
ctx.Fatalln("Missing BUILD_USERNAME")
}
buildNumber = fmt.Sprintf("eng.%.6s.00000000.000000", username)
buildNumber = fmt.Sprintf("eng.%.6s", username)
writeValueIfChanged(ctx, config, config.OutDir(), "file_name_tag.txt", username)
}
// Write the build number to a file so it can be read back in

View file

@ -125,11 +125,13 @@ func installClean(ctx Context, config Config) {
hostCommonOut("obj/PACKAGING"),
productOut("*.img"),
productOut("*.zip"),
productOut("*.zip.sha256sum"),
productOut("android-info.txt"),
productOut("misc_info.txt"),
productOut("apex"),
productOut("kernel"),
productOut("kernel-*"),
productOut("recovery_kernel"),
productOut("data"),
productOut("skin"),
productOut("obj/NOTICE_FILES"),
@ -160,7 +162,8 @@ func installClean(ctx Context, config Config) {
productOut("odm_dlkm"),
productOut("sysloader"),
productOut("testcases"),
productOut("symbols"))
productOut("symbols"),
productOut("install"))
}
// Since products and build variants (unfortunately) shared the same

View file

@ -1488,6 +1488,15 @@ func (c *configImpl) SoongVarsFile() string {
}
}
func (c *configImpl) SoongExtraVarsFile() string {
targetProduct, err := c.TargetProductOrErr()
if err != nil {
return filepath.Join(c.SoongOutDir(), "soong.extra.variables")
} else {
return filepath.Join(c.SoongOutDir(), "soong."+targetProduct+".extra.variables")
}
}
func (c *configImpl) SoongNinjaFile() string {
targetProduct, err := c.TargetProductOrErr()
if err != nil {

View file

@ -147,6 +147,7 @@ func dumpMakeVars(ctx Context, config Config, goals, vars []string, write_soong_
var BannerVars = []string{
"PLATFORM_VERSION_CODENAME",
"PLATFORM_VERSION",
"TEQUILA_VERSION",
"PRODUCT_SOURCE_ROOT_DIRS",
"TARGET_PRODUCT",
"TARGET_BUILD_VARIANT",
@ -164,6 +165,8 @@ var BannerVars = []string{
"BUILD_ID",
"OUT_DIR",
"SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE",
"GMS_MAKEFILE",
"PRODUCT_SOONG_NAMESPACES",
}
func Banner(make_vars map[string]string) string {
@ -242,7 +245,6 @@ func runMakeProductConfig(ctx Context, config Config) {
"HOST_CROSS_ARCH",
"HOST_CROSS_2ND_ARCH",
"HOST_BUILD_TYPE",
"PRODUCT_SOONG_NAMESPACES",
"DEFAULT_WARNING_BUILD_MODULE_TYPES",
"DEFAULT_ERROR_BUILD_MODULE_TYPES",

View file

@ -228,6 +228,13 @@ func (c *Cmd) wrapSandbox() {
sandboxArgs = append(sandboxArgs, "-N")
}
if ccacheExec := os.Getenv("CCACHE_EXEC"); ccacheExec != "" {
bytes, err := exec.Command(ccacheExec, "-k", "cache_dir").Output()
if err == nil {
sandboxArgs = append(sandboxArgs, "-B", strings.TrimSpace(string(bytes)))
}
}
// Stop nsjail from parsing arguments
sandboxArgs = append(sandboxArgs, "--")

View file

@ -694,6 +694,7 @@ func runSoong(ctx Context, config Config) {
}
}
distFile(ctx, config, config.SoongVarsFile(), "soong")
distFile(ctx, config, config.SoongExtraVarsFile(), "soong")
if !config.SkipKati() {
distGzipFile(ctx, config, config.SoongAndroidMk(), "soong")

View file

@ -64,7 +64,8 @@ func testForDanglingRules(ctx Context, config Config) {
outDir := config.OutDir()
modulePathsDir := filepath.Join(outDir, ".module_paths")
rawFilesDir := filepath.Join(outDir, "soong", "raw")
variablesFilePath := filepath.Join(outDir, "soong", "soong.variables")
variablesFilePath := config.SoongVarsFile()
extraVariablesFilePath := config.SoongExtraVarsFile()
// dexpreopt.config is an input to the soong_docs action, which runs the
// soong_build primary builder. However, this file is created from $(shell)
@ -95,6 +96,7 @@ func testForDanglingRules(ctx Context, config Config) {
if strings.HasPrefix(line, modulePathsDir) ||
strings.HasPrefix(line, rawFilesDir) ||
line == variablesFilePath ||
line == extraVariablesFilePath ||
line == dexpreoptConfigFilePath ||
line == buildDatetimeFilePath ||
line == bpglob ||