Merge "Add pom2bp"
diff --git a/Android.bp b/Android.bp
index 5396664..aa65209 100644
--- a/Android.bp
+++ b/Android.bp
@@ -145,6 +145,7 @@
         "cc/vndk_prebuilt.go",
 
         "cc/cmakelists.go",
+        "cc/compdb.go",
         "cc/compiler.go",
         "cc/installer.go",
         "cc/linker.go",
diff --git a/README.md b/README.md
index b234c71..b3239e9 100644
--- a/README.md
+++ b/README.md
@@ -175,6 +175,7 @@
 * [Best Practices](docs/best_practices.md)
 * [Build Performance](docs/perf.md)
 * [Generating CLion Projects](docs/clion.md)
+* [Generating YouCompleteMe/VSCode compile\_commands.json file](docs/compdb.md)
 * Make-specific documentation: [build/make/README.md](https://android.googlesource.com/platform/build/+/master/README.md)
 
 ## FAQ
diff --git a/cc/cc.go b/cc/cc.go
index 1e313c0..9722cf0 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -40,7 +40,6 @@
 		ctx.BottomUp("ndk_api", ndkApiMutator).Parallel()
 		ctx.BottomUp("test_per_src", testPerSrcMutator).Parallel()
 		ctx.BottomUp("begin", beginMutator).Parallel()
-		ctx.BottomUp("coverage", coverageLinkingMutator).Parallel()
 	})
 
 	android.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
@@ -55,6 +54,7 @@
 
 		ctx.TopDown("sanitize_runtime_deps", sanitizerRuntimeDepsMutator())
 
+		ctx.BottomUp("coverage", coverageLinkingMutator).Parallel()
 		ctx.TopDown("vndk_deps", sabiDepsMutator)
 
 		ctx.TopDown("lto_deps", ltoDepsMutator)
@@ -809,15 +809,12 @@
 	if c.compiler != nil {
 		deps = c.compiler.compilerDeps(ctx, deps)
 	}
-	// clang_rt.profile runtime libraries necessary for PGO and coverage
-	// depend on symbols from libgcc.  Add the runtime library dependency
-	// before libgcc gets added in linkerDeps().
+	// Add the PGO dependency (the clang_rt.profile runtime library), which
+	// sometimes depends on symbols from libgcc, before libgcc gets added
+	// in linkerDeps().
 	if c.pgo != nil {
 		deps = c.pgo.deps(ctx, deps)
 	}
-	if c.coverage != nil {
-		deps = c.coverage.deps(ctx, deps)
-	}
 	if c.linker != nil {
 		deps = c.linker.linkerDeps(ctx, deps)
 	}
@@ -827,6 +824,9 @@
 	if c.sanitize != nil {
 		deps = c.sanitize.deps(ctx, deps)
 	}
+	if c.coverage != nil {
+		deps = c.coverage.deps(ctx, deps)
+	}
 	if c.sabi != nil {
 		deps = c.sabi.deps(ctx, deps)
 	}
