summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--android/env.go41
-rw-r--r--android/module.go1
-rw-r--r--android/neverallow.go10
-rw-r--r--android/neverallow_test.go28
-rw-r--r--apex/apex_test.go111
-rw-r--r--apex/builder.go2
-rw-r--r--cmd/soong_build/main.go42
-rw-r--r--genrule/genrule.go7
-rw-r--r--java/androidmk.go12
-rwxr-xr-xjava/app.go12
-rw-r--r--java/app_test.go26
-rw-r--r--java/builder.go38
-rw-r--r--java/config/config.go1
-rw-r--r--java/dex.go5
-rw-r--r--java/droiddoc.go2
-rw-r--r--java/java.go27
-rw-r--r--java/java_test.go26
-rw-r--r--java/jdeps.go1
-rw-r--r--java/sdk_library.go40
-rw-r--r--remoteexec/remoteexec.go11
20 files changed, 344 insertions, 99 deletions
diff --git a/android/env.go b/android/env.go
index 46bd3d6c5..c7c96d5cf 100644
--- a/android/env.go
+++ b/android/env.go
@@ -15,9 +15,11 @@
package android
import (
+ "fmt"
"os"
"os/exec"
"strings"
+ "syscall"
"android/soong/env"
)
@@ -30,28 +32,59 @@ import (
// a manifest regeneration.
var originalEnv map[string]string
-var SoongDelveListen string
-var SoongDelvePath string
+var soongDelveListen string
+var soongDelvePath string
+var soongDelveEnv []string
func init() {
// Delve support needs to read this environment variable very early, before NewConfig has created a way to
// access originalEnv with dependencies. Store the value where soong_build can find it, it will manually
// ensure the dependencies are created.
- SoongDelveListen = os.Getenv("SOONG_DELVE")
- SoongDelvePath, _ = exec.LookPath("dlv")
+ soongDelveListen = os.Getenv("SOONG_DELVE")
+ soongDelvePath, _ = exec.LookPath("dlv")
originalEnv = make(map[string]string)
+ soongDelveEnv = []string{}
for _, env := range os.Environ() {
idx := strings.IndexRune(env, '=')
if idx != -1 {
originalEnv[env[:idx]] = env[idx+1:]
+ if env[:idx] != "SOONG_DELVE" {
+ soongDelveEnv = append(soongDelveEnv, env)
+ }
}
}
+
// Clear the environment to prevent use of os.Getenv(), which would not provide dependencies on environment
// variable values. The environment is available through ctx.Config().Getenv, ctx.Config().IsEnvTrue, etc.
os.Clearenv()
}
+func ReexecWithDelveMaybe() {
+ if soongDelveListen == "" {
+ return
+ }
+
+ if soongDelvePath == "" {
+ fmt.Fprintln(os.Stderr, "SOONG_DELVE is set but failed to find dlv")
+ os.Exit(1)
+ }
+ dlvArgv := []string{
+ soongDelvePath,
+ "--listen=:" + soongDelveListen,
+ "--headless=true",
+ "--api-version=2",
+ "exec",
+ os.Args[0],
+ "--",
+ }
+ dlvArgv = append(dlvArgv, os.Args[1:]...)
+ os.Chdir(absSrcDir)
+ syscall.Exec(soongDelvePath, dlvArgv, soongDelveEnv)
+ fmt.Fprintln(os.Stderr, "exec() failed while trying to reexec with Delve")
+ os.Exit(1)
+}
+
// getenv checks either os.Getenv or originalEnv so that it works before or after the init()
// function above. It doesn't add any dependencies on the environment variable, so it should
// only be used for values that won't change. For values that might change use ctx.Config().Getenv.
diff --git a/android/module.go b/android/module.go
index 45477ea80..6239d272b 100644
--- a/android/module.go
+++ b/android/module.go
@@ -2366,6 +2366,7 @@ type IdeInfo struct {
Classes []string `json:"class,omitempty"`
Installed_paths []string `json:"installed,omitempty"`
SrcJars []string `json:"srcjars,omitempty"`
+ Paths []string `json:"path,omitempty"`
}
func CheckBlueprintSyntax(ctx BaseModuleContext, filename string, contents string) []error {
diff --git a/android/neverallow.go b/android/neverallow.go
index f9fc03caa..9e075b719 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -55,6 +55,7 @@ func init() {
AddNeverAllowRules(createMediaRules()...)
AddNeverAllowRules(createJavaDeviceForHostRules()...)
AddNeverAllowRules(createCcSdkVariantRules()...)
+ AddNeverAllowRules(createUncompressDexRules()...)
}
// Add a NeverAllow rule to the set of rules to apply.
@@ -210,6 +211,15 @@ func createCcSdkVariantRules() []Rule {
}
}
+func createUncompressDexRules() []Rule {
+ return []Rule{
+ NeverAllow().
+ NotIn("art").
+ WithMatcher("uncompress_dex", isSetMatcherInstance).
+ Because("uncompress_dex is only allowed for certain jars for test in art."),
+ }
+}
+
func neverallowMutator(ctx BottomUpMutatorContext) {
m, ok := ctx.Module().(Module)
if !ok {
diff --git a/android/neverallow_test.go b/android/neverallow_test.go
index 2fc42e31f..85c8c5908 100644
--- a/android/neverallow_test.go
+++ b/android/neverallow_test.go
@@ -303,6 +303,29 @@ var neverallowTests = []struct {
`module "outside_whitelist": violates neverallow`,
},
},
+ {
+ name: "uncompress_dex inside art",
+ fs: map[string][]byte{
+ "art/Android.bp": []byte(`
+ java_library {
+ name: "inside_art_libraries",
+ uncompress_dex: true,
+ }`),
+ },
+ },
+ {
+ name: "uncompress_dex outside art",
+ fs: map[string][]byte{
+ "other/Android.bp": []byte(`
+ java_library {
+ name: "outside_art_libraries",
+ uncompress_dex: true,
+ }`),
+ },
+ expectedErrors: []string{
+ "module \"outside_art_libraries\": violates neverallow",
+ },
+ },
}
func TestNeverallow(t *testing.T) {
@@ -396,8 +419,9 @@ func (p *mockCcLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
}
type mockJavaLibraryProperties struct {
- Libs []string
- Sdk_version *string
+ Libs []string
+ Sdk_version *string
+ Uncompress_dex *bool
}
type mockJavaLibraryModule struct {
diff --git a/apex/apex_test.go b/apex/apex_test.go
index cbe59531d..5d08f37ab 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -19,6 +19,7 @@ import (
"os"
"path"
"reflect"
+ "regexp"
"sort"
"strings"
"testing"
@@ -4256,6 +4257,15 @@ func TestLegacyAndroid10Support(t *testing.T) {
}
}
+var filesForSdkLibrary = map[string][]byte{
+ "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,
+}
+
func TestJavaSDKLibrary(t *testing.T) {
ctx, _ := testApex(t, `
apex {
@@ -4276,14 +4286,7 @@ func TestJavaSDKLibrary(t *testing.T) {
api_packages: ["foo"],
apex_available: [ "myapex" ],
}
- `, withFiles(map[string][]byte{
- "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,
- }))
+ `, withFiles(filesForSdkLibrary))
// java_sdk_library installs both impl jar and permission XML
ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
@@ -4295,6 +4298,98 @@ func TestJavaSDKLibrary(t *testing.T) {
ensureContains(t, sdkLibrary.RuleParams.Command, `<library name=\"foo\" file=\"/apex/myapex/javalib/foo.jar\"`)
}
+func TestJavaSDKLibrary_WithinApex(t *testing.T) {
+ ctx, _ := testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ java_libs: ["foo", "bar"],
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ java_sdk_library {
+ name: "foo",
+ srcs: ["a.java"],
+ api_packages: ["foo"],
+ apex_available: ["myapex"],
+ sdk_version: "none",
+ system_modules: "none",
+ }
+
+ java_library {
+ name: "bar",
+ srcs: ["a.java"],
+ libs: ["foo"],
+ apex_available: ["myapex"],
+ sdk_version: "none",
+ system_modules: "none",
+ }
+ `, withFiles(filesForSdkLibrary))
+
+ // java_sdk_library installs both impl jar and permission XML
+ ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
+ "javalib/bar.jar",
+ "javalib/foo.jar",
+ "etc/permissions/foo.xml",
+ })
+
+ // The bar library should depend on the implementation jar.
+ barLibrary := ctx.ModuleForTests("bar", "android_common_myapex").Rule("javac")
+ if expected, actual := `^-classpath /[^:]*/turbine-combined/foo\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
+ t.Errorf("expected %q, found %#q", expected, actual)
+ }
+}
+
+func TestJavaSDKLibrary_CrossBoundary(t *testing.T) {
+ ctx, _ := testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ java_libs: ["foo"],
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ java_sdk_library {
+ name: "foo",
+ srcs: ["a.java"],
+ api_packages: ["foo"],
+ apex_available: ["myapex"],
+ sdk_version: "none",
+ system_modules: "none",
+ }
+
+ java_library {
+ name: "bar",
+ srcs: ["a.java"],
+ libs: ["foo"],
+ sdk_version: "none",
+ system_modules: "none",
+ }
+ `, withFiles(filesForSdkLibrary))
+
+ // java_sdk_library installs both impl jar and permission XML
+ ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
+ "javalib/foo.jar",
+ "etc/permissions/foo.xml",
+ })
+
+ // The bar library should depend on the stubs jar.
+ barLibrary := ctx.ModuleForTests("bar", "android_common").Rule("javac")
+ if expected, actual := `^-classpath /[^:]*/turbine-combined/foo\.stubs\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
+ t.Errorf("expected %q, found %#q", expected, actual)
+ }
+}
+
func TestCompatConfig(t *testing.T) {
ctx, _ := testApex(t, `
apex {
diff --git a/apex/builder.go b/apex/builder.go
index 3d0e9b254..11652bc67 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -470,11 +470,11 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) {
}
targetSdkVersion := ctx.Config().DefaultAppTargetSdk()
+ // TODO(b/157078772): propagate min_sdk_version to apexer.
minSdkVersion := ctx.Config().DefaultAppTargetSdk()
if a.minSdkVersion(ctx) == android.SdkVersion_Android10 {
minSdkVersion = strconv.Itoa(a.minSdkVersion(ctx))
- targetSdkVersion = strconv.Itoa(a.minSdkVersion(ctx))
}
if java.UseApiFingerprint(ctx) {
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index bd1a9edfa..905f2068b 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -18,12 +18,7 @@ import (
"flag"
"fmt"
"os"
- "os/exec"
"path/filepath"
- "strconv"
- "strings"
- "syscall"
- "time"
"github.com/google/blueprint/bootstrap"
@@ -55,42 +50,7 @@ func newNameResolver(config android.Config) *android.NameResolver {
}
func main() {
- if android.SoongDelveListen != "" {
- if android.SoongDelvePath == "" {
- fmt.Fprintln(os.Stderr, "SOONG_DELVE is set but failed to find dlv")
- os.Exit(1)
- }
- pid := strconv.Itoa(os.Getpid())
- cmd := []string{android.SoongDelvePath,
- "attach", pid,
- "--headless",
- "-l", android.SoongDelveListen,
- "--api-version=2",
- "--accept-multiclient",
- "--log",
- }
-
- fmt.Println("Starting", strings.Join(cmd, " "))
- dlv := exec.Command(cmd[0], cmd[1:]...)
- dlv.Stdout = os.Stdout
- dlv.Stderr = os.Stderr
- dlv.Stdin = nil
-
- // Put dlv into its own process group so we can kill it and the child process it starts.
- dlv.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
-
- err := dlv.Start()
- if err != nil {
- // Print the error starting dlv and continue.
- fmt.Println(err)
- } else {
- // Kill the process group for dlv when soong_build exits.
- defer syscall.Kill(-dlv.Process.Pid, syscall.SIGKILL)
- // Wait to give dlv a chance to connect and pause the process.
- time.Sleep(time.Second)
- }
- }
-
+ android.ReexecWithDelveMaybe()
flag.Parse()
// The top-level Blueprints file is passed as the first argument.
diff --git a/genrule/genrule.go b/genrule/genrule.go
index fe877fe8d..f6904f195 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -144,6 +144,9 @@ type Module struct {
subName string
subDir string
+
+ // Collect the module directory for IDE info in java/jdeps.go.
+ modulePaths []string
}
type taskFunc func(ctx android.ModuleContext, rawCommand string, srcFiles android.Paths) []generateTask
@@ -190,6 +193,9 @@ func toolDepsMutator(ctx android.BottomUpMutatorContext) {
func (g *Module) GenerateAndroidBuildActions(ctx android.ModuleContext) {
g.subName = ctx.ModuleSubDir()
+ // Collect the module directory for IDE info in java/jdeps.go.
+ g.modulePaths = append(g.modulePaths, ctx.ModuleDir())
+
if len(g.properties.Export_include_dirs) > 0 {
for _, dir := range g.properties.Export_include_dirs {
g.exportedIncludeDirs = append(g.exportedIncludeDirs,
@@ -529,6 +535,7 @@ func (g *Module) IDEInfo(dpInfo *android.IdeInfo) {
dpInfo.Deps = append(dpInfo.Deps, src)
}
}
+ dpInfo.Paths = append(dpInfo.Paths, g.modulePaths...)
}
func (g *Module) AndroidMk() android.AndroidMkData {
diff --git a/java/androidmk.go b/java/androidmk.go
index 6747b30b0..5e3b7d2cb 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -512,14 +512,12 @@ func (ddoc *Droiddoc) AndroidMkEntries() []android.AndroidMkEntries {
fmt.Fprintln(w, ddoc.Name()+"-check-last-released-api:",
ddoc.checkLastReleasedApiTimestamp.String())
- if ddoc.Name() == "api-stubs-docs" || ddoc.Name() == "system-api-stubs-docs" {
- fmt.Fprintln(w, ".PHONY: checkapi")
- fmt.Fprintln(w, "checkapi:",
- ddoc.checkLastReleasedApiTimestamp.String())
+ fmt.Fprintln(w, ".PHONY: checkapi")
+ fmt.Fprintln(w, "checkapi:",
+ ddoc.checkLastReleasedApiTimestamp.String())
- fmt.Fprintln(w, ".PHONY: droidcore")
- fmt.Fprintln(w, "droidcore: checkapi")
- }
+ fmt.Fprintln(w, ".PHONY: droidcore")
+ fmt.Fprintln(w, "droidcore: checkapi")
}
},
},
diff --git a/java/app.go b/java/app.go
index 8241b6842..40815dea6 100755
--- a/java/app.go
+++ b/java/app.go
@@ -568,16 +568,17 @@ func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) android.Path {
installDir = filepath.Join("app", a.installApkName)
}
a.dexpreopter.installPath = android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
- a.dexpreopter.uncompressedDex = a.shouldUncompressDex(ctx)
-
+ if a.deviceProperties.Uncompress_dex == nil {
+ // If the value was not force-set by the user, use reasonable default based on the module.
+ a.deviceProperties.Uncompress_dex = proptools.BoolPtr(a.shouldUncompressDex(ctx))
+ }
+ a.dexpreopter.uncompressedDex = *a.deviceProperties.Uncompress_dex
a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries()
a.dexpreopter.usesLibs = a.usesLibrary.usesLibraryProperties.Uses_libs
a.dexpreopter.optionalUsesLibs = a.usesLibrary.presentOptionalUsesLibs(ctx)
a.dexpreopter.libraryPaths = a.usesLibrary.usesLibraryPaths(ctx)
a.dexpreopter.manifestFile = a.mergedManifestFile
- a.deviceProperties.UncompressDex = a.dexpreopter.uncompressedDex
-
if ctx.ModuleName() != "framework-res" {
a.Module.compile(ctx, a.aaptSrcJar)
}
@@ -1613,7 +1614,8 @@ func AndroidAppImportFactory() android.Module {
})
android.InitApexModule(module)
- InitJavaModule(module, android.DeviceSupported)
+ android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
+ android.InitDefaultableModule(module)
android.InitSingleSourcePrebuiltModule(module, &module.properties, "Apk")
return module
diff --git a/java/app_test.go b/java/app_test.go
index 1a718f4b3..105afd292 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -2806,6 +2806,32 @@ func TestUncompressDex(t *testing.T) {
uncompressedPlatform: true,
uncompressedUnbundled: true,
},
+ {
+ name: "normal_uncompress_dex_true",
+ bp: `
+ android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ sdk_version: "current",
+ uncompress_dex: true,
+ }
+ `,
+ uncompressedPlatform: true,
+ uncompressedUnbundled: true,
+ },
+ {
+ name: "normal_uncompress_dex_false",
+ bp: `
+ android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ sdk_version: "current",
+ uncompress_dex: false,
+ }
+ `,
+ uncompressedPlatform: false,
+ uncompressedUnbundled: false,
+ },
}
test := func(t *testing.T, bp string, want bool, unbundled bool) {
diff --git a/java/builder.go b/java/builder.go
index b8340295b..b6cb2aeeb 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -116,10 +116,10 @@ var (
},
"abis", "allow-prereleased", "screen-densities", "sdk-version", "stem")
- turbine = pctx.AndroidStaticRule("turbine",
+ turbine, turbineRE = remoteexec.StaticRules(pctx, "turbine",
blueprint.RuleParams{
Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
- `${config.JavaCmd} ${config.JavaVmFlags} -jar ${config.TurbineJar} --output $out.tmp ` +
+ `$reTemplate${config.JavaCmd} ${config.JavaVmFlags} -jar ${config.TurbineJar} --output $out.tmp ` +
`--temp_dir "$outDir" --sources @$out.rsp --source_jars $srcJars ` +
`--javacopts ${config.CommonJdkFlags} ` +
`$javacFlags -source $javaVersion -target $javaVersion -- $bootClasspath $classpath && ` +
@@ -134,7 +134,15 @@ var (
RspfileContent: "$in",
Restat: true,
},
- "javacFlags", "bootClasspath", "classpath", "srcJars", "outDir", "javaVersion")
+ &remoteexec.REParams{Labels: map[string]string{"type": "tool", "name": "turbine"},
+ ExecStrategy: "${config.RETurbineExecStrategy}",
+ Inputs: []string{"${config.TurbineJar}", "${out}.rsp", "$implicits"},
+ RSPFile: "${out}.rsp",
+ OutputFiles: []string{"$out.tmp"},
+ OutputDirectories: []string{"$outDir"},
+ ToolchainInputs: []string{"${config.JavaCmd}"},
+ Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+ }, []string{"javacFlags", "bootClasspath", "classpath", "srcJars", "outDir", "javaVersion"}, []string{"implicits"})
jar = pctx.AndroidStaticRule("jar",
blueprint.RuleParams{
@@ -346,20 +354,26 @@ func TransformJavaToHeaderClasses(ctx android.ModuleContext, outputFile android.
deps = append(deps, classpath...)
deps = append(deps, flags.processorPath...)
+ rule := turbine
+ args := map[string]string{
+ "javacFlags": flags.javacFlags,
+ "bootClasspath": bootClasspath,
+ "srcJars": strings.Join(srcJars.Strings(), " "),
+ "classpath": classpath.FormTurbineClassPath("--classpath "),
+ "outDir": android.PathForModuleOut(ctx, "turbine", "classes").String(),
+ "javaVersion": flags.javaVersion.String(),
+ }
+ if ctx.Config().IsEnvTrue("RBE_TURBINE") {
+ rule = turbineRE
+ args["implicits"] = strings.Join(deps.Strings(), ",")
+ }
ctx.Build(pctx, android.BuildParams{
- Rule: turbine,
+ Rule: rule,
Description: "turbine",
Output: outputFile,
Inputs: srcFiles,
Implicits: deps,
- Args: map[string]string{
- "javacFlags": flags.javacFlags,
- "bootClasspath": bootClasspath,
- "srcJars": strings.Join(srcJars.Strings(), " "),
- "classpath": classpath.FormTurbineClassPath("--classpath "),
- "outDir": android.PathForModuleOut(ctx, "turbine", "classes").String(),
- "javaVersion": flags.javaVersion.String(),
- },
+ Args: args,
})
}
diff --git a/java/config/config.go b/java/config/config.go
index 1344ceb22..fa19afbf5 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -148,6 +148,7 @@ func init() {
pctx.VariableFunc("REJavacExecStrategy", remoteexec.EnvOverrideFunc("RBE_JAVAC_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
pctx.VariableFunc("RED8ExecStrategy", remoteexec.EnvOverrideFunc("RBE_D8_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
pctx.VariableFunc("RER8ExecStrategy", remoteexec.EnvOverrideFunc("RBE_R8_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
+ pctx.VariableFunc("RETurbineExecStrategy", remoteexec.EnvOverrideFunc("RBE_TURBINE_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
pctx.HostJavaToolVariable("JacocoCLIJar", "jacoco-cli.jar")
diff --git a/java/dex.go b/java/dex.go
index 27ec6ee41..e2a8e7eae 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -18,6 +18,7 @@ import (
"strings"
"github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
"android/soong/android"
"android/soong/remoteexec"
@@ -188,7 +189,7 @@ func (j *Module) compileDex(ctx android.ModuleContext, flags javaBuilderFlags,
outDir := android.PathForModuleOut(ctx, "dex")
zipFlags := "--ignore_missing_files"
- if j.deviceProperties.UncompressDex {
+ if proptools.Bool(j.deviceProperties.Uncompress_dex) {
zipFlags += " -L 0"
}
@@ -235,7 +236,7 @@ func (j *Module) compileDex(ctx android.ModuleContext, flags javaBuilderFlags,
},
})
}
- if j.deviceProperties.UncompressDex {
+ if proptools.Bool(j.deviceProperties.Uncompress_dex) {
alignedJavalibJar := android.PathForModuleOut(ctx, "aligned", jarName)
TransformZipAlign(ctx, alignedJavalibJar, javalibJar)
javalibJar = alignedJavalibJar
diff --git a/java/droiddoc.go b/java/droiddoc.go
index a5a678522..821bb6d7d 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -546,7 +546,7 @@ func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
case libTag:
switch dep := module.(type) {
case SdkLibraryDependency:
- deps.classpath = append(deps.classpath, dep.SdkImplementationJars(ctx, j.sdkVersion())...)
+ deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.sdkVersion())...)
case Dependency:
deps.classpath = append(deps.classpath, dep.HeaderJars()...)
deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
diff --git a/java/java.go b/java/java.go
index b97defa88..466132e1e 100644
--- a/java/java.go
+++ b/java/java.go
@@ -342,8 +342,13 @@ type CompilerDeviceProperties struct {
// set the name of the output
Stem *string
- UncompressDex bool `blueprint:"mutated"`
- IsSDKLibrary bool `blueprint:"mutated"`
+ // Keep the data uncompressed. We always need uncompressed dex for execution,
+ // so this might actually save space by avoiding storing the same data twice.
+ // This defaults to reasonable value based on module and should not be set.
+ // It exists only to support ART tests.
+ Uncompress_dex *bool
+
+ IsSDKLibrary bool `blueprint:"mutated"`
}
func (me *CompilerDeviceProperties) EffectiveOptimizeEnabled() bool {
@@ -471,6 +476,9 @@ type Module struct {
kytheFiles android.Paths
distFile android.Path
+
+ // Collect the module directory for IDE info in java/jdeps.go.
+ modulePaths []string
}
func (j *Module) OutputFiles(tag string) (android.Paths, error) {
@@ -1567,7 +1575,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
// Hidden API CSV generation and dex encoding
dexOutputFile = j.hiddenAPI.hiddenAPI(ctx, dexOutputFile, j.implementationJarFile,
- j.deviceProperties.UncompressDex)
+ proptools.Bool(j.deviceProperties.Uncompress_dex))
// merge dex jar with resources if necessary
if j.resourceJar != nil {
@@ -1575,7 +1583,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
combinedJar := android.PathForModuleOut(ctx, "dex-withres", jarName)
TransformJarsToJar(ctx, combinedJar, "for dex resources", jars, android.OptionalPath{},
false, nil, nil)
- if j.deviceProperties.UncompressDex {
+ if *j.deviceProperties.Uncompress_dex {
combinedAlignedJar := android.PathForModuleOut(ctx, "dex-withres-aligned", jarName)
TransformZipAlign(ctx, combinedAlignedJar, combinedJar)
dexOutputFile = combinedAlignedJar
@@ -1776,6 +1784,7 @@ func (j *Module) IDEInfo(dpInfo *android.IdeInfo) {
if j.expandJarjarRules != nil {
dpInfo.Jarjar_rules = append(dpInfo.Jarjar_rules, j.expandJarjarRules.String())
}
+ dpInfo.Paths = append(dpInfo.Paths, j.modulePaths...)
}
func (j *Module) CompilerDeps() []string {
@@ -1852,10 +1861,16 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.checkSdkVersions(ctx)
j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")
j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary
- j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter)
- j.deviceProperties.UncompressDex = j.dexpreopter.uncompressedDex
+ if j.deviceProperties.Uncompress_dex == nil {
+ // If the value was not force-set by the user, use reasonable default based on the module.
+ j.deviceProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, &j.dexpreopter))
+ }
+ j.dexpreopter.uncompressedDex = *j.deviceProperties.Uncompress_dex
j.compile(ctx, nil)
+ // Collect the module directory for IDE info in java/jdeps.go.
+ j.modulePaths = append(j.modulePaths, ctx.ModuleDir())
+
exclusivelyForApex := android.InAnyApex(ctx.ModuleName()) && !j.IsForPlatform()
if (Bool(j.properties.Installable) || ctx.Host()) && !exclusivelyForApex {
var extraInstallDeps android.Paths
diff --git a/java/java_test.go b/java/java_test.go
index ab6d88ed6..e03e57b78 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -19,6 +19,7 @@ import (
"os"
"path/filepath"
"reflect"
+ "regexp"
"sort"
"strconv"
"strings"
@@ -1261,6 +1262,31 @@ func TestJavaSdkLibrary(t *testing.T) {
}
}
+func TestJavaSdkLibrary_DoNotAccessImplWhenItIsNotBuilt(t *testing.T) {
+ ctx, _ := testJava(t, `
+ java_sdk_library {
+ name: "foo",
+ srcs: ["a.java"],
+ api_only: true,
+ public: {
+ enabled: true,
+ },
+ }
+
+ java_library {
+ name: "bar",
+ srcs: ["b.java"],
+ libs: ["foo"],
+ }
+ `)
+
+ // The bar library should depend on the stubs jar.
+ barLibrary := ctx.ModuleForTests("bar", "android_common").Rule("javac")
+ if expected, actual := `^-classpath .*:/[^:]*/turbine-combined/foo\.stubs\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
+ t.Errorf("expected %q, found %#q", expected, actual)
+ }
+}
+
func TestJavaSdkLibrary_UseSourcesFromAnotherSdkLibrary(t *testing.T) {
testJava(t, `
java_sdk_library {
diff --git a/java/jdeps.go b/java/jdeps.go
index 49e3de3cc..9f4388733 100644
--- a/java/jdeps.go
+++ b/java/jdeps.go
@@ -72,6 +72,7 @@ func (j *jdepsGeneratorSingleton) GenerateBuildActions(ctx android.SingletonCont
dpInfo.Jarjar_rules = android.FirstUniqueStrings(dpInfo.Jarjar_rules)
dpInfo.Jars = android.FirstUniqueStrings(dpInfo.Jars)
dpInfo.SrcJars = android.FirstUniqueStrings(dpInfo.SrcJars)
+ dpInfo.Paths = android.FirstUniqueStrings(dpInfo.Paths)
moduleInfos[name] = dpInfo
mkProvider, ok := module.(android.AndroidMkDataProvider)
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 823127896..b487efdbd 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -1293,17 +1293,39 @@ func PrebuiltJars(ctx android.BaseModuleContext, baseName string, s sdkSpec) and
return android.Paths{jarPath.Path()}
}
+// Get the apex name for module, "" if it is for platform.
+func getApexNameForModule(module android.Module) string {
+ if apex, ok := module.(android.ApexModule); ok {
+ return apex.ApexName()
+ }
+
+ return ""
+}
+
+// Check to see if the other module is within the same named APEX as this module.
+//
+// If either this or the other module are on the platform then this will return
+// false.
+func (module *SdkLibrary) withinSameApexAs(other android.Module) bool {
+ name := module.ApexName()
+ return name != "" && getApexNameForModule(other) == name
+}
+
func (module *SdkLibrary) sdkJars(ctx android.BaseModuleContext, sdkVersion sdkSpec, headerJars bool) android.Paths {
- // Check any special cases for java_sdk_library.
- //
- // Only allow access to the implementation library in the following condition:
- // * No sdk_version specified on the referencing module.
- if sdkVersion.kind == sdkPrivate {
- if headerJars {
- return module.HeaderJars()
- } else {
- return module.ImplementationJars()
+ // Only provide access to the implementation library if it is actually built.
+ if module.requiresRuntimeImplementationLibrary() {
+ // Check any special cases for java_sdk_library.
+ //
+ // Only allow access to the implementation library in the following condition:
+ // * No sdk_version specified on the referencing module.
+ // * The referencing module is in the same apex as this.
+ if sdkVersion.kind == sdkPrivate || module.withinSameApexAs(ctx.Module()) {
+ if headerJars {
+ return module.HeaderJars()
+ } else {
+ return module.ImplementationJars()
+ }
}
}
diff --git a/remoteexec/remoteexec.go b/remoteexec/remoteexec.go
index 99e29dc0f..2b513b244 100644
--- a/remoteexec/remoteexec.go
+++ b/remoteexec/remoteexec.go
@@ -75,6 +75,9 @@ type REParams struct {
// OutputFiles is a list of output file paths or ninja variables as placeholders for rule
// outputs.
OutputFiles []string
+ // OutputDirectories is a list of output directory paths or ninja variables as placeholders
+ // for rule outputs.
+ OutputDirectories []string
// ToolchainInputs is a list of paths or ninja variables pointing to the location of
// toolchain binaries used by the rule.
ToolchainInputs []string
@@ -151,6 +154,10 @@ func (r *REParams) wrapperArgs() string {
args += " --output_files=" + strings.Join(r.OutputFiles, ",")
}
+ if len(r.OutputDirectories) > 0 {
+ args += " --output_directories=" + strings.Join(r.OutputDirectories, ",")
+ }
+
if len(r.ToolchainInputs) > 0 {
args += " --toolchain_inputs=" + strings.Join(r.ToolchainInputs, ",")
}
@@ -159,7 +166,9 @@ func (r *REParams) wrapperArgs() string {
}
// StaticRules returns a pair of rules based on the given RuleParams, where the first rule is a
-// locally executable rule and the second rule is a remotely executable rule.
+// locally executable rule and the second rule is a remotely executable rule. commonArgs are args
+// used for both the local and remotely executable rules. reArgs are used only for remote
+// execution.
func StaticRules(ctx android.PackageContext, name string, ruleParams blueprint.RuleParams, reParams *REParams, commonArgs []string, reArgs []string) (blueprint.Rule, blueprint.Rule) {
ruleParamsRE := ruleParams
ruleParams.Command = strings.ReplaceAll(ruleParams.Command, "$reTemplate", "")