Merge changes I28a15bcc,I86cccefc
* changes:
Add (host|host-cross|target)[-<OS>] phony targets when not using make
Fix mma/mmma when soong is not embedded in make
diff --git a/Android.bp b/Android.bp
index 1892670..b8a4f82 100644
--- a/Android.bp
+++ b/Android.bp
@@ -119,6 +119,7 @@
"cc/gen.go",
"cc/lto.go",
"cc/makevars.go",
+ "cc/pgo.go",
"cc/prebuilt.go",
"cc/proto.go",
"cc/relocation_packer.go",
diff --git a/android/config.go b/android/config.go
index f30a708..a70fa76 100644
--- a/android/config.go
+++ b/android/config.go
@@ -462,6 +462,10 @@
return Bool(c.ProductVariables.Allow_missing_dependencies)
}
+func (c *config) UnbundledBuild() bool {
+ return Bool(c.ProductVariables.Unbundled_build)
+}
+
func (c *config) DevicePrefer32BitExecutables() bool {
return Bool(c.ProductVariables.DevicePrefer32BitExecutables)
}
diff --git a/cc/binary.go b/cc/binary.go
index 4b10070..b2405b6 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -325,6 +325,7 @@
linkerDeps = append(linkerDeps, deps.SharedLibsDeps...)
linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...)
linkerDeps = append(linkerDeps, objs.tidyFiles...)
+ linkerDeps = append(linkerDeps, flags.LdFlagsDeps...)
TransformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs, deps.StaticLibs,
deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, true,
diff --git a/cc/cc.go b/cc/cc.go
index af58f9d..b4b70ed 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -134,7 +134,8 @@
RequiredInstructionSet string
DynamicLinker string
- CFlagsDeps android.Paths // Files depended on by compiler flags
+ CFlagsDeps android.Paths // Files depended on by compiler flags
+ LdFlagsDeps android.Paths // Files depended on by linker flags
GroupStaticLibs bool
}
@@ -308,6 +309,7 @@
sabi *sabi
vndkdep *vndkdep
lto *lto
+ pgo *pgo
androidMkSharedLibDeps []string
@@ -350,6 +352,9 @@
if c.lto != nil {
c.AddProperties(c.lto.props()...)
}
+ if c.pgo != nil {
+ c.AddProperties(c.pgo.props()...)
+ }
for _, feature := range c.features {
c.AddProperties(feature.props()...)
}
@@ -506,6 +511,7 @@
module.sabi = &sabi{}
module.vndkdep = &vndkdep{}
module.lto = <o{}
+ module.pgo = &pgo{}
return module
}
@@ -557,6 +563,9 @@
if c.lto != nil {
flags = c.lto.flags(ctx, flags)
}
+ if c.pgo != nil {
+ flags = c.pgo.flags(ctx, flags)
+ }
for _, feature := range c.features {
flags = feature.flags(ctx, flags)
}
@@ -643,6 +652,9 @@
if c.lto != nil {
c.lto.begin(ctx)
}
+ if c.pgo != nil {
+ c.pgo.begin(ctx)
+ }
for _, feature := range c.features {
feature.begin(ctx)
}
@@ -1250,6 +1262,7 @@
&SAbiProperties{},
&VndkProperties{},
<OProperties{},
+ &PgoProperties{},
)
android.InitDefaultsModule(module)
diff --git a/cc/library.go b/cc/library.go
index 2a866dc..f1681db 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -484,6 +484,7 @@
flags Flags, deps PathDeps, objs Objects) android.Path {
var linkerDeps android.Paths
+ linkerDeps = append(linkerDeps, flags.LdFlagsDeps...)
versionScript := android.OptionalPathForModuleSrc(ctx, library.Properties.Version_script)
unexportedSymbols := android.OptionalPathForModuleSrc(ctx, library.Properties.Unexported_symbols_list)
@@ -628,7 +629,6 @@
flags Flags, deps PathDeps, objs Objects) android.Path {
objs = objs.Append(deps.Objs)
-
var out android.Path
if library.static() || library.header() {
out = library.linkStatic(ctx, flags, deps, objs)
diff --git a/cc/pgo.go b/cc/pgo.go
new file mode 100644
index 0000000..ccddece
--- /dev/null
+++ b/cc/pgo.go
@@ -0,0 +1,190 @@
+// Copyright 2017 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cc
+
+import (
+ "fmt"
+ "strings"
+
+ "android/soong/android"
+)
+
+var (
+ // Add flags to ignore warnings that profiles are old or missing for
+ // some functions
+ profileUseOtherFlags = []string{}
+)
+
+const pgoProfileProject = "toolchain/pgo-profiles"
+
+const profileInstrumentFlag = "-fprofile-generate=/data/local/tmp"
+const profileSamplingFlag = "-gline-tables-only"
+const profileUseInstrumentFormat = "-fprofile-use=%s"
+const profileUseSamplingFormat = "-fprofile-sample-use=%s"
+
+type PgoProperties struct {
+ Pgo struct {
+ Instrumentation *bool
+ Sampling *bool
+ Profile_file *string `android:"arch_variant"`
+ Benchmarks []string
+ } `android:"arch_variant"`
+
+ PgoPresent bool `blueprint:"mutated"`
+ ShouldProfileModule bool `blueprint:"mutated"`
+}
+
+type pgo struct {
+ Properties PgoProperties
+}
+
+func (pgo *pgo) props() []interface{} {
+ return []interface{}{&pgo.Properties}
+}
+
+func (pgo *pgo) profileGatherFlags(ctx ModuleContext) string {
+ if *pgo.Properties.Pgo.Instrumentation {
+ return profileInstrumentFlag
+ }
+ if *pgo.Properties.Pgo.Sampling {
+ return profileSamplingFlag
+ }
+ return ""
+}
+
+func (pgo *pgo) profileUseFlag(ctx ModuleContext, file string) string {
+ if *pgo.Properties.Pgo.Instrumentation {
+ return fmt.Sprintf(profileUseInstrumentFormat, file)
+ }
+ if *pgo.Properties.Pgo.Sampling {
+ return fmt.Sprintf(profileUseSamplingFormat, file)
+ }
+ return ""
+}
+
+func (pgo *pgo) profileUseFlags(ctx ModuleContext, file string) []string {
+ flags := []string{pgo.profileUseFlag(ctx, file)}
+ flags = append(flags, profileUseOtherFlags...)
+ return flags
+}
+
+func (props *PgoProperties) isPGO(ctx BaseModuleContext) bool {
+ isInstrumentation := props.Pgo.Instrumentation != nil
+ isSampling := props.Pgo.Sampling != nil
+
+ profileKindPresent := isInstrumentation || isSampling
+ filePresent := props.Pgo.Profile_file != nil
+ benchmarksPresent := len(props.Pgo.Benchmarks) > 0
+
+ // If all three properties are absent, PGO is OFF for this module
+ if !profileKindPresent && !filePresent && !benchmarksPresent {
+ return false
+ }
+
+ // If at least one property exists, validate that all properties exist
+ if !profileKindPresent || !filePresent || !benchmarksPresent {
+ var missing []string
+ if !profileKindPresent {
+ missing = append(missing, "profile kind (either \"instrumentation\" or \"sampling\" property)")
+ }
+ if !filePresent {
+ missing = append(missing, "profile_file property")
+ }
+ if !benchmarksPresent {
+ missing = append(missing, "non-empty benchmarks property")
+ }
+ missingProps := strings.Join(missing, ", ")
+ ctx.ModuleErrorf("PGO specification is missing properties: " + missingProps)
+ }
+
+ // Sampling not supported yet
+ //
+ // TODO When sampling support is turned on, check that instrumentation and
+ // sampling are not simultaneously specified
+ if isSampling {
+ ctx.PropertyErrorf("pgo.sampling", "\"sampling\" is not supported yet)")
+ }
+
+ return true
+}
+
+func getPgoProfilesDir(ctx ModuleContext) android.OptionalPath {
+ return android.ExistentPathForSource(ctx, "", pgoProfileProject)
+}
+
+func (pgo *pgo) begin(ctx BaseModuleContext) {
+ // TODO Evaluate if we need to support PGO for host modules
+ if ctx.Host() {
+ return
+ }
+
+ // Check if PGO is needed for this module
+ pgo.Properties.PgoPresent = pgo.Properties.isPGO(ctx)
+
+ if !pgo.Properties.PgoPresent {
+ return
+ }
+
+ // This module should be instrumented if ANDROID_PGO_INSTRUMENT is set
+ // and includes a benchmark listed for this module
+ //
+ // TODO Validate that each benchmark instruments at least one module
+ pgo.Properties.ShouldProfileModule = false
+ pgoBenchmarks := ctx.AConfig().Getenv("ANDROID_PGO_INSTRUMENT")
+ pgoBenchmarksMap := make(map[string]bool)
+ for _, b := range strings.Split(pgoBenchmarks, ",") {
+ pgoBenchmarksMap[b] = true
+ }
+
+ for _, b := range pgo.Properties.Pgo.Benchmarks {
+ if pgoBenchmarksMap[b] == true {
+ pgo.Properties.ShouldProfileModule = true
+ break
+ }
+ }
+}
+
+func (pgo *pgo) flags(ctx ModuleContext, flags Flags) Flags {
+ if ctx.Host() {
+ return flags
+ }
+
+ props := pgo.Properties
+
+ // Add flags to profile this module based on its profile_kind
+ if props.ShouldProfileModule {
+ profileGatherFlags := pgo.profileGatherFlags(ctx)
+ flags.LdFlags = append(flags.LdFlags, profileGatherFlags)
+ flags.CFlags = append(flags.CFlags, profileGatherFlags)
+ return flags
+ }
+
+ // If the PGO profiles project is found, and this module has PGO
+ // enabled, add flags to use the profile
+ if profilesDir := getPgoProfilesDir(ctx); props.PgoPresent && profilesDir.Valid() {
+ profileFile := android.PathForSource(ctx, profilesDir.String(), *(props.Pgo.Profile_file))
+ profileUseFlags := pgo.profileUseFlags(ctx, profileFile.String())
+
+ flags.CFlags = append(flags.CFlags, profileUseFlags...)
+ flags.LdFlags = append(flags.LdFlags, profileUseFlags...)
+
+ // Update CFlagsDeps and LdFlagsDeps so the module is rebuilt
+ // if profileFile gets updated
+ flags.CFlagsDeps = append(flags.CFlagsDeps, profileFile)
+ flags.LdFlagsDeps = append(flags.LdFlagsDeps, profileFile)
+ }
+
+ return flags
+}
diff --git a/java/app.go b/java/app.go
index e6b91a7..80d62fd 100644
--- a/java/app.go
+++ b/java/app.go
@@ -233,9 +233,7 @@
ctx.VisitDirectDeps(func(module blueprint.Module) {
var depFiles android.Paths
- if sdkDep, ok := module.(sdkDependency); ok {
- depFiles = sdkDep.ClasspathFiles()
- } else if javaDep, ok := module.(Dependency); ok {
+ if javaDep, ok := module.(Dependency); ok {
if ctx.OtherModuleName(module) == "framework-res" {
depFiles = android.Paths{javaDep.(*AndroidApp).exportPackage}
}
diff --git a/java/java.go b/java/java.go
index 2ded80b..43f97ac 100644
--- a/java/java.go
+++ b/java/java.go
@@ -20,6 +20,7 @@
import (
"fmt"
+ "path/filepath"
"strconv"
"strings"
@@ -41,7 +42,6 @@
android.RegisterModuleType("java_binary_host", BinaryHostFactory)
android.RegisterModuleType("java_import", ImportFactory)
android.RegisterModuleType("java_import_host", ImportFactoryHost)
- android.RegisterModuleType("android_prebuilt_sdk", SdkPrebuiltFactory)
android.RegisterModuleType("android_app", AndroidAppFactory)
android.RegisterSingletonType("logtags", LogtagsSingleton)
@@ -179,26 +179,90 @@
libTag = dependencyTag{name: "javalib"}
bootClasspathTag = dependencyTag{name: "bootclasspath"}
frameworkResTag = dependencyTag{name: "framework-res"}
- sdkDependencyTag = dependencyTag{name: "sdk"}
)
+type sdkDep struct {
+ useModule, useFiles, useDefaultLibs bool
+ module string
+ jar android.Path
+ aidl android.Path
+}
+
+func decodeSdkDep(ctx android.BaseContext, v string) sdkDep {
+ switch v {
+ case "", "current", "system_current", "test_current":
+ // OK
+ default:
+ if _, err := strconv.Atoi(v); err != nil {
+ ctx.PropertyErrorf("sdk_version", "invalid sdk version")
+ return sdkDep{}
+ }
+ }
+
+ toFile := func(v string) sdkDep {
+ dir := filepath.Join("prebuilts/sdk", v)
+ jar := filepath.Join(dir, "android.jar")
+ aidl := filepath.Join(dir, "framework.aidl")
+ jarPath := android.ExistentPathForSource(ctx, "sdkdir", jar)
+ aidlPath := android.ExistentPathForSource(ctx, "sdkdir", aidl)
+ if !jarPath.Valid() {
+ ctx.PropertyErrorf("sdk_version", "invalid sdk version %q, %q does not exist", v, jar)
+ return sdkDep{}
+ }
+ if !aidlPath.Valid() {
+ ctx.PropertyErrorf("sdk_version", "invalid sdk version %q, %q does not exist", v, aidl)
+ return sdkDep{}
+ }
+ return sdkDep{
+ useFiles: true,
+ jar: jarPath.Path(),
+ aidl: aidlPath.Path(),
+ }
+ }
+
+ toModule := func(m string) sdkDep {
+ return sdkDep{
+ useModule: true,
+ module: m,
+ }
+ }
+
+ if ctx.AConfig().UnbundledBuild() {
+ if v == "" {
+ if ctx, ok := ctx.(android.ModuleContext); ok {
+ ctx.AddMissingDependencies([]string{"sdk_version_must_be_set_for_modules_used_in_unbundled_builds"})
+ }
+ return sdkDep{}
+ }
+ return toFile(v)
+ }
+
+ switch v {
+ case "":
+ return sdkDep{
+ useDefaultLibs: true,
+ }
+ case "current":
+ return toModule("android_stubs_current")
+ case "system_current":
+ return toModule("android_system_stubs_current")
+ case "test_current":
+ return toModule("android_test_stubs_current")
+ default:
+ return toFile(v)
+ }
+}
+
func (j *Module) deps(ctx android.BottomUpMutatorContext) {
if !proptools.Bool(j.properties.No_standard_libs) {
if ctx.Device() {
- switch j.deviceProperties.Sdk_version {
- case "":
+ sdkDep := decodeSdkDep(ctx, j.deviceProperties.Sdk_version)
+ if sdkDep.useDefaultLibs {
ctx.AddDependency(ctx.Module(), bootClasspathTag, "core-oj", "core-libart")
ctx.AddDependency(ctx.Module(), libTag, config.DefaultLibraries...)
- case "current":
- // TODO: !TARGET_BUILD_APPS
- // TODO: export preprocessed framework.aidl from android_stubs_current
- ctx.AddDependency(ctx.Module(), bootClasspathTag, "android_stubs_current")
- case "test_current":
- ctx.AddDependency(ctx.Module(), bootClasspathTag, "android_test_stubs_current")
- case "system_current":
- ctx.AddDependency(ctx.Module(), bootClasspathTag, "android_system_stubs_current")
- default:
- ctx.AddDependency(ctx.Module(), sdkDependencyTag, "sdk_v"+j.deviceProperties.Sdk_version)
+ }
+ if sdkDep.useModule {
+ ctx.AddDependency(ctx.Module(), bootClasspathTag, sdkDep.module)
}
} else {
if j.deviceProperties.Dex {
@@ -247,6 +311,13 @@
func (j *Module) collectDeps(ctx android.ModuleContext) deps {
var deps deps
+
+ sdkDep := decodeSdkDep(ctx, j.deviceProperties.Sdk_version)
+ if sdkDep.useFiles {
+ deps.classpath = append(deps.classpath, sdkDep.jar)
+ deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, sdkDep.aidl)
+ }
+
ctx.VisitDirectDeps(func(module blueprint.Module) {
otherName := ctx.OtherModuleName(module)
tag := ctx.OtherModuleDependencyTag(module)
@@ -277,17 +348,6 @@
// generated by framework-res.apk
deps.srcFileLists = append(deps.srcFileLists, module.(*AndroidApp).aaptJavaFileList)
}
- case sdkDependencyTag:
- sdkDep := module.(sdkDependency)
- deps.bootClasspath = append(deps.bootClasspath, sdkDep.ClasspathFiles()...)
- if sdkDep.AidlPreprocessed().Valid() {
- if deps.aidlPreprocess.Valid() {
- ctx.ModuleErrorf("multiple dependencies with preprocessed aidls:\n %q\n %q",
- deps.aidlPreprocess, sdkDep.AidlPreprocessed())
- } else {
- deps.aidlPreprocess = sdkDep.AidlPreprocessed()
- }
- }
default:
panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
}
@@ -406,7 +466,8 @@
j.classpathFile = outputFile
- if j.deviceProperties.Dex && len(srcFiles) > 0 {
+ // TODO(ccross): handle hostdex
+ if ctx.Device() && len(srcFiles) > 0 {
dxFlags := j.deviceProperties.Dxflags
if false /* emma enabled */ {
// If you instrument class files that have local variable debug information in
@@ -677,51 +738,6 @@
return module
}
-//
-// SDK java prebuilts (.jar containing resources plus framework.aidl)
-//
-
-type sdkDependency interface {
- Dependency
- AidlPreprocessed() android.OptionalPath
-}
-
-var _ sdkDependency = (*sdkPrebuilt)(nil)
-
-type sdkPrebuiltProperties struct {
- Aidl_preprocessed *string
-}
-
-type sdkPrebuilt struct {
- Import
-
- sdkProperties sdkPrebuiltProperties
-
- aidlPreprocessed android.OptionalPath
-}
-
-func (j *sdkPrebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- j.Import.GenerateAndroidBuildActions(ctx)
-
- j.aidlPreprocessed = android.OptionalPathForModuleSrc(ctx, j.sdkProperties.Aidl_preprocessed)
-}
-
-func (j *sdkPrebuilt) AidlPreprocessed() android.OptionalPath {
- return j.aidlPreprocessed
-}
-
-func SdkPrebuiltFactory() android.Module {
- module := &sdkPrebuilt{}
-
- module.AddProperties(
- &module.sdkProperties,
- &module.Import.properties)
-
- android.InitPrebuiltModule(module, &module.Import.properties.Jars)
- android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
- return module
-}
-
func inList(s string, l []string) bool {
for _, e := range l {
if e == s {
diff --git a/java/java_test.go b/java/java_test.go
index 040adb4..7159e3f 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -59,7 +59,6 @@
ctx.RegisterModuleType("java_library_host", android.ModuleFactoryAdaptor(LibraryHostFactory))
ctx.RegisterModuleType("java_import", android.ModuleFactoryAdaptor(ImportFactory))
ctx.RegisterModuleType("java_defaults", android.ModuleFactoryAdaptor(defaultsFactory))
- ctx.RegisterModuleType("android_prebuilt_sdk", android.ModuleFactoryAdaptor(SdkPrebuiltFactory))
ctx.PreArchMutators(android.RegisterPrebuiltsPreArchMutators)
ctx.PreArchMutators(android.RegisterPrebuiltsPostDepsMutators)
ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
@@ -86,21 +85,15 @@
`, extra)
}
- bp += `
- android_prebuilt_sdk {
- name: "sdk_v14",
- jars: ["sdk_v14.jar"],
- }
- `
-
ctx.MockFileSystem(map[string][]byte{
- "Android.bp": []byte(bp),
- "a.java": nil,
- "b.java": nil,
- "c.java": nil,
- "a.jar": nil,
- "b.jar": nil,
- "sdk_v14.jar": nil,
+ "Android.bp": []byte(bp),
+ "a.java": nil,
+ "b.java": nil,
+ "c.java": nil,
+ "a.jar": nil,
+ "b.jar": nil,
+ "prebuilts/sdk/14/android.jar": nil,
+ "prebuilts/sdk/14/framework.aidl": nil,
})
_, errs := ctx.ParseBlueprintsFiles("Android.bp")
@@ -115,8 +108,8 @@
switch {
case name == `""`:
return name
- case strings.HasPrefix(name, "sdk_v"):
- return name + ".jar"
+ case strings.HasSuffix(name, ".jar"):
+ return name
default:
return filepath.Join(buildDir, ".intermediates", name, "android_common", "classes-desugar.jar")
}
@@ -187,8 +180,8 @@
name: "sdk v14",
properties: `sdk_version: "14",`,
- bootclasspath: []string{"sdk_v14"},
- classpath: []string{},
+ bootclasspath: []string{`""`},
+ classpath: []string{"prebuilts/sdk/14/android.jar"},
},
{