Merge "Add target.linux for linux kernel based targets"
diff --git a/Android.bp b/Android.bp
index 0e57c12..ae31a60 100644
--- a/Android.bp
+++ b/Android.bp
@@ -209,6 +209,7 @@
"java/builder.go",
"java/gen.go",
"java/java.go",
+ "java/proto.go",
"java/resources.go",
],
testSrcs: [
diff --git a/android/proto.go b/android/proto.go
index 9bb9cfb..1c70656 100644
--- a/android/proto.go
+++ b/android/proto.go
@@ -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 @@
// 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 {
diff --git a/cc/cc.go b/cc/cc.go
index b4b70ed..4f10a11 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -673,6 +673,12 @@
if c.compiler != nil {
deps = c.compiler.compilerDeps(ctx, deps)
}
+ // Add the PGO dependency (the clang_rt.profile runtime library), which
+ // sometimes depends on symbols from libgcc, before libgcc gets added
+ // in linkerDeps().
+ if c.pgo != nil {
+ deps = c.pgo.deps(ctx, deps)
+ }
if c.linker != nil {
deps = c.linker.linkerDeps(ctx, deps)
}
diff --git a/cc/config/toolchain.go b/cc/config/toolchain.go
index d62ebe4..796ccfb 100644
--- a/cc/config/toolchain.go
+++ b/cc/config/toolchain.go
@@ -233,6 +233,10 @@
return SanitizerRuntimeLibrary(t, "tsan")
}
+func ProfileRuntimeLibrary(t Toolchain) string {
+ return SanitizerRuntimeLibrary(t, "profile")
+}
+
func ToolPath(t Toolchain) string {
if p := t.ToolPath(); p != "" {
return p
diff --git a/cc/config/x86_darwin_host.go b/cc/config/x86_darwin_host.go
index 3f079a4..6d361b5 100644
--- a/cc/config/x86_darwin_host.go
+++ b/cc/config/x86_darwin_host.go
@@ -159,6 +159,8 @@
strings.Join(ClangFilterUnknownCflags(darwinX8664Cflags), " "))
pctx.StaticVariable("DarwinX86ClangLdflags", strings.Join(darwinX86ClangLdflags, " "))
pctx.StaticVariable("DarwinX8664ClangLdflags", strings.Join(darwinX8664ClangLdflags, " "))
+ pctx.StaticVariable("DarwinX86YasmFlags", "-f macho -m x86")
+ pctx.StaticVariable("DarwinX8664YasmFlags", "-f macho -m amd64")
}
func xcrun(config android.Config, args ...string) (string, error) {
@@ -276,6 +278,14 @@
return "${config.DarwinClangLdflags} ${config.DarwinX8664ClangLdflags}"
}
+func (t *toolchainDarwinX86) YasmFlags() string {
+ return "${config.DarwinX86YasmFlags}"
+}
+
+func (t *toolchainDarwinX8664) YasmFlags() string {
+ return "${config.DarwinX8664YasmFlags}"
+}
+
func (t *toolchainDarwin) ShlibSuffix() string {
return ".dylib"
}
diff --git a/cc/config/x86_linux_host.go b/cc/config/x86_linux_host.go
index 75416bd..88bd514 100644
--- a/cc/config/x86_linux_host.go
+++ b/cc/config/x86_linux_host.go
@@ -159,6 +159,9 @@
pctx.StaticVariable("LinuxX8664ClangLdflags", strings.Join(linuxX8664ClangLdflags, " "))
pctx.StaticVariable("LinuxX86ClangCppflags", strings.Join(linuxX86ClangCppflags, " "))
pctx.StaticVariable("LinuxX8664ClangCppflags", strings.Join(linuxX8664ClangCppflags, " "))
+ // Yasm flags
+ pctx.StaticVariable("LinuxX86YasmFlags", "-f elf32 -m x86")
+ pctx.StaticVariable("LinuxX8664YasmFlags", "-f elf64 -m amd64")
}
type toolchainLinux struct {
@@ -251,6 +254,14 @@
return "${config.LinuxClangLdflags} ${config.LinuxX8664ClangLdflags}"
}
+func (t *toolchainLinuxX86) YasmFlags() string {
+ return "${config.LinuxX86YasmFlags}"
+}
+
+func (t *toolchainLinuxX8664) YasmFlags() string {
+ return "${config.LinuxX8664YasmFlags}"
+}
+
func (t *toolchainLinux) AvailableLibraries() []string {
return linuxAvailableLibraries
}
diff --git a/cc/gen.go b/cc/gen.go
index 9fc14c5..2280e0f 100644
--- a/cc/gen.go
+++ b/cc/gen.go
@@ -153,10 +153,9 @@
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
diff --git a/cc/pgo.go b/cc/pgo.go
index ccddece..a99cbad 100644
--- a/cc/pgo.go
+++ b/cc/pgo.go
@@ -19,12 +19,13 @@
"strings"
"android/soong/android"
+ "android/soong/cc/config"
)
var (
// Add flags to ignore warnings that profiles are old or missing for
// some functions
- profileUseOtherFlags = []string{}
+ profileUseOtherFlags = []string{"-Wno-backend-plugin"}
)
const pgoProfileProject = "toolchain/pgo-profiles"
@@ -50,25 +51,38 @@
Properties PgoProperties
}
+func (props *PgoProperties) isInstrumentation() bool {
+ return props.Pgo.Instrumentation != nil && *props.Pgo.Instrumentation == true
+}
+
+func (props *PgoProperties) isSampling() bool {
+ return props.Pgo.Sampling != nil && *props.Pgo.Sampling == true
+}
+
func (pgo *pgo) props() []interface{} {
return []interface{}{&pgo.Properties}
}
-func (pgo *pgo) profileGatherFlags(ctx ModuleContext) string {
- if *pgo.Properties.Pgo.Instrumentation {
- return profileInstrumentFlag
+func (pgo *pgo) addProfileGatherFlags(ctx ModuleContext, flags Flags) Flags {
+ if pgo.Properties.isInstrumentation() {
+ flags.CFlags = append(flags.CFlags, profileInstrumentFlag)
+ // The profile runtime is added below in deps(). Add the below
+ // flag, which is the only other link-time action performed by
+ // the Clang driver during link.
+ flags.LdFlags = append(flags.LdFlags, "-u__llvm_profile_runtime")
}
- if *pgo.Properties.Pgo.Sampling {
- return profileSamplingFlag
+ if pgo.Properties.isSampling() {
+ flags.CFlags = append(flags.CFlags, profileSamplingFlag)
+ flags.LdFlags = append(flags.LdFlags, profileSamplingFlag)
}
- return ""
+ return flags
}
func (pgo *pgo) profileUseFlag(ctx ModuleContext, file string) string {
- if *pgo.Properties.Pgo.Instrumentation {
+ if pgo.Properties.isInstrumentation() {
return fmt.Sprintf(profileUseInstrumentFormat, file)
}
- if *pgo.Properties.Pgo.Sampling {
+ if pgo.Properties.isSampling() {
return fmt.Sprintf(profileUseSamplingFormat, file)
}
return ""
@@ -81,8 +95,8 @@
}
func (props *PgoProperties) isPGO(ctx BaseModuleContext) bool {
- isInstrumentation := props.Pgo.Instrumentation != nil
- isSampling := props.Pgo.Sampling != nil
+ isInstrumentation := props.isInstrumentation()
+ isSampling := props.isSampling()
profileKindPresent := isInstrumentation || isSampling
filePresent := props.Pgo.Profile_file != nil
@@ -110,13 +124,14 @@
}
// Sampling not supported yet
- //
- // TODO When sampling support is turned on, check that instrumentation and
- // sampling are not simultaneously specified
if isSampling {
ctx.PropertyErrorf("pgo.sampling", "\"sampling\" is not supported yet)")
}
+ if isSampling && isInstrumentation {
+ ctx.PropertyErrorf("pgo", "Exactly one of \"instrumentation\" and \"sampling\" properties must be set")
+ }
+
return true
}
@@ -156,6 +171,14 @@
}
}
+func (pgo *pgo) deps(ctx BaseModuleContext, deps Deps) Deps {
+ if pgo.Properties.ShouldProfileModule {
+ runtimeLibrary := config.ProfileRuntimeLibrary(ctx.toolchain())
+ deps.LateStaticLibs = append(deps.LateStaticLibs, runtimeLibrary)
+ }
+ return deps
+}
+
func (pgo *pgo) flags(ctx ModuleContext, flags Flags) Flags {
if ctx.Host() {
return flags
@@ -165,10 +188,7 @@
// Add flags to profile this module based on its profile_kind
if props.ShouldProfileModule {
- profileGatherFlags := pgo.profileGatherFlags(ctx)
- flags.LdFlags = append(flags.LdFlags, profileGatherFlags)
- flags.CFlags = append(flags.CFlags, profileGatherFlags)
- return flags
+ return pgo.addProfileGatherFlags(ctx, flags)
}
// If the PGO profiles project is found, and this module has PGO
diff --git a/cc/proto.go b/cc/proto.go
index 6049d44..a01951f 100644
--- a/cc/proto.go
+++ b/cc/proto.go
@@ -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
diff --git a/cmd/merge_zips/merge_zips.go b/cmd/merge_zips/merge_zips.go
index a94392b..e16c00e 100644
--- a/cmd/merge_zips/merge_zips.go
+++ b/cmd/merge_zips/merge_zips.go
@@ -29,26 +29,26 @@
"android/soong/third_party/zip"
)
-type stripDir struct{}
+type fileList []string
-func (s *stripDir) String() string {
+func (f *fileList) String() string {
return `""`
}
-func (s *stripDir) Set(dir string) error {
- stripDirs = append(stripDirs, filepath.Clean(dir))
+func (f *fileList) Set(name string) error {
+ *f = append(*f, filepath.Clean(name))
return nil
}
-type zipToNotStrip struct{}
+type zipsToNotStripSet map[string]bool
-func (s *zipToNotStrip) String() string {
+func (s zipsToNotStripSet) String() string {
return `""`
}
-func (s *zipToNotStrip) Set(zip_path string) error {
- zipsToNotStrip[zip_path] = true
+func (s zipsToNotStripSet) Set(zip_path string) error {
+ s[zip_path] = true
return nil
}
@@ -56,15 +56,17 @@
var (
sortEntries = flag.Bool("s", false, "sort entries (defaults to the order from the input zip files)")
emulateJar = flag.Bool("j", false, "sort zip entries using jar ordering (META-INF first)")
- stripDirs []string
- zipsToNotStrip = make(map[string]bool)
+ stripDirs fileList
+ stripFiles fileList
+ zipsToNotStrip = make(zipsToNotStripSet)
stripDirEntries = flag.Bool("D", false, "strip directory entries from the output zip file")
manifest = flag.String("m", "", "manifest file to insert in jar")
)
func init() {
- flag.Var(&stripDir{}, "stripDir", "the prefix of file path to be excluded from the output zip")
- flag.Var(&zipToNotStrip{}, "zipToNotStrip", "the input zip file which is not applicable for stripping")
+ flag.Var(&stripDirs, "stripDir", "the prefix of file path to be excluded from the output zip")
+ flag.Var(&stripFiles, "stripFile", "filenames to be excluded from the output zip, accepts wildcards")
+ flag.Var(&zipsToNotStrip, "zipToNotStrip", "the input zip file which is not applicable for stripping")
}
func main() {
@@ -243,20 +245,9 @@
for _, namedReader := range readers {
_, skipStripThisZip := zipsToNotStrip[namedReader.path]
- FileLoop:
for _, file := range namedReader.reader.File {
- if !skipStripThisZip {
- for _, dir := range stripDirs {
- if strings.HasPrefix(file.Name, dir+"/") {
- if emulateJar {
- if file.Name != jar.MetaDir && file.Name != jar.ManifestFile {
- continue FileLoop
- }
- } else {
- continue FileLoop
- }
- }
- }
+ if !skipStripThisZip && shouldStripFile(emulateJar, file.Name) {
+ continue
}
if stripDirEntries && file.FileInfo().IsDir() {
@@ -310,6 +301,28 @@
return nil
}
+func shouldStripFile(emulateJar bool, name string) bool {
+ for _, dir := range stripDirs {
+ if strings.HasPrefix(name, dir+"/") {
+ if emulateJar {
+ if name != jar.MetaDir && name != jar.ManifestFile {
+ return true
+ }
+ } else {
+ return true
+ }
+ }
+ }
+ for _, pattern := range stripFiles {
+ if match, err := filepath.Match(pattern, filepath.Base(name)); err != nil {
+ panic(fmt.Errorf("%s: %s", err.Error(), pattern))
+ } else if match {
+ return true
+ }
+ }
+ return false
+}
+
func jarSort(files []fileMapping) {
sort.SliceStable(files, func(i, j int) bool {
return jar.EntryNamesLess(files[i].dest, files[j].dest)
diff --git a/jar/jar.go b/jar/jar.go
index 08fa1ab..653e5ee 100644
--- a/jar/jar.go
+++ b/jar/jar.go
@@ -31,7 +31,7 @@
ModuleInfoClass = "module-info.class"
)
-var DefaultTime = time.Date(2009, 1, 1, 0, 0, 0, 0, time.UTC)
+var DefaultTime = time.Date(2008, 1, 1, 0, 0, 0, 0, time.UTC)
var MetaDirExtra = [2]byte{0xca, 0xfe}
diff --git a/java/builder.go b/java/builder.go
index 95345d4..ca0d2c5 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -99,10 +99,12 @@
blueprint.RuleParams{
Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
`${config.DxCmd} --dex --output=$outDir $dxFlags $in && ` +
- `${config.SoongZipCmd} -jar -o $out -C $outDir -D $outDir`,
+ `${config.SoongZipCmd} -o $outDir/classes.dex.jar -C $outDir -D $outDir && ` +
+ `${config.MergeZipsCmd} -D -stripFile "*.class" $out $outDir/classes.dex.jar $in`,
CommandDeps: []string{
"${config.DxCmd}",
"${config.SoongZipCmd}",
+ "${config.MergeZipsCmd}",
},
},
"outDir", "dxFlags")
@@ -127,6 +129,9 @@
desugarFlags string
aidlFlags string
javaVersion string
+
+ protoFlags string
+ protoOutFlag string
}
func TransformJavaToClasses(ctx android.ModuleContext, srcFiles, srcFileLists android.Paths,
@@ -136,7 +141,10 @@
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 +169,8 @@
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 +181,12 @@
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...)
@@ -287,11 +300,13 @@
return outputFile
}
-func TransformClassesJarToDexJar(ctx android.ModuleContext, classesJar android.Path,
+// Converts a classes.jar file to classes*.dex, then combines the dex files with any resources
+// in the classes.jar file into a dex jar.
+func TransformClassesJarToDexJar(ctx android.ModuleContext, stem string, classesJar android.Path,
flags javaBuilderFlags) android.Path {
outDir := android.PathForModuleOut(ctx, "dex")
- outputFile := android.PathForModuleOut(ctx, "classes.dex.jar")
+ outputFile := android.PathForModuleOut(ctx, stem)
ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Rule: dx,
diff --git a/java/config/config.go b/java/config/config.go
index 4f74ef2..70b8fe5 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -53,8 +53,16 @@
pctx.VariableConfigMethod("hostPrebuiltTag", android.Config.PrebuiltOS)
- pctx.SourcePathVariableWithEnvOverride("JavaHome",
- "prebuilts/jdk/jdk8/${hostPrebuiltTag}", "OVERRIDE_ANDROID_JAVA_HOME")
+ pctx.VariableFunc("JavaHome", func(config interface{}) (string, error) {
+ if override := config.(android.Config).Getenv("OVERRIDE_ANDROID_JAVA_HOME"); override != "" {
+ return override, nil
+ }
+ if jdk9 := config.(android.Config).Getenv("EXPERIMENTAL_USE_OPENJDK9"); jdk9 != "" {
+ return "prebuilts/jdk/jdk9/${hostPrebuiltTag}", nil
+ }
+ return "prebuilts/jdk/jdk8/${hostPrebuiltTag}", nil
+ })
+
pctx.SourcePathVariable("JavaToolchain", "${JavaHome}/bin")
pctx.SourcePathVariableWithEnvOverride("JavacCmd",
"${JavaToolchain}/javac", "ALTERNATE_JAVAC")
diff --git a/java/gen.go b/java/gen.go
index e473859..e55be91 100644
--- a/java/gen.go
+++ b/java/gen.go
@@ -85,21 +85,37 @@
}
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 {
diff --git a/java/java.go b/java/java.go
index d8bc0c2..bab77c5 100644
--- a/java/java.go
+++ b/java/java.go
@@ -49,7 +49,6 @@
// TODO:
// Autogenerated files:
-// Proto
// Renderscript
// Post-jar passes:
// Proguard
@@ -145,6 +144,7 @@
android.DefaultableModuleBase
properties CompilerProperties
+ protoProperties android.ProtoProperties
deviceProperties CompilerDeviceProperties
// output file suitable for inserting into the classpath of another compile
@@ -153,9 +153,6 @@
// output file containing classes.dex
dexJarFile android.Path
- // output files containing resources
- resourceJarFiles android.Paths
-
// output file suitable for installing or running
outputFile android.Path
@@ -173,7 +170,6 @@
type Dependency interface {
ClasspathFiles() android.Paths
- ResourceJarFiles() android.Paths
AidlIncludeDirs() android.Paths
}
@@ -285,9 +281,7 @@
ctx.AddDependency(ctx.Module(), bootClasspathTag, sdkDep.module)
}
} else {
- if j.deviceProperties.Dex {
- ctx.AddDependency(ctx.Module(), bootClasspathTag, config.DefaultBootclasspathLibraries...)
- }
+ // TODO(ccross): add hostdex support
}
}
ctx.AddDependency(ctx.Module(), libTag, j.properties.Libs...)
@@ -296,6 +290,24 @@
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,
@@ -364,7 +376,6 @@
case staticLibTag:
deps.classpath = append(deps.classpath, dep.ClasspathFiles()...)
deps.staticJars = append(deps.staticJars, dep.ClasspathFiles()...)
- deps.staticJarResources = append(deps.staticJarResources, dep.ResourceJarFiles()...)
case frameworkResTag:
if ctx.ModuleName() == "framework" {
// framework.jar has a one-off dependency on the R.java and Manifest.java files
@@ -416,7 +427,15 @@
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 +443,7 @@
}
})
- deps.srcFileLists = append(deps.srcFileLists, j.ExtraSrcLists...)
+ srcFileLists = append(srcFileLists, j.ExtraSrcLists...)
var jars android.Paths
@@ -436,12 +455,12 @@
// 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
}
@@ -462,26 +481,20 @@
resDeps = append(resDeps, fileDeps...)
if proptools.Bool(j.properties.Include_srcs) {
- srcArgs, srcDeps := ResourceFilesToJarArgs(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
+ srcArgs, srcDeps := SourceFilesToJarArgs(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
resArgs = append(resArgs, srcArgs...)
resDeps = append(resDeps, srcDeps...)
}
if len(resArgs) > 0 {
- // Combine classes + resources into classes-full-debug.jar
resourceJar := TransformResourcesToJar(ctx, resArgs, resDeps)
if ctx.Failed() {
return
}
- j.resourceJarFiles = append(j.resourceJarFiles, resourceJar)
jars = append(jars, resourceJar)
}
- // Propagate the resources from the transitive closure of static dependencies for copying
- // into dex jars
- j.resourceJarFiles = append(j.resourceJarFiles, deps.staticJarResources...)
-
// static classpath jars have the resources in them, so the resource jars aren't necessary here
jars = append(jars, deps.staticJars...)
@@ -503,7 +516,7 @@
j.classpathFile = outputFile
// TODO(ccross): handle hostdex
- if ctx.Device() && len(srcFiles) > 0 && j.installable() {
+ if ctx.Device() && j.installable() {
dxFlags := j.deviceProperties.Dxflags
if false /* emma enabled */ {
// If you instrument class files that have local variable debug information in
@@ -556,17 +569,12 @@
return
}
- // Compile classes.jar into classes.dex
- dexJarFile := TransformClassesJarToDexJar(ctx, desugarJar, flags)
+ // Compile classes.jar into classes.dex and then javalib.jar
+ outputFile = TransformClassesJarToDexJar(ctx, "javalib.jar", desugarJar, flags)
if ctx.Failed() {
return
}
- jars := android.Paths{dexJarFile}
- jars = append(jars, j.resourceJarFiles...)
-
- outputFile = TransformJarsToJar(ctx, "javalib.jar", jars, android.OptionalPath{}, true)
-
j.dexJarFile = outputFile
}
ctx.CheckbuildFile(outputFile)
@@ -583,10 +591,6 @@
return android.Paths{j.classpathFile}
}
-func (j *Module) ResourceJarFiles() android.Paths {
- return j.resourceJarFiles
-}
-
func (j *Module) AidlIncludeDirs() android.Paths {
return j.exportAidlIncludeDirs
}
@@ -629,7 +633,8 @@
module.AddProperties(
&module.Module.properties,
- &module.Module.deviceProperties)
+ &module.Module.deviceProperties,
+ &module.Module.protoProperties)
InitJavaModule(module, android.HostAndDeviceSupported)
return module
@@ -639,7 +644,9 @@
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 +692,7 @@
module.AddProperties(
&module.Module.properties,
&module.Module.deviceProperties,
+ &module.Module.protoProperties,
&module.binaryProperties)
InitJavaModule(module, android.HostAndDeviceSupported)
@@ -697,6 +705,7 @@
module.AddProperties(
&module.Module.properties,
&module.Module.deviceProperties,
+ &module.Module.protoProperties,
&module.binaryProperties)
InitJavaModule(module, android.HostSupported)
@@ -748,11 +757,6 @@
return j.classpathFiles
}
-func (j *Import) ResourceJarFiles() android.Paths {
- // resources are in the ClasspathFiles
- return nil
-}
-
func (j *Import) AidlIncludeDirs() android.Paths {
return nil
}
diff --git a/java/java_test.go b/java/java_test.go
index 2b92f49..c2c7ee2 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -185,6 +185,7 @@
var classpathTestcases = []struct {
name string
+ moduleType string
host android.OsClass
properties string
bootclasspath []string
@@ -239,27 +240,41 @@
{
name: "host default",
- host: android.Host,
+ moduleType: "java_library_host",
properties: ``,
+ host: android.Host,
classpath: []string{},
},
{
name: "host nostdlib",
+ moduleType: "java_library_host",
host: android.Host,
properties: `no_standard_libs: true`,
classpath: []string{},
},
+ {
+
+ name: "host supported default",
+ host: android.Host,
+ properties: `host_supported: true,`,
+ classpath: []string{},
+ },
+ {
+ name: "host supported nostdlib",
+ host: android.Host,
+ properties: `host_supported: true, no_standard_libs: true`,
+ classpath: []string{},
+ },
}
func TestClasspath(t *testing.T) {
for _, testcase := range classpathTestcases {
t.Run(testcase.name, func(t *testing.T) {
- hostExtra := ""
- if testcase.host == android.Host {
- hostExtra = "_host"
+ moduleType := "java_library"
+ if testcase.moduleType != "" {
+ moduleType = testcase.moduleType
}
- ctx := testJava(t, `
- java_library`+hostExtra+` {
+ ctx := testJava(t, moduleType+` {
name: "foo",
srcs: ["a.java"],
`+testcase.properties+`
@@ -393,16 +408,16 @@
args string
}{
{
- // Test that a module with java_resource_dirs includes a file list file
+ // Test that a module with java_resource_dirs includes the files
name: "resource dirs",
prop: `java_resource_dirs: ["res"]`,
- args: "-C res -l ",
+ args: "-C res -f res/a -f res/b",
},
{
// Test that a module with java_resources includes the files
name: "resource files",
prop: `java_resources: ["res/a", "res/b"]`,
- args: "-C . -f res/a -C . -f res/b",
+ args: "-C . -f res/a -f res/b",
},
{
// Test that a module with a filegroup in java_resources includes the files with the
@@ -415,13 +430,13 @@
path: "res",
srcs: ["res/a", "res/b"],
}`,
- args: "-C res -f res/a -C res -f res/b",
+ args: "-C res -f res/a -f res/b",
},
{
// Test that a module with "include_srcs: true" includes its source files in the resources jar
name: "include sources",
prop: `include_srcs: true`,
- args: "-C . -f a.java -C . -f b.java -C . -f c.java",
+ args: "-C . -f a.java -f b.java -f c.java",
},
}
@@ -447,8 +462,8 @@
foo.Inputs.Strings(), fooRes.Output.String())
}
- if !strings.Contains(fooRes.Args["jarArgs"], test.args) {
- t.Errorf("foo resource jar args %q does not contain %q",
+ if fooRes.Args["jarArgs"] != test.args {
+ t.Errorf("foo resource jar args %q is not %q",
fooRes.Args["jarArgs"], test.args)
}
})
@@ -474,7 +489,7 @@
fooRes := ctx.ModuleForTests("foo", "android_common").Output("res.jar")
- expected := "-C res -l " + fooRes.Implicits[0].String()
+ expected := "-C res -f res/a -f res/b"
if fooRes.Args["jarArgs"] != expected {
t.Errorf("foo resource jar args %q is not %q",
fooRes.Args["jarArgs"], expected)
diff --git a/java/proto.go b/java/proto.go
new file mode 100644
index 0000000..dd8cabd
--- /dev/null
+++ b/java/proto.go
@@ -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", "full", "":
+ flags.protoOutFlag = "--java_out"
+ default:
+ ctx.PropertyErrorf("proto.type", "unknown proto type %q",
+ proptools.String(p.Proto.Type))
+ }
+ return flags
+}
diff --git a/java/resources.go b/java/resources.go
index 85ebd52..a596fd7 100644
--- a/java/resources.go
+++ b/java/resources.go
@@ -19,8 +19,6 @@
"path/filepath"
"strings"
- "github.com/google/blueprint/bootstrap"
-
"android/soong/android"
)
@@ -33,15 +31,6 @@
"**/*~",
}
-func isStringInSlice(str string, slice []string) bool {
- for _, s := range slice {
- if s == str {
- return true
- }
- }
- return false
-}
-
func ResourceDirsToJarArgs(ctx android.ModuleContext,
resourceDirs, excludeDirs []string) (args []string, deps android.Paths) {
var excludes []string
@@ -53,40 +42,64 @@
excludes = append(excludes, resourceExcludes...)
- for _, resourceDir := range resourceDirs {
- if isStringInSlice(resourceDir, excludeDirs) {
- continue
- }
- resourceDir := android.PathForModuleSrc(ctx, resourceDir)
- dirs := ctx.Glob(resourceDir.String(), nil)
- for _, dir := range dirs {
- fileListFile := android.ResPathWithName(ctx, dir, "resources.list")
- depFile := fileListFile.String() + ".d"
+ for _, dir := range resourceDirs {
+ dir := android.PathForModuleSrc(ctx, dir).String()
+ files := ctx.Glob(filepath.Join(dir, "**/*"), excludes)
- pattern := filepath.Join(dir.String(), "**/*")
- bootstrap.GlobFile(ctx, pattern, excludes, fileListFile.String(), depFile)
- args = append(args,
- "-C", dir.String(),
- "-l", fileListFile.String())
- deps = append(deps, fileListFile)
+ deps = append(deps, files...)
+
+ if len(files) > 0 {
+ args = append(args, "-C", dir)
+
+ for _, f := range files {
+ path := f.String()
+ if !strings.HasPrefix(path, dir) {
+ panic(fmt.Errorf("path %q does not start with %q", path, dir))
+ }
+ args = append(args, "-f", path)
+ }
}
}
return args, deps
}
+// Convert java_resources properties to arguments to soong_zip -jar, ignoring common patterns
+// that should not be treated as resources (including *.java).
func ResourceFilesToJarArgs(ctx android.ModuleContext,
res, exclude []string) (args []string, deps android.Paths) {
+
+ exclude = append([]string(nil), exclude...)
+ exclude = append(exclude, resourceExcludes...)
+ return resourceFilesToJarArgs(ctx, res, exclude)
+}
+
+// Convert java_resources properties to arguments to soong_zip -jar, keeping files that should
+// normally not used as resources like *.java
+func SourceFilesToJarArgs(ctx android.ModuleContext,
+ res, exclude []string) (args []string, deps android.Paths) {
+
+ return resourceFilesToJarArgs(ctx, res, exclude)
+}
+
+func resourceFilesToJarArgs(ctx android.ModuleContext,
+ res, exclude []string) (args []string, deps android.Paths) {
+
files := ctx.ExpandSources(res, exclude)
- for _, f := range files {
+ lastDir := ""
+ for i, f := range files {
rel := f.Rel()
path := f.String()
if !strings.HasSuffix(path, rel) {
panic(fmt.Errorf("path %q does not end with %q", path, rel))
}
- path = filepath.Clean(strings.TrimSuffix(path, rel))
- args = append(args, "-C", filepath.Clean(path), "-f", f.String())
+ dir := filepath.Clean(strings.TrimSuffix(path, rel))
+ if i == 0 || dir != lastDir {
+ args = append(args, "-C", dir)
+ }
+ args = append(args, "-f", path)
+ lastDir = dir
}
return args, files