Merge "Make cc.NewLLndkStubLibrary as public"
diff --git a/android/paths.go b/android/paths.go
index d6a1c66..4adaa2d 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -18,6 +18,7 @@
"fmt"
"path/filepath"
"reflect"
+ "sort"
"strings"
"github.com/google/blueprint"
@@ -380,6 +381,38 @@
return ret
}
+// DirectorySortedPaths is a slice of paths that are sorted such that all files in a directory
+// (including subdirectories) are in a contiguous subslice of the list, and can be found in
+// O(log(N)) time using a binary search on the directory prefix.
+type DirectorySortedPaths Paths
+
+func PathsToDirectorySortedPaths(paths Paths) DirectorySortedPaths {
+ ret := append(DirectorySortedPaths(nil), paths...)
+ sort.Slice(ret, func(i, j int) bool {
+ return ret[i].String() < ret[j].String()
+ })
+ return ret
+}
+
+// PathsInDirectory returns a subslice of the DirectorySortedPaths as a Paths that contains all entries
+// that are in the specified directory and its subdirectories.
+func (p DirectorySortedPaths) PathsInDirectory(dir string) Paths {
+ prefix := filepath.Clean(dir) + "/"
+ start := sort.Search(len(p), func(i int) bool {
+ return prefix < p[i].String()
+ })
+
+ ret := p[start:]
+
+ end := sort.Search(len(ret), func(i int) bool {
+ return !strings.HasPrefix(ret[i].String(), prefix)
+ })
+
+ ret = ret[:end]
+
+ return Paths(ret)
+}
+
// WritablePaths is a slice of WritablePaths, used for multiple outputs.
type WritablePaths []WritablePath
diff --git a/android/paths_test.go b/android/paths_test.go
index 248f4d4..82ae4dc 100644
--- a/android/paths_test.go
+++ b/android/paths_test.go
@@ -340,3 +340,75 @@
})
}
}
+
+func TestDirectorySortedPaths(t *testing.T) {
+ makePaths := func() Paths {
+ return Paths{
+ PathForTesting("a.txt"),
+ PathForTesting("a/txt"),
+ PathForTesting("a/b/c"),
+ PathForTesting("a/b/d"),
+ PathForTesting("b"),
+ PathForTesting("b/b.txt"),
+ PathForTesting("a/a.txt"),
+ }
+ }
+
+ expected := []string{
+ "a.txt",
+ "a/a.txt",
+ "a/b/c",
+ "a/b/d",
+ "a/txt",
+ "b",
+ "b/b.txt",
+ }
+
+ paths := makePaths()
+ reversePaths := make(Paths, len(paths))
+ for i, v := range paths {
+ reversePaths[len(paths)-i-1] = v
+ }
+
+ sortedPaths := PathsToDirectorySortedPaths(paths)
+ reverseSortedPaths := PathsToDirectorySortedPaths(reversePaths)
+
+ if !reflect.DeepEqual(Paths(sortedPaths).Strings(), expected) {
+ t.Fatalf("sorted paths:\n %#v\n != \n %#v", paths.Strings(), expected)
+ }
+
+ if !reflect.DeepEqual(Paths(reverseSortedPaths).Strings(), expected) {
+ t.Fatalf("sorted reversed paths:\n %#v\n !=\n %#v", reversePaths.Strings(), expected)
+ }
+
+ expectedA := []string{
+ "a/a.txt",
+ "a/b/c",
+ "a/b/d",
+ "a/txt",
+ }
+
+ inA := sortedPaths.PathsInDirectory("a")
+ if !reflect.DeepEqual(inA.Strings(), expectedA) {
+ t.Errorf("FilesInDirectory(a):\n %#v\n != \n %#v", inA.Strings(), expectedA)
+ }
+
+ expectedA_B := []string{
+ "a/b/c",
+ "a/b/d",
+ }
+
+ inA_B := sortedPaths.PathsInDirectory("a/b")
+ if !reflect.DeepEqual(inA_B.Strings(), expectedA_B) {
+ t.Errorf("FilesInDirectory(a/b):\n %#v\n != \n %#v", inA_B.Strings(), expectedA_B)
+ }
+
+ expectedB := []string{
+ "b/b.txt",
+ }
+
+ inB := sortedPaths.PathsInDirectory("b")
+ if !reflect.DeepEqual(inB.Strings(), expectedB) {
+ t.Errorf("FilesInDirectory(b):\n %#v\n != \n %#v", inA.Strings(), expectedA)
+ }
+}
diff --git a/android/variable.go b/android/variable.go
index d89c146..4272817 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -205,26 +205,29 @@
func (v *productVariables) SetDefaultConfig() {
*v = productVariables{
- Platform_sdk_version: intPtr(24),
+ Platform_sdk_version: intPtr(26),
+ Platform_version_active_codenames: []string{"P"},
+ Platform_version_future_codenames: []string{"P"},
+
HostArch: stringPtr("x86_64"),
HostSecondaryArch: stringPtr("x86"),
- DeviceName: stringPtr("flounder"),
+ DeviceName: stringPtr("generic_arm64"),
DeviceArch: stringPtr("arm64"),
DeviceArchVariant: stringPtr("armv8-a"),
- DeviceCpuVariant: stringPtr("denver64"),
+ DeviceCpuVariant: stringPtr("generic"),
DeviceAbi: &[]string{"arm64-v8a"},
DeviceUsesClang: boolPtr(true),
DeviceSecondaryArch: stringPtr("arm"),
- DeviceSecondaryArchVariant: stringPtr("armv7-a-neon"),
- DeviceSecondaryCpuVariant: stringPtr("denver"),
- DeviceSecondaryAbi: &[]string{"armeabi-v7a"},
+ DeviceSecondaryArchVariant: stringPtr("armv8-a"),
+ DeviceSecondaryCpuVariant: stringPtr("generic"),
+ DeviceSecondaryAbi: &[]string{"armeabi-v7a", "armeabi"},
AAPTConfig: &[]string{"normal", "large", "xlarge", "hdpi", "xhdpi", "xxhdpi"},
AAPTPreferredConfig: stringPtr("xhdpi"),
AAPTCharacteristics: stringPtr("nosdcard"),
AAPTPrebuiltDPI: &[]string{"xhdpi", "xxhdpi"},
- Malloc_not_svelte: boolPtr(false),
+ Malloc_not_svelte: boolPtr(true),
Safestack: boolPtr(false),
}
diff --git a/zip/Android.bp b/zip/Android.bp
index d708089..3bb4f25 100644
--- a/zip/Android.bp
+++ b/zip/Android.bp
@@ -19,6 +19,7 @@
pkgPath: "android/soong/zip",
deps: [
"android-archive-zip",
+ "blueprint-pathtools",
"soong-jar",
],
srcs: [
diff --git a/zip/cmd/main.go b/zip/cmd/main.go
index 348728c..c0418f7 100644
--- a/zip/cmd/main.go
+++ b/zip/cmd/main.go
@@ -120,14 +120,15 @@
}
var (
- out = flag.String("o", "", "file to write zip file to")
- manifest = flag.String("m", "", "input jar manifest file name")
- directories = flag.Bool("d", false, "include directories in zip")
- rootPrefix = flag.String("P", "", "path prefix within the zip at which to place files")
- relativeRoot = flag.String("C", "", "path to use as relative root of files in following -f, -l, or -D arguments")
- parallelJobs = flag.Int("j", runtime.NumCPU(), "number of parallel threads to use")
- compLevel = flag.Int("L", 5, "deflate compression level (0-9)")
- emulateJar = flag.Bool("jar", false, "modify the resultant .zip to emulate the output of 'jar'")
+ out = flag.String("o", "", "file to write zip file to")
+ manifest = flag.String("m", "", "input jar manifest file name")
+ directories = flag.Bool("d", false, "include directories in zip")
+ rootPrefix = flag.String("P", "", "path prefix within the zip at which to place files")
+ relativeRoot = flag.String("C", "", "path to use as relative root of files in following -f, -l, or -D arguments")
+ parallelJobs = flag.Int("j", runtime.NumCPU(), "number of parallel threads to use")
+ compLevel = flag.Int("L", 5, "deflate compression level (0-9)")
+ emulateJar = flag.Bool("jar", false, "modify the resultant .zip to emulate the output of 'jar'")
+ writeIfChanged = flag.Bool("write_if_changed", false, "only update resultant .zip if it has changed")
fArgs zip.FileArgs
nonDeflatedFiles = make(uniqueSet)
@@ -163,6 +164,7 @@
ManifestSourcePath: *manifest,
NumParallelJobs: *parallelJobs,
NonDeflatedFiles: nonDeflatedFiles,
+ WriteIfChanged: *writeIfChanged,
})
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
diff --git a/zip/zip.go b/zip/zip.go
index 95520fe..c878a0c 100644
--- a/zip/zip.go
+++ b/zip/zip.go
@@ -32,6 +32,8 @@
"sync"
"time"
+ "github.com/google/blueprint/pathtools"
+
"android/soong/jar"
"android/soong/third_party/zip"
)
@@ -127,6 +129,7 @@
ManifestSourcePath string
NumParallelJobs int
NonDeflatedFiles map[string]bool
+ WriteIfChanged bool
}
func Run(args ZipArgs) (err error) {
@@ -186,8 +189,38 @@
}
}
- return w.write(args.OutputFilePath, pathMappings, args.ManifestSourcePath, args.EmulateJar, args.NumParallelJobs)
+ buf := &bytes.Buffer{}
+ var out io.Writer = buf
+ if !args.WriteIfChanged {
+ f, err := os.Create(args.OutputFilePath)
+ if err != nil {
+ return err
+ }
+
+ defer f.Close()
+ defer func() {
+ if err != nil {
+ os.Remove(args.OutputFilePath)
+ }
+ }()
+
+ out = f
+ }
+
+ err = w.write(out, pathMappings, args.ManifestSourcePath, args.EmulateJar, args.NumParallelJobs)
+ if err != nil {
+ return err
+ }
+
+ if args.WriteIfChanged {
+ err := pathtools.WriteFileIfChanged(args.OutputFilePath, buf.Bytes(), 0666)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
}
func fillPathPairs(prefix, rel, src string, pathMappings *[]pathMapping, nonDeflatedFiles map[string]bool) error {
@@ -226,19 +259,7 @@
io.Seeker
}
-func (z *ZipWriter) write(out string, pathMappings []pathMapping, manifest string, emulateJar bool, parallelJobs int) error {
- f, err := os.Create(out)
- if err != nil {
- return err
- }
-
- defer f.Close()
- defer func() {
- if err != nil {
- os.Remove(out)
- }
- }()
-
+func (z *ZipWriter) write(f io.Writer, pathMappings []pathMapping, manifest string, emulateJar bool, parallelJobs int) error {
z.errors = make(chan error)
defer close(z.errors)
@@ -324,6 +345,7 @@
case op := <-writeOpChan:
currentWriteOpChan = nil
+ var err error
if op.fh.Method == zip.Deflate {
currentWriter, err = zipw.CreateCompressedHeader(op.fh)
} else {
@@ -356,21 +378,21 @@
currentReader = futureReader
case reader := <-currentReader:
- _, err = io.Copy(currentWriter, reader)
+ _, err := io.Copy(currentWriter, reader)
if err != nil {
return err
}
currentReader = nil
- case err = <-z.errors:
+ case err := <-z.errors:
return err
}
}
// One last chance to catch an error
select {
- case err = <-z.errors:
+ case err := <-z.errors:
return err
default:
zipw.Close()