Merge "Stop linking libdl.a into static bins"
diff --git a/Android.bp b/Android.bp
index 20d45e5..714ce37 100644
--- a/Android.bp
+++ b/Android.bp
@@ -580,104 +580,21 @@
     arch: {
         arm: {
             src: "prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/lib/gcc/arm-linux-androideabi/4.9.x/libgcc.a",
-            strip: {
-                keep_symbols_list: [
-                    // unwind-arm.o
-                    "_Unwind_Complete",
-                    "_Unwind_DeleteException",
-                    "_Unwind_GetCFA",
-                    "_Unwind_VRS_Get",
-                    "_Unwind_VRS_Pop",
-                    "_Unwind_VRS_Set",
-                    "__aeabi_unwind_cpp_pr0",
-                    "__aeabi_unwind_cpp_pr1",
-                    "__aeabi_unwind_cpp_pr2",
-                    "__gnu_Unwind_Backtrace",
-                    "__gnu_Unwind_ForcedUnwind",
-                    "__gnu_Unwind_RaiseException",
-                    "__gnu_Unwind_Resume",
-                    "__gnu_Unwind_Resume_or_Rethrow",
-
-                    // libunwind.o
-                    "_Unwind_Backtrace",
-                    "_Unwind_ForcedUnwind",
-                    "_Unwind_RaiseException",
-                    "_Unwind_Resume",
-                    "_Unwind_Resume_or_Rethrow",
-                    "___Unwind_Backtrace",
-                    "___Unwind_ForcedUnwind",
-                    "___Unwind_RaiseException",
-                    "___Unwind_Resume",
-                    "___Unwind_Resume_or_Rethrow",
-                    "__gnu_Unwind_Restore_VFP",
-                    "__gnu_Unwind_Restore_VFP_D",
-                    "__gnu_Unwind_Restore_VFP_D_16_to_31",
-                    "__gnu_Unwind_Restore_WMMXC",
-                    "__gnu_Unwind_Restore_WMMXD",
-                    "__gnu_Unwind_Save_VFP",
-                    "__gnu_Unwind_Save_VFP_D",
-                    "__gnu_Unwind_Save_VFP_D_16_to_31",
-                    "__gnu_Unwind_Save_WMMXC",
-                    "__gnu_Unwind_Save_WMMXD",
-                    "__restore_core_regs",
-                    "restore_core_regs",
-
-                    // pr-support.o
-                    "_Unwind_GetDataRelBase",
-                    "_Unwind_GetLanguageSpecificData",
-                    "_Unwind_GetRegionStart",
-                    "_Unwind_GetTextRelBase",
-                    "__gnu_unwind_execute",
-                    "__gnu_unwind_frame",
-                ],
-            },
+            repack_objects_to_keep: ["unwind-arm.o", "libunwind.o", "pr-support.o"],
         },
         arm64: {
             src: "prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/lib/gcc/aarch64-linux-android/4.9.x/libgcc.a",
+            repack_objects_to_keep: ["unwind-dw2.o", "unwind-dw2-fde-dip.o"],
         },
         x86: {
             src: "prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/lib/gcc/x86_64-linux-android/4.9.x/32/libgcc.a",
-
+            repack_objects_to_keep: ["unwind-dw2.o", "unwind-dw2-fde-dip.o"],
         },
         x86_64: {
             src: "prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/lib/gcc/x86_64-linux-android/4.9.x/libgcc.a",
+            repack_objects_to_keep: ["unwind-dw2.o", "unwind-dw2-fde-dip.o"],
         },
     },
-    strip: {
-        keep_symbols_list: [
-            // unwind-dw2.o
-            "_Unwind_Backtrace",
-            "_Unwind_DeleteException",
-            "_Unwind_FindEnclosingFunction",
-            "_Unwind_ForcedUnwind",
-            "_Unwind_GetCFA",
-            "_Unwind_GetDataRelBase",
-            "_Unwind_GetGR",
-            "_Unwind_GetIP",
-            "_Unwind_GetIPInfo",
-            "_Unwind_GetLanguageSpecificData",
-            "_Unwind_GetRegionStart",
-            "_Unwind_GetTextRelBase",
-            "_Unwind_RaiseException",
-            "_Unwind_Resume",
-            "_Unwind_Resume_or_Rethrow",
-            "_Unwind_SetGR",
-            "_Unwind_SetIP",
-            "__frame_state_for",
-
-            // unwind-dw2-fde-dip.o
-            "_Unwind_Find_FDE",
-            "__deregister_frame",
-            "__deregister_frame_info",
-            "__deregister_frame_info_bases",
-            "__register_frame",
-            "__register_frame_info",
-            "__register_frame_info_bases",
-            "__register_frame_info_table",
-            "__register_frame_info_table_bases",
-            "__register_frame_table",
-        ],
-    },
 }
 
 toolchain_library {
diff --git a/OWNERS b/OWNERS
index 797229f..4ae045d 100644
--- a/OWNERS
+++ b/OWNERS
@@ -4,4 +4,3 @@
 per-file clang.go,global.go = srhines@google.com, chh@google.com, pirama@google.com, yikong@google.com
 per-file tidy.go = srhines@google.com, chh@google.com
 per-file lto.go,pgo.go = srhines@google.com, pirama@google.com, yikong@google.com
-per-file rust/config/whitelist.go = chh@google.com, ivanlozano@google.com, jeffv@google.com, jgalenson@google.com, srhines@google.com
diff --git a/android/config.go b/android/config.go
index e208dcd..90e7ed1 100644
--- a/android/config.go
+++ b/android/config.go
@@ -113,8 +113,6 @@
 	captureBuild      bool // true for tests, saves build parameters for each module
 	ignoreEnvironment bool // true for tests, returns empty from all Getenv calls
 
-	targetOpenJDK9 bool // Target 1.9
-
 	stopBefore bootstrap.StopBefore
 
 	OncePer
@@ -392,13 +390,9 @@
 func (c *config) fromEnv() error {
 	switch c.Getenv("EXPERIMENTAL_JAVA_LANGUAGE_LEVEL_9") {
 	case "", "true":
-		// Use -source 9 -target 9. This is the default.
-		c.targetOpenJDK9 = true
-	case "false":
-		// Use -source 8 -target 8. This is the legacy behaviour.
-		c.targetOpenJDK9 = false
+		// Do nothing
 	default:
-		return fmt.Errorf(`Invalid value for EXPERIMENTAL_JAVA_LANGUAGE_LEVEL_9, should be "", "true", or "false"`)
+		return fmt.Errorf("The environment variable EXPERIMENTAL_JAVA_LANGUAGE_LEVEL_9 is no longer supported. Java language level 9 is now the global default.")
 	}
 
 	return nil
@@ -779,11 +773,6 @@
 	return c.XrefCorpusName() != ""
 }
 
-// Returns true if -source 1.9 -target 1.9 is being passed to javac
-func (c *config) TargetOpenJDK9() bool {
-	return c.targetOpenJDK9
-}
-
 func (c *config) ClangTidy() bool {
 	return Bool(c.productVariables.ClangTidy)
 }
diff --git a/android/prebuilt.go b/android/prebuilt.go
index 8559df9..0ee1201 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -195,6 +195,10 @@
 	return source == nil || !source.Enabled()
 }
 
+func (p *Prebuilt) SourceExists() bool {
+	return p.properties.SourceExists
+}
+
 func (p *Prebuilt) checkSingleSourceProperties() {
 	if !p.srcProps.IsValid() || p.srcField.Name == "" {
 		panic(fmt.Errorf("invalid single source prebuilt %+v", p))
@@ -215,7 +219,3 @@
 	}
 	return value.String()
 }
