Merge "Use prebuilt llvm-rs-cc for unbundled build"
diff --git a/android/config.go b/android/config.go
index 367b42c..50c1413 100644
--- a/android/config.go
+++ b/android/config.go
@@ -351,6 +351,10 @@
 
 var _ bootstrap.ConfigBlueprintToolLocation = (*config)(nil)
 
+func (c *config) HostToolPath(ctx PathContext, tool string) Path {
+	return PathForOutput(ctx, "host", c.PrebuiltOS(), "bin", tool)
+}
+
 // HostSystemTool looks for non-hermetic tools from the system we're running on.
 // Generally shouldn't be used, but useful to find the XCode SDK, etc.
 func (c *config) HostSystemTool(name string) string {
diff --git a/apex/apex.go b/apex/apex.go
index 81e969d..33143d6 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -61,6 +61,18 @@
 			"${soong_zip}", "${zipalign}", "${aapt2}"},
 		Description: "APEX ${image_dir} => ${out}",
 	}, "tool_path", "image_dir", "copy_commands", "manifest", "file_contexts", "canned_fs_config", "key")
+
+	apexProtoConvertRule = pctx.AndroidStaticRule("apexProtoConvertRule",
+		blueprint.RuleParams{
+			Command:     `${aapt2} convert --output-format proto $in -o $out`,
+			CommandDeps: []string{"${aapt2}"},
+		})
+
+	apexBundleRule = pctx.StaticRule("apexBundleRule", blueprint.RuleParams{
+		Command:     `${zip2zip} -i $in -o $out image.img:apex/${abi}.img manifest.json:root/manifest.json AndroidManifest.xml:manifest/AndroidManifest.xml`,
+		CommandDeps: []string{"${zip2zip}"},
+		Description: "app bundle",
+	}, "abi")
 )
 
 var apexSuffix = ".apex"
@@ -102,6 +114,7 @@
 	pctx.HostBinToolVariable("resize2fs", "resize2fs")
 	pctx.HostBinToolVariable("sefcontext_compile", "sefcontext_compile")
 	pctx.HostBinToolVariable("soong_zip", "soong_zip")
+	pctx.HostBinToolVariable("zip2zip", "zip2zip")
 	pctx.HostBinToolVariable("zipalign", "zipalign")
 
 	android.RegisterModuleType("apex", apexBundleFactory)
