Merge "[CMakeList generator] Add headers to source files"
diff --git a/android/androidmk.go b/android/androidmk.go
index d55cdca..f606522 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -175,19 +175,21 @@
 
 	if data.Custom != nil {
 		prefix := ""
-		switch amod.Os().Class {
-		case Host:
-			prefix = "HOST_"
-		case HostCross:
-			prefix = "HOST_CROSS_"
-		case Device:
-			prefix = "TARGET_"
+		if amod.ArchSpecific() {
+			switch amod.Os().Class {
+			case Host:
+				prefix = "HOST_"
+			case HostCross:
+				prefix = "HOST_CROSS_"
+			case Device:
+				prefix = "TARGET_"
 
-		}
+			}
 
-		config := ctx.Config().(Config)
-		if amod.Arch().ArchType != config.Targets[amod.Os().Class][0].Arch.ArchType {
-			prefix = "2ND_" + prefix
+			config := ctx.Config().(Config)
+			if amod.Arch().ArchType != config.Targets[amod.Os().Class][0].Arch.ArchType {
+				prefix = "2ND_" + prefix
+			}
 		}
 
 		return data.Custom(w, name, prefix, filepath.Dir(ctx.BlueprintFile(mod)))
diff --git a/android/config.go b/android/config.go
index 2361920..686eeb8 100644
--- a/android/config.go
+++ b/android/config.go
@@ -462,11 +462,11 @@
 	return "vendor"
 }
 
-func (c *deviceConfig) VndkVersion() string {
+func (c *deviceConfig) CompileVndk() bool {
 	if c.config.ProductVariables.DeviceVndkVersion == nil {
-		return ""
+		return false
 	}
-	return *c.config.ProductVariables.DeviceVndkVersion
+	return *c.config.ProductVariables.DeviceVndkVersion == "current"
 }
 
 func (c *deviceConfig) BtConfigIncludeDir() string {
diff --git a/android/module.go b/android/module.go
index cc420fb..8228a9c 100644
--- a/android/module.go
+++ b/android/module.go
@@ -59,6 +59,7 @@
 	Darwin() bool
 	Debug() bool
 	PrimaryArch() bool
+	Proprietary() bool
 	AConfig() Config
 	DeviceConfig() DeviceConfig
 }
@@ -87,7 +88,6 @@
 
 	AddMissingDependencies(deps []string)
 
-	Proprietary() bool
 	InstallInData() bool
 
 	RequiredModuleNames() []string
@@ -455,6 +455,7 @@
 	return androidBaseContextImpl{
 		target:        a.commonProperties.CompileTarget,
 		targetPrimary: a.commonProperties.CompilePrimary,
+		proprietary:   a.commonProperties.Proprietary,
 		config:        ctx.Config().(Config),
 	}
 }
@@ -491,6 +492,7 @@
 	target        Target
 	targetPrimary bool
 	debug         bool
+	proprietary   bool
 	config        Config
 }
 
@@ -619,8 +621,8 @@
 	return DeviceConfig{a.config.deviceConfig}
 }
 
