Export static libraries.

Export static libraries through LOCAL_STATIC_LIBRARIES and
LOCAL_WHOLE_STATIC_LIBRARIES. This enables dependency-based NOTICE file
generation. Also, add a notice property in the libwinpthread module.

Bug: 36073965
Test: cc_test.go
Change-Id: Ic63ca523b40acac82bbe876f7aa40ecd495907c5
diff --git a/Android.bp b/Android.bp
index 1b93c0d..ef42c84 100644
--- a/Android.bp
+++ b/Android.bp
@@ -435,6 +435,7 @@
             src: "prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8/x86_64-w64-mingw32/lib/libwinpthread.a",
         },
     },
+    notice: "../../prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8/licenses/mingw-w64-svn-r5861/mingw-w64-libraries/winpthreads/COPYING",
 }
 
 toolchain_library {
diff --git a/android/androidmk.go b/android/androidmk.go
index 7030523..493ba97 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -275,9 +275,10 @@
 		if amod.commonProperties.Owner != nil {
 			fmt.Fprintln(&data.preamble, "LOCAL_MODULE_OWNER :=", *amod.commonProperties.Owner)
 		}
-		if amod.commonProperties.Notice != nil {
-			fmt.Fprintln(&data.preamble, "LOCAL_NOTICE_FILE :=", "$(LOCAL_PATH)/"+*amod.commonProperties.Notice)
-		}
+	}
+
+	if amod.commonProperties.Notice != nil {
+		fmt.Fprintln(&data.preamble, "LOCAL_NOTICE_FILE :=", "$(LOCAL_PATH)/"+*amod.commonProperties.Notice)
 	}
 
 	if host {
diff --git a/android/config.go b/android/config.go
index 695a298..928d07a 100644
--- a/android/config.go
+++ b/android/config.go
@@ -238,6 +238,9 @@
 			{BuildOs, Arch{ArchType: X86_64}},
 			{BuildOs, Arch{ArchType: X86}},
 		},
+		Windows: []Target{
+			{Windows, Arch{ArchType: X86}},
+		},
 	}
 
 	config.BuildOsVariant = config.Targets[BuildOs][0].String()
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 324b5bc..69ed771 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -70,6 +70,12 @@
 				if len(c.Properties.AndroidMkSharedLibs) > 0 {
 					fmt.Fprintln(w, "LOCAL_SHARED_LIBRARIES := "+strings.Join(c.Properties.AndroidMkSharedLibs, " "))
 				}
+				if len(c.Properties.AndroidMkStaticLibs) > 0 {
+					fmt.Fprintln(w, "LOCAL_STATIC_LIBRARIES := "+strings.Join(c.Properties.AndroidMkStaticLibs, " "))
+				}
+				if len(c.Properties.AndroidMkWholeStaticLibs) > 0 {
+					fmt.Fprintln(w, "LOCAL_WHOLE_STATIC_LIBRARIES := "+strings.Join(c.Properties.AndroidMkWholeStaticLibs, " "))
+				}
 				fmt.Fprintln(w, "LOCAL_SOONG_LINK_TYPE :=", c.getMakeLinkType())
 				if c.useVndk() {
 					fmt.Fprintln(w, "LOCAL_USE_VNDK := true")
diff --git a/cc/cc.go b/cc/cc.go
index 0569563..66018d0 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -176,10 +176,12 @@
 	// Minimum sdk version supported when compiling against the ndk
 	Sdk_version *string
 
-	AndroidMkSharedLibs  []string `blueprint:"mutated"`
-	AndroidMkRuntimeLibs []string `blueprint:"mutated"`
-	HideFromMake         bool     `blueprint:"mutated"`
-	PreventInstall       bool     `blueprint:"mutated"`
+	AndroidMkSharedLibs      []string `blueprint:"mutated"`
+	AndroidMkStaticLibs      []string `blueprint:"mutated"`
+	AndroidMkRuntimeLibs     []string `blueprint:"mutated"`
+	AndroidMkWholeStaticLibs []string `blueprint:"mutated"`
+	HideFromMake             bool     `blueprint:"mutated"`
+	PreventInstall           bool     `blueprint:"mutated"`
 
 	UseVndk bool `blueprint:"mutated"`
 
@@ -1479,9 +1481,15 @@
 			// they merely serve as Make dependencies and do not affect this lib itself.
 			c.Properties.AndroidMkSharedLibs = append(
 				c.Properties.AndroidMkSharedLibs, makeLibName(depName))
+		case staticDepTag, staticExportDepTag, lateStaticDepTag:
+			c.Properties.AndroidMkStaticLibs = append(
+				c.Properties.AndroidMkStaticLibs, makeLibName(depName))
 		case runtimeDepTag:
 			c.Properties.AndroidMkRuntimeLibs = append(
 				c.Properties.AndroidMkRuntimeLibs, makeLibName(depName))
+		case wholeStaticDepTag:
+			c.Properties.AndroidMkWholeStaticLibs = append(
+				c.Properties.AndroidMkWholeStaticLibs, makeLibName(depName))
 		}
 	})
 
