Merge "Split local/absolute include into attributes"
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index c2c35e7..371593b 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -255,13 +255,11 @@
 		blueprint: soongCcLibraryPreamble,
 		expectedBazelTargets: []string{`cc_library(
     name = "fake-libarm-optimized-routines-math",
-    copts = [
-        "-Iexternal",
-        "-I$(BINDIR)/external",
-    ] + select({
+    copts = select({
         "//build/bazel/platforms/arch:arm64": ["-DHAVE_FAST_FMA=1"],
         "//conditions:default": [],
     }),
+    local_includes = ["."],
     srcs_c = ["math/cosf.c"],
 )`},
 	})
@@ -494,12 +492,9 @@
 		blueprint: soongCcLibraryPreamble,
 		expectedBazelTargets: []string{`cc_library(
     name = "a",
-    copts = [
-        "bothflag",
-        "-Ifoo/bar",
-        "-I$(BINDIR)/foo/bar",
-    ],
+    copts = ["bothflag"],
     implementation_deps = [":static_dep_for_both"],
+    local_includes = ["."],
     shared = {
         "copts": ["sharedflag"] + select({
             "//build/bazel/platforms/arch:arm": ["-DARM_SHARED"],
@@ -635,14 +630,7 @@
 		blueprint: soongCcLibraryPreamble,
 		expectedBazelTargets: []string{`cc_library(
     name = "a",
-    asflags = [
-        "-Ifoo/bar",
-        "-I$(BINDIR)/foo/bar",
-    ],
-    copts = [
-        "-Ifoo/bar",
-        "-I$(BINDIR)/foo/bar",
-    ],
+    local_includes = ["."],
     shared = {
         "srcs": [
             ":shared_filegroup_cpp_srcs",
diff --git a/bp2build/cc_library_headers_conversion_test.go b/bp2build/cc_library_headers_conversion_test.go
index 8b490f8..37d806c 100644
--- a/bp2build/cc_library_headers_conversion_test.go
+++ b/bp2build/cc_library_headers_conversion_test.go
@@ -130,10 +130,6 @@
 }`,
 		expectedBazelTargets: []string{`cc_library_headers(
     name = "foo_headers",
-    copts = [
-        "-I.",
-        "-I$(BINDIR)/.",
-    ],
     export_includes = [
         "dir-1",
         "dir-2",
diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go
index 5c9afbf..72034fa 100644
--- a/bp2build/cc_library_static_conversion_test.go
+++ b/bp2build/cc_library_static_conversion_test.go
@@ -184,19 +184,13 @@
 }`,
 		expectedBazelTargets: []string{`cc_library_static(
     name = "foo_static",
+    absolute_includes = [
+        "include_dir_1",
+        "include_dir_2",
+    ],
     copts = [
         "-Dflag1",
         "-Dflag2",
-        "-Iinclude_dir_1",
-        "-I$(BINDIR)/include_dir_1",
-        "-Iinclude_dir_2",
-        "-I$(BINDIR)/include_dir_2",
-        "-Ilocal_include_dir_1",
-        "-I$(BINDIR)/local_include_dir_1",
-        "-Ilocal_include_dir_2",
-        "-I$(BINDIR)/local_include_dir_2",
-        "-I.",
-        "-I$(BINDIR)/.",
     ],
     export_includes = [
         "export_include_dir_1",
@@ -209,6 +203,11 @@
         ":static_lib_2",
     ],
     linkstatic = True,
+    local_includes = [
+        "local_include_dir_1",
+        "local_include_dir_2",
+        ".",
+    ],
     srcs = [
         "foo_static1.cc",
         "foo_static2.cc",
@@ -244,21 +243,16 @@
 		blueprint: soongCcLibraryStaticPreamble + `
 cc_library_static {
     name: "foo_static",
-    srcs: [
-    ],
+    srcs: [],
     include_dirs: [
-  "subpackage",
+        "subpackage",
     ],
 }`,
 		expectedBazelTargets: []string{`cc_library_static(
     name = "foo_static",
-    copts = [
-        "-Isubpackage",
-        "-I$(BINDIR)/subpackage",
-        "-I.",
-        "-I$(BINDIR)/.",
-    ],
+    absolute_includes = ["subpackage"],
     linkstatic = True,
+    local_includes = ["."],
 )`},
 	})
 }
@@ -347,20 +341,17 @@
 		blueprint: soongCcLibraryStaticPreamble,
 		expectedBazelTargets: []string{`cc_library_static(
     name = "foo_static",
-    copts = [
-        "-Isubpackage/subsubpackage",
-        "-I$(BINDIR)/subpackage/subsubpackage",
-        "-Isubpackage2",
-        "-I$(BINDIR)/subpackage2",
-        "-Isubpackage3/subsubpackage",
-        "-I$(BINDIR)/subpackage3/subsubpackage",
-        "-Isubpackage/subsubpackage2",
-        "-I$(BINDIR)/subpackage/subsubpackage2",
-        "-Isubpackage",
-        "-I$(BINDIR)/subpackage",
+    absolute_includes = [
+        "subpackage/subsubpackage",
+        "subpackage2",
+        "subpackage3/subsubpackage",
     ],
     export_includes = ["./exported_subsubpackage"],
     linkstatic = True,
+    local_includes = [
+        "subsubpackage2",
+        ".",
+    ],
 )`},
 	})
 }