-func (a *androidModuleContext) Proprietary() bool {
-	return a.module.base().commonProperties.Proprietary
+func (a *androidBaseContextImpl) Proprietary() bool {
+	return a.proprietary
 }
 
 func (a *androidModuleContext) InstallInData() bool {
diff --git a/androidmk/cmd/androidmk/android.go b/androidmk/cmd/androidmk/android.go
index 75c3eec..6d08ca8 100644
--- a/androidmk/cmd/androidmk/android.go
+++ b/androidmk/cmd/androidmk/android.go
@@ -103,6 +103,7 @@
 			"LOCAL_AIDL_INCLUDES":         "aidl_includes",
 			"LOCAL_AAPT_FLAGS":            "aaptflags",
 			"LOCAL_PACKAGE_SPLITS":        "package_splits",
+			"LOCAL_COMPATIBILITY_SUITE":   "test_suites",
 		})
 	addStandardProperties(bpparser.BoolType,
 		map[string]string{
@@ -117,7 +118,6 @@
 			"LOCAL_NO_STANDARD_LIBRARIES":   "no_standard_libraries",
 			"LOCAL_PACK_MODULE_RELOCATIONS": "pack_relocations",
 			"LOCAL_TIDY":                    "tidy",
-			"LOCAL_USE_VNDK":                "use_vndk",
 			"LOCAL_PROPRIETARY_MODULE":      "proprietary",
 
 			"LOCAL_EXPORT_PACKAGE_RESOURCES": "export_package_resources",
diff --git a/cc/androidmk.go b/cc/androidmk.go
index f45fbbe..bf0ca6f 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -59,9 +59,6 @@
 		if c.Target().Os == android.Android && c.Properties.Sdk_version != "" {
 			fmt.Fprintln(w, "LOCAL_SDK_VERSION := "+c.Properties.Sdk_version)
 			fmt.Fprintln(w, "LOCAL_NDK_STL_VARIANT := none")
-		} else if c.Target().Os == android.Android && c.Properties.Use_vndk {
-			fmt.Fprintln(w, "LOCAL_USE_VNDK := true")
-			fmt.Fprintln(w, "LOCAL_NDK_STL_VARIANT := none")
 		} else {
 			// These are already included in LOCAL_SHARED_LIBRARIES
 			fmt.Fprintln(w, "LOCAL_CXX_STL := none")
@@ -200,6 +197,14 @@
 		ret.SubName = "_" + test.binaryDecorator.Properties.Stem
 	}
 
+	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error {
+		if len(test.Properties.Test_suites) > 0 {
+			fmt.Fprintln(w, "LOCAL_COMPATIBILITY_SUITES :=",
+				strings.Join(test.Properties.Test_suites, " "))
+		}
+		return nil
+	})
+
 	var testFiles []string
 	for _, d := range test.data {
 		rel := d.Rel()
diff --git a/cc/cc.go b/cc/cc.go
index 4c69723..84afa73 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -135,9 +135,6 @@
 	// Minimum sdk version supported when compiling against the ndk
 	Sdk_version string
 
-	// Whether to compile against the VNDK
-	Use_vndk bool
-
 	// don't insert default compiler flags into asflags, cflags,
 	// cppflags, conlyflags, ldflags, or include_dirs
 	No_default_compiler_flags *bool
@@ -145,7 +142,6 @@
 	AndroidMkSharedLibs []string `blueprint:"mutated"`
 	HideFromMake        bool     `blueprint:"mutated"`
 	PreventInstall      bool     `blueprint:"mutated"`
-	Vndk_version        string   `blueprint:"mutated"`
 }
 
 type UnusedProperties struct {
@@ -378,8 +374,8 @@
 
 func (ctx *moduleContextImpl) sdkVersion() string {
 	if ctx.ctx.Device() {
-		if ctx.mod.Properties.Use_vndk {
-			return ctx.mod.Properties.Vndk_version
+		if ctx.vndk() {
+			return "current"
 		} else {
 			return ctx.mod.Properties.Sdk_version
 		}
@@ -388,10 +384,7 @@
 }
 
 func (ctx *moduleContextImpl) vndk() bool {
-	if ctx.ctx.Device() {
-		return ctx.mod.Properties.Use_vndk
-	}
-	return false
+	return ctx.ctx.Os() == android.Android && ctx.ctx.Proprietary() && ctx.ctx.DeviceConfig().CompileVndk()
 }
 
 func (ctx *moduleContextImpl) selectedStl() string {
@@ -544,22 +537,11 @@
 		feature.begin(ctx)
 	}
 	if ctx.sdk() {
-		if ctx.vndk() {
-			ctx.PropertyErrorf("use_vndk",
-				"sdk_version and use_vndk cannot be used at the same time")
-		}
-
 		version, err := normalizeNdkApiLevel(ctx.sdkVersion(), ctx.Arch())
 		if err != nil {
 			ctx.PropertyErrorf("sdk_version", err.Error())
 		}
 		c.Properties.Sdk_version = version
-	} else if ctx.vndk() {
-		version, err := normalizeNdkApiLevel(ctx.DeviceConfig().VndkVersion(), ctx.Arch())
-		if err != nil {
-			ctx.ModuleErrorf("Bad BOARD_VNDK_VERSION: %s", err.Error())
-		}
-		c.Properties.Vndk_version = version
 	}
 }
 
@@ -675,7 +657,7 @@
 						variantLibs = append(variantLibs, entry+ndkLibrarySuffix)
 					}
 				} else {
-					nonvariantLibs = append(variantLibs, entry)
+					nonvariantLibs = append(nonvariantLibs, entry)
 				}
 			}
 			return nonvariantLibs, variantLibs
