| // Copyright 2018 The Bazel Authors. 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 link is a thin wrapper around aapt2 to link android resources. |
| package link |
| |
| import ( |
| "flag" |
| "io/ioutil" |
| "log" |
| "os/exec" |
| "sync" |
| |
| "src/common/golang/flags" |
| "src/common/golang/walk" |
| "src/common/golang/ziputils" |
| "src/tools/ak/types" |
| ) |
| |
| var ( |
| // Cmd defines the command to run link. |
| Cmd = types.Command{ |
| Init: Init, |
| Run: Run, |
| Desc: desc, |
| Flags: []string{ |
| "aapt2", |
| "sdk_jar", |
| "manifest", |
| "res_dirs", |
| "asset_dirs", |
| "pkg", |
| "src_jar", |
| "out", |
| }, |
| } |
| |
| aapt2 string |
| sdkJar string |
| manifest string |
| resDirs flags.StringList |
| assetDirs flags.StringList |
| pkg string |
| srcJar string |
| out string |
| |
| initOnce sync.Once |
| ) |
| |
| // Init initializes link. |
| func Init() { |
| initOnce.Do(func() { |
| flag.StringVar(&aapt2, "aapt2", "", "Path to the aapt2 binary.") |
| flag.StringVar(&sdkJar, "sdk_jar", "", "Path to the android jar.") |
| flag.StringVar(&manifest, "manifest", "", "Path to the application AndroidManifest.xml.") |
| flag.Var(&resDirs, "res_dirs", "List of resource archives to link.") |
| flag.Var(&assetDirs, "asset_dirs", "Paths to asset directories..") |
| flag.StringVar(&pkg, "pkg", "", "Package for R.java.") |
| flag.StringVar(&srcJar, "src_jar", "", "R java source jar path.") |
| flag.StringVar(&out, "out", "", "Output path for linked archive.") |
| }) |
| } |
| |
| func desc() string { |
| return "Link compiled Android resources." |
| } |
| |
| // Run is the entry point for link. |
| func Run() { |
| if aapt2 == "" || |
| sdkJar == "" || |
| manifest == "" || |
| resDirs == nil || |
| pkg == "" || |
| srcJar == "" || |
| out == "" { |
| log.Fatal("Flags -aapt2 -sdk_jar -manifest -res_dirs -pkg -src_jar and -out must be specified.") |
| } |
| |
| // Note that relative order between directories needs to be respected by traversal function. |
| // I.e. all files in dir n most come before all files in directory n+1. |
| resArchives, err := walk.Files(resDirs) |
| if err != nil { |
| log.Fatalf("error getting resource archives: %v", err) |
| } |
| |
| rjavaDir, err := ioutil.TempDir("", "rjava") |
| if err != nil { |
| log.Fatalf("error creating temp dir: %v", err) |
| } |
| |
| args := []string{ |
| "link", "--manifest", manifest, "--auto-add-overlay", "--no-static-lib-packages", |
| "--java", rjavaDir, "--custom-package", pkg, "-I", sdkJar} |
| |
| for _, r := range resArchives { |
| args = append(args, "-R", r) |
| } |
| |
| for _, a := range assetDirs { |
| args = append(args, "-A", a) |
| } |
| |
| args = append(args, "-o", out) |
| |
| if out, err := exec.Command(aapt2, args...).CombinedOutput(); err != nil { |
| log.Fatalf("error linking Android resources: %v\n %s", err, string(out)) |
| } |
| if err := ziputils.Zip(rjavaDir, srcJar); err != nil { |
| log.Fatalf("error unable to create resources src jar: %v", err) |
| } |
| } |