Merge "Revert "Set -fomit-frame-pointer for all devices""
diff --git a/Android.bp b/Android.bp
index 3badfcd..b57b0cc 100644
--- a/Android.bp
+++ b/Android.bp
@@ -158,6 +158,8 @@
     ],
     testSrcs: [
         "cc/cc_test.go",
+        "cc/gen_test.go",
+        "cc/library_test.go",
         "cc/test_data_test.go",
     ],
     pluginFor: ["soong_build"],
diff --git a/android/config.go b/android/config.go
index b73680e..79ff32a 100644
--- a/android/config.go
+++ b/android/config.go
@@ -291,6 +291,8 @@
 	switch c.Getenv("EXPERIMENTAL_USE_OPENJDK9") {
 	case "":
 		// Use OpenJDK8
+	case "false":
+		// Use OpenJDK8
 	case "1.8":
 		// Use OpenJDK9, but target 1.8
 		c.useOpenJDK9 = true
diff --git a/android/module.go b/android/module.go
index 2a8837b..66859fa 100644
--- a/android/module.go
+++ b/android/module.go
@@ -108,6 +108,7 @@
 
 	ModuleSubDir() string
 
+	VisitDirectDepsBlueprint(visit func(blueprint.Module))
 	VisitDirectDeps(visit func(Module))
 	VisitDirectDepsIf(pred func(Module) bool, visit func(Module))
 	VisitDepsDepthFirst(visit func(Module))
@@ -686,6 +687,10 @@
 	return aModule
 }
 
