intellij
intellij copied to clipboard
CLion `strip_include_prefix` isn't honored within a `cc_library` target
Description of the bug:
If a cc_library target uses strip_include_prefix and files within that library #include headers using paths relative to the strip_include_prefix folder, CLion will not find the headers. Bazel is able to build these just fine.
What's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.
.
├── BUILD
├── main.cc
├── mylib
│ ├── BUILD
│ ├── lib1
│ │ └── lib1.h
│ └── lib2
│ └── lib2.h
├── repro.bazelproject
└── WORKSPACE
##### BUILD #####
load("@rules_cc//cc:defs.bzl", "cc_binary")
cc_binary(
name = "main",
srcs = ["main.cc"],
deps = ["//mylib"],
)
##### main.cc #####
#include <iostream>
#include "lib2/lib2.h"
int main() {
std::cout << LIB2_HELLO << std::endl;
return 0;
}
##### mylib/BUILD #####
load("@rules_cc//cc:defs.bzl", "cc_library")
cc_library(
name = "mylib",
hdrs = glob(["**/*.h"]),
strip_include_prefix = "//mylib/",
visibility = ["//visibility:public"],
)
##### mylib/lib1/lib1.h #####
#include <string>
const std::string LIB1_HELLO = "Hello";
##### mylib/lib2/lib2.h #####
#include <iostream>
#include "lib1/lib1.h"
const std::string LIB2_HELLO = LIB1_HELLO;
CLion can't find the header include in lib2.h
Which Intellij IDE are you using? Please provide the specific version.
CLion 2023.2.2
What programming languages and tools are you using? Please provide specific versions.
C++
What Bazel plugin version are you using?
2023.09.26.0.1-api-version-232
Have you found anything relevant by searching the web?
No response
Any other information, logs, or outputs that you want to share?
Side note - I had to add a trailing '/' to the strip_include_prefix:
strip_include_prefix = "//mylib/",
Without that, the #include in main.cc isn't found:
CLion logs an error though when I include this trailing '/':
Failed to resolve virtual includes for ExecutionRootPath{path='bazel-out/aarch64-fastbuild/bin/mylib/_virtual_includes/mylib'}
java.lang.IllegalArgumentException: Invalid workspace path 'mylib///mylib/': Workspace path may not end with '/': mylib///mylib/
at com.google.idea.blaze.base.model.primitives.WorkspacePath.<init>(WorkspacePath.java:59)
at com.google.idea.blaze.base.model.primitives.WorkspacePath.<init>(WorkspacePath.java:69)
at com.google.idea.blaze.base.sync.workspace.VirtualIncludesHandler.resolveVirtualInclude(VirtualIncludesHandler.java:107)
at com.google.idea.blaze.base.sync.workspace.ExecutionRootPathResolver.resolveToIncludeDirectories(ExecutionRootPathResolver.java:124)
at com.google.idea.blaze.cpp.HeaderRootTrimmer.lambda$doCollectHeaderRoots$1(HeaderRootTrimmer.java:105)
at com.google.common.util.concurrent.TrustedListenableFutureTask$TrustedFutureInterruptibleTask.runInterruptibly(TrustedListenableFutureTask.java:131)
at com.google.common.util.concurrent.InterruptibleTask.run(InterruptibleTask.java:74)
at com.google.common.util.concurrent.TrustedListenableFutureTask.run(TrustedListenableFutureTask.java:82)
at com.intellij.util.concurrency.BoundedTaskExecutor.doRun(BoundedTaskExecutor.java:249)
at com.intellij.util.concurrency.BoundedTaskExecutor.access$200(BoundedTaskExecutor.java:31)
at com.intellij.util.concurrency.BoundedTaskExecutor$1.executeFirstTaskAndHelpQueue(BoundedTaskExecutor.java:227)
at com.intellij.util.ConcurrencyUtil.runUnderThreadName(ConcurrencyUtil.java:218)
at com.intellij.util.concurrency.BoundedTaskExecutor$1.run(BoundedTaskExecutor.java:215)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:702)
at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:699)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1.run(Executors.java:699)
at java.base/java.lang.Thread.run(Thread.java:833)
There's a probably a simple fix for this to handle the trailing '/'. I can open a separate issue for this if needed.
cc @ujohnny who's been working on strip_include_prefix recently.
Same issue here.
Ok I found the bug and was able to fix it in https://github.com/bazelbuild/intellij/pull/5969. The current code is written assuming the strip_include_prefix is a package-relative path, but strip_include_prefix can also be specified as a repository-relative path (e.g. strip_include_prefix = "//some/prefix". When a repository-relative path is used, it gets concatenated to the package path, which creates header paths that don't exist.
To fix it we just need to skip that concatenation when a repository-relative path is used.
I also fixed the trailing '/' I mentioned at the bottom of the summary. I just needed to trip the trailing '/' before creating the WorkspacePath object.
ptal @ujohnny / @tpasternak
ok, it's fixed iiuc