Split java_binary modules into common and binary variants

am: 6b4a32d771

Change-Id: I6da3e0b26b39e079769dbaed65903416f9fa1ebb
This commit is contained in:
Colin Cross
2017-12-06 04:27:01 +00:00
committed by android-build-merger
5 changed files with 120 additions and 53 deletions

View File

@@ -1072,19 +1072,30 @@ func getCommonTargets(targets []Target) []Target {
return ret return ret
} }
func preferTargets(targets []Target, filters ...string) []Target {
for _, filter := range filters {
buildTargets := filterMultilibTargets(targets, filter)
if len(buildTargets) > 0 {
return buildTargets
}
}
return nil
}
// Use the module multilib setting to select one or more targets from a target list // Use the module multilib setting to select one or more targets from a target list
func decodeMultilib(multilib string, targets []Target, prefer32 bool) ([]Target, error) { func decodeMultilib(multilib string, targets []Target, prefer32 bool) ([]Target, error) {
buildTargets := []Target{} buildTargets := []Target{}
if multilib == "first" {
if prefer32 {
multilib = "prefer32"
} else {
multilib = "prefer64"
}
}
switch multilib { switch multilib {
case "common": case "common":
buildTargets = append(buildTargets, getCommonTargets(targets)...) buildTargets = getCommonTargets(targets)
case "common_first":
buildTargets = getCommonTargets(targets)
if prefer32 {
buildTargets = append(buildTargets, preferTargets(targets, "lib32", "lib64")...)
} else {
buildTargets = append(buildTargets, preferTargets(targets, "lib64", "lib32")...)
}
case "both": case "both":
if prefer32 { if prefer32 {
buildTargets = append(buildTargets, filterMultilibTargets(targets, "lib32")...) buildTargets = append(buildTargets, filterMultilibTargets(targets, "lib32")...)
@@ -1097,16 +1108,14 @@ func decodeMultilib(multilib string, targets []Target, prefer32 bool) ([]Target,
buildTargets = filterMultilibTargets(targets, "lib32") buildTargets = filterMultilibTargets(targets, "lib32")
case "64": case "64":
buildTargets = filterMultilibTargets(targets, "lib64") buildTargets = filterMultilibTargets(targets, "lib64")
case "first":
if prefer32 {
buildTargets = preferTargets(targets, "lib32", "lib64")
} else {
buildTargets = preferTargets(targets, "lib64", "lib32")
}
case "prefer32": case "prefer32":
buildTargets = filterMultilibTargets(targets, "lib32") buildTargets = preferTargets(targets, "lib32", "lib64")
if len(buildTargets) == 0 {
buildTargets = filterMultilibTargets(targets, "lib64")
}
case "prefer64":
buildTargets = filterMultilibTargets(targets, "lib64")
if len(buildTargets) == 0 {
buildTargets = filterMultilibTargets(targets, "lib32")
}
default: default:
return nil, fmt.Errorf(`compile_multilib must be "both", "first", "32", "64", or "prefer32" found %q`, return nil, fmt.Errorf(`compile_multilib must be "both", "first", "32", "64", or "prefer32" found %q`,
multilib) multilib)

View File

@@ -248,10 +248,11 @@ type hostAndDeviceProperties struct {
type Multilib string type Multilib string
const ( const (
MultilibBoth Multilib = "both" MultilibBoth Multilib = "both"
MultilibFirst Multilib = "first" MultilibFirst Multilib = "first"
MultilibCommon Multilib = "common" MultilibCommon Multilib = "common"
MultilibDefault Multilib = "" MultilibCommonFirst Multilib = "common_first"
MultilibDefault Multilib = ""
) )
type HostOrDeviceSupported int type HostOrDeviceSupported int

View File

@@ -95,28 +95,35 @@ func (prebuilt *Import) AndroidMk() android.AndroidMkData {
} }
func (binary *Binary) AndroidMk() android.AndroidMkData { func (binary *Binary) AndroidMk() android.AndroidMkData {
return android.AndroidMkData{
Class: "JAVA_LIBRARIES",
OutputFile: android.OptionalPathForPath(binary.implementationJarFile),
Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
android.WriteAndroidMkData(w, data)
fmt.Fprintln(w, "jar_installed_module := $(LOCAL_INSTALLED_MODULE)") if !binary.isWrapperVariant {
fmt.Fprintln(w, "include $(CLEAR_VARS)") return android.AndroidMkData{
fmt.Fprintln(w, "LOCAL_MODULE := "+name) Class: "JAVA_LIBRARIES",
fmt.Fprintln(w, "LOCAL_MODULE_CLASS := EXECUTABLES") OutputFile: android.OptionalPathForPath(binary.implementationJarFile),
if strings.Contains(prefix, "HOST_") { Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
fmt.Fprintln(w, "LOCAL_IS_HOST_MODULE := true") Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
} android.WriteAndroidMkData(w, data)
fmt.Fprintln(w, "LOCAL_STRIP_MODULE := false")
fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", binary.wrapperFile.String())
fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
// Ensure that the wrapper script timestamp is always updated when the jar is updated fmt.Fprintln(w, "jar_installed_module := $(LOCAL_INSTALLED_MODULE)")
fmt.Fprintln(w, "$(LOCAL_INSTALLED_MODULE): $(jar_installed_module)") },
fmt.Fprintln(w, "jar_installed_module :=") }
}, } else {
return android.AndroidMkData{
Class: "EXECUTABLES",
OutputFile: android.OptionalPathForPath(binary.wrapperFile),
Extra: []android.AndroidMkExtraFunc{
func(w io.Writer, outputFile android.Path) {
fmt.Fprintln(w, "LOCAL_STRIP_MODULE := false")
},
},
Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
android.WriteAndroidMkData(w, data)
// Ensure that the wrapper script timestamp is always updated when the jar is updated
fmt.Fprintln(w, "$(LOCAL_INSTALLED_MODULE): $(jar_installed_module)")
fmt.Fprintln(w, "jar_installed_module :=")
},
}
} }
} }

View File

@@ -1014,6 +1014,8 @@ type Binary struct {
binaryProperties binaryProperties binaryProperties binaryProperties
isWrapperVariant bool
wrapperFile android.SourcePath wrapperFile android.SourcePath
binaryFile android.OutputPath binaryFile android.OutputPath
} }
@@ -1023,21 +1025,32 @@ func (j *Binary) HostToolPath() android.OptionalPath {
} }
func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) { func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.Library.GenerateAndroidBuildActions(ctx) if ctx.Arch().ArchType == android.Common {
// Compile the jar
// Depend on the installed jar (j.installFile) so that the wrapper doesn't get executed by j.Library.GenerateAndroidBuildActions(ctx)
// another build rule before the jar has been installed.
if String(j.binaryProperties.Wrapper) != "" {
j.wrapperFile = android.PathForModuleSrc(ctx, String(j.binaryProperties.Wrapper)).SourcePath
} else { } else {
j.wrapperFile = android.PathForSource(ctx, "build/soong/scripts/jar-wrapper.sh") // Handle the binary wrapper
j.isWrapperVariant = true
if String(j.binaryProperties.Wrapper) != "" {
j.wrapperFile = android.PathForModuleSrc(ctx, String(j.binaryProperties.Wrapper)).SourcePath
} else {
j.wrapperFile = android.PathForSource(ctx, "build/soong/scripts/jar-wrapper.sh")
}
// Depend on the installed jar so that the wrapper doesn't get executed by
// another build rule before the jar has been installed.
jarFile := ctx.PrimaryModule().(*Binary).installFile
j.binaryFile = ctx.InstallExecutable(android.PathForModuleInstall(ctx, "bin"),
ctx.ModuleName(), j.wrapperFile, jarFile)
} }
j.binaryFile = ctx.InstallExecutable(android.PathForModuleInstall(ctx, "bin"),
ctx.ModuleName(), j.wrapperFile, j.installFile)
} }
func (j *Binary) DepsMutator(ctx android.BottomUpMutatorContext) { func (j *Binary) DepsMutator(ctx android.BottomUpMutatorContext) {
j.deps(ctx) if ctx.Arch().ArchType == android.Common {
j.deps(ctx)
}
} }
func BinaryFactory() android.Module { func BinaryFactory() android.Module {
@@ -1049,7 +1062,8 @@ func BinaryFactory() android.Module {
&module.Module.protoProperties, &module.Module.protoProperties,
&module.binaryProperties) &module.binaryProperties)
InitJavaModule(module, android.HostAndDeviceSupported) android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommonFirst)
android.InitDefaultableModule(module)
return module return module
} }
@@ -1062,7 +1076,8 @@ func BinaryHostFactory() android.Module {
&module.Module.protoProperties, &module.Module.protoProperties,
&module.binaryProperties) &module.binaryProperties)
InitJavaModule(module, android.HostSupported) android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommonFirst)
android.InitDefaultableModule(module)
return module return module
} }