@@ -386,13 +377,9 @@
 }`,
 		expectedBazelTargets: []string{`cc_library_static(
     name = "foo_static",
-    copts = [
-        "-Isubpackage",
-        "-I$(BINDIR)/subpackage",
-        "-Isubpackage2",
-        "-I$(BINDIR)/subpackage2",
-    ],
+    absolute_includes = ["subpackage"],
     linkstatic = True,
+    local_includes = ["subpackage2"],
 )`},
 	})
 }
@@ -420,15 +407,12 @@
 }`,
 		expectedBazelTargets: []string{`cc_library_static(
     name = "foo_static",
-    copts = [
-        "-Isubpackage",
-        "-I$(BINDIR)/subpackage",
-        "-Isubpackage2",
-        "-I$(BINDIR)/subpackage2",
-        "-I.",
-        "-I$(BINDIR)/.",
-    ],
+    absolute_includes = ["subpackage"],
     linkstatic = True,
+    local_includes = [
+        "subpackage2",
+        ".",
+    ],
 )`},
 	})
 }
diff --git a/bp2build/cc_object_conversion_test.go b/bp2build/cc_object_conversion_test.go
index 4bda539..b0a88ae 100644
--- a/bp2build/cc_object_conversion_test.go
+++ b/bp2build/cc_object_conversion_test.go
@@ -65,10 +65,10 @@
         "-Wno-gcc-compat",
         "-Wall",
         "-Werror",
-        "-Iinclude",
-        "-I$(BINDIR)/include",
-        "-I.",
-        "-I$(BINDIR)/.",
+    ],
+    local_includes = [
+        "include",
+        ".",
     ],
     srcs = ["a/b/c.c"],
 )`,
@@ -113,9 +113,8 @@
         "-Wall",
         "-Werror",
         "-fno-addrsig",
-        "-I.",
-        "-I$(BINDIR)/.",
     ],
+    local_includes = ["."],
     srcs = ["a/b/c.c"],
 )`,
 		}})
diff --git a/cc/bp2build.go b/cc/bp2build.go
index fffb093..7a98fd0 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -216,6 +216,9 @@
 	srcs     bazel.LabelListAttribute
 
 	rtti bazel.BoolAttribute
+
+	localIncludes    bazel.StringListAttribute
+	absoluteIncludes bazel.StringListAttribute
 }
 
 // bp2BuildParseCompilerProps returns copts, srcs and hdrs and other attributes.
@@ -226,28 +229,8 @@
 	var conlyFlags bazel.StringListAttribute
 	var cppFlags bazel.StringListAttribute
 	var rtti bazel.BoolAttribute