@@ -123,10 +136,10 @@
 // can be built for the apex bundles.
 func apexDepsMutator(mctx android.TopDownMutatorContext) {
 	if _, ok := mctx.Module().(*apexBundle); ok {
-		apexBundleName := mctx.Module().Name()
+		apexBundleName := mctx.ModuleName()
 		mctx.WalkDeps(func(child, parent android.Module) bool {
 			if am, ok := child.(android.ApexModule); ok && am.CanHaveApexVariants() {
-				moduleName := am.Name() + "-" + am.Target().String()
+				moduleName := mctx.OtherModuleName(am) + "-" + am.Target().String()
 				bundleNames, ok := apexBundleNamesFor(mctx.Config())[moduleName]
 				if !ok {
 					bundleNames = make(map[string]bool)
@@ -144,7 +157,7 @@
 // Create apex variations if a module is included in APEX(s).
 func apexMutator(mctx android.BottomUpMutatorContext) {
 	if am, ok := mctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
-		moduleName := am.Name() + "-" + am.Target().String()
+		moduleName := mctx.ModuleName() + "-" + am.Target().String()
 		if bundleNames, ok := apexBundleNamesFor(mctx.Config())[moduleName]; ok {
 			variations := []string{"platform"}
 			for bn := range bundleNames {
@@ -268,8 +281,9 @@
 
 	properties apexBundleProperties
 
-	outputFile android.WritablePath
-	installDir android.OutputPath
+	bundleModuleFile android.WritablePath
+	outputFile       android.WritablePath
+	installDir       android.OutputPath
 
 	// list of files to be included in this apex
 	filesInfo []apexFile
@@ -518,7 +532,7 @@
 		filesInfo[i].moduleName = ctx.ModuleName() + "." + filesInfo[i].moduleName
 	}
 
-	a.flattened = ctx.Config().FlattenApex()
+	a.flattened = ctx.Config().FlattenApex() && !ctx.Config().UnbundledBuild()
 	a.installDir = android.PathForModuleInstall(ctx, "apex")
 	a.filesInfo = filesInfo
 	if ctx.Config().FlattenApex() {
@@ -558,9 +572,10 @@
 	sort.Strings(readOnlyPaths)
 	sort.Strings(executablePaths)
 	cannedFsConfig := android.PathForModuleOut(ctx, "canned_fs_config")
-	ctx.ModuleBuild(pctx, android.ModuleBuildParams{
-		Rule:   generateFsConfig,
-		Output: cannedFsConfig,
+	ctx.Build(pctx, android.BuildParams{
+		Rule:        generateFsConfig,
+		Output:      cannedFsConfig,
+		Description: "generate fs config",
 		Args: map[string]string{
 			"ro_paths":   strings.Join(readOnlyPaths, " "),
 			"exec_paths": strings.Join(executablePaths, " "),
@@ -569,7 +584,7 @@
 
 	manifest := android.PathForModuleSrc(ctx, proptools.StringDefault(a.properties.Manifest, "manifest.json"))
 
-	fcName := proptools.StringDefault(a.properties.File_contexts, a.ModuleBase.Name())
+	fcName := proptools.StringDefault(a.properties.File_contexts, ctx.ModuleName())
 	fileContextsPath := "system/sepolicy/apex/" + fcName + "-file_contexts"
 	fileContextsOptionalPath := android.ExistentPathForSource(ctx, fileContextsPath)
 	if !fileContextsOptionalPath.Valid() {
@@ -578,7 +593,7 @@
 	}
 	fileContexts := fileContextsOptionalPath.Path()
 
-	unsignedOutputFile := android.PathForModuleOut(ctx, a.ModuleBase.Name()+apexSuffix+".unsigned")
+	unsignedOutputFile := android.PathForModuleOut(ctx, ctx.ModuleName()+apexSuffix+".unsigned")
 
 	filesToCopy := []android.Path{}
 	for _, f := range a.filesInfo {
@@ -596,10 +611,11 @@
 	implicitInputs = append(implicitInputs, cannedFsConfig, manifest, fileContexts, keyFile)
 	outHostBinDir := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "bin").String()
 	prebuiltSdkToolsBinDir := filepath.Join("prebuilts", "sdk", "tools", runtime.GOOS, "bin")
-	ctx.ModuleBuild(pctx, android.ModuleBuildParams{
-		Rule:      apexRule,
-		Implicits: implicitInputs,
-		Output:    unsignedOutputFile,
+	ctx.Build(pctx, android.BuildParams{
+		Rule:        apexRule,
+		Implicits:   implicitInputs,
+		Output:      unsignedOutputFile,
+		Description: "apex",
 		Args: map[string]string{
 			"tool_path":        outHostBinDir + ":" + prebuiltSdkToolsBinDir,
 			"image_dir":        android.PathForModuleOut(ctx, "image").String(),
@@ -611,7 +627,34 @@
 		},
 	})
 
-	a.outputFile = android.PathForModuleOut(ctx, a.ModuleBase.Name()+apexSuffix)
+	var abis []string
+	for _, target := range ctx.MultiTargets() {
+		abis = append(abis, target.Arch.Abi[0])
+	}
+	abis = android.FirstUniqueStrings(abis)
+
+	apexProtoFile := android.PathForModuleOut(ctx, ctx.ModuleName()+".pb"+apexSuffix)
+	bundleModuleFile := android.PathForModuleOut(ctx, ctx.ModuleName()+"-base.zip")
+	a.bundleModuleFile = bundleModuleFile
+
+	ctx.Build(pctx, android.BuildParams{
+		Rule:        apexProtoConvertRule,
+		Input:       unsignedOutputFile,
+		Output:      apexProtoFile,
+		Description: "apex proto convert",
+	})
+
+	ctx.Build(pctx, android.BuildParams{
+		Rule:        apexBundleRule,
+		Input:       apexProtoFile,
+		Output:      bundleModuleFile,
+		Description: "apex bundle module",
+		Args: map[string]string{
+			"abi": strings.Join(abis, "."),
+		},
+	})
+
+	a.outputFile = android.PathForModuleOut(ctx, ctx.ModuleName()+apexSuffix)
 	ctx.Build(pctx, android.BuildParams{
 		Rule:        java.Signapk,
 		Description: "signapk",
@@ -627,10 +670,10 @@
 	// For flattened APEX, do nothing but make sure that manifest.json file is also copied along
 	// with other ordinary files.
 	manifest := android.PathForModuleSrc(ctx, proptools.StringDefault(a.properties.Manifest, "manifest.json"))
-	a.filesInfo = append(a.filesInfo, apexFile{manifest, a.Name() + ".manifest.json", android.Common, ".", etc})
+	a.filesInfo = append(a.filesInfo, apexFile{manifest, ctx.ModuleName() + ".manifest.json", android.Common, ".", etc})
 
 	for _, fi := range a.filesInfo {
-		dir := filepath.Join("apex", a.Name(), fi.installDir)
+		dir := filepath.Join("apex", ctx.ModuleName(), fi.installDir)
 		ctx.InstallFile(android.PathForModuleInstall(ctx, dir), fi.builtFile.Base(), fi.builtFile)
 	}
 }
@@ -684,6 +727,8 @@
 				fmt.Fprintln(w, "LOCAL_INSTALLED_MODULE_STEM :=", name+apexSuffix)
 				fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES :=", String(a.properties.Key))
 				fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
+
+				fmt.Fprintln(w, "ALL_MODULES.$(LOCAL_MODULE).BUNDLE :=", a.bundleModuleFile.String())
 			}}
 	}
 }
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 69ed771..5e38973 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -143,6 +143,9 @@
 		ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
 			fmt.Fprintln(w, "LOCAL_SOONG_TOC :=", library.toc().String())
 			fmt.Fprintln(w, "LOCAL_SOONG_UNSTRIPPED_BINARY :=", library.unstrippedOutputFile.String())
+			if len(library.Properties.Overrides) > 0 {
+				fmt.Fprintln(w, "LOCAL_OVERRIDES_MODULES := "+strings.Join(library.Properties.Overrides, " "))
+			}
 		})
 	} else if library.header() {
 		ret.Class = "HEADER_LIBRARIES"
diff --git a/cc/builder.go b/cc/builder.go
index 6d5b595..bf35f84 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -231,8 +231,6 @@
 	ldFlags         string
 	libFlags        string
 	yaccFlags       string
-	protoFlags      string
-	protoOutParams  string
 	tidyFlags       string
 	sAbiFlags       string
 	yasmFlags       string
@@ -242,7 +240,6 @@
 	tidy            bool
 	coverage        bool
 	sAbiDump        bool
-	protoRoot       bool
 
 	systemIncludeFlags string
 
@@ -252,6 +249,14 @@
 	stripKeepMiniDebugInfo bool
 	stripAddGnuDebuglink   bool
 	stripUseLlvmStrip      bool
+
+	protoDeps        android.Paths
+	protoFlags       string
+	protoOutTypeFlag string
+	protoOutParams   string
+	protoC           bool
+	protoOptionsFile bool
+	protoRoot        bool
 }
 
 type Objects struct {
diff --git a/cc/cc.go b/cc/cc.go
index 4a432f4..ed65aa6 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -130,8 +130,6 @@
 	CppFlags        []string // Flags that apply to C++ source files
 	ToolingCppFlags []string // Flags that apply to C++ source files parsed by clang LibTooling tools
 	YaccFlags       []string // Flags that apply to Yacc source files
-	protoFlags      []string // Flags that apply to proto source files
-	protoOutParams  []string // Flags that modify the output of proto generated files
 	aidlFlags       []string // Flags that apply to aidl source files
 	rsFlags         []string // Flags that apply to renderscript source files
 	LdFlags         []string // Flags that apply to linker command lines
@@ -148,7 +146,6 @@
 	Tidy      bool
 	Coverage  bool
 	SAbiDump  bool
-	ProtoRoot bool
 
 	RequiredInstructionSet string
 	DynamicLinker          string
@@ -157,6 +154,14 @@
 	LdFlagsDeps android.Paths // Files depended on by linker flags
 
 	GroupStaticLibs bool
+
+	protoDeps        android.Paths
+	protoFlags       []string // Flags that apply to proto source files
+	protoOutTypeFlag string   // The output type, --cpp_out for example
+	protoOutParams   []string // Flags that modify the output of proto generated files
+	protoC           bool     // Whether to use C instead of C++
+	protoOptionsFile bool     // Whether to look for a .options file next to the .proto
+	ProtoRoot        bool
 }
 
 type ObjectLinkerProperties struct {
diff --git a/cc/gen.go b/cc/gen.go
index 29a2bb2..4852794 100644
--- a/cc/gen.go
+++ b/cc/gen.go
@@ -182,8 +182,7 @@
 			srcFiles[i] = cppFile
 			genLex(ctx, srcFile, cppFile)
 		case ".proto":
-			ccFile, headerFile := genProto(ctx, srcFile, buildFlags.protoFlags,
-				buildFlags.protoOutParams, buildFlags.protoRoot)
+			ccFile, headerFile := genProto(ctx, srcFile, buildFlags)
 			srcFiles[i] = ccFile
 			deps = append(deps, headerFile)
 		case ".aidl":
diff --git a/cc/library.go b/cc/library.go
index 975f325..abaa6c4 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -77,6 +77,16 @@
 		// List versions to generate stubs libs for.
 		Versions []string
 	}
+
+	// set the name of the output
+	Stem *string `android:"arch_variant"`
+
+	// Names of modules to be overridden. Listed modules can only be other shared libraries
+	// (in Make or Soong).
+	// This does not completely prevent installation of the overridden libraries, but if both
+	// binaries would be installed by default (in PRODUCT_PACKAGES) the other library will be removed
+	// from PRODUCT_PACKAGES.
+	Overrides []string
 }
 
 type LibraryMutatedProperties struct {
@@ -429,7 +439,10 @@
 func (library *libraryDecorator) getLibName(ctx ModuleContext) string {
 	name := library.libName
 	if name == "" {
-		name = ctx.baseModuleName()
+		name = String(library.Properties.Stem)
+		if name == "" {
+			name = ctx.baseModuleName()
+		}
 	}
 
 	if ctx.isVndkExt() {
diff --git a/cc/proto.go b/cc/proto.go
index 6e6f95e..61fd607 100644
--- a/cc/proto.go
+++ b/cc/proto.go
@@ -31,41 +31,56 @@
 var (
 	proto = pctx.AndroidStaticRule("protoc",
 		blueprint.RuleParams{
-			Command: "$protocCmd --cpp_out=$protoOutParams:$outDir --dependency_out=$out.d -I $protoBase $protoFlags $in && " +
+			Command: "$protocCmd $protoOut=$protoOutParams:$outDir --dependency_out=$out.d -I $protoBase $protoFlags $in && " +
 				`$depFixCmd $out.d`,
 			CommandDeps: []string{"$protocCmd", "$depFixCmd"},
 			Depfile:     "${out}.d",
 			Deps:        blueprint.DepsGCC,
-		}, "protoFlags", "protoOutParams", "protoBase", "outDir")
+		}, "protoFlags", "protoOut", "protoOutParams", "protoBase", "outDir")
 )
 
 // genProto creates a rule to convert a .proto file to generated .pb.cc and .pb.h files and returns
 // the paths to the generated files.
-func genProto(ctx android.ModuleContext, protoFile android.Path,
-	protoFlags, protoOutParams string, root bool) (ccFile, headerFile android.WritablePath) {
+func genProto(ctx android.ModuleContext, protoFile android.Path, flags builderFlags) (ccFile, headerFile android.WritablePath) {
+
+	srcSuffix := ".cc"
+	if flags.protoC {
+		srcSuffix = ".c"
+	}
 
 	var protoBase string
-	if root {
+	if flags.protoRoot {
 		protoBase = "."
-		ccFile = android.GenPathWithExt(ctx, "proto", protoFile, "pb.cc")
+		ccFile = android.GenPathWithExt(ctx, "proto", protoFile, "pb"+srcSuffix)
 		headerFile = android.GenPathWithExt(ctx, "proto", protoFile, "pb.h")
 	} else {
 		rel := protoFile.Rel()
 		protoBase = strings.TrimSuffix(protoFile.String(), rel)
-		ccFile = android.PathForModuleGen(ctx, "proto", pathtools.ReplaceExtension(rel, "pb.cc"))
+		ccFile = android.PathForModuleGen(ctx, "proto", pathtools.ReplaceExtension(rel, "pb"+srcSuffix))
 		headerFile = android.PathForModuleGen(ctx, "proto", pathtools.ReplaceExtension(rel, "pb.h"))
 	}
 
+	protoDeps := flags.protoDeps
+	if flags.protoOptionsFile {
+		optionsFile := pathtools.ReplaceExtension(protoFile.String(), "options")
+		optionsPath := android.ExistentPathForSource(ctx, optionsFile)
+		if optionsPath.Valid() {
+			protoDeps = append(android.Paths{optionsPath.Path()}, protoDeps...)
+		}
+	}
+
 	ctx.Build(pctx, android.BuildParams{
 		Rule:           proto,
 		Description:    "protoc " + protoFile.Rel(),
 		Output:         ccFile,
 		ImplicitOutput: headerFile,
 		Input:          protoFile,
+		Implicits:      protoDeps,
 		Args: map[string]string{
 			"outDir":         android.ProtoDir(ctx).String(),
-			"protoFlags":     protoFlags,
-			"protoOutParams": protoOutParams,
+			"protoFlags":     flags.protoFlags,
+			"protoOut":       flags.protoOutTypeFlag,
+			"protoOutParams": flags.protoOutParams,
 			"protoBase":      protoBase,
 		},
 	})
@@ -91,6 +106,12 @@
 		} else {
 			lib = "libprotobuf-cpp-lite"
 		}
+	case "nanopb-c":
+		lib = "libprotobuf-c-nano"
+		static = true
+	case "nanopb-c-enable_malloc":
+		lib = "libprotobuf-c-nano-enable_malloc"
+		static = true
 	default:
 		ctx.PropertyErrorf("proto.type", "unknown proto type %q",
 			String(p.Proto.Type))
@@ -118,8 +139,33 @@
 
 	flags.protoFlags = android.ProtoFlags(ctx, p)
 
-	if String(p.Proto.Type) == "lite" {
+	var plugin string
+
+	switch String(p.Proto.Type) {
+	case "nanopb-c", "nanopb-c-enable_malloc":
+		flags.protoC = true
+		flags.protoOptionsFile = true
+		flags.protoOutTypeFlag = "--nanopb_out"
+		plugin = "protoc-gen-nanopb"
+	case "full":
+		flags.protoOutTypeFlag = "--cpp_out"
+	case "lite":
+		flags.protoOutTypeFlag = "--cpp_out"
 		flags.protoOutParams = append(flags.protoOutParams, "lite")
+	case "":
+		// TODO(b/119714316): this should be equivalent to "lite" in
+		// order to match protoDeps, but some modules are depending on
+		// this behavior
+		flags.protoOutTypeFlag = "--cpp_out"
+	default:
+		ctx.PropertyErrorf("proto.type", "unknown proto type %q",
+			String(p.Proto.Type))
+	}
+
+	if plugin != "" {
+		path := ctx.Config().HostToolPath(ctx, plugin)
+		flags.protoDeps = append(flags.protoDeps, path)
+		flags.protoFlags = append(flags.protoFlags, "--plugin="+path.String())
 	}
 
 	return flags
diff --git a/cc/util.go b/cc/util.go
index c900423..925dd74 100644
--- a/cc/util.go
+++ b/cc/util.go
@@ -68,8 +68,6 @@
 		conlyFlags:      strings.Join(in.ConlyFlags, " "),
 		cppFlags:        strings.Join(in.CppFlags, " "),
 		yaccFlags:       strings.Join(in.YaccFlags, " "),
-		protoFlags:      strings.Join(in.protoFlags, " "),
-		protoOutParams:  strings.Join(in.protoOutParams, ","),
 		aidlFlags:       strings.Join(in.aidlFlags, " "),
 		rsFlags:         strings.Join(in.rsFlags, " "),
 		ldFlags:         strings.Join(in.LdFlags, " "),
@@ -81,11 +79,18 @@
 		coverage:        in.Coverage,
 		tidy:            in.Tidy,
 		sAbiDump:        in.SAbiDump,
-		protoRoot:       in.ProtoRoot,
 
 		systemIncludeFlags: strings.Join(in.SystemIncludeFlags, " "),
 
 		groupStaticLibs: in.GroupStaticLibs,
+
+		protoDeps:        in.protoDeps,
+		protoFlags:       strings.Join(in.protoFlags, " "),
+		protoOutTypeFlag: in.protoOutTypeFlag,
+		protoOutParams:   strings.Join(in.protoOutParams, ","),
+		protoC:           in.protoC,
+		protoOptionsFile: in.protoOptionsFile,
+		protoRoot:        in.ProtoRoot,
 	}
 }