From ca65b40fa02f7103363772c2d020dec04a8f93ec Mon Sep 17 00:00:00 2001 From: Zi Wang Date: Mon, 10 Oct 2022 13:45:06 -0700 Subject: [PATCH] Generate a default wrapper for device java_binary Any device java_binary that doesn't have a specific wrapper must have a main_class property, which is used to generate its default wrapper. Otherwise its build should fail. Bug: 250851599 Test: TestDeviceBinaryWrapperGeneration in java_test.go Change-Id: Ice4c580bcfc1b92f95e217b39e984c55d25a3a02 --- java/dexpreopt_test.go | 1 + java/java.go | 34 +++++++++++++++++++++++++++++++++- java/java_test.go | 23 +++++++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/java/dexpreopt_test.go b/java/dexpreopt_test.go index 1c1070add..3d2c5c3a1 100644 --- a/java/dexpreopt_test.go +++ b/java/dexpreopt_test.go @@ -63,6 +63,7 @@ func TestDexpreoptEnabled(t *testing.T) { java_binary { name: "foo", srcs: ["a.java"], + main_class: "foo.bar.jb", }`, enabled: true, }, diff --git a/java/java.go b/java/java.go index 5091d26a2..8f1d2be7a 100644 --- a/java/java.go +++ b/java/java.go @@ -211,6 +211,14 @@ var ( PropertyName: "java_tests", }, } + + // Rule for generating device binary default wrapper + deviceBinaryWrapper = pctx.StaticRule("deviceBinaryWrapper", blueprint.RuleParams{ + Command: `echo -e '#!/system/bin/sh\n` + + `export CLASSPATH=/system/framework/$jar_name\n` + + `exec app_process /$partition/bin $main_class "$$@"'> ${out}`, + Description: "Generating device binary wrapper ${jar_name}", + }, "jar_name", "partition", "main_class") ) // JavaInfo contains information about a java module for use by modules that depend on it. @@ -1398,7 +1406,31 @@ func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.PropertyErrorf("wrapper", "wrapper is required for Windows") } - j.wrapperFile = android.PathForSource(ctx, "build/soong/scripts/jar-wrapper.sh") + if ctx.Device() { + // device binary should have a main_class property if it does not + // have a specific wrapper, so that a default wrapper can + // be generated for it. + if j.binaryProperties.Main_class == nil { + ctx.PropertyErrorf("main_class", "main_class property "+ + "is required for device binary if no default wrapper is assigned") + } else { + wrapper := android.PathForModuleOut(ctx, ctx.ModuleName()+".sh") + jarName := j.Stem() + ".jar" + partition := j.PartitionTag(ctx.DeviceConfig()) + ctx.Build(pctx, android.BuildParams{ + Rule: deviceBinaryWrapper, + Output: wrapper, + Args: map[string]string{ + "jar_name": jarName, + "partition": partition, + "main_class": String(j.binaryProperties.Main_class), + }, + }) + j.wrapperFile = wrapper + } + } else { + j.wrapperFile = android.PathForSource(ctx, "build/soong/scripts/jar-wrapper.sh") + } } ext := "" diff --git a/java/java_test.go b/java/java_test.go index 3b86f9aa4..f06b520d5 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -1783,3 +1783,26 @@ func TestGenAidlIncludeFlagsForMixedBuilds(t *testing.T) { t.Errorf("expected flags to be %q; was %q", expectedFlags, flags) } } + +func TestDeviceBinaryWrapperGeneration(t *testing.T) { + // Scenario 1: java_binary has main_class property in its bp + ctx, _ := testJava(t, ` + java_binary { + name: "foo", + srcs: ["foo.java"], + main_class: "foo.bar.jb", + } + `) + wrapperPath := fmt.Sprint(ctx.ModuleForTests("foo", "android_arm64_armv8-a").AllOutputs()) + if !strings.Contains(wrapperPath, "foo.sh") { + t.Errorf("wrapper file foo.sh is not generated") + } + + // Scenario 2: java_binary has neither wrapper nor main_class, its build + // is expected to be failed. + testJavaError(t, "main_class property is required for device binary if no default wrapper is assigned", ` + java_binary { + name: "foo", + srcs: ["foo.java"], + }`) +}