Merge "Add recursive deny to allowlists."
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 308827c..29695d6 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -144,6 +144,9 @@
// Returns the results of the GetApexInfo query (including output files)
GetApexInfo(label string, cfgkey configKey) (cquery.ApexCqueryInfo, error)
+ // Returns the results of the GetCcUnstrippedInfo query
+ GetCcUnstrippedInfo(label string, cfgkey configKey) (cquery.CcUnstrippedInfo, error)
+
// ** end Cquery Results Retrieval Functions
// Issues commands to Bazel to receive results for all cquery requests
@@ -224,6 +227,7 @@
LabelToCcInfo map[string]cquery.CcInfo
LabelToPythonBinary map[string]string
LabelToApexInfo map[string]cquery.ApexCqueryInfo
+ LabelToCcBinary map[string]cquery.CcUnstrippedInfo
}
func (m MockBazelContext) QueueBazelRequest(_ string, _ cqueryRequest, _ configKey) {
@@ -249,6 +253,11 @@
panic("unimplemented")
}
+func (m MockBazelContext) GetCcUnstrippedInfo(label string, _ configKey) (cquery.CcUnstrippedInfo, error) {
+ result, _ := m.LabelToCcBinary[label]
+ return result, nil
+}
+
func (m MockBazelContext) InvokeBazel(_ Config) error {
panic("unimplemented")
}
@@ -312,6 +321,14 @@
return cquery.ApexCqueryInfo{}, fmt.Errorf("no bazel response found for %v", key)
}
+func (bazelCtx *bazelContext) GetCcUnstrippedInfo(label string, cfgKey configKey) (cquery.CcUnstrippedInfo, error) {
+ key := makeCqueryKey(label, cquery.GetCcUnstrippedInfo, cfgKey)
+ if rawString, ok := bazelCtx.results[key]; ok {
+ return cquery.GetCcUnstrippedInfo.ParseResult(strings.TrimSpace(rawString)), nil
+ }
+ return cquery.CcUnstrippedInfo{}, fmt.Errorf("no bazel response for %s", key)
+}
+
func (n noopBazelContext) QueueBazelRequest(_ string, _ cqueryRequest, _ configKey) {
panic("unimplemented")
}
@@ -332,6 +349,11 @@
panic("unimplemented")
}
+func (n noopBazelContext) GetCcUnstrippedInfo(_ string, _ configKey) (cquery.CcUnstrippedInfo, error) {
+ //TODO implement me
+ panic("implement me")
+}
+
func (n noopBazelContext) InvokeBazel(_ Config) error {
panic("unimplemented")
}
diff --git a/apex/apex.go b/apex/apex.go
index 4247db4..6afbd4a 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -2740,11 +2740,6 @@
return ""
}
- archMinApiLevel := cc.MinApiForArch(ctx, a.MultiTargets()[0].Arch.ArchType)
- if !archMinApiLevel.IsNone() && archMinApiLevel.CompareTo(minApiLevel) > 0 {
- minApiLevel = archMinApiLevel
- }
-
overrideMinSdkValue := ctx.DeviceConfig().ApexGlobalMinSdkVersionOverride()
overrideApiLevel := minSdkVersionFromValue(ctx, overrideMinSdkValue)
if !overrideApiLevel.IsNone() && overrideApiLevel.CompareTo(minApiLevel) > 0 {
diff --git a/apex/apex_test.go b/apex/apex_test.go
index e130fcc..647a575 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -2191,6 +2191,38 @@
`)
}
+func TestApexMinSdkVersion_MinApiForArch(t *testing.T) {
+ // Tests that an apex dependency with min_sdk_version higher than the
+ // min_sdk_version of the apex is allowed as long as the dependency's
+ // min_sdk_version is less than or equal to the api level that the
+ // architecture was introduced in. In this case, arm64 didn't exist
+ // until api level 21, so the arm64 code will never need to run on
+ // an api level 20 device, even if other architectures of the apex
+ // will.
+ testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ native_shared_libs: ["libfoo"],
+ min_sdk_version: "20",
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ cc_library {
+ name: "libfoo",
+ srcs: ["mylib.cpp"],
+ apex_available: ["myapex"],
+ min_sdk_version: "21",
+ stl: "none",
+ }
+ `)
+}
+
func TestJavaStableSdkVersion(t *testing.T) {
testCases := []struct {
name string
diff --git a/bazel/cquery/request_type.go b/bazel/cquery/request_type.go
index e35b531..fcc2f07 100644
--- a/bazel/cquery/request_type.go
+++ b/bazel/cquery/request_type.go
@@ -7,10 +7,11 @@
)
var (
- GetOutputFiles = &getOutputFilesRequestType{}
- GetPythonBinary = &getPythonBinaryRequestType{}
- GetCcInfo = &getCcInfoType{}
- GetApexInfo = &getApexInfoType{}
+ GetOutputFiles = &getOutputFilesRequestType{}
+ GetPythonBinary = &getPythonBinaryRequestType{}
+ GetCcInfo = &getCcInfoType{}
+ GetApexInfo = &getApexInfoType{}
+ GetCcUnstrippedInfo = &getCcUnstippedInfoType{}
)
type CcInfo struct {
@@ -30,6 +31,7 @@
// but general cc_library will also have dynamic libraries in output files).
RootDynamicLibraries []string
TocFile string
+ UnstrippedOutput string
}
type getOutputFilesRequestType struct{}
@@ -135,12 +137,17 @@
rootSharedLibraries = []
shared_info_tag = "//build/bazel/rules/cc:cc_library_shared.bzl%CcSharedLibraryOutputInfo"
+unstripped_tag = "//build/bazel/rules/cc:stripped_cc_common.bzl%CcUnstrippedInfo"
+unstripped = ""
if shared_info_tag in providers(target):
shared_info = providers(target)[shared_info_tag]
path = shared_info.output_file.path
sharedLibraries.append(path)
rootSharedLibraries += [path]
+ unstripped = path
+ if unstripped_tag in providers(target):
+ unstripped = providers(target)[unstripped_tag].unstripped.path
else:
for linker_input in linker_inputs:
for library in linker_input.libraries:
@@ -168,7 +175,8 @@
"Headers": headers,
"RootStaticArchives": rootStaticArchives,
"RootDynamicLibraries": rootSharedLibraries,
- "TocFile": toc_file
+ "TocFile": toc_file,
+ "UnstrippedOutput": unstripped,
})`
}
@@ -237,6 +245,47 @@
return info
}
+// getCcUnstrippedInfoType implements cqueryRequest interface. It handles the
+// interaction with `bazel cquery` to retrieve CcUnstrippedInfo provided
+// by the` cc_binary` and `cc_shared_library` rules.
+type getCcUnstippedInfoType struct{}
+
+func (g getCcUnstippedInfoType) Name() string {
+ return "getCcUnstrippedInfo"
+}
+
+func (g getCcUnstippedInfoType) StarlarkFunctionBody() string {
+ return `unstripped_tag = "//build/bazel/rules/cc:stripped_cc_common.bzl%CcUnstrippedInfo"
+p = providers(target)
+output_path = target.files.to_list()[0].path
+unstripped = output_path
+if unstripped_tag in p:
+ unstripped = p[unstripped_tag].unstripped.files.to_list()[0].path
+return json_encode({
+ "OutputFile": output_path,
+ "UnstrippedOutput": unstripped,
+})
+`
+}
+
+// ParseResult returns a value obtained by parsing the result of the request's Starlark function.
+// The given rawString must correspond to the string output which was created by evaluating the
+// Starlark given in StarlarkFunctionBody.
+func (g getCcUnstippedInfoType) ParseResult(rawString string) CcUnstrippedInfo {
+ var info CcUnstrippedInfo
+ decoder := json.NewDecoder(strings.NewReader(rawString))
+ decoder.DisallowUnknownFields() //useful to detect typos, e.g. in unit tests
+ if err := decoder.Decode(&info); err != nil {
+ panic(fmt.Errorf("cannot parse cquery result '%s': %s", rawString, err))
+ }
+ return info
+}
+
+type CcUnstrippedInfo struct {
+ OutputFile string
+ UnstrippedOutput string
+}
+
// splitOrEmpty is a modification of strings.Split() that returns an empty list
// if the given string is empty.
func splitOrEmpty(s string, sep string) []string {
diff --git a/bazel/cquery/request_type_test.go b/bazel/cquery/request_type_test.go
index afe478b..0f51cc0 100644
--- a/bazel/cquery/request_type_test.go
+++ b/bazel/cquery/request_type_test.go
@@ -165,3 +165,31 @@
}
}
}
+
+func TestGetCcUnstrippedParseResults(t *testing.T) {
+ testCases := []struct {
+ description string
+ input string
+ expectedOutput CcUnstrippedInfo
+ }{
+ {
+ description: "no result",
+ input: "{}",
+ expectedOutput: CcUnstrippedInfo{},
+ },
+ {
+ description: "one result",
+ input: `{"OutputFile":"myapp", "UnstrippedOutput":"myapp_unstripped"}`,
+ expectedOutput: CcUnstrippedInfo{
+ OutputFile: "myapp",
+ UnstrippedOutput: "myapp_unstripped",
+ },
+ },
+ }
+ for _, tc := range testCases {
+ actualOutput := GetCcUnstrippedInfo.ParseResult(tc.input)
+ if !reflect.DeepEqual(tc.expectedOutput, actualOutput) {
+ t.Errorf("%q: expected %#v != actual %#v", tc.description, tc.expectedOutput, actualOutput)
+ }
+ }
+}
diff --git a/cc/api_level.go b/cc/api_level.go
index 8f9e1f6..fdff5cb 100644
--- a/cc/api_level.go
+++ b/cc/api_level.go
@@ -20,7 +20,7 @@
"android/soong/android"
)
-func MinApiForArch(ctx android.EarlyModuleContext,
+func minApiForArch(ctx android.EarlyModuleContext,
arch android.ArchType) android.ApiLevel {
switch arch {
@@ -38,7 +38,7 @@
func nativeApiLevelFromUser(ctx android.BaseModuleContext,
raw string) (android.ApiLevel, error) {
- min := MinApiForArch(ctx, ctx.Arch().ArchType)
+ min := minApiForArch(ctx, ctx.Arch().ArchType)
if raw == "minimum" {
return min, nil
}
diff --git a/cc/binary.go b/cc/binary.go
index 69cf4ac..a6d7507 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -577,25 +577,20 @@
func (handler *ccBinaryBazelHandler) QueueBazelCall(ctx android.BaseModuleContext, label string) {
bazelCtx := ctx.Config().BazelContext
- bazelCtx.QueueBazelRequest(label, cquery.GetOutputFiles, android.GetConfigKey(ctx))
+ bazelCtx.QueueBazelRequest(label, cquery.GetCcUnstrippedInfo, android.GetConfigKey(ctx))
}
func (handler *ccBinaryBazelHandler) ProcessBazelQueryResponse(ctx android.ModuleContext, label string) {
bazelCtx := ctx.Config().BazelContext
- filePaths, err := bazelCtx.GetOutputFiles(label, android.GetConfigKey(ctx))
+ info, err := bazelCtx.GetCcUnstrippedInfo(label, android.GetConfigKey(ctx))
if err != nil {
ctx.ModuleErrorf(err.Error())
return
}
- if len(filePaths) != 1 {
- ctx.ModuleErrorf("expected exactly one output file for '%s', but got %s", label, filePaths)
- return
- }
- outputFilePath := android.PathForBazelOut(ctx, filePaths[0])
+ outputFilePath := android.PathForBazelOut(ctx, info.OutputFile)
handler.module.outputFile = android.OptionalPathForPath(outputFilePath)
- // TODO(b/220164721): We need to decide if we should return the stripped as the unstripped.
- handler.module.linker.(*binaryDecorator).unstrippedOutputFile = outputFilePath
+ handler.module.linker.(*binaryDecorator).unstrippedOutputFile = android.PathForBazelOut(ctx, info.UnstrippedOutput)
}
func binaryBp2buildAttrs(ctx android.TopDownMutatorContext, m *Module) binaryAttributes {
diff --git a/cc/binary_test.go b/cc/binary_test.go
index cba5974..db6fb3a 100644
--- a/cc/binary_test.go
+++ b/cc/binary_test.go
@@ -15,6 +15,7 @@
package cc
import (
+ "android/soong/bazel/cquery"
"testing"
"android/soong/android"
@@ -30,8 +31,11 @@
config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.BazelContext = android.MockBazelContext{
OutputBaseDir: "outputbase",
- LabelToOutputFiles: map[string][]string{
- "//foo/bar:bar": []string{"foo"},
+ LabelToCcBinary: map[string]cquery.CcUnstrippedInfo{
+ "//foo/bar:bar": cquery.CcUnstrippedInfo{
+ OutputFile: "foo",
+ UnstrippedOutput: "foo.unstripped",
+ },
},
}
ctx := testCcWithConfig(t, config)
@@ -46,7 +50,7 @@
android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings())
unStrippedFilePath := binMod.(*Module).UnstrippedOutputFile()
- expectedUnStrippedFile := "outputbase/execroot/__main__/foo"
+ expectedUnStrippedFile := "outputbase/execroot/__main__/foo.unstripped"
android.AssertStringEquals(t, "Unstripped output file", expectedUnStrippedFile, unStrippedFilePath.String())
}
diff --git a/cc/cc.go b/cc/cc.go
index d0362fc..eb7c639 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -3626,6 +3626,16 @@
return err
}
+ // A dependency only needs to support a min_sdk_version at least
+ // as high as the api level that the architecture was introduced in.
+ // This allows introducing new architectures in the platform that
+ // need to be included in apexes that normally require an older
+ // min_sdk_version.
+ minApiForArch := minApiForArch(ctx, c.Target().Arch.ArchType)
+ if sdkVersion.LessThan(minApiForArch) {
+ sdkVersion = minApiForArch
+ }
+
if ver.GreaterThan(sdkVersion) {
return fmt.Errorf("newer SDK(%v)", ver)
}
diff --git a/cc/library.go b/cc/library.go
index 77f686e..a590b22 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -885,7 +885,7 @@
outputFilePath := android.PathForBazelOut(ctx, rootDynamicLibraries[0])
handler.module.outputFile = android.OptionalPathForPath(outputFilePath)
- handler.module.linker.(*libraryDecorator).unstrippedOutputFile = outputFilePath
+ handler.module.linker.(*libraryDecorator).unstrippedOutputFile = android.PathForBazelOut(ctx, ccInfo.UnstrippedOutput)
var tocFile android.OptionalPath
if len(ccInfo.TocFile) > 0 {
diff --git a/cc/library_test.go b/cc/library_test.go
index 6d5eda2..2bc9967 100644
--- a/cc/library_test.go
+++ b/cc/library_test.go
@@ -259,6 +259,7 @@
SystemIncludes: []string{"system_include"},
Headers: []string{"foo.h"},
RootDynamicLibraries: []string{"foo.so"},
+ UnstrippedOutput: "foo_unstripped.so",
},
"//foo/bar:bar_bp2build_cc_library_static": cquery.CcInfo{
CcObjectFiles: []string{"foo.o"},
@@ -294,6 +295,7 @@
expectedOutputFiles = []string{"outputbase/execroot/__main__/foo.so"}
android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings())
+ android.AssertStringEquals(t, "unstripped shared library", "outputbase/execroot/__main__/foo_unstripped.so", sharedFoo.(*Module).linker.unstrippedOutputFilePath().String())
flagExporter = ctx.ModuleProvider(sharedFoo, FlagExporterInfoProvider).(FlagExporterInfo)
android.AssertPathsRelativeToTopEquals(t, "exported include dirs", []string{"outputbase/execroot/__main__/include"}, flagExporter.IncludeDirs)
android.AssertPathsRelativeToTopEquals(t, "exported system include dirs", []string{"outputbase/execroot/__main__/system_include"}, flagExporter.SystemIncludeDirs)