Add support for per-target exported includes.

Test: Added unit test
Change-Id: I8ab58ddc73c15d5ec0f515e43407542bd4e8081a
diff --git a/bp2build/cc_library_headers_conversion_test.go b/bp2build/cc_library_headers_conversion_test.go
index 3180267..00042ab 100644
--- a/bp2build/cc_library_headers_conversion_test.go
+++ b/bp2build/cc_library_headers_conversion_test.go
@@ -271,6 +271,63 @@
     }),
 )`},
 		},
+		{
+			description:                        "cc_library_headers test with arch-specific and target-specific export_system_include_dirs props",
+			moduleTypeUnderTest:                "cc_library_headers",
+			moduleTypeUnderTestFactory:         cc.LibraryHeaderFactory,
+			moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryHeadersBp2Build,
+			depsMutators:                       []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
+			filesystem:                         map[string]string{},
+			bp: soongCcLibraryPreamble + `cc_library_headers {
+    name: "foo_headers",
+    export_system_include_dirs: [
+	"shared_include_dir",
+    ],
+    target: {
+	android: {
+	    export_system_include_dirs: [
+		"android_include_dir",
+            ],
+	},
+        linux_glibc: {
+            export_system_include_dirs: [
+                "linux_include_dir",
+            ],
+        },
+        darwin: {
+            export_system_include_dirs: [
+                "darwin_include_dir",
+            ],
+        },
+    },
+    arch: {
+        arm: {
+	    export_system_include_dirs: [
+		"arm_include_dir",
+            ],
+	},
+        x86_64: {
+            export_system_include_dirs: [
+                "x86_64_include_dir",
+            ],
+        },
+    },
+}`,
+			expectedBazelTargets: []string{`cc_library_headers(
+    name = "foo_headers",
+    copts = ["-I."],
+    includes = ["shared_include_dir"] + select({
+        "//build/bazel/platforms/arch:arm": ["arm_include_dir"],
+        "//build/bazel/platforms/arch:x86_64": ["x86_64_include_dir"],
+        "//conditions:default": [],
+    }) + select({
+        "//build/bazel/platforms/os:android": ["android_include_dir"],
+        "//build/bazel/platforms/os:darwin": ["darwin_include_dir"],
+        "//build/bazel/platforms/os:linux": ["linux_include_dir"],
+        "//conditions:default": [],
+    }),
+)`},
+		},
 	}
 
 	dir := "."
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 79304a5..efa2752 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -262,6 +262,7 @@
 			archIncludeDirs = append(archIncludeDirs, flagExporterProperties.Export_include_dirs...)
 
 			// To avoid duplicate includes when base includes + arch includes are combined
+			// FIXME: This doesn't take conflicts between arch and os includes into account
 			archIncludeDirs = bazel.SubtractStrings(archIncludeDirs, includeDirs)
 
 			if len(archIncludeDirs) > 0 {
@@ -275,6 +276,7 @@
 			archHeaders = bazel.UniqueBazelLabelList(archHeaders)
 
 			// To avoid duplicate headers when base headers + arch headers are combined
+			// FIXME: This doesn't take conflicts between arch and os includes into account
 			archHeaders = bazel.SubtractBazelLabelList(archHeaders, headers)
 
 			if len(archHeaders.Includes) > 0 || len(archHeaders.Excludes) > 0 {
@@ -283,5 +285,34 @@
 		}
 	}
 
+	for os, props := range module.GetTargetProperties(&FlagExporterProperties{}) {
+		if flagExporterProperties, ok := props.(*FlagExporterProperties); ok {
+			osIncludeDirs := flagExporterProperties.Export_system_include_dirs
+			osIncludeDirs = append(osIncludeDirs, flagExporterProperties.Export_include_dirs...)
+
+			// To avoid duplicate includes when base includes + os includes are combined
+			// FIXME: This doesn't take conflicts between arch and os includes into account
+			osIncludeDirs = bazel.SubtractStrings(osIncludeDirs, includeDirs)
+
+			if len(osIncludeDirs) > 0 {
+				includeDirsAttribute.SetValueForOS(os.Name, osIncludeDirs)
+			}
+
+			var osHeaders bazel.LabelList
+			for _, osIncludeDir := range osIncludeDirs {
+				osHeaders.Append(bp2BuildListHeadersInDir(ctx, osIncludeDir))
+			}
+			osHeaders = bazel.UniqueBazelLabelList(osHeaders)
+
+			// To avoid duplicate headers when base headers + os headers are combined
+			// FIXME: This doesn't take conflicts between arch and os includes into account
+			osHeaders = bazel.SubtractBazelLabelList(osHeaders, headers)
+
+			if len(osHeaders.Includes) > 0 || len(osHeaders.Excludes) > 0 {
+				headersAttribute.SetValueForOS(os.Name, osHeaders)
+			}
+		}
+	}
+
 	return includeDirsAttribute, headersAttribute
 }