diff --git a/aspect/intellij_info_impl.bzl b/aspect/intellij_info_impl.bzl index e1f9c42154b..979fccb7b50 100644 --- a/aspect/intellij_info_impl.bzl +++ b/aspect/intellij_info_impl.bzl @@ -472,6 +472,7 @@ def collect_cpp_info(target, ctx, semantics, ide_info, ide_info_file, output_gro transitive_system_include_directory = compilation_context.system_includes.to_list(), include_prefix = getattr(ctx.rule.attr, "include_prefix", None), strip_include_prefix = getattr(ctx.rule.attr, "strip_include_prefix", None), + external_includes = getattr(compilation_context, "external_includes", depset()).to_list(), ) ide_info["c_ide_info"] = c_info resolve_files = compilation_context.headers diff --git a/base/src/com/google/idea/blaze/base/ideinfo/CIdeInfo.java b/base/src/com/google/idea/blaze/base/ideinfo/CIdeInfo.java index 6299e1274b3..7308abbe574 100644 --- a/base/src/com/google/idea/blaze/base/ideinfo/CIdeInfo.java +++ b/base/src/com/google/idea/blaze/base/ideinfo/CIdeInfo.java @@ -38,6 +38,8 @@ public final class CIdeInfo implements ProtoWrapper { private final String includePrefix; private final String stripIncludePrefix; + private final ImmutableList externalIncludes; + private CIdeInfo( ImmutableList sources, ImmutableList headers, @@ -48,7 +50,8 @@ private CIdeInfo( ImmutableList transitiveDefines, ImmutableList transitiveSystemIncludeDirectories, String includePrefix, - String stripIncludePrefix) { + String stripIncludePrefix, + ImmutableList externalIncludes) { this.sources = sources; this.headers = headers; this.textualHeaders = textualHeaders; @@ -59,6 +62,7 @@ private CIdeInfo( this.transitiveSystemIncludeDirectories = transitiveSystemIncludeDirectories; this.includePrefix = includePrefix; this.stripIncludePrefix = stripIncludePrefix; + this.externalIncludes = externalIncludes; } static CIdeInfo fromProto(IntellijIdeInfo.CIdeInfo proto) { @@ -74,7 +78,9 @@ static CIdeInfo fromProto(IntellijIdeInfo.CIdeInfo proto) { ProtoWrapper.map( proto.getTransitiveSystemIncludeDirectoryList(), ExecutionRootPath::fromProto), proto.getIncludePrefix(), - proto.getStripIncludePrefix()); + proto.getStripIncludePrefix(), + ProtoWrapper.map(proto.getExternalIncludesList(), ExecutionRootPath::fromProto) + ); } @Override @@ -90,6 +96,7 @@ public IntellijIdeInfo.CIdeInfo toProto() { .addAllTransitiveDefine(transitiveDefines) .addAllTransitiveSystemIncludeDirectory( ProtoWrapper.mapToProtos(transitiveSystemIncludeDirectories)) + .addAllExternalIncludes(ProtoWrapper.mapToProtos(externalIncludes)) .build(); } @@ -133,6 +140,10 @@ public String getStripIncludePrefix() { return stripIncludePrefix; } + public ImmutableList getExternalIncludes() { + return externalIncludes; + } + public static Builder builder() { return new Builder(); } @@ -155,6 +166,8 @@ public static class Builder { private String includePrefix = ""; private String stripIncludePrefix = ""; + private final ImmutableList.Builder externalIncludes = ImmutableList.builder(); + @CanIgnoreReturnValue public Builder addSources(Iterable sources) { this.sources.addAll(sources); @@ -236,6 +249,12 @@ public Builder setStripIncludePrefix(String stripIncludePrefix) { return this; } + @CanIgnoreReturnValue + public Builder setExternalIncludes(Iterable externalIncludes) { + this.externalIncludes.addAll(externalIncludes); + return this; + } + public CIdeInfo build() { return new CIdeInfo( sources.build(), @@ -247,7 +266,8 @@ public CIdeInfo build() { transitiveDefines.build(), transitiveSystemIncludeDirectories.build(), includePrefix, - stripIncludePrefix); + stripIncludePrefix, + externalIncludes.build()); } } @@ -279,6 +299,9 @@ public String toString() { + " transitiveSystemIncludeDirectories=" + getTransitiveSystemIncludeDirectories() + "\n" + + " externalIncludes" + + getExternalIncludes() + + "\n" + '}'; } @@ -300,7 +323,8 @@ public boolean equals(Object o) { transitiveQuoteIncludeDirectories, cIdeInfo.transitiveQuoteIncludeDirectories) && Objects.equals(transitiveDefines, cIdeInfo.transitiveDefines) && Objects.equals( - transitiveSystemIncludeDirectories, cIdeInfo.transitiveSystemIncludeDirectories); + transitiveSystemIncludeDirectories, cIdeInfo.transitiveSystemIncludeDirectories) + && Objects.equals(externalIncludes, cIdeInfo.externalIncludes); } @Override @@ -313,6 +337,7 @@ public int hashCode() { transitiveIncludeDirectories, transitiveQuoteIncludeDirectories, transitiveDefines, - transitiveSystemIncludeDirectories); + transitiveSystemIncludeDirectories, + externalIncludes); } } diff --git a/cpp/src/com/google/idea/blaze/cpp/BlazeCWorkspace.java b/cpp/src/com/google/idea/blaze/cpp/BlazeCWorkspace.java index 53473c5b1fc..d0480c19290 100644 --- a/cpp/src/com/google/idea/blaze/cpp/BlazeCWorkspace.java +++ b/cpp/src/com/google/idea/blaze/cpp/BlazeCWorkspace.java @@ -69,7 +69,6 @@ import com.jetbrains.cidr.lang.workspace.compiler.CompilerInfoCache.Session; import com.jetbrains.cidr.lang.workspace.compiler.OCCompilerKind; import com.jetbrains.cidr.lang.workspace.compiler.TempFilesPool; - import java.io.File; import java.nio.file.Path; import java.util.Collection; @@ -251,7 +250,10 @@ private OCWorkspaceImpl.ModifiableModel calculateConfigurations( // Note: We would ideally use -isystem here, but it interacts badly with the switches // that get built by ClangUtils::addIncludeDirectories (it uses -I for system libraries). ImmutableList isystemOptionIncludeDirectories = - targetIdeInfo.getcIdeInfo().getTransitiveSystemIncludeDirectories().stream() + Stream.concat( + targetIdeInfo.getcIdeInfo().getTransitiveSystemIncludeDirectories().stream(), + targetIdeInfo.getcIdeInfo().getExternalIncludes().stream() + ) .flatMap(resolver) .filter(configResolveData::isValidHeaderRoot) .map(file -> "-I" + file.getAbsolutePath()) diff --git a/cpp/src/com/google/idea/blaze/cpp/HeaderRootTrimmer.java b/cpp/src/com/google/idea/blaze/cpp/HeaderRootTrimmer.java index 8bb220a1a55..37a8546e020 100644 --- a/cpp/src/com/google/idea/blaze/cpp/HeaderRootTrimmer.java +++ b/cpp/src/com/google/idea/blaze/cpp/HeaderRootTrimmer.java @@ -192,6 +192,7 @@ private static Set collectExecutionRootPaths( paths.addAll(target.getcIdeInfo().getTransitiveSystemIncludeDirectories()); paths.addAll(target.getcIdeInfo().getTransitiveIncludeDirectories()); paths.addAll(target.getcIdeInfo().getTransitiveQuoteIncludeDirectories()); + paths.addAll(target.getcIdeInfo().getExternalIncludes()); } } Set toolchains = new LinkedHashSet<>(toolchainLookupMap.values()); diff --git a/examples/cpp/external_includes/external/BUILD b/examples/cpp/external_includes/external/BUILD new file mode 100644 index 00000000000..2305fda3b0b --- /dev/null +++ b/examples/cpp/external_includes/external/BUILD @@ -0,0 +1,6 @@ +cc_library( + name = "simple", + srcs = ["simple.cc"], + hdrs = ["simple.h"], + visibility = ["//visibility:public"], +) \ No newline at end of file diff --git a/examples/cpp/external_includes/external/WORKSPACE b/examples/cpp/external_includes/external/WORKSPACE new file mode 100644 index 00000000000..e69de29bb2d diff --git a/examples/cpp/external_includes/external/simple.cc b/examples/cpp/external_includes/external/simple.cc new file mode 100644 index 00000000000..31392a0a579 --- /dev/null +++ b/examples/cpp/external_includes/external/simple.cc @@ -0,0 +1,7 @@ +#include "simple.h" + +#include + +void simple_header_fun() { + printf("Hello there!\n"); +} \ No newline at end of file diff --git a/examples/cpp/external_includes/external/simple.h b/examples/cpp/external_includes/external/simple.h new file mode 100644 index 00000000000..dc940a0d80e --- /dev/null +++ b/examples/cpp/external_includes/external/simple.h @@ -0,0 +1,6 @@ +#ifndef SIMPLE_H +#define SIMPLE_H + +void simple_header_fun(); + +#endif \ No newline at end of file diff --git a/examples/cpp/external_includes/project/.bazelrc b/examples/cpp/external_includes/project/.bazelrc new file mode 100644 index 00000000000..2da76b36de4 --- /dev/null +++ b/examples/cpp/external_includes/project/.bazelrc @@ -0,0 +1 @@ +build --features=external_include_paths \ No newline at end of file diff --git a/examples/cpp/external_includes/project/BUILD b/examples/cpp/external_includes/project/BUILD new file mode 100644 index 00000000000..048db18ecb5 --- /dev/null +++ b/examples/cpp/external_includes/project/BUILD @@ -0,0 +1,5 @@ +cc_binary( + name = "simple", + srcs = ["simple.cc"], + deps = ["@lib//:simple"], +) \ No newline at end of file diff --git a/examples/cpp/external_includes/project/WORKSPACE b/examples/cpp/external_includes/project/WORKSPACE new file mode 100644 index 00000000000..2511ccb4114 --- /dev/null +++ b/examples/cpp/external_includes/project/WORKSPACE @@ -0,0 +1,4 @@ +local_repository( + name = "lib", + path = "../external", +) \ No newline at end of file diff --git a/examples/cpp/external_includes/project/simple.cc b/examples/cpp/external_includes/project/simple.cc new file mode 100644 index 00000000000..3982b98220e --- /dev/null +++ b/examples/cpp/external_includes/project/simple.cc @@ -0,0 +1,6 @@ +#include + +int main() { + simple_header_fun(); + return 0; +} \ No newline at end of file diff --git a/proto/intellij_ide_info.proto b/proto/intellij_ide_info.proto index 36efed728b3..38bb4f4e14c 100644 --- a/proto/intellij_ide_info.proto +++ b/proto/intellij_ide_info.proto @@ -66,6 +66,8 @@ message CIdeInfo { string include_prefix = 10; string strip_include_prefix = 11; + + repeated string external_includes = 12; } message AndroidIdeInfo {