Skip to content

Commit 26c9df6

Browse files
committed
Add system_includes to cc_library/cc_binary
Previously even though the attribute was named `includes`, the paths added there were actually propagated through the `system_includes` attribute of compilation context. This lead to crosstools passing these flags with `-isystem` which was unexpected for first party code. Many non bazel-first projects have header directory structures that require custom include paths be propagated throughout the graph, the alternative to `includes` is to use `strip_include_prefix`. The downside of `strip_include_prefix` is that you add 1 include path per `cc_library`, even if the libraries are in the same package. With `includes` these are deduplicated. In the case of LLVM using `includes` reduced the number of search paths on the order of hundreds. If users want to use `-isystem` for third party code that uses `includes`, they can pass `--features=external_include_paths --host_features=external_include_paths` Fixes bazelbuild#20267
1 parent 106903d commit 26c9df6

File tree

7 files changed

+87
-6
lines changed

7 files changed

+87
-6
lines changed

src/main/starlark/builtins_bzl/common/cc/attrs.bzl

+16
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,22 @@ Subject to <a href="${link make-variables}">"Make variable"</a> substitution.
132132
Each string is prepended with the package path and passed to the C++ toolchain for
133133
expansion via the "include_paths" CROSSTOOL feature. A toolchain running on a POSIX system
134134
with typical feature definitions will produce
135+
<code>-iquote path_to_package/include_entry</code>.
136+
Unlike <a href="#cc_binary.copts">COPTS</a>, these flags are added for this rule
137+
and every rule that depends on it. (Note: not the rules it depends upon!) Be
138+
very careful, since this may have far-reaching effects. When in doubt, add
139+
"-I" flags to <a href="#cc_binary.copts">COPTS</a> instead.
140+
<p>
141+
The added <code>include</code> paths will include generated files as well as
142+
files in the source tree.
143+
</p>
144+
"""),
145+
"system_includes": attr.string_list(doc = """
146+
List of include dirs to be added to the compile line.
147+
Subject to <a href="${link make-variables}">"Make variable"</a> substitution.
148+
Each string is prepended with the package path and passed to the C++ toolchain for
149+
expansion via the "include_paths" CROSSTOOL feature. A toolchain running on a POSIX system
150+
with typical feature definitions will produce
135151
<code>-isystem path_to_package/include_entry</code>.
136152
This should only be used for third-party libraries that
137153
do not conform to the Google style of writing #include statements.

src/main/starlark/builtins_bzl/common/cc/cc_binary.bzl

+2-1
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,8 @@ def cc_binary_impl(ctx, additional_linkopts, force_linkstatic = False):
510510
cxx_flags = cc_helper.get_copts(ctx, feature_configuration, additional_make_variable_substitutions, attr = "cxxopts"),
511511
defines = cc_helper.defines(ctx, additional_make_variable_substitutions),
512512
local_defines = cc_helper.local_defines(ctx, additional_make_variable_substitutions) + cc_helper.get_local_defines_for_runfiles_lookup(ctx, ctx.attr.deps),
513-
system_includes = cc_helper.system_include_dirs(ctx, additional_make_variable_substitutions),
513+
includes = cc_helper.include_dirs(ctx, additional_make_variable_substitutions, attr = "includes"),
514+
system_includes = cc_helper.include_dirs(ctx, additional_make_variable_substitutions, attr = "system_includes"),
514515
private_hdrs = cc_helper.get_private_hdrs(ctx),
515516
public_hdrs = cc_helper.get_public_hdrs(ctx),
516517
copts_filter = cc_helper.copts_filter(ctx, additional_make_variable_substitutions),

src/main/starlark/builtins_bzl/common/cc/cc_helper.bzl

+3-3
Original file line numberDiff line numberDiff line change
@@ -1062,13 +1062,13 @@ def _package_source_root(repository, package, sibling_repository_layout):
10621062
repository = repository[1:]
10631063
return paths.get_relative(paths.get_relative("external", repository), package)
10641064