-
-func (p *Prebuilt) SourceExists() bool {
-	return p.properties.SourceExists
-}
diff --git a/androidmk/Android.bp b/androidmk/Android.bp
index 79fe530..4110073 100644
--- a/androidmk/Android.bp
+++ b/androidmk/Android.bp
@@ -19,12 +19,23 @@
 blueprint_go_binary {
     name: "androidmk",
     srcs: [
-        "cmd/androidmk/android.go",
-        "cmd/androidmk/androidmk.go",
-        "cmd/androidmk/values.go",
+        "cmd/androidmk.go",
+    ],
+    deps: [
+        "androidmk-lib",
+    ],
+}
+
+bootstrap_go_package {
+    name: "androidmk-lib",
+    pkgPath: "android/soong/androidmk/androidmk",
+    srcs: [
+        "androidmk/android.go",
+        "androidmk/androidmk.go",
+        "androidmk/values.go",
     ],
     testSrcs: [
-        "cmd/androidmk/androidmk_test.go",
+        "androidmk/androidmk_test.go",
     ],
     deps: [
         "androidmk-parser",
diff --git a/androidmk/cmd/androidmk/android.go b/androidmk/androidmk/android.go
similarity index 99%
rename from androidmk/cmd/androidmk/android.go
rename to androidmk/androidmk/android.go
index fcadd03..be52879 100644
--- a/androidmk/cmd/androidmk/android.go
+++ b/androidmk/androidmk/android.go
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package main
+package androidmk
 
 import (
 	"android/soong/android"
diff --git a/androidmk/cmd/androidmk/androidmk.go b/androidmk/androidmk/androidmk.go
similarity index 93%
rename from androidmk/cmd/androidmk/androidmk.go
rename to androidmk/androidmk/androidmk.go
index d2a84d1..9d0c3ac 100644
--- a/androidmk/cmd/androidmk/androidmk.go
+++ b/androidmk/androidmk/androidmk.go
@@ -12,14 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package main
+package androidmk
 
 import (
 	"bytes"
-	"flag"
 	"fmt"
-	"io/ioutil"
-	"os"
 	"strings"
 	"text/scanner"
 
@@ -30,13 +27,6 @@
 	bpparser "github.com/google/blueprint/parser"
 )
 
-var usage = func() {
-	fmt.Fprintf(os.Stderr, "usage: androidmk [flags] <inputFile>\n"+
-		"\nandroidmk parses <inputFile> as an Android.mk file and attempts to output an analogous Android.bp file (to standard out)\n")
-	flag.PrintDefaults()
-	os.Exit(1)
-}
-
 // TODO: non-expanded variables with expressions
 
 type bpFile struct {
@@ -118,31 +108,7 @@
 	eq   bool
 }
 
-func main() {
-	flag.Usage = usage
-	flag.Parse()
-	if len(flag.Args()) != 1 {
-		usage()
-	}
-	filePathToRead := flag.Arg(0)
-	b, err := ioutil.ReadFile(filePathToRead)
-	if err != nil {
-		fmt.Println(err.Error())
-		return
-	}
-
-	output, errs := convertFile(os.Args[1], bytes.NewBuffer(b))
-	if len(errs) > 0 {
-		for _, err := range errs {
-			fmt.Fprintln(os.Stderr, "ERROR: ", err)
-		}
-		os.Exit(1)
-	}
-
-	fmt.Print(output)
-}
-
-func convertFile(filename string, buffer *bytes.Buffer) (string, []error) {
+func ConvertFile(filename string, buffer *bytes.Buffer) (string, []error) {
 	p := mkparser.NewParser(filename, buffer)
 
 	nodes, errs := p.Parse()
diff --git a/androidmk/cmd/androidmk/androidmk_test.go b/androidmk/androidmk/androidmk_test.go
similarity index 99%
rename from androidmk/cmd/androidmk/androidmk_test.go
rename to androidmk/androidmk/androidmk_test.go
index dbb7fde..7e1a72c 100644
--- a/androidmk/cmd/androidmk/androidmk_test.go
+++ b/androidmk/androidmk/androidmk_test.go
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package main
+package androidmk
 
 import (
 	"bytes"
@@ -1350,7 +1350,7 @@
 			t.Error(err)
 		}
 
-		got, errs := convertFile(fmt.Sprintf("<testcase %d>", i), bytes.NewBufferString(test.in))
+		got, errs := ConvertFile(fmt.Sprintf("<testcase %d>", i), bytes.NewBufferString(test.in))
 		if len(errs) > 0 {
 			t.Errorf("Unexpected errors: %q", errs)
 			continue
diff --git a/androidmk/cmd/androidmk/values.go b/androidmk/androidmk/values.go
similarity index 99%
rename from androidmk/cmd/androidmk/values.go
rename to androidmk/androidmk/values.go
index 90f2e74..6b18a65 100644
--- a/androidmk/cmd/androidmk/values.go
+++ b/androidmk/androidmk/values.go
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package main
+package androidmk
 
 import (
 	"fmt"
diff --git a/androidmk/cmd/androidmk.go b/androidmk/cmd/androidmk.go
new file mode 100644
index 0000000..00488eb
--- /dev/null
+++ b/androidmk/cmd/androidmk.go
@@ -0,0 +1,56 @@
+// 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 (
+	"bytes"
+	"flag"
+	"fmt"
+	"io/ioutil"
+	"os"
+
+	"android/soong/androidmk/androidmk"
+)
+
+var usage = func() {
+	fmt.Fprintf(os.Stderr, "usage: androidmk [flags] <inputFile>\n"+
+		"\nandroidmk parses <inputFile> as an Android.mk file and attempts to output an analogous Android.bp file (to standard out)\n")
+	flag.PrintDefaults()
+	os.Exit(1)
+}
+
+func main() {
+	flag.Usage = usage
+	flag.Parse()
+	if len(flag.Args()) != 1 {
+		usage()
+	}
+	filePathToRead := flag.Arg(0)
+	b, err := ioutil.ReadFile(filePathToRead)
+	if err != nil {
+		fmt.Println(err.Error())
+		return
+	}
+
+	output, errs := androidmk.ConvertFile(os.Args[1], bytes.NewBuffer(b))
+	if len(errs) > 0 {
+		for _, err := range errs {
+			fmt.Fprintln(os.Stderr, "ERROR: ", err)
+		}
+		os.Exit(1)
+	}
+
+	fmt.Print(output)
+}
diff --git a/androidmk/partner_androidmk/Android.bp b/androidmk/partner_androidmk/Android.bp
new file mode 100644
index 0000000..532116a
--- /dev/null
+++ b/androidmk/partner_androidmk/Android.bp
@@ -0,0 +1,49 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//
+// Sample project for creating an extended androidmk
+//
+
+blueprint_go_binary {
+    name: "partner_androidmk",
+    srcs: [
+        "partner_androidmk/androidmk.go",
+    ],
+    testSrcs: [
+        "partner_androidmk/androidmk_test.go",
+    ],
+    deps: [
+        "androidmk-lib",
+        "partner_bpfix_extensions",
+    ],
+}
+
+blueprint_go_binary {
+    name: "partner_bpfix",
+    srcs: [
+        "partner_bpfix/bpfix.go",
+    ],
+    deps: [
+        "bpfix-cmd",
+        "partner_bpfix_extensions",
+    ],
+}
+
+bootstrap_go_package {
+    name: "partner_bpfix_extensions",
+    pkgPath: "partner/android/bpfix/extensions",
+    srcs: ["fixes/headers.go"],
+    deps: ["bpfix-lib"],
+}
diff --git a/androidmk/partner_androidmk/fixes/headers.go b/androidmk/partner_androidmk/fixes/headers.go
new file mode 100644
index 0000000..169dab6
--- /dev/null
+++ b/androidmk/partner_androidmk/fixes/headers.go
@@ -0,0 +1,120 @@
+package extensions
+
+import (
+	"strings"
+
+	"github.com/google/blueprint/parser"
+
+	"android/soong/bpfix/bpfix"
+)
+
+var fixSteps = bpfix.FixStepsExtension{
+	Name: "partner-include-dirs",
+	Steps: []bpfix.FixStep{
+		{
+			Name: "fixIncludeDirs",
+			Fix:  fixIncludeDirs,
+		},
+	},
+}
+
+func init() {
+	bpfix.RegisterFixStepExtension(&fixSteps)
+}
+
+type includeDirFix struct {
+	libName  string
+	libType  string
+	variable string
+	subdir   string
+}
+
+var commonIncludeDirs = []includeDirFix{
+	{
+		libName:  "my_header_lib",
+		libType:  "header_libs",
+		variable: "TARGET_OUT_HEADERS",
+		subdir:   "/my_headers",
+	},
+}
+
+func findHeaderLib(e parser.Expression) (*includeDirFix, bool) {
+	if op, ok := e.(*parser.Operator); ok {
+		if op.Operator != '+' {
+			return nil, false
+		}
+		arg0, ok := op.Args[0].(*parser.Variable)
+		arg1, ok1 := op.Args[1].(*parser.String)
+		if !ok || !ok1 {
+			return nil, false
+		}
+		for _, lib := range commonIncludeDirs {
+			if arg0.Name == lib.variable && arg1.Value == lib.subdir {
+				return &lib, true
+			}
+		}
+	}
+	return nil, false
+}
+func searchThroughOperatorList(mod *parser.Module, e parser.Expression) {
+	if list, ok := e.(*parser.List); ok {
+		newList := make([]parser.Expression, 0, len(list.Values))
+		for _, item := range list.Values {
+			if lib, found := findHeaderLib(item); found {
+				if lib.libName != "" {
+					addLibrary(mod, lib.libType, lib.libName)
+				}
+			} else {
+				newList = append(newList, item)
+			}
+		}
+		list.Values = newList
+	}
+	if op, ok := e.(*parser.Operator); ok {
+		searchThroughOperatorList(mod, op.Args[0])
+		searchThroughOperatorList(mod, op.Args[1])
+	}
+}
+func getLiteralListProperty(mod *parser.Module, name string) (list *parser.List, found bool) {
+	prop, ok := mod.GetProperty(name)
+	if !ok {
+		return nil, false
+	}
+	list, ok = prop.Value.(*parser.List)
+	return list, ok
+}
+func addLibrary(mod *parser.Module, libType string, libName string) {
+	var list, ok = getLiteralListProperty(mod, libType)
+	if !ok {
+		list = new(parser.List)
+		prop := new(parser.Property)
+		prop.Name = libType
+		prop.Value = list
+		mod.Properties = append(mod.Properties, prop)
+	} else {
+		for _, v := range list.Values {
+			if stringValue, ok := v.(*parser.String); ok && stringValue.Value == libName {
+				return
+			}
+		}
+	}
+	lib := new(parser.String)
+	lib.Value = libName
+	list.Values = append(list.Values, lib)
+}
+func fixIncludeDirs(f *bpfix.Fixer) error {
+	tree := f.Tree()
+	for _, def := range tree.Defs {
+		mod, ok := def.(*parser.Module)
+		if !ok {
+			continue
+		}
+		if !strings.HasPrefix(mod.Type, "cc_") {
+			continue
+		}
+		if prop, ok := mod.GetProperty("include_dirs"); ok {
+			searchThroughOperatorList(mod, prop.Value)
+		}
+	}
+	return nil
+}
diff --git a/androidmk/partner_androidmk/partner_androidmk/androidmk.go b/androidmk/partner_androidmk/partner_androidmk/androidmk.go
new file mode 100644
index 0000000..af8cdf3
--- /dev/null
+++ b/androidmk/partner_androidmk/partner_androidmk/androidmk.go
@@ -0,0 +1,58 @@
+// 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 (
+	"bytes"
+	"flag"
+	"fmt"
+	"io/ioutil"
+	"os"
+
+	"android/soong/androidmk/androidmk"
+
+	_ "partner/android/bpfix/extensions"
+)
+
+var usage = func() {
+	fmt.Fprintf(os.Stderr, "usage: %s [flags] <inputFile>\n"+
+		"\n%s parses <inputFile> as an Android.mk file and attempts to output an analogous Android.bp file (to standard out)\n", os.Args[0], os.Args[0])
+	flag.PrintDefaults()
+	os.Exit(1)
+}
+
+func main() {
+	flag.Usage = usage
+	flag.Parse()
+	if len(flag.Args()) != 1 {
+		usage()
+	}
+	filePathToRead := flag.Arg(0)
+	b, err := ioutil.ReadFile(filePathToRead)
+	if err != nil {
+		fmt.Println(err.Error())
+		return
+	}
+
+	output, errs := androidmk.ConvertFile(os.Args[1], bytes.NewBuffer(b))
+	if len(errs) > 0 {
+		for _, err := range errs {
+			fmt.Fprintln(os.Stderr, "ERROR: ", err)
+		}
+		os.Exit(1)
+	}
+
+	fmt.Print(output)
+}
diff --git a/androidmk/partner_androidmk/partner_androidmk/androidmk_test.go b/androidmk/partner_androidmk/partner_androidmk/androidmk_test.go
new file mode 100644
index 0000000..ff04e88
--- /dev/null
+++ b/androidmk/partner_androidmk/partner_androidmk/androidmk_test.go
@@ -0,0 +1,73 @@
+// Copyright 2016 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 (
+	"bytes"
+	"fmt"
+	"strings"
+	"testing"
+
+	"android/soong/androidmk/androidmk"
+	"android/soong/bpfix/bpfix"
+
+	_ "partner/android/bpfix/extensions"
+)
+
+var testCases = []struct {
+	desc     string
+	in       string
+	expected string
+}{
+	{
+		desc: "headers replacement",
+		in: `
+include $(CLEAR_VARS)
+LOCAL_MODULE := test
+LOCAL_SRC_FILES := a.c
+LOCAL_C_INCLUDES := test1 $(TARGET_OUT_HEADERS)/my_headers test2
+include $(BUILD_SHARED_LIBRARY)`,
+		expected: `
+cc_library_shared {
+    name: "test",
+	srcs: ["a.c"],
+	include_dirs: [
+		"test1",
+
+		"test2",
+	],
+	header_libs: ["my_header_lib"]
+}`,
+	},
+}
+
+func TestEndToEnd(t *testing.T) {
+	for i, test := range testCases {
+		expected, err := bpfix.Reformat(test.expected)
+		if err != nil {
+			t.Error(err)
+		}
+
+		got, errs := androidmk.ConvertFile(fmt.Sprintf("<testcase %d>", i), bytes.NewBufferString(test.in))
+		if len(errs) > 0 {
+			t.Errorf("Unexpected errors: %q", errs)
+			continue
+		}
+
+		if got != expected {
+			t.Errorf("failed testcase '%s'\ninput:\n%s\n\nexpected:\n%s\ngot:\n%s\n", test.desc, strings.TrimSpace(test.in), expected, got)
+		}
+	}
+}
diff --git a/androidmk/partner_androidmk/partner_bpfix/bpfix.go b/androidmk/partner_androidmk/partner_bpfix/bpfix.go
new file mode 100644
index 0000000..2c8e0a8
--- /dev/null
+++ b/androidmk/partner_androidmk/partner_bpfix/bpfix.go
@@ -0,0 +1,27 @@
+// 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.
+
+// This file provides a command-line interface to bpfix
+
+package main
+
+import (
+	"android/soong/bpfix/bpfix/cmd"
+
+	_ "partner/android/bpfix/extensions"
+)
+
+func main() {
+	cmd.Run()
+}
diff --git a/apex/apex.go b/apex/apex.go
index c9b989a..629cbbf 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -126,11 +126,15 @@
 	}, "image_content_file", "whitelisted_files_file", "apex_module_name")
 )
 
-var imageApexSuffix = ".apex"
-var zipApexSuffix = ".zipapex"
+const (
+	imageApexSuffix = ".apex"
+	zipApexSuffix   = ".zipapex"
 
-var imageApexType = "image"
-var zipApexType = "zip"
+	imageApexType = "image"
+	zipApexType   = "zip"
+
+	vndkApexNamePrefix = "com.android.vndk.v"
+)
 
 type dependencyTag struct {
 	blueprint.BaseDependencyTag
@@ -182,10 +186,7 @@
 	android.RegisterModuleType("apex_defaults", defaultsFactory)
 	android.RegisterModuleType("prebuilt_apex", PrebuiltFactory)
 
-	android.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
-		ctx.TopDown("apex_vndk_gather", apexVndkGatherMutator).Parallel()
-		ctx.BottomUp("apex_vndk_add_deps", apexVndkAddDepsMutator).Parallel()
-	})
+	android.PreDepsMutators(RegisterPreDepsMutators)
 	android.PostDepsMutators(RegisterPostDepsMutators)
 
 	android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) {
@@ -195,6 +196,11 @@
 	})
 }
 
+func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) {
+	ctx.TopDown("apex_vndk", apexVndkMutator).Parallel()
+	ctx.BottomUp("apex_vndk_deps", apexVndkDepsMutator).Parallel()
+}
+
 func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
 	ctx.TopDown("apex_deps", apexDepsMutator)
 	ctx.BottomUp("apex", apexMutator).Parallel()
@@ -207,44 +213,39 @@
 	vndkApexListMutex sync.Mutex
 )
 
