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
+}
