Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cc/common/cc_helper.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -814,13 +814,13 @@ def _get_cc_flags_make_variable(_ctx, feature_configuration, cc_toolchain):
def _package_exec_path(ctx, package, sibling_repository_layout):
return get_relative_path(_repository_exec_path(ctx.label.workspace_name, sibling_repository_layout), package)

def _include_dirs(ctx, additional_make_variable_substitutions):
def _include_dirs(ctx, additional_make_variable_substitutions, attr = "includes"):
result = []
sibling_repository_layout = ctx.configuration.is_sibling_repository_layout()
package = ctx.label.package
package_exec_path = _package_exec_path(ctx, package, sibling_repository_layout)
package_source_root = _package_source_root(ctx.label.workspace_name, package, sibling_repository_layout)
for include in ctx.attr.includes:
for include in getattr(ctx.attr, attr):
includes_attr = _expand(ctx, include, additional_make_variable_substitutions)
if is_path_absolute(includes_attr):
continue
Expand Down
2 changes: 2 additions & 0 deletions cc/private/cc_common.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,7 @@ def _compile(
textual_hdrs = [],
additional_exported_hdrs = _UNBOUND, # TODO(ilist@): remove, there are no uses
includes = [],
local_includes = [],
quote_includes = [],
system_includes = [],
framework_includes = [],
Expand Down Expand Up @@ -546,6 +547,7 @@ def _compile(
textual_hdrs = textual_hdrs,
additional_exported_hdrs = additional_exported_hdrs,
includes = includes,
local_includes = local_includes,
quote_includes = quote_includes,
system_includes = system_includes,
framework_includes = framework_includes,
Expand Down
8 changes: 8 additions & 0 deletions cc/private/cc_info.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ CcCompilationContextInfo = provider(
# CommandLineCcCompilationContext fields:
"includes": "Returns the set of search paths (as strings) for header files referenced " +
"both by angle bracket and quotes. Usually passed with -I.",
"local_includes": "Returns the set of search paths (as strings) for header files referenced " +
"both by angle bracket and quotes. Usually passed with -I. These values " +
"are not propagated to the target's transitive dependents.",
"quote_includes": "Returns the set of search paths (as strings) for header files " +
"referenced by quotes, e.g. #include \"foo/bar/header.h\". They can be " +
"either relative to the exec root or absolute. Usually passed with -iquote.",
Expand Down Expand Up @@ -114,6 +117,7 @@ EMPTY_COMPILATION_CONTEXT = CcCompilationContextInfo(
direct_private_headers = [],
direct_textual_headers = [],
includes = depset(),
local_includes = depset(),
quote_includes = depset(),
system_includes = depset(),
framework_includes = depset(),
Expand Down Expand Up @@ -276,6 +280,7 @@ def create_compilation_context(
*,
headers = None,
includes = None,
local_includes = None,
quote_includes = None,
system_includes = None,
framework_includes = None,
Expand All @@ -302,6 +307,7 @@ def create_compilation_context(
Args:
headers: A depset of headers to compile.
includes: A depset of include directories.
local_includes: A depset of local include directories.
quote_includes: A depset of quoted include directories.
system_includes: A depset of system include directories.
framework_includes: A depset of framework include directories.
Expand Down Expand Up @@ -361,6 +367,7 @@ def create_compilation_context(
direct_private_headers = header_info.modular_private_headers,
direct_textual_headers = header_info.textual_headers,
includes = includes,
local_includes = local_includes,
quote_includes = quote_includes,
system_includes = system_includes,
framework_includes = framework_includes,
Expand Down Expand Up @@ -466,6 +473,7 @@ def _merge_compilation_contexts(*, compilation_context = EMPTY_COMPILATION_CONTE
transitive = [dep.defines for dep in all_deps] + [compilation_context.defines],
),
local_defines = compilation_context.local_defines,
local_includes = compilation_context.local_includes,
headers = depset(
direct = compilation_context.headers.to_list(),
transitive = [dep.headers for dep in all_deps],
Expand Down
2 changes: 2 additions & 0 deletions cc/private/compile/cc_compilation_helper.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@ def _init_cc_compilation_context(
framework_include_dirs,
system_include_dirs,
include_dirs,
local_includes,
feature_configuration,
public_headers_artifacts,
include_prefix,
Expand Down Expand Up @@ -559,6 +560,7 @@ def _init_cc_compilation_context(
external_includes = depset(external_include_dirs),
system_includes = depset(system_include_dirs_for_context),
includes = depset(include_dirs_for_context),
local_includes = depset(local_includes),
virtual_to_original_headers = virtual_to_original_headers,
dependent_cc_compilation_contexts = dependent_cc_compilation_contexts,
non_code_inputs = additional_inputs,
Expand Down
2 changes: 2 additions & 0 deletions cc/private/compile/compile.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ def compile(
textual_hdrs = [],
additional_exported_hdrs = [],
includes = [],
local_includes = [],
# TODO(b/396122076): seems unused; double-check and remove
loose_includes = None, # buildifier: disable=unused-variable
quote_includes = [],
Expand Down Expand Up @@ -292,6 +293,7 @@ def compile(
framework_include_dirs = framework_includes,
system_include_dirs = system_includes,
include_dirs = includes,
local_includes = local_includes,
feature_configuration = feature_configuration,
public_headers_artifacts = public_hdrs_artifacts,
include_prefix = include_prefix,
Expand Down
7 changes: 6 additions & 1 deletion cc/private/compile/compile_build_variables.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ def create_compile_variables(
output_file = None,
user_compile_flags = None,
includes = None,
local_includes = None,
include_directories = None,
quote_include_directories = None,
system_include_directories = None,
Expand Down Expand Up @@ -123,6 +124,7 @@ def create_compile_variables(
includes: paths to headers that should be included using -include
user_compile_flags: List of additional compilation flags (copts).
include_directories: Depset of include directories.
local_includes: Depset of local include directories.
quote_include_directories: Depset of quote include directories.
system_include_directories: Depset of system include directories.
framework_include_directories: Depset of framework include directories.
Expand Down Expand Up @@ -158,6 +160,7 @@ def create_compile_variables(
fdo_build_stamp = _get_fdo_build_stamp(cpp_configuration, fdo_context, feature_configuration),
variables_extension = variables_extension,
includes = includes or [],
local_includes = local_includes or depset(),
include_dirs = include_directories or depset(),
quote_include_dirs = quote_include_directories or depset(),
system_include_dirs = system_include_directories or depset(),
Expand Down Expand Up @@ -198,6 +201,7 @@ def setup_common_compile_build_variables(
fdo_build_stamp = _get_fdo_build_stamp(cpp_configuration, fdo_context, feature_configuration),
variables_extension = variables_extension,
include_dirs = cc_compilation_context.includes,
local_includes = cc_compilation_context.local_includes,
quote_include_dirs = cc_compilation_context.quote_includes,
system_include_dirs = cc_compilation_context.system_includes,
framework_include_dirs = cc_compilation_context.framework_includes,
Expand All @@ -216,6 +220,7 @@ def _setup_common_compile_build_variables_internal(
variables_extension = [], # [dict{str,object}]
additional_build_variables = {}, # dict{str,str}
include_dirs = depset(),
local_includes = depset(),
quote_include_dirs = depset(),
system_include_dirs = depset(),
framework_include_dirs = depset(),
Expand All @@ -226,7 +231,7 @@ def _setup_common_compile_build_variables_internal(

if feature_configuration.is_enabled("use_header_modules"):
result[_VARS.MODULE_FILES] = []
result[_VARS.INCLUDE_PATHS] = include_dirs
result[_VARS.INCLUDE_PATHS] = depset(transitive = [include_dirs, local_includes])
result[_VARS.QUOTE_INCLUDE_PATHS] = quote_include_dirs
result[_VARS.SYSTEM_INCLUDE_PATHS] = system_include_dirs
if includes:
Expand Down
14 changes: 14 additions & 0 deletions cc/private/rules_impl/attrs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,20 @@ very careful, since this may have far-reaching effects. When in doubt, add
The added <code>include</code> paths will include generated files as well as
files in the source tree.
</p>
"""),
"local_includes": attr.string_list(doc = """
List of include dirs to be added to the compile line.
Subject to <a href="${link make-variables}">"Make variable"</a> substitution.
Each string is prepended with the package path and passed to the C++ toolchain for
expansion via the "include_paths" CROSSTOOL feature. A toolchain running on a
POSIX system with typical feature definitions will produce
<code>-I path_to_package/include_entry</code>.

Unlike <a href="#cc_binary.includes">INCLUDES</a>, these flags are added for
this target and not added to every target that depends on it.

The added <code>include</code> paths will include generated files as well as
files in the source tree.
"""),
"defines": attr.string_list(doc = """
List of defines to add to the compile line of this and all dependent targets.
Expand Down
1 change: 1 addition & 0 deletions cc/private/rules_impl/cc_binary.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,7 @@ def cc_binary_impl(ctx, additional_linkopts, force_linkstatic = False):
defines = cc_helper.defines(ctx, additional_make_variable_substitutions),
local_defines = cc_helper.local_defines(ctx, additional_make_variable_substitutions) + cc_helper.get_local_defines_for_runfiles_lookup(ctx, ctx.attr.deps),
includes = cc_helper.include_dirs(ctx, additional_make_variable_substitutions),
local_includes = cc_helper.include_dirs(ctx, additional_make_variable_substitutions, attr = "local_includes"),
private_hdrs = cc_helper.get_private_hdrs(ctx),
public_hdrs = cc_helper.get_public_hdrs(ctx),
copts_filter = cc_helper.copts_filter(ctx, additional_make_variable_substitutions),
Expand Down
1 change: 1 addition & 0 deletions cc/private/rules_impl/cc_library.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ def _cc_library_impl(ctx):
defines = cc_helper.defines(ctx, additional_make_variable_substitutions),
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),
includes = cc_helper.include_dirs(ctx, additional_make_variable_substitutions),
local_includes = cc_helper.include_dirs(ctx, additional_make_variable_substitutions, attr = "local_includes"),
copts_filter = cc_helper.copts_filter(ctx, additional_make_variable_substitutions),
purpose = "cc_library-compile",
srcs = cc_helper.get_srcs(ctx),
Expand Down
47 changes: 47 additions & 0 deletions tests/local_includes/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Copyright 2025 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

load("//cc:cc_binary.bzl", "cc_binary")
load("//cc:cc_library.bzl", "cc_library")

licenses(["notice"])

cc_library(
name = "lib",
srcs = [
"lib/lib.c",
"lib/private/private.c",
"lib/private/private.h",
],
hdrs = ["lib/include/public.h"],
includes = [
"lib/include",
],
local_includes = [
"lib/private",
],
)

cc_binary(
name = "bin",
srcs = [
"binary.c",
"binary_helper.c",
"private/binary_helper.h",
],
local_includes = [
"private",
],
deps = [":lib"],
)
11 changes: 11 additions & 0 deletions tests/local_includes/binary.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "binary_helper.h"
#include "public.h"

#if __has_include("private.h")
#error "private.h should not be on the include path"
#endif


int main() {
return foo() + helper();
}
3 changes: 3 additions & 0 deletions tests/local_includes/binary_helper.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
int helper() {
return 42;
}
1 change: 1 addition & 0 deletions tests/local_includes/lib/include/public.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
int foo();
5 changes: 5 additions & 0 deletions tests/local_includes/lib/lib.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include "private.h"

int foo() {
return bar();
}
3 changes: 3 additions & 0 deletions tests/local_includes/lib/private/private.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
int bar() {
return 0;
}
1 change: 1 addition & 0 deletions tests/local_includes/lib/private/private.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
int bar();
1 change: 1 addition & 0 deletions tests/local_includes/private/binary_helper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
int helper();