java_library support for building headers-only
Flag for java_library modules to build just the Turbine headers and skip building an impl jar. Test: go test java Bug: 289776578 Change-Id: Iad0babf951710476bc32df93c25d17065a14ab84
This commit is contained in:
@@ -60,6 +60,7 @@ func init() {
|
|||||||
AddNeverAllowRules(createBp2BuildRule())
|
AddNeverAllowRules(createBp2BuildRule())
|
||||||
AddNeverAllowRules(createCcStubsRule())
|
AddNeverAllowRules(createCcStubsRule())
|
||||||
AddNeverAllowRules(createJavaExcludeStaticLibsRule())
|
AddNeverAllowRules(createJavaExcludeStaticLibsRule())
|
||||||
|
AddNeverAllowRules(createProhibitHeaderOnlyRule())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a NeverAllow rule to the set of rules to apply.
|
// Add a NeverAllow rule to the set of rules to apply.
|
||||||
@@ -264,6 +265,13 @@ func createJavaExcludeStaticLibsRule() Rule {
|
|||||||
Because("exclude_static_libs property is only allowed for java modules defined in build/soong, libcore, and frameworks/base/api")
|
Because("exclude_static_libs property is only allowed for java modules defined in build/soong, libcore, and frameworks/base/api")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func createProhibitHeaderOnlyRule() Rule {
|
||||||
|
return NeverAllow().
|
||||||
|
Without("name", "framework-minus-apex-headers").
|
||||||
|
With("headers_only", "true").
|
||||||
|
Because("headers_only can only be used for generating framework-minus-apex headers for non-updatable modules")
|
||||||
|
}
|
||||||
|
|
||||||
func neverallowMutator(ctx BottomUpMutatorContext) {
|
func neverallowMutator(ctx BottomUpMutatorContext) {
|
||||||
m, ok := ctx.Module().(Module)
|
m, ok := ctx.Module().(Module)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@@ -361,6 +361,21 @@ var neverallowTests = []struct {
|
|||||||
`exclude_static_libs property is only allowed for java modules defined in build/soong, libcore, and frameworks/base/api`,
|
`exclude_static_libs property is only allowed for java modules defined in build/soong, libcore, and frameworks/base/api`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
// Test for only allowing headers_only for framework-minus-apex-headers
|
||||||
|
{
|
||||||
|
name: `"headers_only" outside framework-minus-apex-headers modules`,
|
||||||
|
fs: map[string][]byte{
|
||||||
|
"a/b/Android.bp": []byte(`
|
||||||
|
java_library {
|
||||||
|
name: "baz",
|
||||||
|
headers_only: true,
|
||||||
|
}
|
||||||
|
`),
|
||||||
|
},
|
||||||
|
expectedErrors: []string{
|
||||||
|
`headers_only can only be used for generating framework-minus-apex headers for non-updatable modules`,
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var prepareForNeverAllowTest = GroupFixturePreparers(
|
var prepareForNeverAllowTest = GroupFixturePreparers(
|
||||||
@@ -451,6 +466,7 @@ type mockJavaLibraryProperties struct {
|
|||||||
Sdk_version *string
|
Sdk_version *string
|
||||||
Uncompress_dex *bool
|
Uncompress_dex *bool
|
||||||
Exclude_static_libs []string
|
Exclude_static_libs []string
|
||||||
|
Headers_only *bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type mockJavaLibraryModule struct {
|
type mockJavaLibraryModule struct {
|
||||||
|
@@ -79,6 +79,9 @@ func (library *Library) AndroidMkEntries() []android.AndroidMkEntries {
|
|||||||
} else if !library.ApexModuleBase.AvailableFor(android.AvailableToPlatform) {
|
} else if !library.ApexModuleBase.AvailableFor(android.AvailableToPlatform) {
|
||||||
// Platform variant. If not available for the platform, we don't need Make module.
|
// Platform variant. If not available for the platform, we don't need Make module.
|
||||||
entriesList = append(entriesList, android.AndroidMkEntries{Disabled: true})
|
entriesList = append(entriesList, android.AndroidMkEntries{Disabled: true})
|
||||||
|
} else if library.properties.Headers_only {
|
||||||
|
// If generating headers only then don't expose to Make.
|
||||||
|
entriesList = append(entriesList, android.AndroidMkEntries{Disabled: true})
|
||||||
} else {
|
} else {
|
||||||
entriesList = append(entriesList, android.AndroidMkEntries{
|
entriesList = append(entriesList, android.AndroidMkEntries{
|
||||||
Class: "JAVA_LIBRARIES",
|
Class: "JAVA_LIBRARIES",
|
||||||
|
44
java/base.go
44
java/base.go
@@ -192,6 +192,9 @@ type CommonProperties struct {
|
|||||||
|
|
||||||
// Additional srcJars tacked in by GeneratedJavaLibraryModule
|
// Additional srcJars tacked in by GeneratedJavaLibraryModule
|
||||||
Generated_srcjars []android.Path `android:"mutated"`
|
Generated_srcjars []android.Path `android:"mutated"`
|
||||||
|
|
||||||
|
// If true, then only the headers are built and not the implementation jar.
|
||||||
|
Headers_only bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Properties that are specific to device modules. Host module factories should not add these when
|
// Properties that are specific to device modules. Host module factories should not add these when
|
||||||
@@ -574,6 +577,17 @@ func (j *Module) checkPlatformAPI(ctx android.ModuleContext) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (j *Module) checkHeadersOnly(ctx android.ModuleContext) {
|
||||||
|
if _, ok := ctx.Module().(android.SdkContext); ok {
|
||||||
|
headersOnly := proptools.Bool(&j.properties.Headers_only)
|
||||||
|
installable := proptools.Bool(j.properties.Installable)
|
||||||
|
|
||||||
|
if headersOnly && installable {
|
||||||
|
ctx.PropertyErrorf("headers_only", "This module has conflicting settings. headers_only is true which, which means this module doesn't generate an implementation jar. However installable is set to true.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (j *Module) addHostProperties() {
|
func (j *Module) addHostProperties() {
|
||||||
j.AddProperties(
|
j.AddProperties(
|
||||||
&j.properties,
|
&j.properties,
|
||||||
@@ -1151,6 +1165,36 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
|
|||||||
// final R classes from the app.
|
// final R classes from the app.
|
||||||
flags.classpath = append(android.CopyOf(extraClasspathJars), flags.classpath...)
|
flags.classpath = append(android.CopyOf(extraClasspathJars), flags.classpath...)
|
||||||
|
|
||||||
|
// If compiling headers then compile them and skip the rest
|
||||||
|
if j.properties.Headers_only {
|
||||||
|
if srcFiles.HasExt(".kt") {
|
||||||
|
ctx.ModuleErrorf("Compiling headers_only with .kt not supported")
|
||||||
|
}
|
||||||
|
if ctx.Config().IsEnvFalse("TURBINE_ENABLED") || disableTurbine {
|
||||||
|
ctx.ModuleErrorf("headers_only is enabled but Turbine is disabled.")
|
||||||
|
}
|
||||||
|
|
||||||
|
_, j.headerJarFile =
|
||||||
|
j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName,
|
||||||
|
extraCombinedJars)
|
||||||
|
if ctx.Failed() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.SetProvider(JavaInfoProvider, JavaInfo{
|
||||||
|
HeaderJars: android.PathsIfNonNil(j.headerJarFile),
|
||||||
|
TransitiveLibsHeaderJars: j.transitiveLibsHeaderJars,
|
||||||
|
TransitiveStaticLibsHeaderJars: j.transitiveStaticLibsHeaderJars,
|
||||||
|
AidlIncludeDirs: j.exportAidlIncludeDirs,
|
||||||
|
ExportedPlugins: j.exportedPluginJars,
|
||||||
|
ExportedPluginClasses: j.exportedPluginClasses,
|
||||||
|
ExportedPluginDisableTurbine: j.exportedDisableTurbine,
|
||||||
|
})
|
||||||
|
|
||||||
|
j.outputFile = j.headerJarFile
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if srcFiles.HasExt(".kt") {
|
if srcFiles.HasExt(".kt") {
|
||||||
// When using kotlin sources turbine is used to generate annotation processor sources,
|
// When using kotlin sources turbine is used to generate annotation processor sources,
|
||||||
// including for annotation processors that generate API, so we can use turbine for
|
// including for annotation processors that generate API, so we can use turbine for
|
||||||
|
@@ -692,6 +692,7 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
j.checkSdkVersions(ctx)
|
j.checkSdkVersions(ctx)
|
||||||
|
j.checkHeadersOnly(ctx)
|
||||||
if ctx.Device() {
|
if ctx.Device() {
|
||||||
j.dexpreopter.installPath = j.dexpreopter.getInstallPath(
|
j.dexpreopter.installPath = j.dexpreopter.getInstallPath(
|
||||||
ctx, android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar"))
|
ctx, android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar"))
|
||||||
|
@@ -2370,3 +2370,21 @@ func TestJavaLibraryWithResourcesStem(t *testing.T) {
|
|||||||
t.Errorf("Module output does not contain expected jar %s", "test.jar")
|
t.Errorf("Module output does not contain expected jar %s", "test.jar")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHeadersOnly(t *testing.T) {
|
||||||
|
ctx, _ := testJava(t, `
|
||||||
|
java_library {
|
||||||
|
name: "foo",
|
||||||
|
srcs: ["a.java"],
|
||||||
|
headers_only: true,
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
|
||||||
|
turbine := ctx.ModuleForTests("foo", "android_common").Rule("turbine")
|
||||||
|
if len(turbine.Inputs) != 1 || turbine.Inputs[0].String() != "a.java" {
|
||||||
|
t.Errorf(`foo inputs %v != ["a.java"]`, turbine.Inputs)
|
||||||
|
}
|
||||||
|
|
||||||
|
javac := ctx.ModuleForTests("foo", "android_common").MaybeRule("javac")
|
||||||
|
android.AssertDeepEquals(t, "javac rule", nil, javac.Rule)
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user