summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--OWNERS1
-rw-r--r--android/Android.bp1
-rw-r--r--android/arch.go8
-rw-r--r--android/arch_test.go85
-rw-r--r--android/config.go20
-rw-r--r--android/makevars.go124
-rw-r--r--android/module.go84
-rw-r--r--android/neverallow.go18
-rw-r--r--android/neverallow_test.go20
-rw-r--r--android/override_module.go16
-rw-r--r--android/paths.go4
-rw-r--r--android/phony.go75
-rw-r--r--android/prebuilt_test.go70
-rw-r--r--android/register.go3
-rw-r--r--android/singleton.go10
-rw-r--r--android/variable.go6
-rw-r--r--android/writedocs.go6
-rw-r--r--apex/androidmk.go10
-rw-r--r--apex/apex.go48
-rw-r--r--apex/apex_test.go24
-rw-r--r--apex/builder.go16
-rw-r--r--cc/androidmk.go3
-rw-r--r--cc/cc.go18
-rw-r--r--cc/compiler.go2
-rw-r--r--cc/config/global.go4
-rw-r--r--cc/linker.go7
-rw-r--r--cc/ndk_library.go40
-rw-r--r--cc/scriptlib/Android.bp32
-rw-r--r--cc/scriptlib/__init__.py0
-rwxr-xr-xcc/scriptlib/gen_stub_libs.py (renamed from cc/gen_stub_libs.py)1
-rwxr-xr-xcc/scriptlib/ndk_api_coverage_parser.py134
-rwxr-xr-xcc/scriptlib/test_gen_stub_libs.py (renamed from cc/test_gen_stub_libs.py)0
-rw-r--r--cc/scriptlib/test_ndk_api_coverage_parser.py66
-rw-r--r--cc/sdk.go1
-rw-r--r--cc/testing.go24
-rw-r--r--java/aar.go4
-rwxr-xr-xjava/app.go28
-rw-r--r--java/app_test.go9
-rw-r--r--java/device_host_converter.go8
-rw-r--r--java/dexpreopt.go4
-rw-r--r--java/dexpreopt_bootjars.go20
-rw-r--r--java/dexpreopt_bootjars_test.go2
-rw-r--r--java/droiddoc.go2
-rw-r--r--java/java.go21
-rw-r--r--java/java_test.go46
-rw-r--r--java/testing.go62
-rw-r--r--python/androidmk.go12
-rw-r--r--python/test.go4
-rw-r--r--rust/Android.bp2
-rw-r--r--rust/OWNERS4
-rw-r--r--rust/config/Android.bp2
-rw-r--r--rust/config/allowed_list.go (renamed from rust/config/whitelist.go)0
-rw-r--r--rust/library.go11
-rw-r--r--rust/library_test.go14
-rw-r--r--rust/project_json.go161
-rw-r--r--rust/project_json_test.go55
-rw-r--r--rust/test.go4
-rw-r--r--rust/testing.go1
-rwxr-xr-xscripts/build-mainline-modules.sh1
-rw-r--r--sdk/update.go5
-rw-r--r--sh/sh_binary.go13
-rw-r--r--ui/build/config.go1
-rw-r--r--ui/build/dumpvars.go2
63 files changed, 1132 insertions, 347 deletions
diff --git a/OWNERS b/OWNERS
index adf2b4c37..dbb491d8b 100644
--- a/OWNERS
+++ b/OWNERS
@@ -11,3 +11,4 @@ per-file clang.go,global.go = srhines@google.com, chh@google.com, pirama@google.
per-file tidy.go = srhines@google.com, chh@google.com
per-file lto.go,pgo.go = srhines@google.com, pirama@google.com, yikong@google.com
per-file docs/map_files.md = danalbert@google.com, enh@google.com, jiyong@google.com
+per-file *ndk_api_coverage_parser.py = sophiez@google.com \ No newline at end of file
diff --git a/android/Android.bp b/android/Android.bp
index 47dbc5d5f..487372bd8 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -36,6 +36,7 @@ bootstrap_go_package {
"package_ctx.go",
"path_properties.go",
"paths.go",
+ "phony.go",
"prebuilt.go",
"proto.go",
"register.go",
diff --git a/android/arch.go b/android/arch.go
index 08c0256b7..9a5461474 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -810,7 +810,7 @@ func GetOsSpecificVariantsOfCommonOSVariant(mctx BaseModuleContext) []Module {
// Valid multilib values include:
// "both": compile for all Targets supported by the OsClass (generally x86_64 and x86, or arm64 and arm).
// "first": compile for only a single preferred Target supported by the OsClass. This is generally x86_64 or arm64,
-// but may be arm for a 32-bit only build or a build with TARGET_PREFER_32_BIT=true set.
+// but may be arm for a 32-bit only build.
// "32": compile for only a single 32-bit Target supported by the OsClass.
// "64": compile for only a single 64-bit Target supported by the OsClass.
// "common": compile a for a single Target that will work on all Targets suported by the OsClass (for example Java).
@@ -1026,6 +1026,7 @@ func createArchPropTypeDesc(props reflect.Type) []archPropTypeDesc {
"Not_windows",
"Arm_on_x86",
"Arm_on_x86_64",
+ "Native_bridge",
}
for _, os := range OsTypeList {
targets = append(targets, os.Field)
@@ -1413,6 +1414,11 @@ func (m *ModuleBase) setArchProperties(ctx BottomUpMutatorContext) {
prefix := "target.arm_on_x86_64"
m.appendProperties(ctx, genProps, targetProp, field, prefix)
}
+ if os == Android && m.Target().NativeBridge == NativeBridgeEnabled {
+ field := "Native_bridge"
+ prefix := "target.native_bridge"
+ m.appendProperties(ctx, genProps, targetProp, field, prefix)
+ }
}
}
}
diff --git a/android/arch_test.go b/android/arch_test.go
index b987d5697..8525b0349 100644
--- a/android/arch_test.go
+++ b/android/arch_test.go
@@ -383,3 +383,88 @@ func TestArchMutator(t *testing.T) {
})
}
}
+
+func TestArchMutatorNativeBridge(t *testing.T) {
+ bp := `
+ // This module is only enabled for x86.
+ module {
+ name: "foo",
+ }
+
+ // This module is enabled for x86 and arm (via native bridge).
+ module {
+ name: "bar",
+ native_bridge_supported: true,
+ }
+
+ // This module is enabled for arm (native_bridge) only.
+ module {
+ name: "baz",
+ native_bridge_supported: true,
+ enabled: false,
+ target: {
+ native_bridge: {
+ enabled: true,
+ }
+ }
+ }
+ `
+
+ testCases := []struct {
+ name string
+ config func(Config)
+ fooVariants []string
+ barVariants []string
+ bazVariants []string
+ }{
+ {
+ name: "normal",
+ config: nil,
+ fooVariants: []string{"android_x86_64_silvermont", "android_x86_silvermont"},
+ barVariants: []string{"android_x86_64_silvermont", "android_native_bridge_arm64_armv8-a", "android_x86_silvermont", "android_native_bridge_arm_armv7-a-neon"},
+ bazVariants: []string{"android_native_bridge_arm64_armv8-a", "android_native_bridge_arm_armv7-a-neon"},
+ },
+ }
+
+ enabledVariants := func(ctx *TestContext, name string) []string {
+ var ret []string
+ variants := ctx.ModuleVariantsForTests(name)
+ for _, variant := range variants {
+ m := ctx.ModuleForTests(name, variant)
+ if m.Module().Enabled() {
+ ret = append(ret, variant)
+ }
+ }
+ return ret
+ }
+
+ for _, tt := range testCases {
+ t.Run(tt.name, func(t *testing.T) {
+ config := TestArchConfigNativeBridge(buildDir, nil, bp, nil)
+
+ ctx := NewTestArchContext()
+ ctx.RegisterModuleType("module", archTestModuleFactory)
+ ctx.Register(config)
+ if tt.config != nil {
+ tt.config(config)
+ }
+
+ _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
+ FailIfErrored(t, errs)
+ _, errs = ctx.PrepareBuildActions(config)
+ FailIfErrored(t, errs)
+
+ if g, w := enabledVariants(ctx, "foo"), tt.fooVariants; !reflect.DeepEqual(w, g) {
+ t.Errorf("want foo variants:\n%q\ngot:\n%q\n", w, g)
+ }
+
+ if g, w := enabledVariants(ctx, "bar"), tt.barVariants; !reflect.DeepEqual(w, g) {
+ t.Errorf("want bar variants:\n%q\ngot:\n%q\n", w, g)
+ }
+
+ if g, w := enabledVariants(ctx, "baz"), tt.bazVariants; !reflect.DeepEqual(w, g) {
+ t.Errorf("want qux variants:\n%q\ngot:\n%q\n", w, g)
+ }
+ })
+ }
+}
diff --git a/android/config.go b/android/config.go
index 59118ce86..0fe4a0c68 100644
--- a/android/config.go
+++ b/android/config.go
@@ -111,6 +111,10 @@ type config struct {
fs pathtools.FileSystem
mockBpList string
+ // If testAllowNonExistentPaths is true then PathForSource and PathForModuleSrc won't error
+ // in tests when a path doesn't exist.
+ testAllowNonExistentPaths bool
+
OncePer
}
@@ -230,6 +234,10 @@ func TestConfig(buildDir string, env map[string]string, bp string, fs map[string
buildDir: buildDir,
captureBuild: true,
env: envCopy,
+
+ // Set testAllowNonExistentPaths so that test contexts don't need to specify every path
+ // passed to PathForSource or PathForModuleSrc.
+ testAllowNonExistentPaths: true,
}
config.deviceConfig = &deviceConfig{
config: config,
@@ -732,14 +740,6 @@ func (c *config) Eng() bool {
return Bool(c.productVariables.Eng)
}
-func (c *config) DevicePrefer32BitApps() bool {
- return Bool(c.productVariables.DevicePrefer32BitApps)
-}
-
-func (c *config) DevicePrefer32BitExecutables() bool {
- return Bool(c.productVariables.DevicePrefer32BitExecutables)
-}
-
func (c *config) DevicePrimaryArchType() ArchType {
return c.Targets[Android][0].Arch.ArchType
}
@@ -1163,8 +1163,8 @@ func (c *config) EnforceSystemCertificate() bool {
return Bool(c.productVariables.EnforceSystemCertificate)
}
-func (c *config) EnforceSystemCertificateWhitelist() []string {
- return c.productVariables.EnforceSystemCertificateWhitelist
+func (c *config) EnforceSystemCertificateAllowList() []string {
+ return c.productVariables.EnforceSystemCertificateAllowList
}
func (c *config) EnforceProductPartitionInterface() bool {
diff --git a/android/makevars.go b/android/makevars.go
index aba4ccec3..ff7c8e4a7 100644
--- a/android/makevars.go
+++ b/android/makevars.go
@@ -17,12 +17,11 @@ package android
import (
"bytes"
"fmt"
- "io/ioutil"
- "os"
"strconv"
"strings"
"github.com/google/blueprint"
+ "github.com/google/blueprint/pathtools"
"github.com/google/blueprint/proptools"
)
@@ -84,6 +83,29 @@ type MakeVarsContext interface {
// builder whenever a file matching the pattern as added or removed, without rerunning if a
// file that does not match the pattern is added to a searched directory.
GlobWithDeps(pattern string, excludes []string) ([]string, error)
+
+ // Phony creates a phony rule in Make, which will allow additional DistForGoal
+ // dependencies to be added to it. Phony can be called on the same name multiple
+ // times to add additional dependencies.
+ Phony(names string, deps ...Path)
+
+ // DistForGoal creates a rule to copy one or more Paths to the artifacts
+ // directory on the build server when the specified goal is built.
+ DistForGoal(goal string, paths ...Path)
+
+ // DistForGoalWithFilename creates a rule to copy a Path to the artifacts
+ // directory on the build server with the given filename when the specified
+ // goal is built.
+ DistForGoalWithFilename(goal string, path Path, filename string)
+
+ // DistForGoals creates a rule to copy one or more Paths to the artifacts
+ // directory on the build server when any of the specified goals are built.
+ DistForGoals(goals []string, paths ...Path)
+
+ // DistForGoalsWithFilename creates a rule to copy a Path to the artifacts
+ // directory on the build server with the given filename when any of the
+ // specified goals are built.
+ DistForGoalsWithFilename(goals []string, path Path, filename string)
}
var _ PathContext = MakeVarsContext(nil)
@@ -130,9 +152,11 @@ var makeVarsProviders []makeVarsProvider
type makeVarsContext struct {
SingletonContext
- config Config
- pctx PackageContext
- vars []makeVarsVariable
+ config Config
+ pctx PackageContext
+ vars []makeVarsVariable
+ phonies []phony
+ dists []dist
}
var _ MakeVarsContext = &makeVarsContext{}
@@ -144,6 +168,16 @@ type makeVarsVariable struct {
strict bool
}
+type phony struct {
+ name string
+ deps []string
+}
+
+type dist struct {
+ goals []string
+ paths []string
+}
+
func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) {
if !ctx.Config().EmbeddedInMake() {
return
@@ -152,11 +186,16 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) {
outFile := absolutePath(PathForOutput(ctx,
"make_vars"+proptools.String(ctx.Config().productVariables.Make_suffix)+".mk").String())
+ lateOutFile := absolutePath(PathForOutput(ctx,
+ "late"+proptools.String(ctx.Config().productVariables.Make_suffix)+".mk").String())
+
if ctx.Failed() {
return
}
- vars := []makeVarsVariable{}
+ var vars []makeVarsVariable
+ var dists []dist
+ var phonies []phony
for _, provider := range makeVarsProviders {
mctx := &makeVarsContext{
SingletonContext: ctx,
@@ -166,6 +205,8 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) {
provider.call(mctx)
vars = append(vars, mctx.vars...)
+ phonies = append(phonies, mctx.phonies...)
+ dists = append(dists, mctx.dists...)
}
if ctx.Failed() {
@@ -174,17 +215,16 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) {
outBytes := s.writeVars(vars)
- if _, err := os.Stat(absolutePath(outFile)); err == nil {
- if data, err := ioutil.ReadFile(absolutePath(outFile)); err == nil {
- if bytes.Equal(data, outBytes) {
- return
- }
- }
+ if err := pathtools.WriteFileIfChanged(outFile, outBytes, 0666); err != nil {
+ ctx.Errorf(err.Error())
}
- if err := ioutil.WriteFile(absolutePath(outFile), outBytes, 0666); err != nil {
+ lateOutBytes := s.writeLate(phonies, dists)
+
+ if err := pathtools.WriteFileIfChanged(lateOutFile, lateOutBytes, 0666); err != nil {
ctx.Errorf(err.Error())
}
+
}
func (s *makeVarsSingleton) writeVars(vars []makeVarsVariable) []byte {
@@ -263,6 +303,33 @@ my_check_failed :=
fmt.Fprintln(buf, "\nsoong-compare-var :=")
+ fmt.Fprintln(buf)
+
+ return buf.Bytes()
+}
+
+func (s *makeVarsSingleton) writeLate(phonies []phony, dists []dist) []byte {
+ buf := &bytes.Buffer{}
+
+ fmt.Fprint(buf, `# Autogenerated file
+
+# Values written by Soong read after parsing all Android.mk files.
+
+
+`)
+
+ for _, phony := range phonies {
+ fmt.Fprintf(buf, ".PHONY: %s\n", phony.name)
+ fmt.Fprintf(buf, "%s: %s\n", phony.name, strings.Join(phony.deps, "\\\n "))
+ }
+
+ fmt.Fprintln(buf)
+
+ for _, dist := range dists {
+ fmt.Fprintf(buf, "$(call dist-for-goals,%s,%s)\n",
+ strings.Join(dist.goals, " "), strings.Join(dist.paths, " "))
+ }
+
return buf.Bytes()
}
@@ -299,6 +366,17 @@ func (c *makeVarsContext) addVariable(name, ninjaStr string, strict, sort bool)
c.addVariableRaw(name, value, strict, sort)
}
+func (c *makeVarsContext) addPhony(name string, deps []string) {
+ c.phonies = append(c.phonies, phony{name, deps})
+}
+
+func (c *makeVarsContext) addDist(goals []string, paths []string) {
+ c.dists = append(c.dists, dist{
+ goals: goals,
+ paths: paths,
+ })
+}
+
func (c *makeVarsContext) Strict(name, ninjaStr string) {
c.addVariable(name, ninjaStr, true, false)
}
@@ -318,3 +396,23 @@ func (c *makeVarsContext) CheckSorted(name, ninjaStr string) {
func (c *makeVarsContext) CheckRaw(name, value string) {
c.addVariableRaw(name, value, false, false)
}
+
+func (c *makeVarsContext) Phony(name string, deps ...Path) {
+ c.addPhony(name, Paths(deps).Strings())
+}
+
+func (c *makeVarsContext) DistForGoal(goal string, paths ...Path) {
+ c.DistForGoals([]string{goal}, paths...)
+}
+
+func (c *makeVarsContext) DistForGoalWithFilename(goal string, path Path, filename string) {
+ c.DistForGoalsWithFilename([]string{goal}, path, filename)
+}
+
+func (c *makeVarsContext) DistForGoals(goals []string, paths ...Path) {
+ c.addDist(goals, Paths(paths).Strings())
+}
+
+func (c *makeVarsContext) DistForGoalsWithFilename(goals []string, path Path, filename string) {
+ c.addDist(goals, []string{path.String() + ":" + filename})
+}
diff --git a/android/module.go b/android/module.go
index 82321f417..a488c0d77 100644
--- a/android/module.go
+++ b/android/module.go
@@ -207,6 +207,10 @@ type ModuleContext interface {
// Similar to blueprint.ModuleContext.Build, but takes Paths instead of []string,
// and performs more verification.
Build(pctx PackageContext, params BuildParams)
+ // Phony creates a Make-style phony rule, a rule with no commands that can depend on other
+ // phony rules or real files. Phony can be called on the same name multiple times to add
+ // additional dependencies.
+ Phony(phony string, deps ...Path)
PrimaryModule() Module
FinalModule() Module
@@ -722,6 +726,7 @@ type ModuleBase struct {
installFiles InstallPaths
checkbuildFiles Paths
noticeFiles Paths
+ phonies map[string]Paths
// Used by buildTargetSingleton to create checkbuild and per-directory build targets
// Only set on the final variant of each module
@@ -1093,26 +1098,17 @@ func (m *ModuleBase) generateModuleTarget(ctx ModuleContext) {
}
if len(allInstalledFiles) > 0 {
- name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-install")
- ctx.Build(pctx, BuildParams{
- Rule: blueprint.Phony,
- Output: name,
- Implicits: allInstalledFiles.Paths(),
- Default: !ctx.Config().EmbeddedInMake(),
- })
- deps = append(deps, name)
- m.installTarget = name
+ name := namespacePrefix + ctx.ModuleName() + "-install"
+ ctx.Phony(name, allInstalledFiles.Paths()...)
+ m.installTarget = PathForPhony(ctx, name)
+ deps = append(deps, m.installTarget)
}
if len(allCheckbuildFiles) > 0 {
- name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-checkbuild")
- ctx.Build(pctx, BuildParams{
- Rule: blueprint.Phony,
- Output: name,
- Implicits: allCheckbuildFiles,
- })
- deps = append(deps, name)
- m.checkbuildTarget = name
+ name := namespacePrefix + ctx.ModuleName() + "-checkbuild"
+ ctx.Phony(name, allCheckbuildFiles...)
+ m.checkbuildTarget = PathForPhony(ctx, name)
+ deps = append(deps, m.checkbuildTarget)
}
if len(deps) > 0 {
@@ -1121,12 +1117,7 @@ func (m *ModuleBase) generateModuleTarget(ctx ModuleContext) {
suffix = "-soong"
}
- name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+suffix)
- ctx.Build(pctx, BuildParams{
- Rule: blueprint.Phony,
- Outputs: []WritablePath{name},
- Implicits: deps,
- })
+ ctx.Phony(namespacePrefix+ctx.ModuleName()+suffix, deps...)
m.blueprintDir = ctx.ModuleDir()
}
@@ -1313,6 +1304,9 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext)
m.checkbuildFiles = append(m.checkbuildFiles, ctx.checkbuildFiles...)
m.initRcPaths = PathsForModuleSrc(ctx, m.commonProperties.Init_rc)
m.vintfFragmentsPaths = PathsForModuleSrc(ctx, m.commonProperties.Vintf_fragments)
+ for k, v := range ctx.phonies {
+ m.phonies[k] = append(m.phonies[k], v...)
+ }
} 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
@@ -1460,6 +1454,7 @@ type moduleContext struct {
installFiles InstallPaths
checkbuildFiles Paths
module Module
+ phonies map[string]Paths
// For tests
buildParams []BuildParams
@@ -1574,6 +1569,11 @@ func (m *moduleContext) Build(pctx PackageContext, params BuildParams) {
m.bp.Build(pctx.PackageContext, convertBuildParams(params))
}
+
+func (m *moduleContext) Phony(name string, deps ...Path) {
+ addPhony(m.config, name, deps...)
+}
+
func (m *moduleContext) GetMissingDependencies() []string {
var missingDeps []string
missingDeps = append(missingDeps, m.Module().base().commonProperties.MissingDeps...)
@@ -2233,9 +2233,8 @@ type buildTargetSingleton struct{}
func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
var checkbuildDeps Paths
- mmTarget := func(dir string) WritablePath {
- return PathForPhony(ctx,
- "MODULES-IN-"+strings.Replace(filepath.Clean(dir), "/", "-", -1))
+ mmTarget := func(dir string) string {
+ return "MODULES-IN-" + strings.Replace(filepath.Clean(dir), "/", "-", -1)
}
modulesInDir := make(map[string]Paths)
@@ -2261,11 +2260,7 @@ func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
}
// Create a top-level checkbuild target that depends on all modules
- ctx.Build(pctx, BuildParams{
- Rule: blueprint.Phony,
- Output: PathForPhony(ctx, "checkbuild"+suffix),
- Implicits: checkbuildDeps,
- })
+ ctx.Phony("checkbuild"+suffix, checkbuildDeps...)
// Make will generate the MODULES-IN-* targets
if ctx.Config().EmbeddedInMake() {
@@ -2289,7 +2284,7 @@ func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
for _, dir := range dirs {
p := parentDir(dir)
if p != "." && p != "/" {
- modulesInDir[p] = append(modulesInDir[p], mmTarget(dir))
+ modulesInDir[p] = append(modulesInDir[p], PathForPhony(ctx, mmTarget(dir)))
}
}
@@ -2297,14 +2292,7 @@ func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
// depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
// files.
for _, dir := range dirs {
- ctx.Build(pctx, BuildParams{
- Rule: blueprint.Phony,
- Output: mmTarget(dir),
- Implicits: modulesInDir[dir],
- // HACK: checkbuild should be an optional build, but force it
- // enabled for now in standalone builds
- Default: !ctx.Config().EmbeddedInMake(),
- })
+ ctx.Phony(mmTarget(dir), modulesInDir[dir]...)
}
// Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
@@ -2331,23 +2319,15 @@ func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
continue
}
- name := PathForPhony(ctx, className+"-"+os.Name)
- osClass[className] = append(osClass[className], name)
+ name := className + "-" + os.Name
+ osClass[className] = append(osClass[className], PathForPhony(ctx, name))
- ctx.Build(pctx, BuildParams{
- Rule: blueprint.Phony,
- Output: name,
- Implicits: deps,
- })
+ ctx.Phony(name, deps...)
}
// Wrap those into host|host-cross|target phony rules
for _, class := range SortedStringKeys(osClass) {
- ctx.Build(pctx, BuildParams{
- Rule: blueprint.Phony,
- Output: PathForPhony(ctx, class),
- Implicits: osClass[class],
- })
+ ctx.Phony(class, osClass[class]...)
}
}
diff --git a/android/neverallow.go b/android/neverallow.go
index be3f7123b..26e42e656 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -166,7 +166,7 @@ func createMediaRules() []Rule {
}
func createJavaDeviceForHostRules() []Rule {
- javaDeviceForHostProjectsWhitelist := []string{
+ javaDeviceForHostProjectsAllowedList := []string{
"external/guava",
"external/robolectric-shadows",
"framework/layoutlib",
@@ -174,14 +174,14 @@ func createJavaDeviceForHostRules() []Rule {
return []Rule{
NeverAllow().
- NotIn(javaDeviceForHostProjectsWhitelist...).
+ NotIn(javaDeviceForHostProjectsAllowedList...).
ModuleType("java_device_for_host", "java_host_for_device").
- Because("java_device_for_host can only be used in whitelisted projects"),
+ Because("java_device_for_host can only be used in allowed projects"),
}
}
func createCcSdkVariantRules() []Rule {
- sdkVersionOnlyWhitelist := []string{
+ sdkVersionOnlyAllowedList := []string{
// derive_sdk_prefer32 has stem: "derive_sdk" which conflicts with the derive_sdk.
// This sometimes works because the APEX modules that contain derive_sdk and
// derive_sdk_prefer32 suppress the platform installation rules, but fails when
@@ -193,7 +193,7 @@ func createCcSdkVariantRules() []Rule {
"tools/test/graphicsbenchmark/functional_tests/java",
}
- platformVariantPropertiesWhitelist := []string{
+ platformVariantPropertiesAllowedList := []string{
// android_native_app_glue and libRSSupport use native_window.h but target old
// sdk versions (minimum and 9 respectively) where libnativewindow didn't exist,
// so they can't add libnativewindow to shared_libs to get the header directory
@@ -205,13 +205,13 @@ func createCcSdkVariantRules() []Rule {
return []Rule{
NeverAllow().
- NotIn(sdkVersionOnlyWhitelist...).
+ NotIn(sdkVersionOnlyAllowedList...).
WithMatcher("sdk_variant_only", isSetMatcherInstance).
- Because("sdk_variant_only can only be used in whitelisted projects"),
+ Because("sdk_variant_only can only be used in allowed projects"),
NeverAllow().
- NotIn(platformVariantPropertiesWhitelist...).
+ NotIn(platformVariantPropertiesAllowedList...).
WithMatcher("platform.shared_libs", isSetMatcherInstance).
- Because("platform variant properties can only be used in whitelisted projects"),
+ Because("platform variant properties can only be used in allowed projects"),
}
}
diff --git a/android/neverallow_test.go b/android/neverallow_test.go
index 85c8c5908..45d36a69b 100644
--- a/android/neverallow_test.go
+++ b/android/neverallow_test.go
@@ -212,7 +212,7 @@ var neverallowTests = []struct {
}`),
},
expectedErrors: []string{
- "java_device_for_host can only be used in whitelisted projects",
+ "java_device_for_host can only be used in allowed projects",
},
},
// Libcore rule tests
@@ -261,46 +261,46 @@ var neverallowTests = []struct {
},
// CC sdk rule tests
{
- name: `"sdk_variant_only" outside whitelist`,
+ name: `"sdk_variant_only" outside allowed list`,
fs: map[string][]byte{
"Android.bp": []byte(`
cc_library {
- name: "outside_whitelist",
+ name: "outside_allowed_list",
sdk_version: "current",
sdk_variant_only: true,
}`),
},
expectedErrors: []string{
- `module "outside_whitelist": violates neverallow`,
+ `module "outside_allowed_list": violates neverallow`,
},
},
{
- name: `"sdk_variant_only: false" outside whitelist`,
+ name: `"sdk_variant_only: false" outside allowed list`,
fs: map[string][]byte{
"Android.bp": []byte(`
cc_library {
- name: "outside_whitelist",
+ name: "outside_allowed_list",
sdk_version: "current",
sdk_variant_only: false,
}`),
},
expectedErrors: []string{
- `module "outside_whitelist": violates neverallow`,
+ `module "outside_allowed_list": violates neverallow`,
},
},
{
- name: `"platform" outside whitelist`,
+ name: `"platform" outside allowed list`,
fs: map[string][]byte{
"Android.bp": []byte(`
cc_library {
- name: "outside_whitelist",
+ name: "outside_allowed_list",
platform: {
shared_libs: ["libfoo"],
},
}`),
},
expectedErrors: []string{
- `module "outside_whitelist": violates neverallow`,
+ `module "outside_allowed_list": violates neverallow`,
},
},
{
diff --git a/android/override_module.go b/android/override_module.go
index 9f5127dc3..7e58890d7 100644
--- a/android/override_module.go
+++ b/android/override_module.go
@@ -208,7 +208,21 @@ var overrideBaseDepTag overrideBaseDependencyTag
// next phase.
func overrideModuleDepsMutator(ctx BottomUpMutatorContext) {
if module, ok := ctx.Module().(OverrideModule); ok {
- ctx.AddDependency(ctx.Module(), overrideBaseDepTag, *module.getOverrideModuleProperties().Base)
+ // Skip this overriding module if there's a prebuilt module that overrides it with prefer flag.
+ overriddenByPrebuilt := false
+ ctx.VisitDirectDepsWithTag(PrebuiltDepTag, func(dep Module) {
+ prebuilt, ok := dep.(PrebuiltInterface)
+ if !ok {
+ panic("PrebuiltDepTag leads to a non-prebuilt module " + dep.Name())
+ }
+ if prebuilt.Prebuilt().UsePrebuilt() {
+ overriddenByPrebuilt = true
+ return
+ }
+ })
+ if !overriddenByPrebuilt {
+ ctx.AddDependency(ctx.Module(), overrideBaseDepTag, *module.getOverrideModuleProperties().Base)
+ }
}
}
diff --git a/android/paths.go b/android/paths.go
index 3ad27acbe..bed6f3f58 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -405,7 +405,7 @@ func expandOneSrcPath(ctx ModuleContext, s string, expandedExcludes []string) (P
p := pathForModuleSrc(ctx, s)
if exists, _, err := ctx.Config().fs.Exists(p.String()); err != nil {
reportPathErrorf(ctx, "%s: %s", p, err.Error())
- } else if !exists {
+ } else if !exists && !ctx.Config().testAllowNonExistentPaths {
reportPathErrorf(ctx, "module source path %q does not exist", p)
}
@@ -798,7 +798,7 @@ func PathForSource(ctx PathContext, pathComponents ...string) SourcePath {
}
} else if exists, _, err := ctx.Config().fs.Exists(path.String()); err != nil {
reportPathErrorf(ctx, "%s: %s", path, err.Error())
- } else if !exists {
+ } else if !exists && !ctx.Config().testAllowNonExistentPaths {
reportPathErrorf(ctx, "source path %q does not exist", path)
}
return path
diff --git a/android/phony.go b/android/phony.go
new file mode 100644
index 000000000..f8e5a4401
--- /dev/null
+++ b/android/phony.go
@@ -0,0 +1,75 @@
+// Copyright 2020 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package android
+
+import (
+ "sync"
+
+ "github.com/google/blueprint"
+)
+
+var phonyMapOnceKey = NewOnceKey("phony")
+
+type phonyMap map[string]Paths
+
+var phonyMapLock sync.Mutex
+
+func getPhonyMap(config Config) phonyMap {
+ return config.Once(phonyMapOnceKey, func() interface{} {
+ return make(phonyMap)
+ }).(phonyMap)
+}
+
+func addPhony(config Config, name string, deps ...Path) {
+ phonyMap := getPhonyMap(config)
+ phonyMapLock.Lock()
+ defer phonyMapLock.Unlock()
+ phonyMap[name] = append(phonyMap[name], deps...)
+}
+
+type phonySingleton struct {
+ phonyMap phonyMap
+ phonyList []string
+}
+
+var _ SingletonMakeVarsProvider = (*phonySingleton)(nil)
+
+func (p *phonySingleton) GenerateBuildActions(ctx SingletonContext) {
+ p.phonyMap = getPhonyMap(ctx.Config())
+ p.phonyList = SortedStringKeys(p.phonyMap)
+ for _, phony := range p.phonyList {
+ p.phonyMap[phony] = SortedUniquePaths(p.phonyMap[phony])
+ }
+
+ if !ctx.Config().EmbeddedInMake() {
+ for _, phony := range p.phonyList {
+ ctx.Build(pctx, BuildParams{
+ Rule: blueprint.Phony,
+ Outputs: []WritablePath{PathForPhony(ctx, phony)},
+ Implicits: p.phonyMap[phony],
+ })
+ }
+ }
+}
+
+func (p phonySingleton) MakeVars(ctx MakeVarsContext) {
+ for _, phony := range p.phonyList {
+ ctx.Phony(phony, p.phonyMap[phony]...)
+ }
+}
+
+func phonySingletonFactory() Singleton {
+ return &phonySingleton{}
+}
diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go
index b568f781d..8029b85bd 100644
--- a/android/prebuilt_test.go
+++ b/android/prebuilt_test.go
@@ -155,6 +155,44 @@ var prebuiltsTests = []struct {
}`,
prebuilt: []OsClass{Host},
},
+ {
+ name: "prebuilt override not preferred",
+ modules: `
+ source {
+ name: "baz",
+ }
+
+ override_source {
+ name: "bar",
+ base: "baz",
+ }
+
+ prebuilt {
+ name: "bar",
+ prefer: false,
+ srcs: ["prebuilt_file"],
+ }`,
+ prebuilt: nil,
+ },
+ {
+ name: "prebuilt override preferred",
+ modules: `
+ source {
+ name: "baz",
+ }
+
+ override_source {
+ name: "bar",
+ base: "baz",
+ }
+
+ prebuilt {
+ name: "bar",
+ prefer: true,
+ srcs: ["prebuilt_file"],
+ }`,
+ prebuilt: []OsClass{Device, Host},
+ },
}
func TestPrebuilts(t *testing.T) {
@@ -256,8 +294,10 @@ func TestPrebuilts(t *testing.T) {
func registerTestPrebuiltBuildComponents(ctx RegistrationContext) {
ctx.RegisterModuleType("prebuilt", newPrebuiltModule)
ctx.RegisterModuleType("source", newSourceModule)
+ ctx.RegisterModuleType("override_source", newOverrideSourceModule)
RegisterPrebuiltMutators(ctx)
+ ctx.PostDepsMutators(RegisterOverridePostDepsMutators)
}
type prebuiltModule struct {
@@ -300,11 +340,15 @@ func (p *prebuiltModule) OutputFiles(tag string) (Paths, error) {
}
}
+type sourceModuleProperties struct {
+ Deps []string `android:"path,arch_variant"`
+}
+
type sourceModule struct {
ModuleBase
- properties struct {
- Deps []string `android:"path,arch_variant"`
- }
+ OverridableModuleBase
+
+ properties sourceModuleProperties
dependsOnSourceModule, dependsOnPrebuiltModule bool
deps Paths
src Path
@@ -314,10 +358,11 @@ func newSourceModule() Module {
m := &sourceModule{}
m.AddProperties(&m.properties)
InitAndroidArchModule(m, HostAndDeviceDefault, MultilibCommon)
+ InitOverridableModule(m, nil)
return m
}
-func (s *sourceModule) DepsMutator(ctx BottomUpMutatorContext) {
+func (s *sourceModule) OverridablePropertiesDepsMutator(ctx BottomUpMutatorContext) {
// s.properties.Deps are annotated with android:path, so they are
// automatically added to the dependency by pathDeps mutator
}
@@ -330,3 +375,20 @@ func (s *sourceModule) GenerateAndroidBuildActions(ctx ModuleContext) {
func (s *sourceModule) Srcs() Paths {
return Paths{s.src}
}
+
+type overrideSourceModule struct {
+ ModuleBase
+ OverrideModuleBase
+}
+
+func (o *overrideSourceModule) GenerateAndroidBuildActions(_ ModuleContext) {
+}
+
+func newOverrideSourceModule() Module {
+ m := &overrideSourceModule{}
+ m.AddProperties(&sourceModuleProperties{})
+
+ InitAndroidArchModule(m, HostAndDeviceDefault, MultilibCommon)
+ InitOverrideModule(m)
+ return m
+}
diff --git a/android/register.go b/android/register.go
index ccfe01e74..036a8113f 100644
--- a/android/register.go
+++ b/android/register.go
@@ -104,6 +104,9 @@ func (ctx *Context) Register() {
registerMutators(ctx.Context, preArch, preDeps, postDeps, finalDeps)
+ // Register phony just before makevars so it can write out its phony rules as Make rules
+ ctx.RegisterSingletonType("phony", SingletonFactoryAdaptor(phonySingletonFactory))
+
// Register makevars after other singletons so they can export values through makevars
ctx.RegisterSingletonType("makevars", SingletonFactoryAdaptor(makeVarsSingletonFunc))
diff --git a/android/singleton.go b/android/singleton.go
index 568398cdd..2c51c6c48 100644
--- a/android/singleton.go
+++ b/android/singleton.go
@@ -36,6 +36,12 @@ type SingletonContext interface {
Variable(pctx PackageContext, name, value string)
Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule
Build(pctx PackageContext, params BuildParams)
+
+ // Phony creates a Make-style phony rule, a rule with no commands that can depend on other
+ // phony rules or real files. Phony can be called on the same name multiple times to add
+ // additional dependencies.
+ Phony(name string, deps ...Path)
+
RequireNinjaVersion(major, minor, micro int)
// SetNinjaBuildDir sets the value of the top-level "builddir" Ninja variable
@@ -156,6 +162,10 @@ func (s *singletonContextAdaptor) Build(pctx PackageContext, params BuildParams)
}
+func (s *singletonContextAdaptor) Phony(name string, deps ...Path) {
+ addPhony(s.Config(), name, deps...)
+}
+
func (s *singletonContextAdaptor) SetNinjaBuildDir(pctx PackageContext, value string) {
s.SingletonContext.SetNinjaBuildDir(pctx.PackageContext, value)
}
diff --git a/android/variable.go b/android/variable.go
index 3c08405dd..b69d4254d 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -272,10 +272,6 @@ type productVariables struct {
CoveragePaths []string `json:",omitempty"`
CoverageExcludePaths []string `json:",omitempty"`
- DevicePrefer32BitApps *bool `json:",omitempty"`
- DevicePrefer32BitExecutables *bool `json:",omitempty"`
- HostPrefer32BitExecutables *bool `json:",omitempty"`
-
SanitizeHost []string `json:",omitempty"`
SanitizeDevice []string `json:",omitempty"`
SanitizeDeviceDiag []string `json:",omitempty"`
@@ -323,7 +319,7 @@ type productVariables struct {
PackageNameOverrides []string `json:",omitempty"`
EnforceSystemCertificate *bool `json:",omitempty"`
- EnforceSystemCertificateWhitelist []string `json:",omitempty"`
+ EnforceSystemCertificateAllowList []string `json:",omitempty"`
ProductHiddenAPIStubs []string `json:",omitempty"`
ProductHiddenAPIStubsSystem []string `json:",omitempty"`
diff --git a/android/writedocs.go b/android/writedocs.go
index 7262ad810..9e43e80a6 100644
--- a/android/writedocs.go
+++ b/android/writedocs.go
@@ -69,9 +69,5 @@ func (c *docsSingleton) GenerateBuildActions(ctx SingletonContext) {
})
// Add a phony target for building the documentation
- ctx.Build(pctx, BuildParams{
- Rule: blueprint.Phony,
- Output: PathForPhony(ctx, "soong_docs"),
- Input: docsFile,
- })
+ ctx.Phony("soong_docs", docsFile)
}
diff --git a/apex/androidmk.go b/apex/androidmk.go
index 1b3a4ba10..774b62d99 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -180,13 +180,17 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, apexBundleName, apexName, mo
}
switch fi.class {
case javaSharedLib:
- javaModule := fi.module.(java.Dependency)
// soong_java_prebuilt.mk sets LOCAL_MODULE_SUFFIX := .jar Therefore
// we need to remove the suffix from LOCAL_MODULE_STEM, otherwise
// we will have foo.jar.jar
fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", strings.TrimSuffix(fi.Stem(), ".jar"))
- fmt.Fprintln(w, "LOCAL_SOONG_CLASSES_JAR :=", javaModule.ImplementationAndResourcesJars()[0].String())
- fmt.Fprintln(w, "LOCAL_SOONG_HEADER_JAR :=", javaModule.HeaderJars()[0].String())
+ if javaModule, ok := fi.module.(java.Dependency); ok {
+ fmt.Fprintln(w, "LOCAL_SOONG_CLASSES_JAR :=", javaModule.ImplementationAndResourcesJars()[0].String())
+ fmt.Fprintln(w, "LOCAL_SOONG_HEADER_JAR :=", javaModule.HeaderJars()[0].String())
+ } else {
+ fmt.Fprintln(w, "LOCAL_SOONG_CLASSES_JAR :=", fi.builtFile.String())
+ fmt.Fprintln(w, "LOCAL_SOONG_HEADER_JAR :=", fi.builtFile.String())
+ }
fmt.Fprintln(w, "LOCAL_SOONG_DEX_JAR :=", fi.builtFile.String())
fmt.Fprintln(w, "LOCAL_DEX_PREOPT := false")
fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_java_prebuilt.mk")
diff --git a/apex/apex.go b/apex/apex.go
index 2f7b2e535..3fef1ee41 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -64,13 +64,14 @@ var (
usesTag = dependencyTag{name: "uses"}
androidAppTag = dependencyTag{name: "androidApp", payload: true}
rroTag = dependencyTag{name: "rro", payload: true}
- apexAvailWl = makeApexAvailableWhitelist()
- inverseApexAvailWl = invertApexWhiteList(apexAvailWl)
+ apexAvailBaseline = makeApexAvailableBaseline()
+
+ inverseApexAvailBaseline = invertApexBaseline(apexAvailBaseline)
)
// Transform the map of apex -> modules to module -> apexes.
-func invertApexWhiteList(m map[string][]string) map[string][]string {
+func invertApexBaseline(m map[string][]string) map[string][]string {
r := make(map[string][]string)
for apex, modules := range m {
for _, module := range modules {
@@ -80,16 +81,16 @@ func invertApexWhiteList(m map[string][]string) map[string][]string {
return r
}
-// Retrieve the while list of apexes to which the supplied module belongs.
-func WhitelistedApexAvailable(moduleName string) []string {
- return inverseApexAvailWl[normalizeModuleName(moduleName)]
+// Retrieve the baseline of apexes to which the supplied module belongs.
+func BaselineApexAvailable(moduleName string) []string {
+ return inverseApexAvailBaseline[normalizeModuleName(moduleName)]
}
// This is a map from apex to modules, which overrides the
// apex_available setting for that particular module to make
// it available for the apex regardless of its setting.
// TODO(b/147364041): remove this
-func makeApexAvailableWhitelist() map[string][]string {
+func makeApexAvailableBaseline() map[string][]string {
// The "Module separator"s below are employed to minimize merge conflicts.
m := make(map[string][]string)
//
@@ -871,17 +872,17 @@ func apexUsesMutator(mctx android.BottomUpMutatorContext) {
}
var (
- useVendorWhitelistKey = android.NewOnceKey("useVendorWhitelist")
+ useVendorAllowListKey = android.NewOnceKey("useVendorAllowList")
)
-// useVendorWhitelist returns the list of APEXes which are allowed to use_vendor.
+// useVendorAllowList returns the list of APEXes which are allowed to use_vendor.
// When use_vendor is used, native modules are built with __ANDROID_VNDK__ and __ANDROID_APEX__,
// which may cause compatibility issues. (e.g. libbinder)
// Even though libbinder restricts its availability via 'apex_available' property and relies on
// yet another macro __ANDROID_APEX_<NAME>__, we restrict usage of "use_vendor:" from other APEX modules
// to avoid similar problems.
-func useVendorWhitelist(config android.Config) []string {
- return config.Once(useVendorWhitelistKey, func() interface{} {
+func useVendorAllowList(config android.Config) []string {
+ return config.Once(useVendorAllowListKey, func() interface{} {
return []string{
// swcodec uses "vendor" variants for smaller size
"com.android.media.swcodec",
@@ -890,11 +891,11 @@ func useVendorWhitelist(config android.Config) []string {
}).([]string)
}
-// setUseVendorWhitelistForTest overrides useVendorWhitelist and must be
-// called before the first call to useVendorWhitelist()
-func setUseVendorWhitelistForTest(config android.Config, whitelist []string) {
- config.Once(useVendorWhitelistKey, func() interface{} {
- return whitelist
+// setUseVendorAllowListForTest overrides useVendorAllowList and must be
+// called before the first call to useVendorAllowList()
+func setUseVendorAllowListForTest(config android.Config, allowList []string) {
+ config.Once(useVendorAllowListKey, func() interface{} {
+ return allowList
})
}
@@ -992,7 +993,7 @@ type apexBundleProperties struct {
// List of providing APEXes' names so that this APEX can depend on provided shared libraries.
Uses []string
- // A txt file containing list of files that are whitelisted to be included in this APEX.
+ // A txt file containing list of files that are allowed to be included in this APEX.
Whitelisted_files *string
// package format of this apex variant; could be non-flattened, flattened, or zip.
@@ -1332,7 +1333,7 @@ func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
}
func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
- if proptools.Bool(a.properties.Use_vendor) && !android.InList(a.Name(), useVendorWhitelist(ctx.Config())) {
+ if proptools.Bool(a.properties.Use_vendor) && !android.InList(a.Name(), useVendorAllowList(ctx.Config())) {
ctx.PropertyErrorf("use_vendor", "not allowed to set use_vendor: true")
}
@@ -1804,7 +1805,7 @@ func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
return false
}
- if to.AvailableFor(apexName) || whitelistedApexAvailable(apexName, toName) {
+ if to.AvailableFor(apexName) || baselineApexAvailable(apexName, toName) {
return true
}
ctx.ModuleErrorf("%q requires %q that is not available for the APEX. Dependency path:%s", fromName, toName, ctx.GetPathString(true))
@@ -2243,16 +2244,16 @@ func (a *apexBundle) checkJavaStableSdkVersion(ctx android.ModuleContext) {
})
}
-func whitelistedApexAvailable(apex, moduleName string) bool {
+func baselineApexAvailable(apex, moduleName string) bool {
key := apex
moduleName = normalizeModuleName(moduleName)
- if val, ok := apexAvailWl[key]; ok && android.InList(moduleName, val) {
+ if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
return true
}
key = android.AvailableToAnyApex
- if val, ok := apexAvailWl[key]; ok && android.InList(moduleName, val) {
+ if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
return true
}
@@ -2280,9 +2281,6 @@ func newApexBundle() *apexBundle {
module.AddProperties(&module.properties)
module.AddProperties(&module.targetProperties)
module.AddProperties(&module.overridableProperties)
- module.Prefer32(func(ctx android.BaseModuleContext, base *android.ModuleBase, class android.OsClass) bool {
- return class == android.Device && ctx.Config().DevicePrefer32BitExecutables()
- })
android.InitAndroidMultiTargetsArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
android.InitDefaultableModule(module)
android.InitSdkAwareModule(module)
diff --git a/apex/apex_test.go b/apex/apex_test.go
index d6a5d0909..609e6516b 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -329,7 +329,7 @@ func ensureListEmpty(t *testing.T, result []string) {
// Minimal test
func TestBasicApex(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx, config := testApex(t, `
apex_defaults {
name: "myapex-defaults",
manifest: ":myapex.manifest",
@@ -484,6 +484,16 @@ func TestBasicApex(t *testing.T) {
apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
+ // Make sure that Android.mk is created
+ ab := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
+ data := android.AndroidMkDataForTest(t, config, "", ab)
+ var builder strings.Builder
+ data.Custom(&builder, ab.BaseModuleName(), "TARGET_", "", data)
+
+ androidMk := builder.String()
+ ensureContains(t, androidMk, "LOCAL_MODULE := mylib.myapex\n")
+ ensureNotContains(t, androidMk, "LOCAL_MODULE := mylib.com.android.myapex\n")
+
optFlags := apexRule.Args["opt_flags"]
ensureContains(t, optFlags, "--pubkey vendor/foo/devkeys/testkey.avbpubkey")
// Ensure that the NOTICE output is being packaged as an asset.
@@ -1133,7 +1143,7 @@ func TestApexDependsOnLLNDKTransitively(t *testing.T) {
symbol_file: "",
}
`, func(fs map[string][]byte, config android.Config) {
- setUseVendorWhitelistForTest(config, []string{"myapex"})
+ setUseVendorAllowListForTest(config, []string{"myapex"})
}, withUnbundledBuild)
// Ensure that LLNDK dep is not included
@@ -1860,7 +1870,7 @@ func TestUseVendor(t *testing.T) {
apex_available: [ "myapex" ],
}
`, func(fs map[string][]byte, config android.Config) {
- setUseVendorWhitelistForTest(config, []string{"myapex"})
+ setUseVendorAllowListForTest(config, []string{"myapex"})
})
inputsList := []string{}
@@ -1893,9 +1903,9 @@ func TestUseVendorRestriction(t *testing.T) {
private_key: "testkey.pem",
}
`, func(fs map[string][]byte, config android.Config) {
- setUseVendorWhitelistForTest(config, []string{""})
+ setUseVendorAllowListForTest(config, []string{""})
})
- // no error with whitelist
+ // no error with allow list
testApex(t, `
apex {
name: "myapex",
@@ -1908,7 +1918,7 @@ func TestUseVendorRestriction(t *testing.T) {
private_key: "testkey.pem",
}
`, func(fs map[string][]byte, config android.Config) {
- setUseVendorWhitelistForTest(config, []string{"myapex"})
+ setUseVendorAllowListForTest(config, []string{"myapex"})
})
}
@@ -3673,7 +3683,7 @@ func TestApexUsesFailsIfUseVenderMismatch(t *testing.T) {
private_key: "testkey.pem",
}
`, func(fs map[string][]byte, config android.Config) {
- setUseVendorWhitelistForTest(config, []string{"myapex"})
+ setUseVendorAllowListForTest(config, []string{"myapex"})
})
}
diff --git a/apex/builder.go b/apex/builder.go
index 17eac1a39..129358834 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -165,13 +165,13 @@ var (
diffApexContentRule = pctx.StaticRule("diffApexContentRule", blueprint.RuleParams{
Command: `diff --unchanged-group-format='' \` +
`--changed-group-format='%<' \` +
- `${image_content_file} ${whitelisted_files_file} || (` +
+ `${image_content_file} ${allowed_files_file} || (` +
`echo -e "New unexpected files were added to ${apex_module_name}." ` +
` "To fix the build run following command:" && ` +
- `echo "system/apex/tools/update_whitelist.sh ${whitelisted_files_file} ${image_content_file}" && ` +
+ `echo "system/apex/tools/update_allowed_list.sh ${allowed_files_file} ${image_content_file}" && ` +
`exit 1); touch ${out}`,
- Description: "Diff ${image_content_file} and ${whitelisted_files_file}",
- }, "image_content_file", "whitelisted_files_file", "apex_module_name")
+ Description: "Diff ${image_content_file} and ${allowed_files_file}",
+ }, "image_content_file", "allowed_files_file", "apex_module_name")
)
func (a *apexBundle) buildManifest(ctx android.ModuleContext, provideNativeLibs, requireNativeLibs []string) {
@@ -402,7 +402,7 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) {
},
})
implicitInputs = append(implicitInputs, imageContentFile)
- whitelistedFilesFile := android.PathForModuleSrc(ctx, proptools.String(a.properties.Whitelisted_files))
+ allowedFilesFile := android.PathForModuleSrc(ctx, proptools.String(a.properties.Whitelisted_files))
phonyOutput := android.PathForModuleOut(ctx, a.Name()+"-diff-phony-output")
ctx.Build(pctx, android.BuildParams{
@@ -411,9 +411,9 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) {
Output: phonyOutput,
Description: "diff apex image content",
Args: map[string]string{
- "whitelisted_files_file": whitelistedFilesFile.String(),
- "image_content_file": imageContentFile.String(),
- "apex_module_name": a.Name(),
+ "allowed_files_file": allowedFilesFile.String(),
+ "image_content_file": imageContentFile.String(),
+ "apex_module_name": a.Name(),
},
})
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 52480ea68..b3ad610d6 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -457,6 +457,9 @@ func (c *stubDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.
entries.SetString("LOCAL_MODULE_PATH", path)
entries.SetString("LOCAL_MODULE_STEM", stem)
entries.SetBool("LOCAL_NO_NOTICE_FILE", true)
+ if c.parsedCoverageXmlPath.String() != "" {
+ entries.SetString("SOONG_NDK_API_XML", "$(SOONG_NDK_API_XML) "+c.parsedCoverageXmlPath.String())
+ }
})
}
diff --git a/cc/cc.go b/cc/cc.go
index 8eabff516..f80c229cb 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -825,15 +825,8 @@ func (c *Module) Init() android.Module {
}
c.Prefer32(func(ctx android.BaseModuleContext, base *android.ModuleBase, class android.OsClass) bool {
- switch class {
- case android.Device:
- return ctx.Config().DevicePrefer32BitExecutables()
- case android.HostCross:
- // Windows builds always prefer 32-bit
- return true
- default:
- return false
- }
+ // Windows builds always prefer 32-bit
+ return class == android.HostCross
})
android.InitAndroidArchModule(c, c.hod, c.multilib)
android.InitApexModule(c)
@@ -3230,12 +3223,7 @@ func (ks *kytheExtractAllSingleton) GenerateBuildActions(ctx android.SingletonCo
})
// TODO(asmundak): Perhaps emit a rule to output a warning if there were no xrefTargets
if len(xrefTargets) > 0 {
- ctx.Build(pctx, android.BuildParams{
- Rule: blueprint.Phony,
- Output: android.PathForPhony(ctx, "xref_cxx"),
- Inputs: xrefTargets,
- //Default: true,
- })
+ ctx.Phony("xref_cxx", xrefTargets...)
}
}
diff --git a/cc/compiler.go b/cc/compiler.go
index e7495da88..b5f297ce5 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -514,7 +514,7 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps
flags.Local.CFlags = append(flags.Local.CFlags, "-fopenmp")
}
- // Exclude directories from manual binder interface whitelisting.
+ // Exclude directories from manual binder interface allowed list.
//TODO(b/145621474): Move this check into IInterface.h when clang-tidy no longer uses absolute paths.
if android.HasAnyPrefix(ctx.ModuleDir(), allowedManualInterfacePaths) {
flags.Local.CFlags = append(flags.Local.CFlags, "-DDO_NOT_CHECK_MANUAL_BINDER_INTERFACES")
diff --git a/cc/config/global.go b/cc/config/global.go
index 1dd8a2d03..7b651bc84 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -128,8 +128,8 @@ var (
// prebuilts/clang default settings.
ClangDefaultBase = "prebuilts/clang/host"
- ClangDefaultVersion = "clang-r383902"
- ClangDefaultShortVersion = "11.0.1"
+ ClangDefaultVersion = "clang-r383902b"
+ ClangDefaultShortVersion = "11.0.2"
// Directories with warnings from Android.bp files.
WarningAllowedProjects = []string{
diff --git a/cc/linker.go b/cc/linker.go
index 57a0c016a..c9cbd9baf 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -177,7 +177,10 @@ type BaseLinkerProperties struct {
Version_script *string `android:"path,arch_variant"`
// list of static libs that should not be used to build this module
- Exclude_static_libs []string
+ Exclude_static_libs []string `android:"arch_variant"`
+
+ // list of shared libs that should not be used to build this module
+ Exclude_shared_libs []string `android:"arch_variant"`
}
func NewBaseLinker(sanitize *sanitize) *baseLinker {
@@ -223,6 +226,8 @@ func (linker *baseLinker) linkerDeps(ctx DepsContext, deps Deps) Deps {
deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, linker.Properties.Export_shared_lib_headers...)
deps.ReexportGeneratedHeaders = append(deps.ReexportGeneratedHeaders, linker.Properties.Export_generated_headers...)
+ deps.SharedLibs = removeListFromList(deps.SharedLibs, linker.Properties.Exclude_shared_libs)
+ deps.StaticLibs = removeListFromList(deps.StaticLibs, linker.Properties.Exclude_static_libs)
deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Exclude_static_libs)
if Bool(linker.Properties.Use_version_lib) {
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index 1597b88d0..d79badbc4 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -25,8 +25,12 @@ import (
"android/soong/android"
)
+func init() {
+ pctx.HostBinToolVariable("ndk_api_coverage_parser", "ndk_api_coverage_parser")
+}
+
var (
- toolPath = pctx.SourcePathVariable("toolPath", "build/soong/cc/gen_stub_libs.py")
+ toolPath = pctx.SourcePathVariable("toolPath", "build/soong/cc/scriptlib/gen_stub_libs.py")
genStubSrc = pctx.AndroidStaticRule("genStubSrc",
blueprint.RuleParams{
@@ -35,6 +39,12 @@ var (
CommandDeps: []string{"$toolPath"},
}, "arch", "apiLevel", "apiMap", "flags")
+ parseNdkApiRule = pctx.AndroidStaticRule("parseNdkApiRule",
+ blueprint.RuleParams{
+ Command: "$ndk_api_coverage_parser $in $out --api-map $apiMap",
+ CommandDeps: []string{"$ndk_api_coverage_parser"},
+ }, "apiMap")
+
ndkLibrarySuffix = ".ndk"
ndkPrebuiltSharedLibs = []string{
@@ -111,8 +121,9 @@ type stubDecorator struct {
properties libraryProperties
- versionScriptPath android.ModuleGenPath
- installPath android.Path
+ versionScriptPath android.ModuleGenPath
+ parsedCoverageXmlPath android.ModuleOutPath
+ installPath android.Path
}
// OMG GO
@@ -308,14 +319,35 @@ func compileStubLibrary(ctx ModuleContext, flags Flags, symbolFile, apiLevel, ge
return compileObjs(ctx, flagsToBuilderFlags(flags), subdir, srcs, nil, nil), versionScriptPath
}
+func parseSymbolFileForCoverage(ctx ModuleContext, symbolFile string) android.ModuleOutPath {
+ apiLevelsJson := android.GetApiLevelsJson(ctx)
+ symbolFilePath := android.PathForModuleSrc(ctx, symbolFile)
+ outputFileName := strings.Split(symbolFilePath.Base(), ".")[0]
+ parsedApiCoveragePath := android.PathForModuleOut(ctx, outputFileName+".xml")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: parseNdkApiRule,
+ Description: "parse ndk api symbol file for api coverage: " + symbolFilePath.Rel(),
+ Outputs: []android.WritablePath{parsedApiCoveragePath},
+ Input: symbolFilePath,
+ Args: map[string]string{
+ "apiMap": apiLevelsJson.String(),
+ },
+ })
+ return parsedApiCoveragePath
+}
+
func (c *stubDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
if !strings.HasSuffix(String(c.properties.Symbol_file), ".map.txt") {
ctx.PropertyErrorf("symbol_file", "must end with .map.txt")
}
- objs, versionScript := compileStubLibrary(ctx, flags, String(c.properties.Symbol_file),
+ symbolFile := String(c.properties.Symbol_file)
+ objs, versionScript := compileStubLibrary(ctx, flags, symbolFile,
c.properties.ApiLevel, "")
c.versionScriptPath = versionScript
+ if c.properties.ApiLevel == "current" && ctx.PrimaryArch() {
+ c.parsedCoverageXmlPath = parseSymbolFileForCoverage(ctx, symbolFile)
+ }
return objs
}
diff --git a/cc/scriptlib/Android.bp b/cc/scriptlib/Android.bp
new file mode 100644
index 000000000..ff9a2f0f3
--- /dev/null
+++ b/cc/scriptlib/Android.bp
@@ -0,0 +1,32 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+python_test_host {
+ name: "test_ndk_api_coverage_parser",
+ main: "test_ndk_api_coverage_parser.py",
+ srcs: [
+ "test_ndk_api_coverage_parser.py",
+ ],
+}
+
+python_binary_host {
+ name: "ndk_api_coverage_parser",
+ main: "ndk_api_coverage_parser.py",
+ srcs: [
+ "gen_stub_libs.py",
+ "ndk_api_coverage_parser.py",
+ ],
+}
diff --git a/cc/scriptlib/__init__.py b/cc/scriptlib/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/cc/scriptlib/__init__.py
diff --git a/cc/gen_stub_libs.py b/cc/scriptlib/gen_stub_libs.py
index 7deb804c3..d61dfbb07 100755
--- a/cc/gen_stub_libs.py
+++ b/cc/scriptlib/gen_stub_libs.py
@@ -246,6 +246,7 @@ class Symbol(object):
def __eq__(self, other):
return self.name == other.name and set(self.tags) == set(other.tags)
+
class SymbolFileParser(object):
"""Parses NDK symbol files."""
def __init__(self, input_file, api_map, arch, api, llndk, apex):
diff --git a/cc/scriptlib/ndk_api_coverage_parser.py b/cc/scriptlib/ndk_api_coverage_parser.py
new file mode 100755
index 000000000..d74035b2a
--- /dev/null
+++ b/cc/scriptlib/ndk_api_coverage_parser.py
@@ -0,0 +1,134 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2020 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+"""Generates xml of NDK libraries used for API coverage analysis."""
+import argparse
+import json
+import os
+import sys
+
+from xml.etree.ElementTree import Element, SubElement, tostring
+from gen_stub_libs import ALL_ARCHITECTURES, FUTURE_API_LEVEL, MultiplyDefinedSymbolError, SymbolFileParser
+
+
+ROOT_ELEMENT_TAG = 'ndk-library'
+SYMBOL_ELEMENT_TAG = 'symbol'
+ARCHITECTURE_ATTRIBUTE_KEY = 'arch'
+DEPRECATED_ATTRIBUTE_KEY = 'is_deprecated'
+PLATFORM_ATTRIBUTE_KEY = 'is_platform'
+NAME_ATTRIBUTE_KEY = 'name'
+VARIABLE_TAG = 'var'
+EXPOSED_TARGET_TAGS = (
+ 'vndk',
+ 'apex',
+ 'llndk',
+)
+API_LEVEL_TAG_PREFIXES = (
+ 'introduced=',
+ 'introduced-',
+)
+
+
+def parse_tags(tags):
+ """Parses tags and save needed tags in the created attributes.
+
+ Return attributes dictionary.
+ """
+ attributes = {}
+ arch = []
+ for tag in tags:
+ if tag.startswith(tuple(API_LEVEL_TAG_PREFIXES)):
+ key, _, value = tag.partition('=')
+ attributes.update({key: value})
+ elif tag in ALL_ARCHITECTURES:
+ arch.append(tag)
+ elif tag in EXPOSED_TARGET_TAGS:
+ attributes.update({tag: 'True'})
+ attributes.update({ARCHITECTURE_ATTRIBUTE_KEY: ','.join(arch)})
+ return attributes
+
+
+class XmlGenerator(object):
+ """Output generator that writes parsed symbol file to a xml file."""
+ def __init__(self, output_file):
+ self.output_file = output_file
+
+ def convertToXml(self, versions):
+ """Writes all symbol data to the output file."""
+ root = Element(ROOT_ELEMENT_TAG)
+ for version in versions:
+ if VARIABLE_TAG in version.tags:
+ continue
+ version_attributes = parse_tags(version.tags)
+ _, _, postfix = version.name.partition('_')
+ is_platform = postfix == 'PRIVATE' or postfix == 'PLATFORM'
+ is_deprecated = postfix == 'DEPRECATED'
+ version_attributes.update({PLATFORM_ATTRIBUTE_KEY: str(is_platform)})
+ version_attributes.update({DEPRECATED_ATTRIBUTE_KEY: str(is_deprecated)})
+ for symbol in version.symbols:
+ if VARIABLE_TAG in symbol.tags:
+ continue
+ attributes = {NAME_ATTRIBUTE_KEY: symbol.name}
+ attributes.update(version_attributes)
+ # If same version tags already exist, it will be overwrite here.
+ attributes.update(parse_tags(symbol.tags))
+ SubElement(root, SYMBOL_ELEMENT_TAG, attributes)
+ return root
+
+ def write_xml_to_file(self, root):
+ """Write xml element root to output_file."""
+ parsed_data = tostring(root)
+ output_file = open(self.output_file, "wb")
+ output_file.write(parsed_data)
+
+ def write(self, versions):
+ root = self.convertToXml(versions)
+ self.write_xml_to_file(root)
+
+
+def parse_args():
+ """Parses and returns command line arguments."""
+ parser = argparse.ArgumentParser()
+
+ parser.add_argument('symbol_file', type=os.path.realpath, help='Path to symbol file.')
+ parser.add_argument(
+ 'output_file', type=os.path.realpath,
+ help='The output parsed api coverage file.')
+ parser.add_argument(
+ '--api-map', type=os.path.realpath, required=True,
+ help='Path to the API level map JSON file.')
+ return parser.parse_args()
+
+
+def main():
+ """Program entry point."""
+ args = parse_args()
+
+ with open(args.api_map) as map_file:
+ api_map = json.load(map_file)
+
+ with open(args.symbol_file) as symbol_file:
+ try:
+ versions = SymbolFileParser(symbol_file, api_map, "", FUTURE_API_LEVEL,
+ True, True).parse()
+ except MultiplyDefinedSymbolError as ex:
+ sys.exit('{}: error: {}'.format(args.symbol_file, ex))
+
+ generator = XmlGenerator(args.output_file)
+ generator.write(versions)
+
+if __name__ == '__main__':
+ main()
diff --git a/cc/test_gen_stub_libs.py b/cc/scriptlib/test_gen_stub_libs.py
index 0b45e7110..0b45e7110 100755
--- a/cc/test_gen_stub_libs.py
+++ b/cc/scriptlib/test_gen_stub_libs.py
diff --git a/cc/scriptlib/test_ndk_api_coverage_parser.py b/cc/scriptlib/test_ndk_api_coverage_parser.py
new file mode 100644
index 000000000..a3c9b708c
--- /dev/null
+++ b/cc/scriptlib/test_ndk_api_coverage_parser.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+"""Tests for ndk_api_coverage_parser.py."""
+import io
+import textwrap
+import unittest
+
+from xml.etree.ElementTree import tostring
+from gen_stub_libs import FUTURE_API_LEVEL, SymbolFileParser
+import ndk_api_coverage_parser as nparser
+
+
+# pylint: disable=missing-docstring
+
+
+class ApiCoverageSymbolFileParserTest(unittest.TestCase):
+ def test_parse(self):
+ input_file = io.StringIO(textwrap.dedent(u"""\
+ LIBLOG { # introduced-arm64=24 introduced-x86=24 introduced-x86_64=24
+ global:
+ android_name_to_log_id; # apex llndk introduced=23
+ android_log_id_to_name; # llndk arm
+ __android_log_assert; # introduced-x86=23
+ __android_log_buf_print; # var
+ __android_log_buf_write;
+ local:
+ *;
+ };
+
+ LIBLOG_PLATFORM {
+ android_fdtrack; # llndk
+ android_net; # introduced=23
+ };
+
+ LIBLOG_FOO { # var
+ android_var;
+ };
+ """))
+ parser = SymbolFileParser(input_file, {}, "", FUTURE_API_LEVEL, True, True)
+ generator = nparser.XmlGenerator(io.StringIO())
+ result = tostring(generator.convertToXml(parser.parse())).decode()
+ expected = '<ndk-library><symbol apex="True" arch="" introduced="23" introduced-arm64="24" introduced-x86="24" introduced-x86_64="24" is_deprecated="False" is_platform="False" llndk="True" name="android_name_to_log_id" /><symbol arch="arm" introduced-arm64="24" introduced-x86="24" introduced-x86_64="24" is_deprecated="False" is_platform="False" llndk="True" name="android_log_id_to_name" /><symbol arch="" introduced-arm64="24" introduced-x86="23" introduced-x86_64="24" is_deprecated="False" is_platform="False" name="__android_log_assert" /><symbol arch="" introduced-arm64="24" introduced-x86="24" introduced-x86_64="24" is_deprecated="False" is_platform="False" name="__android_log_buf_write" /><symbol arch="" is_deprecated="False" is_platform="True" llndk="True" name="android_fdtrack" /><symbol arch="" introduced="23" is_deprecated="False" is_platform="True" name="android_net" /></ndk-library>'
+ self.assertEqual(expected, result)
+
+
+def main():
+ suite = unittest.TestLoader().loadTestsFromName(__name__)
+ unittest.TextTestRunner(verbosity=3).run(suite)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/cc/sdk.go b/cc/sdk.go
index d05a04a12..a6f94afbb 100644
--- a/cc/sdk.go
+++ b/cc/sdk.go
@@ -43,6 +43,7 @@ func sdkMutator(ctx android.BottomUpMutatorContext) {
if ctx.Config().UnbundledBuild() {
modules[0].(*Module).Properties.HideFromMake = true
+ modules[0].(*Module).Properties.PreventInstall = true
} else {
modules[1].(*Module).Properties.SdkAndPlatformVariantVisibleToMake = true
modules[1].(*Module).Properties.PreventInstall = true
diff --git a/cc/testing.go b/cc/testing.go
index edbb24d13..479b424ab 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -467,15 +467,6 @@ func GatherRequiredDepsForTest(oses ...android.OsType) string {
}
func GatherRequiredFilesForTest(fs map[string][]byte) {
- fs["prebuilts/ndk/current/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++_shared.so"] = nil
- fs["prebuilts/ndk/current/platforms/android-27/arch-arm/usr/lib/crtbegin_so.o"] = nil
- fs["prebuilts/ndk/current/platforms/android-27/arch-arm/usr/lib/crtend_so.o"] = nil
- fs["prebuilts/ndk/current/platforms/android-27/arch-arm64/usr/lib/crtbegin_so.o"] = nil
- fs["prebuilts/ndk/current/platforms/android-27/arch-arm64/usr/lib/crtend_so.o"] = nil
- fs["prebuilts/ndk/current/platforms/android-27/arch-x86/usr/lib/crtbegin_so.o"] = nil
- fs["prebuilts/ndk/current/platforms/android-27/arch-x86/usr/lib/crtend_so.o"] = nil
- fs["prebuilts/ndk/current/platforms/android-27/arch-x86_64/usr/lib64/crtbegin_so.o"] = nil
- fs["prebuilts/ndk/current/platforms/android-27/arch-x86_64/usr/lib64/crtend_so.o"] = nil
}
func TestConfig(buildDir string, os android.OsType, env map[string]string,
@@ -484,20 +475,7 @@ func TestConfig(buildDir string, os android.OsType, env map[string]string,
// add some modules that are required by the compiler and/or linker
bp = bp + GatherRequiredDepsForTest(os)
- mockFS := map[string][]byte{
- "foo.c": nil,
- "foo.lds": nil,
- "bar.c": nil,
- "baz.c": nil,
- "baz.o": nil,
- "a.proto": nil,
- "b.aidl": nil,
- "sub/c.aidl": nil,
- "my_include": nil,
- "foo.map.txt": nil,
- "liba.so": nil,
- "libb.a": nil,
- }
+ mockFS := map[string][]byte{}
GatherRequiredFilesForTest(mockFS)
diff --git a/java/aar.go b/java/aar.go
index 7413c8082..28e388aaf 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -734,6 +734,10 @@ func (a *AARImport) DexJarBuildPath() android.Path {
return nil
}
+func (a *AARImport) DexJarInstallPath() android.Path {
+ return nil
+}
+
func (a *AARImport) AidlIncludeDirs() android.Paths {
return nil
}
diff --git a/java/app.go b/java/app.go
index 24dde79f4..0fdede13a 100755
--- a/java/app.go
+++ b/java/app.go
@@ -691,9 +691,9 @@ func processMainCert(m android.ModuleBase, certPropValue string, certificates []
systemCertPath := ctx.Config().DefaultAppCertificateDir(ctx).String()
if strings.HasPrefix(certPath, systemCertPath) {
enforceSystemCert := ctx.Config().EnforceSystemCertificate()
- whitelist := ctx.Config().EnforceSystemCertificateWhitelist()
+ allowed := ctx.Config().EnforceSystemCertificateAllowList()
- if enforceSystemCert && !inList(m.Name(), whitelist) {
+ if enforceSystemCert && !inList(m.Name(), allowed) {
ctx.PropertyErrorf("certificate", "The module in product partition cannot be signed with certificate in system.")
}
}
@@ -973,10 +973,6 @@ func AndroidAppFactory() android.Module {
&module.overridableAppProperties,
&module.usesLibrary.usesLibraryProperties)
- module.Prefer32(func(ctx android.BaseModuleContext, base *android.ModuleBase, class android.OsClass) bool {
- return class == android.Device && ctx.Config().DevicePrefer32BitApps()
- })
-
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
android.InitDefaultableModule(module)
android.InitOverridableModule(module, &module.appProperties.Overrides)
@@ -1887,16 +1883,22 @@ func (u *usesLibrary) usesLibraryPaths(ctx android.ModuleContext) dexpreopt.Libr
ctx.VisitDirectDepsWithTag(usesLibTag, func(m android.Module) {
dep := ctx.OtherModuleName(m)
if lib, ok := m.(Dependency); ok {
- if dexJar := lib.DexJarBuildPath(); dexJar != nil {
- usesLibPaths[dep] = &dexpreopt.LibraryPath{
- dexJar,
- // TODO(b/132357300): propagate actual install paths here.
- filepath.Join("/system/framework", dep+".jar"),
- }
- } else {
+ buildPath := lib.DexJarBuildPath()
+ if buildPath == nil {
ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must"+
" produce a dex jar, does it have installable: true?", dep)
+ return
}
+
+ var devicePath string
+ installPath := lib.DexJarInstallPath()
+ if installPath == nil {
+ devicePath = filepath.Join("/system/framework", dep+".jar")
+ } else {
+ devicePath = android.InstallPathToOnDevicePath(ctx, installPath.(android.InstallPath))
+ }
+
+ usesLibPaths[dep] = &dexpreopt.LibraryPath{buildPath, devicePath}
} else if ctx.Config().AllowMissingDependencies() {
ctx.AddMissingDependencies([]string{dep})
} else {
diff --git a/java/app_test.go b/java/app_test.go
index eeba161b3..e45ba70d5 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -2657,7 +2657,7 @@ func TestCodelessApp(t *testing.T) {
}
func TestEmbedNotice(t *testing.T) {
- ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
+ ctx, _ := testJavaWithFS(t, cc.GatherRequiredDepsForTest(android.Android)+`
android_app {
name: "foo",
srcs: ["a.java"],
@@ -2713,7 +2713,12 @@ func TestEmbedNotice(t *testing.T) {
srcs: ["b.java"],
notice: "TOOL_NOTICE",
}
- `)
+ `, map[string][]byte{
+ "APP_NOTICE": nil,
+ "GENRULE_NOTICE": nil,
+ "LIB_NOTICE": nil,
+ "TOOL_NOTICE": nil,
+ })
// foo has NOTICE files to process, and embed_notices is true.
foo := ctx.ModuleForTests("foo", "android_common")
diff --git a/java/device_host_converter.go b/java/device_host_converter.go
index 1ffb13f94..9191a8321 100644
--- a/java/device_host_converter.go
+++ b/java/device_host_converter.go
@@ -51,7 +51,7 @@ type DeviceForHost struct {
// java_device_for_host makes the classes.jar output of a device java_library module available to host
// java_library modules.
//
-// It is rarely necessary, and its usage is restricted to a few whitelisted projects.
+// It is rarely necessary, and its usage is restricted to a few allowed projects.
func DeviceForHostFactory() android.Module {
module := &DeviceForHost{}
@@ -68,7 +68,7 @@ type HostForDevice struct {
// java_host_for_device makes the classes.jar output of a host java_library module available to device
// java_library modules.
//
-// It is rarely necessary, and its usage is restricted to a few whitelisted projects.
+// It is rarely necessary, and its usage is restricted to a few allowed projects.
func HostForDeviceFactory() android.Module {
module := &HostForDevice{}
@@ -154,6 +154,10 @@ func (d *DeviceHostConverter) DexJarBuildPath() android.Path {
return nil
}
+func (d *DeviceHostConverter) DexJarInstallPath() android.Path {
+ return nil
+}
+
func (d *DeviceHostConverter) AidlIncludeDirs() android.Paths {
return nil
}
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 2911fd9b9..c33415ef6 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -77,10 +77,6 @@ func (d *dexpreopter) dexpreoptDisabled(ctx android.BaseModuleContext) bool {
return true
}
- if ctx.Config().UnbundledBuild() {
- return true
- }
-
if d.isTest {
return true
}
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index 9d9383814..41205598e 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -179,15 +179,7 @@ func RegisterDexpreoptBootJarsComponents(ctx android.RegistrationContext) {
}
func skipDexpreoptBootJars(ctx android.PathContext) bool {
- if dexpreopt.GetGlobalConfig(ctx).DisablePreopt {
- return true
- }
-
- if ctx.Config().UnbundledBuild() {
- return true
- }
-
- return false
+ return dexpreopt.GetGlobalConfig(ctx).DisablePreopt
}
type dexpreoptBootJars struct {
@@ -340,10 +332,12 @@ func buildBootImage(ctx android.SingletonContext, image *bootImageConfig) *bootI
bootFrameworkProfileRule(ctx, image, missingDeps)
updatableBcpPackagesRule(ctx, image, missingDeps)
- var allFiles android.Paths
+ var zipFiles android.Paths
for _, variant := range image.variants {
files := buildBootImageVariant(ctx, variant, profile, missingDeps)
- allFiles = append(allFiles, files.Paths()...)
+ if variant.target.Os == android.Android {
+ zipFiles = append(zipFiles, files.Paths()...)
+ }
}
if image.zip != nil {
@@ -351,8 +345,8 @@ func buildBootImage(ctx android.SingletonContext, image *bootImageConfig) *bootI
rule.Command().
BuiltTool(ctx, "soong_zip").
FlagWithOutput("-o ", image.zip).
- FlagWithArg("-C ", image.dir.String()).
- FlagWithInputList("-f ", allFiles, " -f ")
+ FlagWithArg("-C ", image.dir.Join(ctx, android.Android.String()).String()).
+ FlagWithInputList("-f ", zipFiles, " -f ")
rule.Build(pctx, ctx, "zip_"+image.name, "zip "+image.name+" image")
}
diff --git a/java/dexpreopt_bootjars_test.go b/java/dexpreopt_bootjars_test.go
index e9704dc2a..9670c7f4b 100644
--- a/java/dexpreopt_bootjars_test.go
+++ b/java/dexpreopt_bootjars_test.go
@@ -118,7 +118,7 @@ func TestDexpreoptBootZip(t *testing.T) {
ctx := android.PathContextForTesting(testConfig(nil, "", nil))
expectedInputs := []string{}
- for _, target := range dexpreoptTargets(ctx) {
+ for _, target := range ctx.Config().Targets[android.Android] {
for _, ext := range []string{".art", ".oat", ".vdex"} {
for _, jar := range []string{"foo", "bar", "baz"} {
expectedInputs = append(expectedInputs,
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 4c3e11236..68cfe9fde 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -1470,7 +1470,7 @@ func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersi
FlagWithInput("@", srcJarList).
FlagWithOutput("--strict-input-files:warn ", android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"violations.txt"))
- if implicitsRsp.String() != "" {
+ if implicitsRsp != nil {
cmd.FlagWithArg("--strict-input-files-exempt ", "@"+implicitsRsp.String())
}
diff --git a/java/java.go b/java/java.go
index af68e56b7..1cdfbf187 100644
--- a/java/java.go
+++ b/java/java.go
@@ -502,6 +502,7 @@ type Dependency interface {
ResourceJars() android.Paths
ImplementationAndResourcesJars() android.Paths
DexJarBuildPath() android.Path
+ DexJarInstallPath() android.Path
AidlIncludeDirs() android.Paths
ExportedSdkLibs() []string
ExportedPlugins() (android.Paths, []string)
@@ -1749,6 +1750,10 @@ func (j *Module) DexJarBuildPath() android.Path {
return j.dexJarFile
}
+func (j *Module) DexJarInstallPath() android.Path {
+ return j.installFile
+}
+
func (j *Module) ResourceJars() android.Paths {
if j.resourceJar == nil {
return nil
@@ -2575,6 +2580,10 @@ func (j *Import) DexJarBuildPath() android.Path {
return nil
}
+func (j *Import) DexJarInstallPath() android.Path {
+ return nil
+}
+
func (j *Import) AidlIncludeDirs() android.Paths {
return j.exportAidlIncludeDirs
}
@@ -2754,8 +2763,10 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.maybeStrippedDexJarFile = dexOutputFile
- ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
- j.Stem()+".jar", dexOutputFile)
+ if j.IsForPlatform() {
+ ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
+ j.Stem()+".jar", dexOutputFile)
+ }
}
func (j *DexImport) DexJarBuildPath() android.Path {
@@ -2863,11 +2874,7 @@ func (ks *kytheExtractJavaSingleton) GenerateBuildActions(ctx android.SingletonC
})
// TODO(asmundak): perhaps emit a rule to output a warning if there were no xrefTargets
if len(xrefTargets) > 0 {
- ctx.Build(pctx, android.BuildParams{
- Rule: blueprint.Phony,
- Output: android.PathForPhony(ctx, "xref_java"),
- Inputs: xrefTargets,
- })
+ ctx.Phony("xref_java", xrefTargets...)
}
}
diff --git a/java/java_test.go b/java/java_test.go
index 8ea34d975..215070e6f 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -142,9 +142,14 @@ func testJavaErrorWithConfig(t *testing.T, pattern string, config android.Config
return ctx, config
}
+func testJavaWithFS(t *testing.T, bp string, fs map[string][]byte) (*android.TestContext, android.Config) {
+ t.Helper()
+ return testJavaWithConfig(t, testConfig(nil, bp, fs))
+}
+
func testJava(t *testing.T, bp string) (*android.TestContext, android.Config) {
t.Helper()
- return testJavaWithConfig(t, testConfig(nil, bp, nil))
+ return testJavaWithFS(t, bp, nil)
}
func testJavaWithConfig(t *testing.T, config android.Config) (*android.TestContext, android.Config) {
@@ -740,7 +745,7 @@ func TestResources(t *testing.T) {
for _, test := range table {
t.Run(test.name, func(t *testing.T) {
- ctx, _ := testJava(t, `
+ ctx, _ := testJavaWithFS(t, `
java_library {
name: "foo",
srcs: [
@@ -750,7 +755,13 @@ func TestResources(t *testing.T) {
],
`+test.prop+`,
}
- `+test.extra)
+ `+test.extra,
+ map[string][]byte{
+ "java-res/a/a": nil,
+ "java-res/b/b": nil,
+ "java-res2/a": nil,
+ },
+ )
foo := ctx.ModuleForTests("foo", "android_common").Output("withres/foo.jar")
fooRes := ctx.ModuleForTests("foo", "android_common").Output("res/foo.jar")
@@ -769,7 +780,7 @@ func TestResources(t *testing.T) {
}
func TestIncludeSrcs(t *testing.T) {
- ctx, _ := testJava(t, `
+ ctx, _ := testJavaWithFS(t, `
java_library {
name: "foo",
srcs: [
@@ -790,7 +801,11 @@ func TestIncludeSrcs(t *testing.T) {
java_resource_dirs: ["java-res"],
include_srcs: true,
}
- `)
+ `, map[string][]byte{
+ "java-res/a/a": nil,
+ "java-res/b/b": nil,
+ "java-res2/a": nil,
+ })
// Test a library with include_srcs: true
foo := ctx.ModuleForTests("foo", "android_common").Output("withres/foo.jar")
@@ -832,7 +847,7 @@ func TestIncludeSrcs(t *testing.T) {
}
func TestGeneratedSources(t *testing.T) {
- ctx, _ := testJava(t, `
+ ctx, _ := testJavaWithFS(t, `
java_library {
name: "foo",
srcs: [
@@ -847,7 +862,10 @@ func TestGeneratedSources(t *testing.T) {
tool_files: ["java-res/a"],
out: ["gen.java"],
}
- `)
+ `, map[string][]byte{
+ "a.java": nil,
+ "b.java": nil,
+ })
javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
genrule := ctx.ModuleForTests("gen", "").Rule("generator")
@@ -932,7 +950,7 @@ func TestSharding(t *testing.T) {
}
func TestDroiddoc(t *testing.T) {
- ctx, _ := testJava(t, `
+ ctx, _ := testJavaWithFS(t, `
droiddoc_exported_dir {
name: "droiddoc-templates-sdk",
path: ".",
@@ -945,7 +963,7 @@ func TestDroiddoc(t *testing.T) {
droiddoc {
name: "bar-doc",
srcs: [
- "bar-doc/*.java",
+ "bar-doc/a.java",
"bar-doc/IFoo.aidl",
":bar-doc-aidl-srcs",
],
@@ -963,7 +981,11 @@ func TestDroiddoc(t *testing.T) {
todo_file: "libcore-docs-todo.html",
args: "-offlinemode -title \"libcore\"",
}
- `)
+ `,
+ map[string][]byte{
+ "bar-doc/a.java": nil,
+ "bar-doc/b.java": nil,
+ })
barDoc := ctx.ModuleForTests("bar-doc", "android_common").Rule("javadoc")
var javaSrcs []string
@@ -989,7 +1011,7 @@ func TestDroidstubsWithSystemModules(t *testing.T) {
droidstubs {
name: "stubs-source-system-modules",
srcs: [
- "bar-doc/*.java",
+ "bar-doc/a.java",
],
sdk_version: "none",
system_modules: "source-system-modules",
@@ -1010,7 +1032,7 @@ func TestDroidstubsWithSystemModules(t *testing.T) {
droidstubs {
name: "stubs-prebuilt-system-modules",
srcs: [
- "bar-doc/*.java",
+ "bar-doc/a.java",
],
sdk_version: "none",
system_modules: "prebuilt-system-modules",
diff --git a/java/testing.go b/java/testing.go
index f993f56b3..f34c64af6 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -25,35 +25,12 @@ func TestConfig(buildDir string, env map[string]string, bp string, fs map[string
bp += GatherRequiredDepsForTest()
mockFS := map[string][]byte{
- "a.java": nil,
- "b.java": nil,
- "c.java": nil,
- "b.kt": nil,
- "a.jar": nil,
- "b.jar": nil,
- "c.jar": nil,
- "APP_NOTICE": nil,
- "GENRULE_NOTICE": nil,
- "LIB_NOTICE": nil,
- "TOOL_NOTICE": nil,
- "AndroidTest.xml": nil,
- "java-res/a/a": nil,
- "java-res/b/b": nil,
- "java-res2/a": nil,
- "java-fg/a.java": nil,
- "java-fg/b.java": nil,
- "java-fg/c.java": nil,
"api/current.txt": nil,
"api/removed.txt": nil,
"api/system-current.txt": nil,
"api/system-removed.txt": nil,
"api/test-current.txt": nil,
"api/test-removed.txt": nil,
- "framework/aidl/a.aidl": nil,
- "aidl/foo/IFoo.aidl": nil,
- "aidl/bar/IBar.aidl": nil,
- "assets_a/a": nil,
- "assets_b/b": nil,
"prebuilts/sdk/14/public/android.jar": nil,
"prebuilts/sdk/14/public/framework.aidl": nil,
@@ -103,45 +80,6 @@ func TestConfig(buildDir string, env map[string]string, bp string, fs map[string
"prebuilts/sdk/30/test/api/bar-removed.txt": nil,
"prebuilts/sdk/tools/core-lambda-stubs.jar": nil,
"prebuilts/sdk/Android.bp": []byte(`prebuilt_apis { name: "sdk", api_dirs: ["14", "28", "30", "current"],}`),
-
- "prebuilts/apk/app.apk": nil,
- "prebuilts/apk/app_arm.apk": nil,
- "prebuilts/apk/app_arm64.apk": nil,
- "prebuilts/apk/app_xhdpi.apk": nil,
- "prebuilts/apk/app_xxhdpi.apk": nil,
-
- "prebuilts/apks/app.apks": nil,
-
- // For framework-res, which is an implicit dependency for framework
- "AndroidManifest.xml": nil,
- "build/make/target/product/security/testkey": nil,
-
- "build/soong/scripts/jar-wrapper.sh": nil,
-
- "build/make/core/verify_uses_libraries.sh": nil,
-
- "build/make/core/proguard.flags": nil,
- "build/make/core/proguard_basic_keeps.flags": nil,
-
- "jdk8/jre/lib/jce.jar": nil,
- "jdk8/jre/lib/rt.jar": nil,
- "jdk8/lib/tools.jar": nil,
-
- "bar-doc/a.java": nil,
- "bar-doc/b.java": nil,
- "bar-doc/IFoo.aidl": nil,
- "bar-doc/IBar.aidl": nil,
- "bar-doc/known_oj_tags.txt": nil,
- "external/doclava/templates-sdk": nil,
-
- "cert/new_cert.x509.pem": nil,
- "cert/new_cert.pk8": nil,
- "lineage.bin": nil,
-
- "testdata/data": nil,
-
- "stubs-sources/foo/Foo.java": nil,
- "stubs/sources/foo/Foo.java": nil,
}
cc.GatherRequiredFilesForTest(mockFS)
diff --git a/python/androidmk.go b/python/androidmk.go
index d293d52a1..247b80dc0 100644
--- a/python/androidmk.go
+++ b/python/androidmk.go
@@ -66,15 +66,9 @@ func (p *testDecorator) AndroidMk(base *Module, ret *android.AndroidMkData) {
fmt.Fprintln(w, "LOCAL_COMPATIBILITY_SUITE :=",
strings.Join(p.binaryDecorator.binaryProperties.Test_suites, " "))
}
- // If the test config has an explicit config specified use it.
- if p.testProperties.Test_config != nil {
- fmt.Fprintln(w, "LOCAL_TEST_CONFIG :=",
- *p.testProperties.Test_config)
- } else {
- if p.testConfig != nil {
- fmt.Fprintln(w, "LOCAL_FULL_TEST_CONFIG :=",
- p.testConfig.String())
- }
+ if p.testConfig != nil {
+ fmt.Fprintln(w, "LOCAL_FULL_TEST_CONFIG :=",
+ p.testConfig.String())
}
if !BoolDefault(p.binaryProperties.Auto_gen_config, true) {
diff --git a/python/test.go b/python/test.go
index f684fd51d..a669c73a6 100644
--- a/python/test.go
+++ b/python/test.go
@@ -29,11 +29,11 @@ func init() {
type TestProperties struct {
// the name of the test configuration (for example "AndroidTest.xml") that should be
// installed with the module.
- Test_config *string `android:"arch_variant"`
+ Test_config *string `android:"path,arch_variant"`
// the name of the test configuration template (for example "AndroidTestTemplate.xml") that
// should be installed with the module.
- Test_config_template *string `android:"arch_variant"`
+ Test_config_template *string `android:"path,arch_variant"`
}
type testDecorator struct {
diff --git a/rust/Android.bp b/rust/Android.bp
index 684db0bdd..b06ea8e75 100644
--- a/rust/Android.bp
+++ b/rust/Android.bp
@@ -16,6 +16,7 @@ bootstrap_go_package {
"library.go",
"prebuilt.go",
"proc_macro.go",
+ "project_json.go",
"rust.go",
"test.go",
"testing.go",
@@ -25,6 +26,7 @@ bootstrap_go_package {
"compiler_test.go",
"coverage_test.go",
"library_test.go",
+ "project_json_test.go",
"rust_test.go",
"test_test.go",
],
diff --git a/rust/OWNERS b/rust/OWNERS
index 82713f996..afd06e422 100644
--- a/rust/OWNERS
+++ b/rust/OWNERS
@@ -1,5 +1,5 @@
# Additional owner/reviewers for rust rules, including parent directory owners.
per-file * = chh@google.com, ivanlozano@google.com, jeffv@google.com, srhines@google.com
-# Limited owners/reviewers of the whitelist.
-per-file whitelist.go = chh@google.com, ivanlozano@google.com, jeffv@google.com, jgalenson@google.com, srhines@google.com
+# Limited owners/reviewers of the allowed list.
+per-file allowed_list.go = chh@google.com, ivanlozano@google.com, jeffv@google.com, jgalenson@google.com, srhines@google.com
diff --git a/rust/config/Android.bp b/rust/config/Android.bp
index 1a10312e2..5026da39e 100644
--- a/rust/config/Android.bp
+++ b/rust/config/Android.bp
@@ -10,7 +10,7 @@ bootstrap_go_package {
"arm64_device.go",
"global.go",
"toolchain.go",
- "whitelist.go",
+ "allowed_list.go",
"x86_darwin_host.go",
"x86_linux_host.go",
"x86_device.go",
diff --git a/rust/config/whitelist.go b/rust/config/allowed_list.go
index a339050f8..a339050f8 100644
--- a/rust/config/whitelist.go
+++ b/rust/config/allowed_list.go
diff --git a/rust/library.go b/rust/library.go
index 8aa033c0f..2e5126639 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -329,12 +329,21 @@ func (library *libraryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps {
return deps
}
+
+func (library *libraryDecorator) sharedLibFilename(ctx ModuleContext) string {
+ return library.getStem(ctx) + ctx.toolchain().SharedLibSuffix()
+}
+
func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
flags.RustFlags = append(flags.RustFlags, "-C metadata="+ctx.baseModuleName())
flags = library.baseCompiler.compilerFlags(ctx, flags)
if library.shared() || library.static() {
library.includeDirs = append(library.includeDirs, android.PathsForModuleSrc(ctx, library.Properties.Include_dirs)...)
}
+ if library.shared() {
+ flags.LinkFlags = append(flags.LinkFlags, "-Wl,-soname="+library.sharedLibFilename(ctx))
+ }
+
return flags
}
@@ -371,7 +380,7 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa
outputs := TransformSrctoStatic(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
library.coverageFile = outputs.coverageFile
} else if library.shared() {
- fileName := library.getStem(ctx) + ctx.toolchain().SharedLibSuffix()
+ fileName := library.sharedLibFilename(ctx)
outputFile = android.PathForModuleOut(ctx, fileName)
outputs := TransformSrctoShared(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
diff --git a/rust/library_test.go b/rust/library_test.go
index 9f9f374b9..37dd5414c 100644
--- a/rust/library_test.go
+++ b/rust/library_test.go
@@ -114,3 +114,17 @@ func TestValidateLibraryStem(t *testing.T) {
}`)
}
+
+func TestSharedLibraryFlags(t *testing.T) {
+ ctx := testRust(t, `
+ rust_library_host {
+ name: "libfoo",
+ srcs: ["foo.rs"],
+ crate_name: "foo",
+ }`)
+
+ libfooShared := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_shared").Output("libfoo.so")
+ if !strings.Contains(libfooShared.Args["linkFlags"], "-Wl,-soname=libfoo.so") {
+ t.Errorf("missing expected -Wl,-soname linker flag for libfoo shared lib, linkFlags: %#v", libfooShared.Args["linkFlags"])
+ }
+}
diff --git a/rust/project_json.go b/rust/project_json.go
new file mode 100644
index 000000000..909aebc98
--- /dev/null
+++ b/rust/project_json.go
@@ -0,0 +1,161 @@
+// Copyright 2020 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 rust
+
+import (
+ "encoding/json"
+ "fmt"
+ "path"
+
+ "android/soong/android"
+)
+
+// This singleton collects Rust crate definitions and generates a JSON file
+// (${OUT_DIR}/soong/rust-project.json) which can be use by external tools,
+// such as rust-analyzer. It does so when either make, mm, mma, mmm or mmma is
+// called. This singleton is enabled only if SOONG_GEN_RUST_PROJECT is set.
+// For example,
+//
+// $ SOONG_GEN_RUST_PROJECT=1 m nothing
+
+func init() {
+ android.RegisterSingletonType("rust_project_generator", rustProjectGeneratorSingleton)
+}
+
+func rustProjectGeneratorSingleton() android.Singleton {
+ return &projectGeneratorSingleton{}
+}
+
+type projectGeneratorSingleton struct{}
+
+const (
+ // Environment variables used to control the behavior of this singleton.
+ envVariableCollectRustDeps = "SOONG_GEN_RUST_PROJECT"
+ rustProjectJsonFileName = "rust-project.json"
+)
+
+// The format of rust-project.json is not yet finalized. A current description is available at:
+// https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/user/manual.adoc#non-cargo-based-projects
+type rustProjectDep struct {
+ Crate int `json:"crate"`
+ Name string `json:"name"`
+}
+
+type rustProjectCrate struct {
+ RootModule string `json:"root_module"`
+ Edition string `json:"edition,omitempty"`
+ Deps []rustProjectDep `json:"deps"`
+ Cfgs []string `json:"cfgs"`
+}
+
+type rustProjectJson struct {
+ Roots []string `json:"roots"`
+ Crates []rustProjectCrate `json:"crates"`
+}
+
+// crateInfo is used during the processing to keep track of the known crates.
+type crateInfo struct {
+ ID int
+ Deps map[string]int
+}
+
+func mergeDependencies(ctx android.SingletonContext, project *rustProjectJson,
+ knownCrates map[string]crateInfo, module android.Module,
+ crate *rustProjectCrate, deps map[string]int) {
+
+ //TODO(tweek): The stdlib dependencies do not appear here. We need to manually add them.
+ ctx.VisitDirectDeps(module, func(child android.Module) {
+ childId, childName, ok := appendLibraryAndDeps(ctx, project, knownCrates, child)
+ if !ok {
+ return
+ }
+ if _, ok = deps[childName]; ok {
+ return
+ }
+ crate.Deps = append(crate.Deps, rustProjectDep{Crate: childId, Name: childName})
+ deps[childName] = childId
+ })
+}
+
+// appendLibraryAndDeps creates a rustProjectCrate for the module argument and
+// appends it to the rustProjectJson struct. It visits the dependencies of the
+// module depth-first. If the current module is already in knownCrates, its
+// its dependencies are merged. Returns a tuple (id, crate_name, ok).
+func appendLibraryAndDeps(ctx android.SingletonContext, project *rustProjectJson,
+ knownCrates map[string]crateInfo, module android.Module) (int, string, bool) {
+ rModule, ok := module.(*Module)
+ if !ok {
+ return 0, "", false
+ }
+ if rModule.compiler == nil {
+ return 0, "", false
+ }
+ rustLib, ok := rModule.compiler.(*libraryDecorator)
+ if !ok {
+ return 0, "", false
+ }
+ crateName := rModule.CrateName()
+ if cInfo, ok := knownCrates[crateName]; ok {
+ // We have seen this crate already; merge any new dependencies.
+ crate := project.Crates[cInfo.ID]
+ mergeDependencies(ctx, project, knownCrates, module, &crate, cInfo.Deps)
+ return cInfo.ID, crateName, true
+ }
+ crate := rustProjectCrate{Deps: make([]rustProjectDep, 0), Cfgs: make([]string, 0)}
+ src := rustLib.Properties.Srcs[0]
+ crate.RootModule = path.Join(ctx.ModuleDir(rModule), src)
+ crate.Edition = getEdition(rustLib.baseCompiler)
+
+ deps := make(map[string]int)
+ mergeDependencies(ctx, project, knownCrates, module, &crate, deps)
+
+ id := len(project.Crates)
+ knownCrates[crateName] = crateInfo{ID: id, Deps: deps}
+ project.Crates = append(project.Crates, crate)
+ // rust-analyzer requires that all crates belong to at least one root:
+ // https://github.com/rust-analyzer/rust-analyzer/issues/4735.
+ project.Roots = append(project.Roots, path.Dir(crate.RootModule))
+ return id, crateName, true
+}
+
+func (r *projectGeneratorSingleton) GenerateBuildActions(ctx android.SingletonContext) {
+ if !ctx.Config().IsEnvTrue(envVariableCollectRustDeps) {
+ return
+ }
+
+ project := rustProjectJson{}
+ knownCrates := make(map[string]crateInfo)
+ ctx.VisitAllModules(func(module android.Module) {
+ appendLibraryAndDeps(ctx, &project, knownCrates, module)
+ })
+
+ path := android.PathForOutput(ctx, rustProjectJsonFileName)
+ err := createJsonFile(project, path)
+ if err != nil {
+ ctx.Errorf(err.Error())
+ }
+}
+
+func createJsonFile(project rustProjectJson, rustProjectPath android.WritablePath) error {
+ buf, err := json.MarshalIndent(project, "", " ")
+ if err != nil {
+ return fmt.Errorf("JSON marshal of rustProjectJson failed: %s", err)
+ }
+ err = android.WriteFileToOutputDir(rustProjectPath, buf, 0666)
+ if err != nil {
+ return fmt.Errorf("Writing rust-project to %s failed: %s", rustProjectPath.String(), err)
+ }
+ return nil
+}
diff --git a/rust/project_json_test.go b/rust/project_json_test.go
new file mode 100644
index 000000000..6786e72c7
--- /dev/null
+++ b/rust/project_json_test.go
@@ -0,0 +1,55 @@
+// Copyright 2020 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 rust
+
+import (
+ "io/ioutil"
+ "path/filepath"
+ "testing"
+
+ "android/soong/android"
+ "android/soong/cc"
+)
+
+func TestProjectJson(t *testing.T) {
+ bp := `rust_library {
+ name: "liba",
+ srcs: ["src/lib.rs"],
+ crate_name: "a"
+ }` + GatherRequiredDepsForTest()
+ env := map[string]string{"SOONG_GEN_RUST_PROJECT": "1"}
+ fs := map[string][]byte{
+ "foo.rs": nil,
+ "src/lib.rs": nil,
+ }
+
+ cc.GatherRequiredFilesForTest(fs)
+
+ config := android.TestArchConfig(buildDir, env, bp, fs)
+ ctx := CreateTestContext()
+ ctx.Register(config)
+ _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
+ android.FailIfErrored(t, errs)
+ _, errs = ctx.PrepareBuildActions(config)
+ android.FailIfErrored(t, errs)
+
+ // The JSON file is generated via WriteFileToOutputDir. Therefore, it
+ // won't appear in the Output of the TestingSingleton. Manually verify
+ // it exists.
+ _, err := ioutil.ReadFile(filepath.Join(buildDir, "rust-project.json"))
+ if err != nil {
+ t.Errorf("rust-project.json has not been generated")
+ }
+}
diff --git a/rust/test.go b/rust/test.go
index 94568c1cc..10c278597 100644
--- a/rust/test.go
+++ b/rust/test.go
@@ -25,11 +25,11 @@ import (
type TestProperties struct {
// the name of the test configuration (for example "AndroidTest.xml") that should be
// installed with the module.
- Test_config *string `android:"arch_variant"`
+ Test_config *string `android:"path,arch_variant"`
// the name of the test configuration template (for example "AndroidTestTemplate.xml") that
// should be installed with the module.
- Test_config_template *string `android:"arch_variant"`
+ Test_config_template *string `android:"path,arch_variant"`
// list of compatibility suites (for example "cts", "vts") that the module should be
// installed into.
diff --git a/rust/testing.go b/rust/testing.go
index 09008a85f..f94af71ee 100644
--- a/rust/testing.go
+++ b/rust/testing.go
@@ -100,6 +100,7 @@ func CreateTestContext() *android.TestContext {
ctx.BottomUp("rust_unit_tests", TestPerSrcMutator).Parallel()
ctx.BottomUp("rust_begin", BeginMutator).Parallel()
})
+ ctx.RegisterSingletonType("rust_project_generator", rustProjectGeneratorSingleton)
return ctx
}
diff --git a/scripts/build-mainline-modules.sh b/scripts/build-mainline-modules.sh
index f836ea9fa..df763c822 100755
--- a/scripts/build-mainline-modules.sh
+++ b/scripts/build-mainline-modules.sh
@@ -20,6 +20,7 @@ MODULES_SDK_AND_EXPORTS=(
conscrypt-module-test-exports
conscrypt-module-host-exports
runtime-module-sdk
+ runtime-module-host-exports
)
# We want to create apex modules for all supported architectures.
diff --git a/sdk/update.go b/sdk/update.go
index 1ba58064d..824115138 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -22,6 +22,7 @@ import (
"android/soong/apex"
"android/soong/cc"
+
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@@ -700,8 +701,8 @@ func (s *snapshotBuilder) AddPrebuiltModule(member android.SdkMember, moduleType
if apexAware, ok := variant.(interface{ ApexAvailable() []string }); ok {
apexAvailable := apexAware.ApexAvailable()
- // Add in any white listed apex available settings.
- apexAvailable = append(apexAvailable, apex.WhitelistedApexAvailable(member.Name())...)
+ // Add in any baseline apex available settings.
+ apexAvailable = append(apexAvailable, apex.BaselineApexAvailable(member.Name())...)
if len(apexAvailable) > 0 {
// Remove duplicates and sort.
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
index 9276a62e9..7bb267da2 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -70,7 +70,7 @@ type TestProperties struct {
// the name of the test configuration (for example "AndroidTest.xml") that should be
// installed with the module.
- Test_config *string `android:"arch_variant"`
+ Test_config *string `android:"path,arch_variant"`
// list of files or filegroup modules that provide data that should be installed alongside
// the test.
@@ -231,12 +231,8 @@ func (s *ShTest) AndroidMkEntries() []android.AndroidMkEntries {
s.customAndroidMkEntries(entries)
entries.AddStrings("LOCAL_COMPATIBILITY_SUITE", s.testProperties.Test_suites...)
- if s.testProperties.Test_config != nil {
- entries.SetString("LOCAL_TEST_CONFIG", proptools.String(s.testProperties.Test_config))
- } else {
- if s.testConfig != nil {
- entries.SetString("LOCAL_FULL_TEST_CONFIG", s.testConfig.String())
- }
+ if s.testConfig != nil {
+ entries.SetPath("LOCAL_FULL_TEST_CONFIG", s.testConfig)
}
for _, d := range s.data {
rel := d.Rel()
@@ -260,9 +256,6 @@ func InitShBinaryModule(s *ShBinary) {
// executable binary to <partition>/bin.
func ShBinaryFactory() android.Module {
module := &ShBinary{}
- module.Prefer32(func(ctx android.BaseModuleContext, base *android.ModuleBase, class android.OsClass) bool {
- return class == android.Device && ctx.Config().DevicePrefer32BitExecutables()
- })
InitShBinaryModule(module)
android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibFirst)
return module
diff --git a/ui/build/config.go b/ui/build/config.go
index 49f506ef9..c4bbad76f 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -592,6 +592,7 @@ func (c *configImpl) Lunch(ctx Context, product, variant string) {
c.environ.Set("TARGET_BUILD_VARIANT", variant)
c.environ.Set("TARGET_BUILD_TYPE", "release")
c.environ.Unset("TARGET_BUILD_APPS")
+ c.environ.Unset("TARGET_BUILD_UNBUNDLED")
}
// Tapas configures the environment to build one or more unbundled apps,
diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go
index 7dc4915e2..e22985675 100644
--- a/ui/build/dumpvars.go
+++ b/ui/build/dumpvars.go
@@ -143,6 +143,7 @@ var BannerVars = []string{
"TARGET_BUILD_VARIANT",
"TARGET_BUILD_TYPE",
"TARGET_BUILD_APPS",
+ "TARGET_BUILD_UNBUNDLED",
"TARGET_ARCH",
"TARGET_ARCH_VARIANT",
"TARGET_CPU_VARIANT",
@@ -187,6 +188,7 @@ func runMakeProductConfig(ctx Context, config Config) {
"TARGET_PRODUCT",
"TARGET_BUILD_VARIANT",
"TARGET_BUILD_APPS",
+ "TARGET_BUILD_UNBUNDLED",
// compiler wrappers set up by make
"CC_WRAPPER",