-func vndkApexList(config android.Config) map[string]*apexBundle {
+func vndkApexList(config android.Config) map[string]string {
 	return config.Once(vndkApexListKey, func() interface{} {
-		return map[string]*apexBundle{}
-	}).(map[string]*apexBundle)
+		return map[string]string{}
+	}).(map[string]string)
 }
 
-// apexVndkGatherMutator gathers "apex_vndk" modules and puts them in a map with vndk_version as a key.
-func apexVndkGatherMutator(mctx android.TopDownMutatorContext) {
+func apexVndkMutator(mctx android.TopDownMutatorContext) {
 	if ab, ok := mctx.Module().(*apexBundle); ok && ab.vndkApex {
 		if ab.IsNativeBridgeSupported() {
 			mctx.PropertyErrorf("native_bridge_supported", "%q doesn't support native bridge binary.", mctx.ModuleType())
 		}
 
-		vndkVersion := proptools.String(ab.vndkProperties.Vndk_version)
+		vndkVersion := ab.vndkVersion(mctx.DeviceConfig())
+		// Ensure VNDK APEX mount point is formatted as com.android.vndk.v###
+		ab.properties.Apex_name = proptools.StringPtr(vndkApexNamePrefix + vndkVersion)
 
+		// vndk_version should be unique
 		vndkApexListMutex.Lock()
 		defer vndkApexListMutex.Unlock()
 		vndkApexList := vndkApexList(mctx.Config())
 		if other, ok := vndkApexList[vndkVersion]; ok {
-			mctx.PropertyErrorf("vndk_version", "%v is already defined in %q", vndkVersion, other.BaseModuleName())
+			mctx.PropertyErrorf("vndk_version", "%v is already defined in %q", vndkVersion, other)
 		}
-		vndkApexList[vndkVersion] = ab
+		vndkApexList[vndkVersion] = mctx.ModuleName()
 	}
 }
 
-// apexVndkAddDepsMutator adds (reverse) dependencies from vndk libs to apex_vndk modules.
-// It filters only libs with matching targets.
-func apexVndkAddDepsMutator(mctx android.BottomUpMutatorContext) {
-	if cc, ok := mctx.Module().(*cc.Module); ok && cc.IsVndkOnSystem() {
+func apexVndkDepsMutator(mctx android.BottomUpMutatorContext) {
+	if m, ok := mctx.Module().(*cc.Module); ok && cc.IsForVndkApex(mctx, m) {
+		vndkVersion := m.VndkVersion()
 		vndkApexList := vndkApexList(mctx.Config())
-		if ab, ok := vndkApexList[cc.VndkVersion()]; ok {
-			targetArch := cc.Target().String()
-			for _, target := range ab.MultiTargets() {
-				if target.String() == targetArch {
-					mctx.AddReverseDependency(mctx.Module(), sharedLibTag, ab.Name())
-					break
-				}
-			}
+		if vndkApex, ok := vndkApexList[vndkVersion]; ok {
+			mctx.AddReverseDependency(mctx.Module(), sharedLibTag, vndkApex)
 		}
 	}
 }
@@ -615,6 +616,12 @@
 
 	// intermediate path for apex_manifest.json
 	manifestOut android.WritablePath
+
+	// list of commands to create symlinks for backward compatibility
+	// these commands will be attached as LOCAL_POST_INSTALL_CMD to
+	// apex package itself(for unflattened build) or apex_manifest.json(for flattened build)
+	// so that compat symlinks are always installed regardless of TARGET_FLATTEN_APEX setting.
+	compatSymlinks []string
 }
 
 func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext,
@@ -654,7 +661,6 @@
 }
 
 func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
-
 	targets := ctx.MultiTargets()
 	config := ctx.DeviceConfig()
 
@@ -824,6 +830,9 @@
 }
 
 func (a *apexBundle) getImageVariation(config android.DeviceConfig) string {
+	if a.vndkApex {
+		return "vendor." + a.vndkVersion(config)
+	}
 	if config.VndkVersion() != "" && proptools.Bool(a.properties.Use_vendor) {
 		return "vendor." + config.PlatformVndkVersion()
 	} else {
@@ -1244,7 +1253,7 @@
 	// prepend the name of this APEX to the module names. These names will be the names of
 	// modules that will be defined if the APEX is flattened.
 	for i := range filesInfo {
-		filesInfo[i].moduleName = ctx.ModuleName() + "." + filesInfo[i].moduleName
+		filesInfo[i].moduleName = filesInfo[i].moduleName + "." + ctx.ModuleName()
 	}
 
 	a.installDir = android.PathForModuleInstall(ctx, "apex")
@@ -1295,6 +1304,8 @@
 		a.buildUnflattenedApex(ctx, imageApex)
 		a.buildFlattenedApex(ctx)
 	}
+
+	a.compatSymlinks = makeCompatSymlinks(apexName, ctx)
 }
 
 func (a *apexBundle) buildNoticeFile(ctx android.ModuleContext, apexFileName string) android.OptionalPath {
@@ -1570,7 +1581,7 @@
 	if a.installable() {
 		// For flattened APEX, do nothing but make sure that apex_manifest.json and apex_pubkey are also copied along
 		// with other ordinary files.
-		a.filesInfo = append(a.filesInfo, apexFile{a.manifestOut, ctx.ModuleName() + ".apex_manifest.json", ".", etc, nil, nil})
+		a.filesInfo = append(a.filesInfo, apexFile{a.manifestOut, "apex_manifest.json." + ctx.ModuleName(), ".", etc, nil, nil})
 
 		// rename to apex_pubkey
 		copiedPubkey := android.PathForModuleOut(ctx, "apex_pubkey")
@@ -1579,7 +1590,7 @@
 			Input:  a.public_key_file,
 			Output: copiedPubkey,
 		})
-		a.filesInfo = append(a.filesInfo, apexFile{copiedPubkey, ctx.ModuleName() + ".apex_pubkey", ".", etc, nil, nil})
+		a.filesInfo = append(a.filesInfo, apexFile{copiedPubkey, "apex_pubkey." + ctx.ModuleName(), ".", etc, nil, nil})
 
 		if ctx.Config().FlattenApex() {
 			apexName := proptools.StringDefault(a.properties.Apex_name, ctx.ModuleName())
@@ -1712,6 +1723,10 @@
 			fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_cc_prebuilt.mk")
 		} else {
 			fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", fi.builtFile.Base())
+			// For flattened apexes, compat symlinks are attached to apex_manifest.json which is guaranteed for every apex
+			if !a.isFlattenedVariant() && fi.builtFile.Base() == "apex_manifest.json" && len(a.compatSymlinks) > 0 {
+				fmt.Fprintln(w, "LOCAL_POST_INSTALL_CMD :=", strings.Join(a.compatSymlinks, " && "))
+			}
 			fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
 		}
 	}
@@ -1762,10 +1777,16 @@
 				if len(a.externalDeps) > 0 {
 					fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES +=", strings.Join(a.externalDeps, " "))
 				}
+				var postInstallCommands []string
 				if a.prebuiltFileToDelete != "" {
-					fmt.Fprintln(w, "LOCAL_POST_INSTALL_CMD :=", "rm -rf "+
+					postInstallCommands = append(postInstallCommands, "rm -rf "+
 						filepath.Join(a.installDir.ToMakePath().String(), a.prebuiltFileToDelete))
 				}
+				// For unflattened apexes, compat symlinks are attached to apex package itself as LOCAL_POST_INSTALL_CMD
+				postInstallCommands = append(postInstallCommands, a.compatSymlinks...)
+				if len(postInstallCommands) > 0 {
+					fmt.Fprintln(w, "LOCAL_POST_INSTALL_CMD :=", strings.Join(postInstallCommands, " && "))
+				}
 				fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
 
 				if apexType == imageApex {
@@ -1819,19 +1840,18 @@
 		}{
 			proptools.StringPtr("both"),
 		})
-
-		vndkVersion := proptools.StringDefault(bundle.vndkProperties.Vndk_version, "current")
-		if vndkVersion == "current" {
-			vndkVersion = ctx.DeviceConfig().PlatformVndkVersion()
-			bundle.vndkProperties.Vndk_version = proptools.StringPtr(vndkVersion)
-		}
-
-		// Ensure VNDK APEX mount point is formatted as com.android.vndk.v###
-		bundle.properties.Apex_name = proptools.StringPtr("com.android.vndk.v" + vndkVersion)
 	})
 	return bundle
 }
 
+func (a *apexBundle) vndkVersion(config android.DeviceConfig) string {
+	vndkVersion := proptools.StringDefault(a.vndkProperties.Vndk_version, "current")
+	if vndkVersion == "current" {
+		vndkVersion = config.PlatformVndkVersion()
+	}
+	return vndkVersion
+}
+
 //
 // Defaults
 //
@@ -1997,6 +2017,8 @@
 	if p.installable() {
 		ctx.InstallFile(p.installDir, p.installFilename, p.inputApex)
 	}
+
+	// TODO(b/143192278): Add compat symlinks for prebuilt_apex
 }
 
 func (p *Prebuilt) Prebuilt() *android.Prebuilt {
@@ -2031,3 +2053,30 @@
 	android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
 	return module
 }
+
+func makeCompatSymlinks(apexName string, ctx android.ModuleContext) (symlinks []string) {
+	// small helper to add symlink commands
+	addSymlink := func(target, dir, linkName string) {
+		outDir := filepath.Join("$(PRODUCT_OUT)", dir)
+		link := filepath.Join(outDir, linkName)
+		symlinks = append(symlinks, "mkdir -p "+outDir+" && rm -rf "+link+" && ln -sf "+target+" "+link)
+	}
+
+	// TODO(b/142911355): [VNDK APEX] Fix hard-coded references to /system/lib/vndk
+	// When all hard-coded references are fixed, remove symbolic links
+	// Note that  we should keep following symlinks for older VNDKs (<=29)
+	// Since prebuilt vndk libs still depend on system/lib/vndk path
+	if strings.HasPrefix(apexName, vndkApexNamePrefix) {
+		// the name of vndk apex is formatted "com.android.vndk.v" + version
+		vndkVersion := strings.TrimPrefix(apexName, vndkApexNamePrefix)
+		if ctx.Config().Android64() {
+			addSymlink("/apex/"+apexName+"/lib64", "/system/lib64", "vndk-sp-"+vndkVersion)
+			addSymlink("/apex/"+apexName+"/lib64", "/system/lib64", "vndk-"+vndkVersion)
+		}
+		if !ctx.Config().Android64() || ctx.DeviceConfig().DeviceSecondaryArch() != "" {
+			addSymlink("/apex/"+apexName+"/lib", "/system/lib", "vndk-sp-"+vndkVersion)
+			addSymlink("/apex/"+apexName+"/lib", "/system/lib", "vndk-"+vndkVersion)
+		}
+	}
+	return
+}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 7a51bb6..cf38caa 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -18,6 +18,7 @@
 	"io/ioutil"
 	"os"
 	"reflect"
+	"sort"
 	"strings"
 	"testing"
 
@@ -85,6 +86,10 @@
 	}
 }
 
+func withBinder32bit(fs map[string][]byte, config android.Config) {
+	config.TestProductVariables.Binder32bit = proptools.BoolPtr(true)
+}
+
 func testApexContext(t *testing.T, bp string, handlers ...testCustomizer) (*android.TestContext, android.Config) {
 	config := android.TestArchConfig(buildDir, nil)
 	config.TestProductVariables.DeviceVndkVersion = proptools.StringPtr("current")
@@ -132,13 +137,10 @@
 		ctx.BottomUp("test_per_src", cc.TestPerSrcMutator).Parallel()
 		ctx.BottomUp("version", cc.VersionMutator).Parallel()
 		ctx.BottomUp("begin", cc.BeginMutator).Parallel()
-		ctx.TopDown("apex_vndk_gather", apexVndkGatherMutator)
-		ctx.BottomUp("apex_vndk_add_deps", apexVndkAddDepsMutator)
 	})
+	ctx.PreDepsMutators(RegisterPreDepsMutators)
+	ctx.PostDepsMutators(RegisterPostDepsMutators)
 	ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
-		ctx.TopDown("apex_deps", apexDepsMutator)
-		ctx.BottomUp("apex", apexMutator)
-		ctx.BottomUp("apex_uses", apexUsesMutator)
 		ctx.TopDown("prebuilt_select", android.PrebuiltSelectModuleMutator).Parallel()
 		ctx.BottomUp("prebuilt_postdeps", android.PrebuiltPostDepsMutator).Parallel()
 	})