View File

@@ -62,6 +62,7 @@ func testContext(config android.Config, bp string,
ctx := android.NewTestArchContext() ctx := android.NewTestArchContext()
ctx.RegisterModuleType("android_app", android.ModuleFactoryAdaptor(AndroidAppFactory)) ctx.RegisterModuleType("android_app", android.ModuleFactoryAdaptor(AndroidAppFactory))
ctx.RegisterModuleType("java_binary_host", android.ModuleFactoryAdaptor(BinaryHostFactory))
ctx.RegisterModuleType("java_library", android.ModuleFactoryAdaptor(LibraryFactory(true))) ctx.RegisterModuleType("java_library", android.ModuleFactoryAdaptor(LibraryFactory(true)))
ctx.RegisterModuleType("java_library_host", android.ModuleFactoryAdaptor(LibraryHostFactory)) ctx.RegisterModuleType("java_library_host", android.ModuleFactoryAdaptor(LibraryHostFactory))
ctx.RegisterModuleType("java_import", android.ModuleFactoryAdaptor(ImportFactory)) ctx.RegisterModuleType("java_import", android.ModuleFactoryAdaptor(ImportFactory))
@@ -147,6 +148,8 @@ func testContext(config android.Config, bp string,
// For framework-res, which is an implicit dependency for framework // For framework-res, which is an implicit dependency for framework
"AndroidManifest.xml": nil, "AndroidManifest.xml": nil,
"build/target/product/security/testkey": nil, "build/target/product/security/testkey": nil,
"build/soong/scripts/jar-wrapper.sh": nil,
} }
for k, v := range fs { for k, v := range fs {
@@ -159,6 +162,7 @@ func testContext(config android.Config, bp string,
} }
func run(t *testing.T, ctx *android.TestContext, config android.Config) { func run(t *testing.T, ctx *android.TestContext, config android.Config) {
t.Helper()
_, errs := ctx.ParseFileList(".", []string{"Android.bp"}) _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
fail(t, errs) fail(t, errs)
_, errs = ctx.PrepareBuildActions(config) _, errs = ctx.PrepareBuildActions(config)
@@ -166,6 +170,7 @@ func run(t *testing.T, ctx *android.TestContext, config android.Config) {
} }
func testJava(t *testing.T, bp string) *android.TestContext { func testJava(t *testing.T, bp string) *android.TestContext {
t.Helper()
config := testConfig(nil) config := testConfig(nil)
ctx := testContext(config, bp, nil) ctx := testContext(config, bp, nil)
run(t, ctx, config) run(t, ctx, config)
@@ -250,6 +255,35 @@ func TestArchSpecific(t *testing.T) {
} }
} }
func TestBinary(t *testing.T) {
ctx := testJava(t, `
java_library_host {
name: "foo",
srcs: ["a.java"],
}
java_binary_host {
name: "bar",
srcs: ["b.java"],
static_libs: ["foo"],
}
`)
buildOS := android.BuildOs.String()
bar := ctx.ModuleForTests("bar", buildOS+"_common")
barJar := bar.Output("bar.jar").Output.String()
barWrapper := ctx.ModuleForTests("bar", buildOS+"_x86_64")
barWrapperDeps := barWrapper.Output("bar").Implicits.Strings()
// Test that the install binary wrapper depends on the installed jar file
if len(barWrapperDeps) != 1 || barWrapperDeps[0] != barJar {
t.Errorf("expected binary wrapper implicits [%q], got %v",
barJar, barWrapperDeps)
}
}
var classpathTestcases = []struct { var classpathTestcases = []struct {
name string name string
moduleType string moduleType string
@@ -831,6 +865,7 @@ func TestJarGenrules(t *testing.T) {
} }
func fail(t *testing.T, errs []error) { func fail(t *testing.T, errs []error) {
t.Helper()
if len(errs) > 0 { if len(errs) > 0 {
for _, err := range errs { for _, err := range errs {
t.Error(err) t.Error(err)