Merge "Add support for .proto files in java modules"

This commit is contained in:
Colin Cross
2017-10-03 23:02:51 +00:00
committed by Gerrit Code Review
8 changed files with 211 additions and 60 deletions

View File

@@ -209,6 +209,7 @@ bootstrap_go_package {
"java/builder.go",
"java/gen.go",
"java/java.go",
"java/proto.go",
"java/resources.go",
],
testSrcs: [

View File

@@ -14,22 +14,6 @@
package android
import (
"github.com/google/blueprint"
)
func init() {
pctx.HostBinToolVariable("protocCmd", "aprotoc")
}
var (
proto = pctx.AndroidStaticRule("protoc",
blueprint.RuleParams{
Command: "$protocCmd $protoOut=$protoOutFlags:$outDir $protoFlags $in",
CommandDeps: []string{"$protocCmd"},
}, "protoFlags", "protoOut", "protoOutFlags", "outDir")
)
// TODO(ccross): protos are often used to communicate between multiple modules. If the only
// way to convert a proto to source is to reference it as a source file, and external modules cannot
// reference source files in other modules, then every module that owns a proto file will need to
@@ -38,30 +22,6 @@ var (
// and then external modules could depend on the proto module but use their own settings to
// generate the source.
func GenProto(ctx ModuleContext, protoFile Path,
protoFlags string, protoOut, protoOutFlags string, extensions []string) WritablePaths {
var outFiles WritablePaths
for _, ext := range extensions {
outFiles = append(outFiles, GenPathWithExt(ctx, "proto", protoFile, ext))
}
ctx.ModuleBuild(pctx, ModuleBuildParams{
Rule: proto,
Description: "protoc " + protoFile.Rel(),
Outputs: outFiles,
Input: protoFile,
Args: map[string]string{
"outDir": ProtoDir(ctx).String(),
"protoOut": protoOut,
"protoOutFlags": protoOutFlags,
"protoFlags": protoFlags,
},
})
return outFiles
}
func ProtoFlags(ctx ModuleContext, p *ProtoProperties) []string {
var protoFlags []string
if len(p.Proto.Local_include_dirs) > 0 {

View File

@@ -153,10 +153,9 @@ func genSources(ctx android.ModuleContext, srcFiles android.Paths,
srcFiles[i] = cppFile
genLex(ctx, srcFile, cppFile)
case ".proto":
protoFiles := android.GenProto(ctx, srcFile, buildFlags.protoFlags,
"--cpp_out", "", []string{"pb.cc", "pb.h"})
srcFiles[i] = protoFiles[0]
deps = append(deps, protoFiles[1])
ccFile, headerFile := genProto(ctx, srcFile, buildFlags.protoFlags)
srcFiles[i] = ccFile
deps = append(deps, headerFile)
case ".aidl":
cppFile := android.GenPathWithExt(ctx, "aidl", srcFile, "cpp")
srcFiles[i] = cppFile

View File

@@ -15,11 +15,46 @@
package cc
import (
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
"android/soong/android"
)
func init() {
pctx.HostBinToolVariable("protocCmd", "aprotoc")
}
var (
proto = pctx.AndroidStaticRule("protoc",
blueprint.RuleParams{
Command: "$protocCmd --cpp_out=$outDir $protoFlags $in",
CommandDeps: []string{"$protocCmd"},
}, "protoFlags", "outDir")
)
// genProto creates a rule to convert a .proto file to generated .pb.cc and .pb.h files and returns
// the paths to the generated files.
func genProto(ctx android.ModuleContext, protoFile android.Path,
protoFlags string) (ccFile, headerFile android.WritablePath) {
ccFile = android.GenPathWithExt(ctx, "proto", protoFile, "pb.cc")
headerFile = android.GenPathWithExt(ctx, "proto", protoFile, "pb.h")
ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Rule: proto,
Description: "protoc " + protoFile.Rel(),
Outputs: android.WritablePaths{ccFile, headerFile},
Input: protoFile,
Args: map[string]string{
"outDir": android.ProtoDir(ctx).String(),
"protoFlags": protoFlags,
},
})
return ccFile, headerFile
}
func protoDeps(ctx BaseModuleContext, deps Deps, p *android.ProtoProperties, static bool) Deps {
var lib string

View File

@@ -127,6 +127,9 @@ type javaBuilderFlags struct {
desugarFlags string
aidlFlags string
javaVersion string
protoFlags string
protoOutFlag string
}
func TransformJavaToClasses(ctx android.ModuleContext, srcFiles, srcFileLists android.Paths,
@@ -136,7 +139,10 @@ func TransformJavaToClasses(ctx android.ModuleContext, srcFiles, srcFileLists an
annoDir := android.PathForModuleOut(ctx, "anno")
classJar := android.PathForModuleOut(ctx, "classes-compiled.jar")
javacFlags := flags.javacFlags + android.JoinWithPrefix(srcFileLists.Strings(), "@")
javacFlags := flags.javacFlags
if len(srcFileLists) > 0 {
javacFlags += " " + android.JoinWithPrefix(srcFileLists.Strings(), "@")
}
deps = append(deps, srcFileLists...)
deps = append(deps, flags.bootClasspath...)
@@ -161,8 +167,8 @@ func TransformJavaToClasses(ctx android.ModuleContext, srcFiles, srcFileLists an
return classJar
}
func RunErrorProne(ctx android.ModuleContext, srcFiles android.Paths, srcFileLists android.Paths,
flags javaBuilderFlags, deps android.Paths) android.Path {
func RunErrorProne(ctx android.ModuleContext, srcFiles, srcFileLists android.Paths,
flags javaBuilderFlags) android.Path {
if config.ErrorProneJar == "" {
ctx.ModuleErrorf("cannot build with Error Prone, missing external/error_prone?")
@@ -173,7 +179,12 @@ func RunErrorProne(ctx android.ModuleContext, srcFiles android.Paths, srcFileLis
annoDir := android.PathForModuleOut(ctx, "anno-errorprone")
classFileList := android.PathForModuleOut(ctx, "classes-errorprone.list")
javacFlags := flags.javacFlags + android.JoinWithPrefix(srcFileLists.Strings(), "@")
javacFlags := flags.javacFlags
if len(srcFileLists) > 0 {
javacFlags += " " + android.JoinWithPrefix(srcFileLists.Strings(), "@")
}
var deps android.Paths
deps = append(deps, srcFileLists...)
deps = append(deps, flags.bootClasspath...)

View File

@@ -85,21 +85,37 @@ func genLogtags(ctx android.ModuleContext, logtagsFile android.Path) android.Pat
}
func (j *Module) genSources(ctx android.ModuleContext, srcFiles android.Paths,
flags javaBuilderFlags) android.Paths {
flags javaBuilderFlags) (android.Paths, android.Paths) {
for i, srcFile := range srcFiles {
var protoFiles android.Paths
outSrcFiles := make(android.Paths, 0, len(srcFiles))
for _, srcFile := range srcFiles {
switch srcFile.Ext() {
case ".aidl":
javaFile := genAidl(ctx, srcFile, flags.aidlFlags)
srcFiles[i] = javaFile
outSrcFiles = append(outSrcFiles, javaFile)
case ".logtags":
j.logtagsSrcs = append(j.logtagsSrcs, srcFile)
javaFile := genLogtags(ctx, srcFile)
srcFiles[i] = javaFile
outSrcFiles = append(outSrcFiles, javaFile)
case ".proto":
protoFiles = append(protoFiles, srcFile)
default:
outSrcFiles = append(outSrcFiles, srcFile)
}
}
return srcFiles
var outSrcFileLists android.Paths
if len(protoFiles) > 0 {
protoFileList := genProto(ctx, protoFiles,
flags.protoFlags, flags.protoOutFlag, "")
outSrcFileLists = append(outSrcFileLists, protoFileList)
}
return outSrcFiles, outSrcFileLists
}
func LogtagsSingleton() blueprint.Singleton {

View File

@@ -49,7 +49,6 @@ func init() {
// TODO:
// Autogenerated files:
// Proto
// Renderscript
// Post-jar passes:
// Proguard
@@ -145,6 +144,7 @@ type Module struct {
android.DefaultableModuleBase
properties CompilerProperties
protoProperties android.ProtoProperties
deviceProperties CompilerDeviceProperties
// output file suitable for inserting into the classpath of another compile
@@ -296,6 +296,24 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) {
android.ExtractSourcesDeps(ctx, j.properties.Srcs)
android.ExtractSourcesDeps(ctx, j.properties.Java_resources)
if j.hasSrcExt(".proto") {
protoDeps(ctx, &j.protoProperties)
}
}
func hasSrcExt(srcs []string, ext string) bool {
for _, src := range srcs {
if filepath.Ext(src) == ext {
return true
}
}
return false
}
func (j *Module) hasSrcExt(ext string) bool {
return hasSrcExt(j.properties.Srcs, ext)
}
func (j *Module) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
@@ -416,7 +434,15 @@ func (j *Module) compile(ctx android.ModuleContext) {
srcFiles := ctx.ExpandSources(j.properties.Srcs, j.properties.Exclude_srcs)
srcFiles = j.genSources(ctx, srcFiles, flags)
if hasSrcExt(srcFiles.Strings(), ".proto") {
flags = protoFlags(ctx, &j.protoProperties, flags)
}
var srcFileLists android.Paths
srcFiles, srcFileLists = j.genSources(ctx, srcFiles, flags)
srcFileLists = append(srcFileLists, deps.srcFileLists...)
ctx.VisitDirectDeps(func(module blueprint.Module) {
if gen, ok := module.(genrule.SourceFileGenerator); ok {
@@ -424,7 +450,7 @@ func (j *Module) compile(ctx android.ModuleContext) {
}
})
deps.srcFileLists = append(deps.srcFileLists, j.ExtraSrcLists...)
srcFileLists = append(srcFileLists, j.ExtraSrcLists...)
var jars android.Paths
@@ -436,12 +462,12 @@ func (j *Module) compile(ctx android.ModuleContext) {
// a rebuild when error-prone is turned off).
// TODO(ccross): Once we always compile with javac9 we may be able to conditionally
// enable error-prone without affecting the output class files.
errorprone := RunErrorProne(ctx, srcFiles, deps.srcFileLists, flags, nil)
errorprone := RunErrorProne(ctx, srcFiles, srcFileLists, flags)
extraJarDeps = append(extraJarDeps, errorprone)
}
// Compile java sources into .class files
classes := TransformJavaToClasses(ctx, srcFiles, deps.srcFileLists, flags, extraJarDeps)
classes := TransformJavaToClasses(ctx, srcFiles, srcFileLists, flags, extraJarDeps)
if ctx.Failed() {
return
}
@@ -629,7 +655,8 @@ func LibraryFactory(installable bool) func() android.Module {
module.AddProperties(
&module.Module.properties,
&module.Module.deviceProperties)
&module.Module.deviceProperties,
&module.Module.protoProperties)
InitJavaModule(module, android.HostAndDeviceSupported)
return module
@@ -639,7 +666,9 @@ func LibraryFactory(installable bool) func() android.Module {
func LibraryHostFactory() android.Module {
module := &Library{}
module.AddProperties(&module.Module.properties)
module.AddProperties(
&module.Module.properties,
&module.Module.protoProperties)
InitJavaModule(module, android.HostSupported)
return module
@@ -685,6 +714,7 @@ func BinaryFactory() android.Module {
module.AddProperties(
&module.Module.properties,
&module.Module.deviceProperties,
&module.Module.protoProperties,
&module.binaryProperties)
InitJavaModule(module, android.HostAndDeviceSupported)
@@ -697,6 +727,7 @@ func BinaryHostFactory() android.Module {
module.AddProperties(
&module.Module.properties,
&module.Module.deviceProperties,
&module.Module.protoProperties,
&module.binaryProperties)
InitJavaModule(module, android.HostSupported)

98
java/proto.go Normal file
View File

@@ -0,0 +1,98 @@
// 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 java
import (
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
"android/soong/android"
)
func init() {
pctx.HostBinToolVariable("protocCmd", "aprotoc")
}
var (
proto = pctx.AndroidStaticRule("protoc",
blueprint.RuleParams{
Command: `rm -rf $outDir && mkdir -p $outDir && ` +
`$protocCmd $protoOut=$protoOutFlags:$outDir $protoFlags $in && ` +
`find $outDir -name "*.java" > $out`,
CommandDeps: []string{"$protocCmd"},
}, "protoFlags", "protoOut", "protoOutFlags", "outDir")
)
func genProto(ctx android.ModuleContext, protoFiles android.Paths,
protoFlags string, protoOut, protoOutFlags string) android.WritablePath {
protoFileList := android.PathForModuleGen(ctx, "proto.filelist")
ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Rule: proto,
Description: "protoc " + protoFiles[0].Rel(),
Output: protoFileList,
Inputs: protoFiles,
Args: map[string]string{
"outDir": android.ProtoDir(ctx).String(),
"protoOut": protoOut,
"protoOutFlags": protoOutFlags,
"protoFlags": protoFlags,
},
})
return protoFileList
}
func protoDeps(ctx android.BottomUpMutatorContext, p *android.ProtoProperties) {
switch proptools.String(p.Proto.Type) {
case "micro":
ctx.AddDependency(ctx.Module(), staticLibTag, "libprotobuf-java-micro")
case "nano":
ctx.AddDependency(ctx.Module(), staticLibTag, "libprotobuf-java-nano")
case "stream":
// TODO(ccross): add dependency on protoc-gen-java-stream binary
ctx.PropertyErrorf("proto.type", `"stream" not supported yet`)
// No library for stream protobufs
case "lite", "":
ctx.AddDependency(ctx.Module(), staticLibTag, "libprotobuf-java-lite")
case "full":
if ctx.Host() {
ctx.AddDependency(ctx.Module(), staticLibTag, "libprotobuf-java-full")
} else {
ctx.PropertyErrorf("proto.type", "full java protos only supported on the host")
}
default:
ctx.PropertyErrorf("proto.type", "unknown proto type %q",
proptools.String(p.Proto.Type))
}
}
func protoFlags(ctx android.ModuleContext, p *android.ProtoProperties, flags javaBuilderFlags) javaBuilderFlags {
switch proptools.String(p.Proto.Type) {
case "micro":
flags.protoOutFlag = "--javamicro_out"
case "nano":
flags.protoOutFlag = "--javanano_out"
case "stream":
flags.protoOutFlag = "--javastream_out"
case "lite", "":
flags.protoOutFlag = "--java_out"
default:
ctx.PropertyErrorf("proto.type", "unknown proto type %q",
proptools.String(p.Proto.Type))
}
return flags
}