Merge "Add exemption for test_framework-apexd and test_service-apexd jars"
diff --git a/Android.bp b/Android.bp
index b5ddaa4..0e8d86d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -127,3 +127,7 @@
srcs: ["cc/config/global.go"],
out: ["clang-prebuilts-version.txt"],
}
+
+dexpreopt_systemserver_check {
+ name: "dexpreopt_systemserver_check",
+}
diff --git a/android/androidmk.go b/android/androidmk.go
index feaef1f..b6b04a6 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -29,6 +29,7 @@
"os"
"path/filepath"
"reflect"
+ "runtime"
"sort"
"strings"
@@ -477,8 +478,9 @@
func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod blueprint.Module) {
a.EntryMap = make(map[string][]string)
- amod := mod.(Module).base()
- name := amod.BaseModuleName()
+ amod := mod.(Module)
+ base := amod.base()
+ name := base.BaseModuleName()
if a.OverrideName != "" {
name = a.OverrideName
}
@@ -486,9 +488,9 @@
if a.Include == "" {
a.Include = "$(BUILD_PREBUILT)"
}
- a.Required = append(a.Required, mod.(Module).RequiredModuleNames()...)
- a.Host_required = append(a.Host_required, mod.(Module).HostRequiredModuleNames()...)
- a.Target_required = append(a.Target_required, mod.(Module).TargetRequiredModuleNames()...)
+ a.Required = append(a.Required, amod.RequiredModuleNames()...)
+ a.Host_required = append(a.Host_required, amod.HostRequiredModuleNames()...)
+ a.Target_required = append(a.Target_required, amod.TargetRequiredModuleNames()...)
for _, distString := range a.GetDistForGoals(mod) {
fmt.Fprintf(&a.header, distString)
@@ -499,14 +501,14 @@
// Collect make variable assignment entries.
a.SetString("LOCAL_PATH", ctx.ModuleDir(mod))
a.SetString("LOCAL_MODULE", name+a.SubName)
- a.AddStrings("LOCAL_LICENSE_KINDS", amod.commonProperties.Effective_license_kinds...)
- a.AddStrings("LOCAL_LICENSE_CONDITIONS", amod.commonProperties.Effective_license_conditions...)
- a.AddStrings("LOCAL_NOTICE_FILE", amod.commonProperties.Effective_license_text.Strings()...)
+ a.AddStrings("LOCAL_LICENSE_KINDS", base.commonProperties.Effective_license_kinds...)
+ a.AddStrings("LOCAL_LICENSE_CONDITIONS", base.commonProperties.Effective_license_conditions...)
+ a.AddStrings("LOCAL_NOTICE_FILE", base.commonProperties.Effective_license_text.Strings()...)
// TODO(b/151177513): Does this code need to set LOCAL_MODULE_IS_CONTAINER ?
- if amod.commonProperties.Effective_package_name != nil {
- a.SetString("LOCAL_LICENSE_PACKAGE_NAME", *amod.commonProperties.Effective_package_name)
- } else if len(amod.commonProperties.Effective_licenses) > 0 {
- a.SetString("LOCAL_LICENSE_PACKAGE_NAME", strings.Join(amod.commonProperties.Effective_licenses, " "))
+ if base.commonProperties.Effective_package_name != nil {
+ a.SetString("LOCAL_LICENSE_PACKAGE_NAME", *base.commonProperties.Effective_package_name)
+ } else if len(base.commonProperties.Effective_licenses) > 0 {
+ a.SetString("LOCAL_LICENSE_PACKAGE_NAME", strings.Join(base.commonProperties.Effective_licenses, " "))
}
a.SetString("LOCAL_MODULE_CLASS", a.Class)
a.SetString("LOCAL_PREBUILT_MODULE_FILE", a.OutputFile.String())
@@ -514,31 +516,41 @@
a.AddStrings("LOCAL_HOST_REQUIRED_MODULES", a.Host_required...)
a.AddStrings("LOCAL_TARGET_REQUIRED_MODULES", a.Target_required...)
+ // If the install rule was generated by Soong tell Make about it.
+ if amod.InstallBypassMake() && len(base.katiInstalls) > 0 {
+ // Assume the primary install file is last since it probably needs to depend on any other
+ // installed files. If that is not the case we can add a method to specify the primary
+ // installed file.
+ a.SetPath("LOCAL_SOONG_INSTALLED_MODULE", base.katiInstalls[len(base.katiInstalls)-1].to)
+ a.SetString("LOCAL_SOONG_INSTALL_PAIRS", base.katiInstalls.BuiltInstalled())
+ a.SetPaths("LOCAL_SOONG_INSTALL_SYMLINKS", base.katiSymlinks.InstallPaths().Paths())
+ }
+
if am, ok := mod.(ApexModule); ok {
a.SetBoolIfTrue("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", am.NotAvailableForPlatform())
}
- archStr := amod.Arch().ArchType.String()
+ archStr := base.Arch().ArchType.String()
host := false
- switch amod.Os().Class {
+ switch base.Os().Class {
case Host:
- if amod.Target().HostCross {
+ if base.Target().HostCross {
// Make cannot identify LOCAL_MODULE_HOST_CROSS_ARCH:= common.
- if amod.Arch().ArchType != Common {
+ if base.Arch().ArchType != Common {
a.SetString("LOCAL_MODULE_HOST_CROSS_ARCH", archStr)
}
} else {
// Make cannot identify LOCAL_MODULE_HOST_ARCH:= common.
- if amod.Arch().ArchType != Common {
+ if base.Arch().ArchType != Common {
a.SetString("LOCAL_MODULE_HOST_ARCH", archStr)
}
}
host = true
case Device:
// Make cannot identify LOCAL_MODULE_TARGET_ARCH:= common.
- if amod.Arch().ArchType != Common {
- if amod.Target().NativeBridge {
- hostArchStr := amod.Target().NativeBridgeHostArchName
+ if base.Arch().ArchType != Common {
+ if base.Target().NativeBridge {
+ hostArchStr := base.Target().NativeBridgeHostArchName
if hostArchStr != "" {
a.SetString("LOCAL_MODULE_TARGET_ARCH", hostArchStr)
}
@@ -547,31 +559,31 @@
}
}
- if !amod.InRamdisk() && !amod.InVendorRamdisk() {
- a.AddPaths("LOCAL_FULL_INIT_RC", amod.initRcPaths)
+ if !base.InRamdisk() && !base.InVendorRamdisk() {
+ a.AddPaths("LOCAL_FULL_INIT_RC", base.initRcPaths)
}
- if len(amod.vintfFragmentsPaths) > 0 {
- a.AddPaths("LOCAL_FULL_VINTF_FRAGMENTS", amod.vintfFragmentsPaths)
+ if len(base.vintfFragmentsPaths) > 0 {
+ a.AddPaths("LOCAL_FULL_VINTF_FRAGMENTS", base.vintfFragmentsPaths)
}
- a.SetBoolIfTrue("LOCAL_PROPRIETARY_MODULE", Bool(amod.commonProperties.Proprietary))
- if Bool(amod.commonProperties.Vendor) || Bool(amod.commonProperties.Soc_specific) {
+ a.SetBoolIfTrue("LOCAL_PROPRIETARY_MODULE", Bool(base.commonProperties.Proprietary))
+ if Bool(base.commonProperties.Vendor) || Bool(base.commonProperties.Soc_specific) {
a.SetString("LOCAL_VENDOR_MODULE", "true")
}
- a.SetBoolIfTrue("LOCAL_ODM_MODULE", Bool(amod.commonProperties.Device_specific))
- a.SetBoolIfTrue("LOCAL_PRODUCT_MODULE", Bool(amod.commonProperties.Product_specific))
- a.SetBoolIfTrue("LOCAL_SYSTEM_EXT_MODULE", Bool(amod.commonProperties.System_ext_specific))
- if amod.commonProperties.Owner != nil {
- a.SetString("LOCAL_MODULE_OWNER", *amod.commonProperties.Owner)
+ a.SetBoolIfTrue("LOCAL_ODM_MODULE", Bool(base.commonProperties.Device_specific))
+ a.SetBoolIfTrue("LOCAL_PRODUCT_MODULE", Bool(base.commonProperties.Product_specific))
+ a.SetBoolIfTrue("LOCAL_SYSTEM_EXT_MODULE", Bool(base.commonProperties.System_ext_specific))
+ if base.commonProperties.Owner != nil {
+ a.SetString("LOCAL_MODULE_OWNER", *base.commonProperties.Owner)
}
}
- if len(amod.noticeFiles) > 0 {
- a.SetString("LOCAL_NOTICE_FILE", strings.Join(amod.noticeFiles.Strings(), " "))
+ if len(base.noticeFiles) > 0 {
+ a.SetString("LOCAL_NOTICE_FILE", strings.Join(base.noticeFiles.Strings(), " "))
}
if host {
- makeOs := amod.Os().String()
- if amod.Os() == Linux || amod.Os() == LinuxBionic || amod.Os() == LinuxMusl {
+ makeOs := base.Os().String()
+ if base.Os() == Linux || base.Os() == LinuxBionic || base.Os() == LinuxMusl {
makeOs = "linux"
}
a.SetString("LOCAL_MODULE_HOST_OS", makeOs)
@@ -579,10 +591,10 @@
}
prefix := ""
- if amod.ArchSpecific() {
- switch amod.Os().Class {
+ if base.ArchSpecific() {
+ switch base.Os().Class {
case Host:
- if amod.Target().HostCross {
+ if base.Target().HostCross {
prefix = "HOST_CROSS_"
} else {
prefix = "HOST_"
@@ -592,7 +604,7 @@
}
- if amod.Arch().ArchType != ctx.Config().Targets[amod.Os()][0].Arch.ArchType {
+ if base.Arch().ArchType != ctx.Config().Targets[base.Os()][0].Arch.ArchType {
prefix = "2ND_" + prefix
}
}
@@ -902,6 +914,18 @@
return true
}
+ // On Mac, only expose host darwin modules to Make, as that's all we claim to support.
+ // In reality, some of them depend on device-built (Java) modules, so we can't disable all
+ // device modules in Soong, but we can hide them from Make (and thus the build user interface)
+ if runtime.GOOS == "darwin" && module.Os() != Darwin {
+ return true
+ }
+
+ // Only expose the primary Darwin target, as Make does not understand Darwin+Arm64
+ if module.Os() == Darwin && module.Target().HostCross {
+ return true
+ }
+
return !module.Enabled() ||
module.commonProperties.HideFromMake ||
// Make does not understand LinuxBionic
diff --git a/android/androidmk_test.go b/android/androidmk_test.go
index 8eda9b2..ecfb008 100644
--- a/android/androidmk_test.go
+++ b/android/androidmk_test.go
@@ -18,6 +18,7 @@
"fmt"
"io"
"reflect"
+ "runtime"
"strings"
"testing"
@@ -155,6 +156,11 @@
}
func TestAndroidMkSingleton_PassesUpdatedAndroidMkDataToCustomCallback(t *testing.T) {
+ if runtime.GOOS == "darwin" {
+ // Device modules are not exported on Mac, so this test doesn't work.
+ t.SkipNow()
+ }
+
bp := `
custom {
name: "foo",
diff --git a/android/arch.go b/android/arch.go
index 5e3e920..3bf54b7 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -308,7 +308,7 @@
// LinuxMusl is the OS for the Linux kernel plus the musl runtime.
LinuxMusl = newOsType("linux_musl", Host, false, X86, X86_64)
// Darwin is the OS for MacOS/Darwin host machines.
- Darwin = newOsType("darwin", Host, false, X86_64)
+ Darwin = newOsType("darwin", Host, false, Arm64, X86_64)
// LinuxBionic is the OS for the Linux kernel plus the Bionic libc runtime, but without the
// rest of Android.
LinuxBionic = newOsType("linux_bionic", Host, false, Arm64, X86_64)
@@ -696,6 +696,11 @@
for i, m := range modules {
addTargetProperties(m, targets[i], multiTargets, i == 0)
m.base().setArchProperties(mctx)
+
+ // Install support doesn't understand Darwin+Arm64
+ if os == Darwin && targets[i].HostCross {
+ m.base().commonProperties.SkipInstall = true
+ }
}
}
diff --git a/android/bazel.go b/android/bazel.go
index 91ca969..5dda655 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -253,6 +253,10 @@
"cap_names.h", // http://b/198596102, depends on _makenames, a cc_binary
"libminijail", // depends on unconverted modules: libcap
+ "getcap", // depends on unconverted modules: libcap
+ "setcap", // depends on unconverted modules: libcap
+ "minijail0", // depends on unconverted modules: libcap, libminijail
+ "drop_privs", // depends on unconverted modules: libminijail
// Tests. Handle later.
"libbionic_tests_headers_posix", // http://b/186024507, cc_library_static, sched.h, time.h not found
@@ -279,6 +283,20 @@
"libgtest_ndk_c++", // b/201816222: Requires sdk_version support.
"libgtest_main_ndk_c++", // b/201816222: Requires sdk_version support.
+
+ "abb", // depends on unconverted modules: libadbd_core, libadbd_services, libcmd, libbinder, libutils, libselinux
+ "adb", // depends on unconverted modules: bin2c_fastdeployagent, libadb_crypto, libadb_host, libadb_pairing_connection, libadb_protos, libandroidfw, libapp_processes_protos_full, libfastdeploy_host, libmdnssd, libopenscreen-discovery, libopenscreen-platform-impl, libusb, libutils, libziparchive, libzstd, AdbWinApi
+ "adbd", // depends on unconverted modules: libadb_crypto, libadb_pairing_connection, libadb_protos, libadbd, libadbd_core, libapp_processes_protos_lite, libmdnssd, libzstd, libadbd_services, libcap, libminijail, libselinux
+ "bionic_tests_zipalign", // depends on unconverted modules: libziparchive, libutils
+ "linker", // depends on unconverted modules: liblinker_debuggerd_stub, libdebuggerd_handler_fallback, libziparchive, liblinker_main, liblinker_malloc
+ "linker_reloc_bench_main", // depends on unconverted modules: liblinker_reloc_bench_*
+ "sefcontext_compile", // depends on unconverted modules: libsepol
+ "versioner", // depends on unconverted modules: libclang_cxx_host, libLLVM_host
+
+ "linkerconfig", // http://b/202876379 has arch-variant static_executable
+ "mdnsd", // http://b/202876379 has arch-variant static_executable
+
+ "acvp_modulewrapper", // disabled for android x86/x86_64
}
// Per-module denylist of cc_library modules to only generate the static
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 06712a1..3c6212e 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -48,11 +48,17 @@
StarlarkFunctionBody() string
}
+// Portion of cquery map key to describe target configuration.
+type configKey struct {
+ archType ArchType
+ osType OsType
+}
+
// Map key to describe bazel cquery requests.
type cqueryKey struct {
label string
requestType cqueryRequest
- archType ArchType
+ configKey configKey
}
// bazelHandler is the interface for a helper object related to deferring to Bazel for
@@ -72,14 +78,14 @@
// has been queued to be run later.
// Returns result files built by building the given bazel target label.
- GetOutputFiles(label string, archType ArchType) ([]string, bool)
+ GetOutputFiles(label string, cfgKey configKey) ([]string, bool)
// TODO(cparsons): Other cquery-related methods should be added here.
// Returns the results of GetOutputFiles and GetCcObjectFiles in a single query (in that order).
- GetCcInfo(label string, archType ArchType) (cquery.CcInfo, bool, error)
+ GetCcInfo(label string, cfgKey configKey) (cquery.CcInfo, bool, error)
// Returns the executable binary resultant from building together the python sources
- GetPythonBinary(label string, archType ArchType) (string, bool)
+ GetPythonBinary(label string, cfgKey configKey) (string, bool)
// ** End cquery methods
@@ -140,17 +146,17 @@
LabelToPythonBinary map[string]string
}
-func (m MockBazelContext) GetOutputFiles(label string, archType ArchType) ([]string, bool) {
+func (m MockBazelContext) GetOutputFiles(label string, cfgKey configKey) ([]string, bool) {
result, ok := m.LabelToOutputFiles[label]
return result, ok
}
-func (m MockBazelContext) GetCcInfo(label string, archType ArchType) (cquery.CcInfo, bool, error) {
+func (m MockBazelContext) GetCcInfo(label string, cfgKey configKey) (cquery.CcInfo, bool, error) {
result, ok := m.LabelToCcInfo[label]
return result, ok, nil
}
-func (m MockBazelContext) GetPythonBinary(label string, archType ArchType) (string, bool) {
+func (m MockBazelContext) GetPythonBinary(label string, cfgKey configKey) (string, bool) {
result, ok := m.LabelToPythonBinary[label]
return result, ok
}
@@ -171,8 +177,8 @@
var _ BazelContext = MockBazelContext{}
-func (bazelCtx *bazelContext) GetOutputFiles(label string, archType ArchType) ([]string, bool) {
- rawString, ok := bazelCtx.cquery(label, cquery.GetOutputFiles, archType)
+func (bazelCtx *bazelContext) GetOutputFiles(label string, cfgKey configKey) ([]string, bool) {
+ rawString, ok := bazelCtx.cquery(label, cquery.GetOutputFiles, cfgKey)
var ret []string
if ok {
bazelOutput := strings.TrimSpace(rawString)
@@ -181,8 +187,8 @@
return ret, ok
}
-func (bazelCtx *bazelContext) GetCcInfo(label string, archType ArchType) (cquery.CcInfo, bool, error) {
- result, ok := bazelCtx.cquery(label, cquery.GetCcInfo, archType)
+func (bazelCtx *bazelContext) GetCcInfo(label string, cfgKey configKey) (cquery.CcInfo, bool, error) {
+ result, ok := bazelCtx.cquery(label, cquery.GetCcInfo, cfgKey)
if !ok {
return cquery.CcInfo{}, ok, nil
}
@@ -192,8 +198,8 @@
return ret, ok, err
}
-func (bazelCtx *bazelContext) GetPythonBinary(label string, archType ArchType) (string, bool) {
- rawString, ok := bazelCtx.cquery(label, cquery.GetPythonBinary, archType)
+func (bazelCtx *bazelContext) GetPythonBinary(label string, cfgKey configKey) (string, bool) {
+ rawString, ok := bazelCtx.cquery(label, cquery.GetPythonBinary, cfgKey)
var ret string
if ok {
bazelOutput := strings.TrimSpace(rawString)
@@ -202,19 +208,15 @@
return ret, ok
}
-func (n noopBazelContext) GetOutputFiles(label string, archType ArchType) ([]string, bool) {
+func (n noopBazelContext) GetOutputFiles(label string, cfgKey configKey) ([]string, bool) {
panic("unimplemented")
}
-func (n noopBazelContext) GetCcInfo(label string, archType ArchType) (cquery.CcInfo, bool, error) {
+func (n noopBazelContext) GetCcInfo(label string, cfgKey configKey) (cquery.CcInfo, bool, error) {
panic("unimplemented")
}
-func (n noopBazelContext) GetPythonBinary(label string, archType ArchType) (string, bool) {
- panic("unimplemented")
-}
-
-func (n noopBazelContext) GetPrebuiltCcStaticLibraryFiles(label string, archType ArchType) ([]string, bool) {
+func (n noopBazelContext) GetPythonBinary(label string, cfgKey configKey) (string, bool) {
panic("unimplemented")
}
@@ -303,8 +305,8 @@
// returns (result, true). If the request is queued but no results are available,
// then returns ("", false).
func (context *bazelContext) cquery(label string, requestType cqueryRequest,
- archType ArchType) (string, bool) {
- key := cqueryKey{label, requestType, archType}
+ cfgKey configKey) (string, bool) {
+ key := cqueryKey{label, requestType, cfgKey}
if result, ok := context.results[key]; ok {
return result, true
} else {
@@ -419,7 +421,7 @@
def _config_node_transition_impl(settings, attr):
return {
- "//command_line_option:platforms": "@//build/bazel/platforms:android_%s" % attr.arch,
+ "//command_line_option:platforms": "@//build/bazel/platforms:%s_%s" % (attr.os, attr.arch),
}
_config_node_transition = transition(
@@ -437,7 +439,8 @@
implementation = _passthrough_rule_impl,
attrs = {
"arch" : attr.string(mandatory = True),
- "deps" : attr.label_list(cfg = _config_node_transition),
+ "os" : attr.string(mandatory = True),
+ "deps" : attr.label_list(cfg = _config_node_transition, allow_files = True),
"_allowlist_function_transition": attr.label(default = "@bazel_tools//tools/allowlists/function_transition_allowlist"),
},
)
@@ -488,38 +491,32 @@
configNodeFormatString := `
config_node(name = "%s",
arch = "%s",
+ os = "%s",
deps = [%s],
)
`
- commonArchFilegroupString := `
-filegroup(name = "common",
- srcs = [%s],
-)
-`
-
configNodesSection := ""
- labelsByArch := map[string][]string{}
+ labelsByConfig := map[string][]string{}
for val, _ := range context.requests {
labelString := fmt.Sprintf("\"@%s\"", val.label)
- archString := getArchString(val)
- labelsByArch[archString] = append(labelsByArch[archString], labelString)
+ configString := getConfigString(val)
+ labelsByConfig[configString] = append(labelsByConfig[configString], labelString)
}
allLabels := []string{}
- for archString, labels := range labelsByArch {
- if archString == "common" {
- // arch-less labels (e.g. filegroups) don't need a config_node
- allLabels = append(allLabels, "\":common\"")
- labelsString := strings.Join(labels, ",\n ")
- configNodesSection += fmt.Sprintf(commonArchFilegroupString, labelsString)
- } else {
- // Create a config_node, and add the config_node's label to allLabels
- allLabels = append(allLabels, fmt.Sprintf("\":%s\"", archString))
- labelsString := strings.Join(labels, ",\n ")
- configNodesSection += fmt.Sprintf(configNodeFormatString, archString, archString, labelsString)
+ for configString, labels := range labelsByConfig {
+ configTokens := strings.Split(configString, "|")
+ if len(configTokens) != 2 {
+ panic(fmt.Errorf("Unexpected config string format: %s", configString))
}
+ archString := configTokens[0]
+ osString := configTokens[1]
+ targetString := fmt.Sprintf("%s_%s", osString, archString)
+ allLabels = append(allLabels, fmt.Sprintf("\":%s\"", targetString))
+ labelsString := strings.Join(labels, ",\n ")
+ configNodesSection += fmt.Sprintf(configNodeFormatString, targetString, archString, osString, labelsString)
}
return []byte(fmt.Sprintf(formatString, configNodesSection, strings.Join(allLabels, ",\n ")))
@@ -587,11 +584,15 @@
%s
def get_arch(target):
+ # TODO(b/199363072): filegroups and file targets aren't associated with any
+ # specific platform architecture in mixed builds. This is consistent with how
+ # Soong treats filegroups, but it may not be the case with manually-written
+ # filegroup BUILD targets.
buildoptions = build_options(target)
if buildoptions == None:
# File targets do not have buildoptions. File targets aren't associated with
- # any specific platform architecture in mixed builds.
- return "common"
+ # any specific platform architecture in mixed builds, so use the host.
+ return "x86_64|linux"
platforms = build_options(target)["//command_line_option:platforms"]
if len(platforms) != 1:
# An individual configured target should have only one platform architecture.
@@ -601,10 +602,12 @@
platform_name = build_options(target)["//command_line_option:platforms"][0].name
if platform_name == "host":
return "HOST"
+ elif platform_name.startswith("linux_glibc_"):
+ return platform_name[len("linux_glibc_"):] + "|" + platform_name[:len("linux_glibc_")-1]
elif platform_name.startswith("android_"):
- return platform_name[len("android_"):]
+ return platform_name[len("android_"):] + "|" + platform_name[:len("android_")-1]
elif platform_name.startswith("linux_"):
- return platform_name[len("linux_"):]
+ return platform_name[len("linux_"):] + "|" + platform_name[:len("linux_")-1]
else:
fail("expected platform name of the form 'android_<arch>' or 'linux_<arch>', but was " + str(platforms))
return "UNKNOWN"
@@ -852,14 +855,23 @@
}
func getCqueryId(key cqueryKey) string {
- return key.label + "|" + getArchString(key)
+ return key.label + "|" + getConfigString(key)
}
-func getArchString(key cqueryKey) string {
- arch := key.archType.Name
- if len(arch) > 0 {
- return arch
- } else {
- return "x86_64"
+func getConfigString(key cqueryKey) string {
+ arch := key.configKey.archType.Name
+ if len(arch) == 0 || arch == "common" {
+ // Use host platform, which is currently hardcoded to be x86_64.
+ arch = "x86_64"
}
+ os := key.configKey.osType.Name
+ if len(os) == 0 || os == "common_os" {
+ // Use host OS, which is currently hardcoded to be linux.
+ os = "linux"
+ }
+ return arch + "|" + os
+}
+
+func GetConfigKey(ctx ModuleContext) configKey {
+ return configKey{archType: ctx.Arch().ArchType, osType: ctx.Os()}
}
diff --git a/android/bazel_handler_test.go b/android/bazel_handler_test.go
index fe66a90..ad5b63b 100644
--- a/android/bazel_handler_test.go
+++ b/android/bazel_handler_test.go
@@ -9,11 +9,11 @@
func TestRequestResultsAfterInvokeBazel(t *testing.T) {
label := "//foo:bar"
- arch := Arm64
+ cfg := configKey{Arm64, Android}
bazelContext, _ := testBazelContext(t, map[bazelCommand]string{
- bazelCommand{command: "cquery", expression: "deps(@soong_injection//mixed_builds:buildroot, 2)"}: `//foo:bar|arm64>>out/foo/bar.txt`,
+ bazelCommand{command: "cquery", expression: "deps(@soong_injection//mixed_builds:buildroot, 2)"}: `//foo:bar|arm64|android>>out/foo/bar.txt`,
})
- g, ok := bazelContext.GetOutputFiles(label, arch)
+ g, ok := bazelContext.GetOutputFiles(label, cfg)
if ok {
t.Errorf("Did not expect cquery results prior to running InvokeBazel(), but got %s", g)
}
@@ -21,7 +21,7 @@
if err != nil {
t.Fatalf("Did not expect error invoking Bazel, but got %s", err)
}
- g, ok = bazelContext.GetOutputFiles(label, arch)
+ g, ok = bazelContext.GetOutputFiles(label, cfg)
if !ok {
t.Errorf("Expected cquery results after running InvokeBazel(), but got none")
} else if w := []string{"out/foo/bar.txt"}; !reflect.DeepEqual(w, g) {
diff --git a/android/config.go b/android/config.go
index c8d7cfd..78d43c6 100644
--- a/android/config.go
+++ b/android/config.go
@@ -355,14 +355,14 @@
config.bp2buildModuleTypeConfig = map[string]bool{}
+ determineBuildOS(config)
+
return Config{config}
}
func modifyTestConfigToSupportArchMutator(testConfig Config) {
config := testConfig.config
- determineBuildOS(config)
-
config.Targets = map[OsType][]Target{
Android: []Target{
{Android, Arch{ArchType: Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}, NativeBridgeDisabled, "", "", false},
@@ -568,15 +568,17 @@
}
func (c *config) HostToolPath(ctx PathContext, tool string) Path {
- return PathForOutput(ctx, "host", c.PrebuiltOS(), "bin", tool)
+ path := pathForInstall(ctx, ctx.Config().BuildOS, ctx.Config().BuildArch, "bin", false, tool)
+ return path
}
-func (c *config) HostJNIToolPath(ctx PathContext, path string) Path {
+func (c *config) HostJNIToolPath(ctx PathContext, lib string) Path {
ext := ".so"
if runtime.GOOS == "darwin" {
ext = ".dylib"
}
- return PathForOutput(ctx, "host", c.PrebuiltOS(), "lib64", path+ext)
+ path := pathForInstall(ctx, ctx.Config().BuildOS, ctx.Config().BuildArch, "lib64", false, lib+ext)
+ return path
}
func (c *config) HostJavaToolPath(ctx PathContext, path string) Path {
@@ -1578,6 +1580,10 @@
return c.config.productVariables.SepolicyFreezeTestExtraPrebuiltDirs
}
+func (c *deviceConfig) GenerateAidlNdkPlatformBackend() bool {
+ return c.config.productVariables.GenerateAidlNdkPlatformBackend
+}
+
// The ConfiguredJarList struct provides methods for handling a list of (apex, jar) pairs.
// Such lists are used in the build system for things like bootclasspath jars or system server jars.
// The apex part is either an apex name, or a special names "platform" or "system_ext". Jar is a
diff --git a/android/filegroup.go b/android/filegroup.go
index f8f0955..a79374d 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -118,14 +118,16 @@
}
archVariant := ctx.Arch().ArchType
+ osVariant := ctx.Os()
if len(fg.Srcs()) == 1 && fg.Srcs()[0].Base() == fg.Name() {
// This will be a regular file target, not filegroup, in Bazel.
// See FilegroupBp2Build for more information.
archVariant = Common
+ osVariant = CommonOS
}
bazelCtx := ctx.Config().BazelContext
- filePaths, ok := bazelCtx.GetOutputFiles(fg.GetBazelLabel(ctx, fg), archVariant)
+ filePaths, ok := bazelCtx.GetOutputFiles(fg.GetBazelLabel(ctx, fg), configKey{archVariant, osVariant})
if !ok {
return
}
diff --git a/android/makevars.go b/android/makevars.go
index 40c0ccd..20db65a 100644
--- a/android/makevars.go
+++ b/android/makevars.go
@@ -17,6 +17,8 @@
import (
"bytes"
"fmt"
+ "path/filepath"
+ "runtime"
"sort"
"strings"
@@ -222,6 +224,9 @@
lateOutFile := absolutePath(PathForOutput(ctx,
"late"+proptools.String(ctx.Config().productVariables.Make_suffix)+".mk").String())
+ installsFile := absolutePath(PathForOutput(ctx,
+ "installs"+proptools.String(ctx.Config().productVariables.Make_suffix)+".mk").String())
+
if ctx.Failed() {
return
}
@@ -229,6 +234,8 @@
var vars []makeVarsVariable
var dists []dist
var phonies []phony
+ var katiInstalls []katiInstall
+ var katiSymlinks []katiInstall
providers := append([]makeVarsProvider(nil), makeVarsInitProviders...)
providers = append(providers, *ctx.Config().Get(singletonMakeVarsProvidersKey).(*[]makeVarsProvider)...)
@@ -258,6 +265,11 @@
phonies = append(phonies, mctx.phonies...)
dists = append(dists, mctx.dists...)
}
+
+ if m.ExportedToMake() {
+ katiInstalls = append(katiInstalls, m.base().katiInstalls...)
+ katiSymlinks = append(katiSymlinks, m.base().katiSymlinks...)
+ }
})
if ctx.Failed() {
@@ -297,6 +309,10 @@
ctx.Errorf(err.Error())
}
+ installsBytes := s.writeInstalls(katiInstalls, katiSymlinks)
+ if err := pathtools.WriteFileIfChanged(installsFile, installsBytes, 0666); err != nil {
+ ctx.Errorf(err.Error())
+ }
}
func (s *makeVarsSingleton) writeVars(vars []makeVarsVariable) []byte {
@@ -405,6 +421,84 @@
return buf.Bytes()
}
+// writeInstalls writes the list of install rules generated by Soong to a makefile. The rules
+// are exported to Make instead of written directly to the ninja file so that main.mk can add
+// the dependencies from the `required` property that are hard to resolve in Soong.
+func (s *makeVarsSingleton) writeInstalls(installs, symlinks []katiInstall) []byte {
+ buf := &bytes.Buffer{}
+
+ fmt.Fprint(buf, `# Autogenerated file
+
+# Values written by Soong to generate install rules that can be amended by Kati.
+
+
+`)
+
+ preserveSymlinksFlag := "-d"
+ if runtime.GOOS == "darwin" {
+ preserveSymlinksFlag = "-R"
+ }
+
+ for _, install := range installs {
+ // Write a rule for each install request in the form:
+ // to: from [ deps ] [ | order only deps ]
+ // cp -f -d $< $@ [ && chmod +x $@ ]
+ fmt.Fprintf(buf, "%s: %s", install.to.String(), install.from.String())
+ for _, dep := range install.implicitDeps {
+ fmt.Fprintf(buf, " %s", dep.String())
+ }
+ if len(install.orderOnlyDeps) > 0 {
+ fmt.Fprintf(buf, " |")
+ }
+ for _, dep := range install.orderOnlyDeps {
+ fmt.Fprintf(buf, " %s", dep.String())
+ }
+ fmt.Fprintln(buf)
+
+ fmt.Fprintf(buf, "\trm -f $@ && cp -f %s $< $@", preserveSymlinksFlag)
+ if install.executable {
+ fmt.Fprintf(buf, " && chmod +x $@")
+ }
+ fmt.Fprintln(buf)
+ fmt.Fprintln(buf)
+ }
+
+ for _, symlink := range symlinks {
+ fmt.Fprintf(buf, "%s:", symlink.to.String())
+ for _, dep := range symlink.implicitDeps {
+ fmt.Fprintf(buf, " %s", dep.String())
+ }
+ if symlink.from != nil || len(symlink.orderOnlyDeps) > 0 {
+ fmt.Fprintf(buf, " |")
+ }
+ if symlink.from != nil {
+ fmt.Fprintf(buf, " %s", symlink.from.String())
+ }
+ for _, dep := range symlink.orderOnlyDeps {
+ fmt.Fprintf(buf, " %s", dep.String())
+ }
+ fmt.Fprintln(buf)
+
+ fromStr := ""
+ if symlink.from != nil {
+ rel, err := filepath.Rel(filepath.Dir(symlink.to.String()), symlink.from.String())
+ if err != nil {
+ panic(fmt.Errorf("failed to find relative path for symlink from %q to %q: %w",
+ symlink.from.String(), symlink.to.String(), err))
+ }
+ fromStr = rel
+ } else {
+ fromStr = symlink.absFrom
+ }
+
+ fmt.Fprintf(buf, "\trm -f $@ && ln -sfn %s $@", fromStr)
+ fmt.Fprintln(buf)
+ fmt.Fprintln(buf)
+ }
+
+ return buf.Bytes()
+}
+
func (c *makeVarsContext) DeviceConfig() DeviceConfig {
return DeviceConfig{c.Config().deviceConfig}
}
diff --git a/android/module.go b/android/module.go
index 02706ec..3447f2b 100644
--- a/android/module.go
+++ b/android/module.go
@@ -409,7 +409,7 @@
PackageFile(installPath InstallPath, name string, srcPath Path) PackagingSpec
CheckbuildFile(srcPath Path)
- TidyFile(srcPath Path)
+ TidyFile(srcPath WritablePath)
InstallInData() bool
InstallInTestcases() bool
@@ -1190,11 +1190,14 @@
installFiles InstallPaths
installFilesDepSet *installPathsDepSet
checkbuildFiles Paths
- tidyFiles Paths
+ tidyFiles WritablePaths
packagingSpecs []PackagingSpec
packagingSpecsDepSet *packagingSpecsDepSet
noticeFiles Paths
- phonies map[string]Paths
+ // katiInstalls tracks the install rules that were created by Soong but are being exported
+ // to Make to convert to ninja rules so that Make can add additional dependencies.
+ katiInstalls katiInstalls
+ katiSymlinks katiInstalls
// The files to copy to the dist as explicitly specified in the .bp file.
distFiles TaggedDistFiles
@@ -1764,12 +1767,18 @@
func (m *ModuleBase) generateModuleTarget(ctx ModuleContext) {
var allInstalledFiles InstallPaths
var allCheckbuildFiles Paths
- var allTidyFiles Paths
+ var allTidyFiles WritablePaths
ctx.VisitAllModuleVariants(func(module Module) {
a := module.base()
allInstalledFiles = append(allInstalledFiles, a.installFiles...)
- allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
- allTidyFiles = append(allTidyFiles, a.tidyFiles...)
+ // A module's -{checkbuild,tidy} phony targets should
+ // not be created if the module is not exported to make.
+ // Those could depend on the build target and fail to compile
+ // for the current build target.
+ if !ctx.Config().KatiEnabled() || !shouldSkipAndroidMkProcessing(a) {
+ allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
+ allTidyFiles = append(allTidyFiles, a.tidyFiles...)
+ }
})
var deps Paths
@@ -1795,7 +1804,7 @@
if len(allTidyFiles) > 0 {
name := namespacePrefix + ctx.ModuleName() + "-tidy"
- ctx.Phony(name, allTidyFiles...)
+ ctx.Phony(name, allTidyFiles.Paths()...)
m.tidyTarget = PathForPhony(ctx, name)
deps = append(deps, m.tidyTarget)
}
@@ -2010,9 +2019,8 @@
m.checkbuildFiles = append(m.checkbuildFiles, ctx.checkbuildFiles...)
m.tidyFiles = append(m.tidyFiles, ctx.tidyFiles...)
m.packagingSpecs = append(m.packagingSpecs, ctx.packagingSpecs...)
- for k, v := range ctx.phonies {
- m.phonies[k] = append(m.phonies[k], v...)
- }
+ m.katiInstalls = append(m.katiInstalls, ctx.katiInstalls...)
+ m.katiSymlinks = append(m.katiSymlinks, ctx.katiSymlinks...)
} else if ctx.Config().AllowMissingDependencies() {
// If the module is not enabled it will not create any build rules, nothing will call
// ctx.GetMissingDependencies(), and blueprint will consider the missing dependencies to be unhandled
@@ -2207,16 +2215,56 @@
packagingSpecs []PackagingSpec
installFiles InstallPaths
checkbuildFiles Paths
- tidyFiles Paths
+ tidyFiles WritablePaths
module Module
phonies map[string]Paths
+ katiInstalls []katiInstall
+ katiSymlinks []katiInstall
+
// For tests
buildParams []BuildParams
ruleParams map[blueprint.Rule]blueprint.RuleParams
variables map[string]string
}
+// katiInstall stores a request from Soong to Make to create an install rule.
+type katiInstall struct {
+ from Path
+ to InstallPath
+ implicitDeps Paths
+ orderOnlyDeps Paths
+ executable bool
+
+ absFrom string
+}
+
+type katiInstalls []katiInstall
+
+// BuiltInstalled returns the katiInstalls in the form used by $(call copy-many-files) in Make, a
+// space separated list of from:to tuples.
+func (installs katiInstalls) BuiltInstalled() string {
+ sb := strings.Builder{}
+ for i, install := range installs {
+ if i != 0 {
+ sb.WriteRune(' ')
+ }
+ sb.WriteString(install.from.String())
+ sb.WriteRune(':')
+ sb.WriteString(install.to.String())
+ }
+ return sb.String()
+}
+
+// InstallPaths returns the install path of each entry.
+func (installs katiInstalls) InstallPaths() InstallPaths {
+ paths := make(InstallPaths, 0, len(installs))
+ for _, install := range installs {
+ paths = append(paths, install.to)
+ }
+ return paths
+}
+
func (m *moduleContext) ninjaError(params BuildParams, err error) (PackageContext, BuildParams) {
return pctx, BuildParams{
Rule: ErrorRule,
@@ -2848,20 +2896,33 @@
orderOnlyDeps = deps
}
- rule := Cp
- if executable {
- rule = CpExecutable
- }
+ if m.Config().KatiEnabled() && m.InstallBypassMake() {
+ // When creating the install rule in Soong but embedding in Make, write the rule to a
+ // makefile instead of directly to the ninja file so that main.mk can add the
+ // dependencies from the `required` property that are hard to resolve in Soong.
+ m.katiInstalls = append(m.katiInstalls, katiInstall{
+ from: srcPath,
+ to: fullInstallPath,
+ implicitDeps: implicitDeps,
+ orderOnlyDeps: orderOnlyDeps,
+ executable: executable,
+ })
+ } else {
+ rule := Cp
+ if executable {
+ rule = CpExecutable
+ }
- m.Build(pctx, BuildParams{
- Rule: rule,
- Description: "install " + fullInstallPath.Base(),
- Output: fullInstallPath,
- Input: srcPath,
- Implicits: implicitDeps,
- OrderOnly: orderOnlyDeps,
- Default: !m.Config().KatiEnabled(),
- })
+ m.Build(pctx, BuildParams{
+ Rule: rule,
+ Description: "install " + fullInstallPath.Base(),
+ Output: fullInstallPath,
+ Input: srcPath,
+ Implicits: implicitDeps,
+ OrderOnly: orderOnlyDeps,
+ Default: !m.Config().KatiEnabled(),
+ })
+ }
m.installFiles = append(m.installFiles, fullInstallPath)
}
@@ -2883,16 +2944,26 @@
}
if !m.skipInstall() {
- m.Build(pctx, BuildParams{
- Rule: Symlink,
- Description: "install symlink " + fullInstallPath.Base(),
- Output: fullInstallPath,
- Input: srcPath,
- Default: !m.Config().KatiEnabled(),
- Args: map[string]string{
- "fromPath": relPath,
- },
- })
+ if m.Config().KatiEnabled() && m.InstallBypassMake() {
+ // When creating the symlink rule in Soong but embedding in Make, write the rule to a
+ // makefile instead of directly to the ninja file so that main.mk can add the
+ // dependencies from the `required` property that are hard to resolve in Soong.
+ m.katiSymlinks = append(m.katiSymlinks, katiInstall{
+ from: srcPath,
+ to: fullInstallPath,
+ })
+ } else {
+ m.Build(pctx, BuildParams{
+ Rule: Symlink,
+ Description: "install symlink " + fullInstallPath.Base(),
+ Output: fullInstallPath,
+ Input: srcPath,
+ Default: !m.Config().KatiEnabled(),
+ Args: map[string]string{
+ "fromPath": relPath,
+ },
+ })
+ }
m.installFiles = append(m.installFiles, fullInstallPath)
m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
@@ -2915,15 +2986,25 @@
m.module.base().hooks.runInstallHooks(m, nil, fullInstallPath, true)
if !m.skipInstall() {
- m.Build(pctx, BuildParams{
- Rule: Symlink,
- Description: "install symlink " + fullInstallPath.Base() + " -> " + absPath,
- Output: fullInstallPath,
- Default: !m.Config().KatiEnabled(),
- Args: map[string]string{
- "fromPath": absPath,
- },
- })
+ if m.Config().KatiEnabled() && m.InstallBypassMake() {
+ // When creating the symlink rule in Soong but embedding in Make, write the rule to a
+ // makefile instead of directly to the ninja file so that main.mk can add the
+ // dependencies from the `required` property that are hard to resolve in Soong.
+ m.katiSymlinks = append(m.katiSymlinks, katiInstall{
+ absFrom: absPath,
+ to: fullInstallPath,
+ })
+ } else {
+ m.Build(pctx, BuildParams{
+ Rule: Symlink,
+ Description: "install symlink " + fullInstallPath.Base() + " -> " + absPath,
+ Output: fullInstallPath,
+ Default: !m.Config().KatiEnabled(),
+ Args: map[string]string{
+ "fromPath": absPath,
+ },
+ })
+ }
m.installFiles = append(m.installFiles, fullInstallPath)
}
@@ -2942,7 +3023,7 @@
m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
}
-func (m *moduleContext) TidyFile(srcPath Path) {
+func (m *moduleContext) TidyFile(srcPath WritablePath) {
m.tidyFiles = append(m.tidyFiles, srcPath)
}
diff --git a/android/neverallow.go b/android/neverallow.go
index 9098a71..04366d3 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -27,7 +27,7 @@
// "neverallow" rules for the build system.
//
// This allows things which aren't related to the build system and are enforced
-// for sanity, in progress code refactors, or policy to be expressed in a
+// against assumptions, in progress code refactors, or policy to be expressed in a
// straightforward away disjoint from implementations and tests which should
// work regardless of these restrictions.
//
diff --git a/android/paths.go b/android/paths.go
index 2e378ba..69ab5f7 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -462,6 +462,13 @@
return ret
}
+// PathForGoBinary returns the path to the installed location of a bootstrap_go_binary module.
+func PathForGoBinary(ctx PathContext, goBinary bootstrap.GoBinaryTool) Path {
+ goBinaryInstallDir := pathForInstall(ctx, ctx.Config().BuildOS, ctx.Config().BuildArch, "bin", false)
+ rel := Rel(ctx, goBinaryInstallDir.String(), goBinary.InstallPath())
+ return goBinaryInstallDir.Join(ctx, rel)
+}
+
// Expands Paths to a SourceFileProducer or OutputFileProducer module dependency referenced via ":name" or ":name{.tag}" syntax.
// If the dependency is not found, a missingErrorDependency is returned.
// If the module dependency is not a SourceFileProducer or OutputFileProducer, appropriate errors will be returned.
@@ -482,11 +489,8 @@
} else if tag != "" {
return nil, fmt.Errorf("path dependency %q is not an output file producing module", path)
} else if goBinary, ok := module.(bootstrap.GoBinaryTool); ok {
- if rel, err := filepath.Rel(PathForOutput(ctx).String(), goBinary.InstallPath()); err == nil {
- return Paths{PathForOutput(ctx, rel).WithoutRel()}, nil
- } else {
- return nil, fmt.Errorf("cannot find output path for %q: %w", goBinary.InstallPath(), err)
- }
+ goBinaryPath := PathForGoBinary(ctx, goBinary)
+ return Paths{goBinaryPath}, nil
} else if srcProducer, ok := module.(SourceFileProducer); ok {
return srcProducer.Srcs(), nil
} else {
@@ -1571,6 +1575,8 @@
// For example, it is host/<os>-<arch> for host modules, and target/product/<device>/<partition> for device modules.
partitionDir string
+ partition string
+
// makePath indicates whether this path is for Soong (false) or Make (true).
makePath bool
}
@@ -1716,6 +1722,7 @@
basePath: basePath{partionPath, ""},
soongOutDir: ctx.Config().soongOutDir,
partitionDir: partionPath,
+ partition: partition,
makePath: false,
}
@@ -1741,8 +1748,7 @@
}
func InstallPathToOnDevicePath(ctx PathContext, path InstallPath) string {
- rel := Rel(ctx, PathForOutput(ctx, "target", "product", ctx.Config().DeviceName()).String(), path.String())
-
+ rel := Rel(ctx, strings.TrimSuffix(path.PartitionDir(), path.partition), path.String())
return "/" + rel
}
diff --git a/android/rule_builder.go b/android/rule_builder.go
index c9a9ddd..1c6b1c0 100644
--- a/android/rule_builder.go
+++ b/android/rule_builder.go
@@ -833,10 +833,11 @@
func sboxPathForToolRel(ctx BuilderContext, path Path) string {
// Errors will be handled in RuleBuilder.Build where we have a context to report them
- relOut, isRelOut, _ := maybeRelErr(PathForOutput(ctx, "host", ctx.Config().PrebuiltOS()).String(), path.String())
- if isRelOut {
- // The tool is in the output directory, it will be copied to __SBOX_OUT_DIR__/tools/out
- return filepath.Join(sboxToolsSubDir, "out", relOut)
+ toolDir := pathForInstall(ctx, ctx.Config().BuildOS, ctx.Config().BuildArch, "", false)
+ relOutSoong, isRelOutSoong, _ := maybeRelErr(toolDir.String(), path.String())
+ if isRelOutSoong {
+ // The tool is in the Soong output directory, it will be copied to __SBOX_OUT_DIR__/tools/out
+ return filepath.Join(sboxToolsSubDir, "out", relOutSoong)
}
// The tool is in the source directory, it will be copied to __SBOX_OUT_DIR__/tools/src
return filepath.Join(sboxToolsSubDir, "src", path.String())
diff --git a/android/sdk_version.go b/android/sdk_version.go
index c6c75a3..1813e7e 100644
--- a/android/sdk_version.go
+++ b/android/sdk_version.go
@@ -157,7 +157,7 @@
return ctx.Config().AlwaysUsePrebuiltSdks()
} else if !s.ApiLevel.IsPreview() {
// validation check
- if s.Kind != SdkPublic && s.Kind != SdkSystem && s.Kind != SdkTest && s.Kind != SdkModule {
+ if s.Kind != SdkPublic && s.Kind != SdkSystem && s.Kind != SdkTest && s.Kind != SdkModule && s.Kind != SdkSystemServer {
panic(fmt.Errorf("prebuilt SDK is not not available for SdkKind=%q", s.Kind))
return false
}
diff --git a/android/soong_config_modules_test.go b/android/soong_config_modules_test.go
index b2f8eaa..0ec9bcb 100644
--- a/android/soong_config_modules_test.go
+++ b/android/soong_config_modules_test.go
@@ -60,7 +60,7 @@
module_type: "test",
config_namespace: "acme",
variables: ["board", "feature1", "FEATURE3", "unused_string_var"],
- bool_variables: ["feature2", "unused_feature"],
+ bool_variables: ["feature2", "unused_feature", "always_true"],
value_variables: ["size", "unused_size"],
properties: ["cflags", "srcs", "defaults"],
}
@@ -148,6 +148,11 @@
cflags: ["DEFAULT_B"],
}
+ test_defaults {
+ name: "foo_defaults_always_true",
+ cflags: ["DEFAULT_ALWAYS_TRUE"],
+ }
+
acme_test {
name: "foo_with_defaults",
cflags: ["-DGENERIC"],
@@ -176,6 +181,15 @@
FEATURE3: {
cflags: ["-DFEATURE3"],
},
+ always_true: {
+ defaults: ["foo_defaults_always_true"],
+ conditions_default: {
+ // verify that conditions_default is skipped if the
+ // soong config variable is true by specifying a
+ // non-existent module in conditions_default
+ defaults: ["//nonexistent:defaults"],
+ }
+ },
},
}
`
@@ -205,6 +219,7 @@
"unused_feature": "true", // unused
"unused_size": "1", // unused
"unused_string_var": "a", // unused
+ "always_true": "true",
},
}),
fooExpectedFlags: []string{
@@ -217,6 +232,7 @@
},
fooDefaultsExpectedFlags: []string{
"DEFAULT_A",
+ "DEFAULT_ALWAYS_TRUE",
"DEFAULT",
"-DGENERIC",
"-DSIZE=42",
@@ -227,7 +243,10 @@
{
name: "empty_prop_for_string_var",
preparer: fixtureForVendorVars(map[string]map[string]string{
- "acme": {"board": "soc_c"}}),
+ "acme": {
+ "board": "soc_c",
+ "always_true": "true",
+ }}),
fooExpectedFlags: []string{
"DEFAULT",
"-DGENERIC",
@@ -236,6 +255,7 @@
"-DF1_CONDITIONS_DEFAULT",
},
fooDefaultsExpectedFlags: []string{
+ "DEFAULT_ALWAYS_TRUE",
"DEFAULT",
"-DGENERIC",
},
@@ -243,7 +263,10 @@
{
name: "unused_string_var",
preparer: fixtureForVendorVars(map[string]map[string]string{
- "acme": {"board": "soc_d"}}),
+ "acme": {
+ "board": "soc_d",
+ "always_true": "true",
+ }}),
fooExpectedFlags: []string{
"DEFAULT",
"-DGENERIC",
@@ -253,14 +276,18 @@
"-DF1_CONDITIONS_DEFAULT",
},
fooDefaultsExpectedFlags: []string{
+ "DEFAULT_ALWAYS_TRUE",
"DEFAULT",
"-DGENERIC",
},
},
{
- name: "conditions_default",
- preparer: fixtureForVendorVars(map[string]map[string]string{}),
+ name: "conditions_default",
+ preparer: fixtureForVendorVars(map[string]map[string]string{
+ "acme": {
+ "always_true": "true",
+ }}),
fooExpectedFlags: []string{
"DEFAULT",
"-DGENERIC",
@@ -270,6 +297,7 @@
"-DF1_CONDITIONS_DEFAULT",
},
fooDefaultsExpectedFlags: []string{
+ "DEFAULT_ALWAYS_TRUE",
"DEFAULT",
"-DGENERIC",
},
diff --git a/android/variable.go b/android/variable.go
index 5c54e94..baa6dfa 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -419,6 +419,8 @@
SepolicyFreezeTestExtraDirs []string `json:",omitempty"`
SepolicyFreezeTestExtraPrebuiltDirs []string `json:",omitempty"`
+
+ GenerateAidlNdkPlatformBackend bool `json:",omitempty"`
}
func boolPtr(v bool) *bool {
diff --git a/apex/apex.go b/apex/apex.go
index 0bca093..33188cb 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -178,6 +178,10 @@
// used in tests.
Test_only_force_compression *bool
+ // Put extra tags (signer=<value>) to apexkeys.txt, so that release tools can sign this apex
+ // with the tool to sign payload contents.
+ Custom_sign_tool *string
+
// Canonical name of this APEX bundle. Used to determine the path to the
// activated APEX on device (i.e. /apex/<apexVariationName>), and used for the
// apex mutator variations. For override_apex modules, this is the name of the
@@ -348,7 +352,6 @@
// Flags for special variants of APEX
testApex bool
vndkApex bool
- artApex bool
// Tells whether this variant of the APEX bundle is the primary one or not. Only the primary
// one gets installed to the device.
@@ -754,13 +757,6 @@
ctx.AddFarVariationDependencies(commonVariation, fsTag, a.properties.Filesystems...)
ctx.AddFarVariationDependencies(commonVariation, compatConfigTag, a.properties.Compat_configs...)
- if a.artApex {
- // With EMMA_INSTRUMENT_FRAMEWORK=true the ART boot image includes jacoco library.
- if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
- ctx.AddFarVariationDependencies(commonVariation, javaLibTag, "jacocoagent")
- }
- }
-
// Marks that this APEX (in fact all the modules in it) has to be built with the given SDKs.
// This field currently isn't used.
// TODO(jiyong): consider dropping this feature
@@ -1462,12 +1458,7 @@
func apexFileForGoBinary(ctx android.BaseModuleContext, depName string, gb bootstrap.GoBinaryTool) apexFile {
dirInApex := "bin"
- s, err := filepath.Rel(android.PathForOutput(ctx).String(), gb.InstallPath())
- if err != nil {
- ctx.ModuleErrorf("Unable to use compiled binary at %s", gb.InstallPath())
- return apexFile{}
- }
- fileToCopy := android.PathForOutput(ctx, s)
+ fileToCopy := android.PathForGoBinary(ctx, gb)
// NB: Since go binaries are static we don't need the module for anything here, which is
// good since the go tool is a blueprint.Module not an android.Module like we would
// normally use.
@@ -2203,10 +2194,9 @@
return module
}
-func ApexBundleFactory(testApex bool, artApex bool) android.Module {
+func ApexBundleFactory(testApex bool) android.Module {
bundle := newApexBundle()
bundle.testApex = testApex
- bundle.artApex = artApex
return bundle
}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 78a6bb8..8aaa31a 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -7683,6 +7683,28 @@
name: "myapex",
key: "myapex.key",
updatable: false,
+ custom_sign_tool: "sign_myapex",
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+ `)
+
+ apexKeysText := ctx.SingletonForTests("apex_keys_text")
+ content := apexKeysText.MaybeDescription("apexkeys.txt").BuildParams.Args["content"]
+ ensureContains(t, content, `name="myapex.apex" public_key="vendor/foo/devkeys/testkey.avbpubkey" private_key="vendor/foo/devkeys/testkey.pem" container_certificate="vendor/foo/devkeys/test.x509.pem" container_private_key="vendor/foo/devkeys/test.pk8" partition="system_ext" sign_tool="sign_myapex"`)
+}
+
+func TestApexKeysTxtOverrides(t *testing.T) {
+ ctx := testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ updatable: false,
+ custom_sign_tool: "sign_myapex",
}
apex_key {
diff --git a/apex/builder.go b/apex/builder.go
index 702b6fc..e22d694 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -106,7 +106,7 @@
Description: "convert ${in}=>${out}",
})
- // TODO(b/113233103): make sure that file_contexts is sane, i.e., validate
+ // TODO(b/113233103): make sure that file_contexts is as expected, i.e., validate
// against the binary policy using sefcontext_compiler -p <policy>.
// TODO(b/114327326): automate the generation of file_contexts
@@ -524,7 +524,7 @@
}
unsignedOutputFile := android.PathForModuleOut(ctx, a.Name()+suffix+".unsigned")
- outHostBinDir := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "bin").String()
+ outHostBinDir := ctx.Config().HostToolPath(ctx, "").String()
prebuiltSdkToolsBinDir := filepath.Join("prebuilts", "sdk", "tools", runtime.GOOS, "bin")
// Figure out if need to compress apex.
@@ -716,12 +716,10 @@
}
}
apisBackedbyOutputFile := android.PathForModuleOut(ctx, a.Name()+"_backing.txt")
- ndkLibraryList := android.PathForSource(ctx, "system/core/rootdir/etc/public.libraries.android.txt")
rule := android.NewRuleBuilder(pctx, ctx)
rule.Command().
Tool(android.PathForSource(ctx, "build/soong/scripts/gen_ndk_backedby_apex.sh")).
Output(apisBackedbyOutputFile).
- Input(ndkLibraryList).
Flags(libNames)
rule.Build("ndk_backedby_list", "Generate API libraries backed by Apex")
a.apisBackedByModuleFile = apisBackedbyOutputFile
diff --git a/apex/key.go b/apex/key.go
index e2695d7..259060f 100644
--- a/apex/key.go
+++ b/apex/key.go
@@ -123,13 +123,18 @@
containerCertificate string
containerPrivateKey string
partition string
+ signTool string
}
toString := func(e apexKeyEntry) string {
- format := "name=%q public_key=%q private_key=%q container_certificate=%q container_private_key=%q partition=%q\n"
+ signTool := ""
+ if e.signTool != "" {
+ signTool = fmt.Sprintf(" sign_tool=%q", e.signTool)
+ }
+ format := "name=%q public_key=%q private_key=%q container_certificate=%q container_private_key=%q partition=%q%s\n"
if e.presigned {
- return fmt.Sprintf(format, e.name, "PRESIGNED", "PRESIGNED", "PRESIGNED", "PRESIGNED", e.partition)
+ return fmt.Sprintf(format, e.name, "PRESIGNED", "PRESIGNED", "PRESIGNED", "PRESIGNED", e.partition, signTool)
} else {
- return fmt.Sprintf(format, e.name, e.publicKey, e.privateKey, e.containerCertificate, e.containerPrivateKey, e.partition)
+ return fmt.Sprintf(format, e.name, e.publicKey, e.privateKey, e.containerCertificate, e.containerPrivateKey, e.partition, signTool)
}
}
@@ -145,6 +150,7 @@
containerCertificate: pem.String(),
containerPrivateKey: key.String(),
partition: m.PartitionTag(ctx.DeviceConfig()),
+ signTool: proptools.String(m.properties.Custom_sign_tool),
}
}
})
diff --git a/bazel/aquery.go b/bazel/aquery.go
index 8741afb..0dedcf4 100644
--- a/bazel/aquery.go
+++ b/bazel/aquery.go
@@ -246,7 +246,8 @@
outDir := proptools.ShellEscapeIncludingSpaces(filepath.Dir(out))
out = proptools.ShellEscapeIncludingSpaces(out)
in := proptools.ShellEscapeIncludingSpaces(inputPaths[0])
- buildStatement.Command = fmt.Sprintf("mkdir -p %[1]s && rm -f %[2]s && ln -rsf %[3]s %[2]s", outDir, out, in)
+ // Use hard links, because some soong actions expect real files (for example, `cp -d`).
+ buildStatement.Command = fmt.Sprintf("mkdir -p %[1]s && rm -f %[2]s && ln -f %[3]s %[2]s", outDir, out, in)
buildStatement.SymlinkPaths = outputPaths[:]
} else if len(actionEntry.Arguments) < 1 {
return nil, fmt.Errorf("received action with no command: [%v]", buildStatement)
diff --git a/bazel/aquery_test.go b/bazel/aquery_test.go
index 43e4155..88066c8 100644
--- a/bazel/aquery_test.go
+++ b/bazel/aquery_test.go
@@ -859,7 +859,7 @@
BuildStatement{
Command: "mkdir -p one/symlink_subdir && " +
"rm -f one/symlink_subdir/symlink && " +
- "ln -rsf one/file_subdir/file one/symlink_subdir/symlink",
+ "ln -f one/file_subdir/file one/symlink_subdir/symlink",
InputPaths: []string{"one/file_subdir/file"},
OutputPaths: []string{"one/symlink_subdir/symlink"},
SymlinkPaths: []string{"one/symlink_subdir/symlink"},
@@ -923,7 +923,7 @@
BuildStatement{
Command: "mkdir -p 'one/symlink subdir' && " +
"rm -f 'one/symlink subdir/symlink' && " +
- "ln -rsf 'one/file subdir/file' 'one/symlink subdir/symlink'",
+ "ln -f 'one/file subdir/file' 'one/symlink subdir/symlink'",
InputPaths: []string{"one/file subdir/file"},
OutputPaths: []string{"one/symlink subdir/symlink"},
SymlinkPaths: []string{"one/symlink subdir/symlink"},
diff --git a/bazel/configurability.go b/bazel/configurability.go
index e9641e7..f05c8e5 100644
--- a/bazel/configurability.go
+++ b/bazel/configurability.go
@@ -39,6 +39,7 @@
osArchAndroidArm64 = "android_arm64"
osArchAndroidX86 = "android_x86"
osArchAndroidX86_64 = "android_x86_64"
+ osArchDarwinArm64 = "darwin_arm64"
osArchDarwinX86_64 = "darwin_x86_64"
osArchLinuxX86 = "linux_glibc_x86"
osArchLinuxX86_64 = "linux_glibc_x86_64"
@@ -96,6 +97,7 @@
osArchAndroidArm64: "//build/bazel/platforms/os_arch:android_arm64",
osArchAndroidX86: "//build/bazel/platforms/os_arch:android_x86",
osArchAndroidX86_64: "//build/bazel/platforms/os_arch:android_x86_64",
+ osArchDarwinArm64: "//build/bazel/platforms/os_arch:darwin_arm64",
osArchDarwinX86_64: "//build/bazel/platforms/os_arch:darwin_x86_64",
osArchLinuxX86: "//build/bazel/platforms/os_arch:linux_glibc_x86",
osArchLinuxX86_64: "//build/bazel/platforms/os_arch:linux_glibc_x86_64",
diff --git a/bootstrap.bash b/bootstrap.bash
index 4db8539..726692a 100755
--- a/bootstrap.bash
+++ b/bootstrap.bash
@@ -15,9 +15,9 @@
# limitations under the License.
echo '==== ERROR: bootstrap.bash & ./soong are obsolete ====' >&2
-echo 'Use `m --skip-make` with a standalone OUT_DIR instead.' >&2
+echo 'Use `m --soong-only` with a standalone OUT_DIR instead.' >&2
echo 'Without envsetup.sh, use:' >&2
-echo ' build/soong/soong_ui.bash --make-mode --skip-make' >&2
+echo ' build/soong/soong_ui.bash --make-mode --soong-only' >&2
echo '======================================================' >&2
exit 1
diff --git a/bp2build/bp2build.go b/bp2build/bp2build.go
index 45a3cb6..b0c3899 100644
--- a/bp2build/bp2build.go
+++ b/bp2build/bp2build.go
@@ -15,11 +15,12 @@
package bp2build
import (
- "android/soong/android"
- "android/soong/bazel"
"fmt"
"os"
"strings"
+
+ "android/soong/android"
+ "android/soong/bazel"
)
// Codegen is the backend of bp2build. The code generator is responsible for
@@ -43,7 +44,7 @@
writeFiles(ctx, bp2buildDir, bp2buildFiles)
soongInjectionDir := android.PathForOutput(ctx, bazel.SoongInjectionDirName)
- writeFiles(ctx, soongInjectionDir, CreateSoongInjectionFiles(res.metrics))
+ writeFiles(ctx, soongInjectionDir, CreateSoongInjectionFiles(ctx.Config(), res.metrics))
return res.metrics
}
diff --git a/bp2build/cc_binary_conversion_test.go b/bp2build/cc_binary_conversion_test.go
new file mode 100644
index 0000000..0b71d89
--- /dev/null
+++ b/bp2build/cc_binary_conversion_test.go
@@ -0,0 +1,435 @@
+// Copyright 2021 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 bp2build
+
+import (
+ "android/soong/android"
+ "android/soong/cc"
+ "android/soong/genrule"
+ "fmt"
+ "strings"
+ "testing"
+)
+
+const (
+ ccBinaryTypePlaceHolder = "{rule_name}"
+ compatibleWithPlaceHolder = "{target_compatible_with}"
+)
+
+func registerCcBinaryModuleTypes(ctx android.RegistrationContext) {
+ cc.RegisterCCBuildComponents(ctx)
+ ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
+ ctx.RegisterModuleType("cc_library_static", cc.LibraryStaticFactory)
+ ctx.RegisterModuleType("cc_library", cc.LibraryFactory)
+ ctx.RegisterModuleType("genrule", genrule.GenRuleFactory)
+}
+
+var binaryReplacer = strings.NewReplacer(ccBinaryTypePlaceHolder, "cc_binary", compatibleWithPlaceHolder, "")
+var hostBinaryReplacer = strings.NewReplacer(ccBinaryTypePlaceHolder, "cc_binary_host", compatibleWithPlaceHolder, `
+ target_compatible_with = select({
+ "//build/bazel/platforms/os:android": ["@platforms//:incompatible"],
+ "//conditions:default": [],
+ }),`)
+
+func runCcBinaryTests(t *testing.T, tc bp2buildTestCase) {
+ t.Helper()
+ runCcBinaryTestCase(t, tc)
+ runCcHostBinaryTestCase(t, tc)
+}
+
+func runCcBinaryTestCase(t *testing.T, tc bp2buildTestCase) {
+ t.Helper()
+ testCase := tc
+ testCase.expectedBazelTargets = append([]string{}, tc.expectedBazelTargets...)
+ testCase.moduleTypeUnderTest = "cc_binary"
+ testCase.moduleTypeUnderTestFactory = cc.BinaryFactory
+ testCase.moduleTypeUnderTestBp2BuildMutator = cc.BinaryBp2build
+ testCase.description = fmt.Sprintf("%s %s", testCase.moduleTypeUnderTest, testCase.description)
+ testCase.blueprint = binaryReplacer.Replace(testCase.blueprint)
+ for i, et := range testCase.expectedBazelTargets {
+ testCase.expectedBazelTargets[i] = binaryReplacer.Replace(et)
+ }
+ t.Run(testCase.description, func(t *testing.T) {
+ runBp2BuildTestCase(t, registerCcBinaryModuleTypes, testCase)
+ })
+}
+
+func runCcHostBinaryTestCase(t *testing.T, tc bp2buildTestCase) {
+ t.Helper()
+ testCase := tc
+ testCase.expectedBazelTargets = append([]string{}, tc.expectedBazelTargets...)
+ testCase.moduleTypeUnderTest = "cc_binary_host"
+ testCase.moduleTypeUnderTestFactory = cc.BinaryHostFactory
+ testCase.moduleTypeUnderTestBp2BuildMutator = cc.BinaryHostBp2build
+ testCase.description = fmt.Sprintf("%s %s", testCase.moduleTypeUnderTest, testCase.description)
+ testCase.blueprint = hostBinaryReplacer.Replace(testCase.blueprint)
+ for i, et := range testCase.expectedBazelTargets {
+ testCase.expectedBazelTargets[i] = hostBinaryReplacer.Replace(et)
+ }
+ t.Run(testCase.description, func(t *testing.T) {
+ runBp2BuildTestCase(t, registerCcBinaryModuleTypes, testCase)
+ })
+}
+
+func TestBasicCcBinary(t *testing.T) {
+ runCcBinaryTests(t, bp2buildTestCase{
+ description: "basic -- properties -> attrs with little/no transformation",
+ blueprint: `
+{rule_name} {
+ name: "foo",
+ srcs: ["a.cc"],
+ local_include_dirs: ["dir"],
+ include_dirs: ["absolute_dir"],
+ cflags: ["-Dcopt"],
+ cppflags: ["-Dcppflag"],
+ conlyflags: ["-Dconlyflag"],
+ asflags: ["-Dasflag"],
+ ldflags: ["ld-flag"],
+ rtti: true,
+ strip: {
+ all: true,
+ keep_symbols: true,
+ keep_symbols_and_debug_frame: true,
+ keep_symbols_list: ["symbol"],
+ none: true,
+ },
+}
+`,
+ expectedBazelTargets: []string{`cc_binary(
+ name = "foo",
+ absolute_includes = ["absolute_dir"],
+ asflags = ["-Dasflag"],
+ conlyflags = ["-Dconlyflag"],
+ copts = ["-Dcopt"],
+ cppflags = ["-Dcppflag"],
+ linkopts = ["ld-flag"],
+ local_includes = [
+ "dir",
+ ".",
+ ],
+ rtti = True,
+ srcs = ["a.cc"],
+ strip = {
+ "all": True,
+ "keep_symbols": True,
+ "keep_symbols_and_debug_frame": True,
+ "keep_symbols_list": ["symbol"],
+ "none": True,
+ },{target_compatible_with}
+)`},
+ })
+}
+
+func TestCcBinaryWithSharedLdflagDisableFeature(t *testing.T) {
+ runCcBinaryTests(t, bp2buildTestCase{
+ description: `ldflag "-shared" disables static_flag feature`,
+ blueprint: `
+{rule_name} {
+ name: "foo",
+ ldflags: ["-shared"],
+ include_build_directory: false,
+}
+`,
+ expectedBazelTargets: []string{`cc_binary(
+ name = "foo",
+ features = ["-static_flag"],
+ linkopts = ["-shared"],{target_compatible_with}
+)`},
+ })
+}
+
+func TestCcBinaryWithLinkStatic(t *testing.T) {
+ runCcBinaryTests(t, bp2buildTestCase{
+ description: "link static",
+ blueprint: `
+{rule_name} {
+ name: "foo",
+ static_executable: true,
+ include_build_directory: false,
+}
+`,
+ expectedBazelTargets: []string{`cc_binary(
+ name = "foo",
+ linkshared = False,{target_compatible_with}
+)`},
+ })
+}
+
+func TestCcBinaryVersionScript(t *testing.T) {
+ runCcBinaryTests(t, bp2buildTestCase{
+ description: `version script`,
+ blueprint: `
+{rule_name} {
+ name: "foo",
+ include_build_directory: false,
+ version_script: "vs",
+}
+`,
+ expectedBazelTargets: []string{`cc_binary(
+ name = "foo",
+ additional_linker_inputs = ["vs"],
+ linkopts = ["-Wl,--version-script,$(location vs)"],{target_compatible_with}
+)`},
+ })
+}
+
+func TestCcBinarySplitSrcsByLang(t *testing.T) {
+ runCcHostBinaryTestCase(t, bp2buildTestCase{
+ description: "split srcs by lang",
+ blueprint: `
+{rule_name} {
+ name: "foo",
+ srcs: [
+ "asonly.S",
+ "conly.c",
+ "cpponly.cpp",
+ ":fg_foo",
+ ],
+ include_build_directory: false,
+}
+` + simpleModuleDoNotConvertBp2build("filegroup", "fg_foo"),
+ expectedBazelTargets: []string{`cc_binary(
+ name = "foo",
+ srcs = [
+ "cpponly.cpp",
+ ":fg_foo_cpp_srcs",
+ ],
+ srcs_as = [
+ "asonly.S",
+ ":fg_foo_as_srcs",
+ ],
+ srcs_c = [
+ "conly.c",
+ ":fg_foo_c_srcs",
+ ],{target_compatible_with}
+)`},
+ })
+}
+
+func TestCcBinaryDoNotDistinguishBetweenDepsAndImplementationDeps(t *testing.T) {
+ runCcBinaryTestCase(t, bp2buildTestCase{
+ description: "no implementation deps",
+ blueprint: `
+genrule {
+ name: "generated_hdr",
+ cmd: "nothing to see here",
+}
+
+genrule {
+ name: "export_generated_hdr",
+ cmd: "nothing to see here",
+}
+
+{rule_name} {
+ name: "foo",
+ srcs: ["foo.cpp"],
+ shared_libs: ["implementation_shared_dep", "shared_dep"],
+ export_shared_lib_headers: ["shared_dep"],
+ static_libs: ["implementation_static_dep", "static_dep"],
+ export_static_lib_headers: ["static_dep", "whole_static_dep"],
+ whole_static_libs: ["not_explicitly_exported_whole_static_dep", "whole_static_dep"],
+ include_build_directory: false,
+ generated_headers: ["generated_hdr", "export_generated_hdr"],
+ export_generated_headers: ["export_generated_hdr"],
+}
+` +
+ simpleModuleDoNotConvertBp2build("cc_library_static", "static_dep") +
+ simpleModuleDoNotConvertBp2build("cc_library_static", "implementation_static_dep") +
+ simpleModuleDoNotConvertBp2build("cc_library_static", "whole_static_dep") +
+ simpleModuleDoNotConvertBp2build("cc_library_static", "not_explicitly_exported_whole_static_dep") +
+ simpleModuleDoNotConvertBp2build("cc_library", "shared_dep") +
+ simpleModuleDoNotConvertBp2build("cc_library", "implementation_shared_dep"),
+ expectedBazelTargets: []string{`cc_binary(
+ name = "foo",
+ deps = [
+ ":implementation_static_dep",
+ ":static_dep",
+ ],
+ dynamic_deps = [
+ ":implementation_shared_dep",
+ ":shared_dep",
+ ],
+ srcs = [
+ "foo.cpp",
+ ":generated_hdr",
+ ":export_generated_hdr",
+ ],{target_compatible_with}
+ whole_archive_deps = [
+ ":not_explicitly_exported_whole_static_dep",
+ ":whole_static_dep",
+ ],
+)`},
+ })
+}
+
+func TestCcBinaryNocrtTests(t *testing.T) {
+ baseTestCases := []struct {
+ description string
+ soongProperty string
+ bazelAttr string
+ }{
+ {
+ description: "nocrt: true",
+ soongProperty: `nocrt: true,`,
+ bazelAttr: ` link_crt = False,`,
+ },
+ {
+ description: "nocrt: false",
+ soongProperty: `nocrt: false,`,
+ },
+ {
+ description: "nocrt: not set",
+ },
+ }
+
+ baseBlueprint := `{rule_name} {
+ name: "foo",%s
+ include_build_directory: false,
+}
+`
+
+ baseBazelTarget := `cc_binary(
+ name = "foo",%s{target_compatible_with}
+)`
+
+ for _, btc := range baseTestCases {
+ prop := btc.soongProperty
+ if len(prop) > 0 {
+ prop = "\n" + prop
+ }
+ attr := btc.bazelAttr
+ if len(attr) > 0 {
+ attr = "\n" + attr
+ }
+ runCcBinaryTests(t, bp2buildTestCase{
+ description: btc.description,
+ blueprint: fmt.Sprintf(baseBlueprint, prop),
+ expectedBazelTargets: []string{
+ fmt.Sprintf(baseBazelTarget, attr),
+ },
+ })
+ }
+}
+
+func TestCcBinaryNo_libcrtTests(t *testing.T) {
+ baseTestCases := []struct {
+ description string
+ soongProperty string
+ bazelAttr string
+ }{
+ {
+ description: "no_libcrt: true",
+ soongProperty: `no_libcrt: true,`,
+ bazelAttr: ` use_libcrt = False,`,
+ },
+ {
+ description: "no_libcrt: false",
+ soongProperty: `no_libcrt: false,`,
+ bazelAttr: ` use_libcrt = True,`,
+ },
+ {
+ description: "no_libcrt: not set",
+ },
+ }
+
+ baseBlueprint := `{rule_name} {
+ name: "foo",%s
+ include_build_directory: false,
+}
+`
+
+ baseBazelTarget := `cc_binary(
+ name = "foo",{target_compatible_with}%s
+)`
+
+ for _, btc := range baseTestCases {
+ prop := btc.soongProperty
+ if len(prop) > 0 {
+ prop = "\n" + prop
+ }
+ attr := btc.bazelAttr
+ if len(attr) > 0 {
+ attr = "\n" + attr
+ }
+ runCcBinaryTests(t, bp2buildTestCase{
+ description: btc.description,
+ blueprint: fmt.Sprintf(baseBlueprint, prop),
+ expectedBazelTargets: []string{
+ fmt.Sprintf(baseBazelTarget, attr),
+ },
+ })
+ }
+}
+
+func TestCcBinaryPropertiesToFeatures(t *testing.T) {
+ baseTestCases := []struct {
+ description string
+ soongProperty string
+ bazelAttr string
+ }{
+ {
+ description: "pack_relocation: true",
+ soongProperty: `pack_relocations: true,`,
+ },
+ {
+ description: "pack_relocations: false",
+ soongProperty: `pack_relocations: false,`,
+ bazelAttr: ` features = ["disable_pack_relocations"],`,
+ },
+ {
+ description: "pack_relocations: not set",
+ },
+ {
+ description: "pack_relocation: true",
+ soongProperty: `allow_undefined_symbols: true,`,
+ bazelAttr: ` features = ["-no_undefined_symbols"],`,
+ },
+ {
+ description: "allow_undefined_symbols: false",
+ soongProperty: `allow_undefined_symbols: false,`,
+ },
+ {
+ description: "allow_undefined_symbols: not set",
+ },
+ }
+
+ baseBlueprint := `{rule_name} {
+ name: "foo",%s
+ include_build_directory: false,
+}
+`
+
+ baseBazelTarget := `cc_binary(
+ name = "foo",%s{target_compatible_with}
+)`
+
+ for _, btc := range baseTestCases {
+ prop := btc.soongProperty
+ if len(prop) > 0 {
+ prop = "\n" + prop
+ }
+ attr := btc.bazelAttr
+ if len(attr) > 0 {
+ attr = "\n" + attr
+ }
+ runCcBinaryTests(t, bp2buildTestCase{
+ description: btc.description,
+ blueprint: fmt.Sprintf(baseBlueprint, prop),
+ expectedBazelTargets: []string{
+ fmt.Sprintf(baseBazelTarget, attr),
+ },
+ })
+ }
+}
diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go
index 9f6f450..9887811 100644
--- a/bp2build/cc_library_static_conversion_test.go
+++ b/bp2build/cc_library_static_conversion_test.go
@@ -986,6 +986,48 @@
})
}
+func TestCcLibraryStaticGeneratedHeadersAllPartitions(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ moduleTypeUnderTest: "cc_library_static",
+ moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
+ blueprint: soongCcLibraryStaticPreamble + `
+genrule {
+ name: "generated_hdr",
+ cmd: "nothing to see here",
+}
+
+genrule {
+ name: "export_generated_hdr",
+ cmd: "nothing to see here",
+}
+
+cc_library_static {
+ name: "foo_static",
+ srcs: ["cpp_src.cpp", "as_src.S", "c_src.c"],
+ generated_headers: ["generated_hdr", "export_generated_hdr"],
+ export_generated_headers: ["export_generated_hdr"],
+ include_build_directory: false,
+}`,
+ expectedBazelTargets: []string{`cc_library_static(
+ name = "foo_static",
+ hdrs = [":export_generated_hdr"],
+ srcs = [
+ "cpp_src.cpp",
+ ":generated_hdr",
+ ],
+ srcs_as = [
+ "as_src.S",
+ ":generated_hdr",
+ ],
+ srcs_c = [
+ "c_src.c",
+ ":generated_hdr",
+ ],
+)`},
+ })
+}
+
func TestCcLibraryStaticArchSrcsExcludeSrcsGeneratedFiles(t *testing.T) {
runCcLibraryStaticTestCase(t, bp2buildTestCase{
description: "cc_library_static arch srcs/exclude_srcs with generated files",
@@ -1067,10 +1109,10 @@
name = "foo_static3",
srcs = [
"common.cpp",
- ":generated_hdr",
- "//dep:generated_hdr_other_pkg",
":generated_src",
"//dep:generated_src_other_pkg",
+ ":generated_hdr",
+ "//dep:generated_hdr_other_pkg",
] + select({
"//build/bazel/platforms/arch:x86": [
"for-x86.cpp",
@@ -1082,8 +1124,8 @@
],
}) + select({
"//build/bazel/platforms/os:android": [
- "//dep:generated_hdr_other_pkg_android",
":generated_src_android",
+ "//dep:generated_hdr_other_pkg_android",
],
"//conditions:default": [],
}),
diff --git a/bp2build/cc_prebuilt_library_shared_test.go b/bp2build/cc_prebuilt_library_shared_test.go
new file mode 100644
index 0000000..97545c8
--- /dev/null
+++ b/bp2build/cc_prebuilt_library_shared_test.go
@@ -0,0 +1,65 @@
+package bp2build
+
+import (
+ "testing"
+
+ "android/soong/cc"
+)
+
+func TestSharedPrebuiltLibrary(t *testing.T) {
+ runBp2BuildTestCaseSimple(t,
+ bp2buildTestCase{
+ description: "prebuilt library shared simple",
+ moduleTypeUnderTest: "cc_prebuilt_library_shared",
+ moduleTypeUnderTestFactory: cc.PrebuiltSharedLibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.PrebuiltLibrarySharedBp2Build,
+ filesystem: map[string]string{
+ "libf.so": "",
+ },
+ blueprint: `
+cc_prebuilt_library_shared {
+ name: "libtest",
+ srcs: ["libf.so"],
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedBazelTargets: []string{
+ `prebuilt_library_shared(
+ name = "libtest",
+ shared_library = "libf.so",
+)`,
+ },
+ })
+}
+
+func TestSharedPrebuiltLibraryWithArchVariance(t *testing.T) {
+ runBp2BuildTestCaseSimple(t,
+ bp2buildTestCase{
+ description: "prebuilt library shared with arch variance",
+ moduleTypeUnderTest: "cc_prebuilt_library_shared",
+ moduleTypeUnderTestFactory: cc.PrebuiltSharedLibraryFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.PrebuiltLibrarySharedBp2Build,
+ filesystem: map[string]string{
+ "libf.so": "",
+ "libg.so": "",
+ },
+ blueprint: `
+cc_prebuilt_library_shared {
+ name: "libtest",
+ arch: {
+ arm64: { srcs: ["libf.so"], },
+ arm: { srcs: ["libg.so"], },
+ },
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedBazelTargets: []string{
+ `prebuilt_library_shared(
+ name = "libtest",
+ shared_library = select({
+ "//build/bazel/platforms/arch:arm": "libg.so",
+ "//build/bazel/platforms/arch:arm64": "libf.so",
+ "//conditions:default": None,
+ }),
+)`,
+ },
+ })
+}
diff --git a/bp2build/conversion.go b/bp2build/conversion.go
index d34a4ba..944cb83 100644
--- a/bp2build/conversion.go
+++ b/bp2build/conversion.go
@@ -17,11 +17,11 @@
Contents string
}
-func CreateSoongInjectionFiles(metrics CodegenMetrics) []BazelFile {
+func CreateSoongInjectionFiles(cfg android.Config, metrics CodegenMetrics) []BazelFile {
var files []BazelFile
files = append(files, newFile("cc_toolchain", GeneratedBuildFileName, "")) // Creates a //cc_toolchain package.
- files = append(files, newFile("cc_toolchain", "constants.bzl", config.BazelCcToolchainVars()))
+ files = append(files, newFile("cc_toolchain", "constants.bzl", config.BazelCcToolchainVars(cfg)))
files = append(files, newFile("metrics", "converted_modules.txt", strings.Join(metrics.convertedModules, "\n")))
diff --git a/bp2build/conversion_test.go b/bp2build/conversion_test.go
index dfa1a9e..d09238a 100644
--- a/bp2build/conversion_test.go
+++ b/bp2build/conversion_test.go
@@ -17,6 +17,8 @@
import (
"sort"
"testing"
+
+ "android/soong/android"
)
type bazelFilepath struct {
@@ -80,7 +82,7 @@
}
func TestCreateBazelFiles_Bp2Build_CreatesDefaultFiles(t *testing.T) {
- files := CreateSoongInjectionFiles(CodegenMetrics{})
+ files := CreateSoongInjectionFiles(android.Config{}, CodegenMetrics{})
expectedFilePaths := []bazelFilepath{
{
diff --git a/cc/binary.go b/cc/binary.go
index b423c50..a5afb07 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -20,6 +20,7 @@
"github.com/google/blueprint"
"android/soong/android"
+ "android/soong/bazel"
)
type BinaryLinkerProperties struct {
@@ -62,7 +63,7 @@
func RegisterBinaryBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("cc_binary", BinaryFactory)
- ctx.RegisterModuleType("cc_binary_host", binaryHostFactory)
+ ctx.RegisterModuleType("cc_binary_host", BinaryHostFactory)
}
// cc_binary produces a binary that is runnable on a device.
@@ -72,7 +73,7 @@
}
// cc_binary_host produces a binary that is runnable on a host.
-func binaryHostFactory() android.Module {
+func BinaryHostFactory() android.Module {
module, _ := NewBinary(android.HostSupported)
return module.Init()
}
@@ -412,7 +413,7 @@
linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...)
}
- linkerDeps = append(linkerDeps, objs.tidyFiles...)
+ validations = append(validations, objs.tidyFiles...)
linkerDeps = append(linkerDeps, flags.LdFlagsDeps...)
// Register link action.
@@ -541,3 +542,124 @@
},
})
}
+
+func init() {
+ android.RegisterBp2BuildMutator("cc_binary", BinaryBp2build)
+ android.RegisterBp2BuildMutator("cc_binary_host", BinaryHostBp2build)
+}
+
+func BinaryBp2build(ctx android.TopDownMutatorContext) {
+ binaryBp2build(ctx, "cc_binary")
+}
+
+func BinaryHostBp2build(ctx android.TopDownMutatorContext) {
+ binaryBp2build(ctx, "cc_binary_host")
+}
+
+func binaryBp2build(ctx android.TopDownMutatorContext, typ string) {
+ m, ok := ctx.Module().(*Module)
+ if !ok {
+ // Not a cc module
+ return
+ }
+ if !m.ConvertWithBp2build(ctx) {
+ return
+ }
+
+ if ctx.ModuleType() != typ {
+ return
+ }
+
+ var compatibleWith bazel.StringListAttribute
+ if typ == "cc_binary_host" {
+ //incompatible with android OS
+ compatibleWith.SetSelectValue(bazel.OsConfigurationAxis, android.Android.Name, []string{"@platforms//:incompatible"})
+ compatibleWith.SetSelectValue(bazel.OsConfigurationAxis, bazel.ConditionsDefaultConfigKey, []string{})
+ }
+
+ baseAttrs := bp2BuildParseBaseProps(ctx, m)
+
+ attrs := &binaryAttributes{
+ binaryLinkerAttrs: bp2buildBinaryLinkerProps(ctx, m),
+
+ Srcs: baseAttrs.srcs,
+ Srcs_c: baseAttrs.cSrcs,
+ Srcs_as: baseAttrs.asSrcs,
+
+ Copts: baseAttrs.copts,
+ Cppflags: baseAttrs.cppFlags,
+ Conlyflags: baseAttrs.conlyFlags,
+ Asflags: baseAttrs.asFlags,
+
+ Deps: baseAttrs.implementationDeps,
+ Dynamic_deps: baseAttrs.implementationDynamicDeps,
+ Whole_archive_deps: baseAttrs.wholeArchiveDeps,
+ System_deps: baseAttrs.systemDynamicDeps,
+
+ Local_includes: baseAttrs.localIncludes,
+ Absolute_includes: baseAttrs.absoluteIncludes,
+ Linkopts: baseAttrs.linkopts,
+ Link_crt: baseAttrs.linkCrt,
+ Use_libcrt: baseAttrs.useLibcrt,
+ Rtti: baseAttrs.rtti,
+ Stl: baseAttrs.stl,
+ Cpp_std: baseAttrs.cppStd,
+
+ Additional_linker_inputs: baseAttrs.additionalLinkerInputs,
+
+ Strip: stripAttributes{
+ Keep_symbols: baseAttrs.stripKeepSymbols,
+ Keep_symbols_and_debug_frame: baseAttrs.stripKeepSymbolsAndDebugFrame,
+ Keep_symbols_list: baseAttrs.stripKeepSymbolsList,
+ All: baseAttrs.stripAll,
+ None: baseAttrs.stripNone,
+ },
+
+ Target_compatible_with: compatibleWith,
+ Features: baseAttrs.features,
+ }
+
+ ctx.CreateBazelTargetModule(bazel.BazelTargetModuleProperties{
+ Rule_class: "cc_binary",
+ Bzl_load_location: "//build/bazel/rules:cc_binary.bzl",
+ },
+ android.CommonAttributes{Name: m.Name()},
+ attrs)
+}
+
+// binaryAttributes contains Bazel attributes corresponding to a cc binary
+type binaryAttributes struct {
+ binaryLinkerAttrs
+ Srcs bazel.LabelListAttribute
+ Srcs_c bazel.LabelListAttribute
+ Srcs_as bazel.LabelListAttribute
+
+ Copts bazel.StringListAttribute
+ Cppflags bazel.StringListAttribute
+ Conlyflags bazel.StringListAttribute
+ Asflags bazel.StringListAttribute
+
+ Deps bazel.LabelListAttribute
+ Dynamic_deps bazel.LabelListAttribute
+ Whole_archive_deps bazel.LabelListAttribute
+ System_deps bazel.LabelListAttribute
+
+ Local_includes bazel.StringListAttribute
+ Absolute_includes bazel.StringListAttribute
+
+ Linkopts bazel.StringListAttribute
+ Additional_linker_inputs bazel.LabelListAttribute
+
+ Link_crt bazel.BoolAttribute
+ Use_libcrt bazel.BoolAttribute
+
+ Rtti bazel.BoolAttribute
+ Stl *string
+ Cpp_std *string
+
+ Strip stripAttributes
+
+ Features bazel.StringListAttribute
+
+ Target_compatible_with bazel.StringListAttribute
+}
diff --git a/cc/bp2build.go b/cc/bp2build.go
index c078096..e20f7c3 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -26,12 +26,19 @@
"github.com/google/blueprint/proptools"
)
+const (
+ cSrcPartition = "c"
+ asSrcPartition = "as"
+ cppSrcPartition = "cpp"
+)
+
// staticOrSharedAttributes are the Bazel-ified versions of StaticOrSharedProperties --
// properties which apply to either the shared or static version of a cc_library module.
type staticOrSharedAttributes struct {
Srcs bazel.LabelListAttribute
Srcs_c bazel.LabelListAttribute
Srcs_as bazel.LabelListAttribute
+ Hdrs bazel.LabelListAttribute
Copts bazel.StringListAttribute
Deps bazel.LabelListAttribute
@@ -43,7 +50,7 @@
System_dynamic_deps bazel.LabelListAttribute
}
-func groupSrcsByExtension(ctx android.TopDownMutatorContext, srcs bazel.LabelListAttribute) (cppSrcs, cSrcs, asSrcs bazel.LabelListAttribute) {
+func groupSrcsByExtension(ctx android.TopDownMutatorContext, srcs bazel.LabelListAttribute) bazel.PartitionToLabelListAttribute {
// Check that a module is a filegroup type named <label>.
isFilegroupNamed := func(m android.Module, fullLabel string) bool {
if ctx.OtherModuleType(m) != "filegroup" {
@@ -75,17 +82,14 @@
// TODO(b/190006308): Handle language detection of sources in a Bazel rule.
partitioned := bazel.PartitionLabelListAttribute(ctx, &srcs, bazel.LabelPartitions{
- "c": bazel.LabelPartition{Extensions: []string{".c"}, LabelMapper: addSuffixForFilegroup("_c_srcs")},
- "as": bazel.LabelPartition{Extensions: []string{".s", ".S"}, LabelMapper: addSuffixForFilegroup("_as_srcs")},
+ cSrcPartition: bazel.LabelPartition{Extensions: []string{".c"}, LabelMapper: addSuffixForFilegroup("_c_srcs")},
+ asSrcPartition: bazel.LabelPartition{Extensions: []string{".s", ".S"}, LabelMapper: addSuffixForFilegroup("_as_srcs")},
// C++ is the "catch-all" group, and comprises generated sources because we don't
// know the language of these sources until the genrule is executed.
- "cpp": bazel.LabelPartition{Extensions: []string{".cpp", ".cc", ".cxx", ".mm"}, LabelMapper: addSuffixForFilegroup("_cpp_srcs"), Keep_remainder: true},
+ cppSrcPartition: bazel.LabelPartition{Extensions: []string{".cpp", ".cc", ".cxx", ".mm"}, LabelMapper: addSuffixForFilegroup("_cpp_srcs"), Keep_remainder: true},
})
- cSrcs = partitioned["c"]
- asSrcs = partitioned["as"]
- cppSrcs = partitioned["cpp"]
- return
+ return partitioned
}
// bp2BuildParseLibProps returns the attributes for a variant of a cc_library.
@@ -114,7 +118,13 @@
type bazelLabelForDepsFn func(android.TopDownMutatorContext, []string) bazel.LabelList
-func partitionExportedAndImplementationsDeps(ctx android.TopDownMutatorContext, allDeps, exportedDeps []string, fn bazelLabelForDepsFn) depsPartition {
+func maybePartitionExportedAndImplementationsDeps(ctx android.TopDownMutatorContext, exportsDeps bool, allDeps, exportedDeps []string, fn bazelLabelForDepsFn) depsPartition {
+ if !exportsDeps {
+ return depsPartition{
+ implementation: fn(ctx, allDeps),
+ }
+ }
+
implementation, export := android.FilterList(allDeps, exportedDeps)
return depsPartition{
@@ -125,7 +135,12 @@
type bazelLabelForDepsExcludesFn func(android.TopDownMutatorContext, []string, []string) bazel.LabelList
-func partitionExportedAndImplementationsDepsExcludes(ctx android.TopDownMutatorContext, allDeps, excludes, exportedDeps []string, fn bazelLabelForDepsExcludesFn) depsPartition {
+func maybePartitionExportedAndImplementationsDepsExcludes(ctx android.TopDownMutatorContext, exportsDeps bool, allDeps, excludes, exportedDeps []string, fn bazelLabelForDepsExcludesFn) depsPartition {
+ if !exportsDeps {
+ return depsPartition{
+ implementation: fn(ctx, allDeps, excludes),
+ }
+ }
implementation, export := android.FilterList(allDeps, exportedDeps)
return depsPartition{
@@ -142,11 +157,11 @@
attrs.Srcs.SetSelectValue(axis, config, android.BazelLabelForModuleSrc(ctx, props.Srcs))
attrs.System_dynamic_deps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, props.System_shared_libs))
- staticDeps := partitionExportedAndImplementationsDeps(ctx, props.Static_libs, props.Export_static_lib_headers, bazelLabelForStaticDeps)
+ staticDeps := maybePartitionExportedAndImplementationsDeps(ctx, true, props.Static_libs, props.Export_static_lib_headers, bazelLabelForStaticDeps)
attrs.Deps.SetSelectValue(axis, config, staticDeps.export)
attrs.Implementation_deps.SetSelectValue(axis, config, staticDeps.implementation)
- sharedDeps := partitionExportedAndImplementationsDeps(ctx, props.Shared_libs, props.Export_shared_lib_headers, bazelLabelForSharedDeps)
+ sharedDeps := maybePartitionExportedAndImplementationsDeps(ctx, true, props.Shared_libs, props.Export_shared_lib_headers, bazelLabelForSharedDeps)
attrs.Dynamic_deps.SetSelectValue(axis, config, sharedDeps.export)
attrs.Implementation_dynamic_deps.SetSelectValue(axis, config, sharedDeps.implementation)
@@ -175,10 +190,10 @@
}
}
- cppSrcs, cSrcs, asSrcs := groupSrcsByExtension(ctx, attrs.Srcs)
- attrs.Srcs = cppSrcs
- attrs.Srcs_c = cSrcs
- attrs.Srcs_as = asSrcs
+ partitionedSrcs := groupSrcsByExtension(ctx, attrs.Srcs)
+ attrs.Srcs = partitionedSrcs[cppSrcPartition]
+ attrs.Srcs_c = partitionedSrcs[cSrcPartition]
+ attrs.Srcs_as = partitionedSrcs[asSrcPartition]
return attrs
}
@@ -212,6 +227,11 @@
}
}
+type baseAttributes struct {
+ compilerAttributes
+ linkerAttributes
+}
+
// Convenience struct to hold all attributes parsed from compiler properties.
type compilerAttributes struct {
// Options for all languages
@@ -226,6 +246,8 @@
cppFlags bazel.StringListAttribute
srcs bazel.LabelListAttribute
+ hdrs bazel.LabelListAttribute
+
rtti bazel.BoolAttribute
// Not affected by arch variants
@@ -236,108 +258,67 @@
absoluteIncludes bazel.StringListAttribute
}
-// bp2BuildParseCompilerProps returns copts, srcs and hdrs and other attributes.
-func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Module) compilerAttributes {
- var srcs bazel.LabelListAttribute
- var copts bazel.StringListAttribute
- var asFlags bazel.StringListAttribute
- var conlyFlags bazel.StringListAttribute
- var cppFlags bazel.StringListAttribute
- var rtti bazel.BoolAttribute
- var localIncludes bazel.StringListAttribute
- var absoluteIncludes bazel.StringListAttribute
- var stl *string = nil
- var cppStd *string = nil
+func parseCommandLineFlags(soongFlags []string) []string {
+ var result []string
+ for _, flag := range soongFlags {
+ // Soong's cflags can contain spaces, like `-include header.h`. For
+ // Bazel's copts, split them up to be compatible with the
+ // no_copts_tokenization feature.
+ result = append(result, strings.Split(flag, " ")...)
+ }
+ return result
+}
- parseCommandLineFlags := func(soongFlags []string) []string {
- var result []string
- for _, flag := range soongFlags {
- // Soong's cflags can contain spaces, like `-include header.h`. For
- // Bazel's copts, split them up to be compatible with the
- // no_copts_tokenization feature.
- result = append(result, strings.Split(flag, " ")...)
- }
- return result
+func (ca *compilerAttributes) bp2buildForAxisAndConfig(ctx android.TopDownMutatorContext, axis bazel.ConfigurationAxis, config string, props *BaseCompilerProperties) {
+ // If there's arch specific srcs or exclude_srcs, generate a select entry for it.
+ // TODO(b/186153868): do this for OS specific srcs and exclude_srcs too.
+ if srcsList, ok := parseSrcs(ctx, props); ok {
+ ca.srcs.SetSelectValue(axis, config, srcsList)
}
- // Parse srcs from an arch or OS's props value.
- parseSrcs := func(props *BaseCompilerProperties) (bazel.LabelList, bool) {
- anySrcs := false
- // Add srcs-like dependencies such as generated files.
- // First create a LabelList containing these dependencies, then merge the values with srcs.
- generatedHdrsAndSrcs := props.Generated_headers
- generatedHdrsAndSrcs = append(generatedHdrsAndSrcs, props.Generated_sources...)
- generatedHdrsAndSrcsLabelList := android.BazelLabelForModuleDepsExcludes(ctx, generatedHdrsAndSrcs, props.Exclude_generated_sources)
- if len(generatedHdrsAndSrcs) > 0 || len(props.Exclude_generated_sources) > 0 {
- anySrcs = true
- }
+ localIncludeDirs := props.Local_include_dirs
+ if axis == bazel.NoConfigAxis {
+ ca.cppStd = bp2buildResolveCppStdValue(props.Cpp_std, props.Gnu_extensions)
- allSrcsLabelList := android.BazelLabelForModuleSrcExcludes(ctx, props.Srcs, props.Exclude_srcs)
- if len(props.Srcs) > 0 || len(props.Exclude_srcs) > 0 {
- anySrcs = true
+ if includeBuildDirectory(props.Include_build_directory) {
+ localIncludeDirs = append(localIncludeDirs, ".")
}
- return bazel.AppendBazelLabelLists(allSrcsLabelList, generatedHdrsAndSrcsLabelList), anySrcs
}
- archVariantCompilerProps := module.GetArchVariantProperties(ctx, &BaseCompilerProperties{})
- for axis, configToProps := range archVariantCompilerProps {
- for config, props := range configToProps {
- if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
- // If there's arch specific srcs or exclude_srcs, generate a select entry for it.
- // TODO(b/186153868): do this for OS specific srcs and exclude_srcs too.
- if srcsList, ok := parseSrcs(baseCompilerProps); ok {
- srcs.SetSelectValue(axis, config, srcsList)
+ ca.absoluteIncludes.SetSelectValue(axis, config, props.Include_dirs)
+ ca.localIncludes.SetSelectValue(axis, config, localIncludeDirs)
+
+ ca.copts.SetSelectValue(axis, config, parseCommandLineFlags(props.Cflags))
+ ca.asFlags.SetSelectValue(axis, config, parseCommandLineFlags(props.Asflags))
+ ca.conlyFlags.SetSelectValue(axis, config, parseCommandLineFlags(props.Conlyflags))
+ ca.cppFlags.SetSelectValue(axis, config, parseCommandLineFlags(props.Cppflags))
+ ca.rtti.SetSelectValue(axis, config, props.Rtti)
+}
+
+func (ca *compilerAttributes) convertStlProps(ctx android.TopDownMutatorContext, module *Module) {
+ stlPropsByArch := module.GetArchVariantProperties(ctx, &StlProperties{})
+ for _, configToProps := range stlPropsByArch {
+ for _, props := range configToProps {
+ if stlProps, ok := props.(*StlProperties); ok {
+ if stlProps.Stl == nil {
+ continue
}
-
- if axis == bazel.NoConfigAxis {
- // If cpp_std is not specified, don't generate it in the
- // BUILD file. For readability purposes, cpp_std and gnu_extensions are
- // combined into a single -std=<version> copt, except in the
- // default case where cpp_std is nil and gnu_extensions is true or unspecified,
- // then the toolchain's default "gnu++17" will be used.
- if baseCompilerProps.Cpp_std != nil {
- // TODO(b/202491296): Handle C_std.
- // These transformations are shared with compiler.go.
- cppStdVal := parseCppStd(baseCompilerProps.Cpp_std)
- _, cppStdVal = maybeReplaceGnuToC(baseCompilerProps.Gnu_extensions, "", cppStdVal)
- cppStd = &cppStdVal
- } else if baseCompilerProps.Gnu_extensions != nil && !*baseCompilerProps.Gnu_extensions {
- cppStdVal := "c++17"
- cppStd = &cppStdVal
- }
+ if ca.stl == nil {
+ ca.stl = stlProps.Stl
+ } else if ca.stl != stlProps.Stl {
+ ctx.ModuleErrorf("Unsupported conversion: module with different stl for different variants: %s and %s", *ca.stl, stlProps.Stl)
}
-
- var archVariantCopts []string
- archVariantCopts = append(archVariantCopts, parseCommandLineFlags(baseCompilerProps.Cflags)...)
- archVariantAsflags := parseCommandLineFlags(baseCompilerProps.Asflags)
-
- localIncludeDirs := baseCompilerProps.Local_include_dirs
- if axis == bazel.NoConfigAxis && includeBuildDirectory(baseCompilerProps.Include_build_directory) {
- localIncludeDirs = append(localIncludeDirs, ".")
- }
-
- absoluteIncludes.SetSelectValue(axis, config, baseCompilerProps.Include_dirs)
- localIncludes.SetSelectValue(axis, config, localIncludeDirs)
-
- copts.SetSelectValue(axis, config, archVariantCopts)
- asFlags.SetSelectValue(axis, config, archVariantAsflags)
- conlyFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Conlyflags))
- cppFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Cppflags))
- rtti.SetSelectValue(axis, config, baseCompilerProps.Rtti)
}
}
}
+}
- srcs.ResolveExcludes()
- absoluteIncludes.DeduplicateAxesFromBase()
- localIncludes.DeduplicateAxesFromBase()
-
+func (ca *compilerAttributes) convertProductVariables(ctx android.TopDownMutatorContext, productVariableProps android.ProductConfigProperties) {
productVarPropNameToAttribute := map[string]*bazel.StringListAttribute{
- "Cflags": &copts,
- "Asflags": &asFlags,
- "CppFlags": &cppFlags,
+ "Cflags": &ca.copts,
+ "Asflags": &ca.asFlags,
+ "CppFlags": &ca.cppFlags,
}
- productVariableProps := android.ProductVariableProperties(ctx)
for propName, attr := range productVarPropNameToAttribute {
if props, exists := productVariableProps[propName]; exists {
for _, prop := range props {
@@ -350,39 +331,126 @@
}
}
}
+}
- srcs, cSrcs, asSrcs := groupSrcsByExtension(ctx, srcs)
+func (ca *compilerAttributes) finalize(ctx android.TopDownMutatorContext, implementationHdrs bazel.LabelListAttribute) {
+ ca.srcs.ResolveExcludes()
+ partitionedSrcs := groupSrcsByExtension(ctx, ca.srcs)
- stlPropsByArch := module.GetArchVariantProperties(ctx, &StlProperties{})
- for _, configToProps := range stlPropsByArch {
- for _, props := range configToProps {
- if stlProps, ok := props.(*StlProperties); ok {
- if stlProps.Stl != nil {
- if stl == nil {
- stl = stlProps.Stl
- } else {
- if stl != stlProps.Stl {
- ctx.ModuleErrorf("Unsupported conversion: module with different stl for different variants: %s and %s", *stl, stlProps.Stl)
- }
- }
- }
+ for p, lla := range partitionedSrcs {
+ // if there are no sources, there is no need for headers
+ if lla.IsEmpty() {
+ continue
+ }
+ lla.Append(implementationHdrs)
+ partitionedSrcs[p] = lla
+ }
+
+ ca.srcs = partitionedSrcs[cppSrcPartition]
+ ca.cSrcs = partitionedSrcs[cSrcPartition]
+ ca.asSrcs = partitionedSrcs[asSrcPartition]
+
+ ca.absoluteIncludes.DeduplicateAxesFromBase()
+ ca.localIncludes.DeduplicateAxesFromBase()
+}
+
+// Parse srcs from an arch or OS's props value.
+func parseSrcs(ctx android.TopDownMutatorContext, props *BaseCompilerProperties) (bazel.LabelList, bool) {
+ anySrcs := false
+ // Add srcs-like dependencies such as generated files.
+ // First create a LabelList containing these dependencies, then merge the values with srcs.
+ generatedSrcsLabelList := android.BazelLabelForModuleDepsExcludes(ctx, props.Generated_sources, props.Exclude_generated_sources)
+ if len(props.Generated_sources) > 0 || len(props.Exclude_generated_sources) > 0 {
+ anySrcs = true
+ }
+
+ allSrcsLabelList := android.BazelLabelForModuleSrcExcludes(ctx, props.Srcs, props.Exclude_srcs)
+ if len(props.Srcs) > 0 || len(props.Exclude_srcs) > 0 {
+ anySrcs = true
+ }
+ return bazel.AppendBazelLabelLists(allSrcsLabelList, generatedSrcsLabelList), anySrcs
+}
+
+func bp2buildResolveCppStdValue(cpp_std *string, gnu_extensions *bool) *string {
+ var cppStd *string
+ // If cpp_std is not specified, don't generate it in the
+ // BUILD file. For readability purposes, cpp_std and gnu_extensions are
+ // combined into a single -std=<version> copt, except in the
+ // default case where cpp_std is nil and gnu_extensions is true or unspecified,
+ // then the toolchain's default "gnu++17" will be used.
+ if cpp_std != nil {
+ // TODO(b/202491296): Handle C_std.
+ // These transformations are shared with compiler.go.
+ cppStdVal := parseCppStd(cpp_std)
+ _, cppStdVal = maybeReplaceGnuToC(gnu_extensions, "", cppStdVal)
+ cppStd = &cppStdVal
+ } else if gnu_extensions != nil && !*gnu_extensions {
+ cppStdVal := "c++17"
+ cppStd = &cppStdVal
+ }
+ return cppStd
+}
+
+// bp2BuildParseCompilerProps returns copts, srcs and hdrs and other attributes.
+func bp2BuildParseBaseProps(ctx android.TopDownMutatorContext, module *Module) baseAttributes {
+ archVariantCompilerProps := module.GetArchVariantProperties(ctx, &BaseCompilerProperties{})
+ archVariantLinkerProps := module.GetArchVariantProperties(ctx, &BaseLinkerProperties{})
+
+ var implementationHdrs bazel.LabelListAttribute
+
+ axisToConfigs := map[bazel.ConfigurationAxis]map[string]bool{}
+ allAxesAndConfigs := func(cp android.ConfigurationAxisToArchVariantProperties) {
+ for axis, configMap := range cp {
+ if _, ok := axisToConfigs[axis]; !ok {
+ axisToConfigs[axis] = map[string]bool{}
+ }
+ for config, _ := range configMap {
+ axisToConfigs[axis][config] = true
}
}
}
+ allAxesAndConfigs(archVariantCompilerProps)
+ allAxesAndConfigs(archVariantLinkerProps)
- return compilerAttributes{
- copts: copts,
- srcs: srcs,
- asFlags: asFlags,
- asSrcs: asSrcs,
- cSrcs: cSrcs,
- conlyFlags: conlyFlags,
- cppFlags: cppFlags,
- rtti: rtti,
- stl: stl,
- cppStd: cppStd,
- localIncludes: localIncludes,
- absoluteIncludes: absoluteIncludes,
+ compilerAttrs := compilerAttributes{}
+ linkerAttrs := linkerAttributes{}
+
+ for axis, configs := range axisToConfigs {
+ for config, _ := range configs {
+ var allHdrs []string
+ if baseCompilerProps, ok := archVariantCompilerProps[axis][config].(*BaseCompilerProperties); ok {
+ allHdrs = baseCompilerProps.Generated_headers
+
+ (&compilerAttrs).bp2buildForAxisAndConfig(ctx, axis, config, baseCompilerProps)
+ }
+
+ var exportHdrs []string
+
+ if baseLinkerProps, ok := archVariantLinkerProps[axis][config].(*BaseLinkerProperties); ok {
+ exportHdrs = baseLinkerProps.Export_generated_headers
+
+ (&linkerAttrs).bp2buildForAxisAndConfig(ctx, module.Binary(), axis, config, baseLinkerProps)
+ }
+ headers := maybePartitionExportedAndImplementationsDeps(ctx, !module.Binary(), allHdrs, exportHdrs, android.BazelLabelForModuleDeps)
+ implementationHdrs.SetSelectValue(axis, config, headers.implementation)
+ compilerAttrs.hdrs.SetSelectValue(axis, config, headers.export)
+ }
+ }
+
+ compilerAttrs.convertStlProps(ctx, module)
+ (&linkerAttrs).convertStripProps(ctx, module)
+
+ productVariableProps := android.ProductVariableProperties(ctx)
+
+ (&compilerAttrs).convertProductVariables(ctx, productVariableProps)
+ (&linkerAttrs).convertProductVariables(ctx, productVariableProps)
+
+ (&compilerAttrs).finalize(ctx, implementationHdrs)
+ (&linkerAttrs).finalize()
+
+ return baseAttributes{
+ compilerAttrs,
+ linkerAttrs,
}
}
@@ -407,121 +475,94 @@
features bazel.StringListAttribute
}
-// bp2BuildParseLinkerProps parses the linker properties of a module, including
-// configurable attribute values.
-func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) linkerAttributes {
+func (la *linkerAttributes) bp2buildForAxisAndConfig(ctx android.TopDownMutatorContext, isBinary bool, axis bazel.ConfigurationAxis, config string, props *BaseLinkerProperties) {
+ // Use a single variable to capture usage of nocrt in arch variants, so there's only 1 error message for this module
+ var axisFeatures []string
- var headerDeps bazel.LabelListAttribute
- var implementationHeaderDeps bazel.LabelListAttribute
- var deps bazel.LabelListAttribute
- var implementationDeps bazel.LabelListAttribute
- var dynamicDeps bazel.LabelListAttribute
- var implementationDynamicDeps bazel.LabelListAttribute
- var wholeArchiveDeps bazel.LabelListAttribute
- systemSharedDeps := bazel.LabelListAttribute{ForceSpecifyEmptyList: true}
+ // Excludes to parallel Soong:
+ // https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/linker.go;l=247-249;drc=088b53577dde6e40085ffd737a1ae96ad82fc4b0
+ staticLibs := android.FirstUniqueStrings(props.Static_libs)
+ staticDeps := maybePartitionExportedAndImplementationsDepsExcludes(ctx, !isBinary, staticLibs, props.Exclude_static_libs, props.Export_static_lib_headers, bazelLabelForStaticDepsExcludes)
- var linkopts bazel.StringListAttribute
- var linkCrt bazel.BoolAttribute
- var additionalLinkerInputs bazel.LabelListAttribute
- var useLibcrt bazel.BoolAttribute
+ headerLibs := android.FirstUniqueStrings(props.Header_libs)
+ hDeps := maybePartitionExportedAndImplementationsDeps(ctx, !isBinary, headerLibs, props.Export_header_lib_headers, bazelLabelForHeaderDeps)
- var stripKeepSymbols bazel.BoolAttribute
- var stripKeepSymbolsAndDebugFrame bazel.BoolAttribute
- var stripKeepSymbolsList bazel.StringListAttribute
- var stripAll bazel.BoolAttribute
- var stripNone bazel.BoolAttribute
+ (&hDeps.export).Append(staticDeps.export)
+ la.deps.SetSelectValue(axis, config, hDeps.export)
- var features bazel.StringListAttribute
+ (&hDeps.implementation).Append(staticDeps.implementation)
+ la.implementationDeps.SetSelectValue(axis, config, hDeps.implementation)
+ wholeStaticLibs := android.FirstUniqueStrings(props.Whole_static_libs)
+ la.wholeArchiveDeps.SetSelectValue(axis, config, bazelLabelForWholeDepsExcludes(ctx, wholeStaticLibs, props.Exclude_static_libs))
+
+ systemSharedLibs := props.System_shared_libs
+ // systemSharedLibs distinguishes between nil/empty list behavior:
+ // nil -> use default values
+ // empty list -> no values specified
+ if len(systemSharedLibs) > 0 {
+ systemSharedLibs = android.FirstUniqueStrings(systemSharedLibs)
+ }
+ la.systemDynamicDeps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, systemSharedLibs))
+
+ sharedLibs := android.FirstUniqueStrings(props.Shared_libs)
+ sharedDeps := maybePartitionExportedAndImplementationsDepsExcludes(ctx, !isBinary, sharedLibs, props.Exclude_shared_libs, props.Export_shared_lib_headers, bazelLabelForSharedDepsExcludes)
+ la.dynamicDeps.SetSelectValue(axis, config, sharedDeps.export)
+ la.implementationDynamicDeps.SetSelectValue(axis, config, sharedDeps.implementation)
+
+ if !BoolDefault(props.Pack_relocations, packRelocationsDefault) {
+ axisFeatures = append(axisFeatures, "disable_pack_relocations")
+ }
+
+ if Bool(props.Allow_undefined_symbols) {
+ axisFeatures = append(axisFeatures, "-no_undefined_symbols")
+ }
+
+ var linkerFlags []string
+ if len(props.Ldflags) > 0 {
+ linkerFlags = append(linkerFlags, props.Ldflags...)
+ // binaries remove static flag if -shared is in the linker flags
+ if isBinary && android.InList("-shared", linkerFlags) {
+ axisFeatures = append(axisFeatures, "-static_flag")
+ }
+ }
+ if props.Version_script != nil {
+ label := android.BazelLabelForModuleSrcSingle(ctx, *props.Version_script)
+ la.additionalLinkerInputs.SetSelectValue(axis, config, bazel.LabelList{Includes: []bazel.Label{label}})
+ linkerFlags = append(linkerFlags, fmt.Sprintf("-Wl,--version-script,$(location %s)", label.Label))
+ }
+ la.linkopts.SetSelectValue(axis, config, linkerFlags)
+ la.useLibcrt.SetSelectValue(axis, config, props.libCrt())
+
+ // it's very unlikely for nocrt to be arch variant, so bp2build doesn't support it.
+ if props.crt() != nil {
+ if axis == bazel.NoConfigAxis {
+ la.linkCrt.SetSelectValue(axis, config, props.crt())
+ } else if axis == bazel.ArchConfigurationAxis {
+ ctx.ModuleErrorf("nocrt is not supported for arch variants")
+ }
+ }
+
+ if axisFeatures != nil {
+ la.features.SetSelectValue(axis, config, axisFeatures)
+ }
+}
+
+func (la *linkerAttributes) convertStripProps(ctx android.TopDownMutatorContext, module *Module) {
for axis, configToProps := range module.GetArchVariantProperties(ctx, &StripProperties{}) {
for config, props := range configToProps {
if stripProperties, ok := props.(*StripProperties); ok {
- stripKeepSymbols.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols)
- stripKeepSymbolsList.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols_list)
- stripKeepSymbolsAndDebugFrame.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols_and_debug_frame)
- stripAll.SetSelectValue(axis, config, stripProperties.Strip.All)
- stripNone.SetSelectValue(axis, config, stripProperties.Strip.None)
+ la.stripKeepSymbols.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols)
+ la.stripKeepSymbolsList.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols_list)
+ la.stripKeepSymbolsAndDebugFrame.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols_and_debug_frame)
+ la.stripAll.SetSelectValue(axis, config, stripProperties.Strip.All)
+ la.stripNone.SetSelectValue(axis, config, stripProperties.Strip.None)
}
}
}
+}
- // Use a single variable to capture usage of nocrt in arch variants, so there's only 1 error message for this module
- var disallowedArchVariantCrt bool
-
- for axis, configToProps := range module.GetArchVariantProperties(ctx, &BaseLinkerProperties{}) {
- for config, props := range configToProps {
- if baseLinkerProps, ok := props.(*BaseLinkerProperties); ok {
- var axisFeatures []string
-
- // Excludes to parallel Soong:
- // https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/linker.go;l=247-249;drc=088b53577dde6e40085ffd737a1ae96ad82fc4b0
- staticLibs := android.FirstUniqueStrings(baseLinkerProps.Static_libs)
- staticDeps := partitionExportedAndImplementationsDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs, baseLinkerProps.Export_static_lib_headers, bazelLabelForStaticDepsExcludes)
- deps.SetSelectValue(axis, config, staticDeps.export)
- implementationDeps.SetSelectValue(axis, config, staticDeps.implementation)
-
- wholeStaticLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs)
- wholeArchiveDeps.SetSelectValue(axis, config, bazelLabelForWholeDepsExcludes(ctx, wholeStaticLibs, baseLinkerProps.Exclude_static_libs))
-
- systemSharedLibs := baseLinkerProps.System_shared_libs
- // systemSharedLibs distinguishes between nil/empty list behavior:
- // nil -> use default values
- // empty list -> no values specified
- if len(systemSharedLibs) > 0 {
- systemSharedLibs = android.FirstUniqueStrings(systemSharedLibs)
- }
- systemSharedDeps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, systemSharedLibs))
-
- sharedLibs := android.FirstUniqueStrings(baseLinkerProps.Shared_libs)
- sharedDeps := partitionExportedAndImplementationsDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs, baseLinkerProps.Export_shared_lib_headers, bazelLabelForSharedDepsExcludes)
- dynamicDeps.SetSelectValue(axis, config, sharedDeps.export)
- implementationDynamicDeps.SetSelectValue(axis, config, sharedDeps.implementation)
-
- headerLibs := android.FirstUniqueStrings(baseLinkerProps.Header_libs)
- hDeps := partitionExportedAndImplementationsDeps(ctx, headerLibs, baseLinkerProps.Export_header_lib_headers, bazelLabelForHeaderDeps)
-
- headerDeps.SetSelectValue(axis, config, hDeps.export)
- implementationHeaderDeps.SetSelectValue(axis, config, hDeps.implementation)
-
- if !BoolDefault(baseLinkerProps.Pack_relocations, packRelocationsDefault) {
- axisFeatures = append(axisFeatures, "disable_pack_relocations")
- }
-
- if Bool(baseLinkerProps.Allow_undefined_symbols) {
- axisFeatures = append(axisFeatures, "-no_undefined_symbols")
- }
-
- var linkerFlags []string
- if len(baseLinkerProps.Ldflags) > 0 {
- linkerFlags = append(linkerFlags, baseLinkerProps.Ldflags...)
- }
- if baseLinkerProps.Version_script != nil {
- label := android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script)
- additionalLinkerInputs.SetSelectValue(axis, config, bazel.LabelList{Includes: []bazel.Label{label}})
- linkerFlags = append(linkerFlags, fmt.Sprintf("-Wl,--version-script,$(location %s)", label.Label))
- }
- linkopts.SetSelectValue(axis, config, linkerFlags)
- useLibcrt.SetSelectValue(axis, config, baseLinkerProps.libCrt())
-
- // it's very unlikely for nocrt to be arch variant, so bp2build doesn't support it.
- if baseLinkerProps.crt() != nil {
- if axis == bazel.NoConfigAxis {
- linkCrt.SetSelectValue(axis, config, baseLinkerProps.crt())
- } else if axis == bazel.ArchConfigurationAxis {
- disallowedArchVariantCrt = true
- }
- }
-
- if axisFeatures != nil {
- features.SetSelectValue(axis, config, axisFeatures)
- }
- }
- }
- }
-
- if disallowedArchVariantCrt {
- ctx.ModuleErrorf("nocrt is not supported for arch variants")
- }
+func (la *linkerAttributes) convertProductVariables(ctx android.TopDownMutatorContext, productVariableProps android.ProductConfigProperties) {
type productVarDep struct {
// the name of the corresponding excludes field, if one exists
@@ -534,12 +575,11 @@
productVarToDepFields := map[string]productVarDep{
// product variables do not support exclude_shared_libs
- "Shared_libs": productVarDep{attribute: &implementationDynamicDeps, depResolutionFunc: bazelLabelForSharedDepsExcludes},
- "Static_libs": productVarDep{"Exclude_static_libs", &implementationDeps, bazelLabelForStaticDepsExcludes},
- "Whole_static_libs": productVarDep{"Exclude_static_libs", &wholeArchiveDeps, bazelLabelForWholeDepsExcludes},
+ "Shared_libs": productVarDep{attribute: &la.implementationDynamicDeps, depResolutionFunc: bazelLabelForSharedDepsExcludes},
+ "Static_libs": productVarDep{"Exclude_static_libs", &la.implementationDeps, bazelLabelForStaticDepsExcludes},
+ "Whole_static_libs": productVarDep{"Exclude_static_libs", &la.wholeArchiveDeps, bazelLabelForWholeDepsExcludes},
}
- productVariableProps := android.ProductVariableProperties(ctx)
for name, dep := range productVarToDepFields {
props, exists := productVariableProps[name]
excludeProps, excludesExists := productVariableProps[dep.excludesField]
@@ -574,38 +614,15 @@
dep.attribute.SetSelectValue(bazel.ProductVariableConfigurationAxis(config), config, dep.depResolutionFunc(ctx, android.FirstUniqueStrings(includes), excludes))
}
}
+}
- headerDeps.Append(deps)
- implementationHeaderDeps.Append(implementationDeps)
-
- headerDeps.ResolveExcludes()
- implementationHeaderDeps.ResolveExcludes()
- dynamicDeps.ResolveExcludes()
- implementationDynamicDeps.ResolveExcludes()
- wholeArchiveDeps.ResolveExcludes()
-
- return linkerAttributes{
- deps: headerDeps,
- implementationDeps: implementationHeaderDeps,
- dynamicDeps: dynamicDeps,
- implementationDynamicDeps: implementationDynamicDeps,
- wholeArchiveDeps: wholeArchiveDeps,
- systemDynamicDeps: systemSharedDeps,
-
- linkCrt: linkCrt,
- linkopts: linkopts,
- useLibcrt: useLibcrt,
- additionalLinkerInputs: additionalLinkerInputs,
-
- // Strip properties
- stripKeepSymbols: stripKeepSymbols,
- stripKeepSymbolsAndDebugFrame: stripKeepSymbolsAndDebugFrame,
- stripKeepSymbolsList: stripKeepSymbolsList,
- stripAll: stripAll,
- stripNone: stripNone,
-
- features: features,
- }
+func (la *linkerAttributes) finalize() {
+ la.deps.ResolveExcludes()
+ la.implementationDeps.ResolveExcludes()
+ la.dynamicDeps.ResolveExcludes()
+ la.implementationDynamicDeps.ResolveExcludes()
+ la.wholeArchiveDeps.ResolveExcludes()
+ la.systemDynamicDeps.ForceSpecifyEmptyList = true
}
// Relativize a list of root-relative paths with respect to the module's
@@ -728,3 +745,29 @@
func bazelLabelForSharedDepsExcludes(ctx android.TopDownMutatorContext, modules, excludes []string) bazel.LabelList {
return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForSharedModule)
}
+
+type binaryLinkerAttrs struct {
+ Linkshared *bool
+}
+
+func bp2buildBinaryLinkerProps(ctx android.TopDownMutatorContext, m *Module) binaryLinkerAttrs {
+ attrs := binaryLinkerAttrs{}
+ archVariantProps := m.GetArchVariantProperties(ctx, &BinaryLinkerProperties{})
+ for axis, configToProps := range archVariantProps {
+ for _, p := range configToProps {
+ props := p.(*BinaryLinkerProperties)
+ staticExecutable := props.Static_executable
+ if axis == bazel.NoConfigAxis {
+ if linkBinaryShared := !proptools.Bool(staticExecutable); !linkBinaryShared {
+ attrs.Linkshared = &linkBinaryShared
+ }
+ } else if staticExecutable != nil {
+ // TODO(b/202876379): Static_executable is arch-variant; however, linkshared is a
+ // nonconfigurable attribute. Only 4 AOSP modules use this feature, defer handling
+ ctx.ModuleErrorf("bp2build cannot migrate a module with arch/target-specific static_executable values")
+ }
+ }
+ }
+
+ return attrs
+}
diff --git a/cc/builder.go b/cc/builder.go
index b494f7b..abd5f1d 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -238,14 +238,6 @@
},
"asFlags")
- // Rule to invoke windres, for interaction with Windows resources.
- windres = pctx.AndroidStaticRule("windres",
- blueprint.RuleParams{
- Command: "$windresCmd $flags -I$$(dirname $in) -i $in -o $out --preprocessor \"${config.ClangBin}/clang -E -xc-header -DRC_INVOKED\"",
- CommandDeps: []string{"$windresCmd"},
- },
- "windresCmd", "flags")
-
_ = pctx.SourcePathVariable("sAbiDumper", "prebuilts/clang-tools/${config.HostPrebuiltTag}/bin/header-abi-dumper")
// -w has been added since header-abi-dumper does not need to produce any sort of diagnostic information.
@@ -421,7 +413,7 @@
// Objects is a collection of file paths corresponding to outputs for C++ related build statements.
type Objects struct {
objFiles android.Paths
- tidyFiles android.Paths
+ tidyFiles android.WritablePaths
coverageFiles android.Paths
sAbiDumpFiles android.Paths
kytheFiles android.Paths
@@ -430,7 +422,7 @@
func (a Objects) Copy() Objects {
return Objects{
objFiles: append(android.Paths{}, a.objFiles...),
- tidyFiles: append(android.Paths{}, a.tidyFiles...),
+ tidyFiles: append(android.WritablePaths{}, a.tidyFiles...),
coverageFiles: append(android.Paths{}, a.coverageFiles...),
sAbiDumpFiles: append(android.Paths{}, a.sAbiDumpFiles...),
kytheFiles: append(android.Paths{}, a.kytheFiles...),
@@ -459,11 +451,11 @@
// Source files are one-to-one with tidy, coverage, or kythe files, if enabled.
objFiles := make(android.Paths, len(srcFiles))
- var tidyFiles android.Paths
+ var tidyFiles android.WritablePaths
noTidySrcsMap := make(map[android.Path]bool)
var tidyVars string
if flags.tidy {
- tidyFiles = make(android.Paths, 0, len(srcFiles))
+ tidyFiles = make(android.WritablePaths, 0, len(srcFiles))
for _, path := range noTidySrcs {
noTidySrcsMap[path] = true
}
@@ -577,20 +569,6 @@
},
})
continue
- case ".rc":
- ctx.Build(pctx, android.BuildParams{
- Rule: windres,
- Description: "windres " + srcFile.Rel(),
- Output: objFile,
- Input: srcFile,
- Implicits: cFlagsDeps,
- OrderOnly: pathDeps,
- Args: map[string]string{
- "windresCmd": mingwCmd(flags.toolchain, "windres"),
- "flags": shareFlags("flags", flags.toolchain.WindresFlags()),
- },
- })
- continue
case ".o":
objFiles[i] = srcFile
continue
@@ -741,7 +719,7 @@
// Generate a rule for compiling multiple .o files to a static library (.a)
func transformObjToStaticLib(ctx android.ModuleContext,
objFiles android.Paths, wholeStaticLibs android.Paths,
- flags builderFlags, outputFile android.ModuleOutPath, deps android.Paths) {
+ flags builderFlags, outputFile android.ModuleOutPath, deps android.Paths, validations android.WritablePaths) {
arCmd := "${config.ClangBin}/llvm-ar"
arFlags := ""
@@ -756,6 +734,7 @@
Output: outputFile,
Inputs: objFiles,
Implicits: deps,
+ Validations: validations.Paths(),
Args: map[string]string{
"arFlags": "crsPD" + arFlags,
"arCmd": arCmd,
diff --git a/cc/cc.go b/cc/cc.go
index 1c65549..32652c1 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -325,7 +325,7 @@
SnapshotStaticLibs []string `blueprint:"mutated"`
SnapshotRuntimeLibs []string `blueprint:"mutated"`
- Installable *bool
+ Installable *bool `android:"arch_variant"`
// Set by factories of module types that can only be referenced from variants compiled against
// the SDK.
@@ -1865,7 +1865,7 @@
}
func (c *Module) maybeInstall(ctx ModuleContext, apexInfo android.ApexInfo) {
- if !proptools.BoolDefault(c.Properties.Installable, true) {
+ if !proptools.BoolDefault(c.Installable(), true) {
// If the module has been specifically configure to not be installed then
// hide from make as otherwise it will break when running inside make
// as the output path to install will not be specified. Not all uninstallable
@@ -3260,6 +3260,11 @@
}
func (c *Module) Installable() *bool {
+ if c.library != nil {
+ if i := c.library.installable(); i != nil {
+ return i
+ }
+ }
return c.Properties.Installable
}
diff --git a/cc/compiler.go b/cc/compiler.go
index 2ac7bf3..00df669 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -537,11 +537,6 @@
"-I"+android.PathForModuleGen(ctx, "yacc", ctx.ModuleDir()).String())
}
- if compiler.hasSrcExt(".mc") {
- flags.Local.CommonFlags = append(flags.Local.CommonFlags,
- "-I"+android.PathForModuleGen(ctx, "windmc", ctx.ModuleDir()).String())
- }
-
if compiler.hasSrcExt(".aidl") {
flags.aidlFlags = append(flags.aidlFlags, compiler.Properties.Aidl.Flags...)
if len(compiler.Properties.Aidl.Local_include_dirs) > 0 {
diff --git a/cc/config/Android.bp b/cc/config/Android.bp
index 3e8ee48..7b7ee28 100644
--- a/cc/config/Android.bp
+++ b/cc/config/Android.bp
@@ -24,7 +24,7 @@
"x86_device.go",
"x86_64_device.go",
- "x86_darwin_host.go",
+ "darwin_host.go",
"x86_linux_host.go",
"x86_linux_bionic_host.go",
"x86_windows_host.go",
diff --git a/cc/config/bp2build.go b/cc/config/bp2build.go
index d19f5ac..4797acc 100644
--- a/cc/config/bp2build.go
+++ b/cc/config/bp2build.go
@@ -16,9 +16,13 @@
import (
"fmt"
+ "reflect"
"regexp"
"sort"
"strings"
+
+ "android/soong/android"
+ "github.com/google/blueprint"
)
const (
@@ -26,18 +30,27 @@
)
type bazelVarExporter interface {
- asBazel(exportedStringVariables, exportedStringListVariables) []bazelConstant
+ asBazel(android.Config, exportedStringVariables, exportedStringListVariables, exportedConfigDependingVariables) []bazelConstant
}
// Helpers for exporting cc configuration information to Bazel.
var (
- // Map containing toolchain variables that are independent of the
+ // Maps containing toolchain variables that are independent of the
// environment variables of the build.
exportedStringListVars = exportedStringListVariables{}
exportedStringVars = exportedStringVariables{}
exportedStringListDictVars = exportedStringListDictVariables{}
+
+ /// Maps containing variables that are dependent on the build config.
+ exportedConfigDependingVars = exportedConfigDependingVariables{}
)
+type exportedConfigDependingVariables map[string]interface{}
+
+func (m exportedConfigDependingVariables) Set(k string, v interface{}) {
+ m[k] = v
+}
+
// Ensure that string s has no invalid characters to be generated into the bzl file.
func validateCharacters(s string) string {
for _, c := range []string{`\n`, `"`, `\`} {
@@ -74,10 +87,14 @@
return strings.Join(list, "\n")
}
-func (m exportedStringVariables) asBazel(stringScope exportedStringVariables, stringListScope exportedStringListVariables) []bazelConstant {
+func (m exportedStringVariables) asBazel(config android.Config,
+ stringVars exportedStringVariables, stringListVars exportedStringListVariables, cfgDepVars exportedConfigDependingVariables) []bazelConstant {
ret := make([]bazelConstant, 0, len(m))
for k, variableValue := range m {
- expandedVar := expandVar(variableValue, exportedStringVars, exportedStringListVars)
+ expandedVar, err := expandVar(config, variableValue, stringVars, stringListVars, cfgDepVars)
+ if err != nil {
+ panic(fmt.Errorf("error expanding config variable %s: %s", k, err))
+ }
if len(expandedVar) > 1 {
panic(fmt.Errorf("%s expands to more than one string value: %s", variableValue, expandedVar))
}
@@ -101,7 +118,9 @@
m[k] = v
}
-func (m exportedStringListVariables) asBazel(stringScope exportedStringVariables, stringListScope exportedStringListVariables) []bazelConstant {
+func (m exportedStringListVariables) asBazel(config android.Config,
+ stringScope exportedStringVariables, stringListScope exportedStringListVariables,
+ exportedVars exportedConfigDependingVariables) []bazelConstant {
ret := make([]bazelConstant, 0, len(m))
// For each exported variable, recursively expand elements in the variableValue
// list to ensure that interpolated variables are expanded according to their values
@@ -109,7 +128,11 @@
for k, variableValue := range m {
var expandedVars []string
for _, v := range variableValue {
- expandedVars = append(expandedVars, expandVar(v, stringScope, stringListScope)...)
+ expandedVar, err := expandVar(config, v, stringScope, stringListScope, exportedVars)
+ if err != nil {
+ panic(fmt.Errorf("Error expanding config variable %s=%s: %s", k, v, err))
+ }
+ expandedVars = append(expandedVars, expandedVar...)
}
// Assign the list as a bzl-private variable; this variable will be exported
// out through a constants struct later.
@@ -121,6 +144,18 @@
return ret
}
+// Convenience function to declare a static "source path" variable and export it to Bazel's cc_toolchain.
+func exportVariableConfigMethod(name string, method interface{}) blueprint.Variable {
+ exportedConfigDependingVars.Set(name, method)
+ return pctx.VariableConfigMethod(name, method)
+}
+
+// Convenience function to declare a static "source path" variable and export it to Bazel's cc_toolchain.
+func exportSourcePathVariable(name string, value string) {
+ pctx.SourcePathVariable(name, value)
+ exportedStringVars.Set(name, value)
+}
+
// Convenience function to declare a static variable and export it to Bazel's cc_toolchain.
func exportStringListStaticVariable(name string, value []string) {
pctx.StaticVariable(name, strings.Join(value, " "))
@@ -145,7 +180,8 @@
}
// Since dictionaries are not supported in Ninja, we do not expand variables for dictionaries
-func (m exportedStringListDictVariables) asBazel(_ exportedStringVariables, _ exportedStringListVariables) []bazelConstant {
+func (m exportedStringListDictVariables) asBazel(_ android.Config, _ exportedStringVariables,
+ _ exportedStringListVariables, _ exportedConfigDependingVariables) []bazelConstant {
ret := make([]bazelConstant, 0, len(m))
for k, dict := range m {
ret = append(ret, bazelConstant{
@@ -158,19 +194,20 @@
// BazelCcToolchainVars generates bzl file content containing variables for
// Bazel's cc_toolchain configuration.
-func BazelCcToolchainVars() string {
+func BazelCcToolchainVars(config android.Config) string {
return bazelToolchainVars(
+ config,
exportedStringListDictVars,
exportedStringListVars,
exportedStringVars)
}
-func bazelToolchainVars(vars ...bazelVarExporter) string {
+func bazelToolchainVars(config android.Config, vars ...bazelVarExporter) string {
ret := "# GENERATED FOR BAZEL FROM SOONG. DO NOT EDIT.\n\n"
results := []bazelConstant{}
for _, v := range vars {
- results = append(results, v.asBazel(exportedStringVars, exportedStringListVars)...)
+ results = append(results, v.asBazel(config, exportedStringVars, exportedStringListVars, exportedConfigDependingVars)...)
}
sort.Slice(results, func(i, j int) bool { return results[i].variableName < results[j].variableName })
@@ -201,34 +238,35 @@
// string slice than to handle a pass-by-referenced map, which would make it
// quite complex to track depth-first interpolations. It's also unlikely the
// interpolation stacks are deep (n > 1).
-func expandVar(toExpand string, stringScope exportedStringVariables, stringListScope exportedStringListVariables) []string {
+func expandVar(config android.Config, toExpand string, stringScope exportedStringVariables,
+ stringListScope exportedStringListVariables, exportedVars exportedConfigDependingVariables) ([]string, error) {
// e.g. "${ExternalCflags}"
r := regexp.MustCompile(`\${([a-zA-Z0-9_]+)}`)
// Internal recursive function.
- var expandVarInternal func(string, map[string]bool) []string
- expandVarInternal = func(toExpand string, seenVars map[string]bool) []string {
- var ret []string
- for _, v := range strings.Split(toExpand, " ") {
- matches := r.FindStringSubmatch(v)
+ var expandVarInternal func(string, map[string]bool) (string, error)
+ expandVarInternal = func(toExpand string, seenVars map[string]bool) (string, error) {
+ var ret string
+ remainingString := toExpand
+ for len(remainingString) > 0 {
+ matches := r.FindStringSubmatch(remainingString)
if len(matches) == 0 {
- return []string{v}
+ return ret + remainingString, nil
}
-
if len(matches) != 2 {
- panic(fmt.Errorf(
- "Expected to only match 1 subexpression in %s, got %d",
- v,
- len(matches)-1))
+ panic(fmt.Errorf("Expected to only match 1 subexpression in %s, got %d", remainingString, len(matches)-1))
}
+ matchIndex := strings.Index(remainingString, matches[0])
+ ret += remainingString[:matchIndex]
+ remainingString = remainingString[matchIndex+len(matches[0]):]
// Index 1 of FindStringSubmatch contains the subexpression match
// (variable name) of the capture group.
variable := matches[1]
// toExpand contains a variable.
if _, ok := seenVars[variable]; ok {
- panic(fmt.Errorf(
- "Unbounded recursive interpolation of variable: %s", variable))
+ return ret, fmt.Errorf(
+ "Unbounded recursive interpolation of variable: %s", variable)
}
// A map is passed-by-reference. Create a new map for
// this scope to prevent variables seen in one depth-first expansion
@@ -239,15 +277,65 @@
}
newSeenVars[variable] = true
if unexpandedVars, ok := stringListScope[variable]; ok {
+ expandedVars := []string{}
for _, unexpandedVar := range unexpandedVars {
- ret = append(ret, expandVarInternal(unexpandedVar, newSeenVars)...)
+ expandedVar, err := expandVarInternal(unexpandedVar, newSeenVars)
+ if err != nil {
+ return ret, err
+ }
+ expandedVars = append(expandedVars, expandedVar)
}
+ ret += strings.Join(expandedVars, " ")
} else if unexpandedVar, ok := stringScope[variable]; ok {
- ret = append(ret, expandVarInternal(unexpandedVar, newSeenVars)...)
+ expandedVar, err := expandVarInternal(unexpandedVar, newSeenVars)
+ if err != nil {
+ return ret, err
+ }
+ ret += expandedVar
+ } else if unevaluatedVar, ok := exportedVars[variable]; ok {
+ evalFunc := reflect.ValueOf(unevaluatedVar)
+ validateVariableMethod(variable, evalFunc)
+ evaluatedResult := evalFunc.Call([]reflect.Value{reflect.ValueOf(config)})
+ evaluatedValue := evaluatedResult[0].Interface().(string)
+ expandedVar, err := expandVarInternal(evaluatedValue, newSeenVars)
+ if err != nil {
+ return ret, err
+ }
+ ret += expandedVar
+ } else {
+ return "", fmt.Errorf("Unbound config variable %s", variable)
}
}
- return ret
+ return ret, nil
+ }
+ var ret []string
+ for _, v := range strings.Split(toExpand, " ") {
+ val, err := expandVarInternal(v, map[string]bool{})
+ if err != nil {
+ return ret, err
+ }
+ ret = append(ret, val)
}
- return expandVarInternal(toExpand, map[string]bool{})
+ return ret, nil
+}
+
+func validateVariableMethod(name string, methodValue reflect.Value) {
+ methodType := methodValue.Type()
+ if methodType.Kind() != reflect.Func {
+ panic(fmt.Errorf("method given for variable %s is not a function",
+ name))
+ }
+ if n := methodType.NumIn(); n != 1 {
+ panic(fmt.Errorf("method for variable %s has %d inputs (should be 1)",
+ name, n))
+ }
+ if n := methodType.NumOut(); n != 1 {
+ panic(fmt.Errorf("method for variable %s has %d outputs (should be 1)",
+ name, n))
+ }
+ if kind := methodType.Out(0).Kind(); kind != reflect.String {
+ panic(fmt.Errorf("method for variable %s does not return a string",
+ name))
+ }
}
diff --git a/cc/config/bp2build_test.go b/cc/config/bp2build_test.go
index 883597a..3118df1 100644
--- a/cc/config/bp2build_test.go
+++ b/cc/config/bp2build_test.go
@@ -16,13 +16,21 @@
import (
"testing"
+
+ "android/soong/android"
)
func TestExpandVars(t *testing.T) {
+ android_arm64_config := android.TestConfig("out", nil, "", nil)
+ android_arm64_config.BuildOS = android.Android
+ android_arm64_config.BuildArch = android.Arm64
+
testCases := []struct {
description string
+ config android.Config
stringScope exportedStringVariables
stringListScope exportedStringListVariables
+ configVars exportedConfigDependingVariables
toExpand string
expectedValues []string
}{
@@ -57,7 +65,7 @@
"bar": []string{"baz", "${qux}"},
},
toExpand: "${foo}",
- expectedValues: []string{"baz", "hello"},
+ expectedValues: []string{"baz hello"},
},
{
description: "double level expansion",
@@ -75,7 +83,7 @@
"b": []string{"d"},
},
toExpand: "${a}",
- expectedValues: []string{"d", "c"},
+ expectedValues: []string{"d c"},
},
{
description: "double level expansion, with two variables in a string",
@@ -85,7 +93,7 @@
"c": []string{"e"},
},
toExpand: "${a}",
- expectedValues: []string{"d", "e"},
+ expectedValues: []string{"d e"},
},
{
description: "triple level expansion with two variables in a string",
@@ -96,13 +104,38 @@
"d": []string{"foo"},
},
toExpand: "${a}",
- expectedValues: []string{"foo", "foo", "foo"},
+ expectedValues: []string{"foo foo foo"},
+ },
+ {
+ description: "expansion with config depending vars",
+ configVars: exportedConfigDependingVariables{
+ "a": func(c android.Config) string { return c.BuildOS.String() },
+ "b": func(c android.Config) string { return c.BuildArch.String() },
+ },
+ config: android_arm64_config,
+ toExpand: "${a}-${b}",
+ expectedValues: []string{"android-arm64"},
+ },
+ {
+ description: "double level multi type expansion",
+ stringListScope: exportedStringListVariables{
+ "platform": []string{"${os}-${arch}"},
+ "const": []string{"const"},
+ },
+ configVars: exportedConfigDependingVariables{
+ "os": func(c android.Config) string { return c.BuildOS.String() },
+ "arch": func(c android.Config) string { return c.BuildArch.String() },
+ "foo": func(c android.Config) string { return "foo" },
+ },
+ config: android_arm64_config,
+ toExpand: "${const}/${platform}/${foo}",
+ expectedValues: []string{"const/android-arm64/foo"},
},
}
for _, testCase := range testCases {
t.Run(testCase.description, func(t *testing.T) {
- output := expandVar(testCase.toExpand, testCase.stringScope, testCase.stringListScope)
+ output, _ := expandVar(testCase.config, testCase.toExpand, testCase.stringScope, testCase.stringListScope, testCase.configVars)
if len(output) != len(testCase.expectedValues) {
t.Errorf("Expected %d values, got %d", len(testCase.expectedValues), len(output))
}
@@ -119,6 +152,7 @@
func TestBazelToolchainVars(t *testing.T) {
testCases := []struct {
name string
+ config android.Config
vars []bazelVarExporter
expectedOut string
}{
@@ -248,7 +282,7 @@
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
- out := bazelToolchainVars(tc.vars...)
+ out := bazelToolchainVars(tc.config, tc.vars...)
if out != tc.expectedOut {
t.Errorf("Expected \n%s, got \n%s", tc.expectedOut, out)
}
diff --git a/cc/config/x86_darwin_host.go b/cc/config/darwin_host.go
similarity index 73%
rename from cc/config/x86_darwin_host.go
rename to cc/config/darwin_host.go
index ecdcbde..318acb4 100644
--- a/cc/config/x86_darwin_host.go
+++ b/cc/config/darwin_host.go
@@ -53,12 +53,7 @@
}
darwinSupportedSdkVersions = []string{
- "10.13",
- "10.14",
- "10.15",
- "11.0",
- "11.1",
- "11.3",
+ "11",
}
darwinAvailableLibraries = append(
@@ -138,7 +133,7 @@
return ""
}
- bytes, err := exec.Command(xcrunTool, args...).Output()
+ bytes, err := exec.Command(xcrunTool, append([]string{"--sdk", "macosx"}, args...)...).Output()
if err != nil {
macTools.err = fmt.Errorf("xcrun %q failed with: %q", args, err)
return ""
@@ -147,27 +142,19 @@
return strings.TrimSpace(string(bytes))
}
- xcrunSdk := func(arg string) string {
- if selected := ctx.Config().Getenv("MAC_SDK_VERSION"); selected != "" {
- if !inList(selected, darwinSupportedSdkVersions) {
- macTools.err = fmt.Errorf("MAC_SDK_VERSION %s isn't supported: %q", selected, darwinSupportedSdkVersions)
- return ""
- }
-
- return xcrun("--sdk", "macosx"+selected, arg)
+ sdkVersion := xcrun("--show-sdk-version")
+ sdkVersionSupported := false
+ for _, version := range darwinSupportedSdkVersions {
+ if version == sdkVersion || strings.HasPrefix(sdkVersion, version+".") {
+ sdkVersionSupported = true
}
-
- for _, sdk := range darwinSupportedSdkVersions {
- bytes, err := exec.Command(xcrunTool, "--sdk", "macosx"+sdk, arg).Output()
- if err == nil {
- return strings.TrimSpace(string(bytes))
- }
- }
- macTools.err = fmt.Errorf("Could not find a supported mac sdk: %q", darwinSupportedSdkVersions)
- return ""
+ }
+ if !sdkVersionSupported {
+ macTools.err = fmt.Errorf("Unsupported macOS SDK version %q not in %v", sdkVersion, darwinSupportedSdkVersions)
+ return
}
- macTools.sdkRoot = xcrunSdk("--show-sdk-path")
+ macTools.sdkRoot = xcrun("--show-sdk-path")
macTools.arPath = xcrun("--find", "ar")
macTools.stripPath = xcrun("--find", "strip")
@@ -184,19 +171,43 @@
toolchain64Bit
}
-func (t *toolchainDarwin) Name() string {
+type toolchainDarwinX86 struct {
+ toolchainDarwin
+}
+
+type toolchainDarwinArm struct {
+ toolchainDarwin
+}
+
+func (t *toolchainDarwinArm) Name() string {
+ return "arm64"
+}
+
+func (t *toolchainDarwinX86) Name() string {
return "x86_64"
}
-func (t *toolchainDarwin) GccRoot() string {
+func (t *toolchainDarwinArm) GccRoot() string {
+ panic("unimplemented")
+}
+
+func (t *toolchainDarwinArm) GccTriple() string {
+ panic("unimplemented")
+}
+
+func (t *toolchainDarwinArm) GccVersion() string {
+ panic("unimplemented")
+}
+
+func (t *toolchainDarwinX86) GccRoot() string {
return "${config.DarwinGccRoot}"
}
-func (t *toolchainDarwin) GccTriple() string {
+func (t *toolchainDarwinX86) GccTriple() string {
return "${config.DarwinGccTriple}"
}
-func (t *toolchainDarwin) GccVersion() string {
+func (t *toolchainDarwinX86) GccVersion() string {
return darwinGccVersion
}
@@ -204,7 +215,11 @@
return ""
}
-func (t *toolchainDarwin) ClangTriple() string {
+func (t *toolchainDarwinArm) ClangTriple() string {
+ return "aarch64-apple-darwin"
+}
+
+func (t *toolchainDarwinX86) ClangTriple() string {
return "x86_64-apple-darwin"
}
@@ -240,12 +255,18 @@
return "${config.MacToolPath}"
}
-var toolchainDarwinSingleton Toolchain = &toolchainDarwin{}
+var toolchainDarwinArmSingleton Toolchain = &toolchainDarwinArm{}
+var toolchainDarwinX86Singleton Toolchain = &toolchainDarwinX86{}
-func darwinToolchainFactory(arch android.Arch) Toolchain {
- return toolchainDarwinSingleton
+func darwinArmToolchainFactory(arch android.Arch) Toolchain {
+ return toolchainDarwinArmSingleton
+}
+
+func darwinX86ToolchainFactory(arch android.Arch) Toolchain {
+ return toolchainDarwinX86Singleton
}
func init() {
- registerToolchainFactory(android.Darwin, android.X86_64, darwinToolchainFactory)
+ registerToolchainFactory(android.Darwin, android.Arm64, darwinArmToolchainFactory)
+ registerToolchainFactory(android.Darwin, android.X86_64, darwinX86ToolchainFactory)
}
diff --git a/cc/config/global.go b/cc/config/global.go
index 6108d3d..7abd2fc 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -404,7 +404,7 @@
pctx.StaticVariableWithEnvOverride("REAbiLinkerExecStrategy", "RBE_ABI_LINKER_EXEC_STRATEGY", remoteexec.LocalExecStrategy)
}
-var HostPrebuiltTag = pctx.VariableConfigMethod("HostPrebuiltTag", android.Config.PrebuiltOS)
+var HostPrebuiltTag = exportVariableConfigMethod("HostPrebuiltTag", android.Config.PrebuiltOS)
func ClangPath(ctx android.PathContext, file string) android.SourcePath {
type clangToolKey string
diff --git a/cc/config/toolchain.go b/cc/config/toolchain.go
index 20384a8..6320dbb 100644
--- a/cc/config/toolchain.go
+++ b/cc/config/toolchain.go
@@ -95,8 +95,6 @@
YasmFlags() string
- WindresFlags() string
-
Is64Bit() bool
ShlibSuffix() string
@@ -169,10 +167,6 @@
return ""
}
-func (toolchainBase) WindresFlags() string {
- return ""
-}
-
func (toolchainBase) LibclangRuntimeLibraryArch() string {
return ""
}
diff --git a/cc/config/vndk.go b/cc/config/vndk.go
index b2e164f..9577a8c 100644
--- a/cc/config/vndk.go
+++ b/cc/config/vndk.go
@@ -30,6 +30,8 @@
"android.hardware.gnss-V1-ndk_platform",
"android.hardware.gnss-ndk_platform",
"android.hardware.gnss-unstable-ndk_platform",
+ "android.hardware.health-V1-ndk",
+ "android.hardware.health-ndk",
"android.hardware.health.storage-V1-ndk",
"android.hardware.health.storage-V1-ndk_platform",
"android.hardware.health.storage-ndk_platform",
@@ -101,6 +103,7 @@
"android.system.keystore2-V1-ndk",
"android.hardware.wifi.hostapd-V1-ndk",
"android.hardware.wifi.hostapd-V1-ndk_platform",
+ "android.hardware.wifi.supplicant-V1-ndk",
"android.system.keystore2-V1-ndk_platform",
"android.system.keystore2-ndk_platform",
"android.system.keystore2-unstable-ndk_platform",
diff --git a/cc/config/x86_linux_host.go b/cc/config/x86_linux_host.go
index ac5d5f7..43333fa 100644
--- a/cc/config/x86_linux_host.go
+++ b/cc/config/x86_linux_host.go
@@ -120,40 +120,40 @@
)
func init() {
- pctx.StaticVariable("LinuxGccVersion", linuxGccVersion)
- pctx.StaticVariable("LinuxGlibcVersion", linuxGlibcVersion)
+ exportStringStaticVariable("LinuxGccVersion", linuxGccVersion)
+ exportStringStaticVariable("LinuxGlibcVersion", linuxGlibcVersion)
+
// Most places use the full GCC version. A few only use up to the first two numbers.
if p := strings.Split(linuxGccVersion, "."); len(p) > 2 {
- pctx.StaticVariable("ShortLinuxGccVersion", strings.Join(p[:2], "."))
+ exportStringStaticVariable("ShortLinuxGccVersion", strings.Join(p[:2], "."))
} else {
- pctx.StaticVariable("ShortLinuxGccVersion", linuxGccVersion)
+ exportStringStaticVariable("ShortLinuxGccVersion", linuxGccVersion)
}
- pctx.SourcePathVariable("LinuxGccRoot",
- "prebuilts/gcc/${HostPrebuiltTag}/host/x86_64-linux-glibc${LinuxGlibcVersion}-${ShortLinuxGccVersion}")
+ exportSourcePathVariable("LinuxGccRoot",
+ "prebuilts/gcc/linux-x86/host/x86_64-linux-glibc${LinuxGlibcVersion}-${ShortLinuxGccVersion}")
- pctx.StaticVariable("LinuxGccTriple", "x86_64-linux")
+ exportStringListStaticVariable("LinuxGccTriple", []string{"x86_64-linux"})
- pctx.StaticVariable("LinuxCflags", strings.Join(linuxCflags, " "))
- pctx.StaticVariable("LinuxLdflags", strings.Join(linuxLdflags, " "))
- pctx.StaticVariable("LinuxLldflags", strings.Join(linuxLdflags, " "))
+ exportStringListStaticVariable("LinuxCflags", linuxCflags)
+ exportStringListStaticVariable("LinuxLdflags", linuxLdflags)
+ exportStringListStaticVariable("LinuxLldflags", linuxLdflags)
+ exportStringListStaticVariable("LinuxGlibcCflags", linuxGlibcCflags)
+ exportStringListStaticVariable("LinuxGlibcLdflags", linuxGlibcLdflags)
+ exportStringListStaticVariable("LinuxGlibcLldflags", linuxGlibcLdflags)
+ exportStringListStaticVariable("LinuxMuslCflags", linuxMuslCflags)
+ exportStringListStaticVariable("LinuxMuslLdflags", linuxMuslLdflags)
+ exportStringListStaticVariable("LinuxMuslLldflags", linuxMuslLdflags)
- pctx.StaticVariable("LinuxX86Cflags", strings.Join(linuxX86Cflags, " "))
- pctx.StaticVariable("LinuxX8664Cflags", strings.Join(linuxX8664Cflags, " "))
- pctx.StaticVariable("LinuxX86Ldflags", strings.Join(linuxX86Ldflags, " "))
- pctx.StaticVariable("LinuxX86Lldflags", strings.Join(linuxX86Ldflags, " "))
- pctx.StaticVariable("LinuxX8664Ldflags", strings.Join(linuxX8664Ldflags, " "))
- pctx.StaticVariable("LinuxX8664Lldflags", strings.Join(linuxX8664Ldflags, " "))
+ exportStringListStaticVariable("LinuxX86Cflags", linuxX86Cflags)
+ exportStringListStaticVariable("LinuxX8664Cflags", linuxX8664Cflags)
+ exportStringListStaticVariable("LinuxX86Ldflags", linuxX86Ldflags)
+ exportStringListStaticVariable("LinuxX86Lldflags", linuxX86Ldflags)
+ exportStringListStaticVariable("LinuxX8664Ldflags", linuxX8664Ldflags)
+ exportStringListStaticVariable("LinuxX8664Lldflags", linuxX8664Ldflags)
// Yasm flags
- pctx.StaticVariable("LinuxX86YasmFlags", "-f elf32 -m x86")
- pctx.StaticVariable("LinuxX8664YasmFlags", "-f elf64 -m amd64")
-
- pctx.StaticVariable("LinuxGlibcCflags", strings.Join(linuxGlibcCflags, " "))
- pctx.StaticVariable("LinuxGlibcLdflags", strings.Join(linuxGlibcLdflags, " "))
- pctx.StaticVariable("LinuxGlibcLldflags", strings.Join(linuxGlibcLdflags, " "))
- pctx.StaticVariable("LinuxMuslCflags", strings.Join(linuxMuslCflags, " "))
- pctx.StaticVariable("LinuxMuslLdflags", strings.Join(linuxMuslLdflags, " "))
- pctx.StaticVariable("LinuxMuslLldflags", strings.Join(linuxMuslLdflags, " "))
+ exportStringListStaticVariable("LinuxX86YasmFlags", []string{"-f elf32 -m x86"})
+ exportStringListStaticVariable("LinuxX8664YasmFlags", []string{"-f elf64 -m amd64"})
}
type toolchainLinux struct {
diff --git a/cc/config/x86_windows_host.go b/cc/config/x86_windows_host.go
index d9a7537..9daf40f 100644
--- a/cc/config/x86_windows_host.go
+++ b/cc/config/x86_windows_host.go
@@ -188,14 +188,6 @@
return "${config.WindowsIncludeFlags}"
}
-func (t *toolchainWindowsX86) WindresFlags() string {
- return "-F pe-i386"
-}
-
-func (t *toolchainWindowsX8664) WindresFlags() string {
- return "-F pe-x86-64"
-}
-
func (t *toolchainWindowsX86) ClangTriple() string {
return "i686-windows-gnu"
}
diff --git a/cc/fuzz.go b/cc/fuzz.go
index 40f16f3..e987fe4 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -123,7 +123,7 @@
}
// Discard installable:false libraries because they are expected to be absent
// in runtime.
- if !proptools.BoolDefault(ccLibrary.Properties.Installable, true) {
+ if !proptools.BoolDefault(ccLibrary.Installable(), true) {
return false
}
}
diff --git a/cc/gen.go b/cc/gen.go
index 3a1a0e2..8f62363 100644
--- a/cc/gen.go
+++ b/cc/gen.go
@@ -45,13 +45,6 @@
CommandDeps: []string{"$syspropCmd"},
},
"headerOutDir", "publicOutDir", "srcOutDir", "includeName")
-
- windmc = pctx.AndroidStaticRule("windmc",
- blueprint.RuleParams{
- Command: "$windmcCmd -r$$(dirname $out) -h$$(dirname $out) $in",
- CommandDeps: []string{"$windmcCmd"},
- },
- "windmcCmd")
)
type YaccProperties struct {
@@ -200,26 +193,6 @@
return cppFile, headers.Paths()
}
-func genWinMsg(ctx android.ModuleContext, srcFile android.Path, flags builderFlags) (android.Path, android.Path) {
- headerFile := android.GenPathWithExt(ctx, "windmc", srcFile, "h")
- rcFile := android.GenPathWithExt(ctx, "windmc", srcFile, "rc")
-
- windmcCmd := mingwCmd(flags.toolchain, "windmc")
-
- ctx.Build(pctx, android.BuildParams{
- Rule: windmc,
- Description: "windmc " + srcFile.Rel(),
- Output: rcFile,
- ImplicitOutput: headerFile,
- Input: srcFile,
- Args: map[string]string{
- "windmcCmd": windmcCmd,
- },
- })
-
- return rcFile, headerFile
-}
-
// Used to communicate information from the genSources method back to the library code that uses
// it.
type generatedSourceInfo struct {
@@ -305,10 +278,6 @@
cppFile := rsGeneratedCppFile(ctx, srcFile)
rsFiles = append(rsFiles, srcFiles[i])
srcFiles[i] = cppFile
- case ".mc":
- rcFile, headerFile := genWinMsg(ctx, srcFile, buildFlags)
- srcFiles[i] = rcFile
- deps = append(deps, headerFile)
case ".sysprop":
cppFile, headerFiles := genSysprop(ctx, srcFile)
srcFiles[i] = cppFile
diff --git a/cc/installer.go b/cc/installer.go
index f95b493..2522610 100644
--- a/cc/installer.go
+++ b/cc/installer.go
@@ -29,6 +29,9 @@
// Install output directly in {partition}/, not in any subdir. This is only intended for use by
// init_first_stage.
Install_in_root *bool `android:"arch_variant"`
+
+ // Install output directly in {partition}/xbin
+ Install_in_xbin *bool `android:"arch_vvariant"`
}
type installLocation int
@@ -73,6 +76,8 @@
if installer.installInRoot() {
dir = ""
+ } else if installer.installInXbin() {
+ dir = "xbin"
}
if ctx.Target().NativeBridge == android.NativeBridgeEnabled {
@@ -123,3 +128,7 @@
func (installer *baseInstaller) installInRoot() bool {
return Bool(installer.Properties.Install_in_root)
}
+
+func (installer *baseInstaller) installInXbin() bool {
+ return Bool(installer.Properties.Install_in_xbin)
+}
diff --git a/cc/library.go b/cc/library.go
index ed4d3d2..c3f7305 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -159,6 +159,8 @@
Export_static_lib_headers []string `android:"arch_variant"`
Apex_available []string `android:"arch_variant"`
+
+ Installable *bool `android:"arch_variant"`
}
type LibraryMutatedProperties struct {
@@ -293,8 +295,9 @@
sharedAttrs := bp2BuildParseSharedProps(ctx, m)
staticAttrs := bp2BuildParseStaticProps(ctx, m)
- compilerAttrs := bp2BuildParseCompilerProps(ctx, m)
- linkerAttrs := bp2BuildParseLinkerProps(ctx, m)
+ baseAttributes := bp2BuildParseBaseProps(ctx, m)
+ compilerAttrs := baseAttributes.compilerAttributes
+ linkerAttrs := baseAttributes.linkerAttributes
exportedIncludes := bp2BuildParseExportedIncludes(ctx, m)
srcs := compilerAttrs.srcs
@@ -309,6 +312,7 @@
Srcs: srcs,
Srcs_c: compilerAttrs.cSrcs,
Srcs_as: compilerAttrs.asSrcs,
+ Hdrs: compilerAttrs.hdrs,
Copts: compilerAttrs.copts,
Cppflags: compilerAttrs.cppFlags,
@@ -639,7 +643,7 @@
func (handler *ccLibraryBazelHandler) GenerateBazelBuildActions(ctx android.ModuleContext, label string) bool {
bazelCtx := ctx.Config().BazelContext
- ccInfo, ok, err := bazelCtx.GetCcInfo(label, ctx.Arch().ArchType)
+ ccInfo, ok, err := bazelCtx.GetCcInfo(label, android.GetConfigKey(ctx))
if err != nil {
ctx.ModuleErrorf("Error getting Bazel CcInfo: %s", err)
return false
@@ -1046,6 +1050,8 @@
availableFor(string) bool
getAPIListCoverageXMLPath() android.ModuleOutPath
+
+ installable() *bool
}
type versionedInterface interface {
@@ -1288,7 +1294,7 @@
}
}
- transformObjToStaticLib(ctx, library.objects.objFiles, deps.WholeStaticLibsFromPrebuilts, builderFlags, outputFile, objs.tidyFiles)
+ transformObjToStaticLib(ctx, library.objects.objFiles, deps.WholeStaticLibsFromPrebuilts, builderFlags, outputFile, nil, objs.tidyFiles)
library.coverageOutputFile = transformCoverageFilesToZip(ctx, library.objects, ctx.ModuleName())
@@ -1417,10 +1423,9 @@
linkerDeps = append(linkerDeps, deps.EarlySharedLibsDeps...)
linkerDeps = append(linkerDeps, deps.SharedLibsDeps...)
linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...)
- linkerDeps = append(linkerDeps, objs.tidyFiles...)
transformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs,
deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs,
- linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, outputFile, implicitOutputs, nil)
+ linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, outputFile, implicitOutputs, objs.tidyFiles)
objs.coverageFiles = append(objs.coverageFiles, deps.StaticLibObjs.coverageFiles...)
objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...)
@@ -1971,6 +1976,15 @@
return android.CheckAvailableForApex(what, list)
}
+func (library *libraryDecorator) installable() *bool {
+ if library.static() {
+ return library.StaticProperties.Static.Installable
+ } else if library.shared() {
+ return library.SharedProperties.Shared.Installable
+ }
+ return nil
+}
+
func (library *libraryDecorator) makeUninstallable(mod *Module) {
if library.static() && library.buildStatic() && !library.buildStubs() {
// If we're asked to make a static library uninstallable we don't do
@@ -2357,8 +2371,10 @@
}
isStatic := modType == "cc_library_static"
- compilerAttrs := bp2BuildParseCompilerProps(ctx, module)
- linkerAttrs := bp2BuildParseLinkerProps(ctx, module)
+ baseAttributes := bp2BuildParseBaseProps(ctx, module)
+ compilerAttrs := baseAttributes.compilerAttributes
+ linkerAttrs := baseAttributes.linkerAttributes
+
exportedIncludes := bp2BuildParseExportedIncludes(ctx, module)
// Append shared/static{} stanza properties. These won't be specified on
@@ -2388,6 +2404,7 @@
Srcs_c: compilerAttrs.cSrcs,
Srcs_as: compilerAttrs.asSrcs,
Copts: compilerAttrs.copts,
+ Hdrs: compilerAttrs.hdrs,
Deps: linkerAttrs.deps,
Implementation_deps: linkerAttrs.implementationDeps,
diff --git a/cc/library_headers.go b/cc/library_headers.go
index 51c1eb8..ede6ab3 100644
--- a/cc/library_headers.go
+++ b/cc/library_headers.go
@@ -57,7 +57,7 @@
func (h *libraryHeaderBazelHander) GenerateBazelBuildActions(ctx android.ModuleContext, label string) bool {
bazelCtx := ctx.Config().BazelContext
- ccInfo, ok, err := bazelCtx.GetCcInfo(label, ctx.Arch().ArchType)
+ ccInfo, ok, err := bazelCtx.GetCcInfo(label, android.GetConfigKey(ctx))
if err != nil {
ctx.ModuleErrorf("Error getting Bazel CcInfo: %s", err)
return false
@@ -132,7 +132,8 @@
}
exportedIncludes := bp2BuildParseExportedIncludes(ctx, module)
- linkerAttrs := bp2BuildParseLinkerProps(ctx, module)
+ baseAttributes := bp2BuildParseBaseProps(ctx, module)
+ linkerAttrs := baseAttributes.linkerAttributes
attrs := &bazelCcLibraryHeadersAttributes{
Export_includes: exportedIncludes.Includes,
@@ -140,6 +141,7 @@
Implementation_deps: linkerAttrs.implementationDeps,
Deps: linkerAttrs.deps,
System_dynamic_deps: linkerAttrs.systemDynamicDeps,
+ Hdrs: baseAttributes.hdrs,
}
props := bazel.BazelTargetModuleProperties{
diff --git a/cc/ndk_sysroot.go b/cc/ndk_sysroot.go
index 2726b1a..fd458d9 100644
--- a/cc/ndk_sysroot.go
+++ b/cc/ndk_sysroot.go
@@ -33,7 +33,7 @@
// Component 3: Stub Libraries
// The shared libraries in the NDK are not the actual shared libraries they
// refer to (to prevent people from accidentally loading them), but stub
-// libraries with dummy implementations of everything for use at build time
+// libraries with placeholder implementations of everything for use at build time
// only.
//
// Since we don't actually need to know anything about the stub libraries aside
diff --git a/cc/object.go b/cc/object.go
index d8bb08f..0327a45 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -54,7 +54,7 @@
func (handler *objectBazelHandler) GenerateBazelBuildActions(ctx android.ModuleContext, label string) bool {
bazelCtx := ctx.Config().BazelContext
- objPaths, ok := bazelCtx.GetOutputFiles(label, ctx.Arch().ArchType)
+ objPaths, ok := bazelCtx.GetOutputFiles(label, android.GetConfigKey(ctx))
if ok {
if len(objPaths) != 1 {
ctx.ModuleErrorf("expected exactly one object file for '%s', but got %s", label, objPaths)
@@ -154,7 +154,8 @@
}
// Set arch-specific configurable attributes
- compilerAttrs := bp2BuildParseCompilerProps(ctx, m)
+ baseAttributes := bp2BuildParseBaseProps(ctx, m)
+ compilerAttrs := baseAttributes.compilerAttributes
var deps bazel.LabelListAttribute
systemDynamicDeps := bazel.LabelListAttribute{ForceSpecifyEmptyList: true}
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index d324241..3401e36 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -16,9 +16,9 @@
import (
"path/filepath"
- "strings"
"android/soong/android"
+ "android/soong/bazel"
)
func init() {
@@ -32,6 +32,8 @@
ctx.RegisterModuleType("cc_prebuilt_test_library_shared", PrebuiltSharedTestLibraryFactory)
ctx.RegisterModuleType("cc_prebuilt_object", prebuiltObjectFactory)
ctx.RegisterModuleType("cc_prebuilt_binary", prebuiltBinaryFactory)
+
+ android.RegisterBp2BuildMutator("cc_prebuilt_library_shared", PrebuiltLibrarySharedBp2Build)
}
type prebuiltLinkerInterface interface {
@@ -232,7 +234,7 @@
// Implements versionedInterface
func (p *prebuiltLibraryLinker) implementationModuleName(name string) string {
- return strings.TrimPrefix(name, "prebuilt_")
+ return android.RemoveOptionalPrebuiltPrefix(name)
}
func NewPrebuiltLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
@@ -310,6 +312,42 @@
return module, library
}
+type bazelPrebuiltLibrarySharedAttributes struct {
+ Shared_library bazel.LabelAttribute
+}
+
+func PrebuiltLibrarySharedBp2Build(ctx android.TopDownMutatorContext) {
+ module, ok := ctx.Module().(*Module)
+ if !ok {
+ // Not a cc module
+ return
+ }
+ if !module.ConvertWithBp2build(ctx) {
+ return
+ }
+ if ctx.ModuleType() != "cc_prebuilt_library_shared" {
+ return
+ }
+
+ prebuiltLibrarySharedBp2BuildInternal(ctx, module)
+}
+
+func prebuiltLibrarySharedBp2BuildInternal(ctx android.TopDownMutatorContext, module *Module) {
+ prebuiltAttrs := Bp2BuildParsePrebuiltLibraryProps(ctx, module)
+
+ attrs := &bazelPrebuiltLibrarySharedAttributes{
+ Shared_library: prebuiltAttrs.Src,
+ }
+
+ props := bazel.BazelTargetModuleProperties{
+ Rule_class: "prebuilt_library_shared",
+ Bzl_load_location: "//build/bazel/rules:prebuilt_library_shared.bzl",
+ }
+
+ name := android.RemoveOptionalPrebuiltPrefix(module.Name())
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: name}, attrs)
+}
+
type prebuiltObjectProperties struct {
Srcs []string `android:"path,arch_variant"`
}
@@ -330,7 +368,7 @@
func (h *prebuiltStaticLibraryBazelHandler) GenerateBazelBuildActions(ctx android.ModuleContext, label string) bool {
bazelCtx := ctx.Config().BazelContext
- ccInfo, ok, err := bazelCtx.GetCcInfo(label, ctx.Arch().ArchType)
+ ccInfo, ok, err := bazelCtx.GetCcInfo(label, android.GetConfigKey(ctx))
if err != nil {
ctx.ModuleErrorf("Error getting Bazel CcInfo: %s", err)
}
diff --git a/cmd/multiproduct_kati/Android.bp b/cmd/multiproduct_kati/Android.bp
index e5be6c0..20ca2a3 100644
--- a/cmd/multiproduct_kati/Android.bp
+++ b/cmd/multiproduct_kati/Android.bp
@@ -31,4 +31,14 @@
testSrcs: [
"main_test.go",
],
+ linux: {
+ srcs: [
+ "main_linux.go",
+ ],
+ },
+ darwin: {
+ srcs: [
+ "main_darwin.go",
+ ],
+ },
}
diff --git a/cmd/multiproduct_kati/main.go b/cmd/multiproduct_kati/main.go
index 3c9cac1..0577c86 100644
--- a/cmd/multiproduct_kati/main.go
+++ b/cmd/multiproduct_kati/main.go
@@ -166,15 +166,6 @@
MainLogsDir string
}
-func detectTotalRAM() uint64 {
- var info syscall.Sysinfo_t
- err := syscall.Sysinfo(&info)
- if err != nil {
- panic(err)
- }
- return info.Totalram * uint64(info.Unit)
-}
-
func findNamedProducts(soongUi string, log logger.Logger) []string {
cmd := exec.Command(soongUi, "--dumpvars-mode", "--vars=all_named_products")
output, err := cmd.Output()
@@ -301,7 +292,7 @@
jobs = runtime.NumCPU() / 4
ramGb := int(detectTotalRAM() / (1024 * 1024 * 1024))
- if ramJobs := ramGb / 25; ramGb > 0 && jobs > ramJobs {
+ if ramJobs := ramGb / 30; ramGb > 0 && jobs > ramJobs {
jobs = ramJobs
}
diff --git a/cmd/multiproduct_kati/main_darwin.go b/cmd/multiproduct_kati/main_darwin.go
new file mode 100644
index 0000000..3d1b12a
--- /dev/null
+++ b/cmd/multiproduct_kati/main_darwin.go
@@ -0,0 +1,20 @@
+// Copyright 2017 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 main
+
+func detectTotalRAM() uint64 {
+ // unimplemented stub on darwin
+ return 0
+}
diff --git a/cmd/multiproduct_kati/main_linux.go b/cmd/multiproduct_kati/main_linux.go
new file mode 100644
index 0000000..db74496
--- /dev/null
+++ b/cmd/multiproduct_kati/main_linux.go
@@ -0,0 +1,28 @@
+// Copyright 2017 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 main
+
+import (
+ "syscall"
+)
+
+func detectTotalRAM() uint64 {
+ var info syscall.Sysinfo_t
+ err := syscall.Sysinfo(&info)
+ if err != nil {
+ panic(err)
+ }
+ return info.Totalram * uint64(info.Unit)
+}
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index c5e8896..e9eabd3 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -217,15 +217,6 @@
generateModuleGraphFile := moduleGraphFile != ""
generateDocFile := docFile != ""
- blueprintArgs := cmdlineArgs
-
- var stopBefore bootstrap.StopBefore
- if !generateModuleGraphFile && !generateQueryView && !generateDocFile {
- stopBefore = bootstrap.DoEverything
- } else {
- stopBefore = bootstrap.StopBeforePrepareBuildActions
- }
-
if generateBazelWorkspace {
// Run the alternate pipeline of bp2build mutators and singleton to convert
// Blueprint to BUILD files before everything else.
@@ -233,6 +224,19 @@
return bp2buildMarker
}
+ blueprintArgs := cmdlineArgs
+
+ var stopBefore bootstrap.StopBefore
+ if generateModuleGraphFile {
+ stopBefore = bootstrap.StopBeforeWriteNinja
+ } else if generateQueryView {
+ stopBefore = bootstrap.StopBeforePrepareBuildActions
+ } else if generateDocFile {
+ stopBefore = bootstrap.StopBeforePrepareBuildActions
+ } else {
+ stopBefore = bootstrap.DoEverything
+ }
+
ctx := newContext(configuration)
if mixedModeBuild {
runMixedModeBuild(configuration, ctx, extraNinjaDeps)
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index 965b755..3145315 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -204,6 +204,17 @@
return fmt.Sprintf("/system/framework/%s.jar", lib)
}
+// Returns the location to the odex file for the dex file at `path`.
+func ToOdexPath(path string, arch android.ArchType) string {
+ if strings.HasPrefix(path, "/apex/") {
+ return filepath.Join("/system/framework/oat", arch.String(),
+ strings.ReplaceAll(path[1:], "/", "@")+"@classes.odex")
+ }
+
+ return filepath.Join(filepath.Dir(path), "oat", arch.String(),
+ pathtools.ReplaceExtension(filepath.Base(path), "odex"))
+}
+
func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, global *GlobalConfig,
module *ModuleConfig, rule *android.RuleBuilder, archIdx int, profile android.WritablePath,
appImage bool, generateDM bool) {
@@ -218,23 +229,8 @@
base = "package.apk"
}
- toOdexPath := func(path string) string {
- if global.ApexSystemServerJars.ContainsJar(module.Name) {
- return filepath.Join(
- "/system/framework/oat",
- arch.String(),
- strings.ReplaceAll(path[1:], "/", "@")+"@classes.odex")
- }
-
- return filepath.Join(
- filepath.Dir(path),
- "oat",
- arch.String(),
- pathtools.ReplaceExtension(filepath.Base(path), "odex"))
- }
-
odexPath := module.BuildPath.InSameDir(ctx, "oat", arch.String(), pathtools.ReplaceExtension(base, "odex"))
- odexInstallPath := toOdexPath(module.DexLocation)
+ odexInstallPath := ToOdexPath(module.DexLocation, arch)
if odexOnSystemOther(module, global) {
odexInstallPath = filepath.Join(SystemOtherPartition, odexInstallPath)
}
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 4dd2135..c9bf958 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -248,7 +248,7 @@
// Returns true if information was available from Bazel, false if bazel invocation still needs to occur.
func (c *Module) GenerateBazelBuildActions(ctx android.ModuleContext, label string) bool {
bazelCtx := ctx.Config().BazelContext
- filePaths, ok := bazelCtx.GetOutputFiles(label, ctx.Arch().ArchType)
+ filePaths, ok := bazelCtx.GetOutputFiles(label, android.GetConfigKey(ctx))
if ok {
var bazelOutputFiles android.Paths
exportIncludeDirs := map[string]bool{}
@@ -336,14 +336,9 @@
}
case bootstrap.GoBinaryTool:
// A GoBinaryTool provides the install path to a tool, which will be copied.
- if s, err := filepath.Rel(android.PathForOutput(ctx).String(), t.InstallPath()); err == nil {
- toolPath := android.PathForOutput(ctx, s)
- tools = append(tools, toolPath)
- addLocationLabel(tag.label, toolLocation{android.Paths{toolPath}})
- } else {
- ctx.ModuleErrorf("cannot find path for %q: %v", tool, err)
- return
- }
+ p := android.PathForGoBinary(ctx, t)
+ tools = append(tools, p)
+ addLocationLabel(tag.label, toolLocation{android.Paths{p}})
default:
ctx.ModuleErrorf("%q is not a host tool provider", tool)
return
diff --git a/java/Android.bp b/java/Android.bp
index 9ffa123..8835b44 100644
--- a/java/Android.bp
+++ b/java/Android.bp
@@ -40,6 +40,7 @@
"dex.go",
"dexpreopt.go",
"dexpreopt_bootjars.go",
+ "dexpreopt_check.go",
"dexpreopt_config.go",
"droiddoc.go",
"droidstubs.go",
@@ -92,6 +93,7 @@
"platform_bootclasspath_test.go",
"platform_compat_config_test.go",
"plugin_test.go",
+ "prebuilt_apis_test.go",
"rro_test.go",
"sdk_test.go",
"sdk_library_test.go",
diff --git a/java/core-libraries/Android.bp b/java/core-libraries/Android.bp
index b198c24..2eafe9d 100644
--- a/java/core-libraries/Android.bp
+++ b/java/core-libraries/Android.bp
@@ -28,6 +28,11 @@
default_applicable_licenses: ["Android-Apache-2.0"],
}
+dist_targets = [
+ "sdk",
+ "win_sdk",
+]
+
java_library {
name: "core.current.stubs",
visibility: ["//visibility:public"],
@@ -40,15 +45,16 @@
system_modules: "none",
dist: {
- targets: [
- "sdk",
- "win_sdk",
- ],
+ targets: dist_targets,
},
}
// Distributed with the SDK for turning into system modules to compile apps
// against.
+//
+// Also, produces dist files that are used by the
+// prebuilts/sdk/update_prebuilts.py script to update the prebuilts/sdk
+// directory.
java_library {
name: "core-current-stubs-for-system-modules",
visibility: ["//development/sdk"],
@@ -65,13 +71,17 @@
],
sdk_version: "none",
system_modules: "none",
- dist: {
- dest: "core-for-system-modules.jar",
- targets: [
- "sdk",
- "win_sdk",
- ],
- },
+ dists: [
+ {
+ // Legacy dist location for the public file.
+ dest: "core-for-system-modules.jar",
+ targets: dist_targets,
+ },
+ {
+ dest: "system-modules/public/core-for-system-modules.jar",
+ targets: dist_targets,
+ },
+ ],
}
// Used when compiling higher-level code against core.current.stubs.
@@ -103,10 +113,13 @@
visibility: ["//visibility:private"],
}
-// Used when compiling higher-level code with sdk_version "module_current"
-java_system_modules {
- name: "core-module-lib-stubs-system-modules",
- libs: [
+// Produces a dist file that is used by the
+// prebuilts/sdk/update_prebuilts.py script to update the prebuilts/sdk
+// directory.
+java_library {
+ name: "core-module-lib-stubs-for-system-modules",
+ visibility: ["//visibility:private"],
+ static_libs: [
"core.module_lib.stubs",
// This one is not on device but it's needed when javac compiles code
// containing lambdas.
@@ -117,6 +130,20 @@
// See http://b/123891440.
"core-generated-annotation-stubs",
],
+ sdk_version: "none",
+ system_modules: "none",
+ dist: {
+ dest: "system-modules/module-lib/core-for-system-modules.jar",
+ targets: dist_targets,
+ },
+}
+
+// Used when compiling higher-level code with sdk_version "module_current"
+java_system_modules {
+ name: "core-module-lib-stubs-system-modules",
+ libs: [
+ "core-module-lib-stubs-for-system-modules",
+ ],
visibility: ["//visibility:public"],
}
diff --git a/java/dexpreopt_check.go b/java/dexpreopt_check.go
new file mode 100644
index 0000000..565901d
--- /dev/null
+++ b/java/dexpreopt_check.go
@@ -0,0 +1,96 @@
+// Copyright 2021 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 java
+
+import (
+ "strings"
+
+ "android/soong/android"
+ "android/soong/dexpreopt"
+
+ "github.com/google/blueprint/pathtools"
+)
+
+func init() {
+ RegisterDexpreoptCheckBuildComponents(android.InitRegistrationContext)
+}
+
+func RegisterDexpreoptCheckBuildComponents(ctx android.RegistrationContext) {
+ ctx.RegisterSingletonModuleType("dexpreopt_systemserver_check", dexpreoptSystemserverCheckFactory)
+}
+
+// A build-time check to verify if all compilation artifacts of system server jars are installed
+// into the system image. When the check fails, it means that dexpreopting is not working for some
+// system server jars and needs to be fixed.
+// This singleton module generates a list of the paths to the artifacts based on
+// PRODUCT_SYSTEM_SERVER_JARS and PRODUCT_APEX_SYSTEM_SERVER_JARS, and passes it to Make via a
+// variable. Make will then do the actual check.
+// Currently, it only checks artifacts of modules defined in Soong. Artifacts of modules defined in
+// Makefile are generated by a script generated by dexpreopt_gen, and their existence is unknown to
+// Make and Ninja.
+type dexpreoptSystemserverCheck struct {
+ android.SingletonModuleBase
+
+ // Mapping from the module name to the install paths to the compilation artifacts.
+ artifactsByModuleName map[string][]string
+
+ // The install paths to the compilation artifacts.
+ artifacts []string
+}
+
+func dexpreoptSystemserverCheckFactory() android.SingletonModule {
+ m := &dexpreoptSystemserverCheck{}
+ m.artifactsByModuleName = make(map[string][]string)
+ android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
+ return m
+}
+
+func getInstallPath(ctx android.ModuleContext, location string) android.InstallPath {
+ return android.PathForModuleInPartitionInstall(
+ ctx, "", strings.TrimPrefix(location, "/")).ToMakePath()
+}
+
+func (m *dexpreoptSystemserverCheck) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ global := dexpreopt.GetGlobalConfig(ctx)
+ targets := ctx.Config().Targets[android.Android]
+
+ // The check should be skipped on unbundled builds because system server jars are not preopted on
+ // unbundled builds since the artifacts are installed into the system image, not the APEXes.
+ if global.DisablePreopt || len(targets) == 0 || ctx.Config().UnbundledBuild() {
+ return
+ }
+
+ systemServerJars := dexpreopt.AllSystemServerJars(ctx, global)
+ for _, jar := range systemServerJars.CopyOfJars() {
+ dexLocation := dexpreopt.GetSystemServerDexLocation(global, jar)
+ odexLocation := dexpreopt.ToOdexPath(dexLocation, targets[0].Arch.ArchType)
+ odexPath := getInstallPath(ctx, odexLocation)
+ vdexPath := getInstallPath(ctx, pathtools.ReplaceExtension(odexLocation, "vdex"))
+ m.artifactsByModuleName[jar] = []string{odexPath.String(), vdexPath.String()}
+ }
+}
+
+func (m *dexpreoptSystemserverCheck) GenerateSingletonBuildActions(ctx android.SingletonContext) {
+ // Only keep modules defined in Soong.
+ ctx.VisitAllModules(func(module android.Module) {
+ if artifacts, ok := m.artifactsByModuleName[module.Name()]; ok {
+ m.artifacts = append(m.artifacts, artifacts...)
+ }
+ })
+}
+
+func (m *dexpreoptSystemserverCheck) MakeVars(ctx android.MakeVarsContext) {
+ ctx.Strict("DEXPREOPT_SYSTEMSERVER_ARTIFACTS", strings.Join(m.artifacts, " "))
+}
diff --git a/java/java.go b/java/java.go
index 29f31e5..854097b 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1540,9 +1540,6 @@
var _ android.IDECustomizedModuleName = (*Import)(nil)
// Collect information for opening IDE project files in java/jdeps.go.
-const (
- removedPrefix = "prebuilt_"
-)
func (j *Import) IDEInfo(dpInfo *android.IdeInfo) {
dpInfo.Jars = append(dpInfo.Jars, j.PrebuiltSrcs()...)
diff --git a/java/prebuilt_apis.go b/java/prebuilt_apis.go
index c33e6c2..c67e2bd 100644
--- a/java/prebuilt_apis.go
+++ b/java/prebuilt_apis.go
@@ -167,30 +167,24 @@
localPath := strings.TrimPrefix(f, mydir)
module, apiver, scope := parseJarPath(localPath)
createImport(mctx, module, scope, apiver, localPath, sdkVersion, compileDex)
+
+ if module == "core-for-system-modules" {
+ createSystemModules(mctx, apiver, scope)
+ }
}
}
-func createSystemModules(mctx android.LoadHookContext, apiver string) {
+func createSystemModules(mctx android.LoadHookContext, apiver string, scope string) {
props := struct {
Name *string
Libs []string
}{}
- props.Name = proptools.StringPtr(prebuiltApiModuleName(mctx, "system_modules", "public", apiver))
- props.Libs = append(props.Libs, prebuiltApiModuleName(mctx, "core-for-system-modules", "public", apiver))
+ props.Name = proptools.StringPtr(prebuiltApiModuleName(mctx, "system_modules", scope, apiver))
+ props.Libs = append(props.Libs, prebuiltApiModuleName(mctx, "core-for-system-modules", scope, apiver))
mctx.CreateModule(systemModulesImportFactory, &props)
}
-func prebuiltSdkSystemModules(mctx android.LoadHookContext, p *prebuiltApis) {
- for _, apiver := range p.properties.Api_dirs {
- jar := android.ExistentPathForSource(mctx,
- mctx.ModuleDir(), apiver, "public", "core-for-system-modules.jar")
- if jar.Valid() {
- createSystemModules(mctx, apiver)
- }
- }
-}
-
func prebuiltApiFiles(mctx android.LoadHookContext, p *prebuiltApis) {
mydir := mctx.ModuleDir() + "/"
// <apiver>/<scope>/api/<module>.txt
@@ -273,7 +267,6 @@
if p, ok := mctx.Module().(*prebuiltApis); ok {
prebuiltApiFiles(mctx, p)
prebuiltSdkStubs(mctx, p)
- prebuiltSdkSystemModules(mctx, p)
}
}
diff --git a/java/prebuilt_apis_test.go b/java/prebuilt_apis_test.go
new file mode 100644
index 0000000..7c2e526
--- /dev/null
+++ b/java/prebuilt_apis_test.go
@@ -0,0 +1,52 @@
+// Copyright 2021 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 java
+
+import (
+ "sort"
+ "strings"
+ "testing"
+
+ "android/soong/android"
+ "github.com/google/blueprint"
+)
+
+func TestPrebuiltApis_SystemModulesCreation(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForJavaTest,
+ FixtureWithPrebuiltApis(map[string][]string{
+ "31": {},
+ "current": {},
+ }),
+ ).RunTest(t)
+
+ sdkSystemModules := []string{}
+ result.VisitAllModules(func(module blueprint.Module) {
+ name := android.RemoveOptionalPrebuiltPrefix(module.Name())
+ if strings.HasPrefix(name, "sdk_") && strings.HasSuffix(name, "_system_modules") {
+ sdkSystemModules = append(sdkSystemModules, name)
+ }
+ })
+ sort.Strings(sdkSystemModules)
+ expected := []string{
+ // 31 only has public system modules.
+ "sdk_public_31_system_modules",
+
+ // current only has public system modules.
+ "sdk_public_current_system_modules",
+ }
+ sort.Strings(expected)
+ android.AssertArrayString(t, "sdk system modules", expected, sdkSystemModules)
+}
diff --git a/java/proto.go b/java/proto.go
index 8731822..ab913d8 100644
--- a/java/proto.go
+++ b/java/proto.go
@@ -24,7 +24,7 @@
func genProto(ctx android.ModuleContext, protoFiles android.Paths, flags android.ProtoFlags) android.Paths {
// Shard proto files into groups of 100 to avoid having to recompile all of them if one changes and to avoid
// hitting command line length limits.
- shards := android.ShardPaths(protoFiles, 100)
+ shards := android.ShardPaths(protoFiles, 50)
srcJarFiles := make(android.Paths, 0, len(shards))
@@ -102,6 +102,9 @@
if String(p.Proto.Plugin) == "" {
var typeToPlugin string
switch String(p.Proto.Type) {
+ case "stream":
+ flags.proto.OutTypeFlag = "--javastream_out"
+ typeToPlugin = "javastream"
case "micro":
flags.proto.OutTypeFlag = "--javamicro_out"
typeToPlugin = "javamicro"
diff --git a/java/robolectric.go b/java/robolectric.go
index a3603ad..16af546 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -212,13 +212,7 @@
installDeps = append(installDeps, installedData)
}
- installed := ctx.InstallFile(installPath, ctx.ModuleName()+".jar", r.combinedJar, installDeps...)
-
- if r.ExportedToMake() {
- // Soong handles installation here, but Make is usually what creates the phony rule that atest
- // uses to build the module. Create it here for now.
- ctx.Phony(ctx.ModuleName(), installed)
- }
+ r.installFile = ctx.InstallFile(installPath, ctx.ModuleName()+".jar", r.combinedJar, installDeps...)
}
func generateRoboTestConfig(ctx android.ModuleContext, outputFile android.WritablePath,
@@ -282,6 +276,10 @@
func (r *robolectricTest) AndroidMkEntries() []android.AndroidMkEntries {
entriesList := r.Library.AndroidMkEntries()
entries := &entriesList[0]
+ entries.ExtraEntries = append(entries.ExtraEntries,
+ func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
+ entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
+ })
entries.ExtraFooters = []android.AndroidMkExtraFootersFunc{
func(w io.Writer, name, prefix, moduleDir string) {
diff --git a/java/sdk.go b/java/sdk.go
index 80f2d6a..42ed14f 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -60,6 +60,12 @@
}
}
+// systemModuleKind returns the kind of system modules to use.
+func systemModuleKind() android.SdkKind {
+ // Currently, every sdk version uses the system modules for the public API.
+ return android.SdkPublic
+}
+
func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext android.SdkContext) sdkDep {
sdkVersion := sdkContext.SdkVersion(ctx)
if !sdkVersion.Valid() {
@@ -105,7 +111,8 @@
var systemModules string
if defaultJavaLanguageVersion(ctx, sdkVersion).usesJavaModules() {
- systemModules = "sdk_public_" + sdkVersion.ApiLevel.String() + "_system_modules"
+ systemModuleKind := systemModuleKind()
+ systemModules = fmt.Sprintf("sdk_%s_%s_system_modules", systemModuleKind, sdkVersion.ApiLevel)
}
return sdkDep{
@@ -116,13 +123,13 @@
}
}
- toModule := func(modules []string, res string, aidl android.Path) sdkDep {
+ toModule := func(systemModules string, module string, aidl android.Path) sdkDep {
return sdkDep{
useModule: true,
- bootclasspath: append(modules, config.DefaultLambdaStubsLibrary),
- systemModules: "core-current-stubs-system-modules",
- java9Classpath: modules,
- frameworkResModule: res,
+ bootclasspath: []string{module, config.DefaultLambdaStubsLibrary},
+ systemModules: systemModules,
+ java9Classpath: []string{module},
+ frameworkResModule: "framework-res",
aidl: android.OptionalPathForPath(aidl),
}
}
@@ -161,11 +168,11 @@
noFrameworksLibs: true,
}
case android.SdkPublic:
- return toModule([]string{"android_stubs_current"}, "framework-res", sdkFrameworkAidlPath(ctx))
+ return toModule("core-current-stubs-system-modules", "android_stubs_current", sdkFrameworkAidlPath(ctx))
case android.SdkSystem:
- return toModule([]string{"android_system_stubs_current"}, "framework-res", sdkFrameworkAidlPath(ctx))
+ return toModule("core-current-stubs-system-modules", "android_system_stubs_current", sdkFrameworkAidlPath(ctx))
case android.SdkTest:
- return toModule([]string{"android_test_stubs_current"}, "framework-res", sdkFrameworkAidlPath(ctx))
+ return toModule("core-current-stubs-system-modules", "android_test_stubs_current", sdkFrameworkAidlPath(ctx))
case android.SdkCore:
return sdkDep{
useModule: true,
@@ -175,24 +182,10 @@
}
case android.SdkModule:
// TODO(146757305): provide .apk and .aidl that have more APIs for modules
- return sdkDep{
- useModule: true,
- bootclasspath: []string{"android_module_lib_stubs_current", config.DefaultLambdaStubsLibrary},
- systemModules: "core-module-lib-stubs-system-modules",
- java9Classpath: []string{"android_module_lib_stubs_current"},
- frameworkResModule: "framework-res",
- aidl: android.OptionalPathForPath(nonUpdatableFrameworkAidlPath(ctx)),
- }
+ return toModule("core-module-lib-stubs-system-modules", "android_module_lib_stubs_current", nonUpdatableFrameworkAidlPath(ctx))
case android.SdkSystemServer:
// TODO(146757305): provide .apk and .aidl that have more APIs for modules
- return sdkDep{
- useModule: true,
- bootclasspath: []string{"android_system_server_stubs_current", config.DefaultLambdaStubsLibrary},
- systemModules: "core-module-lib-stubs-system-modules",
- java9Classpath: []string{"android_system_server_stubs_current"},
- frameworkResModule: "framework-res",
- aidl: android.OptionalPathForPath(sdkFrameworkAidlPath(ctx)),
- }
+ return toModule("core-module-lib-stubs-system-modules", "android_system_server_stubs_current", sdkFrameworkAidlPath(ctx))
default:
panic(fmt.Errorf("invalid sdk %q", sdkVersion.Raw))
}
diff --git a/java/sdk_test.go b/java/sdk_test.go
index 6d62130..9a71192 100644
--- a/java/sdk_test.go
+++ b/java/sdk_test.go
@@ -25,27 +25,36 @@
"android/soong/java/config"
)
+type classpathTestCase struct {
+ name string
+ unbundled bool
+ moduleType string
+ host android.OsClass
+ properties string
+
+ // for java 8
+ bootclasspath []string
+ java8classpath []string
+
+ // for java 9
+ system string
+ java9classpath []string
+
+ forces8 bool // if set, javac will always be called with java 8 arguments
+
+ aidl string
+
+ // Indicates how this test case is affected by the setting of Always_use_prebuilt_sdks.
+ //
+ // If this is nil then the test case is unaffected by the setting of Always_use_prebuilt_sdks.
+ // Otherwise, the test case can only be used when
+ // Always_use_prebuilt_sdks=*forAlwaysUsePrebuiltSdks.
+ forAlwaysUsePrebuiltSdks *bool
+}
+
func TestClasspath(t *testing.T) {
const frameworkAidl = "-I" + defaultJavaDir + "/framework/aidl"
- var classpathTestcases = []struct {
- name string
- unbundled bool
- moduleType string
- host android.OsClass
- properties string
-
- // for java 8
- bootclasspath []string
- java8classpath []string
-
- // for java 9
- system string
- java9classpath []string
-
- forces8 bool // if set, javac will always be called with java 8 arguments
-
- aidl string
- }{
+ var classpathTestcases = []classpathTestCase{
{
name: "default",
bootclasspath: config.StableCorePlatformBootclasspathLibraries,
@@ -91,6 +100,8 @@
aidl: "-pprebuilts/sdk/30/public/framework.aidl",
},
{
+ // Test case only applies when Always_use_prebuilt_sdks=false (the default).
+ forAlwaysUsePrebuiltSdks: proptools.BoolPtr(false),
name: "current",
properties: `sdk_version: "current",`,
@@ -100,6 +111,20 @@
aidl: "-pout/soong/framework.aidl",
},
{
+ // Test case only applies when Always_use_prebuilt_sdks=true.
+ forAlwaysUsePrebuiltSdks: proptools.BoolPtr(true),
+
+ name: "current",
+ properties: `sdk_version: "current",`,
+ bootclasspath: []string{`""`},
+ system: "sdk_public_current_system_modules",
+ java8classpath: []string{"prebuilts/sdk/current/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ java9classpath: []string{"prebuilts/sdk/current/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ aidl: "-pprebuilts/sdk/current/public/framework.aidl",
+ },
+ {
+ // Test case only applies when Always_use_prebuilt_sdks=false (the default).
+ forAlwaysUsePrebuiltSdks: proptools.BoolPtr(false),
name: "system_current",
properties: `sdk_version: "system_current",`,
@@ -109,7 +134,18 @@
aidl: "-pout/soong/framework.aidl",
},
{
+ // Test case only applies when Always_use_prebuilt_sdks=true.
+ forAlwaysUsePrebuiltSdks: proptools.BoolPtr(true),
+ name: "system_current",
+ properties: `sdk_version: "system_current",`,
+ bootclasspath: []string{`""`},
+ system: "sdk_public_current_system_modules",
+ java8classpath: []string{"prebuilts/sdk/current/system/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ java9classpath: []string{"prebuilts/sdk/current/system/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ aidl: "-pprebuilts/sdk/current/public/framework.aidl",
+ },
+ {
name: "system_29",
properties: `sdk_version: "system_29",`,
bootclasspath: []string{`""`},
@@ -118,7 +154,6 @@
aidl: "-pprebuilts/sdk/29/public/framework.aidl",
},
{
-
name: "system_30",
properties: `sdk_version: "system_30",`,
bootclasspath: []string{`""`},
@@ -128,6 +163,8 @@
aidl: "-pprebuilts/sdk/30/public/framework.aidl",
},
{
+ // Test case only applies when Always_use_prebuilt_sdks=false (the default).
+ forAlwaysUsePrebuiltSdks: proptools.BoolPtr(false),
name: "test_current",
properties: `sdk_version: "test_current",`,
@@ -137,6 +174,29 @@
aidl: "-pout/soong/framework.aidl",
},
{
+ // Test case only applies when Always_use_prebuilt_sdks=true.
+ forAlwaysUsePrebuiltSdks: proptools.BoolPtr(true),
+
+ name: "test_current",
+ properties: `sdk_version: "test_current",`,
+ bootclasspath: []string{`""`},
+ system: "sdk_public_current_system_modules",
+ java8classpath: []string{"prebuilts/sdk/current/test/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ java9classpath: []string{"prebuilts/sdk/current/test/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ aidl: "-pprebuilts/sdk/current/public/framework.aidl",
+ },
+ {
+ name: "test_30",
+ properties: `sdk_version: "test_30",`,
+ bootclasspath: []string{`""`},
+ system: "sdk_public_30_system_modules",
+ java8classpath: []string{"prebuilts/sdk/30/test/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ java9classpath: []string{"prebuilts/sdk/30/test/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ aidl: "-pprebuilts/sdk/30/public/framework.aidl",
+ },
+ {
+ // Test case only applies when Always_use_prebuilt_sdks=false (the default).
+ forAlwaysUsePrebuiltSdks: proptools.BoolPtr(false),
name: "core_current",
properties: `sdk_version: "core_current",`,
@@ -144,6 +204,18 @@
system: "core-current-stubs-system-modules",
},
{
+ // Test case only applies when Always_use_prebuilt_sdks=true.
+ forAlwaysUsePrebuiltSdks: proptools.BoolPtr(true),
+
+ name: "core_current",
+ properties: `sdk_version: "core_current",`,
+ bootclasspath: []string{`""`},
+ system: "sdk_public_current_system_modules",
+ java8classpath: []string{"prebuilts/sdk/current/core/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ java9classpath: []string{"prebuilts/sdk/current/core/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ aidl: "-pprebuilts/sdk/current/public/framework.aidl",
+ },
+ {
name: "nostdlib",
properties: `sdk_version: "none", system_modules: "none"`,
@@ -214,8 +286,10 @@
java9classpath: []string{"prebuilts/sdk/current/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
aidl: "-pprebuilts/sdk/current/public/framework.aidl",
},
-
{
+ // Test case only applies when Always_use_prebuilt_sdks=false (the default).
+ forAlwaysUsePrebuiltSdks: proptools.BoolPtr(false),
+
name: "module_current",
properties: `sdk_version: "module_current",`,
bootclasspath: []string{"android_module_lib_stubs_current", "core-lambda-stubs"},
@@ -224,6 +298,48 @@
aidl: "-pout/soong/framework_non_updatable.aidl",
},
{
+ // Test case only applies when Always_use_prebuilt_sdks=true.
+ forAlwaysUsePrebuiltSdks: proptools.BoolPtr(true),
+
+ name: "module_current",
+ properties: `sdk_version: "module_current",`,
+ bootclasspath: []string{`""`},
+ system: "sdk_public_current_system_modules",
+ java8classpath: []string{"prebuilts/sdk/current/module-lib/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ java9classpath: []string{"prebuilts/sdk/current/module-lib/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ aidl: "-pprebuilts/sdk/current/public/framework.aidl",
+ },
+ {
+ name: "module_30",
+ properties: `sdk_version: "module_30",`,
+ bootclasspath: []string{`""`},
+ system: "sdk_public_30_system_modules",
+ java8classpath: []string{"prebuilts/sdk/30/module-lib/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ java9classpath: []string{"prebuilts/sdk/30/module-lib/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ aidl: "-pprebuilts/sdk/30/public/framework.aidl",
+ },
+ {
+ name: "module_31",
+ properties: `sdk_version: "module_31",`,
+ bootclasspath: []string{`""`},
+ system: "sdk_public_31_system_modules",
+ java8classpath: []string{"prebuilts/sdk/31/module-lib/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ java9classpath: []string{"prebuilts/sdk/31/module-lib/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ aidl: "-pprebuilts/sdk/31/public/framework.aidl",
+ },
+ {
+ name: "module_32",
+ properties: `sdk_version: "module_32",`,
+ bootclasspath: []string{`""`},
+ system: "sdk_public_32_system_modules",
+ java8classpath: []string{"prebuilts/sdk/32/module-lib/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ java9classpath: []string{"prebuilts/sdk/32/module-lib/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ aidl: "-pprebuilts/sdk/32/public/framework.aidl",
+ },
+ {
+ // Test case only applies when Always_use_prebuilt_sdks=false (the default).
+ forAlwaysUsePrebuiltSdks: proptools.BoolPtr(false),
+
name: "system_server_current",
properties: `sdk_version: "system_server_current",`,
bootclasspath: []string{"android_system_server_stubs_current", "core-lambda-stubs"},
@@ -231,9 +347,62 @@
java9classpath: []string{"android_system_server_stubs_current"},
aidl: "-pout/soong/framework.aidl",
},
+ {
+ // Test case only applies when Always_use_prebuilt_sdks=true.
+ forAlwaysUsePrebuiltSdks: proptools.BoolPtr(true),
+
+ name: "system_server_current",
+ properties: `sdk_version: "system_server_current",`,
+ bootclasspath: []string{`""`},
+ system: "sdk_public_current_system_modules",
+ java8classpath: []string{"prebuilts/sdk/current/system-server/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ java9classpath: []string{"prebuilts/sdk/current/system-server/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ aidl: "-pprebuilts/sdk/current/public/framework.aidl",
+ },
+ {
+ name: "system_server_30",
+ properties: `sdk_version: "system_server_30",`,
+ bootclasspath: []string{`""`},
+ system: "sdk_public_30_system_modules",
+ java8classpath: []string{"prebuilts/sdk/30/system-server/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ java9classpath: []string{"prebuilts/sdk/30/system-server/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ aidl: "-pprebuilts/sdk/30/public/framework.aidl",
+ },
+ {
+ name: "system_server_31",
+ properties: `sdk_version: "system_server_31",`,
+ bootclasspath: []string{`""`},
+ system: "sdk_public_31_system_modules",
+ java8classpath: []string{"prebuilts/sdk/31/system-server/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ java9classpath: []string{"prebuilts/sdk/31/system-server/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ aidl: "-pprebuilts/sdk/31/public/framework.aidl",
+ },
+ {
+ name: "system_server_32",
+ properties: `sdk_version: "system_server_32",`,
+ bootclasspath: []string{`""`},
+ system: "sdk_public_32_system_modules",
+ java8classpath: []string{"prebuilts/sdk/32/system-server/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ java9classpath: []string{"prebuilts/sdk/32/system-server/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"},
+ aidl: "-pprebuilts/sdk/32/public/framework.aidl",
+ },
}
+ t.Run("basic", func(t *testing.T) {
+ testClasspathTestCases(t, classpathTestcases, false)
+ })
+
+ t.Run("Always_use_prebuilt_sdks=true", func(t *testing.T) {
+ testClasspathTestCases(t, classpathTestcases, true)
+ })
+}
+
+func testClasspathTestCases(t *testing.T, classpathTestcases []classpathTestCase, alwaysUsePrebuiltSdks bool) {
for _, testcase := range classpathTestcases {
+ if testcase.forAlwaysUsePrebuiltSdks != nil && *testcase.forAlwaysUsePrebuiltSdks != alwaysUsePrebuiltSdks {
+ continue
+ }
+
t.Run(testcase.name, func(t *testing.T) {
moduleType := "java_library"
if testcase.moduleType != "" {
@@ -299,7 +468,9 @@
system = "--system=none"
} else if testcase.system != "" {
dir := ""
- if strings.HasPrefix(testcase.system, "sdk_public_") {
+ // If the system modules name starts with sdk_ then it is a prebuilt module and so comes
+ // from the prebuilt directory.
+ if strings.HasPrefix(testcase.system, "sdk_") {
dir = "prebuilts/sdk"
} else {
dir = defaultJavaDir
@@ -351,11 +522,20 @@
android.AssertPathsRelativeToTopEquals(t, "implicits", deps, javac.Implicits)
}
+ preparer := android.NullFixturePreparer
+ if alwaysUsePrebuiltSdks {
+ preparer = android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
+ })
+ }
+
fixtureFactory := android.GroupFixturePreparers(
prepareForJavaTest,
FixtureWithPrebuiltApis(map[string][]string{
"29": {},
"30": {},
+ "31": {},
+ "32": {},
"current": {},
}),
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
@@ -369,6 +549,7 @@
env["ANDROID_JAVA8_HOME"] = "jdk8"
}
}),
+ preparer,
)
// Test with legacy javac -source 1.8 -target 1.8
diff --git a/java/testing.go b/java/testing.go
index 99d55a0..fafc8d7 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -159,8 +159,7 @@
`, strings.Join(android.SortedStringKeys(release2Modules), `", "`))
for release, modules := range release2Modules {
- libs := append([]string{"android", "core-for-system-modules"}, modules...)
- mockFS.Merge(prebuiltApisFilesForLibs([]string{release}, libs))
+ mockFS.Merge(prebuiltApisFilesForModules([]string{release}, modules))
}
return android.GroupFixturePreparers(
android.FixtureAddTextFile(path, bp),
@@ -168,19 +167,31 @@
)
}
-func prebuiltApisFilesForLibs(apiLevels []string, sdkLibs []string) map[string][]byte {
+func prebuiltApisFilesForModules(apiLevels []string, modules []string) map[string][]byte {
+ libs := append([]string{"android"}, modules...)
+
fs := make(map[string][]byte)
for _, level := range apiLevels {
- for _, lib := range sdkLibs {
- for _, scope := range []string{"public", "system", "module-lib", "system-server", "test"} {
- fs[fmt.Sprintf("prebuilts/sdk/%s/%s/%s.jar", level, scope, lib)] = nil
+ for _, sdkKind := range []android.SdkKind{android.SdkPublic, android.SdkSystem, android.SdkModule, android.SdkSystemServer, android.SdkTest} {
+ // A core-for-system-modules file must only be created for the sdk kind that supports it.
+ if sdkKind == systemModuleKind() {
+ fs[fmt.Sprintf("prebuilts/sdk/%s/%s/core-for-system-modules.jar", level, sdkKind)] = nil
+ }
+
+ for _, lib := range libs {
+ // Create a jar file for every library.
+ fs[fmt.Sprintf("prebuilts/sdk/%s/%s/%s.jar", level, sdkKind, lib)] = nil
+
// No finalized API files for "current"
if level != "current" {
- fs[fmt.Sprintf("prebuilts/sdk/%s/%s/api/%s.txt", level, scope, lib)] = nil
- fs[fmt.Sprintf("prebuilts/sdk/%s/%s/api/%s-removed.txt", level, scope, lib)] = nil
+ fs[fmt.Sprintf("prebuilts/sdk/%s/%s/api/%s.txt", level, sdkKind, lib)] = nil
+ fs[fmt.Sprintf("prebuilts/sdk/%s/%s/api/%s-removed.txt", level, sdkKind, lib)] = nil
}
}
}
+ if level == "current" {
+ fs["prebuilts/sdk/current/core/android.jar"] = nil
+ }
fs[fmt.Sprintf("prebuilts/sdk/%s/public/framework.aidl", level)] = nil
}
return fs
diff --git a/mk2rbc/cmd/mk2rbc.go b/mk2rbc/cmd/mk2rbc.go
index d8e7018..b089f91 100644
--- a/mk2rbc/cmd/mk2rbc.go
+++ b/mk2rbc/cmd/mk2rbc.go
@@ -60,7 +60,7 @@
)
func init() {
- // Poor man's flag aliasing: works, but the usage string is ugly and
+ // Simplistic flag aliasing: works, but the usage string is ugly and
// both flag and its alias can be present on the command line
flagAlias := func(target string, alias string) {
if f := flag.Lookup(target); f != nil {
diff --git a/mk2rbc/mk2rbc.go b/mk2rbc/mk2rbc.go
index 3ae8ab9..6227164 100644
--- a/mk2rbc/mk2rbc.go
+++ b/mk2rbc/mk2rbc.go
@@ -40,12 +40,15 @@
)
const (
- baseUri = "//build/make/core:product_config.rbc"
+ annotationCommentPrefix = "RBC#"
+ baseUri = "//build/make/core:product_config.rbc"
// The name of the struct exported by the product_config.rbc
// that contains the functions and variables available to
// product configuration Starlark files.
baseName = "rblf"
+ soongNsPrefix = "SOONG_CONFIG_"
+
// And here are the functions and variables:
cfnGetCfg = baseName + ".cfg"
cfnMain = baseName + ".product_configuration"
@@ -60,10 +63,14 @@
const (
// Phony makefile functions, they are eventually rewritten
// according to knownFunctions map
- addSoongNamespace = "add_soong_config_namespace"
- addSoongConfigVarValue = "add_soong_config_var_value"
- fileExistsPhony = "$file_exists"
- wildcardExistsPhony = "$wildcard_exists"
+ fileExistsPhony = "$file_exists"
+ // The following two macros are obsolete, and will we deleted once
+ // there are deleted from the makefiles:
+ soongConfigNamespaceOld = "add_soong_config_namespace"
+ soongConfigVarSetOld = "add_soong_config_var_value"
+ soongConfigAppend = "soong_config_append"
+ soongConfigAssign = "soong_config_set"
+ wildcardExistsPhony = "$wildcard_exists"
)
const (
@@ -82,8 +89,10 @@
"abspath": {baseName + ".abspath", starlarkTypeString, hiddenArgNone},
fileExistsPhony: {baseName + ".file_exists", starlarkTypeBool, hiddenArgNone},
wildcardExistsPhony: {baseName + ".file_wildcard_exists", starlarkTypeBool, hiddenArgNone},
- addSoongNamespace: {baseName + ".add_soong_config_namespace", starlarkTypeVoid, hiddenArgGlobal},
- addSoongConfigVarValue: {baseName + ".add_soong_config_var_value", starlarkTypeVoid, hiddenArgGlobal},
+ soongConfigNamespaceOld: {baseName + ".soong_config_namespace", starlarkTypeVoid, hiddenArgGlobal},
+ soongConfigVarSetOld: {baseName + ".soong_config_set", starlarkTypeVoid, hiddenArgGlobal},
+ soongConfigAssign: {baseName + ".soong_config_set", starlarkTypeVoid, hiddenArgGlobal},
+ soongConfigAppend: {baseName + ".soong_config_append", starlarkTypeVoid, hiddenArgGlobal},
"add-to-product-copy-files-if-exists": {baseName + ".copy_if_exists", starlarkTypeList, hiddenArgNone},
"addprefix": {baseName + ".addprefix", starlarkTypeList, hiddenArgNone},
"addsuffix": {baseName + ".addsuffix", starlarkTypeList, hiddenArgNone},
@@ -102,13 +111,16 @@
"is-android-codename": {"!is-android-codename", starlarkTypeBool, hiddenArgNone}, // unused by product config
"is-android-codename-in-list": {"!is-android-codename-in-list", starlarkTypeBool, hiddenArgNone}, // unused by product config
"is-board-platform": {"!is-board-platform", starlarkTypeBool, hiddenArgNone},
+ "is-board-platform2": {baseName + ".board_platform_is", starlarkTypeBool, hiddenArgGlobal},
"is-board-platform-in-list": {"!is-board-platform-in-list", starlarkTypeBool, hiddenArgNone},
+ "is-board-platform-in-list2": {baseName + ".board_platform_in", starlarkTypeBool, hiddenArgGlobal},
"is-chipset-in-board-platform": {"!is-chipset-in-board-platform", starlarkTypeUnknown, hiddenArgNone}, // unused by product config
"is-chipset-prefix-in-board-platform": {"!is-chipset-prefix-in-board-platform", starlarkTypeBool, hiddenArgNone}, // unused by product config
"is-not-board-platform": {"!is-not-board-platform", starlarkTypeBool, hiddenArgNone}, // defined but never used
"is-platform-sdk-version-at-least": {"!is-platform-sdk-version-at-least", starlarkTypeBool, hiddenArgNone}, // unused by product config
"is-product-in-list": {"!is-product-in-list", starlarkTypeBool, hiddenArgNone},
"is-vendor-board-platform": {"!is-vendor-board-platform", starlarkTypeBool, hiddenArgNone},
+ "is-vendor-board-qcom": {"!is-vendor-board-qcom", starlarkTypeBool, hiddenArgNone},
callLoadAlways: {"!inherit-product", starlarkTypeVoid, hiddenArgNone},
callLoadIf: {"!inherit-product-if-exists", starlarkTypeVoid, hiddenArgNone},
"lastword": {"!lastword", starlarkTypeString, hiddenArgNone},
@@ -399,6 +411,7 @@
outputDir string
dependentModules map[string]*moduleInfo
soongNamespaces map[string]map[string]bool
+ includeTops []string
}
func newParseContext(ss *StarlarkScript, nodes []mkparser.Node) *parseContext {
@@ -444,6 +457,7 @@
variables: make(map[string]variable),
dependentModules: make(map[string]*moduleInfo),
soongNamespaces: make(map[string]map[string]bool),
+ includeTops: []string{"vendor/google-devices"},
}
ctx.pushVarAssignments()
for _, item := range predefined {
@@ -522,7 +536,6 @@
return
}
name := a.Name.Strings[0]
- const soongNsPrefix = "SOONG_CONFIG_"
// Soong confuguration
if strings.HasPrefix(name, soongNsPrefix) {
ctx.handleSoongNsAssignment(strings.TrimPrefix(name, soongNsPrefix), a)
@@ -615,7 +628,7 @@
for _, ns := range strings.Fields(s) {
ctx.addSoongNamespace(ns)
ctx.receiver.newNode(&exprNode{&callExpr{
- name: addSoongNamespace,
+ name: soongConfigNamespaceOld,
args: []starlarkExpr{&stringLiteralExpr{ns}},
returnType: starlarkTypeVoid,
}})
@@ -665,8 +678,12 @@
ctx.errorf(asgn, "no %s variable in %s namespace, please use add_soong_config_var_value instead", varName, namespaceName)
return
}
+ fname := soongConfigVarSetOld
+ if asgn.Type == "+=" {
+ fname = soongConfigAppend
+ }
ctx.receiver.newNode(&exprNode{&callExpr{
- name: addSoongConfigVarValue,
+ name: fname,
args: []starlarkExpr{&stringLiteralExpr{namespaceName}, &stringLiteralExpr{varName}, val},
returnType: starlarkTypeVoid,
}})
@@ -799,21 +816,15 @@
pathPattern = append(pathPattern, chunk)
}
}
- if pathPattern[0] != "" {
- matchingPaths = ctx.findMatchingPaths(pathPattern)
- } else {
- // Heuristics -- if pattern starts from top, restrict it to the directories where
- // we know inherit-product uses dynamically calculated path. Restrict it even further
- // for certain path which would yield too many useless matches
- if len(varPath.chunks) == 2 && varPath.chunks[1] == "/BoardConfigVendor.mk" {
- pathPattern[0] = "vendor/google_devices"
- matchingPaths = ctx.findMatchingPaths(pathPattern)
- } else {
- for _, t := range []string{"vendor/qcom", "vendor/google_devices"} {
- pathPattern[0] = t
- matchingPaths = append(matchingPaths, ctx.findMatchingPaths(pathPattern)...)
- }
+ if pathPattern[0] == "" {
+ // If pattern starts from the top. restrict it to the directories where
+ // we know inherit-product uses dynamically calculated path.
+ for _, p := range ctx.includeTops {
+ pathPattern[0] = p
+ matchingPaths = append(matchingPaths, ctx.findMatchingPaths(pathPattern)...)
}
+ } else {
+ matchingPaths = ctx.findMatchingPaths(pathPattern)
}
// Safeguard against $(call inherit-product,$(PRODUCT_PATH))
const maxMatchingFiles = 150
@@ -1133,6 +1144,34 @@
list: &variableRefExpr{ctx.addVariable(s + "_BOARD_PLATFORMS"), true},
isNot: negate,
}, true
+
+ case "is-board-platform2", "is-board-platform-in-list2":
+ if s, ok := maybeString(xValue); !ok || s != "" {
+ return ctx.newBadExpr(directive,
+ fmt.Sprintf("the result of %s can be compared only to empty", x.name)), true
+ }
+ if len(x.args) != 1 {
+ return ctx.newBadExpr(directive, "%s requires an argument", x.name), true
+ }
+ cc := &callExpr{
+ name: x.name,
+ args: []starlarkExpr{x.args[0]},
+ returnType: starlarkTypeBool,
+ }
+ if !negate {
+ return ¬Expr{cc}, true
+ }
+ return cc, true
+ case "is-vendor-board-qcom":
+ if s, ok := maybeString(xValue); !ok || s != "" {
+ return ctx.newBadExpr(directive,
+ fmt.Sprintf("the result of %s can be compared only to empty", x.name)), true
+ }
+ return &inExpr{
+ expr: &variableRefExpr{ctx.addVariable("TARGET_BOARD_PLATFORM"), false},
+ list: &variableRefExpr{ctx.addVariable("QCOM_BOARD_PLATFORMS"), true},
+ isNot: negate,
+ }, true
default:
return ctx.newBadExpr(directive, "Unknown function in ifeq: %s", x.name), true
}
@@ -1162,17 +1201,21 @@
}
// Either pattern or text should be const, and the
// non-const one should be varRefExpr
- if xInList, ok = xPattern.(*stringLiteralExpr); ok {
+ if xInList, ok = xPattern.(*stringLiteralExpr); ok && !strings.ContainsRune(xInList.literal, '%') && xText.typ() == starlarkTypeList {
expr = xText
} else if xInList, ok = xText.(*stringLiteralExpr); ok {
expr = xPattern
} else {
- return &callExpr{
+ expr = &callExpr{
object: nil,
name: filterFuncCall.name,
args: filterFuncCall.args,
returnType: starlarkTypeBool,
}
+ if negate {
+ expr = ¬Expr{expr: expr}
+ }
+ return expr
}
case *variableRefExpr:
if v, ok := xPattern.(*variableRefExpr); ok {
@@ -1273,6 +1316,10 @@
returnType: starlarkTypeUnknown,
}
}
+ if strings.HasPrefix(refDump, soongNsPrefix) {
+ // TODO (asmundak): if we find many, maybe handle them.
+ return ctx.newBadExpr(node, "SOONG_CONFIG_ variables cannot be referenced: %s", refDump)
+ }
if v := ctx.addVariable(refDump); v != nil {
return &variableRefExpr{v, ctx.lastAssignment(v.name()) != nil}
}
@@ -1434,6 +1481,7 @@
handled := true
switch x := node.(type) {
case *mkparser.Comment:
+ ctx.maybeHandleAnnotation(x)
ctx.insertComment("#" + x.Comment)
case *mkparser.Assignment:
ctx.handleAssignment(x)
@@ -1449,11 +1497,33 @@
handled = false
}
default:
- ctx.errorf(x, "unsupported line %s", x.Dump())
+ ctx.errorf(x, "unsupported line %s", strings.ReplaceAll(x.Dump(), "\n", "\n#"))
}
return handled
}
+// Processes annotation. An annotation is a comment that starts with #RBC# and provides
+// a conversion hint -- say, where to look for the dynamically calculated inherit/include
+// paths.
+func (ctx *parseContext) maybeHandleAnnotation(cnode *mkparser.Comment) {
+ maybeTrim := func(s, prefix string) (string, bool) {
+ if strings.HasPrefix(s, prefix) {
+ return strings.TrimSpace(strings.TrimPrefix(s, prefix)), true
+ }
+ return s, false
+ }
+ annotation, ok := maybeTrim(cnode.Comment, annotationCommentPrefix)
+ if !ok {
+ return
+ }
+ if p, ok := maybeTrim(annotation, "include_top"); ok {
+ ctx.includeTops = append(ctx.includeTops, p)
+ return
+ }
+ ctx.errorf(cnode, "unsupported annotation %s", cnode.Comment)
+
+}
+
func (ctx *parseContext) insertComment(s string) {
ctx.receiver.newNode(&commentNode{strings.TrimSpace(s)})
}
diff --git a/mk2rbc/mk2rbc_test.go b/mk2rbc/mk2rbc_test.go
index 434500b..511bb0f 100644
--- a/mk2rbc/mk2rbc_test.go
+++ b/mk2rbc/mk2rbc_test.go
@@ -360,20 +360,27 @@
endif
ifneq (,$(filter true, $(v1)$(v2)))
endif
+ifeq (,$(filter barbet coral%,$(TARGET_PRODUCT)))
+else ifneq (,$(filter barbet%,$(TARGET_PRODUCT)))
+endif
`,
expected: `load("//build/make/core:product_config.rbc", "rblf")
def init(g, handle):
cfg = rblf.cfg(handle)
- if g["TARGET_BUILD_VARIANT"] not in ["userdebug", "eng"]:
+ if not rblf.filter("userdebug eng", g["TARGET_BUILD_VARIANT"]):
pass
- if g["TARGET_BUILD_VARIANT"] == "userdebug":
+ if rblf.filter("userdebug", g["TARGET_BUILD_VARIANT"]):
pass
if "plaf" in g.get("PLATFORM_LIST", []):
pass
if g["TARGET_BUILD_VARIANT"] in ["userdebug", "eng"]:
pass
- if "%s%s" % (_v1, _v2) == "true":
+ if rblf.filter("true", "%s%s" % (_v1, _v2)):
+ pass
+ if not rblf.filter("barbet coral%", g["TARGET_PRODUCT"]):
+ pass
+ elif rblf.filter("barbet%", g["TARGET_PRODUCT"]):
pass
`,
},
@@ -556,6 +563,27 @@
`,
},
{
+ desc: "new is-board calls",
+ mkname: "product.mk",
+ in: `
+ifneq (,$(call is-board-platform-in-list2,msm8998 $(X))
+else ifeq (,$(call is-board-platform2,copper)
+else ifneq (,$(call is-vendor-board-qcom))
+endif
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ if rblf.board_platform_in(g, "msm8998 %s" % g.get("X", "")):
+ pass
+ elif not rblf.board_platform_is(g, "copper"):
+ pass
+ elif g.get("TARGET_BOARD_PLATFORM", "") not in g["QCOM_BOARD_PLATFORMS"]:
+ pass
+`,
+ },
+ {
desc: "findstring call",
mkname: "product.mk",
in: `
@@ -674,6 +702,8 @@
$(info $(notdir foo/bar))
$(call add_soong_config_namespace,snsconfig)
$(call add_soong_config_var_value,snsconfig,imagetype,odm_image)
+$(call soong_config_set, snsconfig, foo, foo_value)
+$(call soong_config_append, snsconfig, bar, bar_value)
PRODUCT_COPY_FILES := $(call copy-files,$(wildcard foo*.mk),etc)
PRODUCT_COPY_FILES := $(call product-copy-files-by-pattern,from/%,to/%,a b c)
`,
@@ -693,8 +723,10 @@
rblf.mkinfo("product.mk", rblf.dir((_foobar).split()[-1]))
rblf.mkinfo("product.mk", rblf.abspath("foo/bar"))
rblf.mkinfo("product.mk", rblf.notdir("foo/bar"))
- rblf.add_soong_config_namespace(g, "snsconfig")
- rblf.add_soong_config_var_value(g, "snsconfig", "imagetype", "odm_image")
+ rblf.soong_config_namespace(g, "snsconfig")
+ rblf.soong_config_set(g, "snsconfig", "imagetype", "odm_image")
+ rblf.soong_config_set(g, "snsconfig", "foo", "foo_value")
+ rblf.soong_config_append(g, "snsconfig", "bar", "bar_value")
cfg["PRODUCT_COPY_FILES"] = rblf.copy_files(rblf.expand_wildcard("foo*.mk"), "etc")
cfg["PRODUCT_COPY_FILES"] = rblf.product_copy_files_by_pattern("from/%", "to/%", "a b c")
`,
@@ -777,17 +809,21 @@
in: `
SOONG_CONFIG_NAMESPACES += cvd
SOONG_CONFIG_cvd += launch_configs
-SOONG_CONFIG_cvd_launch_configs += cvd_config_auto.json
+SOONG_CONFIG_cvd_launch_configs = cvd_config_auto.json
SOONG_CONFIG_cvd += grub_config
SOONG_CONFIG_cvd_grub_config += grub.cfg
+x := $(SOONG_CONFIG_cvd_grub_config)
`,
expected: `load("//build/make/core:product_config.rbc", "rblf")
def init(g, handle):
cfg = rblf.cfg(handle)
- rblf.add_soong_config_namespace(g, "cvd")
- rblf.add_soong_config_var_value(g, "cvd", "launch_configs", "cvd_config_auto.json")
- rblf.add_soong_config_var_value(g, "cvd", "grub_config", "grub.cfg")
+ rblf.soong_config_namespace(g, "cvd")
+ rblf.soong_config_set(g, "cvd", "launch_configs", "cvd_config_auto.json")
+ rblf.soong_config_append(g, "cvd", "grub_config", "grub.cfg")
+ # MK2RBC TRANSLATION ERROR: SOONG_CONFIG_ variables cannot be referenced: SOONG_CONFIG_cvd_grub_config
+ # x := $(SOONG_CONFIG_cvd_grub_config)
+ rblf.warning("product.mk", "partially successful conversion")
`,
},
{
@@ -904,7 +940,7 @@
desc: "Dynamic inherit path",
mkname: "product.mk",
in: `
-MY_PATH=foo
+MY_PATH:=foo
$(call inherit-product,vendor/$(MY_PATH)/cfg.mk)
`,
expected: `load("//build/make/core:product_config.rbc", "rblf")
@@ -924,6 +960,47 @@
rblf.inherit(handle, _varmod, _varmod_init)
`,
},
+ {
+ desc: "Dynamic inherit with hint",
+ mkname: "product.mk",
+ in: `
+MY_PATH:=foo
+#RBC# include_top vendor/foo1
+$(call inherit-product,$(MY_PATH)/cfg.mk)
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+load("//vendor/foo1:cfg.star|init", _cfg_init = "init")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ g["MY_PATH"] = "foo"
+ #RBC# include_top vendor/foo1
+ _entry = {
+ "vendor/foo1/cfg.mk": ("_cfg", _cfg_init),
+ }.get("%s/cfg.mk" % g["MY_PATH"])
+ (_varmod, _varmod_init) = _entry if _entry else (None, None)
+ if not _varmod_init:
+ rblf.mkerror("cannot")
+ rblf.inherit(handle, _varmod, _varmod_init)
+`,
+ },
+ {
+ desc: "Ignore make rules",
+ mkname: "product.mk",
+ in: `
+foo: foo.c
+ gcc -o $@ $*`,
+ expected: `# MK2RBC TRANSLATION ERROR: unsupported line rule: foo: foo.c
+#gcc -o $@ $*
+# rule: foo: foo.c
+# gcc -o $@ $*
+load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ rblf.warning("product.mk", "partially successful conversion")
+`,
+ },
}
var known_variables = []struct {
diff --git a/mk2rbc/types.go b/mk2rbc/types.go
index ebd52d8..46c6aa9 100644
--- a/mk2rbc/types.go
+++ b/mk2rbc/types.go
@@ -53,7 +53,7 @@
NewVariable(name string, varClass varClass, valueType starlarkType)
}
-// ScopeBase is a dummy implementation of the mkparser.Scope.
+// ScopeBase is a placeholder implementation of the mkparser.Scope.
// All our scopes are read-only and resolve only simple variables.
type ScopeBase struct{}
diff --git a/mk2rbc/version_defaults.go b/mk2rbc/version_defaults.go
index 27e8198..64645d7 100644
--- a/mk2rbc/version_defaults.go
+++ b/mk2rbc/version_defaults.go
@@ -15,7 +15,6 @@
package mk2rbc
import (
- mkparser "android/soong/androidmk/parser"
"bytes"
"fmt"
"io/ioutil"
@@ -23,6 +22,8 @@
"sort"
"strconv"
"strings"
+
+ mkparser "android/soong/androidmk/parser"
)
const codenamePrefix = "PLATFORM_VERSION_CODENAME."
@@ -97,7 +98,10 @@
strings.ToLower(name), genericValue(value)))
}
}
+
sort.Strings(lines)
+ sort.Strings(codenames)
+
sink.WriteString("version_defaults = struct(\n")
for _, l := range lines {
sink.WriteString(l)
diff --git a/rust/builder.go b/rust/builder.go
index 426a569..f79cf9b 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -95,7 +95,7 @@
func TransformSrcToBinary(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
outputFile android.WritablePath) buildOutput {
- flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto")
+ flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "bin")
}
@@ -112,13 +112,13 @@
func TransformSrctoStatic(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
outputFile android.WritablePath) buildOutput {
- flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto")
+ flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "staticlib")
}
func TransformSrctoShared(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
outputFile android.WritablePath) buildOutput {
- flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto")
+ flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "cdylib")
}
diff --git a/rust/config/Android.bp b/rust/config/Android.bp
index 5b121c3..7757c79 100644
--- a/rust/config/Android.bp
+++ b/rust/config/Android.bp
@@ -16,7 +16,7 @@
"lints.go",
"toolchain.go",
"allowed_list.go",
- "x86_darwin_host.go",
+ "darwin_host.go",
"x86_linux_bionic_host.go",
"x86_linux_host.go",
"x86_device.go",
diff --git a/rust/config/allowed_list.go b/rust/config/allowed_list.go
index 47ca3a7..8182c32 100644
--- a/rust/config/allowed_list.go
+++ b/rust/config/allowed_list.go
@@ -18,6 +18,7 @@
"frameworks/native/libs/binder/rust",
"frameworks/proto_logging/stats",
"packages/modules/DnsResolver",
+ "packages/modules/Uwb",
"packages/modules/Virtualization",
"prebuilts/rust",
"system/bt",
@@ -32,6 +33,7 @@
"system/security",
"system/tools/aidl",
"tools/security/fuzzing/example_rust_fuzzer",
+ "tools/security/fuzzing/orphans",
"vendor/",
}
diff --git a/rust/config/x86_darwin_host.go b/rust/config/darwin_host.go
similarity index 67%
rename from rust/config/x86_darwin_host.go
rename to rust/config/darwin_host.go
index 8ff0dd4..03bea82 100644
--- a/rust/config/x86_darwin_host.go
+++ b/rust/config/darwin_host.go
@@ -25,41 +25,64 @@
DarwinRustLinkFlags = []string{
"-B${cc_config.MacToolPath}",
}
+ darwinArm64Rustflags = []string{}
+ darwinArm64Linkflags = []string{}
darwinX8664Rustflags = []string{}
darwinX8664Linkflags = []string{}
)
func init() {
+ registerToolchainFactory(android.Darwin, android.Arm64, darwinArm64ToolchainFactory)
registerToolchainFactory(android.Darwin, android.X86_64, darwinX8664ToolchainFactory)
+
pctx.StaticVariable("DarwinToolchainRustFlags", strings.Join(DarwinRustFlags, " "))
pctx.StaticVariable("DarwinToolchainLinkFlags", strings.Join(DarwinRustLinkFlags, " "))
+
+ pctx.StaticVariable("DarwinToolchainArm64RustFlags", strings.Join(darwinArm64Rustflags, " "))
+ pctx.StaticVariable("DarwinToolchainArm64LinkFlags", strings.Join(darwinArm64Linkflags, " "))
pctx.StaticVariable("DarwinToolchainX8664RustFlags", strings.Join(darwinX8664Rustflags, " "))
pctx.StaticVariable("DarwinToolchainX8664LinkFlags", strings.Join(darwinX8664Linkflags, " "))
}
type toolchainDarwin struct {
+ toolchain64Bit
toolchainRustFlags string
toolchainLinkFlags string
}
-type toolchainDarwinX8664 struct {
- toolchain64Bit
+type toolchainDarwinArm64 struct {
toolchainDarwin
}
+type toolchainDarwinX8664 struct {
+ toolchainDarwin
+}
+
+func (toolchainDarwinArm64) Supported() bool {
+ return true
+}
+
func (toolchainDarwinX8664) Supported() bool {
return true
}
-func (toolchainDarwinX8664) Bionic() bool {
+func (toolchainDarwin) Bionic() bool {
return false
}
+func (t *toolchainDarwinArm64) Name() string {
+ return "arm64"
+}
+
func (t *toolchainDarwinX8664) Name() string {
return "x86_64"
}
+func (t *toolchainDarwinArm64) RustTriple() string {
+ return "aarch64-apple-darwin"
+}
+
func (t *toolchainDarwinX8664) RustTriple() string {
return "x86_64-apple-darwin"
}
@@ -76,6 +99,15 @@
return ".dylib"
}
+func (t *toolchainDarwinArm64) ToolchainLinkFlags() string {
+ // Prepend the lld flags from cc_config so we stay in sync with cc
+ return "${cc_config.DarwinLldflags} ${config.DarwinToolchainLinkFlags} ${config.DarwinToolchainArm64LinkFlags}"
+}
+
+func (t *toolchainDarwinArm64) ToolchainRustFlags() string {
+ return "${config.DarwinToolchainRustFlags} ${config.DarwinToolchainArm64RustFlags}"
+}
+
func (t *toolchainDarwinX8664) ToolchainLinkFlags() string {
// Prepend the lld flags from cc_config so we stay in sync with cc
return "${cc_config.DarwinLldflags} ${config.DarwinToolchainLinkFlags} ${config.DarwinToolchainX8664LinkFlags}"
@@ -85,8 +117,13 @@
return "${config.DarwinToolchainRustFlags} ${config.DarwinToolchainX8664RustFlags}"
}
+func darwinArm64ToolchainFactory(arch android.Arch) Toolchain {
+ return toolchainDarwinArm64Singleton
+}
+
func darwinX8664ToolchainFactory(arch android.Arch) Toolchain {
return toolchainDarwinX8664Singleton
}
+var toolchainDarwinArm64Singleton Toolchain = &toolchainDarwinArm64{}
var toolchainDarwinX8664Singleton Toolchain = &toolchainDarwinX8664{}
diff --git a/scripts/build-aml-prebuilts.sh b/scripts/build-aml-prebuilts.sh
index 8a5513e..1a16f7c 100755
--- a/scripts/build-aml-prebuilts.sh
+++ b/scripts/build-aml-prebuilts.sh
@@ -23,10 +23,10 @@
export OUT_DIR=${OUT_DIR:-out}
if [ -e ${OUT_DIR}/soong/.soong.kati_enabled ]; then
- # If ${OUT_DIR} has been created without --skip-make, Soong will create an
+ # If ${OUT_DIR} has been created without --soong-only, Soong will create an
# ${OUT_DIR}/soong/build.ninja that leaves out many targets which are
# expected to be supplied by the .mk files, and that might cause errors in
- # "m --skip-make" below. We therefore default to a different out dir
+ # "m --soong-only" below. We therefore default to a different out dir
# location in that case.
AML_OUT_DIR=out/aml
echo "Avoiding in-make OUT_DIR '${OUT_DIR}' - building in '${AML_OUT_DIR}' instead"
diff --git a/scripts/build-mainline-modules.sh b/scripts/build-mainline-modules.sh
index b05861b..f183c05 100755
--- a/scripts/build-mainline-modules.sh
+++ b/scripts/build-mainline-modules.sh
@@ -17,6 +17,7 @@
MODULES_SDK_AND_EXPORTS=(
art-module-sdk
art-module-test-exports
+ compos-module-sdk
conscrypt-module-host-exports
conscrypt-module-sdk
conscrypt-module-test-exports
@@ -98,7 +99,7 @@
export FORCE_BUILD_LLVM_COMPONENTS=true
# Create multi-archs SDKs in a different out directory. The multi-arch script
-# uses Soong in --skip-make mode which cannot use the same directory as normal
+# uses Soong in --soong-only mode which cannot use the same directory as normal
# mode with make.
export OUT_DIR=${OUT_DIR}/aml
echo_and_run build/soong/scripts/build-aml-prebuilts.sh \
diff --git a/scripts/build-ndk-prebuilts.sh b/scripts/build-ndk-prebuilts.sh
index a1fa48d..4783037 100755
--- a/scripts/build-ndk-prebuilts.sh
+++ b/scripts/build-ndk-prebuilts.sh
@@ -64,7 +64,7 @@
"MissingUsesLibraries": ${MISSING_USES_LIBRARIES}
}
EOF
-m --skip-make ${SOONG_OUT}/ndk.timestamp
+m --soong-only --skip-config ${SOONG_OUT}/ndk.timestamp
if [ -n "${DIST_DIR}" ]; then
mkdir -p ${DIST_DIR} || true
diff --git a/scripts/check_boot_jars/package_allowed_list.txt b/scripts/check_boot_jars/package_allowed_list.txt
index b1b1e7e..ed63651 100644
--- a/scripts/check_boot_jars/package_allowed_list.txt
+++ b/scripts/check_boot_jars/package_allowed_list.txt
@@ -69,6 +69,7 @@
javax\.xml\.transform\.stream
javax\.xml\.validation
javax\.xml\.xpath
+jdk\.internal
jdk\.internal\.math
jdk\.internal\.misc
jdk\.internal\.reflect
diff --git a/scripts/gen_ndk_backedby_apex.sh b/scripts/gen_ndk_backedby_apex.sh
index 4abaaba..212362e 100755
--- a/scripts/gen_ndk_backedby_apex.sh
+++ b/scripts/gen_ndk_backedby_apex.sh
@@ -21,52 +21,29 @@
# After the parse function below "dlopen" would be write to the output file.
printHelp() {
echo "**************************** Usage Instructions ****************************"
- echo "This script is used to generate the Mainline modules backed-by NDK symbols."
+ echo "This script is used to generate the native libraries backed by Mainline modules."
echo ""
- echo "To run this script use: ./gen_ndk_backed_by_apex.sh \$OUTPUT_FILE_PATH \$NDK_LIB_NAME_LIST \$MODULE_LIB1 \$MODULE_LIB2..."
+ echo "To run this script use: ./gen_ndk_backed_by_apex.sh \$OUTPUT_FILE_PATH \$MODULE_LIB1 \$MODULE_LIB2..."
echo "For example: If output write to /backedby.txt then the command would be:"
- echo "./gen_ndk_backed_by_apex.sh /backedby.txt /ndkLibList.txt lib1.so lib2.so"
+ echo "./gen_ndk_backed_by_apex.sh /backedby.txt lib1.so lib2.so"
echo "If the module1 is backing lib1 then the backedby.txt would contains: "
- echo "lib1"
+ echo "lib1.so lib2.so"
}
-contains() {
- val="$1"
- shift
- for x in "$@"; do
- if [ "$x" = "$val" ]; then
- return 0
- fi
- done
- return 1
-}
-
-
-genBackedByList() {
+genAllBackedByList() {
out="$1"
shift
- ndk_list="$1"
- shift
rm -f "$out"
touch "$out"
- while IFS= read -r line
- do
- soFileName=$(echo "$line" | sed 's/\(.*so\).*/\1/')
- if [[ ! -z "$soFileName" && "$soFileName" != *"#"* ]]
- then
- if contains "$soFileName" "$@"; then
- echo "$soFileName" >> "$out"
- fi
- fi
- done < "$ndk_list"
+ echo "$@" >> "$out"
}
if [[ "$1" == "help" ]]
then
printHelp
-elif [[ "$#" -lt 2 ]]
+elif [[ "$#" -lt 1 ]]
then
- echo "Wrong argument length. Expecting at least 2 argument representing output path, path to ndk library list, followed by a list of libraries in the Mainline module."
+ echo "Wrong argument length. Expecting at least 1 argument representing output path, followed by a list of libraries in the Mainline module."
else
- genBackedByList "$@"
+ genAllBackedByList "$@"
fi
diff --git a/scripts/manifest_check.py b/scripts/manifest_check.py
index b4936b8..8bed52a 100755
--- a/scripts/manifest_check.py
+++ b/scripts/manifest_check.py
@@ -84,6 +84,13 @@
return parser.parse_args()
+C_RED = "\033[1;31m"
+C_GREEN = "\033[1;32m"
+C_BLUE = "\033[1;34m"
+C_OFF = "\033[0m"
+C_BOLD = "\033[1m"
+
+
def enforce_uses_libraries(manifest, required, optional, relax, is_apk, path):
"""Verify that the <uses-library> tags in the manifest match those provided
@@ -119,22 +126,21 @@
errmsg = ''.join([
'mismatch in the <uses-library> tags between the build system and the '
'manifest:\n',
- '\t- required libraries in build system: [%s]\n' % ', '.join(required),
- '\t vs. in the manifest: [%s]\n' %
- ', '.join(manifest_required),
- '\t- optional libraries in build system: [%s]\n' % ', '.join(optional),
- '\t vs. in the manifest: [%s]\n' %
- ', '.join(manifest_optional),
+ '\t- required libraries in build system: %s[%s]%s\n' % (C_RED, ', '.join(required), C_OFF),
+ '\t vs. in the manifest: %s[%s]%s\n' % (C_RED, ', '.join(manifest_required), C_OFF),
+ '\t- optional libraries in build system: %s[%s]%s\n' % (C_RED, ', '.join(optional), C_OFF),
+ '\t vs. in the manifest: %s[%s]%s\n' % (C_RED, ', '.join(manifest_optional), C_OFF),
'\t- tags in the manifest (%s):\n' % path,
'\t\t%s\n' % '\t\t'.join(tags),
- 'note: the following options are available:\n',
+ '%snote:%s the following options are available:\n' % (C_BLUE, C_OFF),
'\t- to temporarily disable the check on command line, rebuild with ',
- 'RELAX_USES_LIBRARY_CHECK=true (this will set compiler filter "verify" ',
- 'and disable AOT-compilation in dexpreopt)\n',
+ '%sRELAX_USES_LIBRARY_CHECK=true%s' % (C_BOLD, C_OFF),
+ ' (this will set compiler filter "verify" and disable AOT-compilation in dexpreopt)\n',
'\t- to temporarily disable the check for the whole product, set ',
- 'PRODUCT_BROKEN_VERIFY_USES_LIBRARIES := true in the product makefiles\n',
- '\t- to fix the check, make build system properties coherent with the '
- 'manifest\n', '\t- see build/make/Changes.md for details\n'
+ '%sPRODUCT_BROKEN_VERIFY_USES_LIBRARIES := true%s in the product makefiles\n' % (C_BOLD, C_OFF),
+ '\t- to fix the check, make build system properties coherent with the manifest\n',
+ '\t- for details, see %sbuild/make/Changes.md%s' % (C_GREEN, C_OFF),
+ ' and %shttps://source.android.com/devices/tech/dalvik/art-class-loader-context%s\n' % (C_GREEN, C_OFF)
])
#pylint: enable=line-too-long
@@ -380,7 +386,7 @@
# pylint: disable=broad-except
except Exception as err:
- print('error: ' + str(err), file=sys.stderr)
+ print('%serror:%s ' % (C_RED, C_OFF) + str(err), file=sys.stderr)
sys.exit(-1)
diff --git a/soong.bash b/soong.bash
index 8cf2ec6..db7af7c 100755
--- a/soong.bash
+++ b/soong.bash
@@ -15,8 +15,8 @@
# limitations under the License.
echo '==== ERROR: bootstrap.bash & ./soong are obsolete ====' >&2
-echo 'Use `m --skip-make` with a standalone OUT_DIR instead.' >&2
+echo 'Use `m --soong-only` with a standalone OUT_DIR instead.' >&2
echo 'Without envsetup.sh, use:' >&2
-echo ' build/soong/soong_ui.bash --make-mode --skip-make' >&2
+echo ' build/soong/soong_ui.bash --make-mode --soong-only' >&2
echo '======================================================' >&2
exit 1
diff --git a/tests/lib.sh b/tests/lib.sh
index e777820..e6074f8 100644
--- a/tests/lib.sh
+++ b/tests/lib.sh
@@ -105,7 +105,7 @@
}
function run_soong() {
- build/soong/soong_ui.bash --make-mode --skip-ninja --skip-make --skip-soong-tests "$@"
+ build/soong/soong_ui.bash --make-mode --skip-ninja --skip-config --soong-only --skip-soong-tests "$@"
}
function create_mock_bazel() {
@@ -125,7 +125,7 @@
}
run_ninja() {
- build/soong/soong_ui.bash --make-mode --skip-make --skip-soong-tests "$@"
+ build/soong/soong_ui.bash --make-mode --skip-config --soong-only --skip-soong-tests "$@"
}
info "Starting Soong integration test suite $(basename $0)"
diff --git a/third_party/zip/reader_test.go b/third_party/zip/reader_test.go
index dfaae78..11c6d6e 100644
--- a/third_party/zip/reader_test.go
+++ b/third_party/zip/reader_test.go
@@ -786,7 +786,7 @@
}
}
-// Verify the number of files is sane.
+// Verify the number of files is within expected bounds
func TestIssue10956(t *testing.T) {
data := []byte("PK\x06\x06PK\x06\a0000\x00\x00\x00\x00\x00\x00\x00\x00" +
"0000PK\x05\x06000000000000" +
diff --git a/ui/build/config.go b/ui/build/config.go
index 7837cc4..07ffb44 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -796,10 +796,6 @@
return shared.JoinPath(c.SoongOutDir(), usedEnvFile+"."+tag)
}
-func (c *configImpl) MainNinjaFile() string {
- return shared.JoinPath(c.SoongOutDir(), "build.ninja")
-}
-
func (c *configImpl) Bp2BuildMarkerFile() string {
return shared.JoinPath(c.SoongOutDir(), ".bootstrap/bp2build_workspace_marker")
}
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 617d293..a0f223b 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -170,7 +170,7 @@
ctx.BeginTrace(metrics.RunSoong, "blueprint bootstrap")
defer ctx.EndTrace()
- mainSoongBuildExtraArgs := []string{"-o", config.MainNinjaFile()}
+ mainSoongBuildExtraArgs := []string{"-o", config.SoongNinjaFile()}
if config.EmptyNinjaFile() {
mainSoongBuildExtraArgs = append(mainSoongBuildExtraArgs, "--empty-ninja-file")
}
@@ -178,7 +178,7 @@
mainSoongBuildInvocation := primaryBuilderInvocation(
config,
soongBuildTag,
- config.MainNinjaFile(),
+ config.SoongNinjaFile(),
mainSoongBuildExtraArgs)
if config.bazelBuildMode() == mixedBuild {
@@ -401,7 +401,7 @@
if config.SoongBuildInvocationNeeded() {
// This build generates <builddir>/build.ninja, which is used later by build/soong/ui/build/build.go#Build().
- targets = append(targets, config.MainNinjaFile())
+ targets = append(targets, config.SoongNinjaFile())
}
ninja("bootstrap", ".bootstrap/build.ninja", targets...)