diff --git a/cc/config/arm64_device.go b/cc/config/arm64_device.go
index fe47ddf..23186e7 100644
--- a/cc/config/arm64_device.go
+++ b/cc/config/arm64_device.go
@@ -66,9 +66,6 @@
 		"-fuse-ld=gold",
 		"-Wl,--icf=safe",
 		"-Wl,--no-undefined-version",
-
-		// Disable transitive dependency library symbol resolving.
-		"-Wl,--allow-shlib-undefined",
 	}
 
 	arm64Cppflags = []string{
diff --git a/cc/config/clang.go b/cc/config/clang.go
index 10f4cea..30ab1c6 100644
--- a/cc/config/clang.go
+++ b/cc/config/clang.go
@@ -91,6 +91,10 @@
 
 		// http://b/29823425 Disable -Wexpansion-to-defined for Clang update to r271374
 		"-Wno-expansion-to-defined",
+
+		// http://b/36463318 Clang executes with an absolute path, so clang-provided
+		// headers are now absolute.
+		"-fdebug-prefix-map=$$PWD/=",
 	}, " "))
 
 	pctx.StaticVariable("ClangExtraCppflags", strings.Join([]string{
diff --git a/cc/config/toolchain.go b/cc/config/toolchain.go
index 8fc4a21..5270437 100644
--- a/cc/config/toolchain.go
+++ b/cc/config/toolchain.go
@@ -207,20 +207,24 @@
 	return indexList(s, list) != -1
 }
 
-func AddressSanitizerRuntimeLibrary(t Toolchain) string {
+func SanitizerRuntimeLibrary(t Toolchain, sanitizer string) string {
 	arch := t.SanitizerRuntimeLibraryArch()
 	if arch == "" {
 		return ""
 	}
-	return "libclang_rt.asan-" + arch + "-android.so"
+	return "libclang_rt." + sanitizer + "-" + arch + "-android.so"
+}
+
+func AddressSanitizerRuntimeLibrary(t Toolchain) string {
+	return SanitizerRuntimeLibrary(t, "asan")
 }
 
 func UndefinedBehaviorSanitizerRuntimeLibrary(t Toolchain) string {
-	arch := t.SanitizerRuntimeLibraryArch()
-	if arch == "" {
-		return ""
-	}
-	return "libclang_rt.ubsan_standalone-" + arch + "-android.so"
+	return SanitizerRuntimeLibrary(t, "ubsan_standalone")
+}
+
+func ThreadSanitizerRuntimeLibrary(t Toolchain) string {
+	return SanitizerRuntimeLibrary(t, "tsan")
 }
 
 func ToolPath(t Toolchain) string {
diff --git a/cc/makevars.go b/cc/makevars.go
index 200faff..dcde828 100644
--- a/cc/makevars.go
+++ b/cc/makevars.go
@@ -209,6 +209,7 @@
 		if target.Os.Class == android.Device {
 			ctx.Strict(secondPrefix+"ADDRESS_SANITIZER_RUNTIME_LIBRARY", strings.TrimSuffix(config.AddressSanitizerRuntimeLibrary(toolchain), ".so"))
 			ctx.Strict(secondPrefix+"UBSAN_RUNTIME_LIBRARY", strings.TrimSuffix(config.UndefinedBehaviorSanitizerRuntimeLibrary(toolchain), ".so"))
+			ctx.Strict(secondPrefix+"TSAN_RUNTIME_LIBRARY", strings.TrimSuffix(config.ThreadSanitizerRuntimeLibrary(toolchain), ".so"))
 		}
 
 		// This is used by external/gentoo/...
diff --git a/cc/ndk_headers.go b/cc/ndk_headers.go
index e4a790f..6a083ae 100644
--- a/cc/ndk_headers.go
+++ b/cc/ndk_headers.go
@@ -27,11 +27,13 @@
 var (
 	preprocessBionicHeaders = pctx.AndroidStaticRule("preprocessBionicHeaders",
 		blueprint.RuleParams{
-			Command:     "$versionerCmd $srcDir $depsPath -o $out",
+			// The `&& touch $out` isn't really necessary, but Blueprint won't
+			// let us have only implicit outputs.
+			Command:     "$versionerCmd -o $outDir $srcDir $depsPath && touch $out",
 			CommandDeps: []string{"$versionerCmd"},
 			Description: "versioner preprocess $in",
 		},
-		"depsPath", "srcDir")
+		"depsPath", "srcDir", "outDir")
 )
 
 func init() {
@@ -229,14 +231,16 @@
 		}
 	}
 
+	timestampFile := android.PathForModuleOut(ctx, "versioner.timestamp")
 	ctx.ModuleBuild(pctx, android.ModuleBuildParams{
 		Rule:            preprocessBionicHeaders,
-		Output:          toOutputPath,
+		Output:          timestampFile,
 		Implicits:       append(srcFiles, depsGlob...),
 		ImplicitOutputs: installPaths,
 		Args: map[string]string{
 			"depsPath": depsPath.String(),
 			"srcDir":   fromSrcPath.String(),
+			"outDir":   toOutputPath.String(),
 		},
 	})
 }
diff --git a/cc/test.go b/cc/test.go
index d3556bf..145b5b0 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -20,6 +20,7 @@
 	"strings"
 
 	"android/soong/android"
+
 	"github.com/google/blueprint"
 )
 