@@ -1207,16 +1209,22 @@
 	mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_core_static").Rule("cc").Args["cFlags"]
 	ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__=myapex")
 	ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__=otherapex")
+	ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
+	ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__")
 
 	// APEX variant has __ANDROID_APEX__=<apexname> defined
 	mylibCFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_core_static_myapex").Rule("cc").Args["cFlags"]
 	ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__=myapex")
 	ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__=otherapex")
+	ensureContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
+	ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__")
 
 	// APEX variant has __ANDROID_APEX__=<apexname> defined
 	mylibCFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_core_static_otherapex").Rule("cc").Args["cFlags"]
 	ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__=myapex")
 	ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__=otherapex")
+	ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
+	ensureContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__")
 }
 
 func TestHeaderLibsDependency(t *testing.T) {
@@ -1267,6 +1275,74 @@
 	ensureContains(t, cFlags, "-Imy_include")
 }
 
+func ensureExactContents(t *testing.T, ctx *android.TestContext, moduleName string, files []string) {
+	t.Helper()
+	apexRule := ctx.ModuleForTests(moduleName, "android_common_"+moduleName).Rule("apexRule")
+	copyCmds := apexRule.Args["copy_commands"]
+	imageApexDir := "/image.apex/"
+	dstFiles := []string{}
+	for _, cmd := range strings.Split(copyCmds, "&&") {
+		cmd = strings.TrimSpace(cmd)
+		if cmd == "" {
+			continue
+		}
+		terms := strings.Split(cmd, " ")
+		switch terms[0] {
+		case "mkdir":
+		case "cp":
+			if len(terms) != 3 {
+				t.Fatal("copyCmds contains invalid cp command", cmd)
+			}
+			dst := terms[2]
+			index := strings.Index(dst, imageApexDir)
+			if index == -1 {
+				t.Fatal("copyCmds should copy a file to image.apex/", cmd)
+			}
+			dstFile := dst[index+len(imageApexDir):]
+			dstFiles = append(dstFiles, dstFile)
+		default:
+			t.Fatalf("copyCmds should contain mkdir/cp commands only: %q", cmd)
+		}
+	}
+	sort.Strings(dstFiles)
+	sort.Strings(files)
+	missing := []string{}
+	surplus := []string{}
+	i := 0
+	j := 0
+	for i < len(dstFiles) && j < len(files) {
+		if dstFiles[i] == files[j] {
+			i++
+			j++
+		} else if dstFiles[i] < files[j] {
+			surplus = append(surplus, dstFiles[i])
+			i++
+		} else {
+			missing = append(missing, files[j])
+			j++
+		}
+	}
+	if i < len(dstFiles) {
+		surplus = append(surplus, dstFiles[i:]...)
+	}
+	if j < len(files) {
+		missing = append(missing, files[j:]...)
+	}
+
+	failed := false
+	if len(surplus) > 0 {
+		t.Log("surplus files", surplus)
+		failed = true
+	}
+	if len(missing) > 0 {
+		t.Log("missing files", missing)
+		failed = true
+	}
+	if failed {
+		t.Fail()
+	}
+}
+
 func TestVndkApexCurrent(t *testing.T) {
 	ctx, _ := testApex(t, `
 		apex_vndk {
@@ -1305,12 +1381,12 @@
 		}
 	`)
 
-	apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
-	copyCmds := apexRule.Args["copy_commands"]
-	ensureContains(t, copyCmds, "image.apex/lib/libvndk.so")
-	ensureContains(t, copyCmds, "image.apex/lib/libvndksp.so")
-	ensureContains(t, copyCmds, "image.apex/lib64/libvndk.so")
-	ensureContains(t, copyCmds, "image.apex/lib64/libvndksp.so")
+	ensureExactContents(t, ctx, "myapex", []string{
+		"lib/libvndk.so",
+		"lib/libvndksp.so",
+		"lib64/libvndk.so",
+		"lib64/libvndksp.so",
+	})
 }
 
 func TestVndkApexWithPrebuilt(t *testing.T) {
@@ -1328,8 +1404,8 @@
 		}
 
 		cc_prebuilt_library_shared {
-			name: "libvndkshared",
-			srcs: ["libvndkshared.so"],
+			name: "libvndk",
+			srcs: ["libvndk.so"],
 			vendor_available: true,
 			vndk: {
 				enabled: true,
@@ -1337,13 +1413,33 @@
 			system_shared_libs: [],
 			stl: "none",
 		}
+
+		cc_prebuilt_library_shared {
+			name: "libvndk.arm",
+			srcs: ["libvndk.arm.so"],
+			vendor_available: true,
+			vndk: {
+				enabled: true,
+			},
+			enabled: false,
+			arch: {
+				arm: {
+					enabled: true,
+				},
+			},
+			system_shared_libs: [],
+			stl: "none",
+		}
 	`, withFiles(map[string][]byte{
-		"libvndkshared.so": nil,
+		"libvndk.so":     nil,
+		"libvndk.arm.so": nil,
 	}))
 
-	apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
-	copyCmds := apexRule.Args["copy_commands"]
-	ensureContains(t, copyCmds, "image.apex/lib/libvndkshared.so")
+	ensureExactContents(t, ctx, "myapex", []string{
+		"lib/libvndk.so",
+		"lib/libvndk.arm.so",
+		"lib64/libvndk.so",
+	})
 }
 
 func TestVndkApexVersion(t *testing.T) {
@@ -1361,15 +1457,22 @@
 			private_key: "testkey.pem",
 		}
 
-		cc_library {
-			name: "libvndk",
-			srcs: ["mylib.cpp"],
+		vndk_prebuilt_shared {
+			name: "libvndk27",
+			version: "27",
 			vendor_available: true,
 			vndk: {
 				enabled: true,
 			},
-			system_shared_libs: [],
-			stl: "none",
+			target_arch: "arm64",
+			arch: {
+				arm: {
+					srcs: ["libvndk27_arm.so"],
+				},
+				arm64: {
+					srcs: ["libvndk27_arm64.so"],
+				},
+			},
 		}
 
 		vndk_prebuilt_shared {
@@ -1379,18 +1482,27 @@
 			vndk: {
 				enabled: true,
 			},
-			target_arch: "arm64",
-			srcs: ["libvndk27.so"],
-		}
+			target_arch: "x86_64",
+			arch: {
+				x86: {
+					srcs: ["libvndk27_x86.so"],
+				},
+				x86_64: {
+					srcs: ["libvndk27_x86_64.so"],
+				},
+			},
+	}
 	`, withFiles(map[string][]byte{
-		"libvndk27.so": nil,
+		"libvndk27_arm.so":    nil,
+		"libvndk27_arm64.so":  nil,
+		"libvndk27_x86.so":    nil,
+		"libvndk27_x86_64.so": nil,
 	}))
 
-	apexRule := ctx.ModuleForTests("myapex_v27", "android_common_myapex_v27").Rule("apexRule")
-	copyCmds := apexRule.Args["copy_commands"]
-	ensureContains(t, copyCmds, "image.apex/lib/libvndk27.so")
-	ensureContains(t, copyCmds, "image.apex/lib64/libvndk27.so")
-	ensureNotContains(t, copyCmds, "image.apex/lib/libvndk.so")
+	ensureExactContents(t, ctx, "myapex_v27", []string{
+		"lib/libvndk27_arm.so",
+		"lib64/libvndk27_arm64.so",
+	})
 }
 
 func TestVndkApexErrorWithDuplicateVersion(t *testing.T) {
@@ -1505,14 +1617,10 @@
 		},
 	}))
 
