Merge changes from topic "host_bionic"
* changes:
Extract the linker and embed it into host bionic binaries
Add prefix_symbols support to cc_object
Fix ToolchainClangCflags for host bionic
Don't add a rpath to the linker
diff --git a/android/config.go b/android/config.go
index 4f35114..f30a708 100644
--- a/android/config.go
+++ b/android/config.go
@@ -185,6 +185,25 @@
return Config{config}
}
+// TestConfig returns a Config object suitable for using for tests that need to run the arch mutator
+func TestArchConfig(buildDir string) Config {
+ testConfig := TestConfig(buildDir)
+ config := testConfig.config
+
+ config.Targets = map[OsClass][]Target{
+ Device: []Target{
+ {Android, Arch{ArchType: Arm64, Native: true}},
+ {Android, Arch{ArchType: Arm, Native: true}},
+ },
+ Host: []Target{
+ {BuildOs, Arch{ArchType: X86_64}},
+ {BuildOs, Arch{ArchType: X86}},
+ },
+ }
+
+ return testConfig
+}
+
// New creates a new Config object. The srcDir argument specifies the path to
// the root source directory. It also loads the config file, if found.
func NewConfig(srcDir, buildDir string) (Config, error) {
diff --git a/android/mutator.go b/android/mutator.go
index e20bc2c..04407eb 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -78,11 +78,13 @@
RegisterDefaultsPreArchMutators,
}
+func registerArchMutator(ctx RegisterMutatorsContext) {
+ ctx.BottomUp("arch", archMutator).Parallel()
+ ctx.TopDown("arch_hooks", archHookMutator).Parallel()
+}
+
var preDeps = []RegisterMutatorFunc{
- func(ctx RegisterMutatorsContext) {
- ctx.BottomUp("arch", archMutator).Parallel()
- ctx.TopDown("arch_hooks", archHookMutator).Parallel()
- },
+ registerArchMutator,
}
var postDeps = []RegisterMutatorFunc{
diff --git a/android/testing.go b/android/testing.go
index 4144775..519e279 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -27,6 +27,12 @@
}
}
+func NewTestArchContext() *TestContext {
+ ctx := NewTestContext()
+ ctx.preDeps = append(ctx.preDeps, registerArchMutator)
+ return ctx
+}
+
type TestContext struct {
*blueprint.Context
preArch, preDeps, postDeps []RegisterMutatorFunc
diff --git a/cmd/merge_zips/merge_zips.go b/cmd/merge_zips/merge_zips.go
index 9fd5ddd..a94392b 100644
--- a/cmd/merge_zips/merge_zips.go
+++ b/cmd/merge_zips/merge_zips.go
@@ -15,8 +15,10 @@
package main
import (
+ "errors"
"flag"
"fmt"
+ "hash/crc32"
"log"
"os"
"path/filepath"
@@ -52,10 +54,12 @@
}
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)
+ 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)
+ 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() {
@@ -65,7 +69,7 @@
func main() {
flag.Usage = func() {
- fmt.Fprintln(os.Stderr, "usage: merge_zips [-j] output [inputs...]")
+ fmt.Fprintln(os.Stderr, "usage: merge_zips [-jsD] [-m manifest] output [inputs...]")
flag.PrintDefaults()
}
@@ -107,8 +111,13 @@
readers = append(readers, namedReader)
}
+ if *manifest != "" && !*emulateJar {
+ log.Fatal(errors.New("must specify -j when specifying a manifest via -m"))
+ }
+
// do merge
- if err := mergeZips(readers, writer, *sortEntries, *emulateJar); err != nil {
+ err = mergeZips(readers, writer, *manifest, *sortEntries, *emulateJar, *stripDirEntries)
+ if err != nil {
log.Fatal(err)
}
}
@@ -129,23 +138,109 @@
return p.zipName + "/" + p.entryName
}
-// a zipEntry knows the location and content of a file within a zip
+// a zipEntry is a zipSource that pulls its content from another zip
type zipEntry struct {
path zipEntryPath
content *zip.File
}
-// a fileMapping specifies to copy a zip entry from one place to another
-type fileMapping struct {
- source zipEntry
- dest string
+func (ze zipEntry) String() string {
+ return ze.path.String()
}
-func mergeZips(readers []namedZipReader, writer *zip.Writer, sortEntries bool, emulateJar bool) error {
+func (ze zipEntry) IsDir() bool {
+ return ze.content.FileInfo().IsDir()
+}
- mappingsByDest := make(map[string]fileMapping, 0)
+func (ze zipEntry) CRC32() uint32 {
+ return ze.content.FileHeader.CRC32
+}
+
+func (ze zipEntry) WriteToZip(dest string, zw *zip.Writer) error {
+ return zw.CopyFrom(ze.content, dest)
+}
+
+// a bufferEntry is a zipSource that pulls its content from a []byte
+type bufferEntry struct {
+ fh *zip.FileHeader
+ content []byte
+}
+
+func (be bufferEntry) String() string {
+ return "internal buffer"
+}
+
+func (be bufferEntry) IsDir() bool {
+ return be.fh.FileInfo().IsDir()
+}
+
+func (be bufferEntry) CRC32() uint32 {
+ return crc32.ChecksumIEEE(be.content)
+}
+
+func (be bufferEntry) WriteToZip(dest string, zw *zip.Writer) error {
+ w, err := zw.CreateHeader(be.fh)
+ if err != nil {
+ return err
+ }
+
+ if !be.IsDir() {
+ _, err = w.Write(be.content)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+type zipSource interface {
+ String() string
+ IsDir() bool
+ CRC32() uint32
+ WriteToZip(dest string, zw *zip.Writer) error
+}
+
+// a fileMapping specifies to copy a zip entry from one place to another
+type fileMapping struct {
+ dest string
+ source zipSource
+}
+
+func mergeZips(readers []namedZipReader, writer *zip.Writer, manifest string,
+ sortEntries, emulateJar, stripDirEntries bool) error {
+
+ sourceByDest := make(map[string]zipSource, 0)
orderedMappings := []fileMapping{}
+ // if dest already exists returns a non-null zipSource for the existing source
+ addMapping := func(dest string, source zipSource) zipSource {
+ mapKey := filepath.Clean(dest)
+ if existingSource, exists := sourceByDest[mapKey]; exists {
+ return existingSource
+ }
+
+ sourceByDest[mapKey] = source
+ orderedMappings = append(orderedMappings, fileMapping{source: source, dest: dest})
+ return nil
+ }
+
+ if manifest != "" {
+ if !stripDirEntries {
+ dirHeader := jar.MetaDirFileHeader()
+ dirSource := bufferEntry{dirHeader, nil}
+ addMapping(jar.MetaDir, dirSource)
+ }
+
+ fh, buf, err := jar.ManifestFileContents(manifest)
+ if err != nil {
+ return err
+ }
+
+ fileSource := bufferEntry{fh, buf}
+ addMapping(jar.ManifestFile, fileSource)
+ }
+
for _, namedReader := range readers {
_, skipStripThisZip := zipsToNotStrip[namedReader.path]
FileLoop:
@@ -163,46 +258,39 @@
}
}
}
+
+ if stripDirEntries && file.FileInfo().IsDir() {
+ continue
+ }
+
// check for other files or directories destined for the same path
dest := file.Name
- mapKey := dest
- if strings.HasSuffix(mapKey, "/") {
- mapKey = mapKey[:len(mapKey)-1]
- }
- existingMapping, exists := mappingsByDest[mapKey]
// make a new entry to add
source := zipEntry{path: zipEntryPath{zipName: namedReader.path, entryName: file.Name}, content: file}
- newMapping := fileMapping{source: source, dest: dest}
- if exists {
+ if existingSource := addMapping(dest, source); existingSource != nil {
// handle duplicates
- wasDir := existingMapping.source.content.FileHeader.FileInfo().IsDir()
- isDir := newMapping.source.content.FileHeader.FileInfo().IsDir()
- if wasDir != isDir {
+ if existingSource.IsDir() != source.IsDir() {
return fmt.Errorf("Directory/file mismatch at %v from %v and %v\n",
- dest, existingMapping.source.path, newMapping.source.path)
+ dest, existingSource, source)
}
if emulateJar &&
file.Name == jar.ManifestFile || file.Name == jar.ModuleInfoClass {
// Skip manifest and module info files that are not from the first input file
continue
}
- if !isDir {
+ if !source.IsDir() {
if emulateJar {
- if existingMapping.source.content.CRC32 != newMapping.source.content.CRC32 {
+ if existingSource.CRC32() != source.CRC32() {
fmt.Fprintf(os.Stdout, "WARNING: Duplicate path %v found in %v and %v\n",
- dest, existingMapping.source.path, newMapping.source.path)
+ dest, existingSource, source)
}
} else {
return fmt.Errorf("Duplicate path %v found in %v and %v\n",
- dest, existingMapping.source.path, newMapping.source.path)
+ dest, existingSource, source)
}
}
- } else {
- // save entry
- mappingsByDest[mapKey] = newMapping
- orderedMappings = append(orderedMappings, newMapping)
}
}
}
@@ -214,7 +302,7 @@
}
for _, entry := range orderedMappings {
- if err := writer.CopyFrom(entry.source.content, entry.dest); err != nil {
+ if err := entry.source.WriteToZip(entry.dest, writer); err != nil {
return err
}
}
diff --git a/cmd/soong_zip/soong_zip.go b/cmd/soong_zip/soong_zip.go
index 4cf0764..cb9df9a 100644
--- a/cmd/soong_zip/soong_zip.go
+++ b/cmd/soong_zip/soong_zip.go
@@ -58,7 +58,7 @@
}
type byteReaderCloser struct {
- bytes.Reader
+ *bytes.Reader
io.Closer
}
@@ -252,7 +252,7 @@
}
w := &zipWriter{
- time: time.Date(2009, 1, 1, 0, 0, 0, 0, time.UTC),
+ time: jar.DefaultTime,
createdDirs: make(map[string]string),
createdFiles: make(map[string]string),
directories: *directories,
@@ -353,14 +353,14 @@
z.memoryRateLimiter.Stop()
}()
- if manifest != "" {
- if !*emulateJar {
- return errors.New("must specify --jar when specifying a manifest via -m")
- }
- pathMappings = append(pathMappings, pathMapping{jar.ManifestFile, manifest, zip.Deflate})
+ if manifest != "" && !*emulateJar {
+ return errors.New("must specify --jar when specifying a manifest via -m")
}
if *emulateJar {
+ // manifest may be empty, in which case addManifest will fill in a default
+ pathMappings = append(pathMappings, pathMapping{jar.ManifestFile, manifest, zip.Deflate})
+
jarSort(pathMappings)
}
@@ -524,11 +524,6 @@
}
func (z *zipWriter) addManifest(dest string, src string, method uint16) error {
- givenBytes, err := ioutil.ReadFile(src)
- if err != nil {
- return err
- }
-
if prev, exists := z.createdDirs[dest]; exists {
return fmt.Errorf("destination %q is both a directory %q and a file %q", dest, prev, src)
}
@@ -536,27 +531,18 @@
return fmt.Errorf("destination %q has two files %q and %q", dest, prev, src)
}
- manifestMarker := []byte("Manifest-Version:")
- header := append(manifestMarker, []byte(" 1.0\nCreated-By: soong_zip\n")...)
-
- var finalBytes []byte
- if !bytes.Contains(givenBytes, manifestMarker) {
- finalBytes = append(append(header, givenBytes...), byte('\n'))
- } else {
- finalBytes = givenBytes
+ if err := z.writeDirectory(filepath.Dir(dest), src); err != nil {
+ return err
}
- byteReader := bytes.NewReader(finalBytes)
-
- reader := &byteReaderCloser{*byteReader, ioutil.NopCloser(nil)}
-
- fileHeader := &zip.FileHeader{
- Name: dest,
- Method: zip.Store,
- UncompressedSize64: uint64(byteReader.Len()),
+ fh, buf, err := jar.ManifestFileContents(src)
+ if err != nil {
+ return err
}
- return z.writeFileContents(fileHeader, reader)
+ reader := &byteReaderCloser{bytes.NewReader(buf), ioutil.NopCloser(nil)}
+
+ return z.writeFileContents(fh, reader)
}
func (z *zipWriter) writeFileContents(header *zip.FileHeader, r readerSeekerCloser) (err error) {
@@ -770,19 +756,6 @@
close(compressChan)
}
-func (z *zipWriter) addExtraField(zipHeader *zip.FileHeader, fieldHeader [2]byte, data []byte) {
- // add the field header in little-endian order
- zipHeader.Extra = append(zipHeader.Extra, fieldHeader[1], fieldHeader[0])
-
- // specify the length of the data (in little-endian order)
- dataLength := len(data)
- lengthBytes := []byte{byte(dataLength % 256), byte(dataLength / 256)}
- zipHeader.Extra = append(zipHeader.Extra, lengthBytes...)
-
- // add the contents of the extra field
- zipHeader.Extra = append(zipHeader.Extra, data...)
-}
-
// writeDirectory annotates that dir is a directory created for the src file or directory, and adds
// the directory entry to the zip file if directories are enabled.
func (z *zipWriter) writeDirectory(dir, src string) error {
@@ -810,17 +783,19 @@
if z.directories {
// make a directory entry for each uncreated directory
for _, cleanDir := range zipDirs {
- dirHeader := &zip.FileHeader{
- Name: cleanDir + "/",
- }
- dirHeader.SetMode(0700 | os.ModeDir)
- dirHeader.SetModTime(z.time)
+ var dirHeader *zip.FileHeader
- if *emulateJar && dir == "META-INF/" {
- // Jar files have a 0-length extra field with header "CAFE"
- z.addExtraField(dirHeader, [2]byte{0xca, 0xfe}, []byte{})
+ if *emulateJar && cleanDir+"/" == jar.MetaDir {
+ dirHeader = jar.MetaDirFileHeader()
+ } else {
+ dirHeader = &zip.FileHeader{
+ Name: cleanDir + "/",
+ }
+ dirHeader.SetMode(0700 | os.ModeDir)
}
+ dirHeader.SetModTime(z.time)
+
ze := make(chan *zipEntry, 1)
ze <- &zipEntry{
fh: dirHeader,
diff --git a/jar/Android.bp b/jar/Android.bp
index 23ad536..6c2e60e 100644
--- a/jar/Android.bp
+++ b/jar/Android.bp
@@ -18,5 +18,8 @@
srcs: [
"jar.go",
],
+ deps: [
+ "android-archive-zip",
+ ],
}
diff --git a/jar/jar.go b/jar/jar.go
index 5960bf0..f17bc98 100644
--- a/jar/jar.go
+++ b/jar/jar.go
@@ -15,8 +15,14 @@
package jar
import (
+ "bytes"
"fmt"
+ "io/ioutil"
+ "os"
"strings"
+ "time"
+
+ "android/soong/third_party/zip"
)
const (
@@ -25,6 +31,10 @@
ModuleInfoClass = "module-info.class"
)
+var DefaultTime = time.Date(2009, 1, 1, 0, 0, 0, 0, time.UTC)
+
+var MetaDirExtra = [2]byte{0xca, 0xfe}
+
// EntryNamesLess tells whether <filepathA> should precede <filepathB> in
// the order of files with a .jar
func EntryNamesLess(filepathA string, filepathB string) (less bool) {
@@ -59,3 +69,56 @@
}
panic(fmt.Errorf("file %q did not match any pattern", name))
}
+
+func MetaDirFileHeader() *zip.FileHeader {
+ dirHeader := &zip.FileHeader{
+ Name: MetaDir,
+ Extra: []byte{MetaDirExtra[1], MetaDirExtra[0], 0, 0},
+ }
+ dirHeader.SetMode(0700 | os.ModeDir)
+ dirHeader.SetModTime(DefaultTime)
+
+ return dirHeader
+}
+
+// Convert manifest source path to zip header and contents. If path is empty uses a default
+// manifest.
+func ManifestFileContents(src string) (*zip.FileHeader, []byte, error) {
+ b, err := manifestContents(src)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ fh := &zip.FileHeader{
+ Name: ManifestFile,
+ Method: zip.Store,
+ UncompressedSize64: uint64(len(b)),
+ }
+
+ return fh, b, nil
+}
+
+// Convert manifest source path to contents. If path is empty uses a default manifest.
+func manifestContents(src string) ([]byte, error) {
+ var givenBytes []byte
+ var err error
+
+ if src != "" {
+ givenBytes, err = ioutil.ReadFile(src)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ manifestMarker := []byte("Manifest-Version:")
+ header := append(manifestMarker, []byte(" 1.0\nCreated-By: soong_zip\n")...)
+
+ var finalBytes []byte
+ if !bytes.Contains(givenBytes, manifestMarker) {
+ finalBytes = append(append(header, givenBytes...), byte('\n'))
+ } else {
+ finalBytes = givenBytes
+ }
+
+ return finalBytes, nil
+}
diff --git a/java/androidmk.go b/java/androidmk.go
index 680d864..89d7d51 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -25,13 +25,17 @@
func (library *Library) AndroidMk() android.AndroidMkData {
return android.AndroidMkData{
Class: "JAVA_LIBRARIES",
- OutputFile: android.OptionalPathForPath(library.outputFile),
+ OutputFile: android.OptionalPathForPath(library.classpathFile),
Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
Extra: []android.AndroidMkExtraFunc{
func(w io.Writer, outputFile android.Path) {
if library.properties.Installable != nil && *library.properties.Installable == false {
fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
}
+ if library.dexJarFile != nil {
+ fmt.Fprintln(w, "LOCAL_SOONG_DEX_JAR :=", library.dexJarFile.String())
+ }
+ fmt.Fprintln(w, "LOCAL_SDK_VERSION :=", library.deviceProperties.Sdk_version)
},
},
}
@@ -53,7 +57,7 @@
func (binary *Binary) AndroidMk() android.AndroidMkData {
return android.AndroidMkData{
Class: "JAVA_LIBRARIES",
- OutputFile: android.OptionalPathForPath(binary.outputFile),
+ OutputFile: android.OptionalPathForPath(binary.classpathFile),
Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
android.WriteAndroidMkData(w, data)
diff --git a/java/builder.go b/java/builder.go
index d6f8c5b..b8332ad 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -78,17 +78,32 @@
combineJar = pctx.AndroidStaticRule("combineJar",
blueprint.RuleParams{
- Command: `${config.MergeZipsCmd} -j $out $in`,
+ Command: `${config.MergeZipsCmd} -j $jarArgs $out $in`,
CommandDeps: []string{"${config.MergeZipsCmd}"},
},
- "outDir")
+ "jarArgs")
+
+ desugar = pctx.AndroidStaticRule("desugar",
+ blueprint.RuleParams{
+ Command: `rm -rf $dumpDir && mkdir -p $dumpDir && ` +
+ `${config.JavaCmd} ` +
+ `-Djdk.internal.lambda.dumpProxyClasses=$$(cd $dumpDir && pwd) ` +
+ `$javaFlags ` +
+ `-jar ${config.DesugarJar} $classpathFlags $desugarFlags ` +
+ `-i $in -o $out`,
+ CommandDeps: []string{"${config.DesugarJar}"},
+ },
+ "javaFlags", "classpathFlags", "desugarFlags", "dumpDir")
dx = pctx.AndroidStaticRule("dx",
blueprint.RuleParams{
Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
- `${config.DxCmd} --dex --output=$outDir $dxFlags $in || ( rm -rf "$outDir"; exit 41 ) && ` +
- `find "$outDir" -name "classes*.dex" | sort > $out`,
- CommandDeps: []string{"${config.DxCmd}"},
+ `${config.DxCmd} --dex --output=$outDir $dxFlags $in && ` +
+ `${config.SoongZipCmd} -jar -o $out -C $outDir -D $outDir`,
+ CommandDeps: []string{
+ "${config.DxCmd}",
+ "${config.SoongZipCmd}",
+ },
},
"outDir", "dxFlags")
@@ -107,8 +122,9 @@
type javaBuilderFlags struct {
javacFlags string
dxFlags string
- bootClasspath string
- classpath string
+ bootClasspath classpath
+ classpath classpath
+ desugarFlags string
aidlFlags string
javaVersion string
}
@@ -126,11 +142,13 @@
classDir := android.PathForModuleOut(ctx, "classes")
annoDir := android.PathForModuleOut(ctx, "anno")
- classJar := android.PathForModuleOut(ctx, "classes.jar")
+ classJar := android.PathForModuleOut(ctx, "classes-compiled.jar")
javacFlags := flags.javacFlags + android.JoinWithPrefix(srcFileLists.Strings(), "@")
deps = append(deps, srcFileLists...)
+ deps = append(deps, flags.bootClasspath...)
+ deps = append(deps, flags.classpath...)
ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Rule: javac,
@@ -140,8 +158,8 @@
Implicits: deps,
Args: map[string]string{
"javacFlags": javacFlags,
- "bootClasspath": flags.bootClasspath,
- "classpath": flags.classpath,
+ "bootClasspath": flags.bootClasspath.JavaBootClasspath(ctx.Device()),
+ "classpath": flags.classpath.JavaClasspath(),
"outDir": classDir.String(),
"annoDir": annoDir.String(),
"javaVersion": flags.javaVersion,
@@ -166,6 +184,8 @@
javacFlags := flags.javacFlags + android.JoinWithPrefix(srcFileLists.Strings(), "@")
deps = append(deps, srcFileLists...)
+ deps = append(deps, flags.bootClasspath...)
+ deps = append(deps, flags.classpath...)
ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Rule: errorprone,
@@ -175,8 +195,8 @@
Implicits: deps,
Args: map[string]string{
"javacFlags": javacFlags,
- "bootClasspath": flags.bootClasspath,
- "classpath": flags.classpath,
+ "bootClasspath": flags.bootClasspath.JavaBootClasspath(ctx.Device()),
+ "classpath": flags.classpath.JavaClasspath(),
"outDir": classDir.String(),
"annoDir": annoDir.String(),
"javaVersion": flags.javaVersion,
@@ -187,7 +207,7 @@
}
func TransformResourcesToJar(ctx android.ModuleContext, resources []jarSpec,
- manifest android.OptionalPath, deps android.Paths) android.Path {
+ deps android.Paths) android.Path {
outputFile := android.PathForModuleOut(ctx, "res.jar")
@@ -198,11 +218,6 @@
jarArgs = append(jarArgs, j.soongJarArgs())
}
- if manifest.Valid() {
- deps = append(deps, manifest.Path())
- jarArgs = append(jarArgs, "-m "+manifest.String())
- }
-
ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Rule: jar,
Description: "jar",
@@ -216,29 +231,82 @@
return outputFile
}
-func TransformJarsToJar(ctx android.ModuleContext, stem string, jars android.Paths) android.Path {
+func TransformJarsToJar(ctx android.ModuleContext, stem string, jars android.Paths,
+ manifest android.OptionalPath, stripDirs bool) android.Path {
outputFile := android.PathForModuleOut(ctx, stem)
- if len(jars) == 1 {
+ if len(jars) == 1 && !manifest.Valid() {
return jars[0]
}
+ var deps android.Paths
+
+ var jarArgs []string
+ if manifest.Valid() {
+ jarArgs = append(jarArgs, "-m "+manifest.String())
+ deps = append(deps, manifest.Path())
+ }
+
+ if stripDirs {
+ jarArgs = append(jarArgs, "-D")
+ }
+
ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Rule: combineJar,
Description: "combine jars",
Output: outputFile,
Inputs: jars,
+ Implicits: deps,
+ Args: map[string]string{
+ "jarArgs": strings.Join(jarArgs, " "),
+ },
})
return outputFile
}
-func TransformClassesJarToDex(ctx android.ModuleContext, classesJar android.Path,
- flags javaBuilderFlags) jarSpec {
+func TransformDesugar(ctx android.ModuleContext, classesJar android.Path,
+ flags javaBuilderFlags) android.Path {
+
+ outputFile := android.PathForModuleOut(ctx, "classes-desugar.jar")
+ dumpDir := android.PathForModuleOut(ctx, "desugar_dumped_classes")
+
+ javaFlags := ""
+ if ctx.AConfig().Getenv("EXPERIMENTAL_USE_OPENJDK9") != "" {
+ javaFlags = "--add-opens java.base/java.lang.invoke=ALL-UNNAMED"
+ }
+
+ var desugarFlags []string
+ desugarFlags = append(desugarFlags, flags.bootClasspath.DesugarBootClasspath()...)
+ desugarFlags = append(desugarFlags, flags.classpath.DesugarClasspath()...)
+
+ var deps android.Paths
+ deps = append(deps, flags.bootClasspath...)
+ deps = append(deps, flags.classpath...)
+
+ ctx.ModuleBuild(pctx, android.ModuleBuildParams{
+ Rule: desugar,
+ Description: "desugar",
+ Output: outputFile,
+ Input: classesJar,
+ Implicits: deps,
+ Args: map[string]string{
+ "dumpDir": dumpDir.String(),
+ "javaFlags": javaFlags,
+ "classpathFlags": strings.Join(desugarFlags, " "),
+ "desugarFlags": flags.desugarFlags,
+ },
+ })
+
+ return outputFile
+}
+
+func TransformClassesJarToDexJar(ctx android.ModuleContext, classesJar android.Path,
+ flags javaBuilderFlags) android.Path {
outDir := android.PathForModuleOut(ctx, "dex")
- outputFile := android.PathForModuleOut(ctx, "dex.filelist")
+ outputFile := android.PathForModuleOut(ctx, "classes.dex.jar")
ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Rule: dx,
@@ -251,34 +319,6 @@
},
})
- return jarSpec{outputFile, outDir}
-}
-
-func TransformDexToJavaLib(ctx android.ModuleContext, resources []jarSpec,
- dexJarSpec jarSpec) android.Path {
-
- outputFile := android.PathForModuleOut(ctx, "javalib.jar")
- var deps android.Paths
- var jarArgs []string
-
- for _, j := range resources {
- deps = append(deps, j.fileList)
- jarArgs = append(jarArgs, j.soongJarArgs())
- }
-
- deps = append(deps, dexJarSpec.fileList)
- jarArgs = append(jarArgs, dexJarSpec.soongJarArgs())
-
- ctx.ModuleBuild(pctx, android.ModuleBuildParams{
- Rule: jar,
- Description: "jar",
- Output: outputFile,
- Implicits: deps,
- Args: map[string]string{
- "jarArgs": strings.Join(jarArgs, " "),
- },
- })
-
return outputFile
}
@@ -297,3 +337,83 @@
return outputFile
}
+
+type classpath []android.Path
+
+// Returns a -classpath argument in the form java or javac expects
+func (x *classpath) JavaClasspath() string {
+ if len(*x) > 0 {
+ return "-classpath " + strings.Join(x.Strings(), ":")
+ } else {
+ return ""
+ }
+}
+
+// Returns a -processorpath argument in the form java or javac expects
+func (x *classpath) JavaProcessorpath() string {
+ if len(*x) > 0 {
+ return "-processorpath " + strings.Join(x.Strings(), ":")
+ } else {
+ return ""
+ }
+}
+
+// Returns a -bootclasspath argument in the form java or javac expects. If forceEmpty is true,
+// returns -bootclasspath "" if the bootclasspath is empty to ensure javac does not fall back to the
+// default bootclasspath.
+func (x *classpath) JavaBootClasspath(forceEmpty bool) string {
+ if len(*x) > 0 {
+ return "-bootclasspath " + strings.Join(x.Strings(), ":")
+ } else if forceEmpty {
+ return `-bootclasspath ""`
+ } else {
+ return ""
+ }
+}
+
+func (x *classpath) DesugarBootClasspath() []string {
+ if x == nil || *x == nil {
+ return nil
+ }
+ flags := make([]string, len(*x))
+ for i, v := range *x {
+ flags[i] = "--bootclasspath_entry " + v.String()
+ }
+
+ return flags
+}
+
+func (x *classpath) DesugarClasspath() []string {
+ if x == nil || *x == nil {
+ return nil
+ }
+ flags := make([]string, len(*x))
+ for i, v := range *x {
+ flags[i] = "--classpath_entry " + v.String()
+ }
+
+ return flags
+}
+
+// Append an android.Paths to the end of the classpath list
+func (x *classpath) AddPaths(paths android.Paths) {
+ for _, path := range paths {
+ *x = append(*x, path)
+ }
+}
+
+// Convert a classpath to an android.Paths
+func (x *classpath) Paths() android.Paths {
+ return append(android.Paths(nil), (*x)...)
+}
+
+func (x *classpath) Strings() []string {
+ if x == nil {
+ return nil
+ }
+ ret := make([]string, len(*x))
+ for i, path := range *x {
+ ret[i] = path.String()
+ }
+ return ret
+}
diff --git a/java/config/config.go b/java/config/config.go
index 69d6fc3..3029a5a 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -68,6 +68,7 @@
pctx.StaticVariable("MergeZipsCmd", filepath.Join("${bootstrap.ToolDir}", "merge_zips"))
pctx.HostBinToolVariable("DxCmd", "dx")
pctx.HostJavaToolVariable("JarjarCmd", "jarjar.jar")
+ pctx.HostJavaToolVariable("DesugarJar", "desugar.jar")
pctx.VariableFunc("JavacWrapper", func(config interface{}) (string, error) {
if override := config.(android.Config).Getenv("JAVAC_WRAPPER"); override != "" {
diff --git a/java/java.go b/java/java.go
index b4ce35e..2ded80b 100644
--- a/java/java.go
+++ b/java/java.go
@@ -137,6 +137,12 @@
// output file suitable for inserting into the classpath of another compile
classpathFile android.Path
+ // 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
@@ -154,6 +160,7 @@
type Dependency interface {
ClasspathFiles() android.Paths
+ ResourceJarFiles() android.Paths
AidlIncludeDirs() android.Paths
}
@@ -168,12 +175,11 @@
}
var (
- staticLibTag = dependencyTag{name: "staticlib"}
- libTag = dependencyTag{name: "javalib"}
- bootClasspathTag = dependencyTag{name: "bootclasspath"}
- frameworkResTag = dependencyTag{name: "framework-res"}
- sdkDependencyTag = dependencyTag{name: "sdk"}
- annotationProcessorTag = dependencyTag{name: "annotation processor"}
+ staticLibTag = dependencyTag{name: "staticlib"}
+ libTag = dependencyTag{name: "javalib"}
+ bootClasspathTag = dependencyTag{name: "bootclasspath"}
+ frameworkResTag = dependencyTag{name: "framework-res"}
+ sdkDependencyTag = dependencyTag{name: "sdk"}
)
func (j *Module) deps(ctx android.BottomUpMutatorContext) {
@@ -202,7 +208,7 @@
}
ctx.AddDependency(ctx.Module(), libTag, j.properties.Libs...)
ctx.AddDependency(ctx.Module(), staticLibTag, j.properties.Static_libs...)
- ctx.AddDependency(ctx.Module(), annotationProcessorTag, j.properties.Annotation_processors...)
+ ctx.AddDependency(ctx.Module(), libTag, j.properties.Annotation_processors...)
android.ExtractSourcesDeps(ctx, j.properties.Srcs)
}
@@ -230,13 +236,13 @@
}
type deps struct {
- classpath android.Paths
- bootClasspath android.Paths
- staticJars android.Paths
- aidlIncludeDirs android.Paths
- srcFileLists android.Paths
- annotationProcessors android.Paths
- aidlPreprocess android.OptionalPath
+ classpath android.Paths
+ bootClasspath android.Paths
+ staticJars android.Paths
+ staticJarResources android.Paths
+ aidlIncludeDirs android.Paths
+ srcFileLists android.Paths
+ aidlPreprocess android.OptionalPath
}
func (j *Module) collectDeps(ctx android.ModuleContext) deps {
@@ -264,8 +270,7 @@
case staticLibTag:
deps.classpath = append(deps.classpath, dep.ClasspathFiles()...)
deps.staticJars = append(deps.staticJars, dep.ClasspathFiles()...)
- case annotationProcessorTag:
- deps.annotationProcessors = append(deps.annotationProcessors, 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
@@ -306,21 +311,17 @@
javacFlags = config.StripJavac9Flags(javacFlags)
}
- if len(deps.annotationProcessors) > 0 {
- javacFlags = append(javacFlags,
- "-processorpath "+strings.Join(deps.annotationProcessors.Strings(), ":"))
- }
-
- for _, c := range j.properties.Annotation_processor_classes {
- javacFlags = append(javacFlags, "-processor "+c)
- }
-
if j.properties.Java_version != nil {
flags.javaVersion = *j.properties.Java_version
} else {
flags.javaVersion = "${config.DefaultJavaVersion}"
}
+ var extraDeps android.Paths
+
+ flags.bootClasspath.AddPaths(deps.bootClasspath)
+ flags.classpath.AddPaths(deps.classpath)
+
if len(javacFlags) > 0 {
ctx.Variable(pctx, "javacFlags", strings.Join(javacFlags, " "))
flags.javacFlags = "$javacFlags"
@@ -332,21 +333,6 @@
flags.aidlFlags = "$aidlFlags"
}
- var extraDeps android.Paths
-
- if len(deps.bootClasspath) > 0 {
- flags.bootClasspath = "-bootclasspath " + strings.Join(deps.bootClasspath.Strings(), ":")
- extraDeps = append(extraDeps, deps.bootClasspath...)
- } else if ctx.Device() {
- // Explicitly clear the bootclasspath for device builds
- flags.bootClasspath = `-bootclasspath ""`
- }
-
- if len(deps.classpath) > 0 {
- flags.classpath = "-classpath " + strings.Join(deps.classpath.Strings(), ":")
- extraDeps = append(extraDeps, deps.classpath...)
- }
-
srcFiles := ctx.ExpandSources(j.properties.Srcs, j.properties.Exclude_srcs)
srcFiles = j.genSources(ctx, srcFiles, flags)
@@ -385,23 +371,29 @@
}
resourceJarSpecs := ResourceDirsToJarSpecs(ctx, j.properties.Resource_dirs, j.properties.Exclude_resource_dirs)
- manifest := android.OptionalPathForModuleSrc(ctx, j.properties.Manifest)
-
- if len(resourceJarSpecs) > 0 || manifest.Valid() {
+ if len(resourceJarSpecs) > 0 {
// Combine classes + resources into classes-full-debug.jar
- resourceJar := TransformResourcesToJar(ctx, resourceJarSpecs, manifest, extraJarDeps)
+ resourceJar := TransformResourcesToJar(ctx, resourceJarSpecs, extraJarDeps)
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...)
+ manifest := android.OptionalPathForModuleSrc(ctx, j.properties.Manifest)
+
// Combine the classes built from sources, any manifests, and any static libraries into
// classes-combined.jar. If there is only one input jar this step will be skipped.
- outputFile := TransformJarsToJar(ctx, "classes-combined.jar", jars)
+ outputFile := TransformJarsToJar(ctx, "classes.jar", jars, manifest, false)
if j.properties.Jarjar_rules != nil {
jarjar_rules := android.PathForModuleSrc(ctx, *j.properties.Jarjar_rules)
@@ -450,14 +442,39 @@
flags.dxFlags = strings.Join(dxFlags, " ")
- // Compile classes.jar into classes.dex
- dexJarSpec := TransformClassesJarToDex(ctx, outputFile, flags)
+ desugarFlags := []string{
+ "--min_sdk_version " + minSdkVersion,
+ "--desugar_try_with_resources_if_needed=false",
+ "--allow_empty_bootclasspath",
+ }
+
+ if inList("--core-library", dxFlags) {
+ desugarFlags = append(desugarFlags, "--core_library")
+ }
+
+ flags.desugarFlags = strings.Join(desugarFlags, " ")
+
+ desugarJar := TransformDesugar(ctx, outputFile, flags)
if ctx.Failed() {
return
}
- // Combine classes.dex + resources into javalib.jar
- outputFile = TransformDexToJavaLib(ctx, resourceJarSpecs, dexJarSpec)
+ // TODO(ccross): For now, use the desugared jar as the classpath file. Eventually this
+ // might cause problems because desugar wants non-desugared jars in its class path.
+ j.classpathFile = desugarJar
+
+ // Compile classes.jar into classes.dex
+ dexJarFile := TransformClassesJarToDexJar(ctx, 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)
j.outputFile = outputFile
@@ -469,6 +486,10 @@
return android.Paths{j.classpathFile}
}
+func (j *Module) ResourceJarFiles() android.Paths {
+ return j.resourceJarFiles
+}
+
func (j *Module) AidlIncludeDirs() android.Paths {
return j.exportAidlIncludeDirs
}
@@ -616,7 +637,7 @@
func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.classpathFiles = android.PathsForModuleSrc(ctx, j.properties.Jars)
- j.combinedClasspathFile = TransformJarsToJar(ctx, "classes.jar", j.classpathFiles)
+ j.combinedClasspathFile = TransformJarsToJar(ctx, "classes.jar", j.classpathFiles, android.OptionalPath{}, false)
}
var _ Dependency = (*Import)(nil)
@@ -625,6 +646,11 @@
return j.classpathFiles
}
+func (j *Import) ResourceJarFiles() android.Paths {
+ // resources are in the ClasspathFiles
+ return nil
+}
+
func (j *Import) AidlIncludeDirs() android.Paths {
return nil
}
@@ -687,9 +713,11 @@
func SdkPrebuiltFactory() android.Module {
module := &sdkPrebuilt{}
- module.AddProperties(&module.sdkProperties)
+ module.AddProperties(
+ &module.sdkProperties,
+ &module.Import.properties)
- android.InitPrebuiltModule(module, &module.properties.Jars)
+ android.InitPrebuiltModule(module, &module.Import.properties.Jars)
android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
return module
}
diff --git a/java/java_test.go b/java/java_test.go
index 4f5c0ec..040adb4 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -51,19 +51,30 @@
}
func testJava(t *testing.T, bp string) *android.TestContext {
- config := android.TestConfig(buildDir)
+ config := android.TestArchConfig(buildDir)
- ctx := android.NewTestContext()
+ ctx := android.NewTestArchContext()
ctx.RegisterModuleType("android_app", android.ModuleFactoryAdaptor(AndroidAppFactory))
ctx.RegisterModuleType("java_library", android.ModuleFactoryAdaptor(LibraryFactory))
+ ctx.RegisterModuleType("java_library_host", android.ModuleFactoryAdaptor(LibraryHostFactory))
ctx.RegisterModuleType("java_import", android.ModuleFactoryAdaptor(ImportFactory))
ctx.RegisterModuleType("java_defaults", android.ModuleFactoryAdaptor(defaultsFactory))
+ ctx.RegisterModuleType("android_prebuilt_sdk", android.ModuleFactoryAdaptor(SdkPrebuiltFactory))
ctx.PreArchMutators(android.RegisterPrebuiltsPreArchMutators)
ctx.PreArchMutators(android.RegisterPrebuiltsPostDepsMutators)
ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
ctx.Register()
- extraModules := []string{"core-oj", "core-libart", "frameworks", "sdk_v14"}
+ extraModules := []string{
+ "core-oj",
+ "core-libart",
+ "framework",
+ "ext",
+ "okhttp",
+ "android_stubs_current",
+ "android_system_stubs_current",
+ "android_test_stubs_current",
+ }
for _, extra := range extraModules {
bp += fmt.Sprintf(`
@@ -75,13 +86,21 @@
`, extra)
}
+ bp += `
+ android_prebuilt_sdk {
+ name: "sdk_v14",
+ jars: ["sdk_v14.jar"],
+ }
+ `
+
ctx.MockFileSystem(map[string][]byte{
- "Android.bp": []byte(bp),
- "a.java": nil,
- "b.java": nil,
- "c.java": nil,
- "a.jar": nil,
- "b.jar": nil,
+ "Android.bp": []byte(bp),
+ "a.java": nil,
+ "b.java": nil,
+ "c.java": nil,
+ "a.jar": nil,
+ "b.jar": nil,
+ "sdk_v14.jar": nil,
})
_, errs := ctx.ParseBlueprintsFiles("Android.bp")
@@ -92,6 +111,17 @@
return ctx
}
+func moduleToPath(name string) string {
+ switch {
+ case name == `""`:
+ return name
+ case strings.HasPrefix(name, "sdk_v"):
+ return name + ".jar"
+ default:
+ return filepath.Join(buildDir, ".intermediates", name, "android_common", "classes-desugar.jar")
+ }
+}
+
func TestSimple(t *testing.T) {
ctx := testJava(t, `
java_library {
@@ -112,15 +142,15 @@
}
`)
- javac := ctx.ModuleForTests("foo", "").Rule("javac")
- combineJar := ctx.ModuleForTests("foo", "").Rule("combineJar")
+ javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
+ combineJar := ctx.ModuleForTests("foo", "android_common").Rule("combineJar")
if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
}
- bar := filepath.Join(buildDir, ".intermediates", "bar", "classes.jar")
- baz := filepath.Join(buildDir, ".intermediates", "baz", "classes.jar")
+ bar := filepath.Join(buildDir, ".intermediates", "bar", "android_common", "classes-desugar.jar")
+ baz := filepath.Join(buildDir, ".intermediates", "baz", "android_common", "classes-desugar.jar")
if !strings.Contains(javac.Args["classpath"], bar) {
t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], bar)
@@ -135,83 +165,130 @@
}
}
-func TestSdk(t *testing.T) {
- ctx := testJava(t, `
- java_library {
- name: "foo1",
- srcs: ["a.java"],
- }
+var classpathTestcases = []struct {
+ name string
+ host android.OsClass
+ properties string
+ bootclasspath []string
+ classpath []string
+}{
+ {
+ name: "default",
+ bootclasspath: []string{"core-oj", "core-libart"},
+ classpath: []string{"ext", "framework", "okhttp"},
+ },
+ {
+ name: "blank sdk version",
+ properties: `sdk_version: "",`,
+ bootclasspath: []string{"core-oj", "core-libart"},
+ classpath: []string{"ext", "framework", "okhttp"},
+ },
+ {
- java_library {
- name: "foo2",
- srcs: ["a.java"],
- sdk_version: "",
- }
+ name: "sdk v14",
+ properties: `sdk_version: "14",`,
+ bootclasspath: []string{"sdk_v14"},
+ classpath: []string{},
+ },
+ {
- java_library {
- name: "foo3",
- srcs: ["a.java"],
- sdk_version: "14",
- }
+ name: "current",
+ properties: `sdk_version: "current",`,
+ bootclasspath: []string{"android_stubs_current"},
+ classpath: []string{},
+ },
+ {
- java_library {
- name: "foo4",
- srcs: ["a.java"],
- sdk_version: "current",
- }
+ name: "system_current",
+ properties: `sdk_version: "system_current",`,
+ bootclasspath: []string{"android_system_stubs_current"},
+ classpath: []string{},
+ },
+ {
- java_library {
- name: "foo5",
- srcs: ["a.java"],
- sdk_version: "system_current",
- }
+ name: "test_current",
+ properties: `sdk_version: "test_current",`,
+ bootclasspath: []string{"android_test_stubs_current"},
+ classpath: []string{},
+ },
+ {
- java_library {
- name: "foo6",
- srcs: ["a.java"],
- sdk_version: "test_current",
- }
- `)
+ name: "nostdlib",
+ properties: `no_standard_libs: true`,
+ bootclasspath: []string{`""`},
+ classpath: []string{},
+ },
+ {
- type depType int
- const (
- staticLib = iota
- classpathLib
- bootclasspathLib
- )
+ name: "host default",
+ host: android.Host,
+ properties: ``,
+ classpath: []string{},
+ },
+ {
+ name: "host nostdlib",
+ host: android.Host,
+ properties: `no_standard_libs: true`,
+ classpath: []string{},
+ },
+}
- check := func(module string, depType depType, deps ...string) {
- for i := range deps {
- deps[i] = filepath.Join(buildDir, ".intermediates", deps[i], "classes.jar")
- }
- dep := strings.Join(deps, ":")
+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"
+ }
+ ctx := testJava(t, `
+ java_library`+hostExtra+` {
+ name: "foo",
+ srcs: ["a.java"],
+ `+testcase.properties+`
+ }
+ `)
- javac := ctx.ModuleForTests(module, "").Rule("javac")
+ convertModulesToPaths := func(cp []string) []string {
+ ret := make([]string, len(cp))
+ for i, e := range cp {
+ ret[i] = moduleToPath(e)
+ }
+ return ret
+ }
- if depType == bootclasspathLib {
+ bootclasspath := convertModulesToPaths(testcase.bootclasspath)
+ classpath := convertModulesToPaths(testcase.classpath)
+
+ variant := "android_common"
+ if testcase.host == android.Host {
+ variant = android.BuildOs.String() + "_common"
+ }
+ javac := ctx.ModuleForTests("foo", variant).Rule("javac")
+
got := strings.TrimPrefix(javac.Args["bootClasspath"], "-bootclasspath ")
- if got != dep {
- t.Errorf("module %q bootclasspath %q != %q", module, got, dep)
+ bc := strings.Join(bootclasspath, ":")
+ if got != bc {
+ t.Errorf("bootclasspath expected %q != got %q", bc, got)
}
- } else if depType == classpathLib {
- got := strings.TrimPrefix(javac.Args["classpath"], "-classpath ")
- if got != dep {
- t.Errorf("module %q classpath %q != %q", module, got, dep)
- }
- }
- if !reflect.DeepEqual(javac.Implicits.Strings(), deps) {
- t.Errorf("module %q implicits %q != %q", module, javac.Implicits.Strings(), deps)
- }
+ got = strings.TrimPrefix(javac.Args["classpath"], "-classpath ")
+ c := strings.Join(classpath, ":")
+ if got != c {
+ t.Errorf("classpath expected %q != got %q", c, got)
+ }
+
+ var deps []string
+ if len(bootclasspath) > 0 && bootclasspath[0] != `""` {
+ deps = append(deps, bootclasspath...)
+ }
+ deps = append(deps, classpath...)
+
+ if !reflect.DeepEqual(javac.Implicits.Strings(), deps) {
+ t.Errorf("implicits expected %q != got %q", deps, javac.Implicits.Strings())
+ }
+ })
}
- check("foo1", bootclasspathLib, "core-oj", "core-libart")
- check("foo2", bootclasspathLib, "core-oj", "core-libart")
- // TODO(ccross): these need the arch mutator to run to work correctly
- //check("foo3", bootclasspathLib, "sdk_v14")
- //check("foo4", bootclasspathLib, "android_stubs_current")
- //check("foo5", bootclasspathLib, "android_system_stubs_current")
- //check("foo6", bootclasspathLib, "android_test_stubs_current")
}
func TestPrebuilts(t *testing.T) {
@@ -234,8 +311,8 @@
}
`)
- javac := ctx.ModuleForTests("foo", "").Rule("javac")
- combineJar := ctx.ModuleForTests("foo", "").Rule("combineJar")
+ javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
+ combineJar := ctx.ModuleForTests("foo", "android_common").Rule("combineJar")
bar := "a.jar"
if !strings.Contains(javac.Args["classpath"], bar) {
@@ -272,19 +349,19 @@
}
`)
- javac := ctx.ModuleForTests("foo", "").Rule("javac")
- combineJar := ctx.ModuleForTests("foo", "").Rule("combineJar")
+ javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
+ combineJar := ctx.ModuleForTests("foo", "android_common").Rule("combineJar")
if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
}
- bar := filepath.Join(buildDir, ".intermediates", "bar", "classes.jar")
+ bar := filepath.Join(buildDir, ".intermediates", "bar", "android_common", "classes-desugar.jar")
if !strings.Contains(javac.Args["classpath"], bar) {
t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], bar)
}
- baz := filepath.Join(buildDir, ".intermediates", "baz", "classes.jar")
+ baz := filepath.Join(buildDir, ".intermediates", "baz", "android_common", "classes-desugar.jar")
if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != baz {
t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, baz)
}