Skip to content

external_include_paths adds external repository root as -isystem include path #801

Description

@DoDoENT

When --features=external_include_paths is enabled, rules_cc appears to add the external repository root itself to external_includes, which is later emitted as -isystem <external repo root>. This can make non-header files in an external repository visible to angle-bracket includes.

In particular, on case-insensitive filesystems this can break libc++ includes. If an external repository contains a file named VERSION, and the compile action also includes -isystem external/<repo>+, libc++'s #include <version> can resolve to that repository's VERSION file instead of the standard library <version> header.

Example observed in a downstream build using libtiff through OpenCV on macOS (see this issue):

-isystem external/libtiff+
-isystem bazel-out/darwin_arm64-fastbuild/bin/external/libtiff+
-isystem external/libtiff+/libtiff
-isystem bazel-out/darwin_arm64-fastbuild/bin/external/libtiff+/libtiff

Only the libtiff subdirectory entries are expected from libtiff's includes = ["libtiff"]. The root entries come from rules_cc's external include path reclassification.

The problematic code appears to be in cc/private/compile/cc_compilation_helper.bzl:

external_include_dirs.append(repo_path)
external_include_dirs.append(gen_include_dir)
external_include_dirs.append(bin_include_dir)
external_include_dirs.extend(quote_include_dirs)
external_include_dirs.extend(system_include_dirs)
external_include_dirs.extend(include_dirs)

The first three entries are implicit quote roots for the target's own repository. Reclassifying them as public system include paths for external repositories exposes the entire repository root to downstream compilation.

This is important because external_include_paths is very useful for treating third-party headers as system headers while still keeping warnings-as-errors for first-party code. Disabling the feature works around this specific failure but loses that behavior globally.

A possible fix is to keep converting explicit public include directories (includes, system_includes, and relevant configured include dirs) into external_includes, but avoid exporting the implicit external repository root/default quote include roots as system include paths to downstream dependents.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions