diff options
author | Colin Cross <ccross@android.com> | 2015-03-30 17:20:39 -0700 |
---|---|---|
committer | Colin Cross <ccross@android.com> | 2015-04-03 16:24:44 -0700 |
commit | 2fe6687847a137c6897b19afefa187a38a2a8b6e (patch) | |
tree | d710173c69915e0f8a1d22712b746e9f839a2c6c /cmd | |
parent | 35cec12a11e1b279960f463f53a74b5407de056a (diff) | |
download | build_soong-2fe6687847a137c6897b19afefa187a38a2a8b6e.tar.gz build_soong-2fe6687847a137c6897b19afefa187a38a2a8b6e.tar.bz2 build_soong-2fe6687847a137c6897b19afefa187a38a2a8b6e.zip |
Support java libraries, binaries, and prebuilts
Add support for compiling java libraries (.jar files with
or without .dex), java binaries (.jar files with a wrapper
script to run them), and java prebuilts (for the SDK .jars)
Change-Id: Id624da64c92cf20c6d9577c6bb06e5b212af0d1b
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/soong_build/main.go | 8 | ||||
-rw-r--r-- | cmd/soong_jar/soong_jar.go | 220 |
2 files changed, 228 insertions, 0 deletions
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go index 23bcb561..01740d1c 100644 --- a/cmd/soong_build/main.go +++ b/cmd/soong_build/main.go @@ -28,6 +28,7 @@ import ( "android/soong/common" "android/soong/config" "android/soong/genrule" + "android/soong/java" ) func main() { @@ -61,6 +62,13 @@ func main() { ctx.RegisterModuleType("art_cc_library", art.ArtCCLibraryFactory) ctx.RegisterModuleType("art_cc_binary", art.ArtCCBinaryFactory) + ctx.RegisterModuleType("java_library", java.JavaLibraryFactory) + ctx.RegisterModuleType("java_library_static", java.JavaLibraryFactory) + ctx.RegisterModuleType("java_library_host", java.JavaLibraryHostFactory) + ctx.RegisterModuleType("java_binary", java.JavaBinaryFactory) + ctx.RegisterModuleType("java_binary_host", java.JavaBinaryHostFactory) + ctx.RegisterModuleType("prebuilt_java_library", java.JavaPrebuiltFactory) + // Mutators ctx.RegisterEarlyMutator("arch", common.ArchMutator) ctx.RegisterEarlyMutator("link", cc.LinkageMutator) diff --git a/cmd/soong_jar/soong_jar.go b/cmd/soong_jar/soong_jar.go new file mode 100644 index 00000000..23144969 --- /dev/null +++ b/cmd/soong_jar/soong_jar.go @@ -0,0 +1,220 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "archive/zip" + "flag" + "fmt" + "io" + "io/ioutil" + "os" + "path/filepath" + "strings" + "time" +) + +type fileArg struct { + relativeRoot, file string +} + +type fileArgs []fileArg + +func (l *fileArgs) String() string { + return `""` +} + +func (l *fileArgs) Set(s string) error { + if *relativeRoot == "" { + return fmt.Errorf("must pass -C before -f") + } + + *l = append(*l, fileArg{*relativeRoot, s}) + return nil +} + +func (l *fileArgs) Get() interface{} { + return l +} + +var ( + out = flag.String("o", "", "file to write jar file to") + manifest = flag.String("m", "", "input manifest file name") + directories = flag.Bool("d", false, "include directories in jar") + relativeRoot = flag.String("C", "", "path to use as relative root of files in next -f or -l argument") + listFiles fileArgs + files fileArgs +) + +func init() { + flag.Var(&listFiles, "l", "file containing list of .class files") + flag.Var(&files, "f", "file to include in jar") +} + +func usage() { + fmt.Fprintf(os.Stderr, "usage: soong_jar -o jarfile [-m manifest] -C dir [-f|-l file]...\n") + flag.PrintDefaults() + os.Exit(2) +} + +type zipInfo struct { + time time.Time + createdDirs map[string]bool + directories bool +} + +func main() { + flag.Parse() + + if *out == "" { + fmt.Fprintf(os.Stderr, "error: -o is required\n") + usage() + } + + info := zipInfo{ + time: time.Now(), + createdDirs: make(map[string]bool), + directories: *directories, + } + + // TODO: Go's zip implementation doesn't support increasing the compression level yet + err := writeZipFile(*out, listFiles, *manifest, info) + if err != nil { + fmt.Fprintln(os.Stderr, err.Error()) + os.Exit(1) + } +} + +func writeZipFile(out string, listFiles fileArgs, manifest string, info zipInfo) error { + f, err := os.Create(out) + if err != nil { + return err + } + + defer f.Close() + defer func() { + if err != nil { + os.Remove(out) + } + }() + + zipFile := zip.NewWriter(f) + defer zipFile.Close() + + for _, listFile := range listFiles { + err = writeListFile(zipFile, listFile, info) + if err != nil { + return err + } + } + + for _, file := range files { + err = writeRelFile(zipFile, file.relativeRoot, file.file, info) + if err != nil { + return err + } + } + + if manifest != "" { + err = writeFile(zipFile, "META-INF/MANIFEST.MF", manifest, info) + if err != nil { + return err + } + } + + return nil +} + +func writeListFile(zipFile *zip.Writer, listFile fileArg, info zipInfo) error { + list, err := ioutil.ReadFile(listFile.file) + if err != nil { + return err + } + + files := strings.Split(string(list), "\n") + + for _, file := range files { + file = strings.TrimSpace(file) + if file == "" { + continue + } + err = writeRelFile(zipFile, listFile.relativeRoot, file, info) + if err != nil { + return err + } + } + + return nil +} + +func writeRelFile(zipFile *zip.Writer, root, file string, info zipInfo) error { + rel, err := filepath.Rel(root, file) + if err != nil { + return err + } + + err = writeFile(zipFile, rel, file, info) + if err != nil { + return err + } + + return nil +} + +func writeFile(zipFile *zip.Writer, rel, file string, info zipInfo) error { + if info.directories { + dir, _ := filepath.Split(rel) + for dir != "" && !info.createdDirs[dir] { + info.createdDirs[dir] = true + + dirHeader := &zip.FileHeader{ + Name: dir, + } + dirHeader.SetMode(os.ModeDir) + dirHeader.SetModTime(info.time) + + _, err := zipFile.CreateHeader(dirHeader) + if err != nil { + return err + } + + dir, _ = filepath.Split(dir) + } + } + + fileHeader := &zip.FileHeader{ + Name: rel, + Method: zip.Deflate, + } + fileHeader.SetModTime(info.time) + + out, err := zipFile.CreateHeader(fileHeader) + if err != nil { + return err + } + + in, err := os.Open(file) + if err != nil { + return err + } + defer in.Close() + + _, err = io.Copy(out, in) + if err != nil { + return err + } + + return nil +} |