diff --git a/cc/compdb.go b/cc/compdb.go
new file mode 100644
index 0000000..a9c5b5e
--- /dev/null
+++ b/cc/compdb.go
@@ -0,0 +1,192 @@
+// Copyright 2018 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 cc
+
+import (
+	"encoding/json"
+	"log"
+	"os"
+	"path/filepath"
+	"strings"
+
+	"android/soong/android"
+)
+
+// This singleton generates a compile_commands.json file. It does so for each
+// blueprint Android.bp resulting in a cc.Module when either make, mm, mma, mmm
+// or mmma is called. It will only create a single compile_commands.json file
+// at out/development/ide/compdb/compile_commands.json. It will also symlink it
+// to ${SOONG_LINK_COMPDB_TO} if set. In general this should be created by running
+// make SOONG_GEN_COMPDB=1 nothing to get all targets.
+
+func init() {
+	android.RegisterSingletonType("compdb_generator", compDBGeneratorSingleton)
+}
+
+func compDBGeneratorSingleton() android.Singleton {
+	return &compdbGeneratorSingleton{}
+}
+
+type compdbGeneratorSingleton struct{}
+
+const (
+	compdbFilename                = "compile_commands.json"
+	compdbOutputProjectsDirectory = "out/development/ide/compdb"
+
+	// Environment variables used to modify behavior of this singleton.
+	envVariableGenerateCompdb          = "SOONG_GEN_COMPDB"
+	envVariableGenerateCompdbDebugInfo = "SOONG_GEN_COMPDB_DEBUG"
+	envVariableCompdbLink              = "SOONG_LINK_COMPDB_TO"
+)
+
+// A compdb entry. The compile_commands.json file is a list of these.
+type compDbEntry struct {
+	Directory string   `json:"directory"`
+	Arguments []string `json:"arguments"`
+	File      string   `json:"file"`
+	Output    string   `json:"output,omitempty"`
+}
+
+func (c *compdbGeneratorSingleton) GenerateBuildActions(ctx android.SingletonContext) {
+	if !ctx.Config().IsEnvTrue(envVariableGenerateCompdb) {
+		return
+	}
+
+	// Instruct the generator to indent the json file for easier debugging.
+	outputCompdbDebugInfo := ctx.Config().IsEnvTrue(envVariableGenerateCompdbDebugInfo)
+
+	// We only want one entry per file. We don't care what module/isa it's from
+	m := make(map[string]compDbEntry)
+	ctx.VisitAllModules(func(module android.Module) {
+		if ccModule, ok := module.(*Module); ok {
+			if compiledModule, ok := ccModule.compiler.(CompiledInterface); ok {
+				generateCompdbProject(compiledModule, ctx, ccModule, m)
+			}
+		}
+	})
+
+	// Create the output file.
+	dir := filepath.Join(getCompdbAndroidSrcRootDirectory(ctx), compdbOutputProjectsDirectory)
+	os.MkdirAll(dir, 0777)
+	compDBFile := filepath.Join(dir, compdbFilename)
+	f, err := os.Create(compdbFilename)
+	if err != nil {
+		log.Fatalf("Could not create file %s: %s", filepath.Join(dir, compdbFilename), err)
+	}
+	defer f.Close()
+
+	v := make([]compDbEntry, 0, len(m))
+
+	for _, value := range m {
+		v = append(v, value)
+	}
+	var dat []byte
+	if outputCompdbDebugInfo {
+		dat, err = json.MarshalIndent(v, "", " ")
+	} else {
+		dat, err = json.Marshal(v)
+	}
+	if err != nil {
+		log.Fatalf("Failed to marshal: %s", err)
+	}
+	f.Write(dat)
+
+	finalLinkPath := filepath.Join(ctx.Config().Getenv(envVariableCompdbLink), compdbFilename)
+	if finalLinkPath != "" {
+		os.Remove(finalLinkPath)
+		if err := os.Symlink(compDBFile, finalLinkPath); err != nil {
+			log.Fatalf("Unable to symlink %s to %s: %s", compDBFile, finalLinkPath, err)
+		}
+	}
+}
+
+func expandAllVars(ctx android.SingletonContext, args []string) []string {
+	var out []string
+	for _, arg := range args {
+		if arg != "" {
+			if val, err := evalAndSplitVariable(ctx, arg); err == nil {
+				out = append(out, val...)
+			} else {
+				out = append(out, arg)
+			}
+		}
+	}
+	return out
+}
+
+func getArguments(src android.Path, ctx android.SingletonContext, ccModule *Module) []string {
+	var args []string
+	isCpp := false
+	isAsm := false
+	// TODO It would be better to ask soong for the types here.
+	switch src.Ext() {
+	case ".S", ".s", ".asm":
+		isAsm = true
+		isCpp = false
+	case ".c":
+		isAsm = false
+		isCpp = false
+	case ".cpp", ".cc", ".mm":
+		isAsm = false
+		isCpp = true
+	default:
+		log.Print("Unknown file extension " + src.Ext() + " on file " + src.String())
+		isAsm = true
+		isCpp = false
+	}
+	// The executable for the compilation doesn't matter but we need something there.
+	args = append(args, "/bin/false")
+	args = append(args, expandAllVars(ctx, ccModule.flags.GlobalFlags)...)
+	args = append(args, expandAllVars(ctx, ccModule.flags.CFlags)...)
+	if isCpp {
+		args = append(args, expandAllVars(ctx, ccModule.flags.CppFlags)...)
+	} else if !isAsm {
+		args = append(args, expandAllVars(ctx, ccModule.flags.ConlyFlags)...)
+	}
+	args = append(args, expandAllVars(ctx, ccModule.flags.SystemIncludeFlags)...)
+	args = append(args, src.String())
+	return args
+}
+
+func generateCompdbProject(compiledModule CompiledInterface, ctx android.SingletonContext, ccModule *Module, builds map[string]compDbEntry) {
+	srcs := compiledModule.Srcs()
+	if len(srcs) == 0 {
+		return
+	}
+
+	rootDir := getCompdbAndroidSrcRootDirectory(ctx)
+	for _, src := range srcs {
+		if _, ok := builds[src.String()]; !ok {
+			builds[src.String()] = compDbEntry{
+				Directory: rootDir,
+				Arguments: getArguments(src, ctx, ccModule),
+				File:      src.String(),
+			}
+		}
+	}
+}
+
+func evalAndSplitVariable(ctx android.SingletonContext, str string) ([]string, error) {
+	evaluated, err := ctx.Eval(pctx, str)
+	if err == nil {
+		return strings.Split(evaluated, " "), nil
+	}
+	return []string{""}, err
+}
+
+func getCompdbAndroidSrcRootDirectory(ctx android.SingletonContext) string {
+	srcPath, _ := filepath.Abs(android.PathForSource(ctx).String())
+	return srcPath
+}
diff --git a/cc/config/toolchain.go b/cc/config/toolchain.go
index 19d2828..ca863a7 100644
--- a/cc/config/toolchain.go
+++ b/cc/config/toolchain.go
@@ -85,8 +85,6 @@
 	AvailableLibraries() []string
 
 	Bionic() bool
