Rearrange manifest file handling in merge_zips and soong_zip
Jar always puts default MANIFEST.MF files in if none was specified. Copying that behavior in soong_zip causes problems with merge_zips, because it ends up taking the default manifest from the classes.jar instead of the user's manifest from res.jar. We don't want the user's manifest in the classes.jar, otherwise a change to the manifest will cause all the class files to rebuild. Instead, move the manifest insertion to the final merge_zips stage. Test: m -j checkbuild Change-Id: Id6376961dbaf743c2fb92843f9bdf2e44b963be0
This commit is contained in:
@@ -15,8 +15,10 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"hash/crc32"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -52,10 +54,12 @@ func (s *zipToNotStrip) Set(zip_path string) error {
|
||||
}
|
||||
|
||||
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 init() {
|
||||
|
||||
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 @@ func main() {
|
||||
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 @@ func (p zipEntryPath) String() string {
|
||||
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 @@ func mergeZips(readers []namedZipReader, writer *zip.Writer, sortEntries bool, e
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ func mergeZips(readers []namedZipReader, writer *zip.Writer, sortEntries bool, e
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user