1065-
def _system_include_dirs(ctx, additional_make_variable_substitutions):
1065+
def _include_dirs(ctx, additional_make_variable_substitutions, *, attr):
10661066
result = []
10671067
sibling_repository_layout = ctx.configuration.is_sibling_repository_layout()
10681068
package = ctx.label.package
10691069
package_exec_path = _package_exec_path(ctx, package, sibling_repository_layout)
10701070
package_source_root = _package_source_root(ctx.label.workspace_name, package, sibling_repository_layout)
1071-
for include in ctx.attr.includes:
1071+
for include in getattr(ctx.attr, attr, []):
10721072
includes_attr = _expand(ctx, include, additional_make_variable_substitutions)
10731073
if includes_attr.startswith("/"):
10741074
continue
@@ -1264,7 +1264,7 @@ cc_helper = struct(
12641264
get_private_hdrs = _get_private_hdrs,
12651265
get_public_hdrs = _get_public_hdrs,
12661266
report_invalid_options = _report_invalid_options,
1267-
system_include_dirs = _system_include_dirs,
1267+
include_dirs = _include_dirs,
12681268
get_coverage_environment = _get_coverage_environment,
12691269
create_cc_instrumented_files_info = _create_cc_instrumented_files_info,
12701270
linkopts = _linkopts,

src/main/starlark/builtins_bzl/common/cc/cc_library.bzl

+2-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ def _cc_library_impl(ctx):
6363
cxx_flags = cc_helper.get_copts(ctx, feature_configuration, additional_make_variable_substitutions, attr = "cxxopts"),
6464
defines = cc_helper.defines(ctx, additional_make_variable_substitutions),
6565
local_defines = cc_helper.local_defines(ctx, additional_make_variable_substitutions) + cc_helper.get_local_defines_for_runfiles_lookup(ctx, ctx.attr.deps + ctx.attr.implementation_deps),
66-
system_includes = cc_helper.system_include_dirs(ctx, additional_make_variable_substitutions),
66+
includes = cc_helper.include_dirs(ctx, additional_make_variable_substitutions, attr = "includes"),
67+
system_includes = cc_helper.include_dirs(ctx, additional_make_variable_substitutions, attr = "system_includes"),
6768
copts_filter = cc_helper.copts_filter(ctx, additional_make_variable_substitutions),
6869
purpose = "cc_library-compile",
6970
srcs = cc_helper.get_srcs(ctx),

src/main/starlark/builtins_bzl/common/objc/compilation_support.bzl

+1-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ def _build_common_variables(
105105
has_module_map = has_module_map,
106106
attr_linkopts = attr_linkopts,
107107
direct_cc_compilation_contexts = direct_cc_compilation_contexts,
108-
includes = cc_helper.system_include_dirs(ctx, {}) if hasattr(ctx.attr, "includes") else [],
108+
includes = cc_helper.include_dirs(ctx, {}, attr = "includes"),
109109
)
110110

111111
return struct(

src/test/java/com/google/devtools/build/lib/rules/cpp/CcCommonTest.java

+54
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,60 @@ public void testUseIsystemForIncludes() throws Exception {
644644
.containsExactlyElementsIn(expected);
645645
}
646646

647+
@Test
648+
public void testSystemAndNormalIncludes() throws Exception {
649+
scratch.file(
650+
"BUILD",
651+
"""
652+
cc_library(
653+
name = "no_includes",
654+
srcs = ["no_includes.cc"],
655+
)
656+
657+
cc_library(
658+
name = "lib",
659+
srcs = ["lib.cc"],
660+
includes = ["normal-includes"],
661+
system_includes = ["system-includes"],
662+
)
663+
cc_library(
664+
name = "bin",
665+
srcs = ["bin.cc"],
666+
includes = ["normal-includes"],
667+
system_includes = ["system-includes"],
668+
)
669+
""");
670+
ConfiguredTarget noIncludes = getConfiguredTarget("//:no_includes");
671+
ConfiguredTarget lib = getConfiguredTarget("//:lib");
672+
ConfiguredTarget bin = getConfiguredTarget("//:bin");
673+
674+
String systemRoot = "system-includes";
675+
List<PathFragment> expectedSystem =
676+
new ImmutableList.Builder<PathFragment>()
677+
.addAll(
678+
noIncludes.get(CcInfo.PROVIDER).getCcCompilationContext().getSystemIncludeDirs())
679+
.add(PathFragment.create(systemRoot))
680+
.add(targetConfig.getBinFragment(RepositoryName.MAIN).getRelative(systemRoot))
681+
.build();
682+
assertThat(lib.get(CcInfo.PROVIDER).getCcCompilationContext().getSystemIncludeDirs())
683+
.containsExactlyElementsIn(expectedSystem);
684+
assertThat(bin.get(CcInfo.PROVIDER).getCcCompilationContext().getSystemIncludeDirs())
685+
.containsExactlyElementsIn(expectedSystem);
686+
687+
String normalRoot = "normal-includes";
688+
List<PathFragment> expectedNormalIncludes =
689+
new ImmutableList.Builder<PathFragment>()
690+
.addAll(
691+
noIncludes.get(CcInfo.PROVIDER).getCcCompilationContext().getSystemIncludeDirs())
692+
.add(PathFragment.create(normalRoot))
693+
.add(targetConfig.getBinFragment(RepositoryName.MAIN).getRelative(normalRoot))
694+
.build();
695+
assertThat(lib.get(CcInfo.PROVIDER).getCcCompilationContext().getIncludeDirs())
696+
.containsExactlyElementsIn(expectedNormalIncludes);
697+
assertThat(bin.get(CcInfo.PROVIDER).getCcCompilationContext().getIncludeDirs())
698+
.containsExactlyElementsIn(expectedNormalIncludes);
699+
}
700+
647701
@Test
648702
public void testCcTestDisallowsAlwaysLink() throws Exception {
649703
scratch.file(

src/test/java/com/google/devtools/build/lib/rules/objc/ObjcLibraryTest.java

+9
Original file line numberDiff line numberDiff line change
@@ -1381,6 +1381,7 @@ public void testIncludesDirsOfTransitiveCcDepsGetPassedToCompileAction() throws
13811381
name = "cc_lib",
13821382
srcs = ["a.cc"],
13831383
includes = ["foo/bar"],
1384+
system_includes = ["baz/qux"],
13841385
)
13851386
13861387
objc_library(
@@ -1397,6 +1398,14 @@ public void testIncludesDirsOfTransitiveCcDepsGetPassedToCompileAction() throws
13971398
Iterables.concat(
13981399
Iterables.transform(
13991400
rootedIncludePaths("package/foo/bar"),
1401+
element -> ImmutableList.of("-I" + element)))));
1402+
1403+
assertContainsSublist(
1404+
removeConfigFragment(removeConfigFragment(compileAction.getArguments())),
1405+
ImmutableList.copyOf(
1406+
Iterables.concat(
1407+
Iterables.transform(
1408+
rootedIncludePaths("package/baz/qux"),
14001409
element -> ImmutableList.of("-isystem", element)))));
14011410
}
14021411

0 commit comments

Comments
 (0)