-
-	// Creates the -I flags for a directory, while making the directory relative
-	// to the exec root for Bazel to work.
-	includeFlags := func(dir string) []string {
-		// filepath.Join canonicalizes the path, i.e. it takes care of . or .. elements.
-		moduleDirRootedPath := filepath.Join(ctx.ModuleDir(), dir)
-		return []string{
-			"-I" + moduleDirRootedPath,
-			// Include the bindir-rooted path (using make variable substitution). This most
-			// closely matches Bazel's native include path handling, which allows for dependency
-			// on generated headers in these directories.
-			// TODO(b/188084383): Handle local include directories in Bazel.
-			"-I$(BINDIR)/" + moduleDirRootedPath,
-		}
-	}
-
-	// Parse the list of module-relative include directories (-I).
-	parseLocalIncludeDirs := func(baseCompilerProps *BaseCompilerProperties) []string {
-		// include_dirs are root-relative, not module-relative.
-		includeDirs := bp2BuildMakePathsRelativeToModule(ctx, baseCompilerProps.Include_dirs)
-		return append(includeDirs, baseCompilerProps.Local_include_dirs...)
-	}
+	var localIncludes bazel.StringListAttribute
+	var absoluteIncludes bazel.StringListAttribute
 
 	parseCommandLineFlags := func(soongFlags []string) []string {
 		var result []string
@@ -285,18 +268,14 @@
 
 				archVariantCopts := parseCommandLineFlags(baseCompilerProps.Cflags)
 				archVariantAsflags := parseCommandLineFlags(baseCompilerProps.Asflags)
-				for _, dir := range parseLocalIncludeDirs(baseCompilerProps) {
-					archVariantCopts = append(archVariantCopts, includeFlags(dir)...)
-					archVariantAsflags = append(archVariantAsflags, includeFlags(dir)...)
+
+				localIncludeDirs := baseCompilerProps.Local_include_dirs
+				if axis == bazel.NoConfigAxis && includeBuildDirectory(baseCompilerProps.Include_build_directory) {
+					localIncludeDirs = append(localIncludeDirs, ".")
 				}
 
-				if axis == bazel.NoConfigAxis {
-					if includeBuildDirectory(baseCompilerProps.Include_build_directory) {
-						flags := includeFlags(".")
-						archVariantCopts = append(archVariantCopts, flags...)
-						archVariantAsflags = append(archVariantAsflags, flags...)
-					}
-				}
+				absoluteIncludes.SetSelectValue(axis, config, baseCompilerProps.Include_dirs)
+				localIncludes.SetSelectValue(axis, config, localIncludeDirs)
 
 				copts.SetSelectValue(axis, config, archVariantCopts)
 				asFlags.SetSelectValue(axis, config, archVariantAsflags)
@@ -308,6 +287,8 @@
 	}
 
 	srcs.ResolveExcludes()
+	absoluteIncludes.DeduplicateAxesFromBase()
+	localIncludes.DeduplicateAxesFromBase()
 
 	productVarPropNameToAttribute := map[string]*bazel.StringListAttribute{
 		"Cflags":   &copts,
@@ -331,14 +312,16 @@
 	srcs, cSrcs, asSrcs := groupSrcsByExtension(ctx, srcs)
 
 	return compilerAttributes{
-		copts:      copts,
-		srcs:       srcs,
-		asFlags:    asFlags,
-		asSrcs:     asSrcs,
-		cSrcs:      cSrcs,
-		conlyFlags: conlyFlags,
-		cppFlags:   cppFlags,
-		rtti:       rtti,
+		copts:            copts,
+		srcs:             srcs,
+		asFlags:          asFlags,
+		asSrcs:           asSrcs,
+		cSrcs:            cSrcs,
+		conlyFlags:       conlyFlags,
+		cppFlags:         cppFlags,
+		rtti:             rtti,
+		localIncludes:    localIncludes,
+		absoluteIncludes: absoluteIncludes,
 	}
 }
 
diff --git a/cc/library.go b/cc/library.go
index 28bd741..f568247 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -236,6 +236,8 @@
 	System_dynamic_deps    bazel.LabelListAttribute
 	Export_includes        bazel.StringListAttribute
 	Export_system_includes bazel.StringListAttribute
+	Local_includes         bazel.StringListAttribute
+	Absolute_includes      bazel.StringListAttribute
 	Linkopts               bazel.StringListAttribute
 	Use_libcrt             bazel.BoolAttribute
 	Rtti                   bazel.BoolAttribute
@@ -307,6 +309,8 @@
 		System_dynamic_deps:    linkerAttrs.systemDynamicDeps,
 		Export_includes:        exportedIncludes.Includes,
 		Export_system_includes: exportedIncludes.SystemIncludes,
+		Local_includes:         compilerAttrs.localIncludes,
+		Absolute_includes:      compilerAttrs.absoluteIncludes,
 		Linkopts:               linkerAttrs.linkopts,
 		Use_libcrt:             linkerAttrs.useLibcrt,
 		Rtti:                   compilerAttrs.rtti,
@@ -2333,6 +2337,8 @@
 	Rtti                   bazel.BoolAttribute
 	Export_includes        bazel.StringListAttribute
 	Export_system_includes bazel.StringListAttribute
+	Local_includes         bazel.StringListAttribute
+	Absolute_includes      bazel.StringListAttribute
 	Hdrs                   bazel.LabelListAttribute
 
 	Cppflags   bazel.StringListAttribute
@@ -2384,6 +2390,8 @@
 		Rtti:                   compilerAttrs.rtti,
 		Export_includes:        exportedIncludes.Includes,
 		Export_system_includes: exportedIncludes.SystemIncludes,
+		Local_includes:         compilerAttrs.localIncludes,
+		Absolute_includes:      compilerAttrs.absoluteIncludes,
 
 		Cppflags:   compilerAttrs.cppFlags,
 		Srcs_c:     compilerAttrs.cSrcs,
diff --git a/cc/library_headers.go b/cc/library_headers.go
index 30a81cc..14b90c1 100644
--- a/cc/library_headers.go
+++ b/cc/library_headers.go
@@ -103,7 +103,6 @@
 }
 
 type bazelCcLibraryHeadersAttributes struct {
-	Copts                  bazel.StringListAttribute
 	Hdrs                   bazel.LabelListAttribute
 	Export_includes        bazel.StringListAttribute
 	Export_system_includes bazel.StringListAttribute
@@ -128,11 +127,9 @@
 	}
 
 	exportedIncludes := bp2BuildParseExportedIncludes(ctx, module)