-
-	profileRuntimeLibrary() string
 }
 
 type toolchainBase struct {
@@ -171,10 +169,6 @@
 	return true
 }
 
-func (t toolchainBase) profileRuntimeLibrary() string {
-	return ""
-}
-
 func (t toolchainBase) ToolPath() string {
 	return ""
 }
@@ -246,12 +240,6 @@
 }
 
 func ProfileRuntimeLibrary(t Toolchain) string {
-	lib := t.profileRuntimeLibrary()
-	if lib != "" {
-		// Return the directly exported profile library
-		return lib
-	}
-	// Return the Android-specific library
 	return SanitizerRuntimeLibrary(t, "profile")
 }
 
diff --git a/cc/config/x86_linux_bionic_host.go b/cc/config/x86_linux_bionic_host.go
index 290793e..a9fb1f6 100644
--- a/cc/config/x86_linux_bionic_host.go
+++ b/cc/config/x86_linux_bionic_host.go
@@ -151,10 +151,6 @@
 	return true
 }
 
-func (t *toolchainLinuxBionic) profileRuntimeLibrary() string {
-	return "libclang_rt.profile-x86_64"
-}
-
 var toolchainLinuxBionicSingleton Toolchain = &toolchainLinuxBionic{}
 
 func linuxBionicToolchainFactory(arch android.Arch) Toolchain {
diff --git a/cc/config/x86_linux_host.go b/cc/config/x86_linux_host.go
index 653f819..354500e 100644
--- a/cc/config/x86_linux_host.go
+++ b/cc/config/x86_linux_host.go
@@ -270,14 +270,6 @@
 	return "${config.LinuxX8664YasmFlags}"
 }
 
-func (t *toolchainLinuxX86) profileRuntimeLibrary() string {
-	return "libclang_rt.profile-i386"
-}
-
-func (t *toolchainLinuxX8664) profileRuntimeLibrary() string {
-	return "libclang_rt.profile-x86_64"
-}
-
 func (t *toolchainLinux) AvailableLibraries() []string {
 	return linuxAvailableLibraries
 }
