Merge "Add default -Wimplicit-fallthrough."
diff --git a/android/arch.go b/android/arch.go
index 95f8803..6516558 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -288,6 +288,30 @@
return target.Os.String() + "_" + target.Arch.String()
}
+// archMutator splits a module into a variant for each Target requested by the module. Target selection
+// for a module is in three levels, OsClass, mulitlib, and then Target.
+// OsClass selection is determined by:
+// - The HostOrDeviceSupported value passed in to InitAndroidArchModule by the module type factory, which selects
+// whether the module type can compile for host, device or both.
+// - The host_supported and device_supported properties on the module.
+// If host is supported for the module, the Host and HostCross OsClasses are are selected. If device is supported
+// for the module, the Device OsClass is selected.
+// Within each selected OsClass, the multilib selection is determined by:
+// - The compile_multilib property if it set (which may be overriden by target.android.compile_multlib or
+// target.host.compile_multilib).
+// - The default multilib passed to InitAndroidArchModule if compile_multilib was not set.
+// 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.
+// "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).
+//
+// Once the list of Targets is determined, the module is split into a variant for each Target.
+//
+// Modules can be initialized with InitAndroidMultiTargetsArchModule, in which case they will be split by OsClass,
+// but will have a common Target that is expected to handle all other selected Targets via ctx.MultiTargets().
func archMutator(mctx BottomUpMutatorContext) {
var module Module
var ok bool
@@ -304,6 +328,7 @@
osClasses := base.OsClassSupported()
var moduleTargets []Target
+ moduleMultiTargets := make(map[int][]Target)
primaryModules := make(map[int]bool)
for _, class := range osClasses {
@@ -311,36 +336,34 @@
if len(classTargets) == 0 {
continue
}
+
// only the primary arch in the recovery partition
if module.InstallInRecovery() {
classTargets = []Target{mctx.Config().Targets[Device][0]}
}
- var multilib string
- switch class {
- case Device:
- multilib = String(base.commonProperties.Target.Android.Compile_multilib)
- case Host, HostCross:
- multilib = String(base.commonProperties.Target.Host.Compile_multilib)
- }
- if multilib == "" {
- multilib = String(base.commonProperties.Compile_multilib)
- }
- if multilib == "" {
- multilib = base.commonProperties.Default_multilib
- }
-
prefer32 := false
if base.prefer32 != nil {
prefer32 = base.prefer32(mctx, base, class)
}
- targets, err := decodeMultilib(multilib, classTargets, prefer32)
+ multilib, extraMultilib := decodeMultilib(base, class)
+ targets, err := decodeMultilibTargets(multilib, classTargets, prefer32)
if err != nil {
mctx.ModuleErrorf("%s", err.Error())
}
+
+ var multiTargets []Target
+ if extraMultilib != "" {
+ multiTargets, err = decodeMultilibTargets(extraMultilib, classTargets, prefer32)
+ if err != nil {
+ mctx.ModuleErrorf("%s", err.Error())
+ }
+ }
+
if len(targets) > 0 {
primaryModules[len(moduleTargets)] = true
+ moduleMultiTargets[len(moduleTargets)] = multiTargets
moduleTargets = append(moduleTargets, targets...)
}
}
@@ -358,11 +381,37 @@
modules := mctx.CreateVariations(targetNames...)
for i, m := range modules {
- m.(Module).base().SetTarget(moduleTargets[i], primaryModules[i])
+ m.(Module).base().SetTarget(moduleTargets[i], moduleMultiTargets[i], primaryModules[i])
m.(Module).base().setArchProperties(mctx)
}
}
+func decodeMultilib(base *ModuleBase, class OsClass) (multilib, extraMultilib string) {
+ switch class {
+ case Device:
+ multilib = String(base.commonProperties.Target.Android.Compile_multilib)
+ case Host, HostCross:
+ multilib = String(base.commonProperties.Target.Host.Compile_multilib)
+ }
+ if multilib == "" {
+ multilib = String(base.commonProperties.Compile_multilib)
+ }
+ if multilib == "" {
+ multilib = base.commonProperties.Default_multilib
+ }
+
+ if base.commonProperties.UseTargetVariants {
+ return multilib, ""
+ } else {
+ // For app modules a single arch variant will be created per OS class which is expected to handle all the
+ // selected arches. Return the common-type as multilib and any Android.bp provided multilib as extraMultilib
+ if multilib == base.commonProperties.Default_multilib {
+ multilib = "first"
+ }
+ return base.commonProperties.Default_multilib, multilib
+ }
+}
+
func filterArchStruct(prop reflect.Type) (reflect.Type, bool) {
var fields []reflect.StructField
@@ -1114,7 +1163,7 @@
}
// Use the module multilib setting to select one or more targets from a target list
-func decodeMultilib(multilib string, targets []Target, prefer32 bool) ([]Target, error) {
+func decodeMultilibTargets(multilib string, targets []Target, prefer32 bool) ([]Target, error) {
buildTargets := []Target{}
switch multilib {
diff --git a/android/module.go b/android/module.go
index 01766b4..9d9d9a9 100644
--- a/android/module.go
+++ b/android/module.go
@@ -58,6 +58,7 @@
type androidBaseContext interface {
Target() Target
TargetPrimary() bool
+ MultiTargets() []Target
Arch() Arch
Os() OsType
Host() bool
@@ -215,7 +216,8 @@
}
}
- Default_multilib string `blueprint:"mutated"`
+ UseTargetVariants bool `blueprint:"mutated"`
+ Default_multilib string `blueprint:"mutated"`
// whether this is a proprietary vendor module, and should be installed into /vendor
Proprietary *bool
@@ -264,8 +266,9 @@
Notice *string
// Set by TargetMutator
- CompileTarget Target `blueprint:"mutated"`
- CompilePrimary bool `blueprint:"mutated"`
+ CompileTarget Target `blueprint:"mutated"`
+ CompileMultiTargets []Target `blueprint:"mutated"`
+ CompilePrimary bool `blueprint:"mutated"`
// Set by InitAndroidModule
HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
@@ -362,6 +365,7 @@
base.commonProperties.HostOrDeviceSupported = hod
base.commonProperties.Default_multilib = string(defaultMultilib)
base.commonProperties.ArchSpecific = true
+ base.commonProperties.UseTargetVariants = true
switch hod {
case HostAndDeviceSupported, HostAndDeviceDefault:
@@ -371,6 +375,11 @@
InitArchModule(m)
}
+func InitAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
+ InitAndroidArchModule(m, hod, defaultMultilib)
+ m.base().commonProperties.UseTargetVariants = false
+}
+
// A ModuleBase object contains the properties that are common to all Android
// modules. It should be included as an anonymous field in every module
// struct definition. InitAndroidModule should then be called from the module's
@@ -477,8 +486,9 @@
return a
}
-func (a *ModuleBase) SetTarget(target Target, primary bool) {
+func (a *ModuleBase) SetTarget(target Target, multiTargets []Target, primary bool) {
a.commonProperties.CompileTarget = target
+ a.commonProperties.CompileMultiTargets = multiTargets
a.commonProperties.CompilePrimary = primary
}
@@ -490,6 +500,10 @@
return a.commonProperties.CompilePrimary
}
+func (a *ModuleBase) MultiTargets() []Target {
+ return a.commonProperties.CompileMultiTargets
+}
+
func (a *ModuleBase) Os() OsType {
return a.Target().Os
}
@@ -731,6 +745,7 @@
return androidBaseContextImpl{
target: a.commonProperties.CompileTarget,
targetPrimary: a.commonProperties.CompilePrimary,
+ multiTargets: a.commonProperties.CompileMultiTargets,
kind: determineModuleKind(a, ctx),
config: ctx.Config().(Config),
}
@@ -785,6 +800,7 @@
type androidBaseContextImpl struct {
target Target
+ multiTargets []Target
targetPrimary bool
debug bool
kind moduleKind
@@ -1022,6 +1038,10 @@
return a.targetPrimary
}
+func (a *androidBaseContextImpl) MultiTargets() []Target {
+ return a.multiTargets
+}
+
func (a *androidBaseContextImpl) Arch() Arch {
return a.target.Arch
}
diff --git a/cc/cc.go b/cc/cc.go
index d04485d..640c552 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -35,11 +35,11 @@
android.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
ctx.BottomUp("image", imageMutator).Parallel()
- ctx.BottomUp("link", linkageMutator).Parallel()
+ ctx.BottomUp("link", LinkageMutator).Parallel()
ctx.BottomUp("vndk", vndkMutator).Parallel()
ctx.BottomUp("ndk_api", ndkApiMutator).Parallel()
ctx.BottomUp("test_per_src", testPerSrcMutator).Parallel()
- ctx.BottomUp("begin", beginMutator).Parallel()
+ ctx.BottomUp("begin", BeginMutator).Parallel()
})
android.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
@@ -1093,7 +1093,7 @@
}
}
-func beginMutator(ctx android.BottomUpMutatorContext) {
+func BeginMutator(ctx android.BottomUpMutatorContext) {
if c, ok := ctx.Module().(*Module); ok && c.Enabled() {
c.beginMutator(ctx)
}
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 01beb66..bca26ea 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -56,17 +56,17 @@
ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(LibraryFactory))
ctx.RegisterModuleType("cc_library_shared", android.ModuleFactoryAdaptor(LibrarySharedFactory))
ctx.RegisterModuleType("cc_library_headers", android.ModuleFactoryAdaptor(LibraryHeaderFactory))
- ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(toolchainLibraryFactory))
+ ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(ToolchainLibraryFactory))
ctx.RegisterModuleType("llndk_library", android.ModuleFactoryAdaptor(llndkLibraryFactory))
ctx.RegisterModuleType("llndk_headers", android.ModuleFactoryAdaptor(llndkHeadersFactory))
ctx.RegisterModuleType("vendor_public_library", android.ModuleFactoryAdaptor(vendorPublicLibraryFactory))
- ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(objectFactory))
+ ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(ObjectFactory))
ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(android.FileGroupFactory))
ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
ctx.BottomUp("image", imageMutator).Parallel()
- ctx.BottomUp("link", linkageMutator).Parallel()
+ ctx.BottomUp("link", LinkageMutator).Parallel()
ctx.BottomUp("vndk", vndkMutator).Parallel()
- ctx.BottomUp("begin", beginMutator).Parallel()
+ ctx.BottomUp("begin", BeginMutator).Parallel()
})
ctx.Register()
diff --git a/cc/library.go b/cc/library.go
index 0e45af9..4f9b5b2 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -821,7 +821,7 @@
}
}
-func linkageMutator(mctx android.BottomUpMutatorContext) {
+func LinkageMutator(mctx android.BottomUpMutatorContext) {
if m, ok := mctx.Module().(*Module); ok && m.linker != nil {
if library, ok := m.linker.(libraryInterface); ok {
var modules []blueprint.Module
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index 2709a89..63d9f29 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -61,7 +61,7 @@
// These libraries have migrated over to the new ndk_library, which is added
// as a variation dependency via depsMutator.
ndkMigratedLibs = []string{}
- ndkMigratedLibsLock sync.Mutex // protects ndkMigratedLibs writes during parallel beginMutator
+ ndkMigratedLibsLock sync.Mutex // protects ndkMigratedLibs writes during parallel BeginMutator
)
// Creates a stub shared library based on the provided version file.
diff --git a/cc/object.go b/cc/object.go
index 7c134ac..2577195 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -25,7 +25,7 @@
//
func init() {
- android.RegisterModuleType("cc_object", objectFactory)
+ android.RegisterModuleType("cc_object", ObjectFactory)
}
type objectLinker struct {
@@ -33,7 +33,7 @@
Properties ObjectLinkerProperties
}
-func objectFactory() android.Module {
+func ObjectFactory() android.Module {
module := newBaseModule(android.HostAndDeviceSupported, android.MultilibBoth)
module.linker = &objectLinker{
baseLinker: NewBaseLinker(nil),
diff --git a/cc/toolchain_library.go b/cc/toolchain_library.go
index 20b0f85..742d1c1 100644
--- a/cc/toolchain_library.go
+++ b/cc/toolchain_library.go
@@ -23,7 +23,7 @@
//
func init() {
- android.RegisterModuleType("toolchain_library", toolchainLibraryFactory)
+ android.RegisterModuleType("toolchain_library", ToolchainLibraryFactory)
}
type toolchainLibraryProperties struct {
@@ -48,7 +48,7 @@
return append(props, &library.Properties)
}
-func toolchainLibraryFactory() android.Module {
+func ToolchainLibraryFactory() android.Module {
module, library := NewLibrary(android.HostAndDeviceSupported)
library.BuildOnlyStatic()
toolchainLibrary := &toolchainLibraryDecorator{
diff --git a/cmd/zip2zip/zip2zip.go b/cmd/zip2zip/zip2zip.go
index e8ea9b9..d3b349c 100644
--- a/cmd/zip2zip/zip2zip.go
+++ b/cmd/zip2zip/zip2zip.go
@@ -17,6 +17,7 @@
import (
"flag"
"fmt"
+ "io"
"log"
"os"
"path/filepath"
@@ -39,11 +40,13 @@
staticTime = time.Date(2009, 1, 1, 0, 0, 0, 0, time.UTC)
- excludes excludeArgs
+ excludes multiFlag
+ uncompress multiFlag
)
func init() {
flag.Var(&excludes, "x", "exclude a filespec from the output")
+ flag.Var(&uncompress, "0", "convert a filespec to uncompressed in the output")
}
func main() {
@@ -93,7 +96,7 @@
}()
if err := zip2zip(&reader.Reader, writer, *sortGlobs, *sortJava, *setTime,
- flag.Args(), excludes); err != nil {
+ flag.Args(), excludes, uncompress); err != nil {
log.Fatal(err)
}
@@ -101,11 +104,12 @@
type pair struct {
*zip.File
- newName string
+ newName string
+ uncompress bool
}
func zip2zip(reader *zip.Reader, writer *zip.Writer, sortOutput, sortJava, setTime bool,
- includes []string, excludes []string) error {
+ includes, excludes, uncompresses []string) error {
matches := []pair{}
@@ -149,7 +153,7 @@
newName = output
}
}
- includeMatches = append(includeMatches, pair{file, newName})
+ includeMatches = append(includeMatches, pair{file, newName, false})
}
}
@@ -160,7 +164,7 @@
if len(includes) == 0 {
// implicitly match everything
for _, file := range reader.File {
- matches = append(matches, pair{file, file.Name})
+ matches = append(matches, pair{file, file.Name, false})
}
sortMatches(matches)
}
@@ -193,6 +197,15 @@
}
seen[match.newName] = match.File
+ for _, u := range uncompresses {
+ if uncompressMatch, err := pathtools.Match(u, match.newName); err != nil {
+ return err
+ } else if uncompressMatch {
+ match.uncompress = true
+ break
+ }
+ }
+
matchesAfterExcludes = append(matchesAfterExcludes, match)
}
@@ -200,8 +213,32 @@
if setTime {
match.File.SetModTime(staticTime)
}
- if err := writer.CopyFrom(match.File, match.newName); err != nil {
- return err
+ if match.uncompress && match.File.FileHeader.Method != zip.Store {
+ fh := match.File.FileHeader
+ fh.Name = match.newName
+ fh.Method = zip.Store
+ fh.CompressedSize64 = fh.UncompressedSize64
+
+ zw, err := writer.CreateHeaderAndroid(&fh)
+ if err != nil {
+ return err
+ }
+
+ zr, err := match.File.Open()
+ if err != nil {
+ return err
+ }
+
+ _, err = io.Copy(zw, zr)
+ zr.Close()
+ if err != nil {
+ return err
+ }
+ } else {
+ err := writer.CopyFrom(match.File, match.newName)
+ if err != nil {
+ return err
+ }
}
}
@@ -217,13 +254,13 @@
}
}
-type excludeArgs []string
+type multiFlag []string
-func (e *excludeArgs) String() string {
+func (e *multiFlag) String() string {
return strings.Join(*e, " ")
}
-func (e *excludeArgs) Set(s string) error {
+func (e *multiFlag) Set(s string) error {
*e = append(*e, s)
return nil
}
diff --git a/cmd/zip2zip/zip2zip_test.go b/cmd/zip2zip/zip2zip_test.go
index 212ab28..e032fe6 100644
--- a/cmd/zip2zip/zip2zip_test.go
+++ b/cmd/zip2zip/zip2zip_test.go
@@ -26,13 +26,15 @@
var testCases = []struct {
name string
- inputFiles []string
- sortGlobs bool
- sortJava bool
- args []string
- excludes []string
+ inputFiles []string
+ sortGlobs bool
+ sortJava bool
+ args []string
+ excludes []string
+ uncompresses []string
outputFiles []string
+ storedFiles []string
err error
}{
{
@@ -251,6 +253,79 @@
outputFiles: nil,
},
+ {
+ name: "uncompress one",
+
+ inputFiles: []string{
+ "a/a",
+ "a/b",
+ },
+ uncompresses: []string{"a/a"},
+
+ outputFiles: []string{
+ "a/a",
+ "a/b",
+ },
+ storedFiles: []string{
+ "a/a",
+ },
+ },
+ {
+ name: "uncompress two",
+
+ inputFiles: []string{
+ "a/a",
+ "a/b",
+ },
+ uncompresses: []string{"a/a", "a/b"},
+
+ outputFiles: []string{
+ "a/a",
+ "a/b",
+ },
+ storedFiles: []string{
+ "a/a",
+ "a/b",
+ },
+ },
+ {
+ name: "uncompress glob",
+
+ inputFiles: []string{
+ "a/a",
+ "a/b",
+ "a/c.so",
+ "a/d.so",
+ },
+ uncompresses: []string{"a/*.so"},
+
+ outputFiles: []string{
+ "a/a",
+ "a/b",
+ "a/c.so",
+ "a/d.so",
+ },
+ storedFiles: []string{
+ "a/c.so",
+ "a/d.so",
+ },
+ },
+ {
+ name: "uncompress rename",
+
+ inputFiles: []string{
+ "a/a",
+ },
+ args: []string{"a/a:a/b"},
+ uncompresses: []string{"a/b"},
+
+ outputFiles: []string{
+ "a/b",
+ },
+ storedFiles: []string{
+ "a/b",
+ },
+ },
}
func errorString(e error) string {
@@ -282,7 +357,8 @@
}
outputWriter := zip.NewWriter(outputBuf)
- err = zip2zip(inputReader, outputWriter, testCase.sortGlobs, testCase.sortJava, false, testCase.args, testCase.excludes)
+ err = zip2zip(inputReader, outputWriter, testCase.sortGlobs, testCase.sortJava, false,
+ testCase.args, testCase.excludes, testCase.uncompresses)
if errorString(testCase.err) != errorString(err) {
t.Fatalf("Unexpected error:\n got: %q\nwant: %q", errorString(err), errorString(testCase.err))
}
@@ -294,15 +370,22 @@
t.Fatal(err)
}
var outputFiles []string
+ var storedFiles []string
if len(outputReader.File) > 0 {
outputFiles = make([]string, len(outputReader.File))
for i, file := range outputReader.File {
outputFiles[i] = file.Name
+ if file.Method == zip.Store {
+ storedFiles = append(storedFiles, file.Name)
+ }
}
}
if !reflect.DeepEqual(testCase.outputFiles, outputFiles) {
- t.Fatalf("Output file list does not match:\n got: %v\nwant: %v", outputFiles, testCase.outputFiles)
+ t.Fatalf("Output file list does not match:\nwant: %v\n got: %v", testCase.outputFiles, outputFiles)
+ }
+ if !reflect.DeepEqual(testCase.storedFiles, storedFiles) {
+ t.Fatalf("Stored file list does not match:\nwant: %v\n got: %v", testCase.storedFiles, storedFiles)
}
})
}