Add soong_build primary builder
Initial build logic for building android with soong. It can build
a variety of C and C++ files for arm/arm64 and host.
Change-Id: I10eb37c2c2a50be6af1bb5fd568c0962b9476bf0
diff --git a/glob/glob.go b/glob/glob.go
new file mode 100644
index 0000000..45ba285
--- /dev/null
+++ b/glob/glob.go
@@ -0,0 +1,129 @@
+// 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 glob
+
+import (
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "blueprint/deptools"
+)
+
+func IsGlob(glob string) bool {
+ return strings.IndexAny(glob, "*?[") >= 0
+}
+
+// GlobWithDepFile finds all files that match glob. It compares the list of files
+// against the contents of fileListFile, and rewrites fileListFile if it has changed. It also
+// writes all of the the directories it traversed as a depenencies on fileListFile to depFile.
+//
+// The format of glob is either path/*.ext for a single directory glob, or path/**/*.ext
+// for a recursive glob.
+//
+// Returns a list of file paths, and an error.
+func GlobWithDepFile(glob, fileListFile, depFile string) (files []string, err error) {
+ globPattern := filepath.Base(glob)
+ globDir := filepath.Dir(glob)
+ recursive := false
+
+ if filepath.Base(globDir) == "**" {
+ recursive = true
+ globDir = filepath.Dir(globDir)
+ }
+
+ var dirs []string
+
+ err = filepath.Walk(globDir,
+ func(path string, info os.FileInfo, err error) error {
+ if err != nil {
+ return err
+ }
+
+ if info.Mode().IsDir() {
+ dirs = append(dirs, path)
+ if !recursive && path != globDir {
+ return filepath.SkipDir
+ }
+ } else if info.Mode().IsRegular() {
+ match, err := filepath.Match(globPattern, info.Name())
+ if err != nil {
+ return err
+ }
+ if match {
+ files = append(files, path)
+ }
+ }
+
+ return nil
+ })
+
+ fileList := strings.Join(files, "\n")
+
+ writeFileIfChanged(fileListFile, []byte(fileList), 0666)
+ deptools.WriteDepFile(depFile, fileListFile, dirs)
+
+ return
+}
+
+func writeFileIfChanged(filename string, data []byte, perm os.FileMode) error {
+ var isChanged bool
+
+ dir := filepath.Dir(filename)
+ err := os.MkdirAll(dir, 0777)
+ if err != nil {
+ return err
+ }
+
+ info, err := os.Stat(filename)
+ if err != nil {
+ if os.IsNotExist(err) {
+ // The file does not exist yet.
+ isChanged = true
+ } else {
+ return err
+ }
+ } else {
+ if info.Size() != int64(len(data)) {
+ isChanged = true
+ } else {
+ oldData, err := ioutil.ReadFile(filename)
+ if err != nil {
+ return err
+ }
+
+ if len(oldData) != len(data) {
+ isChanged = true
+ } else {
+ for i := range data {
+ if oldData[i] != data[i] {
+ isChanged = true
+ break
+ }
+ }
+ }
+ }
+ }
+
+ if isChanged {
+ err = ioutil.WriteFile(filename, data, perm)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}