-	apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
-	copyCmds := apexRule.Args["copy_commands"]
-	ensureContains(t, copyCmds, "image.apex/lib/libvndk.so")
-	ensureContains(t, copyCmds, "image.apex/lib64/libvndk.so")
-
-	// apex
-	ensureNotContains(t, copyCmds, "image.apex/lib/x86/libvndk.so")
-	ensureNotContains(t, copyCmds, "image.apex/lib64/x86_64/libvndk.so")
+	ensureExactContents(t, ctx, "myapex", []string{
+		"lib/libvndk.so",
+		"lib64/libvndk.so",
+	})
 }
 
 func TestVndkApexDoesntSupportNativeBridgeSupported(t *testing.T) {
@@ -1545,6 +1653,70 @@
 	`)
 }
 
+func TestVndkApexWithBinder32(t *testing.T) {
+	ctx, _ := testApex(t,
+		`
+		apex_vndk {
+			name: "myapex_v27",
+			key: "myapex.key",
+			file_contexts: "myapex",
+			vndk_version: "27",
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+
+		vndk_prebuilt_shared {
+			name: "libvndk27",
+			version: "27",
+			target_arch: "arm",
+			vendor_available: true,
+			vndk: {
+				enabled: true,
+			},
+			arch: {
+				arm: {
+					srcs: ["libvndk27.so"],
+				}
+			},
+		}
+
+		vndk_prebuilt_shared {
+			name: "libvndk27",
+			version: "27",
+			target_arch: "arm",
+			binder32bit: true,
+			vendor_available: true,
+			vndk: {
+				enabled: true,
+			},
+			arch: {
+				arm: {
+					srcs: ["libvndk27binder32.so"],
+				}
+			},
+		}
+		`,
+		withFiles(map[string][]byte{
+			"libvndk27.so":         nil,
+			"libvndk27binder32.so": nil,
+		}),
+		withBinder32bit,
+		withTargets(map[android.OsType][]android.Target{
+			android.Android: []android.Target{
+				{Os: android.Android, Arch: android.Arch{ArchType: android.Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}, NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: ""},
+			},
+		}),
+	)
+
+	ensureExactContents(t, ctx, "myapex_v27", []string{
+		"lib/libvndk27binder32.so",
+	})
+}
+
 func TestDependenciesInApexManifest(t *testing.T) {
 	ctx, _ := testApex(t, `
 		apex {
@@ -2055,12 +2227,12 @@
 	var builder strings.Builder
 	data.Custom(&builder, name, prefix, "", data)
 	androidMk := builder.String()
-	ensureContains(t, androidMk, "LOCAL_MODULE := myapex.mytest\n")
-	ensureContains(t, androidMk, "LOCAL_MODULE := myapex.mytest1\n")
-	ensureContains(t, androidMk, "LOCAL_MODULE := myapex.mytest2\n")
-	ensureContains(t, androidMk, "LOCAL_MODULE := myapex.mytest3\n")
-	ensureContains(t, androidMk, "LOCAL_MODULE := myapex.apex_manifest.json\n")
-	ensureContains(t, androidMk, "LOCAL_MODULE := myapex.apex_pubkey\n")
+	ensureContains(t, androidMk, "LOCAL_MODULE := mytest.myapex\n")
+	ensureContains(t, androidMk, "LOCAL_MODULE := mytest1.myapex\n")
+	ensureContains(t, androidMk, "LOCAL_MODULE := mytest2.myapex\n")
+	ensureContains(t, androidMk, "LOCAL_MODULE := mytest3.myapex\n")
+	ensureContains(t, androidMk, "LOCAL_MODULE := apex_manifest.json.myapex\n")
+	ensureContains(t, androidMk, "LOCAL_MODULE := apex_pubkey.myapex\n")
 	ensureContains(t, androidMk, "LOCAL_MODULE := myapex\n")
 }
 
diff --git a/bpfix/Android.bp b/bpfix/Android.bp
index 90a453d..aec9ff9 100644
--- a/bpfix/Android.bp
+++ b/bpfix/Android.bp
@@ -19,7 +19,18 @@
 blueprint_go_binary {
     name: "bpfix",
     srcs: [
-        "cmd/bpfix.go",
+        "cmd/main.go",
+    ],
+    deps: [
+        "bpfix-cmd",
+    ],
+}
+
+bootstrap_go_package {
+    name: "bpfix-cmd",
+    pkgPath: "android/soong/bpfix/bpfix/cmd",
+    srcs: [
+        "cmd-lib/bpfix.go",
     ],
     deps: [
         "bpfix-lib",
diff --git a/bpfix/bpfix/bpfix.go b/bpfix/bpfix/bpfix.go
index 5f1cce8..9cba80a 100644
--- a/bpfix/bpfix/bpfix.go
+++ b/bpfix/bpfix/bpfix.go
@@ -45,66 +45,76 @@
 // A FixRequest specifies the details of which fixes to apply to an individual file
 // A FixRequest doesn't specify whether to do a dry run or where to write the results; that's in cmd/bpfix.go
 type FixRequest struct {
-	steps []fixStep
+	steps []FixStep
+}
+type FixStepsExtension struct {
+	Name  string
+	Steps []FixStep
 }
 
-type fixStep struct {
-	name string
-	fix  func(f *Fixer) error
+type FixStep struct {
+	Name string
+	Fix  func(f *Fixer) error
 }
 
-var fixSteps = []fixStep{
+var fixStepsExtensions = []*FixStepsExtension(nil)
+
+func RegisterFixStepExtension(extension *FixStepsExtension) {
+	fixStepsExtensions = append(fixStepsExtensions, extension)
+}
+
+var fixSteps = []FixStep{
 	{
-		name: "simplifyKnownRedundantVariables",
-		fix:  runPatchListMod(simplifyKnownPropertiesDuplicatingEachOther),
+		Name: "simplifyKnownRedundantVariables",
+		Fix:  runPatchListMod(simplifyKnownPropertiesDuplicatingEachOther),
 	},
 	{
-		name: "rewriteIncorrectAndroidmkPrebuilts",
-		fix:  rewriteIncorrectAndroidmkPrebuilts,
+		Name: "rewriteIncorrectAndroidmkPrebuilts",
+		Fix:  rewriteIncorrectAndroidmkPrebuilts,
 	},
 	{
-		name: "rewriteCtsModuleTypes",
-		fix:  rewriteCtsModuleTypes,
+		Name: "rewriteCtsModuleTypes",
+		Fix:  rewriteCtsModuleTypes,
 	},
 	{
-		name: "rewriteIncorrectAndroidmkAndroidLibraries",
-		fix:  rewriteIncorrectAndroidmkAndroidLibraries,
+		Name: "rewriteIncorrectAndroidmkAndroidLibraries",
+		Fix:  rewriteIncorrectAndroidmkAndroidLibraries,
 	},
 	{
-		name: "rewriteTestModuleTypes",
-		fix:  rewriteTestModuleTypes,
+		Name: "rewriteTestModuleTypes",
+		Fix:  rewriteTestModuleTypes,
 	},
 	{
-		name: "rewriteAndroidmkJavaLibs",
-		fix:  rewriteAndroidmkJavaLibs,
+		Name: "rewriteAndroidmkJavaLibs",
+		Fix:  rewriteAndroidmkJavaLibs,
 	},
 	{
-		name: "rewriteJavaStaticLibs",
-		fix:  rewriteJavaStaticLibs,
+		Name: "rewriteJavaStaticLibs",
+		Fix:  rewriteJavaStaticLibs,
 	},
 	{
-		name: "rewritePrebuiltEtc",
-		fix:  rewriteAndroidmkPrebuiltEtc,
+		Name: "rewritePrebuiltEtc",
+		Fix:  rewriteAndroidmkPrebuiltEtc,
 	},
 	{
-		name: "mergeMatchingModuleProperties",
-		fix:  runPatchListMod(mergeMatchingModuleProperties),
+		Name: "mergeMatchingModuleProperties",
+		Fix:  runPatchListMod(mergeMatchingModuleProperties),
 	},
 	{
-		name: "reorderCommonProperties",
-		fix:  runPatchListMod(reorderCommonProperties),
+		Name: "reorderCommonProperties",
+		Fix:  runPatchListMod(reorderCommonProperties),
 	},
 	{
-		name: "removeTags",
-		fix:  runPatchListMod(removeTags),
+		Name: "removeTags",
+		Fix:  runPatchListMod(removeTags),
 	},
 	{
-		name: "rewriteAndroidTest",
-		fix:  rewriteAndroidTest,
+		Name: "rewriteAndroidTest",
+		Fix:  rewriteAndroidTest,
 	},
 	{
-		name: "rewriteAndroidAppImport",
-		fix:  rewriteAndroidAppImport,
+		Name: "rewriteAndroidAppImport",
+		Fix:  rewriteAndroidAppImport,
 	},
 }
 
@@ -113,8 +123,27 @@
 }
 
 func (r FixRequest) AddAll() (result FixRequest) {
-	result.steps = append([]fixStep(nil), r.steps...)
+	result.steps = append([]FixStep(nil), r.steps...)
 	result.steps = append(result.steps, fixSteps...)
+	for _, extension := range fixStepsExtensions {
+		result.steps = append(result.steps, extension.Steps...)
+	}
+	return result
+}
+
+func (r FixRequest) AddBase() (result FixRequest) {
+	result.steps = append([]FixStep(nil), r.steps...)
+	result.steps = append(result.steps, fixSteps...)
+	return result
+}
+
+func (r FixRequest) AddMatchingExtensions(pattern string) (result FixRequest) {
+	result.steps = append([]FixStep(nil), r.steps...)
+	for _, extension := range fixStepsExtensions {
+		if match, _ := filepath.Match(pattern, extension.Name); match {
+			result.steps = append(result.steps, extension.Steps...)
+		}
+	}
 	return result
 }
 
@@ -122,6 +151,10 @@
 	tree *parser.File
 }
 
+func (f Fixer) Tree() *parser.File {
+	return f.tree
+}
+
 func NewFixer(tree *parser.File) *Fixer {
 	fixer := &Fixer{tree}
 
@@ -198,7 +231,7 @@
 
 func (f *Fixer) fixTreeOnce(config FixRequest) error {
 	for _, fix := range config.steps {
-		err := fix.fix(f)
+		err := fix.Fix(f)
 		if err != nil {
 			return err
 		}
diff --git a/bpfix/cmd/bpfix.go b/bpfix/cmd-lib/bpfix.go
similarity index 97%
rename from bpfix/cmd/bpfix.go
rename to bpfix/cmd-lib/bpfix.go
index ccdae16..98122f2 100644
--- a/bpfix/cmd/bpfix.go
+++ b/bpfix/cmd-lib/bpfix.go
@@ -12,11 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-// This file provides a command-line interface to bpfix
+// This file provides a bpfix command-line library
 
 // TODO(jeffrygaston) should this file be consolidated with bpfmt.go?
 
-package main
+package cmd
 
 import (
 	"bytes"
@@ -128,7 +128,7 @@
 	filepath.Walk(path, makeFileVisitor(fixRequest))
 }
 
-func main() {
+func Run() {
 	flag.Parse()
 
 	fixRequest := bpfix.NewFixRequest().AddAll()
diff --git a/bpfix/cmd/main.go b/bpfix/cmd/main.go
new file mode 100644
index 0000000..8ca16b4
--- /dev/null
+++ b/bpfix/cmd/main.go
@@ -0,0 +1,25 @@
+// 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.
+
+// This file provides a wrapper to the bpfix command-line library
+
+package main
+
+import (
+	"android/soong/bpfix/bpfix/cmd"
+)
+
+func main() {
+	cmd.Run()
+}
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 9a98b0e..cdd8e92 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -148,10 +148,10 @@
 func (library *libraryDecorator) androidMkWriteExportedFlags(w io.Writer) {
 	exportedFlags := library.exportedFlags()
 	for _, dir := range library.exportedDirs() {
-		exportedFlags = append(exportedFlags, "-I"+dir)
+		exportedFlags = append(exportedFlags, "-I"+dir.String())
 	}
 	for _, dir := range library.exportedSystemDirs() {
-		exportedFlags = append(exportedFlags, "-isystem "+dir)
+		exportedFlags = append(exportedFlags, "-isystem "+dir.String())
 	}
 	if len(exportedFlags) > 0 {
 		fmt.Fprintln(w, "LOCAL_EXPORT_CFLAGS :=", strings.Join(exportedFlags, " "))
diff --git a/cc/builder.go b/cc/builder.go
index 0760dd4..491ebc5 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -130,6 +130,17 @@
 		},
 		"args", "crossCompile")
 
+	_ = pctx.SourcePathVariable("archiveRepackPath", "build/soong/scripts/archive_repack.sh")
+
+	archiveRepack = pctx.AndroidStaticRule("archiveRepack",
+		blueprint.RuleParams{
+			Depfile:     "${out}.d",
+			Deps:        blueprint.DepsGCC,
+			Command:     "CLANG_BIN=${config.ClangBin} $archiveRepackPath -i ${in} -o ${out} -d ${out}.d ${objects}",
+			CommandDeps: []string{"$archiveRepackPath"},
+		},
+		"objects")
+
 	emptyFile = pctx.AndroidStaticRule("emptyFile",
 		blueprint.RuleParams{
 			Command: "rm -f $out && touch $out",
@@ -866,6 +877,20 @@
 	return android.OptionalPath{}
 }
 
+func TransformArchiveRepack(ctx android.ModuleContext, inputFile android.Path,
+	outputFile android.WritablePath, objects []string) {
+
+	ctx.Build(pctx, android.BuildParams{
+		Rule:        archiveRepack,
+		Description: "Repack archive " + outputFile.Base(),
+		Output:      outputFile,
+		Input:       inputFile,
+		Args: map[string]string{
+			"objects": strings.Join(objects, " "),
+		},
+	})
+}
+
 func gccCmd(toolchain config.Toolchain, cmd string) string {
 	return filepath.Join(toolchain.GccRoot(), "bin", toolchain.GccTriple()+"-"+cmd)
 }
diff --git a/cc/cc.go b/cc/cc.go
index 806a6ed..67132e4 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -123,10 +123,10 @@
 	GeneratedHeaders android.Paths
 
 	Flags                []string
-	IncludeDirs          []string
-	SystemIncludeDirs    []string
-	ReexportedDirs       []string
-	ReexportedSystemDirs []string
+	IncludeDirs          android.Paths
+	SystemIncludeDirs    android.Paths
+	ReexportedDirs       android.Paths
+	ReexportedSystemDirs android.Paths
 	ReexportedFlags      []string
 	ReexportedDeps       android.Paths
 
@@ -215,6 +215,10 @@
 	// Allows this module to use non-APEX version of libraries. Useful
 	// for building binaries that are started before APEXes are activated.
 	Bootstrap *bool
+
+	// Even if DeviceConfig().VndkUseCoreVariant() is set, this module must use vendor variant.
+	// see soong/cc/config/vndk.go
+	MustUseVendorVariant bool `blueprint:"mutated"`
 }
 
 type VendorProperties struct {
@@ -488,15 +492,6 @@
 	return ""
 }
 
-// IsVndkOnSystem returns true if a module is supposed to be a vndk library provided by system to vendor
-func (c *Module) IsVndkOnSystem() bool {
-	if linker, ok := c.linker.(libraryInterface); ok {
-		return linker.shared() && c.isVndk() && c.useVndk() && !c.isVndkExt()
-	}
-
-	return false
-}
-
 func (c *Module) VndkVersion() string {
 	return c.vndkVersion()
 }
@@ -586,7 +581,7 @@
 
 func (c *Module) isLlndk(config android.Config) bool {
 	// Returns true for both LLNDK (public) and LLNDK-private libs.
-	return inList(c.Name(), *llndkLibraries(config))
+	return inList(c.BaseModuleName(), *llndkLibraries(config))
 }
 
 func (c *Module) isLlndkPublic(config android.Config) bool {
@@ -596,7 +591,7 @@
 
 func (c *Module) isVndkPrivate(config android.Config) bool {
 	// Returns true for LLNDK-private, VNDK-SP-private, and VNDK-core-private.
-	return inList(c.Name(), *vndkPrivateLibraries(config))
+	return inList(c.BaseModuleName(), *vndkPrivateLibraries(config))
 }
 
 func (c *Module) isVndk() bool {
@@ -639,7 +634,7 @@
 }
 
 func (c *Module) mustUseVendorVariant() bool {
-	return c.isVndkSp() || inList(c.Name(), config.VndkMustUseVendorVariantList)
+	return c.isVndkSp() || c.Properties.MustUseVendorVariant
 }
 
 func (c *Module) getVndkExtendsModuleName() string {
@@ -1101,10 +1096,10 @@
 	flags.GlobalFlags = append(flags.GlobalFlags, deps.Flags...)
 
 	for _, dir := range deps.IncludeDirs {
-		flags.GlobalFlags = append(flags.GlobalFlags, "-I"+dir)
+		flags.GlobalFlags = append(flags.GlobalFlags, "-I"+dir.String())
 	}
 	for _, dir := range deps.SystemIncludeDirs {
-		flags.GlobalFlags = append(flags.GlobalFlags, "-isystem "+dir)
+		flags.GlobalFlags = append(flags.GlobalFlags, "-isystem "+dir.String())
 	}
 
 	c.flags = flags
@@ -1730,13 +1725,13 @@
 				if genRule, ok := dep.(genrule.SourceFileGenerator); ok {
 					depPaths.GeneratedHeaders = append(depPaths.GeneratedHeaders,
 						genRule.GeneratedDeps()...)
-					dirs := genRule.GeneratedHeaderDirs().Strings()
+					dirs := genRule.GeneratedHeaderDirs()
 					depPaths.IncludeDirs = append(depPaths.IncludeDirs, dirs...)
 					if depTag == genHeaderExportDepTag {
 						depPaths.ReexportedDirs = append(depPaths.ReexportedDirs, dirs...)
 						depPaths.ReexportedDeps = append(depPaths.ReexportedDeps, genRule.GeneratedDeps()...)
 						// Add these re-exported flags to help header-abi-dumper to infer the abi exported by a library.
-						c.sabi.Properties.ReexportedIncludes = append(c.sabi.Properties.ReexportedIncludes, dirs...)
+						c.sabi.Properties.ReexportedIncludes = append(c.sabi.Properties.ReexportedIncludes, dirs.Strings()...)
 
 					}
 				} else {
@@ -1852,7 +1847,7 @@
 					// -isystem headers are not included since for bionic libraries, abi-filtering is taken care of by version
 					// scripts.
 					c.sabi.Properties.ReexportedIncludes = append(
-						c.sabi.Properties.ReexportedIncludes, i.exportedDirs()...)
+						c.sabi.Properties.ReexportedIncludes, i.exportedDirs().Strings()...)
 				}
 			}
 
@@ -2026,11 +2021,11 @@
 
 	// Dedup exported flags from dependencies
 	depPaths.Flags = android.FirstUniqueStrings(depPaths.Flags)
-	depPaths.IncludeDirs = android.FirstUniqueStrings(depPaths.IncludeDirs)
-	depPaths.SystemIncludeDirs = android.FirstUniqueStrings(depPaths.SystemIncludeDirs)
+	depPaths.IncludeDirs = android.FirstUniquePaths(depPaths.IncludeDirs)
+	depPaths.SystemIncludeDirs = android.FirstUniquePaths(depPaths.SystemIncludeDirs)
 	depPaths.GeneratedHeaders = android.FirstUniquePaths(depPaths.GeneratedHeaders)
-	depPaths.ReexportedDirs = android.FirstUniqueStrings(depPaths.ReexportedDirs)
-	depPaths.ReexportedSystemDirs = android.FirstUniqueStrings(depPaths.ReexportedSystemDirs)
+	depPaths.ReexportedDirs = android.FirstUniquePaths(depPaths.ReexportedDirs)
+	depPaths.ReexportedSystemDirs = android.FirstUniquePaths(depPaths.ReexportedSystemDirs)
 	depPaths.ReexportedFlags = android.FirstUniqueStrings(depPaths.ReexportedFlags)
 	depPaths.ReexportedDeps = android.FirstUniquePaths(depPaths.ReexportedDeps)
 
@@ -2113,7 +2108,6 @@
 }
 
 func (c *Module) getMakeLinkType(actx android.ModuleContext) string {
-	name := actx.ModuleName()
 	if c.useVndk() {
 		if lib, ok := c.linker.(*llndkStubDecorator); ok {
 			if Bool(lib.Properties.Vendor_available) {
@@ -2135,7 +2129,7 @@
 		// TODO(b/114741097): use the correct ndk stl once build errors have been fixed
 		//family, link := getNdkStlFamilyAndLinkType(c)
 		//return fmt.Sprintf("native:ndk:%s:%s", family, link)
-	} else if inList(name, *vndkUsingCoreVariantLibraries(actx.Config())) {
+	} else if actx.DeviceConfig().VndkUseCoreVariant() && !c.mustUseVendorVariant() {
 		return "native:platform_vndk"
 	} else {
 		return "native:platform"
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 56078d9..635e7d0 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -264,6 +264,13 @@
 	}
 }
 
+func checkVndkOutput(t *testing.T, ctx *android.TestContext, output string, expected []string) {
+	t.Helper()
+	vndkSnapshot := ctx.SingletonForTests("vndk-snapshot")
+	actual := strings.FieldsFunc(strings.ReplaceAll(vndkSnapshot.Output(output).Args["content"], "\\n", "\n"), func(r rune) bool { return r == '\n' })
+	assertArrayString(t, actual, expected)
+}
+
 func TestVndk(t *testing.T) {
 	config := android.TestArchConfig(buildDir, nil)
 	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
@@ -336,6 +343,69 @@
 	checkVndkSnapshot(t, ctx, "libvndk", vndkCoreLib2ndPath, variant2nd)
 	checkVndkSnapshot(t, ctx, "libvndk_sp", vndkSpLibPath, variant)
 	checkVndkSnapshot(t, ctx, "libvndk_sp", vndkSpLib2ndPath, variant2nd)
+
+	checkVndkOutput(t, ctx, "vndk/llndk.libraries.txt", []string{"libc.so", "libdl.so", "libft2.so", "libm.so"})
+	checkVndkOutput(t, ctx, "vndk/vndkcore.libraries.txt", []string{"libvndk.so", "libvndk_private.so"})
+	checkVndkOutput(t, ctx, "vndk/vndkprivate.libraries.txt", []string{"libft2.so", "libvndk_private.so", "libvndk_sp_private.so"})
+	checkVndkOutput(t, ctx, "vndk/vndksp.libraries.txt", []string{"libc++.so", "libvndk_sp.so", "libvndk_sp_private.so"})
+	checkVndkOutput(t, ctx, "vndk/vndkcorevariant.libraries.txt", nil)
+	// merged & tagged & filtered-out(libclang_rt)
+	checkVndkOutput(t, ctx, "vndk/vndk.libraries.txt", []string{
+		"LLNDK: libc.so",
+		"LLNDK: libdl.so",
+		"LLNDK: libft2.so",
+		"LLNDK: libm.so",
+		"VNDK-SP: libc++.so",
+		"VNDK-SP: libvndk_sp.so",
+		"VNDK-SP: libvndk_sp_private.so",
+		"VNDK-core: libvndk.so",
+		"VNDK-core: libvndk_private.so",
+		"VNDK-private: libft2.so",
+		"VNDK-private: libvndk_private.so",
+		"VNDK-private: libvndk_sp_private.so",
+	})
+}
+
+func TestVndkUsingCoreVariant(t *testing.T) {
+	config := android.TestArchConfig(buildDir, nil)
+	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
+	config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
+	config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true)
+
+	setVndkMustUseVendorVariantListForTest(config, []string{"libvndk"})
+
+	ctx := testCcWithConfig(t, `
+		cc_library {
+			name: "libvndk",
+			vendor_available: true,
+			vndk: {
+				enabled: true,
+			},
+			nocrt: true,
+		}
+
+		cc_library {
+			name: "libvndk_sp",
+			vendor_available: true,
+			vndk: {
+				enabled: true,
+				support_system_process: true,
+			},
+			nocrt: true,
+		}
+
+		cc_library {
+			name: "libvndk2",
+			vendor_available: false,
+			vndk: {
+				enabled: true,
+			},
+			nocrt: true,
+		}
+	`, config)
+
+	checkVndkOutput(t, ctx, "vndk/vndkcore.libraries.txt", []string{"libvndk.so", "libvndk2.so"})
+	checkVndkOutput(t, ctx, "vndk/vndkcorevariant.libraries.txt", []string{"libvndk2.so"})
 }
 
 func TestVndkDepError(t *testing.T) {
@@ -1366,9 +1436,9 @@
 	assertArrayString(t, *vndkSpLibraries(config),
 		[]string{"libc++", "libvndksp"})
 	assertArrayString(t, *llndkLibraries(config),
-		[]string{"libc", "libdl", "libllndk", "libllndkprivate", "libm"})
+		[]string{"libc", "libdl", "libft2", "libllndk", "libllndkprivate", "libm"})
 	assertArrayString(t, *vndkPrivateLibraries(config),
-		[]string{"libllndkprivate", "libvndkprivate"})
+		[]string{"libft2", "libllndkprivate", "libvndkprivate"})
 
 	vendorVariant27 := "android_arm64_armv8-a_vendor.27_shared"
 
diff --git a/cc/compiler.go b/cc/compiler.go
index ffb6ad2..438dee7 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -320,7 +320,9 @@
 	}
 
 	if ctx.apexName() != "" {
+		// TODO(b/142582178): remove the value for __ANDROID_APEX__
 		flags.GlobalFlags = append(flags.GlobalFlags, "-D__ANDROID_APEX__="+ctx.apexName())
+		flags.GlobalFlags = append(flags.GlobalFlags, "-D__ANDROID_APEX_"+makeDefineString(ctx.apexName())+"__")
 	}
 
 	instructionSet := String(compiler.Properties.Instruction_set)
@@ -528,6 +530,12 @@
 	return false
 }
 
+// makeDefineString transforms a name of an APEX module into a value to be used as value for C define
+// For example, com.android.foo => COM_ANDROID_FOO
+func makeDefineString(name string) string {
+	return strings.ReplaceAll(strings.ToUpper(name), ".", "_")
+}
+
 var gnuToCReplacer = strings.NewReplacer("gnu", "c")
 
 func ndkPathDeps(ctx ModuleContext) android.Paths {
diff --git a/cc/kernel_headers.go b/cc/kernel_headers.go
index fff419e..796de62 100644
--- a/cc/kernel_headers.go
+++ b/cc/kernel_headers.go
@@ -25,7 +25,7 @@
 func (stub *kernelHeadersDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path {
 	if ctx.Device() {
 		f := &stub.libraryDecorator.flagExporter
-		f.reexportSystemDirs(ctx.DeviceConfig().DeviceKernelHeaderDirs()...)
+		f.reexportSystemDirs(android.PathsForSource(ctx, ctx.DeviceConfig().DeviceKernelHeaderDirs())...)
 	}
 	return stub.libraryDecorator.linkStatic(ctx, flags, deps, objs)
 }
diff --git a/cc/library.go b/cc/library.go
index 829c617..1943e89 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -229,8 +229,8 @@
 type flagExporter struct {
 	Properties FlagExporterProperties
 
-	dirs       []string
-	systemDirs []string
+	dirs       android.Paths
+	systemDirs android.Paths
 	flags      []string
 	deps       android.Paths
 }
@@ -244,18 +244,18 @@
 }
 
 func (f *flagExporter) exportIncludes(ctx ModuleContext) {
-	f.dirs = append(f.dirs, f.exportedIncludes(ctx).Strings()...)
+	f.dirs = append(f.dirs, f.exportedIncludes(ctx)...)
 }
 
 func (f *flagExporter) exportIncludesAsSystem(ctx ModuleContext) {
-	f.systemDirs = append(f.systemDirs, f.exportedIncludes(ctx).Strings()...)
+	f.systemDirs = append(f.systemDirs, f.exportedIncludes(ctx)...)
 }
 
-func (f *flagExporter) reexportDirs(dirs ...string) {
+func (f *flagExporter) reexportDirs(dirs ...android.Path) {
 	f.dirs = append(f.dirs, dirs...)
 }
 
-func (f *flagExporter) reexportSystemDirs(dirs ...string) {
+func (f *flagExporter) reexportSystemDirs(dirs ...android.Path) {
 	f.systemDirs = append(f.systemDirs, dirs...)
 }
 
@@ -273,11 +273,11 @@
 	f.deps = append(f.deps, deps...)
 }
 
-func (f *flagExporter) exportedDirs() []string {
+func (f *flagExporter) exportedDirs() android.Paths {
 	return f.dirs
 }
 
-func (f *flagExporter) exportedSystemDirs() []string {
+func (f *flagExporter) exportedSystemDirs() android.Paths {
 	return f.systemDirs
 }
 
@@ -290,8 +290,8 @@
 }
 
 type exportedFlagsProducer interface {
-	exportedDirs() []string
-	exportedSystemDirs() []string
+	exportedDirs() android.Paths
+	exportedSystemDirs() android.Paths
 	exportedFlags() []string
 	exportedDeps() android.Paths
 }
@@ -958,7 +958,7 @@
 
 	if Bool(library.Properties.Aidl.Export_aidl_headers) {
 		if library.baseCompiler.hasSrcExt(".aidl") {
-			dir := android.PathForModuleGen(ctx, "aidl").String()
+			dir := android.PathForModuleGen(ctx, "aidl")
 			library.reexportDirs(dir)
 			library.reexportDeps(library.baseCompiler.pathDeps...) // TODO: restrict to aidl deps
 		}
@@ -966,25 +966,25 @@
 
 	if Bool(library.Properties.Proto.Export_proto_headers) {
 		if library.baseCompiler.hasSrcExt(".proto") {
-			includes := []string{}
+			var includes android.Paths
 			if flags.proto.CanonicalPathFromRoot {
-				includes = append(includes, flags.proto.SubDir.String())
+				includes = append(includes, flags.proto.SubDir)
 			}
-			includes = append(includes, flags.proto.Dir.String())
+			includes = append(includes, flags.proto.Dir)
 			library.reexportDirs(includes...)
 			library.reexportDeps(library.baseCompiler.pathDeps...) // TODO: restrict to proto deps
 		}
 	}
 
 	if library.baseCompiler.hasSrcExt(".sysprop") {
-		dir := android.PathForModuleGen(ctx, "sysprop", "include").String()
+		dir := android.PathForModuleGen(ctx, "sysprop", "include")
 		if library.Properties.Sysprop.Platform != nil {
 			isProduct := ctx.ProductSpecific() && !ctx.useVndk()
 			isVendor := ctx.useVndk()
 			isOwnerPlatform := Bool(library.Properties.Sysprop.Platform)
 
 			if !ctx.inRecovery() && (isProduct || (isOwnerPlatform == isVendor)) {
-				dir = android.PathForModuleGen(ctx, "sysprop/public", "include").String()
+				dir = android.PathForModuleGen(ctx, "sysprop/public", "include")
 			}
 		}
 
diff --git a/cc/llndk_library.go b/cc/llndk_library.go
index 9cbe800..16e089e 100644
--- a/cc/llndk_library.go
+++ b/cc/llndk_library.go
@@ -146,9 +146,9 @@
 		}
 
 		if Bool(stub.Properties.Export_headers_as_system) {
-			stub.reexportSystemDirs(genHeaderOutDir.String())
+			stub.reexportSystemDirs(genHeaderOutDir)
 		} else {
-			stub.reexportDirs(genHeaderOutDir.String())
+			stub.reexportDirs(genHeaderOutDir)
 		}
 
 		stub.reexportDeps(timestampFiles...)
diff --git a/cc/testing.go b/cc/testing.go
index 6fa6ea7..fafaeb0 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -145,6 +145,18 @@
 			symbol_file: "",
 		}
 		cc_library {
+			name: "libft2",
+			no_libcrt: true,
+			nocrt: true,
+			system_shared_libs: [],
+			recovery_available: true,
+		}
+		llndk_library {
+			name: "libft2",
+			symbol_file: "",
+			vendor_available: false,
+		}
+		cc_library {
 			name: "libc++_static",
 			no_libcrt: true,
 			nocrt: true,
diff --git a/cc/toolchain_library.go b/cc/toolchain_library.go
index fef4508..dfc6f76 100644
--- a/cc/toolchain_library.go
+++ b/cc/toolchain_library.go
@@ -29,6 +29,9 @@
 type toolchainLibraryProperties struct {
 	// the prebuilt toolchain library, as a path from the top of the source tree
 	Src *string `android:"arch_variant"`
+
+	// Repack the archive with only the selected objects.
+	Repack_objects_to_keep []string `android:"arch_variant"`
 }
 
 type toolchainLibraryDecorator struct {
@@ -90,6 +93,14 @@
 		return outputFile
 	}
 
+	if library.Properties.Repack_objects_to_keep != nil {
+		fileName := ctx.ModuleName() + staticLibraryExtension
+		outputFile := android.PathForModuleOut(ctx, fileName)
+		TransformArchiveRepack(ctx, srcPath, outputFile, library.Properties.Repack_objects_to_keep)
+
+		return outputFile
+	}
+
 	return srcPath
 }
 
diff --git a/cc/vndk.go b/cc/vndk.go
index 14bbf11..2997204 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -194,14 +194,16 @@
 }
 
 var (
-	vndkCoreLibrariesKey             = android.NewOnceKey("vndkCoreLibrarires")
-	vndkSpLibrariesKey               = android.NewOnceKey("vndkSpLibrarires")
-	llndkLibrariesKey                = android.NewOnceKey("llndkLibrarires")
-	vndkPrivateLibrariesKey          = android.NewOnceKey("vndkPrivateLibrarires")
-	vndkUsingCoreVariantLibrariesKey = android.NewOnceKey("vndkUsingCoreVariantLibrarires")
-	modulePathsKey                   = android.NewOnceKey("modulePaths")
-	vndkSnapshotOutputsKey           = android.NewOnceKey("vndkSnapshotOutputs")
-	vndkLibrariesLock                sync.Mutex
+	vndkCoreLibrariesKey                = android.NewOnceKey("vndkCoreLibrarires")
+	vndkSpLibrariesKey                  = android.NewOnceKey("vndkSpLibrarires")
+	llndkLibrariesKey                   = android.NewOnceKey("llndkLibrarires")
+	vndkPrivateLibrariesKey             = android.NewOnceKey("vndkPrivateLibrarires")
+	vndkUsingCoreVariantLibrariesKey    = android.NewOnceKey("vndkUsingCoreVariantLibrarires")
+	modulePathsKey                      = android.NewOnceKey("modulePaths")
+	vndkSnapshotOutputsKey              = android.NewOnceKey("vndkSnapshotOutputs")
+	vndkMustUseVendorVariantListKey     = android.NewOnceKey("vndkMustUseVendorVariantListKey")
+	testVndkMustUseVendorVariantListKey = android.NewOnceKey("testVndkMustUseVendorVariantListKey")
+	vndkLibrariesLock                   sync.Mutex
 
 	headerExts = []string{".h", ".hh", ".hpp", ".hxx", ".h++", ".inl", ".inc", ".ipp", ".h.generic"}
 )
@@ -248,6 +250,26 @@
 	}).(*android.RuleBuilderInstalls)
 }
 
+func vndkMustUseVendorVariantList(cfg android.Config) []string {
+	return cfg.Once(vndkMustUseVendorVariantListKey, func() interface{} {
+		override := cfg.Once(testVndkMustUseVendorVariantListKey, func() interface{} {
+			return []string(nil)
+		}).([]string)
+		if override != nil {
+			return override
+		}
+		return config.VndkMustUseVendorVariantList
+	}).([]string)
+}
+
+// test may call this to override global configuration(config.VndkMustUseVendorVariantList)
+// when it is called, it must be before the first call to vndkMustUseVendorVariantList()
+func setVndkMustUseVendorVariantListForTest(config android.Config, mustUseVendorVariantList []string) {
+	config.Once(testVndkMustUseVendorVariantListKey, func() interface{} {
+		return mustUseVendorVariantList
+	})
+}
+
 func processLlndkLibrary(mctx android.BottomUpMutatorContext, m *Module) {
 	lib := m.linker.(*llndkStubDecorator)
 	name := strings.TrimSuffix(m.Name(), llndkLibrarySuffix)
@@ -276,7 +298,10 @@
 	defer vndkLibrariesLock.Unlock()
 
 	modulePaths := modulePaths(mctx.Config())
-	if mctx.DeviceConfig().VndkUseCoreVariant() && !inList(name, config.VndkMustUseVendorVariantList) {
+	if inList(name, vndkMustUseVendorVariantList(mctx.Config())) {
+		m.Properties.MustUseVendorVariant = true
+	}
+	if mctx.DeviceConfig().VndkUseCoreVariant() && !inList(name, vndkMustUseVendorVariantList(mctx.Config())) {
 		vndkUsingCoreVariantLibraries := vndkUsingCoreVariantLibraries(mctx.Config())
 		if !inList(name, *vndkUsingCoreVariantLibraries) {
 			*vndkUsingCoreVariantLibraries = append(*vndkUsingCoreVariantLibraries, name)
@@ -307,6 +332,31 @@
 	}
 }
 
+func IsForVndkApex(mctx android.BottomUpMutatorContext, m *Module) bool {
+	if !m.Enabled() {
+		return false
+	}
+
+	if m.Target().NativeBridge == android.NativeBridgeEnabled {
+		return false
+	}
+
+	// prebuilt vndk modules should match with device
+	// TODO(b/142675459): Use enabled: to select target device in vndk_prebuilt_shared
+	// When b/142675459 is landed, remove following check
+	if p, ok := m.linker.(*vndkPrebuiltLibraryDecorator); ok && !p.matchesWithDevice(mctx.DeviceConfig()) {
+		return false
+	}
+
+	if lib, ok := m.linker.(libraryInterface); ok {
+		useCoreVariant := m.vndkVersion() == mctx.DeviceConfig().PlatformVndkVersion() &&
+			mctx.DeviceConfig().VndkUseCoreVariant() &&
+			!inList(m.BaseModuleName(), config.VndkMustUseVendorVariantList)
+		return lib.shared() && m.useVndk() && m.isVndk() && !m.isVndkExt() && !useCoreVariant
+	}
+	return false
+}
+
 // gather list of vndk-core, vndk-sp, and ll-ndk libs
 func VndkMutator(mctx android.BottomUpMutatorContext) {
 	m, ok := mctx.Module().(*Module)
@@ -365,6 +415,8 @@
 		return
 	}
 
+	c.buildVndkLibrariesTxtFiles(ctx)
+
 	outputs := vndkSnapshotOutputs(ctx.Config())
 
 	snapshotDir := "vndk-snapshot"
@@ -463,8 +515,8 @@
 				RelativeInstallPath string   `json:",omitempty"`
 			}{}
 			prop.ExportedFlags = l.exportedFlags()
-			prop.ExportedDirs = l.exportedDirs()
-			prop.ExportedSystemDirs = l.exportedSystemDirs()
+			prop.ExportedDirs = l.exportedDirs().Strings()
+			prop.ExportedSystemDirs = l.exportedSystemDirs().Strings()
 			prop.RelativeInstallPath = m.RelativeInstallPath()
 
 			propOut := libOut + ".json"
@@ -523,7 +575,7 @@
 
 		generatedHeaders = append(generatedHeaders, l.exportedDeps()...)
 		for _, dir := range append(l.exportedDirs(), l.exportedSystemDirs()...) {
-			includeDirs[dir] = true
+			includeDirs[dir.String()] = true
 		}
 	})
 
@@ -604,3 +656,88 @@
 	installSnapshotFileFromContent(modulePathTxtBuilder.String(),
 		filepath.Join(configsDir, "module_paths.txt"))
 }
+
+func installListFile(ctx android.SingletonContext, list []string, pathComponents ...string) android.OutputPath {
+	out := android.PathForOutput(ctx, pathComponents...)
+	ctx.Build(pctx, android.BuildParams{
+		Rule:        android.WriteFile,
+		Output:      out,
+		Description: "Writing " + out.String(),
+		Args: map[string]string{
+			"content": strings.Join(list, "\\n"),
+		},
+	})
+	return out
+}
+
+func (c *vndkSnapshotSingleton) buildVndkLibrariesTxtFiles(ctx android.SingletonContext) {
+	var (
+		llndk, vndkcore, vndksp, vndkprivate, vndkcorevariant, merged []string
+	)
+	vndkVersion := ctx.DeviceConfig().PlatformVndkVersion()
+	config := ctx.Config()
+	ctx.VisitAllModules(func(m android.Module) {
+		if !m.Enabled() {
+			return
+		}
+		c, ok := m.(*Module)
+		if !ok || c.Os().Class != android.Device {
+			return
+		}
+		lib, ok := c.linker.(interface{ shared() bool })
+		if !ok || !lib.shared() {
+			return
+		}
+
+		if !c.OutputFile().Valid() {
+			return
+		}
+
+		filename := c.OutputFile().Path().Base()
+		if c.isLlndk(config) {
+			llndk = append(llndk, filename)
+			if c.isVndkPrivate(config) {
+				vndkprivate = append(vndkprivate, filename)
+			}
+		} else if c.vndkVersion() == vndkVersion && c.isVndk() && !c.isVndkExt() {
+			if c.isVndkSp() {
+				vndksp = append(vndksp, filename)
+			} else {
+				vndkcore = append(vndkcore, filename)
+			}
+			if c.isVndkPrivate(config) {
+				vndkprivate = append(vndkprivate, filename)
+			}
+			if ctx.DeviceConfig().VndkUseCoreVariant() && !c.mustUseVendorVariant() {
+				vndkcorevariant = append(vndkcorevariant, filename)
+			}
+		}
+	})
+	llndk = android.SortedUniqueStrings(llndk)
+	vndkcore = android.SortedUniqueStrings(vndkcore)
+	vndksp = android.SortedUniqueStrings(vndksp)
+	vndkprivate = android.SortedUniqueStrings(vndkprivate)
+	vndkcorevariant = android.SortedUniqueStrings(vndkcorevariant)
+
+	installListFile(ctx, llndk, "vndk", "llndk.libraries.txt")
+	installListFile(ctx, vndkcore, "vndk", "vndkcore.libraries.txt")
+	installListFile(ctx, vndksp, "vndk", "vndksp.libraries.txt")
+	installListFile(ctx, vndkprivate, "vndk", "vndkprivate.libraries.txt")
+	installListFile(ctx, vndkcorevariant, "vndk", "vndkcorevariant.libraries.txt")
+
+	// merged & tagged & filtered-out(libclang_rt)
+	filterOutLibClangRt := func(libList []string) (filtered []string) {
+		for _, lib := range libList {
+			if !strings.HasPrefix(lib, "libclang_rt.") {
+				filtered = append(filtered, lib)
+			}
+		}
+		return
+	}
+	merged = append(merged, addPrefix(filterOutLibClangRt(llndk), "LLNDK: ")...)
+	merged = append(merged, addPrefix(vndksp, "VNDK-SP: ")...)
+	merged = append(merged, addPrefix(filterOutLibClangRt(vndkcore), "VNDK-core: ")...)
+	merged = append(merged, addPrefix(vndkprivate, "VNDK-private: ")...)
+
+	installListFile(ctx, merged, "vndk", "vndk.libraries.txt")
+}
diff --git a/cc/vndk_prebuilt.go b/cc/vndk_prebuilt.go
index 2cebb6d..c941c46 100644
--- a/cc/vndk_prebuilt.go
+++ b/cc/vndk_prebuilt.go
@@ -130,20 +130,15 @@
 func (p *vndkPrebuiltLibraryDecorator) link(ctx ModuleContext,
 	flags Flags, deps PathDeps, objs Objects) android.Path {
 
-	arches := ctx.DeviceConfig().Arches()
-	if len(arches) == 0 || arches[0].ArchType.String() != p.arch() {
-		ctx.Module().SkipInstall()
-		return nil
-	}
-
-	if ctx.DeviceConfig().BinderBitness() != p.binderBit() {
+	if !p.matchesWithDevice(ctx.DeviceConfig()) {
 		ctx.Module().SkipInstall()
 		return nil
 	}
 
 	if len(p.properties.Srcs) > 0 && p.shared() {
 		p.libraryDecorator.exportIncludes(ctx)
-		p.libraryDecorator.reexportSystemDirs(p.properties.Export_system_include_dirs...)
+		p.libraryDecorator.reexportSystemDirs(
+			android.PathsForModuleSrc(ctx, p.properties.Export_system_include_dirs)...)
 		p.libraryDecorator.reexportFlags(p.properties.Export_flags...)
 		// current VNDK prebuilts are only shared libs.
 		return p.singleSourcePath(ctx)
@@ -153,6 +148,20 @@
 	return nil
 }
 
+func (p *vndkPrebuiltLibraryDecorator) matchesWithDevice(config android.DeviceConfig) bool {
+	arches := config.Arches()
+	if len(arches) == 0 || arches[0].ArchType.String() != p.arch() {
+		return false
+	}
+	if config.BinderBitness() != p.binderBit() {
+		return false
+	}
+	if len(p.properties.Srcs) == 0 {
+		return false
+	}
+	return true
+}
+
 func (p *vndkPrebuiltLibraryDecorator) nativeCoverage() bool {
 	return false
 }
diff --git a/java/config/makevars.go b/java/config/makevars.go
index 2fa6f89..981a736 100644
--- a/java/config/makevars.go
+++ b/java/config/makevars.go
@@ -29,12 +29,6 @@
 	ctx.Strict("TARGET_DEFAULT_BOOTCLASSPATH_LIBRARIES", strings.Join(DefaultBootclasspathLibraries, " "))
 	ctx.Strict("DEFAULT_SYSTEM_MODULES", DefaultSystemModules)
 
-	if ctx.Config().TargetOpenJDK9() {
-		ctx.Strict("DEFAULT_JAVA_LANGUAGE_VERSION", "1.9")
-	} else {
-		ctx.Strict("DEFAULT_JAVA_LANGUAGE_VERSION", "1.8")
-	}
-
 	ctx.Strict("ANDROID_JAVA_HOME", "${JavaHome}")
 	ctx.Strict("ANDROID_JAVA8_HOME", "prebuilts/jdk/jdk8/${hostPrebuiltTag}")
 	ctx.Strict("ANDROID_JAVA9_HOME", "prebuilts/jdk/jdk9/${hostPrebuiltTag}")
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 12335ff..1091331 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -425,16 +425,12 @@
 		if sdkDep.hasStandardLibs() {
 			if sdkDep.useDefaultLibs {
 				ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
-				if ctx.Config().TargetOpenJDK9() {
-					ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
-				}
+				ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
 				if sdkDep.hasFrameworkLibs() {
 					ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
 				}
 			} else if sdkDep.useModule {
-				if ctx.Config().TargetOpenJDK9() {
-					ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
-				}
+				ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
 				ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.modules...)
 			}
 		} else if sdkDep.systemModules != "" {
diff --git a/java/java.go b/java/java.go
index be48256..9ed7621 100644
--- a/java/java.go
+++ b/java/java.go
@@ -274,6 +274,9 @@
 	// otherwise provides defaults libraries to add to the bootclasspath.
 	System_modules *string
 
+	// set the name of the output
+	Stem *string
+
 	UncompressDex bool `blueprint:"mutated"`
 	IsSDKLibrary  bool `blueprint:"mutated"`
 }
@@ -884,7 +887,7 @@
 		ret = normalizeJavaVersion(ctx, javaVersion)
 	} else if ctx.Device() && sdk <= 23 {
 		ret = "1.7"
-	} else if ctx.Device() && sdk <= 29 || !ctx.Config().TargetOpenJDK9() {
+	} else if ctx.Device() && sdk <= 29 {
 		ret = "1.8"
 	} else if ctx.Device() &&
 		sdkContext.sdkVersion() != "" &&
@@ -1600,7 +1603,8 @@
 }
 
 func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", ctx.ModuleName()+".jar")
+	j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework",
+		proptools.StringDefault(j.deviceProperties.Stem, ctx.ModuleName())+".jar")
 	j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary
 	j.dexpreopter.isInstallable = Bool(j.properties.Installable)
 	j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter)
