Skip to content

Use includes instead of system_includes for includes attr #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

arvi18
Copy link

@arvi18 arvi18 commented Apr 15, 2025

Previously even though the attribute was named includes it was passed
through the system_includes field of the compilation context. This
resulted in toolchains passing these include paths with -isystem,
which is unexpected if you use this 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

If there are first party libraries users want to use -isystem with,
they can use features = ["system_include_paths"]

Fixes bazelbuild#20267

RELNOTES[INC]: Use -I instead of -isystem for cc_library / cc_binary includes attr. To use -isystem for only external repositories, you can pass --features=external_include_paths --host_features=external_include_paths. To use -isystem for a single cc_library / cc_binary includes, you can set features = ["system_include_paths"], on the target

Previously even though the attribute was named `includes` it was passed
through the `system_includes` field of the compilation context. This
resulted in toolchains passing these include paths with `-isystem`,
which is unexpected if you use this 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`

If there are first party libraries users want to use `-isystem` with,
they can use `features = ["system_include_paths"]`

Fixes bazelbuild#20267

RELNOTES[INC]: Use `-I` instead of `-isystem` for `cc_library` / `cc_binary` `includes` attr. To use `-isystem` for only external repositories, you can pass `--features=external_include_paths --host_features=external_include_paths`. To use `-isystem` for a single `cc_library` / `cc_binary` `includes`, you can set `features = ["system_include_paths"],` on the target
@arvi18
Copy link
Author

arvi18 commented Apr 15, 2025

this requires a toolchain change in order to add a test, I can do that if folks are happy with this direction

@arvi18
Copy link
Author

arvi18 commented Apr 15, 2025

see the alternative here bazelbuild#25751

@arvi18
Copy link
Author

arvi18 commented Apr 15, 2025

Selfishly, we have on the order of a dozen+ cc_toolchains that will need to add the "system_include_paths" feature for backwards compatibility until we can spend the time to test the rollout.

I'm not opposed in principle, but can we add an incompatible flag for this? Or keep the current behavior if a feature is unset?

Open to suggestions, but I'd like to have a way to disable this globally (for our monorepo) without having to modify many toolchains.

@arvi18
Copy link
Author

arvi18 commented Apr 15, 2025

totally fair, I can add this behind an incompatible flag, before I do that on this one, should we consider bazelbuild#25751 or should I close that and move forward with this approach?

@arvi18
Copy link
Author

arvi18 commented Apr 15, 2025

it looks like there is another implementation option, we can use feature_configuration.is_requested instead of is_enabled so that toolchains don't have to contain the feature, then I imagine it could be added in the REPO.bazel to enable globally, without any toolchain updates. What do you think about that option? The downside is still that you'd have to handle --features=external_include_paths --host_features=external_include_paths separately

@arvi18
Copy link
Author

arvi18 commented Apr 15, 2025

I've updated to the is_requested approach because the tests have the same issue

@arvi18
Copy link
Author

arvi18 commented Apr 15, 2025

ok the CI failures here lead to some interesting discoveries. for one the BUILD files of both grpc and c-ares have undeclared inclusion errors lurking that only hit if you use --spawn_strategy=standalone (which the bootstrap build of bazel does).

the change here is that previously those were ignored because --strict_system_includes=false (the default) disables those checks for any headers from -isystem, but they no longer are.

The fix here is to pass --features=external_include_paths --host_features=external_include_paths to continue using -isystem for external headers, and to start external_includes the same as system_includes for --strict_system_includes.

I've added a release notes blurb as well

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Request: rename includes to system_includes in cc_* functions
2 participants