diff --git a/cc/coverage.go b/cc/coverage.go
index 671353c..391b118 100644
--- a/cc/coverage.go
+++ b/cc/coverage.go
@@ -16,7 +16,6 @@
 
 import (
 	"android/soong/android"
-	"android/soong/cc/config"
 )
 
 type CoverageProperties struct {
@@ -39,10 +38,6 @@
 func (cov *coverage) begin(ctx BaseModuleContext) {}
 
 func (cov *coverage) deps(ctx BaseModuleContext, deps Deps) Deps {
-	if cov.Properties.CoverageEnabled {
-		runtimeLibrary := config.ProfileRuntimeLibrary(ctx.toolchain())
-		deps.LateStaticLibs = append(deps.LateStaticLibs, runtimeLibrary)
-	}
 	return deps
 }
 
@@ -104,8 +99,9 @@
 
 		if !mctx.DeviceConfig().NativeCoverageEnabled() {
 			// Coverage is disabled globally
-		} else if mctx.Darwin() || mctx.Windows() {
-			// Coverage not supported for Darwin and Windows
+		} else if mctx.Host() {
+			// TODO(dwillemsen): because of -nodefaultlibs, we must depend on libclang_rt.profile-*.a
+			// Just turn off for now.
 		} else if c.coverage.Properties.Native_coverage != nil {
 			enabled = *c.coverage.Properties.Native_coverage
 		} else {
diff --git a/docs/compdb.md b/docs/compdb.md
new file mode 100644
index 0000000..68927ca
--- /dev/null
+++ b/docs/compdb.md
@@ -0,0 +1,27 @@
+# Compdb (compile\_commands.json) Generator
+
+Soong can generate compdb files. This is intended for use with editing tools
+such as YouCompleteMe and other libclang based completers.
+
+compdb file generation is enabled via environment variable:
+
+```bash
+$ export SOONG_GEN_COMPDB=1
+$ export SOONG_GEN_COMPDB_DEBUG=1
+```
+
+One can make soong generate a symlink to the compdb file using an environment
+variable:
+
+```bash
+$ export SOONG_LINK_COMPDB_TO=$ANDROID_HOST_OUT
+```
+
+You can then trigger an empty build:
+
+```bash
+$ make nothing
+```
+
+Note that if you build using mm or other limited makes with these environment
+variables set the compdb will only include files in included modules.
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 0700487..a29f0ba 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -256,7 +256,9 @@
 func (j *Javadoc) genWhitelistPathPrefixes(whitelistPathPrefixes map[string]bool) {
 	for _, dir := range j.properties.Srcs_lib_whitelist_dirs {
 		for _, pkg := range j.properties.Srcs_lib_whitelist_pkgs {
-			prefix := filepath.Join(dir, pkg)
+			// convert foo.bar.baz to foo/bar/baz
+			pkgAsPath := filepath.Join(strings.Split(pkg, ".")...)
+			prefix := filepath.Join(dir, pkgAsPath)
 			if _, found := whitelistPathPrefixes[prefix]; !found {
 				whitelistPathPrefixes[prefix] = true
 			}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 301ec61..13a9275 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -18,8 +18,11 @@
 	"android/soong/android"
 	"android/soong/genrule"
 	"fmt"
+	"io"
 	"path"
+	"sort"
 	"strings"
+	"sync"
 
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
@@ -43,6 +46,10 @@
 	systemApiStubsTag = dependencyTag{name: "system"}
 )
 
+var (
+	javaSdkLibrariesLock sync.Mutex
+)
+
 // java_sdk_library is to make a Java library that implements optional platform APIs to apps.
 // It is actually a wrapper of several modules: 1) stubs library that clients are linked against
 // to, 2) droiddoc module that internally generates API stubs source files, 3) the real runtime
@@ -62,6 +69,12 @@
 	android.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
 		ctx.TopDown("java_sdk_library", sdkLibraryMutator).Parallel()
 	})
+
+	android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) {
+		javaSdkLibraries := javaSdkLibraries(ctx.Config())
+		sort.Strings(*javaSdkLibraries)
+		ctx.Strict("JAVA_SDK_LIBRARIES", strings.Join(*javaSdkLibraries, " "))
+	})
 }
 
 type sdkLibraryProperties struct {
@@ -120,6 +133,20 @@
 	})
 }
 
