diff --git a/cmd/merge_zips/merge_zips.go b/cmd/merge_zips/merge_zips.go index 7874a41b7..3c1cb9a18 100644 --- a/cmd/merge_zips/merge_zips.go +++ b/cmd/merge_zips/merge_zips.go @@ -26,11 +26,28 @@ import ( "android/soong/third_party/zip" ) +type strip struct{} + +func (s *strip) String() string { + return `""` +} + +func (s *strip) Set(path_prefix string) error { + strippings = append(strippings, path_prefix) + + return nil +} + 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)") + strippings []string ) +func init() { + flag.Var(&strip{}, "strip", "the prefix of file path to be excluded from the output zip") +} + func main() { flag.Usage = func() { fmt.Fprintln(os.Stderr, "usage: merge_zips [-j] output [inputs...]") @@ -115,7 +132,13 @@ func mergeZips(readers []namedZipReader, writer *zip.Writer, sortEntries bool, e orderedMappings := []fileMapping{} for _, namedReader := range readers { + FileLoop: for _, file := range namedReader.reader.File { + for _, path_prefix := range strippings { + if strings.HasPrefix(file.Name, path_prefix) { + continue FileLoop + } + } // check for other files or directories destined for the same path dest := file.Name mapKey := dest @@ -142,8 +165,15 @@ func mergeZips(readers []namedZipReader, writer *zip.Writer, sortEntries bool, e continue } if !isDir { - return fmt.Errorf("Duplicate path %v found in %v and %v\n", - dest, existingMapping.source.path, newMapping.source.path) + if emulateJar { + if existingMapping.source.content.CRC32 != newMapping.source.content.CRC32 { + fmt.Fprintf(os.Stdout, "WARNING: Duplicate path %v found in %v and %v\n", + dest, existingMapping.source.path, newMapping.source.path) + } + } else { + return fmt.Errorf("Duplicate path %v found in %v and %v\n", + dest, existingMapping.source.path, newMapping.source.path) + } } } else { // save entry @@ -151,7 +181,6 @@ func mergeZips(readers []namedZipReader, writer *zip.Writer, sortEntries bool, e orderedMappings = append(orderedMappings, newMapping) } } - } if emulateJar { diff --git a/third_party/zip/android.go b/third_party/zip/android.go index bde3afa4f..d35513fd7 100644 --- a/third_party/zip/android.go +++ b/third_party/zip/android.go @@ -32,7 +32,6 @@ func (w *Writer) CopyFrom(orig *File, newName string) error { fileHeader := orig.FileHeader fileHeader.Name = newName fh := &fileHeader - fh.Flags |= DataDescriptorFlag // The zip64 extras change between the Central Directory and Local File Header, while we use // the same structure for both. The Local File Haeder is taken care of by us writing a data @@ -57,24 +56,26 @@ func (w *Writer) CopyFrom(orig *File, newName string) error { } io.Copy(w.cw, io.NewSectionReader(orig.zipr, dataOffset, int64(orig.CompressedSize64))) - // Write data descriptor. - var buf []byte - if fh.isZip64() { - buf = make([]byte, dataDescriptor64Len) - } else { - buf = make([]byte, dataDescriptorLen) + if orig.hasDataDescriptor() { + // Write data descriptor. + var buf []byte + if fh.isZip64() { + buf = make([]byte, dataDescriptor64Len) + } else { + buf = make([]byte, dataDescriptorLen) + } + b := writeBuf(buf) + b.uint32(dataDescriptorSignature) + b.uint32(fh.CRC32) + if fh.isZip64() { + b.uint64(fh.CompressedSize64) + b.uint64(fh.UncompressedSize64) + } else { + b.uint32(fh.CompressedSize) + b.uint32(fh.UncompressedSize) + } + _, err = w.cw.Write(buf) } - b := writeBuf(buf) - b.uint32(dataDescriptorSignature) - b.uint32(fh.CRC32) - if fh.isZip64() { - b.uint64(fh.CompressedSize64) - b.uint64(fh.UncompressedSize64) - } else { - b.uint32(fh.CompressedSize) - b.uint32(fh.UncompressedSize) - } - _, err = w.cw.Write(buf) return err }