llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
26.68k stars 10.93k forks source link

[clang-tidy] Add --query-driver option #53468

Open ladislas opened 2 years ago

ladislas commented 2 years ago

when using clangd for cross-compilation projects, the option --query-driver allows clangd to find the standard headers used by the cross-compilation compiler.

For example, in our project we have in our vscode settings: "--query-driver=/opt/homebrew/bin/arm-none-eabi*"

1ca174b6420a49bcd3331d6f86e237b627163597 adds this feature to clangd.

We are also using clang-tidy to modernize our project. When using clang-tidy through clangd, everything works fine thanks to the aforementioned --query-driver.

But when running clang-tidy or run-clang-tidy.py from CLI, we hit stupid errors such as:

Error while processing /Users/ladislas/dev/leka/LekaOS/libs/LogKit/include/LogKit.h.
/Users/blablabla/LekaOS/drivers/CoreLED/include/RGB.h:8:10: error: 'cstdint' file not found [clang-diagnostic-error]
#include <cstdint>
         ^~~~~~~~~
/Users/blablabla/LekaOS/include/interface/drivers/LED.h:8:10: error: 'cstdint' file not found [clang-diagnostic-error]
#include <cstdint>
         ^~~~~~~~~
/Users/blablabla/LekaOS/libs/LogKit/include/LogKit.h:8:10: error: 'array' file not found [clang-diagnostic-error]
#include <array>
         ^~~~~~~
make: *** [clang_tidy_diff] Error 123

We've tried to fix this through CMake and the compilation database but with no success...

It would be amazing to also have clang-tidy accept the --query-driver option and generate the compiler standard include path to fix the kind of issue we are facing.

njames93 commented 2 years ago

@sam-mccall should this be a drop in replacement or is there lots of boilerplate for the functionality in clangd?

llvmbot commented 2 years ago

@llvm/issue-subscribers-clang-tidy

kadircet commented 2 years ago

Implementation in clangd today doesn't depend much on clangd-specific pieces, apart from a thread-safe computation cache. unfortunately that cache is quite important for a sensible UX, especially when running the tool over a compilation database and not just a single file.

I suppose thread-safety constraints doesn't matter much to other tools today, so in theory that caching logic could still live inside clangd and the main implementation would only provide a single-threaded cache.

So it should be enough to expose extractSystemIncludesAndTarget so that clangd (and other tools that have thread-safety concerns) can build its thread-safe cache on top of it. And also wrap that in a clang::tooling::CompilationDatabase and make it available for general tooling use.

ladislas commented 2 years ago

In the mean time, and for those who might have the same issue/need, after studying the way it was done by clangd, we recreated the feature with a simple ruby script than you can find here:

https://github.com/leka/LekaOS/blob/develop/tools/run-clang-tidy.rb

We call it to run clang-tidy only on the files added/modified in a branch/pr, both locally and in Github Actions:

git diff --name-status <base_branch (e.g. develop, main)> \
| grep -E -v "_test" | grep -E "^A|^M" | sed "s/^[AM]\t//g" | grep -E "\.h\$$|\.cpp\$$" \
| xargs --no-run-if-empty ruby tools/run-clang-tidy.rb <build_dir>

For the CI version, it's here:

https://github.com/leka/LekaOS/blob/a95edefe357204bf1ce6c2b0dafef8f2ac6e49a5/.github/workflows/ci-code_analysis-clang_tidy.yml#L63-L76

gianmarcoodorizzi commented 1 year ago

Any update on this @kadircet? I think I might have stumbled upon the same issue here, though some system header files are found. For instance I get errors for:

Not sure why... Thanks.

EDIT: is there a workaround for this? Like a way to ignore such "not found" errors?

itavero commented 1 month ago

Excuse me for "hijacking" the comment section for this...

Just wondering if someone has a workaround currently to check my source code that's being compiled with arm-none-eabi-gcc. I'm struggling with setting up clang-tidy to correctly interpret our code base. I've posted some more details on the CMake Discourse (as we use CMake for build automation).

HighCommander4 commented 1 month ago

Clangd's --query-driver feature is basically just a convenient way to automate adding certain flags (specifically, a --target flag and some -isystem flags) to the compile command.

The same effect can be replicated in other clang-based tools by looking at what the added flags are (e.g. by looking at clangd's log, if you're using clangd) and adding them manually.

That's assuming your cross-compilation scenario is one that works in clangd with --query-driver. There may be cases where it doesn't work, e.g. because clang is missing support for a target that gcc has. In that case I don't have a workaround to suggest (using clang-based tools generally requires that the code be buildable with clang, or at least processable by the clang frontend in the case of front-end tools like clang-tidy and clangd).