-	compilerAttrs := bp2BuildParseCompilerProps(ctx, module)
 	linkerAttrs := bp2BuildParseLinkerProps(ctx, module)
 
 	attrs := &bazelCcLibraryHeadersAttributes{
-		Copts:                  compilerAttrs.copts,
 		Export_includes:        exportedIncludes.Includes,
 		Export_system_includes: exportedIncludes.SystemIncludes,
 		Implementation_deps:    linkerAttrs.deps,
diff --git a/cc/object.go b/cc/object.go
index 606e368..99b257a 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -122,12 +122,14 @@
 
 // For bp2build conversion.
 type bazelObjectAttributes struct {
-	Srcs    bazel.LabelListAttribute
-	Srcs_as bazel.LabelListAttribute
-	Hdrs    bazel.LabelListAttribute
-	Deps    bazel.LabelListAttribute
-	Copts   bazel.StringListAttribute
-	Asflags bazel.StringListAttribute
+	Srcs              bazel.LabelListAttribute
+	Srcs_as           bazel.LabelListAttribute
+	Hdrs              bazel.LabelListAttribute
+	Deps              bazel.LabelListAttribute
+	Copts             bazel.StringListAttribute
+	Asflags           bazel.StringListAttribute
+	Local_includes    bazel.StringListAttribute
+	Absolute_includes bazel.StringListAttribute
 }
 
 // ObjectBp2Build is the bp2build converter from cc_object modules to the
@@ -170,11 +172,13 @@
 	}
 
 	attrs := &bazelObjectAttributes{
-		Srcs:    srcs,
-		Srcs_as: compilerAttrs.asSrcs,
-		Deps:    deps,
-		Copts:   compilerAttrs.copts,
-		Asflags: asFlags,
+		Srcs:              srcs,
+		Srcs_as:           compilerAttrs.asSrcs,
+		Deps:              deps,
+		Copts:             compilerAttrs.copts,
+		Asflags:           asFlags,
+		Local_includes:    compilerAttrs.localIncludes,
+		Absolute_includes: compilerAttrs.absoluteIncludes,
 	}
 
 	props := bazel.BazelTargetModuleProperties{