@@ -41,6 +42,10 @@
 	// list of files or filegroup modules that provide data that should be installed alongside
 	// the test
 	Data []string
+
+	// list of compatibility suites (for example "cts", "vts") that the module should be
+	// installed into.
+	Test_suites []string
 }
 
 func init() {
diff --git a/cmd/fileslist/Android.bp b/cmd/fileslist/Android.bp
new file mode 100644
index 0000000..cbf939a
--- /dev/null
+++ b/cmd/fileslist/Android.bp
@@ -0,0 +1,20 @@
+// Copyright 2017 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.
+
+blueprint_go_binary {
+    name: "fileslist",
+    srcs: [
+        "fileslist.go",
+    ],
+}
diff --git a/cmd/fileslist/fileslist.go b/cmd/fileslist/fileslist.go
new file mode 100755
index 0000000..56ea66d
--- /dev/null
+++ b/cmd/fileslist/fileslist.go
@@ -0,0 +1,173 @@
+// Copyright 2017 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.
+
+// fileslist.py replacement written in GO, which utilizes multi-cores.
+
+package main
+
+import (
+	"crypto/sha256"
+	"encoding/json"
+	"flag"
+	"fmt"
+	"io"
+	"os"
+	"path/filepath"
+	"runtime"
+	"sort"
+	"strings"
+	"sync"
+)
+
+const (
+	MAX_DEFAULT_PARA = 24
+)
+
+func defaultPara() int {
+	ret := runtime.NumCPU()
+	if ret > MAX_DEFAULT_PARA {
+		return MAX_DEFAULT_PARA
+	}
+	return ret
+}
+
+var (
+	para = flag.Int("para", defaultPara(), "Number of goroutines")
+)
+
+// Represents each file.
+type Node struct {
+	SHA256 string
+	Name   string // device side path.
+	Size   int64
+	path   string // host side path.
+	stat   os.FileInfo
+}
+
+func newNode(hostPath string, devicePath string, stat os.FileInfo) Node {
+	return Node{Name: devicePath, path: hostPath, stat: stat}
+}
+
+// Scan a Node and returns true if it should be added to the result.
+func (n *Node) scan() bool {
+	n.Size = n.stat.Size()
+
+	// Calculate SHA256.
+	h := sha256.New()
+	if n.stat.Mode()&os.ModeSymlink == 0 {
+		f, err := os.Open(n.path)
+		if err != nil {
+			panic(err)
+		}
+		defer f.Close()
+
+		if _, err := io.Copy(h, f); err != nil {
+			panic(err)
+		}
+	} else {
+		// Hash the content of symlink, not the file it points to.
+		s, err := os.Readlink(n.path)
+		if err != nil {
+			panic(err)
+		}
+		if _, err := io.WriteString(h, s); err != nil {
+			panic(err)
+		}
+	}
+	n.SHA256 = fmt.Sprintf("%x", h.Sum(nil))
+	return true
+}
+
+func main() {
+	flag.Parse()
+
+	allOutput := make([]Node, 0, 1024) // Store all outputs.
+	mutex := &sync.Mutex{}             // Guard allOutput
+
+	ch := make(chan Node) // Pass nodes to goroutines.
+
+	var wg sync.WaitGroup // To wait for all goroutines.
+	wg.Add(*para)
+
+	// Scan files in multiple goroutines.
+	for i := 0; i < *para; i++ {
+		go func() {
+			defer wg.Done()
+
+			output := make([]Node, 0, 1024) // Local output list.
+			for node := range ch {
+				if node.scan() {
+					output = append(output, node)
+				}
+			}
+			// Add to the global output list.
+			mutex.Lock()
+			allOutput = append(allOutput, output...)
+			mutex.Unlock()
+		}()
+	}
+
+	// Walk the directories and find files to scan.
+	for _, dir := range flag.Args() {
+		absDir, err := filepath.Abs(dir)
+		if err != nil {
+			panic(err)
+		}
+		deviceRoot := filepath.Clean(absDir + "/..")
+		err = filepath.Walk(dir, func(path string, stat os.FileInfo, err error) error {
+			if err != nil {
+				panic(err)
+			}
+			if stat.IsDir() {
+				return nil
+			}
+			absPath, err := filepath.Abs(path)
+			if err != nil {
+				panic(err)
+			}
+			devicePath, err := filepath.Rel(deviceRoot, absPath)
+			if err != nil {
+				panic(err)
+			}
+			devicePath = "/" + devicePath
+			ch <- newNode(absPath, devicePath, stat)
+			return nil
+		})
+		if err != nil {
+			panic(err)
+		}
+	}
+
+	// Wait until all the goroutines finish.
+	close(ch)
+	wg.Wait()
+
+	// Sort the entries and dump as json.
+	sort.Slice(allOutput, func(i, j int) bool {
+		if allOutput[i].Size > allOutput[j].Size {
+			return true
+		}
+		if allOutput[i].Size == allOutput[j].Size && strings.Compare(allOutput[i].Name, allOutput[j].Name) > 0 {
+			return true
+		}
+		return false
+	})
+
+	j, err := json.MarshalIndent(allOutput, "", "  ")
+	if err != nil {
+		panic(nil)
+	}
+
+	fmt.Printf("%s\n", j)
+}