diff --git a/cc/cc_test.go b/cc/cc_test.go
index fba38a2..8e257d3 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -55,13 +55,17 @@
 	ctx := android.NewTestArchContext()
 	ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(LibraryFactory))
 	ctx.RegisterModuleType("cc_library_shared", android.ModuleFactoryAdaptor(LibrarySharedFactory))
+	ctx.RegisterModuleType("cc_library_static", android.ModuleFactoryAdaptor(LibraryStaticFactory))
 	ctx.RegisterModuleType("cc_library_headers", android.ModuleFactoryAdaptor(LibraryHeaderFactory))
+	ctx.RegisterModuleType("cc_library_host_static", android.ModuleFactoryAdaptor(LibraryHostStaticFactory))
 	ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(ToolchainLibraryFactory))
 	ctx.RegisterModuleType("llndk_library", android.ModuleFactoryAdaptor(llndkLibraryFactory))
 	ctx.RegisterModuleType("llndk_headers", android.ModuleFactoryAdaptor(llndkHeadersFactory))
 	ctx.RegisterModuleType("vendor_public_library", android.ModuleFactoryAdaptor(vendorPublicLibraryFactory))
 	ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(ObjectFactory))
 	ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(android.FileGroupFactory))
+	ctx.RegisterModuleType("cc_binary", android.ModuleFactoryAdaptor(binaryFactory))
+	ctx.RegisterModuleType("cc_binary_host", android.ModuleFactoryAdaptor(binaryHostFactory))
 	ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
 		ctx.BottomUp("image", imageMutator).Parallel()
 		ctx.BottomUp("link", LinkageMutator).Parallel()
@@ -122,6 +126,19 @@
 			src: "",
 		}
 
+		toolchain_library {
+			name: "libwinpthread",
+			vendor_available: true,
+			recovery_available: true,
+			host_supported: true,
+			src: "",
+			target: {
+				windows: {
+					enabled: true,
+				},
+			},
+		}
+
 		cc_library {
 			name: "libc",
 			no_libgcc: true,
@@ -155,14 +172,20 @@
 			name: "libdl",
 			symbol_file: "",
 		}
-		cc_library {
+		cc_library_static {
 			name: "libc++_static",
 			no_libgcc: true,
 			nocrt: true,
 			system_shared_libs: [],
 			stl: "none",
+			host_supported: true,
 			vendor_available: true,
 			recovery_available: true,
+			target: {
+				windows: {
+					enabled: true,
+				},
+			},
 		}
 		cc_library {
 			name: "libc++",
@@ -194,6 +217,14 @@
 		}
 
 		cc_object {
+			name: "crtbegin_dynamic",
+		}
+
+		cc_object {
+			name: "crtend_android",
+		}
+
+		cc_object {
 			name: "crtend_so",
 			recovery_available: true,
 			vendor_available: true,
@@ -1549,6 +1580,65 @@
 	checkRuntimeLibs(t, []string{"libvendor_available1", "libvendor1"}, module)
 }
 
+func checkStaticLibs(t *testing.T, expected []string, module *Module) {
+	actual := module.Properties.AndroidMkStaticLibs
+	if !reflect.DeepEqual(actual, expected) {
+		t.Errorf("incorrect static_libs"+
+			"\nactual:   %v"+
+			"\nexpected: %v",
+			actual,
+			expected,
+		)
+	}
+}
+
+const staticLibAndroidBp = `
+	cc_library {
+		name: "lib1",
+	}
+	cc_binary {
+		name: "bin1",
+		static_libs: ["lib1"],
+	}
+	cc_library_host_static {
+		name: "lib2",
+		target: {
+			windows: {
+				enabled: true,
+			},
+		}
+	}
+	cc_binary_host {
+		name: "bin2",
+		static_libs: ["lib2"],
+		stl: "libc++_static",
+		target: {
+			windows: {
+				enabled: true,
+			},
+		},
+	}
+`
+
+func TestStaticLibs(t *testing.T) {
+	ctx := testCc(t, staticLibAndroidBp)
+
+	// Check a device binary.
+	variant := "android_arm64_armv8-a_core"
+	module := ctx.ModuleForTests("bin1", variant).Module().(*Module)
+	checkStaticLibs(t, []string{"lib1", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc"}, module)
+
+	// Check a host binary.
+	variant = "linux_glibc_x86_64"
+	module = ctx.ModuleForTests("bin2", variant).Module().(*Module)
+	checkStaticLibs(t, []string{"lib2", "libc++_static"}, module)
+
+	// Check a host binary on Windows.
+	variant = "windows_x86"
+	module = ctx.ModuleForTests("bin2", variant).Module().(*Module)
+	checkStaticLibs(t, []string{"lib2", "libc++_static", "libwinpthread"}, module)
+}
+
 var compilerFlagsTestCases = []struct {
 	in  string
 	out bool