diff options
| -rw-r--r-- | Android.bp | 1 | ||||
| -rw-r--r-- | android/mutator.go | 26 | ||||
| -rw-r--r-- | android/mutator_test.go | 110 | ||||
| -rw-r--r-- | android/register.go | 7 | ||||
| -rw-r--r-- | android/testing.go | 12 | ||||
| -rw-r--r-- | apex/androidmk.go | 37 | ||||
| -rw-r--r-- | apex/apex.go | 62 | ||||
| -rw-r--r-- | apex/apex_test.go | 164 | ||||
| -rw-r--r-- | apex/builder.go | 62 | ||||
| -rw-r--r-- | cc/cc_test.go | 4 | ||||
| -rw-r--r-- | cc/config/global.go | 4 | ||||
| -rw-r--r-- | cc/linker.go | 3 | ||||
| -rw-r--r-- | cc/stl.go | 10 | ||||
| -rw-r--r-- | cc/testing.go | 3 | ||||
| -rw-r--r-- | docs/perf.md | 96 | ||||
| -rw-r--r-- | genrule/genrule.go | 16 | ||||
| -rw-r--r-- | genrule/genrule_test.go | 6 | ||||
| -rw-r--r-- | java/android_manifest.go | 14 | ||||
| -rw-r--r-- | java/sdk.go | 20 | ||||
| -rw-r--r-- | python/python.go | 5 |
20 files changed, 524 insertions, 138 deletions
diff --git a/Android.bp b/Android.bp index 0382ee2ed..ab03a36f1 100644 --- a/Android.bp +++ b/Android.bp @@ -596,6 +596,7 @@ toolchain_library { vendor_available: true, recovery_available: true, native_bridge_supported: true, + sdk_version: "current", arch: { arm: { diff --git a/android/mutator.go b/android/mutator.go index f2f966399..3d1bb4f7d 100644 --- a/android/mutator.go +++ b/android/mutator.go @@ -27,6 +27,7 @@ import ( // run Pre-deps mutators // run depsMutator // run PostDeps mutators +// run FinalDeps mutators (CreateVariations disallowed in this phase) // continue on to GenerateAndroidBuildActions func registerMutatorsToContext(ctx *blueprint.Context, mutators []*mutator) { @@ -43,7 +44,7 @@ func registerMutatorsToContext(ctx *blueprint.Context, mutators []*mutator) { } } -func registerMutators(ctx *blueprint.Context, preArch, preDeps, postDeps []RegisterMutatorFunc) { +func registerMutators(ctx *blueprint.Context, preArch, preDeps, postDeps, finalDeps []RegisterMutatorFunc) { mctx := ®isterMutatorsContext{} register := func(funcs []RegisterMutatorFunc) { @@ -60,11 +61,15 @@ func registerMutators(ctx *blueprint.Context, preArch, preDeps, postDeps []Regis register(postDeps) + mctx.finalPhase = true + register(finalDeps) + registerMutatorsToContext(ctx, mctx.mutators) } type registerMutatorsContext struct { - mutators []*mutator + mutators []*mutator + finalPhase bool } type RegisterMutatorsContext interface { @@ -102,6 +107,8 @@ var postDeps = []RegisterMutatorFunc{ RegisterOverridePostDepsMutators, } +var finalDeps = []RegisterMutatorFunc{} + func PreArchMutators(f RegisterMutatorFunc) { preArch = append(preArch, f) } @@ -114,6 +121,10 @@ func PostDepsMutators(f RegisterMutatorFunc) { postDeps = append(postDeps, f) } +func FinalDepsMutators(f RegisterMutatorFunc) { + finalDeps = append(finalDeps, f) +} + type TopDownMutator func(TopDownMutatorContext) type TopDownMutatorContext interface { @@ -156,14 +167,17 @@ type BottomUpMutatorContext interface { type bottomUpMutatorContext struct { bp blueprint.BottomUpMutatorContext baseModuleContext + finalPhase bool } func (x *registerMutatorsContext) BottomUp(name string, m BottomUpMutator) MutatorHandle { + finalPhase := x.finalPhase f := func(ctx blueprint.BottomUpMutatorContext) { if a, ok := ctx.Module().(Module); ok { actx := &bottomUpMutatorContext{ bp: ctx, baseModuleContext: a.base().baseModuleContextFactory(ctx), + finalPhase: finalPhase, } m(actx) } @@ -285,6 +299,10 @@ func (b *bottomUpMutatorContext) AddReverseDependency(module blueprint.Module, t } func (b *bottomUpMutatorContext) CreateVariations(variations ...string) []Module { + if b.finalPhase { + panic("CreateVariations not allowed in FinalDepsMutators") + } + modules := b.bp.CreateVariations(variations...) aModules := make([]Module, len(modules)) @@ -299,6 +317,10 @@ func (b *bottomUpMutatorContext) CreateVariations(variations ...string) []Module } func (b *bottomUpMutatorContext) CreateLocalVariations(variations ...string) []Module { + if b.finalPhase { + panic("CreateLocalVariations not allowed in FinalDepsMutators") + } + modules := b.bp.CreateLocalVariations(variations...) aModules := make([]Module, len(modules)) diff --git a/android/mutator_test.go b/android/mutator_test.go index d179f9d4b..191b535a3 100644 --- a/android/mutator_test.go +++ b/android/mutator_test.go @@ -15,9 +15,12 @@ package android import ( + "fmt" "reflect" + "strings" "testing" + "github.com/google/blueprint" "github.com/google/blueprint/proptools" ) @@ -185,3 +188,110 @@ func TestModuleString(t *testing.T) { t.Errorf("want module String() values:\n%q\ngot:\n%q", want, moduleStrings) } } + +func TestFinalDepsPhase(t *testing.T) { + ctx := NewTestContext() + + finalGot := map[string]int{} + + dep1Tag := struct { + blueprint.BaseDependencyTag + }{} + dep2Tag := struct { + blueprint.BaseDependencyTag + }{} + + ctx.PostDepsMutators(func(ctx RegisterMutatorsContext) { + ctx.BottomUp("far_deps_1", func(ctx BottomUpMutatorContext) { + if !strings.HasPrefix(ctx.ModuleName(), "common_dep") { + ctx.AddFarVariationDependencies([]blueprint.Variation{}, dep1Tag, "common_dep_1") + } + }) + ctx.BottomUp("variant", func(ctx BottomUpMutatorContext) { + ctx.CreateLocalVariations("a", "b") + }) + }) + + ctx.FinalDepsMutators(func(ctx RegisterMutatorsContext) { + ctx.BottomUp("far_deps_2", func(ctx BottomUpMutatorContext) { + if !strings.HasPrefix(ctx.ModuleName(), "common_dep") { + ctx.AddFarVariationDependencies([]blueprint.Variation{}, dep2Tag, "common_dep_2") + } + }) + ctx.BottomUp("final", func(ctx BottomUpMutatorContext) { + finalGot[ctx.Module().String()] += 1 + ctx.VisitDirectDeps(func(mod Module) { + finalGot[fmt.Sprintf("%s -> %s", ctx.Module().String(), mod)] += 1 + }) + }) + }) + + ctx.RegisterModuleType("test", mutatorTestModuleFactory) + + bp := ` + test { + name: "common_dep_1", + } + test { + name: "common_dep_2", + } + test { + name: "foo", + } + ` + + config := TestConfig(buildDir, nil, bp, nil) + ctx.Register(config) + + _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) + FailIfErrored(t, errs) + _, errs = ctx.PrepareBuildActions(config) + FailIfErrored(t, errs) + + finalWant := map[string]int{ + "common_dep_1{variant:a}": 1, + "common_dep_1{variant:b}": 1, + "common_dep_2{variant:a}": 1, + "common_dep_2{variant:b}": 1, + "foo{variant:a}": 1, + "foo{variant:a} -> common_dep_1{variant:a}": 1, + "foo{variant:a} -> common_dep_2{variant:a}": 1, + "foo{variant:b}": 1, + "foo{variant:b} -> common_dep_1{variant:b}": 1, + "foo{variant:b} -> common_dep_2{variant:a}": 1, + } + + if !reflect.DeepEqual(finalWant, finalGot) { + t.Errorf("want:\n%q\ngot:\n%q", finalWant, finalGot) + } +} + +func TestNoCreateVariationsInFinalDeps(t *testing.T) { + ctx := NewTestContext() + + checkErr := func() { + if err := recover(); err == nil || !strings.Contains(fmt.Sprintf("%s", err), "not allowed in FinalDepsMutators") { + panic("Expected FinalDepsMutators consistency check to fail") + } + } + + ctx.FinalDepsMutators(func(ctx RegisterMutatorsContext) { + ctx.BottomUp("vars", func(ctx BottomUpMutatorContext) { + defer checkErr() + ctx.CreateVariations("a", "b") + }) + ctx.BottomUp("local_vars", func(ctx BottomUpMutatorContext) { + defer checkErr() + ctx.CreateLocalVariations("a", "b") + }) + }) + + ctx.RegisterModuleType("test", mutatorTestModuleFactory) + config := TestConfig(buildDir, nil, `test {name: "foo"}`, nil) + ctx.Register(config) + + _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) + FailIfErrored(t, errs) + _, errs = ctx.PrepareBuildActions(config) + FailIfErrored(t, errs) +} diff --git a/android/register.go b/android/register.go index d5aa1a537..ccfe01e74 100644 --- a/android/register.go +++ b/android/register.go @@ -102,7 +102,7 @@ func (ctx *Context) Register() { ctx.RegisterSingletonType(t.name, t.factory) } - registerMutators(ctx.Context, preArch, preDeps, postDeps) + registerMutators(ctx.Context, preArch, preDeps, postDeps, finalDeps) // Register makevars after other singletons so they can export values through makevars ctx.RegisterSingletonType("makevars", SingletonFactoryAdaptor(makeVarsSingletonFunc)) @@ -135,6 +135,7 @@ type RegistrationContext interface { PreDepsMutators(f RegisterMutatorFunc) PostDepsMutators(f RegisterMutatorFunc) + FinalDepsMutators(f RegisterMutatorFunc) } // Used to register build components from an init() method, e.g. @@ -197,3 +198,7 @@ func (ctx *initRegistrationContext) PreDepsMutators(f RegisterMutatorFunc) { func (ctx *initRegistrationContext) PostDepsMutators(f RegisterMutatorFunc) { PostDepsMutators(f) } + +func (ctx *initRegistrationContext) FinalDepsMutators(f RegisterMutatorFunc) { + FinalDepsMutators(f) +} diff --git a/android/testing.go b/android/testing.go index c07af7f32..9aff03940 100644 --- a/android/testing.go +++ b/android/testing.go @@ -50,9 +50,9 @@ func NewTestArchContext() *TestContext { type TestContext struct { *Context - preArch, preDeps, postDeps []RegisterMutatorFunc - NameResolver *NameResolver - config Config + preArch, preDeps, postDeps, finalDeps []RegisterMutatorFunc + NameResolver *NameResolver + config Config } func (ctx *TestContext) PreArchMutators(f RegisterMutatorFunc) { @@ -72,12 +72,16 @@ func (ctx *TestContext) PostDepsMutators(f RegisterMutatorFunc) { ctx.postDeps = append(ctx.postDeps, f) } +func (ctx *TestContext) FinalDepsMutators(f RegisterMutatorFunc) { + ctx.finalDeps = append(ctx.finalDeps, f) +} + func (ctx *TestContext) Register(config Config) { ctx.SetFs(config.fs) if config.mockBpList != "" { ctx.SetModuleListFile(config.mockBpList) } - registerMutators(ctx.Context.Context, ctx.preArch, ctx.preDeps, ctx.postDeps) + registerMutators(ctx.Context.Context, ctx.preArch, ctx.preDeps, ctx.postDeps, ctx.finalDeps) ctx.RegisterSingletonType("env", EnvSingleton) diff --git a/apex/androidmk.go b/apex/androidmk.go index ad7d2f142..f1194be71 100644 --- a/apex/androidmk.go +++ b/apex/androidmk.go @@ -52,13 +52,40 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, apexName, moduleDir string) return moduleNames } + var postInstallCommands []string + for _, fi := range a.filesInfo { + if a.linkToSystemLib && fi.transitiveDep && fi.AvailableToPlatform() { + // TODO(jiyong): pathOnDevice should come from fi.module, not being calculated here + linkTarget := filepath.Join("/system", fi.Path()) + linkPath := filepath.Join(a.installDir.ToMakePath().String(), apexName, fi.Path()) + mkdirCmd := "mkdir -p " + filepath.Dir(linkPath) + linkCmd := "ln -sfn " + linkTarget + " " + linkPath + postInstallCommands = append(postInstallCommands, mkdirCmd, linkCmd) + } + } + postInstallCommands = append(postInstallCommands, a.compatSymlinks...) + for _, fi := range a.filesInfo { if cc, ok := fi.module.(*cc.Module); ok && cc.Properties.HideFromMake { continue } - if !android.InList(fi.moduleName, moduleNames) { - moduleNames = append(moduleNames, fi.moduleName) + linkToSystemLib := a.linkToSystemLib && fi.transitiveDep && fi.AvailableToPlatform() + + var moduleName string + if linkToSystemLib { + moduleName = fi.moduleName + } else { + moduleName = fi.moduleName + "." + apexName + a.suffix + } + + if !android.InList(moduleName, moduleNames) { + moduleNames = append(moduleNames, moduleName) + } + + if linkToSystemLib { + // No need to copy the file since it's linked to the system file + continue } fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)") @@ -67,7 +94,7 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, apexName, moduleDir string) } else { fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir) } - fmt.Fprintln(w, "LOCAL_MODULE :=", fi.moduleName) + fmt.Fprintln(w, "LOCAL_MODULE :=", moduleName) // /apex/<apex_name>/{lib|framework|...} pathWhenActivated := filepath.Join("$(PRODUCT_OUT)", "apex", apexName, fi.installDir) if apexType == flattenedApex { @@ -160,9 +187,9 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, apexName, moduleDir string) } fmt.Fprintln(w, "LOCAL_OVERRIDES_MODULES :=", strings.Join(patterns, " ")) - if len(a.compatSymlinks) > 0 { + if apexType == flattenedApex && len(postInstallCommands) > 0 { // For flattened apexes, compat symlinks are attached to apex_manifest.json which is guaranteed for every apex - fmt.Fprintln(w, "LOCAL_POST_INSTALL_CMD :=", strings.Join(a.compatSymlinks, " && ")) + fmt.Fprintln(w, "LOCAL_POST_INSTALL_CMD :=", strings.Join(postInstallCommands, " && ")) } } fmt.Fprintln(w, "include $(BUILD_PREBUILT)") diff --git a/apex/apex.go b/apex/apex.go index 33b1be329..d908cd328 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -733,6 +733,30 @@ func (af *apexFile) Ok() bool { return af.builtFile != nil && af.builtFile.String() != "" } +// Path() returns path of this apex file relative to the APEX root +func (af *apexFile) Path() string { + return filepath.Join(af.installDir, af.builtFile.Base()) +} + +// SymlinkPaths() returns paths of the symlinks (if any) relative to the APEX root +func (af *apexFile) SymlinkPaths() []string { + var ret []string + for _, symlink := range af.symlinks { + ret = append(ret, filepath.Join(af.installDir, symlink)) + } + return ret +} + +func (af *apexFile) AvailableToPlatform() bool { + if af.module == nil { + return false + } + if am, ok := af.module.(android.ApexModule); ok { + return am.AvailableFor(android.AvailableToPlatform) + } + return false +} + type apexBundle struct { android.ModuleBase android.DefaultableModuleBase @@ -790,6 +814,10 @@ type apexBundle struct { suffix string installedFilesFile android.WritablePath + + // Whether to create symlink to the system file instead of having a file + // inside the apex or not + linkToSystemLib bool } func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, @@ -1414,7 +1442,8 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { // of the original test module (`depName`, shared by all `test_per_src` // variations of that module). af.moduleName = filepath.Base(af.builtFile.String()) - af.transitiveDep = true + // these are not considered transitive dep + af.transitiveDep = false filesInfo = append(filesInfo, af) return true // track transitive dependencies } @@ -1452,15 +1481,22 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { // remove duplicates in filesInfo removeDup := func(filesInfo []apexFile) []apexFile { - encountered := make(map[string]bool) - result := []apexFile{} + encountered := make(map[string]apexFile) for _, f := range filesInfo { dest := filepath.Join(f.installDir, f.builtFile.Base()) - if !encountered[dest] { - encountered[dest] = true - result = append(result, f) + if e, ok := encountered[dest]; !ok { + encountered[dest] = f + } else { + // If a module is directly included and also transitively depended on + // consider it as directly included. + e.transitiveDep = e.transitiveDep && f.transitiveDep + encountered[dest] = e } } + var result []apexFile + for _, v := range encountered { + result = append(result, v) + } return result } filesInfo = removeDup(filesInfo) @@ -1487,12 +1523,6 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { } } - // prepend the name of this APEX to the module names. These names will be the names of - // modules that will be defined if the APEX is flattened. - for i := range filesInfo { - filesInfo[i].moduleName = filesInfo[i].moduleName + "." + a.Name() + a.suffix - } - a.installDir = android.PathForModuleInstall(ctx, "apex") a.filesInfo = filesInfo @@ -1512,6 +1542,14 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { return } } + // Optimization. If we are building bundled APEX, for the files that are gathered due to the + // transitive dependencies, don't place them inside the APEX, but place a symlink pointing + // the same library in the system partition, thus effectively sharing the same libraries + // across the APEX boundary. For unbundled APEX, all the gathered files are actually placed + // in the APEX. + a.linkToSystemLib = !ctx.Config().UnbundledBuild() && + a.installable() && + !proptools.Bool(a.properties.Use_vendor) // prepare apex_manifest.json a.buildManifest(ctx, provideNativeLibs, requireNativeLibs) diff --git a/apex/apex_test.go b/apex/apex_test.go index 2103b6ebd..1a9b95cea 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -91,6 +91,10 @@ func withBinder32bit(fs map[string][]byte, config android.Config) { config.TestProductVariables.Binder32bit = proptools.BoolPtr(true) } +func withUnbundledBuild(fs map[string][]byte, config android.Config) { + config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true) +} + func testApexContext(t *testing.T, bp string, handlers ...testCustomizer) (*android.TestContext, android.Config) { android.ClearApexDependency() @@ -516,7 +520,7 @@ func TestBasicApex(t *testing.T) { found_foo_link_64 := false found_foo := false for _, cmd := range strings.Split(copyCmds, " && ") { - if strings.HasPrefix(cmd, "ln -s foo64") { + if strings.HasPrefix(cmd, "ln -sfn foo64") { if strings.HasSuffix(cmd, "bin/foo") { found_foo = true } else if strings.HasSuffix(cmd, "bin/foo_link_64") { @@ -1597,46 +1601,68 @@ func TestHeaderLibsDependency(t *testing.T) { ensureContains(t, cFlags, "-Imy_include") } -func ensureExactContents(t *testing.T, ctx *android.TestContext, moduleName string, files []string) { +type fileInApex struct { + path string // path in apex + isLink bool +} + +func getFiles(t *testing.T, ctx *android.TestContext, moduleName string) []fileInApex { t.Helper() apexRule := ctx.ModuleForTests(moduleName, "android_common_"+moduleName+"_image").Rule("apexRule") copyCmds := apexRule.Args["copy_commands"] imageApexDir := "/image.apex/" - var failed bool - var surplus []string - filesMatched := make(map[string]bool) - addContent := func(content string) { - for _, expected := range files { - if matched, _ := path.Match(expected, content); matched { - filesMatched[expected] = true - return - } - } - surplus = append(surplus, content) - } + var ret []fileInApex for _, cmd := range strings.Split(copyCmds, "&&") { cmd = strings.TrimSpace(cmd) if cmd == "" { continue } terms := strings.Split(cmd, " ") + var dst string + var isLink bool switch terms[0] { case "mkdir": case "cp": - if len(terms) != 3 { + if len(terms) != 3 && len(terms) != 4 { t.Fatal("copyCmds contains invalid cp command", cmd) } - dst := terms[2] + dst = terms[len(terms)-1] + isLink = false + case "ln": + if len(terms) != 3 && len(terms) != 4 { + // ln LINK TARGET or ln -s LINK TARGET + t.Fatal("copyCmds contains invalid ln command", cmd) + } + dst = terms[len(terms)-1] + isLink = true + default: + t.Fatalf("copyCmds should contain mkdir/cp commands only: %q", cmd) + } + if dst != "" { index := strings.Index(dst, imageApexDir) if index == -1 { t.Fatal("copyCmds should copy a file to image.apex/", cmd) } dstFile := dst[index+len(imageApexDir):] - addContent(dstFile) - default: - t.Fatalf("copyCmds should contain mkdir/cp commands only: %q", cmd) + ret = append(ret, fileInApex{path: dstFile, isLink: isLink}) } } + return ret +} + +func ensureExactContents(t *testing.T, ctx *android.TestContext, moduleName string, files []string) { + var failed bool + var surplus []string + filesMatched := make(map[string]bool) + for _, file := range getFiles(t, ctx, moduleName) { + for _, expected := range files { + if matched, _ := path.Match(expected, file.path); matched { + filesMatched[expected] = true + return + } + } + surplus = append(surplus, file.path) + } if len(surplus) > 0 { sort.Strings(surplus) @@ -3481,6 +3507,106 @@ func TestCarryRequiredModuleNames(t *testing.T) { ensureContains(t, androidMk, "LOCAL_TARGET_REQUIRED_MODULES += e f\n") } +func TestSymlinksFromApexToSystem(t *testing.T) { + bp := ` + apex { + name: "myapex", + key: "myapex.key", + native_shared_libs: ["mylib"], + java_libs: ["myjar"], + } + + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + + cc_library { + name: "mylib", + srcs: ["mylib.cpp"], + shared_libs: ["myotherlib"], + system_shared_libs: [], + stl: "none", + apex_available: [ + "myapex", + "//apex_available:platform", + ], + } + + cc_library { + name: "myotherlib", + srcs: ["mylib.cpp"], + system_shared_libs: [], + stl: "none", + apex_available: [ + "myapex", + "//apex_available:platform", + ], + } + + java_library { + name: "myjar", + srcs: ["foo/bar/MyClass.java"], + sdk_version: "none", + system_modules: "none", + libs: ["myotherjar"], + compile_dex: true, + apex_available: [ + "myapex", + "//apex_available:platform", + ], + } + + java_library { + name: "myotherjar", + srcs: ["foo/bar/MyClass.java"], + sdk_version: "none", + system_modules: "none", + apex_available: [ + "myapex", + "//apex_available:platform", + ], + } + ` + + ensureRealfileExists := func(t *testing.T, files []fileInApex, file string) { + for _, f := range files { + if f.path == file { + if f.isLink { + t.Errorf("%q is not a real file", file) + } + return + } + } + t.Errorf("%q is not found", file) + } + + ensureSymlinkExists := func(t *testing.T, files []fileInApex, file string) { + for _, f := range files { + if f.path == file { + if !f.isLink { + t.Errorf("%q is not a symlink", file) + } + return + } + } + t.Errorf("%q is not found", file) + } + + ctx, _ := testApex(t, bp, withUnbundledBuild) + files := getFiles(t, ctx, "myapex") + ensureRealfileExists(t, files, "javalib/myjar.jar") + ensureRealfileExists(t, files, "lib64/mylib.so") + ensureRealfileExists(t, files, "lib64/myotherlib.so") + + ctx, _ = testApex(t, bp) + files = getFiles(t, ctx, "myapex") + ensureRealfileExists(t, files, "javalib/myjar.jar") + ensureRealfileExists(t, files, "lib64/mylib.so") + ensureSymlinkExists(t, files, "lib64/myotherlib.so") // this is symlink +} + func TestMain(m *testing.M) { run := func() int { setUp() diff --git a/apex/builder.go b/apex/builder.go index 290c1ea90..8209f690e 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -258,34 +258,40 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) { apexType := a.properties.ApexType suffix := apexType.suffix() + var implicitInputs []android.Path unsignedOutputFile := android.PathForModuleOut(ctx, a.Name()+suffix+".unsigned") - filesToCopy := []android.Path{} - for _, f := range a.filesInfo { - filesToCopy = append(filesToCopy, f.builtFile) + // TODO(jiyong): construct the copy rules using RuleBuilder + var copyCommands []string + for _, fi := range a.filesInfo { + destPath := android.PathForModuleOut(ctx, "image"+suffix, fi.Path()).String() + copyCommands = append(copyCommands, "mkdir -p "+filepath.Dir(destPath)) + if a.linkToSystemLib && fi.transitiveDep && fi.AvailableToPlatform() { + // TODO(jiyong): pathOnDevice should come from fi.module, not being calculated here + pathOnDevice := filepath.Join("/system", fi.Path()) + copyCommands = append(copyCommands, "ln -sfn "+pathOnDevice+" "+destPath) + } else { + copyCommands = append(copyCommands, "cp -f "+fi.builtFile.String()+" "+destPath) + implicitInputs = append(implicitInputs, fi.builtFile) + } + // create additional symlinks pointing the file inside the APEX + for _, symlinkPath := range fi.SymlinkPaths() { + symlinkDest := android.PathForModuleOut(ctx, "image"+suffix, symlinkPath).String() + copyCommands = append(copyCommands, "ln -sfn "+filepath.Base(destPath)+" "+symlinkDest) + } } - copyCommands := []string{} - emitCommands := []string{} - imageContentFile := android.PathForModuleOut(ctx, a.Name()+"-content.txt") + // TODO(jiyong): use RuleBuilder + var emitCommands []string + imageContentFile := android.PathForModuleOut(ctx, "content.txt") emitCommands = append(emitCommands, "echo ./apex_manifest.pb >> "+imageContentFile.String()) if proptools.Bool(a.properties.Legacy_android10_support) { emitCommands = append(emitCommands, "echo ./apex_manifest.json >> "+imageContentFile.String()) } - for i, src := range filesToCopy { - dest := filepath.Join(a.filesInfo[i].installDir, src.Base()) - emitCommands = append(emitCommands, "echo './"+dest+"' >> "+imageContentFile.String()) - dest_path := filepath.Join(android.PathForModuleOut(ctx, "image"+suffix).String(), dest) - copyCommands = append(copyCommands, "mkdir -p "+filepath.Dir(dest_path)) - copyCommands = append(copyCommands, "cp "+src.String()+" "+dest_path) - for _, sym := range a.filesInfo[i].symlinks { - symlinkDest := filepath.Join(filepath.Dir(dest_path), sym) - copyCommands = append(copyCommands, "ln -s "+filepath.Base(dest)+" "+symlinkDest) - } + for _, fi := range a.filesInfo { + emitCommands = append(emitCommands, "echo './"+fi.Path()+"' >> "+imageContentFile.String()) } emitCommands = append(emitCommands, "sort -o "+imageContentFile.String()+" "+imageContentFile.String()) - - implicitInputs := append(android.Paths(nil), filesToCopy...) implicitInputs = append(implicitInputs, a.manifestPbOut) if a.properties.Whitelisted_files != nil { @@ -376,17 +382,15 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) { } targetSdkVersion := ctx.Config().DefaultAppTargetSdk() - minSdkVersion := ctx.Config().DefaultAppTargetSdk() - if java.UseApiFingerprint(ctx, targetSdkVersion) { - targetSdkVersion += fmt.Sprintf(".$$(cat %s)", java.ApiFingerprintPath(ctx).String()) - implicitInputs = append(implicitInputs, java.ApiFingerprintPath(ctx)) - } - if java.UseApiFingerprint(ctx, minSdkVersion) { - minSdkVersion += fmt.Sprintf(".$$(cat %s)", java.ApiFingerprintPath(ctx).String()) - implicitInputs = append(implicitInputs, java.ApiFingerprintPath(ctx)) + if targetSdkVersion == ctx.Config().PlatformSdkCodename() && + ctx.Config().UnbundledBuild() && + !ctx.Config().UnbundledBuildUsePrebuiltSdks() && + ctx.Config().IsEnvTrue("UNBUNDLED_BUILD_TARGET_SDK_WITH_API_FINGERPRINT") { + apiFingerprint := java.ApiFingerprintPath(ctx) + targetSdkVersion += fmt.Sprintf(".$$(cat %s)", apiFingerprint.String()) + implicitInputs = append(implicitInputs, apiFingerprint) } optFlags = append(optFlags, "--target_sdk_version "+targetSdkVersion) - optFlags = append(optFlags, "--min_sdk_version "+minSdkVersion) noticeFile := a.buildNoticeFile(ctx, a.Name()+suffix) if noticeFile.Valid() { @@ -532,7 +536,7 @@ func (a *apexBundle) buildFilesInfo(ctx android.ModuleContext) { if a.installable() { // For flattened APEX, do nothing but make sure that APEX manifest and apex_pubkey are also copied along // with other ordinary files. - a.filesInfo = append(a.filesInfo, newApexFile(ctx, a.manifestPbOut, "apex_manifest.pb."+a.Name()+a.suffix, ".", etc, nil)) + a.filesInfo = append(a.filesInfo, newApexFile(ctx, a.manifestPbOut, "apex_manifest.pb", ".", etc, nil)) // rename to apex_pubkey copiedPubkey := android.PathForModuleOut(ctx, "apex_pubkey") @@ -541,7 +545,7 @@ func (a *apexBundle) buildFilesInfo(ctx android.ModuleContext) { Input: a.public_key_file, Output: copiedPubkey, }) - a.filesInfo = append(a.filesInfo, newApexFile(ctx, copiedPubkey, "apex_pubkey."+a.Name()+a.suffix, ".", etc, nil)) + a.filesInfo = append(a.filesInfo, newApexFile(ctx, copiedPubkey, "apex_pubkey", ".", etc, nil)) if a.properties.ApexType == flattenedApex { apexName := proptools.StringDefault(a.properties.Apex_name, a.Name()) diff --git a/cc/cc_test.go b/cc/cc_test.go index 4d02f4f62..332cc45e7 100644 --- a/cc/cc_test.go +++ b/cc/cc_test.go @@ -2303,13 +2303,13 @@ func TestStaticLibDepExport(t *testing.T) { // Check the shared version of lib2. variant := "android_arm64_armv8-a_shared" module := ctx.ModuleForTests("lib2", variant).Module().(*Module) - checkStaticLibs(t, []string{"lib1", "libc++demangle", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc_stripped"}, module) + checkStaticLibs(t, []string{"lib1", "libc++demangle", "libclang_rt.builtins-aarch64-android", "libatomic"}, module) // Check the static version of lib2. variant = "android_arm64_armv8-a_static" module = ctx.ModuleForTests("lib2", variant).Module().(*Module) // libc++_static is linked additionally. - checkStaticLibs(t, []string{"lib1", "libc++_static", "libc++demangle", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc_stripped"}, module) + checkStaticLibs(t, []string{"lib1", "libc++_static", "libc++demangle", "libclang_rt.builtins-aarch64-android", "libatomic"}, module) } var compilerFlagsTestCases = []struct { diff --git a/cc/config/global.go b/cc/config/global.go index bae5555f9..1ce29b981 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -88,6 +88,7 @@ var ( "-Wl,--no-undefined-version", "-Wl,--exclude-libs,libgcc.a", "-Wl,--exclude-libs,libgcc_stripped.a", + "-Wl,--exclude-libs,libunwind_llvm.a", } deviceGlobalLldflags = append(ClangFilterUnknownLldflags(deviceGlobalLdflags), @@ -165,6 +166,9 @@ func init() { flags = append(flags, "-ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang") } else if ctx.Config().IsEnvTrue("AUTO_PATTERN_INITIALIZE") { flags = append(flags, "-ftrivial-auto-var-init=pattern") + } else { + // Default to pattern initialization. + flags = append(flags, "-ftrivial-auto-var-init=pattern") } return strings.Join(flags, " ") diff --git a/cc/linker.go b/cc/linker.go index 61ae7575a..6f2e5b7d0 100644 --- a/cc/linker.go +++ b/cc/linker.go @@ -224,11 +224,10 @@ func (linker *baseLinker) linkerDeps(ctx DepsContext, deps Deps) Deps { } if ctx.toolchain().Bionic() { - // libclang_rt.builtins, libgcc and libatomic have to be last on the command line + // libclang_rt.builtins and libatomic have to be last on the command line if !Bool(linker.Properties.No_libcrt) { deps.LateStaticLibs = append(deps.LateStaticLibs, config.BuiltinsRuntimeLibrary(ctx.toolchain())) deps.LateStaticLibs = append(deps.LateStaticLibs, "libatomic") - deps.LateStaticLibs = append(deps.LateStaticLibs, "libgcc_stripped") } systemSharedLibs := linker.Properties.System_shared_libs @@ -171,11 +171,13 @@ func (stl *stl) deps(ctx BaseModuleContext, deps Deps) Deps { deps.StaticLibs = append(deps.StaticLibs, "libc++demangle") } if ctx.toolchain().Bionic() { - if ctx.Arch().ArchType == android.Arm { - deps.StaticLibs = append(deps.StaticLibs, "libunwind_llvm") - } if ctx.staticBinary() { deps.StaticLibs = append(deps.StaticLibs, "libm", "libc") + if ctx.Arch().ArchType == android.Arm { + deps.StaticLibs = append(deps.StaticLibs, "libunwind_llvm") + } else { + deps.StaticLibs = append(deps.StaticLibs, "libgcc_stripped") + } } } case "": @@ -196,6 +198,8 @@ func (stl *stl) deps(ctx BaseModuleContext, deps Deps) Deps { } if ctx.Arch().ArchType == android.Arm { deps.StaticLibs = append(deps.StaticLibs, "ndk_libunwind") + } else { + deps.StaticLibs = append(deps.StaticLibs, "libgcc_stripped") } default: panic(fmt.Errorf("Unknown stl: %q", stl.Properties.SelectedStl)) diff --git a/cc/testing.go b/cc/testing.go index 198a346f5..ba8ed95dd 100644 --- a/cc/testing.go +++ b/cc/testing.go @@ -136,6 +136,7 @@ func GatherRequiredDepsForTest(os android.OsType) string { name: "libc", no_libcrt: true, nocrt: true, + stl: "none", system_shared_libs: [], recovery_available: true, } @@ -147,6 +148,7 @@ func GatherRequiredDepsForTest(os android.OsType) string { name: "libm", no_libcrt: true, nocrt: true, + stl: "none", system_shared_libs: [], recovery_available: true, } @@ -158,6 +160,7 @@ func GatherRequiredDepsForTest(os android.OsType) string { name: "libdl", no_libcrt: true, nocrt: true, + stl: "none", system_shared_libs: [], recovery_available: true, } diff --git a/docs/perf.md b/docs/perf.md index c3a26474f..538adffb5 100644 --- a/docs/perf.md +++ b/docs/perf.md @@ -8,7 +8,7 @@ soong_ui has tracing built in, so that every build execution's trace can be viewed. Just open `$OUT_DIR/build.trace.gz` in Chrome's <chrome://tracing>, or with [catapult's trace viewer][catapult trace_viewer]. The last few traces are stored in `build.trace.#.gz` (larger numbers are older). The associated logs -are stored in `soong.#.log`. +are stored in `soong.#.log` and `verbose.#.log.gz`.  @@ -31,29 +31,29 @@ or read a file that's going to change on every build. In most cases, we've found that the fast-path is slow because all of the `$(shell)` commands need to be re-executed to determine if their output changed. -The `$OUT_DIR/soong.log` contains statistics from the regen check: - -``` -.../kati.go:127: *kati*: regen check time: 1.699207 -.../kati.go:127: *kati*: glob time (regen): 0.377193 / 33609 -.../kati.go:127: *kati*: shell time (regen): 1.313529 / 184 -.../kati.go:127: *kati*: 0.217 find device vendor -type f -name \*.pk8 -o -name verifiedboot\* -o -name \*.x509.pem -o -name oem\*.prop | sort -.../kati.go:127: *kati*: 0.105 cd packages/apps/Dialer ; find -L . -type d -name "res" -.../kati.go:127: *kati*: 0.035 find device vendor -maxdepth 4 -name '*_aux_variant_config.mk' -o -name '*_aux_os_config.mk' | sort -.../kati.go:127: *kati*: 0.029 cd frameworks/base ; find -L core/java graphics/java location/java media/java media/mca/effect/java media/mca/filterfw/java media/mca/filterpacks/java drm/java opengl/java sax/java telecomm/java telephony/java wifi/java lowpan/java keystore/java rs/java ../opt/telephony/src/java/android/telephony ../opt/telephony/src/java/android/telephony/gsm ../opt/net/voip/src/java/android/net/rtp ../opt/net/voip/src/java/android/net/sip -name "*.html" -and -not -name ".*" -.../kati.go:127: *kati*: 0.025 test -d device && find -L device -maxdepth 4 -path '*/marlin/BoardConfig.mk' -.../kati.go:127: *kati*: 0.023 find packages/apps/Settings/tests/robotests -type f -name '*Test.java' | sed -e 's!.*\(com/google.*Test\)\.java!\1!' -e 's!.*\(com/android.*Test\)\.java!\1!' | sed 's!/!\.!g' | cat -.../kati.go:127: *kati*: 0.022 test -d vendor && find -L vendor -maxdepth 4 -path '*/marlin/BoardConfig.mk' -.../kati.go:127: *kati*: 0.017 cd cts/tests/tests/shortcutmanager/packages/launchermanifest ; find -L ../src -name "*.java" -and -not -name ".*" -.../kati.go:127: *kati*: 0.016 cd cts/tests/tests/shortcutmanager/packages/launchermanifest ; find -L ../../common/src -name "*.java" -and -not -name ".*" -.../kati.go:127: *kati*: 0.015 cd libcore && (find luni/src/test/java -name "*.java" 2> /dev/null) | grep -v -f java_tests_blacklist -.../kati.go:127: *kati*: stat time (regen): 0.250384 / 4405 -``` - -In this case, the total time spent checking was 1.69 seconds, even though the +The `$OUT_DIR/verbose.log.gz` contains statistics from the regen check: + +``` +verbose: *kati*: regen check time: 0.754030 +verbose: *kati*: glob time (regen): 0.545859 / 43840 +verbose: *kati*: shell time (regen): 0.278095 / 66 (59 unique) +verbose: *kati*: 0.012 / 1 mkdir -p out/target/product/generic && echo Android/aosp_arm/generic:R/AOSP.MASTER/$(date -d @$(cat out/build_date.txt) +%m%d%H%M):eng/test-keys >out/target/product/generic/build_fingerprint.txt && grep " " out/target/product/generic/build_fingerprint.txt +verbose: *kati*: 0.010 / 1 echo 'com.android.launcher3.config.FlagOverrideSampleTest com.android.launcher3.logging.FileLogTest com.android.launcher3.model.AddWorkspaceItemsTaskTest com.android.launcher3.model.CacheDataUpdatedTaskTest com.android.launcher3.model.DbDowngradeHelperTest com.android.launcher3.model.GridBackupTableTest com.android.launcher3.model.GridSizeMigrationTaskTest com.android.launcher3.model.PackageInstallStateChangedTaskTest com.android.launcher3.popup.PopupPopulatorTest com.android.launcher3.util.GridOccupancyTest com.android.launcher3.util.IntSetTest' | tr ' ' '\n' | cat +verbose: *kati*: 0.010 / 1 cd cts/tests/framework/base/windowmanager ; find -L * -name "Components.java" -and -not -name ".*" +verbose: *kati*: 0.010 / 1 git -C test/framework/build log -s -n 1 --format="%cd" --date=format:"%Y%m%d_%H%M%S" 2>/dev/null +verbose: *kati*: 0.009 / 2 cd development/samples/ShortcutDemo/publisher ; find -L ../common/src -name "*.java" -and -not -name ".*" +verbose: *kati*: 0.009 / 2 cd development/samples/ShortcutDemo/launcher ; find -L ../common/src -name "*.java" -and -not -name ".*" +verbose: *kati*: 0.009 / 1 if ! cmp -s out/target/product/generic/obj/CONFIG/kati_packaging/dist.mk.tmp out/target/product/generic/obj/CONFIG/kati_packaging/dist.mk; then mv out/target/product/generic/obj/CONFIG/kati_packaging/dist.mk.tmp out/target/product/generic/obj/CONFIG/kati_packaging/dist.mk; else rm out/target/product/generic/obj/CONFIG/kati_packaging/dist.mk.tmp; fi +verbose: *kati*: 0.008 / 1 mkdir -p out/target/product/generic && echo R/AOSP.MASTER/$(cat out/build_number.txt):eng/test-keys >out/target/product/generic/build_thumbprint.txt && grep " " out/target/product/generic/build_thumbprint.txt +verbose: *kati*: 0.007 / 1 echo 'com.android.customization.model.clock.BaseClockManagerTest com.android.customization.model.clock.ClockManagerTest com.android.customization.model.grid.GridOptionsManagerTest com.android.customization.model.theme.ThemeManagerTest' | tr ' ' '\n' | cat +verbose: *kati*: 0.007 / 1 uname -sm +verbose: *kati*: stat time (regen): 0.361907 / 1241 +``` + +In this case, the total time spent checking was 0.75 seconds, even though the other "(regen)" numbers add up to more than that (some parts are parallelized -where possible). The biggest contributor is the `$(shell)` times -- 184 -executions took a total of 1.31 seconds. The top 10 longest shell functions are +where possible). Often times, the biggest contributor is the `$(shell)` times +-- in this case, 66 calls took 0.27s. The top 10 longest shell functions are printed. All the longest commands in this case are all variants of a call to `find`, but @@ -96,7 +96,8 @@ cached by Kati: $(sort $(shell find device vendor -type -f -a -name \*.pk8 -o -name verifiedboot\* -o -name \*.x509.pem -o -name oem\*.prop)) ``` -Kati is learning about the implicit `-a` in [this change](https://github.com/google/kati/pull/132) +Kati has now learned about the implicit `-a`, so this particular change is no +longer necessary, but the basic concept holds. #### Kati regens too often @@ -113,6 +114,46 @@ read with the `ckati_stamp_dump` tool in prebuilts/build-tools. More debugging is available when ckati is run with `--regen_debug`, but that can be a lot of data to understand. +#### Debugging the slow path + +Kati will now dump out information about which Makefiles took the most time to +execute. This is also in the `verbose.log.gz` file: + +``` +verbose: *kati*: included makefiles: 73.640833 / 232810 (1066 unique) +verbose: *kati*: 18.389 / 1 out/soong/Android-aosp_arm.mk +verbose: *kati*: 13.137 / 20144 build/make/core/soong_cc_prebuilt.mk +verbose: *kati*: 11.743 / 27666 build/make/core/base_rules.mk +verbose: *kati*: 2.289 / 1 art/Android.mk +verbose: *kati*: 2.054 / 1 art/build/Android.cpplint.mk +verbose: *kati*: 1.955 / 28269 build/make/core/clear_vars.mk +verbose: *kati*: 1.795 / 283 build/make/core/package.mk +verbose: *kati*: 1.790 / 283 build/make/core/package_internal.mk +verbose: *kati*: 1.757 / 17382 build/make/core/link_type.mk +verbose: *kati*: 1.078 / 297 build/make/core/aapt2.mk +``` + +This shows that soong_cc_prebuilt.mk was included 20144 times, for a total time +spent of 13.137 secounds. While Android-aosp_arm.mk was only included once, and +took 18.389 seconds. In this case, Android-aosp_arm.mk is the only file that +includes soong_cc_prebuilt.mk, so we can safely assume that 13 of the 18 seconds +in Android-aosp_arm.mk was actually spent within soong_cc_prebuilt.mk (or +something that it included, like base_rules.mk). + +By default this only includes the top 10 entries, but you can ask for the stats +for any makefile to be printed with `$(KATI_profile_makefile)`: + +``` +$(KATI_profile_makefile build/make/core/product.mk) +``` + +With these primitives, it's possible to get the timing information for small +chunks, or even single lines, of a makefile. Just move the lines you want to +measure into a new makefile, and replace their use with an `include` of the +new makefile. It's possible to analyze where the time is being spent by doing +a binary search using this method, but you do need to be careful not to split +conditionals across two files (the ifeq/else/endif must all be in the same file). + ### Ninja #### Understanding why something rebuilt @@ -164,15 +205,14 @@ use, disk bandwidth, etc) may also be necessary. ### Common -#### mm +### <= Android 10 (Q): mm Soong always loads the entire module graph, so as modules convert from Make to Soong, `mm` is becoming closer to `mma`. This produces more correct builds, but does slow down builds, as we need to verify/produce/load a larger build graph. -We're exploring a few options to speed up build startup, one being [an -experimental set of ninja patches][ninja parse optimization], -though that's not the current path we're working towards. +As of Android Q, loading large build graphs is fast, and in Android R, `mm` is +now an alias of `mma`. ### Android 8.1 (Oreo MR1) diff --git a/genrule/genrule.go b/genrule/genrule.go index 57ca9bc6f..c5aaed29c 100644 --- a/genrule/genrule.go +++ b/genrule/genrule.go @@ -30,10 +30,18 @@ import ( ) func init() { - android.RegisterModuleType("genrule_defaults", defaultsFactory) + registerGenruleBuildComponents(android.InitRegistrationContext) +} + +func registerGenruleBuildComponents(ctx android.RegistrationContext) { + ctx.RegisterModuleType("genrule_defaults", defaultsFactory) + + ctx.RegisterModuleType("gensrcs", GenSrcsFactory) + ctx.RegisterModuleType("genrule", GenRuleFactory) - android.RegisterModuleType("gensrcs", GenSrcsFactory) - android.RegisterModuleType("genrule", GenRuleFactory) + ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) { + ctx.BottomUp("genrule_tool_deps", toolDepsMutator).Parallel() + }) } var ( @@ -166,7 +174,7 @@ func (g *Module) GeneratedDeps() android.Paths { return g.outputDeps } -func (g *Module) DepsMutator(ctx android.BottomUpMutatorContext) { +func toolDepsMutator(ctx android.BottomUpMutatorContext) { if g, ok := ctx.Module().(*Module); ok { for _, tool := range g.properties.Tools { tag := hostToolDependencyTag{label: tool} diff --git a/genrule/genrule_test.go b/genrule/genrule_test.go index ea49e0891..7eb43ac9d 100644 --- a/genrule/genrule_test.go +++ b/genrule/genrule_test.go @@ -55,10 +55,10 @@ func testContext(config android.Config) *android.TestContext { ctx := android.NewTestArchContext() ctx.RegisterModuleType("filegroup", android.FileGroupFactory) - ctx.RegisterModuleType("genrule", GenRuleFactory) - ctx.RegisterModuleType("gensrcs", GenSrcsFactory) - ctx.RegisterModuleType("genrule_defaults", defaultsFactory) ctx.RegisterModuleType("tool", toolFactory) + + registerGenruleBuildComponents(ctx) + ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators) ctx.Register(config) diff --git a/java/android_manifest.go b/java/android_manifest.go index dc7a3fc7e..021883e60 100644 --- a/java/android_manifest.go +++ b/java/android_manifest.go @@ -93,11 +93,13 @@ func manifestFixer(ctx android.ModuleContext, manifest android.Path, sdkContext var deps android.Paths targetSdkVersion := sdkVersionOrDefault(ctx, sdkContext.targetSdkVersion()) - minSdkVersion := sdkVersionOrDefault(ctx, sdkContext.minSdkVersion()) - if (UseApiFingerprint(ctx, sdkContext.targetSdkVersion()) || - UseApiFingerprint(ctx, sdkContext.minSdkVersion())) { - apiFingerprint := ApiFingerprintPath(ctx) - deps = append(deps, apiFingerprint) + if targetSdkVersion == ctx.Config().PlatformSdkCodename() && + ctx.Config().UnbundledBuild() && + !ctx.Config().UnbundledBuildUsePrebuiltSdks() && + ctx.Config().IsEnvTrue("UNBUNDLED_BUILD_TARGET_SDK_WITH_API_FINGERPRINT") { + apiFingerprint := ApiFingerprintPath(ctx) + targetSdkVersion += fmt.Sprintf(".$$(cat %s)", apiFingerprint.String()) + deps = append(deps, apiFingerprint) } fixedManifest := android.PathForModuleOut(ctx, "manifest_fixer", "AndroidManifest.xml") @@ -108,7 +110,7 @@ func manifestFixer(ctx android.ModuleContext, manifest android.Path, sdkContext Implicits: deps, Output: fixedManifest, Args: map[string]string{ - "minSdkVersion": minSdkVersion, + "minSdkVersion": sdkVersionOrDefault(ctx, sdkContext.minSdkVersion()), "targetSdkVersion": targetSdkVersion, "args": strings.Join(args, " "), }, diff --git a/java/sdk.go b/java/sdk.go index 73b7dcf78..66eb284ba 100644 --- a/java/sdk.go +++ b/java/sdk.go @@ -47,29 +47,13 @@ type sdkContext interface { targetSdkVersion() string } -func UseApiFingerprint(ctx android.BaseModuleContext, v string) bool { - if v == ctx.Config().PlatformSdkCodename() && - ctx.Config().UnbundledBuild() && - !ctx.Config().UnbundledBuildUsePrebuiltSdks() && - ctx.Config().IsEnvTrue("UNBUNDLED_BUILD_TARGET_SDK_WITH_API_FINGERPRINT") { - return true - } - return false -} - func sdkVersionOrDefault(ctx android.BaseModuleContext, v string) string { - var sdkVersion string switch v { case "", "none", "current", "test_current", "system_current", "core_current", "core_platform": - sdkVersion = ctx.Config().DefaultAppTargetSdk() + return ctx.Config().DefaultAppTargetSdk() default: - sdkVersion = v - } - if UseApiFingerprint(ctx, sdkVersion) { - apiFingerprint := ApiFingerprintPath(ctx) - sdkVersion += fmt.Sprintf(".$$(cat %s)", apiFingerprint.String()) + return v } - return sdkVersion } // Returns a sdk version as a number. For modules targeting an unreleased SDK (meaning it does not yet have a number) diff --git a/python/python.go b/python/python.go index c67c577dc..8b912be17 100644 --- a/python/python.go +++ b/python/python.go @@ -340,6 +340,11 @@ func (p *Module) DepsMutator(ctx android.BottomUpMutatorContext) { // dependencies later. ctx.AddFarVariationDependencies(ctx.Target().Variations(), launcherSharedLibTag, "libsqlite") + if ctx.Device() { + ctx.AddFarVariationDependencies(ctx.Target().Variations(), launcherSharedLibTag, + "liblog") + } + if ctx.Target().Os.Bionic() { ctx.AddFarVariationDependencies(ctx.Target().Variations(), launcherSharedLibTag, "libc", "libdl", "libm") |