@@ -1924,6 +1928,9 @@
 
 	// if set to true, run Jetifier against .jar file. Defaults to false.
 	Jetifier *bool
+
+	// set the name of the output
+	Stem *string
 }
 
 type Import struct {
@@ -1966,7 +1973,7 @@
 func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 	jars := android.PathsForModuleSrc(ctx, j.properties.Jars)
 
-	jarName := ctx.ModuleName() + ".jar"
+	jarName := proptools.StringDefault(j.properties.Stem, ctx.ModuleName()) + ".jar"
 	outputFile := android.PathForModuleOut(ctx, "combined", jarName)
 	TransformJarsToJar(ctx, outputFile, "for prebuilts", jars, android.OptionalPath{},
 		false, j.properties.Exclude_files, j.properties.Exclude_dirs)
@@ -2000,7 +2007,7 @@
 	j.exportedSdkLibs = android.FirstUniqueStrings(j.exportedSdkLibs)
 	if Bool(j.properties.Installable) {
 		ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
-			ctx.ModuleName()+".jar", outputFile)
+			jarName, outputFile)
 	}
 }
 
@@ -2112,6 +2119,9 @@
 
 type DexImportProperties struct {
 	Jars []string `android:"path"`
+
+	// set the name of the output
+	Stem *string
 }
 
 type DexImport struct {
@@ -2145,7 +2155,8 @@
 		ctx.PropertyErrorf("jars", "exactly one jar must be provided")
 	}
 