+func (a *androidModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) {
+	a.ModuleContext.VisitDirectDeps(visit)
+}
+
 func (a *androidModuleContext) VisitDirectDeps(visit func(Module)) {
 	a.ModuleContext.VisitDirectDeps(func(module blueprint.Module) {
 		if aModule := a.validateAndroidModule(module); aModule != nil {
diff --git a/androidmk/cmd/androidmk/android.go b/androidmk/cmd/androidmk/android.go
index 0de5009..df01cf4 100644
--- a/androidmk/cmd/androidmk/android.go
+++ b/androidmk/cmd/androidmk/android.go
@@ -1,3 +1,17 @@
+// 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.
+
 package main
 
 import (
diff --git a/androidmk/cmd/androidmk/androidmk.go b/androidmk/cmd/androidmk/androidmk.go
index 5cb3f7a..660d9a0 100644
--- a/androidmk/cmd/androidmk/androidmk.go
+++ b/androidmk/cmd/androidmk/androidmk.go
@@ -1,3 +1,17 @@
+// 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.
+
 package main
 
 import (
diff --git a/androidmk/cmd/androidmk/values.go b/androidmk/cmd/androidmk/values.go
index 0074bb9..d240a01 100644
--- a/androidmk/cmd/androidmk/values.go
+++ b/androidmk/cmd/androidmk/values.go
@@ -1,3 +1,17 @@
+// 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.
+
 package main
 
 import (
diff --git a/androidmk/parser/ast.go b/androidmk/parser/ast.go
index 07e1842..d5d1354 100644
--- a/androidmk/parser/ast.go
+++ b/androidmk/parser/ast.go
@@ -1,3 +1,17 @@
+// 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.
+
 package parser
 
 type Pos int
diff --git a/androidmk/parser/make_strings.go b/androidmk/parser/make_strings.go
index 142dc71..e6885a8 100644
--- a/androidmk/parser/make_strings.go
+++ b/androidmk/parser/make_strings.go
@@ -1,3 +1,17 @@
+// 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.
+
 package parser
 
 import (
diff --git a/androidmk/parser/make_strings_test.go b/androidmk/parser/make_strings_test.go
index 5636b79..8ad3d74 100644
--- a/androidmk/parser/make_strings_test.go
+++ b/androidmk/parser/make_strings_test.go
@@ -1,3 +1,17 @@
+// 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.
+
 package parser
 
 import (
diff --git a/androidmk/parser/parser.go b/androidmk/parser/parser.go
index ef5b492..89ee308 100644
--- a/androidmk/parser/parser.go
+++ b/androidmk/parser/parser.go
@@ -1,3 +1,17 @@
+// 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.
+
 package parser
 
 import (
diff --git a/androidmk/parser/scope.go b/androidmk/parser/scope.go
index 60efac2..7a514fa 100644
--- a/androidmk/parser/scope.go
+++ b/androidmk/parser/scope.go
@@ -1,3 +1,17 @@
+// 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.
+
 package parser
 
 import (
diff --git a/bootstrap.bash b/bootstrap.bash
index 769736f..4db8539 100755
--- a/bootstrap.bash
+++ b/bootstrap.bash
@@ -1,5 +1,19 @@
 #!/bin/bash
 
+# 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.
+
 echo '==== ERROR: bootstrap.bash & ./soong are obsolete ====' >&2
 echo 'Use `m --skip-make` with a standalone OUT_DIR instead.' >&2
 echo 'Without envsetup.sh, use:' >&2
diff --git a/cc/cc.go b/cc/cc.go
index 86a60c9..384b240 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -230,7 +230,7 @@
 type compiler interface {
 	compilerInit(ctx BaseModuleContext)
 	compilerDeps(ctx DepsContext, deps Deps) Deps
-	compilerFlags(ctx ModuleContext, flags Flags) Flags
+	compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags
 	compilerProps() []interface{}
 
 	appendCflags([]string)
@@ -589,12 +589,17 @@
 	}
 	ctx.ctx = ctx
 
+	deps := c.depsToPaths(ctx)
+	if ctx.Failed() {
+		return
+	}
+
 	flags := Flags{
 		Toolchain: c.toolchain(ctx),
 		Clang:     c.clang(ctx),
 	}
 	if c.compiler != nil {
-		flags = c.compiler.compilerFlags(ctx, flags)
+		flags = c.compiler.compilerFlags(ctx, flags, deps)
 	}
 	if c.linker != nil {
 		flags = c.linker.linkerFlags(ctx, flags)
@@ -625,10 +630,6 @@
 	flags.CppFlags, _ = filterList(flags.CppFlags, config.IllegalFlags)
 	flags.ConlyFlags, _ = filterList(flags.ConlyFlags, config.IllegalFlags)
 
-	deps := c.depsToPaths(ctx)
-	if ctx.Failed() {
-		return
-	}
 	flags.GlobalFlags = append(flags.GlobalFlags, deps.Flags...)
 	c.flags = flags
 	// We need access to all the flags seen by a source file.
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 32cffe4..bdc8c17 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -1,7 +1,23 @@
+// 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.
+
 package cc
 
 import (
 	"android/soong/android"
+	"android/soong/genrule"
+
 	"fmt"
 	"io/ioutil"
 	"os"
@@ -42,9 +58,11 @@
 
 	ctx := android.NewTestArchContext()
 	ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(LibraryFactory))
+	ctx.RegisterModuleType("cc_library_shared", android.ModuleFactoryAdaptor(LibrarySharedFactory))
 	ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(toolchainLibraryFactory))
 	ctx.RegisterModuleType("llndk_library", android.ModuleFactoryAdaptor(llndkLibraryFactory))
 	ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(objectFactory))
+	ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(genrule.FileGroupFactory))
 	ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
 		ctx.BottomUp("image", vendorMutator).Parallel()
 		ctx.BottomUp("link", linkageMutator).Parallel()
@@ -108,12 +126,18 @@
 			name: "crtend_so",
 		}
 
+		cc_library {
+			name: "libprotobuf-cpp-lite",
+		}
+
 `
 
 	ctx.MockFileSystem(map[string][]byte{
 		"Android.bp": []byte(bp),
 		"foo.c":      nil,
 		"bar.c":      nil,
+		"a.proto":    nil,
+		"b.aidl":     nil,
 	})
 
 	_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
diff --git a/cc/cmakelists.go b/cc/cmakelists.go
index c353f44..13a2e8e 100644
--- a/cc/cmakelists.go
+++ b/cc/cmakelists.go
@@ -1,3 +1,17 @@
+// 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.
+
 package cc
 
 import (
diff --git a/cc/compiler.go b/cc/compiler.go
index 4112930..ca68a00 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -158,8 +158,15 @@
 	Properties BaseCompilerProperties
 	Proto      android.ProtoProperties
 	deps       android.Paths
-	srcs       android.Paths
 	flags      builderFlags
+
+	// Sources that were passed to the C/C++ compiler
+	srcs android.Paths
+
+	// Sources that were passed in the Android.bp file, including generated sources generated by
+	// other modules and filegroups. May include source files that have not yet been translated to
+	// C/C++ (.aidl, .proto, etc.)
+	srcsBeforeGen android.Paths
 }
 
 var _ compiler = (*baseCompiler)(nil)
@@ -201,9 +208,12 @@
 
 // Create a Flags struct that collects the compile flags from global values,
 // per-target values, module type values, and per-module Blueprints properties
-func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags) Flags {
+func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags {
 	tc := ctx.toolchain()
 
+	compiler.srcsBeforeGen = ctx.ExpandSources(compiler.Properties.Srcs, compiler.Properties.Exclude_srcs)
+	compiler.srcsBeforeGen = append(compiler.srcsBeforeGen, deps.GeneratedSources...)
+
 	CheckBadCompilerFlags(ctx, "cflags", compiler.Properties.Cflags)
 	CheckBadCompilerFlags(ctx, "cppflags", compiler.Properties.Cppflags)
 	CheckBadCompilerFlags(ctx, "conlyflags", compiler.Properties.Conlyflags)
@@ -458,6 +468,11 @@
 }
 
 func (compiler *baseCompiler) hasSrcExt(ext string) bool {
+	for _, src := range compiler.srcsBeforeGen {
+		if src.Ext() == ext {
+			return true
+		}
+	}
 	for _, src := range compiler.Properties.Srcs {
 		if filepath.Ext(src) == ext {
 			return true
@@ -487,11 +502,10 @@
 	pathDeps := deps.GeneratedHeaders
 	pathDeps = append(pathDeps, ndkPathDeps(ctx)...)
 
-	srcs := ctx.ExpandSources(compiler.Properties.Srcs, compiler.Properties.Exclude_srcs)
-	srcs = append(srcs, deps.GeneratedSources...)
-
 	buildFlags := flagsToBuilderFlags(flags)
 
+	srcs := append(android.Paths(nil), compiler.srcsBeforeGen...)
+
 	srcs, genDeps := genSources(ctx, srcs, buildFlags)
 
 	pathDeps = append(pathDeps, genDeps...)
diff --git a/cc/config/clang.go b/cc/config/clang.go
index 2345ebc..2ef153b 100644
--- a/cc/config/clang.go
+++ b/cc/config/clang.go
@@ -1,3 +1,17 @@
+// 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.
+
 package config
 
 import (
diff --git a/cc/gen_test.go b/cc/gen_test.go
new file mode 100644
index 0000000..a0f7308
--- /dev/null
+++ b/cc/gen_test.go
@@ -0,0 +1,63 @@
+// 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.
+
+package cc
+
+import (
+	"testing"
+)
+
+func TestGen(t *testing.T) {
+	t.Run("simple", func(t *testing.T) {
+		ctx := testCc(t, `
+		cc_library_shared {
+			name: "libfoo",
+			srcs: [
+				"foo.c",
+				"b.aidl",
+			],
+		}`)
+
+		aidl := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_core_shared").Rule("aidl")
+		libfoo := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_core_shared").Module().(*Module)
+
+		if !inList("-I"+aidl.Args["outDir"], libfoo.flags.GlobalFlags) {
+			t.Errorf("missing aidl includes in global flags")
+		}
+	})
+
+	t.Run("filegroup", func(t *testing.T) {
+		ctx := testCc(t, `
+		filegroup {
+			name: "fg",
+			srcs: ["b.aidl"],
+		}
+
+		cc_library_shared {
+			name: "libfoo",
+			srcs: [
+				"foo.c",
+				":fg",
+			],
+		}`)
+
+		aidl := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_core_shared").Rule("aidl")
+		libfoo := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_core_shared").Module().(*Module)
+
+		if !inList("-I"+aidl.Args["outDir"], libfoo.flags.GlobalFlags) {
+			t.Errorf("missing aidl includes in global flags")
+		}
+	})
+
+}
diff --git a/cc/library.go b/cc/library.go
index d4ed7c6..192496a 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -317,7 +317,7 @@
 	return flags
 }
 
-func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
+func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags {
 	exportIncludeDirs := library.flagExporter.exportedIncludes(ctx)
 	if len(exportIncludeDirs) > 0 {
 		f := includeDirsToFlags(exportIncludeDirs)
@@ -325,7 +325,7 @@
 		flags.YasmFlags = append(flags.YasmFlags, f)
 	}
 
-	return library.baseCompiler.compilerFlags(ctx, flags)
+	return library.baseCompiler.compilerFlags(ctx, flags, deps)
 }
 
 func extractExportIncludesFromFlags(flags []string) []string {
@@ -651,7 +651,7 @@
 func (library *libraryDecorator) link(ctx ModuleContext,
 	flags Flags, deps PathDeps, objs Objects) android.Path {
 
-	objs = objs.Append(deps.Objs)
+	objs = deps.Objs.Copy().Append(objs)
 	var out android.Path
 	if library.static() || library.header() {
 		out = library.linkStatic(ctx, flags, deps, objs)
diff --git a/cc/library_test.go b/cc/library_test.go
new file mode 100644
index 0000000..859b05a
--- /dev/null
+++ b/cc/library_test.go
@@ -0,0 +1,185 @@
+// 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.
+
+package cc
+
+import (
+	"reflect"
+	"testing"
+)
+
+func TestLibraryReuse(t *testing.T) {
+	t.Run("simple", func(t *testing.T) {
+		ctx := testCc(t, `
+		cc_library {
+			name: "libfoo",
+			srcs: ["foo.c"],
+		}`)
+
+		libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_core_shared").Rule("ld")
+		libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_core_static").Output("libfoo.a")
+
+		if len(libfooShared.Inputs) != 1 {
+			t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings())
+		}
+
+		if len(libfooStatic.Inputs) != 1 {
+			t.Fatalf("unexpected inputs to libfoo static: %#v", libfooStatic.Inputs.Strings())
+		}
+
+		if libfooShared.Inputs[0] != libfooStatic.Inputs[0] {
+			t.Errorf("static object not reused for shared library")
+		}
+	})
+
+	t.Run("extra static source", func(t *testing.T) {
+		ctx := testCc(t, `
+		cc_library {
+			name: "libfoo",
+			srcs: ["foo.c"],
+			static: {
+				srcs: ["bar.c"]
+			},
+		}`)
+
+		libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_core_shared").Rule("ld")
+		libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_core_static").Output("libfoo.a")
+
+		if len(libfooShared.Inputs) != 1 {
+			t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings())
+		}
+
+		if len(libfooStatic.Inputs) != 2 {
+			t.Fatalf("unexpected inputs to libfoo static: %#v", libfooStatic.Inputs.Strings())
+		}
+
+		if libfooShared.Inputs[0] != libfooStatic.Inputs[0] {
+			t.Errorf("static object not reused for shared library")
+		}
+	})
+
+	t.Run("extra shared source", func(t *testing.T) {
+		ctx := testCc(t, `
+		cc_library {
+			name: "libfoo",
+			srcs: ["foo.c"],
+			shared: {
+				srcs: ["bar.c"]
+			},
+		}`)
+
+		libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_core_shared").Rule("ld")
+		libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_core_static").Output("libfoo.a")
+
+		if len(libfooShared.Inputs) != 2 {
+			t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings())
+		}
+
+		if len(libfooStatic.Inputs) != 1 {
+			t.Fatalf("unexpected inputs to libfoo static: %#v", libfooStatic.Inputs.Strings())
+		}
+
+		if libfooShared.Inputs[0] != libfooStatic.Inputs[0] {
+			t.Errorf("static object not reused for shared library")
+		}
+	})
+
+	t.Run("extra static cflags", func(t *testing.T) {
+		ctx := testCc(t, `
+		cc_library {
+			name: "libfoo",
+			srcs: ["foo.c"],
+			static: {
+				cflags: ["-DFOO"],
+			},
+		}`)
+
+		libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_core_shared").Rule("ld")
+		libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_core_static").Output("libfoo.a")
+
+		if len(libfooShared.Inputs) != 1 {
+			t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings())
+		}
+
+		if len(libfooStatic.Inputs) != 1 {
+			t.Fatalf("unexpected inputs to libfoo static: %#v", libfooStatic.Inputs.Strings())
+		}
+
+		if libfooShared.Inputs[0] == libfooStatic.Inputs[0] {
+			t.Errorf("static object reused for shared library when it shouldn't be")
+		}
+	})
+
+	t.Run("extra shared cflags", func(t *testing.T) {
+		ctx := testCc(t, `
+		cc_library {
+			name: "libfoo",
+			srcs: ["foo.c"],
+			shared: {
+				cflags: ["-DFOO"],
+			},
+		}`)
+
+		libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_core_shared").Rule("ld")
+		libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_core_static").Output("libfoo.a")
+
+		if len(libfooShared.Inputs) != 1 {
+			t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings())
+		}
+
+		if len(libfooStatic.Inputs) != 1 {
+			t.Fatalf("unexpected inputs to libfoo static: %#v", libfooStatic.Inputs.Strings())
+		}
+
+		if libfooShared.Inputs[0] == libfooStatic.Inputs[0] {
+			t.Errorf("static object reused for shared library when it shouldn't be")
+		}
+	})
+
+	t.Run("global cflags for reused generated sources", func(t *testing.T) {
+		ctx := testCc(t, `
+		cc_library {
+			name: "libfoo",
+			srcs: [
+				"foo.c",
+				"a.proto",
+			],
+			shared: {
+				srcs: [
+					"bar.c",
+				],
+			},
+		}`)
+
+		libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_core_shared").Rule("ld")
+		libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_core_static").Output("libfoo.a")
+
+		if len(libfooShared.Inputs) != 3 {
+			t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings())
+		}
+
+		if len(libfooStatic.Inputs) != 2 {
+			t.Fatalf("unexpected inputs to libfoo static: %#v", libfooStatic.Inputs.Strings())
+		}
+
+		if !reflect.DeepEqual(libfooShared.Inputs[0:2].Strings(), libfooStatic.Inputs.Strings()) {
+			t.Errorf("static objects not reused for shared library")
+		}
+
+		libfoo := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_core_shared").Module().(*Module)
+		if !inList("-DGOOGLE_PROTOBUF_NO_RTTI", libfoo.flags.CFlags) {
+			t.Errorf("missing protobuf cflags")
+		}
+	})
+}
diff --git a/cc/llndk_library.go b/cc/llndk_library.go
index 154b3f4..9a29964 100644
--- a/cc/llndk_library.go
+++ b/cc/llndk_library.go
@@ -70,8 +70,8 @@
 	versionScriptPath      android.ModuleGenPath
 }
 
-func (stub *llndkStubDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
-	flags = stub.baseCompiler.compilerFlags(ctx, flags)
+func (stub *llndkStubDecorator) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags {
+	flags = stub.baseCompiler.compilerFlags(ctx, flags, deps)
 	return addStubLibraryCompilerFlags(flags)
 }
 
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index 066fb98..c517523 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -258,8 +258,8 @@
 	return flags
 }
 
-func (stub *stubDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
-	flags = stub.baseCompiler.compilerFlags(ctx, flags)
+func (stub *stubDecorator) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags {
+	flags = stub.baseCompiler.compilerFlags(ctx, flags, deps)
 	return addStubLibraryCompilerFlags(flags)
 }
 
diff --git a/cmd/multiproduct_kati/main.go b/cmd/multiproduct_kati/main.go
index 183f800..2fee1f7 100644
--- a/cmd/multiproduct_kati/main.go
+++ b/cmd/multiproduct_kati/main.go
@@ -56,6 +56,7 @@
 var buildVariant = flag.String("variant", "eng", "build variant to use")
 
 var skipProducts = flag.String("skip-products", "", "comma-separated list of products to skip (known failures, etc)")
+var includeProducts = flag.String("products", "", "comma-separated list of products to build")
 
 const errorLeadingLines = 20
 const errorTrailingLines = 20
@@ -158,6 +159,15 @@
 	return s.failed
 }
 
+func inList(str string, list []string) bool {
+	for _, other := range list {
+		if str == other {
+			return true
+		}
+	}
+	return false
+}
+
 func main() {
 	log := logger.New(os.Stderr)
 	defer log.Cleanup()
@@ -222,7 +232,24 @@
 	if err != nil {
 		log.Fatal(err)
 	}
-	productsList := strings.Fields(vars["all_named_products"])
+	var productsList []string
+	allProducts := strings.Fields(vars["all_named_products"])
+
+	if *includeProducts != "" {
+		missingProducts := []string{}
+		for _, product := range strings.Split(*includeProducts, ",") {
+			if inList(product, allProducts) {
+				productsList = append(productsList, product)
+			} else {
+				missingProducts = append(missingProducts, product)
+			}
+		}
+		if len(missingProducts) > 0 {
+			log.Fatalf("Products don't exist: %s\n", missingProducts)
+		}
+	} else {
+		productsList = allProducts
+	}
 
 	products := make([]string, 0, len(productsList))
 	skipList := strings.Split(*skipProducts, ",")
diff --git a/genrule/genrule.go b/genrule/genrule.go
index c5b7e1d..c142c53 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -158,7 +158,7 @@
 	tools := map[string]android.Path{}
 
 	if len(g.properties.Tools) > 0 {
-		ctx.VisitDirectDeps(func(module android.Module) {
+		ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) {
 			switch ctx.OtherModuleDependencyTag(module) {
 			case android.SourceDepTag:
 				// Nothing to do
@@ -167,6 +167,14 @@
 				var path android.OptionalPath
 
 				if t, ok := module.(HostToolProvider); ok {
+					if !t.(android.Module).Enabled() {
+						if ctx.AConfig().AllowMissingDependencies() {
+							ctx.AddMissingDependencies([]string{tool})
+						} else {
+							ctx.ModuleErrorf("depends on disabled module %q", tool)
+						}
+						break
+					}
 					path = t.HostToolPath()
 				} else if t, ok := module.(bootstrap.GoBinaryTool); ok {
 					if s, err := filepath.Rel(android.PathForOutput(ctx).String(), t.InstallPath()); err == nil {
diff --git a/java/builder.go b/java/builder.go
index 45e59a4..d2e02fd 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -186,7 +186,7 @@
 	kotlincFlags     string
 	kotlincClasspath classpath
 
-	protoFlags   string
+	protoFlags   []string
 	protoOutFlag string
 }
 
diff --git a/java/config/config.go b/java/config/config.go
index d4994a1..3cd2841 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -70,7 +70,7 @@
 	pctx.SourcePathVariable("JrtFsJar", "${JavaHome}/lib/jrt-fs.jar")
 	pctx.SourcePathVariable("Ziptime", "prebuilts/build-tools/${hostPrebuiltTag}/bin/ziptime")
 
-	pctx.SourcePathVariable("ExtractSrcJarsCmd", "build/soong/scripts/extract-src-jars.sh")
+	pctx.SourcePathVariable("ExtractSrcJarsCmd", "build/soong/scripts/extract-srcjars.sh")
 	pctx.SourcePathVariable("JarArgsCmd", "build/soong/scripts/jar-args.sh")
 	pctx.HostBinToolVariable("SoongZipCmd", "soong_zip")
 	pctx.HostBinToolVariable("MergeZipsCmd", "merge_zips")
diff --git a/java/config/makevars.go b/java/config/makevars.go
index 96fa92b..dabf2e7 100644
--- a/java/config/makevars.go
+++ b/java/config/makevars.go
@@ -61,4 +61,5 @@
 	}
 
 	ctx.Strict("SOONG_JAVAC_WRAPPER", "${SoongJavacWrapper}")
+	ctx.Strict("EXTRACT_SRCJARS", "${ExtractSrcJarsCmd}")
 }
diff --git a/java/gen.go b/java/gen.go
index 8fa199e..b5973ec 100644
--- a/java/gen.go
+++ b/java/gen.go
@@ -42,7 +42,7 @@
 
 	logtags = pctx.AndroidStaticRule("logtags",
 		blueprint.RuleParams{
-			Command:     "$logtagsCmd -o $out $in $allLogtagsFile",
+			Command:     "$logtagsCmd -o $out $in",
 			CommandDeps: []string{"$logtagsCmd"},
 		})
 
@@ -85,7 +85,7 @@
 }
 
 func (j *Module) genSources(ctx android.ModuleContext, srcFiles android.Paths,
-	flags javaBuilderFlags) (android.Paths, android.Paths) {
+	flags javaBuilderFlags) android.Paths {
 
 	var protoFiles android.Paths
 	outSrcFiles := make(android.Paths, 0, len(srcFiles))
@@ -106,17 +106,15 @@
 		}
 	}
 
-	var outSrcJars android.Paths
-
 	if len(protoFiles) > 0 {
-		protoSrcJar := android.PathForModuleGen(ctx, "proto.src.jar")
+		protoSrcJar := android.PathForModuleGen(ctx, "proto.srcjar")
 		genProto(ctx, protoSrcJar, protoFiles,
 			flags.protoFlags, flags.protoOutFlag, "")
 
-		outSrcJars = append(outSrcJars, protoSrcJar)
+		outSrcFiles = append(outSrcFiles, protoSrcJar)
 	}
 
-	return outSrcFiles, outSrcJars
+	return outSrcFiles
 }
 
 func LogtagsSingleton() blueprint.Singleton {
diff --git a/java/java.go b/java/java.go
index 432e816..b2bd2b0 100644
--- a/java/java.go
+++ b/java/java.go
@@ -136,12 +136,17 @@
 	// if not blank, set to the version of the sdk to compile against
 	Sdk_version *string
 
-	// directories to pass to aidl tool
-	Aidl_includes []string
+	Aidl struct {
+		// Top level directories to pass to aidl tool
+		Include_dirs []string
 
-	// directories that should be added as include directories
-	// for any aidl sources of modules that depend on this module
-	Export_aidl_include_dirs []string
+		// Directories rooted at the Android.bp file to pass to aidl tool
+		Local_include_dirs []string
+
+		// directories that should be added as include directories for any aidl sources of modules
+		// that depend on this module, as well as to aidl for this module.
+		Export_include_dirs []string
+	}
 
 	// If true, export a copy of the module as a -hostdex module for host testing.
 	Hostdex *bool
@@ -377,7 +382,11 @@
 func (j *Module) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
 	aidlIncludeDirs android.Paths) []string {
 
-	localAidlIncludes := android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl_includes)
+	aidlIncludes := android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Local_include_dirs)
+	aidlIncludes = append(aidlIncludes,
+		android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs)...)
+	aidlIncludes = append(aidlIncludes,
+		android.PathsForSource(ctx, j.deviceProperties.Aidl.Include_dirs)...)
 
 	var flags []string
 	if aidlPreprocess.Valid() {
@@ -387,7 +396,7 @@
 	}
 
 	flags = append(flags, android.JoinWithPrefix(j.exportAidlIncludeDirs.Strings(), "-I"))
-	flags = append(flags, android.JoinWithPrefix(localAidlIncludes.Strings(), "-I"))
+	flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
 	flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
 	if src := android.ExistentPathForSource(ctx, "", ctx.ModuleDir(), "src"); src.Valid() {
 		flags = append(flags, "-I"+src.String())
@@ -528,7 +537,7 @@
 
 func (j *Module) compile(ctx android.ModuleContext) {
 
-	j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.deviceProperties.Export_aidl_include_dirs)
+	j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs)
 
 	deps := j.collectDeps(ctx)
 	flags := j.collectBuilderFlags(ctx, deps)
@@ -541,8 +550,9 @@
 		flags = protoFlags(ctx, &j.protoProperties, flags)
 	}
 
-	var srcJars android.Paths
-	srcFiles, srcJars = j.genSources(ctx, srcFiles, flags)
+	srcFiles = j.genSources(ctx, srcFiles, flags)
+
+	srcJars := srcFiles.FilterByExt(".srcjar")
 	srcJars = append(srcJars, deps.srcJars...)
 	srcJars = append(srcJars, j.ExtraSrcJars...)
 
diff --git a/java/proto.go b/java/proto.go
index 1077fd6..17f02a3 100644
--- a/java/proto.go
+++ b/java/proto.go
@@ -15,6 +15,8 @@
 package java
 
 import (
+	"strings"
+
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
 
@@ -39,7 +41,7 @@
 )
 
 func genProto(ctx android.ModuleContext, outputSrcJar android.WritablePath,
-	protoFiles android.Paths, protoFlags string, protoOut, protoOutFlags string) {
+	protoFiles android.Paths, protoFlags []string, protoOut, protoOutFlags string) {
 
 	ctx.Build(pctx, android.BuildParams{
 		Rule:        proto,
@@ -50,7 +52,7 @@
 			"outDir":        android.ProtoDir(ctx).String(),
 			"protoOut":      protoOut,
 			"protoOutFlags": protoOutFlags,
-			"protoFlags":    protoFlags,
+			"protoFlags":    strings.Join(protoFlags, " "),
 		},
 	})
 }
@@ -61,10 +63,6 @@
 		ctx.AddDependency(ctx.Module(), staticLibTag, "libprotobuf-java-micro")
 	case "nano":
 		ctx.AddDependency(ctx.Module(), staticLibTag, "libprotobuf-java-nano")
-	case "stream":
-		// TODO(ccross): add dependency on protoc-gen-java-stream binary
-		ctx.PropertyErrorf("proto.type", `"stream" not supported yet`)
-		// No library for stream protobufs
 	case "lite", "":
 		ctx.AddDependency(ctx.Module(), staticLibTag, "libprotobuf-java-lite")
 	case "full":
@@ -85,13 +83,14 @@
 		flags.protoOutFlag = "--javamicro_out"
 	case "nano":
 		flags.protoOutFlag = "--javanano_out"
-	case "stream":
-		flags.protoOutFlag = "--javastream_out"
 	case "lite", "full", "":
 		flags.protoOutFlag = "--java_out"
 	default:
 		ctx.PropertyErrorf("proto.type", "unknown proto type %q",
 			proptools.String(p.Proto.Type))
 	}
+
+	flags.protoFlags = android.ProtoFlags(ctx, p)
+
 	return flags
 }
diff --git a/root.bp b/root.bp
index bc59171..7e0c1ed 100644
--- a/root.bp
+++ b/root.bp
@@ -1,44 +1,4 @@
-subname = "Android.bp"
-
-build = [
-    "build/blueprint/Blueprints",
-]
-
-subdirs = [
-    "build/soong",
-]
-
-optional_subdirs = [
-    "art",
-    "bionic",
-    "bootable/recovery",
-    "build/kati",
-    "build/make/tools/*",
-    "dalvik",
-    "development/*",
-    "device/*/*",
-    "external/*",
-    "external/python/*",
-    "frameworks/*",
-    "frameworks/compile/*",
-    "frameworks/hardware/interfaces",
-    "frameworks/opt/net/wifi",
-    "hardware/*",
-    "libcore",
-    "libnativehelper",
-    "packages/apps/*",
-    "prebuilts/clang/host/linux-x86",
-    "prebuilts/ndk",
-    "prebuilts/r8",
-    "prebuilts/sdk",
-    "prebuilts/misc",
-    "system/*",
-    "system/hardware/interfaces",
-    "system/tools/*",
-    "test/vts",
-    "test/vts-testcase/*",
-    "tools/*",
-    "tools/tradefederation/*",
-    "toolchain/*",
-    "vendor/*/*",
-]
+// Soong finds all Android.bp and Blueprints files in the source tree,
+// subdirs= and optional_subdirs= are obsolete and this file no longer
+// needs a list of the top level directories that may contain Android.bp
+// files.
diff --git a/scripts/build-ndk-prebuilts.sh b/scripts/build-ndk-prebuilts.sh
index 197a38d..55214b2 100755
--- a/scripts/build-ndk-prebuilts.sh
+++ b/scripts/build-ndk-prebuilts.sh
@@ -1,5 +1,19 @@
 #!/bin/bash -ex
 
+# 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.
+
 if [ -z "${OUT_DIR}" ]; then
     echo Must set OUT_DIR
     exit 1
diff --git a/scripts/copygcclib.sh b/scripts/copygcclib.sh
index 4bd6f9b..28359fc 100755
--- a/scripts/copygcclib.sh
+++ b/scripts/copygcclib.sh
@@ -1,5 +1,19 @@
 #!/bin/bash -e
 
+# 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.
+
 OUT=$1
 shift
 LIBPATH=$($@ | sed -e "s|^$PWD/||")
diff --git a/scripts/diff_build_graphs.sh b/scripts/diff_build_graphs.sh
new file mode 100755
index 0000000..e7d8749
--- /dev/null
+++ b/scripts/diff_build_graphs.sh
@@ -0,0 +1,170 @@
+#!/bin/bash -eu
+#
+# 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.
+
+set -e
+
+# This file makes it easy to confirm that a set of changes in source code don't result in any
+# changes to the generated ninja files. This is to reduce the effort required to be confident
+# in the correctness of refactorings
+
+function die() {
+  echo "$@" >&2
+  exit 1
+}
+
+function usage() {
+  violation="$1"
+  die "$violation
+
+  Usage: diff_build_graphs.sh [--products=product1,product2...] <OLD_VERSIONS> <NEW_VERSIONS>
+
+  This file builds and parses the build files (Android.mk, Android.bp, etc) for each requested
+  product and for both sets of versions, and checks whether the ninja files (which implement
+  the build graph) changed between the two versions.
+
+  Example: diff_build_graphs.sh 'build/soong:work^ build/blueprint:work^' 'build/soong:work build/blueprint:work'
+
+  Options:
+    --products=PRODUCTS  comma-separated list of products to check"
+}
+
+PRODUCTS_ARG=""
+OLD_VERSIONS=""
+NEW_VERSIONS=""
+function parse_args() {
+  # parse optional arguments
+  while true; do
+    arg="${1-}"
+    case "$arg" in
+      --products=*) PRODUCTS_ARG="$arg";;
+      *) break;;
+    esac
+    shift
+  done
+  # parse required arguments
+  if [ "$#" != "2" ]; then
+    usage ""
+  fi
+  #argument validation
+  OLD_VERSIONS="$1"
+  NEW_VERSIONS="$2"
+
+}
+parse_args "$@"
+
+
+# find some file paths
+cd "$(dirname $0)"
+SCRIPT_DIR="$PWD"
+cd ../../..
+CHECKOUT_ROOT="$PWD"
+OUT_DIR="${OUT_DIR-}"
+if [ -z "$OUT_DIR" ]; then
+  OUT_DIR=out
+fi
+WORK_DIR="$OUT_DIR/diff"
+OUT_DIR_OLD="$WORK_DIR/out_old"
+OUT_DIR_NEW="$WORK_DIR/out_new"
+OUT_DIR_TEMP="$WORK_DIR/out_temp"
+
+
+function checkout() {
+  versionSpecs="$1"
+  for versionSpec in $versionSpecs; do
+    project="$(echo $versionSpec | sed 's|\([^:]*\):\([^:]*\)|\1|')"
+    ref="$(echo     $versionSpec | sed 's|\([^:]*\):\([^:]*\)|\2|')"
+    echo "checking out ref $ref in project $project"
+    git -C "$project" checkout "$ref"
+  done
+}
+
+function run_build() {
+  echo
+  echo "Starting build"
+  # rebuild multiproduct_kati, in case it was missing before,
+  # or in case it is affected by some of the changes we're testing
+  make blueprint_tools
+  # find multiproduct_kati and have it build the ninja files for each product
+  builder="$(echo $OUT_DIR/soong/host/*/bin/multiproduct_kati)"
+  BUILD_NUMBER=sample "$builder" $PRODUCTS_ARG --keep --out "$OUT_DIR_TEMP" || true
+  echo
+}
+
+function diffProduct() {
+  product="$1"
+
+  zip1="$OUT_DIR_OLD/${product}.zip"
+  unzipped1="$OUT_DIR_OLD/$product"
+
+  zip2="$OUT_DIR_NEW/${product}.zip"
+  unzipped2="$OUT_DIR_NEW/$product"
+
+  unzip -qq "$zip1" -d "$unzipped1"
+  unzip -qq "$zip2" -d "$unzipped2"
+
+  #do a diff of the ninja files
+  diffFile="$WORK_DIR/diff.txt"
+  diff -r "$unzipped1" "$unzipped2" -x build_date.txt -x build_number.txt -x '\.*' -x '*.log' -x build_fingerprint.txt -x build.ninja.d -x '*.zip' > $diffFile || true
+  if [[ -s "$diffFile" ]]; then
+    # outputs are different, so remove the unzipped versions but keep the zipped versions
+    echo "Some differences for product $product:"
+    cat "$diffFile" | head -n 10
+    echo "End of differences for product $product"
+    rm -rf "$unzipped1" "$unzipped2"
+  else
+    # outputs are the same, so remove all of the outputs
+    rm -rf "$zip1" "$unzipped1" "$zip2" "$unzipped2"
+  fi
+}
+
+function do_builds() {
+  #reset work dir
+  rm -rf "$WORK_DIR"
+  mkdir "$WORK_DIR"
+
+  #build new code
+  checkout "$NEW_VERSIONS"
+  run_build
+  mv "$OUT_DIR_TEMP" "$OUT_DIR_NEW"
+
+  #build old code
+  #TODO do we want to cache old results? Maybe by the time we care to cache old results this will
+  #be running on a remote server somewhere and be completely different
+  checkout "$OLD_VERSIONS"
+  run_build
+  mv "$OUT_DIR_TEMP" "$OUT_DIR_OLD"
+
+  #cleanup
+  echo created "$OUT_DIR_OLD" and "$OUT_DIR_NEW"
+}
+
+function main() {
+  do_builds
+  checkout "$NEW_VERSIONS"
+
+  #find all products
+  productsFile="$WORK_DIR/all_products.txt"
+  find $OUT_DIR_OLD $OUT_DIR_NEW -mindepth 1 -maxdepth 1 -name "*.zip" | sed "s|^$OUT_DIR_OLD/||" | sed "s|^$OUT_DIR_NEW/||" | sed "s|\.zip$||" | sort | uniq > "$productsFile"
+  echo Diffing products
+  for product in $(cat $productsFile); do
+    diffProduct "$product"
+  done
+  echo Done diffing products
+  echo "Any differing outputs can be seen at $OUT_DIR_OLD/*.zip and $OUT_DIR_NEW/*.zip"
+  echo "See $WORK_DIR/diff.txt for the full list of differences for the latest product checked"
+}
+
+main
diff --git a/scripts/extract-src-jars.sh b/scripts/extract-src-jars.sh
deleted file mode 100755
index 918cf8a..0000000
--- a/scripts/extract-src-jars.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/bash -e
-
-# Extracts .java files from source jars in a specified directory and writes out a list of the files
-
-if [ -z "$1" -o -z "$2" ]; then
-  echo "usage: $0 <output dir> <output file> [<jar> ...]" >&2
-  exit 1
-fi
-
-output_dir=$1
-shift
-output_file=$1
-shift
-
-rm -f $output_file
-touch $output_file
-
-for j in "$@"; do
-  for f in $(zipinfo -1 $j '*.java'); do
-    echo $output_dir/$f >> $output_file
-  done
-  unzip -qn -d $output_dir $j '*.java'
-done
-
-duplicates=$(cat $output_file | sort | uniq -d | uniq)
-if [ -n "$duplicates" ]; then
-  echo Duplicate source files:
-  echo $duplicates
-  exit 1
-fi
diff --git a/scripts/extract-srcjars.sh b/scripts/extract-srcjars.sh
new file mode 100755
index 0000000..f81032b
--- /dev/null
+++ b/scripts/extract-srcjars.sh
@@ -0,0 +1,44 @@
+#!/bin/bash -e
+
+# 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.
+
+# Extracts .java files from source jars in a specified directory and writes out a list of the files
+
+if [ -z "$1" -o -z "$2" ]; then
+  echo "usage: $0 <output dir> <output file> [<jar> ...]" >&2
+  exit 1
+fi
+
+output_dir=$1
+shift
+output_file=$1
+shift
+
+rm -f $output_file
+touch $output_file
+
+for j in "$@"; do
+  for f in $(zipinfo -1 $j '*.java'); do
+    echo $output_dir/$f >> $output_file
+  done
+  unzip -qn -d $output_dir $j '*.java'
+done
+
+duplicates=$(cat $output_file | sort | uniq -d | uniq)
+if [ -n "$duplicates" ]; then
+  echo Duplicate source files:
+  echo $duplicates
+  exit 1
+fi
diff --git a/scripts/jar-args.sh b/scripts/jar-args.sh
index 9f05394..340e9a3 100755
--- a/scripts/jar-args.sh
+++ b/scripts/jar-args.sh
@@ -1,5 +1,19 @@
 #!/bin/bash -e
 
+# 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.
+
 # Script that takes a list of files on stdin and converts it to arguments to jar on stdout
 # Usage:
 #        find $dir -type f | sort | jar-args.sh $dir > jar_args.txt
diff --git a/scripts/jars-to-module-info-java.sh b/scripts/jars-to-module-info-java.sh
index 44be549..dd15198 100755
--- a/scripts/jars-to-module-info-java.sh
+++ b/scripts/jars-to-module-info-java.sh
@@ -1,5 +1,19 @@
 #!/bin/bash -e
 
+# 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.
+
 # Extracts the Java package names of all classes in the .jar files and writes a module-info.java
 # file to stdout that exports all of those packages.
 
diff --git a/scripts/setup_go_workspace_for_soong.sh b/scripts/setup_go_workspace_for_soong.sh
index 4b118ef..1c9a0b7 100755
--- a/scripts/setup_go_workspace_for_soong.sh
+++ b/scripts/setup_go_workspace_for_soong.sh
@@ -1,6 +1,20 @@
 #!/bin/bash
 set -e
 
+# 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.
+
 #mounts the components of soong into a directory structure that Go tools and editors expect
 
 #move to the script's directory
diff --git a/scripts/strip.sh b/scripts/strip.sh
index b9ff741..848fe8d 100755
--- a/scripts/strip.sh
+++ b/scripts/strip.sh
@@ -1,5 +1,19 @@
 #!/bin/bash -e
 
+# 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.
+
 # Script to handle the various ways soong may need to strip binaries
 # Inputs:
 #  Environment:
diff --git a/scripts/toc.sh b/scripts/toc.sh
index 59bf8a3..7b2224c 100755
--- a/scripts/toc.sh
+++ b/scripts/toc.sh
@@ -1,5 +1,19 @@
 #!/bin/bash -eu
 
+# 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.
+
 # Script to handle generating a .toc file from a .so file
 # Inputs:
 #  Environment:
diff --git a/soong.bash b/soong.bash
index 41608d5..8cf2ec6 100755
--- a/soong.bash
+++ b/soong.bash
@@ -1,5 +1,19 @@
 #!/bin/bash
 
+# 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.
+
 echo '==== ERROR: bootstrap.bash & ./soong are obsolete ====' >&2
 echo 'Use `m --skip-make` with a standalone OUT_DIR instead.' >&2
 echo 'Without envsetup.sh, use:' >&2
diff --git a/ui/build/config.go b/ui/build/config.go
index 940bb2f..6e5559d 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -149,7 +149,7 @@
 		if override, ok := ret.environ.Get("OVERRIDE_ANDROID_JAVA_HOME"); ok {
 			return override
 		}
-		if v, ok := ret.environ.Get("EXPERIMENTAL_USE_OPENJDK9"); ok && v != "" {
+		if v, ok := ret.environ.Get("EXPERIMENTAL_USE_OPENJDK9"); ok && v != "" && v != "false" {
 			return filepath.Join("prebuilts/jdk/jdk9", ret.HostPrebuiltTag())
 		}
 		return filepath.Join("prebuilts/jdk/jdk8", ret.HostPrebuiltTag())