+func (module *sdkLibrary) AndroidMk() android.AndroidMkData {
+	// Create a phony module that installs the impl library, for the case when this lib is
+	// in PRODUCT_PACKAGES.
+	return android.AndroidMkData{
+		Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
+			fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
+			fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
+			fmt.Fprintln(w, "LOCAL_MODULE :=", name)
+			fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES := "+module.implName())
+			fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
+		},
+	}
+}
+
 // Module name of the stubs library
 func (module *sdkLibrary) stubsName(forSystemApi bool) string {
 	stubsName := module.BaseModuleName() + sdkStubsLibrarySuffix
@@ -210,6 +237,9 @@
 			Unbundled_build struct {
 				Enabled *bool
 			}
+			Pdk struct {
+				Enabled *bool
+			}
 		}
 	}{}
 
@@ -219,6 +249,7 @@
 	props.Sdk_version = proptools.StringPtr(module.sdkVersion(forSystemApi))
 	// Unbundled apps will use the prebult one from /prebuilts/sdk
 	props.Product_variables.Unbundled_build.Enabled = proptools.BoolPtr(false)
+	props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
 
 	if module.SocSpecific() {
 		props.Soc_specific = proptools.BoolPtr(true)
@@ -281,17 +312,25 @@
 	props.Api_filename = proptools.StringPtr(currentApiFileName)
 	props.Removed_api_filename = proptools.StringPtr(removedApiFileName)
 
-	// Includes the main framework source to ensure that doclava has access to the
-	// visibility information for the base classes of the mock classes. Without it
-	// otherwise hidden methods could be visible.
-	// TODO: remove the need for this
+	// Include the part of the framework source. This is required for the case when
+	// API class is extending from the framework class. In that case, doclava needs
+	// to know whether the base class is hidden or not. Since that information is
+	// encoded as @hide string in the comment, we need source files for the classes,
+	// not the compiled ones. Also there are rare cases where part of SDK library is
+	// implemented in the framework (e.g. org.apache.http.legacy). In that case,
+	// we need framework source to make API stubs, though the sources are not
+	// required to build the runtime library.
 	props.Srcs_lib = proptools.StringPtr("framework")
 	props.Srcs_lib_whitelist_dirs = []string{"core/java"}
-	props.Srcs_lib_whitelist_pkgs = []string{"android"}
-	// These libs are required by doclava to parse the sources from framework.
+	props.Srcs_lib_whitelist_pkgs = module.properties.Api_packages
+	// Add android.annotation package to give access to the framework-defined
+	// annotations such as SystemApi, NonNull, etc.
+	props.Srcs_lib_whitelist_pkgs = append(props.Srcs_lib_whitelist_pkgs, "android.annotation")
+	// These libs are required by doclava to parse the framework sources add via
+	// Src_lib and Src_lib_whitelist_* properties just above.
 	// If we don't add them to the classpath, errors messages are generated by doclava,
 	// though they don't break the build.
-	props.Libs = append(props.Libs, "conscrypt", "bouncycastle", "okhttp")
+	props.Libs = append(props.Libs, "conscrypt", "bouncycastle", "okhttp", "framework")
 
 	mctx.CreateModule(android.ModuleFactoryAdaptor(DroiddocFactory), &props)
 }
@@ -397,6 +436,12 @@
 	}
 }
 
+func javaSdkLibraries(config android.Config) *[]string {
+	return config.Once("javaSdkLibraries", func() interface{} {
+		return &[]string{}
+	}).(*[]string)
+}
+
 // For a java_sdk_library module, create internal modules for stubs, docs,
 // runtime libs and xml file. If requested, the stubs and docs are created twice
 // once for public API level and once for system API level
@@ -413,6 +458,12 @@
 		// for runtime
 		module.createXmlFile(mctx)
 		module.createImplLibrary(mctx)
+
+		// record java_sdk_library modules so that they are exported to make
+		javaSdkLibraries := javaSdkLibraries(mctx.Config())
+		javaSdkLibrariesLock.Lock()
+		defer javaSdkLibrariesLock.Unlock()
+		*javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
 	}
 }