aboutsummaryrefslogtreecommitdiffstats
path: root/cmd
diff options
context:
space:
mode:
authorNan Zhang <nanzhang@google.com>2017-04-25 16:47:45 -0700
committerNan Zhang <nanzhang@google.com>2017-05-02 17:28:35 -0700
commitf281bd8c7b2d5dd7bd2545eb6fbbabb540c8a99f (patch)
tree4a2b328d735b21288342ebae9c3fa5cde0d29a40 /cmd
parentdd29407e74d796ab4493b3e0a8ccdb5693e15acd (diff)
downloadbuild_soong-f281bd8c7b2d5dd7bd2545eb6fbbabb540c8a99f.tar.gz
build_soong-f281bd8c7b2d5dd7bd2545eb6fbbabb540c8a99f.tar.bz2
build_soong-f281bd8c7b2d5dd7bd2545eb6fbbabb540c8a99f.zip
Supported minor features in soong_zip
1. Added ability to keep the mixed "-f"/"-l" order as same as command-line flags order. 2. Added "-s" flag to specify which target file within zip is stored uncompressed. Test: manual Change-Id: I338b25a7bd6bf1b7e9cc29ad3324575167630fb7
Diffstat (limited to 'cmd')
-rw-r--r--cmd/soong_zip/soong_zip.go150
1 files changed, 103 insertions, 47 deletions
diff --git a/cmd/soong_zip/soong_zip.go b/cmd/soong_zip/soong_zip.go
index 3e620168..84077884 100644
--- a/cmd/soong_zip/soong_zip.go
+++ b/cmd/soong_zip/soong_zip.go
@@ -55,33 +55,76 @@ func (nopCloser) Close() error {
}
type fileArg struct {
- rootPrefix, relativeRoot, file string
+ pathPrefixInZip, sourcePrefixToStrip string
+ sourceFiles []string
}
type pathMapping struct {
dest, src string
+ zipMethod uint16
+}
+
+type uniqueSet map[string]bool
+
+func (u *uniqueSet) String() string {
+ return `""`
+}
+
+func (u *uniqueSet) Set(s string) error {
+ if _, found := (*u)[s]; found {
+ return fmt.Errorf("File %q was specified twice as a file to not deflate", s)
+ } else {
+ (*u)[s] = true
+ }
+
+ return nil
}
type fileArgs []fileArg
-func (l *fileArgs) String() string {
+type file struct{}
+
+type listFiles struct{}
+
+func (f *file) String() string {
return `""`
}
-func (l *fileArgs) Set(s string) error {
+func (f *file) Set(s string) error {
if *relativeRoot == "" {
return fmt.Errorf("must pass -C before -f or -l")
}
- *l = append(*l,
- fileArg{rootPrefix: filepath.Clean(*rootPrefix),
- relativeRoot: filepath.Clean(*relativeRoot),
- file: s})
+ fArgs = append(fArgs, fileArg{
+ pathPrefixInZip: filepath.Clean(*rootPrefix),
+ sourcePrefixToStrip: filepath.Clean(*relativeRoot),
+ sourceFiles: []string{s},
+ })
+
return nil
}
-func (l *fileArgs) Get() interface{} {
- return l
+func (l *listFiles) String() string {
+ return `""`
+}
+
+func (l *listFiles) Set(s string) error {
+ if *relativeRoot == "" {
+ return fmt.Errorf("must pass -C before -f or -l")
+ }
+
+ list, err := ioutil.ReadFile(s)
+ if err != nil {
+ return err
+ }
+
+ fArgs = append(fArgs, fileArg{
+ pathPrefixInZip: filepath.Clean(*rootPrefix),
+ sourcePrefixToStrip: filepath.Clean(*relativeRoot),
+ sourceFiles: strings.Split(string(list), "\n"),
+ })
+
+ return nil
}
var (
@@ -93,16 +136,17 @@ var (
parallelJobs = flag.Int("j", runtime.NumCPU(), "number of parallel threads to use")
compLevel = flag.Int("L", 5, "deflate compression level (0-9)")
- listFiles fileArgs
- files fileArgs
+ fArgs fileArgs
+ nonDeflatedFiles = make(uniqueSet)
cpuProfile = flag.String("cpuprofile", "", "write cpu profile to file")
traceFile = flag.String("trace", "", "write trace to file")
)
func init() {
- flag.Var(&listFiles, "l", "file containing list of .class files")
- flag.Var(&files, "f", "file to include in zip")
+ flag.Var(&listFiles{}, "l", "file containing list of .class files")
+ flag.Var(&file{}, "f", "file to include in zip")
+ flag.Var(&nonDeflatedFiles, "s", "file path to be stored within the zip without compression")
}
func usage() {
@@ -176,30 +220,15 @@ func main() {
pathMappings := []pathMapping{}
set := make(map[string]string)
- // load listFiles, which specify other files to include.
- for _, l := range listFiles {
- list, err := ioutil.ReadFile(l.file)
- if err != nil {
- fmt.Fprintln(os.Stderr, err.Error())
- os.Exit(1)
- }
- srcs := strings.Split(string(list), "\n")
- for _, src := range srcs {
- if err := fillPathPairs(l.rootPrefix, l.relativeRoot, src,
- set, &pathMappings); err != nil {
+ for _, fa := range fArgs {
+ for _, src := range fa.sourceFiles {
+ if err := fillPathPairs(fa.pathPrefixInZip,
+ fa.sourcePrefixToStrip, src, set, &pathMappings); err != nil {
log.Fatal(err)
}
}
}
- // also include the usual files that are to be added directly.
- for _, f := range files {
- if err := fillPathPairs(f.rootPrefix, f.relativeRoot,
- f.file, set, &pathMappings); err != nil {
- log.Fatal(err)
- }
- }
-
err := w.write(*out, pathMappings, *manifest)
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
@@ -227,7 +256,12 @@ func fillPathPairs(prefix, rel, src string, set map[string]string, pathMappings
set[dest] = src
}
- *pathMappings = append(*pathMappings, pathMapping{dest: dest, src: src})
+ zipMethod := zip.Deflate
+ if _, found := nonDeflatedFiles[dest]; found {
+ zipMethod = zip.Store
+ }
+ *pathMappings = append(*pathMappings,
+ pathMapping{dest: dest, src: src, zipMethod: zipMethod})
return nil
}
@@ -269,7 +303,7 @@ func (z *zipWriter) write(out string, pathMappings []pathMapping, manifest strin
defer close(z.writeOps)
for _, ele := range pathMappings {
- err = z.writeFile(ele.dest, ele.src)
+ err = z.writeFile(ele.dest, ele.src, ele.zipMethod)
if err != nil {
z.errors <- err
return
@@ -277,7 +311,7 @@ func (z *zipWriter) write(out string, pathMappings []pathMapping, manifest strin
}
if manifest != "" {
- err = z.writeFile("META-INF/MANIFEST.MF", manifest)
+ err = z.writeFile("META-INF/MANIFEST.MF", manifest, zip.Deflate)
if err != nil {
z.errors <- err
return
@@ -371,7 +405,7 @@ func (z *zipWriter) write(out string, pathMappings []pathMapping, manifest strin
}
}
-func (z *zipWriter) writeFile(dest, src string) error {
+func (z *zipWriter) writeFile(dest, src string, method uint16) error {
var fileSize int64
var executable bool
@@ -407,7 +441,7 @@ func (z *zipWriter) writeFile(dest, src string) error {
ze := &zipEntry{
fh: &zip.FileHeader{
Name: dest,
- Method: zip.Deflate,
+ Method: method,
UncompressedSize64: uint64(fileSize),
},
@@ -424,7 +458,7 @@ func (z *zipWriter) writeFile(dest, src string) error {
exec := z.rateLimit.RequestExecution()
- if fileSize >= minParallelFileSize {
+ if method == zip.Deflate && fileSize >= minParallelFileSize {
wg := new(sync.WaitGroup)
// Allocate enough buffer to hold all readers. We'll limit
@@ -555,33 +589,55 @@ func (z *zipWriter) compressWholeFile(ze *zipEntry, r *os.File, exec Execution,
return
}
- compressed, err := z.compressBlock(r, nil, true)
+ readFile := func(r *os.File) ([]byte, error) {
+ _, err = r.Seek(0, 0)
+ if err != nil {
+ return nil, err
+ }
+
+ buf, err := ioutil.ReadAll(r)
+ if err != nil {
+ return nil, err
+ }
+
+ return buf, nil
+ }
ze.futureReaders = make(chan chan io.Reader, 1)
futureReader := make(chan io.Reader, 1)
ze.futureReaders <- futureReader
close(ze.futureReaders)
- if uint64(compressed.Len()) < ze.fh.UncompressedSize64 {
- futureReader <- compressed
- bufSize = compressed.Len()
- } else {
- _, err = r.Seek(0, 0)
+ if ze.fh.Method == zip.Deflate {
+ compressed, err := z.compressBlock(r, nil, true)
if err != nil {
z.errors <- err
return
}
-
- buf, err := ioutil.ReadAll(r)
+ if uint64(compressed.Len()) < ze.fh.UncompressedSize64 {
+ futureReader <- compressed
+ bufSize = compressed.Len()
+ } else {
+ buf, err := readFile(r)
+ if err != nil {
+ z.errors <- err
+ return
+ }
+ ze.fh.Method = zip.Store
+ futureReader <- bytes.NewReader(buf)
+ bufSize = int(ze.fh.UncompressedSize64)
+ }
+ } else {
+ buf, err := readFile(r)
if err != nil {
z.errors <- err
return
}
-
ze.fh.Method = zip.Store
futureReader <- bytes.NewReader(buf)
bufSize = int(ze.fh.UncompressedSize64)
}
+
exec.Finish(bufSize)
close(futureReader)