-	j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", ctx.ModuleName()+".jar")
+	j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework",
+		proptools.StringDefault(j.properties.Stem, ctx.ModuleName())+".jar")
 	j.dexpreopter.isInstallable = true
 	j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter)
 
diff --git a/java/proto.go b/java/proto.go
index e013bb4..4d735eb 100644
--- a/java/proto.go
+++ b/java/proto.go
@@ -108,10 +108,10 @@
 		case "nano":
 			flags.proto.OutTypeFlag = "--javanano_out"
 			typeToPlugin = "javanano"
-		case "lite":
+		case "lite", "":
 			flags.proto.OutTypeFlag = "--java_out"
 			flags.proto.OutParams = append(flags.proto.OutParams, "lite")
-		case "full", "":
+		case "full":
 			flags.proto.OutTypeFlag = "--java_out"
 		default:
 			ctx.PropertyErrorf("proto.type", "unknown proto type %q",
diff --git a/rust/OWNERS b/rust/OWNERS
new file mode 100644
index 0000000..82713f9
--- /dev/null
+++ b/rust/OWNERS
@@ -0,0 +1,5 @@
+# Additional owner/reviewers for rust rules, including parent directory owners.
+per-file * = chh@google.com, ivanlozano@google.com, jeffv@google.com, srhines@google.com
+
+# Limited owners/reviewers of the whitelist.
+per-file whitelist.go = chh@google.com, ivanlozano@google.com, jeffv@google.com, jgalenson@google.com, srhines@google.com
diff --git a/rust/config/whitelist.go b/rust/config/whitelist.go
index 4646264..8025bcf 100644
--- a/rust/config/whitelist.go
+++ b/rust/config/whitelist.go
@@ -2,7 +2,7 @@
 
 var (
 	RustAllowedPaths = []string{
-		"external/rust/crates",
+		"external/rust",
 		"external/crosvm",
 		"external/adhd",
 	}
diff --git a/scripts/archive_repack.sh b/scripts/archive_repack.sh
new file mode 100755
index 0000000..f09372d
--- /dev/null
+++ b/scripts/archive_repack.sh
@@ -0,0 +1,87 @@
+#!/bin/bash -e
+
+# Copyright 2019 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 extract and repack an archive with specified object files.
+# Inputs:
+#  Environment:
+#   CLANG_BIN: path to the clang bin directory
+#  Arguments:
+#   -i ${file}: input file
+#   -o ${file}: output file
+#   -d ${file}: deps file
+
+set -o pipefail
+
+OPTSTRING=d:i:o:
+
+usage() {
+    cat <<EOF
+Usage: archive_repack.sh [options] <objects to repack>
+
+OPTIONS:
+    -i <file>: input file
+    -o <file>: output file
+    -d <file>: deps file
+EOF
+    exit 1
+}
+
+while getopts $OPTSTRING opt; do
+    case "$opt" in
+        d) depsfile="${OPTARG}" ;;
+        i) infile="${OPTARG}" ;;
+        o) outfile="${OPTARG}" ;;
+        ?) usage ;;
+    esac
+done
+shift "$(($OPTIND -1))"
+
+if [ -z "${infile}" ]; then
+    echo "-i argument is required"
+    usage
+fi
+
+if [ -z "${outfile}" ]; then
+    echo "-o argument is required"
+    usage
+fi
+
+# Produce deps file
+if [ ! -z "${depsfile}" ]; then
+    cat <<EOF > "${depsfile}"
+${outfile}: ${infile} ${CLANG_BIN}/llvm-ar
+EOF
+fi
+
+# Get absolute path for outfile and llvm-ar.
+LLVM_AR="${PWD}/${CLANG_BIN}/llvm-ar"
+if [[ "$outfile" != /* ]]; then
+    outfile="${PWD}/${outfile}"
+fi
+
+tempdir="${outfile}.tmp"
+
+# Clean up any previous temporary files.
+rm -f "${outfile}"
+rm -rf "${tempdir}"
+
+# Do repack
+# We have to change working directory since ar only allows extracting to CWD.
+mkdir "${tempdir}"
+cp "${infile}" "${tempdir}/archive"
+cd "${tempdir}"
+"${LLVM_AR}" x "archive"
+"${LLVM_AR}" --format=gnu qc "${outfile}" "$@"