clangd 修改系统包含路径

问题描述 投票:0回答:1

跑步

clangd --check=my_file.cu
我得到了一些类似的东西(简化):

I[13:05:09.356] Testing on source file /path/to/my_file.cu
I[13:05:09.362] Loading compilation database...
I[13:05:09.363] Loaded compilation database from /path/to/build/compile_commands.json
I[13:05:09.364] Compile command from CDB is: /path/to/bin/nvcc [...] -isystem=/path/to/lib/include [...] -- /path/to/my_file.cu
[...]
I[13:05:09.364] Parsing command...
I[13:05:09.371] internal (cc1) args are: -cc1 [...] -isystem =/path/to/lib/include [...] -x cuda /path/to/my_file.cu

最重要的是,编译数据库中的命令和解析的内部命令之间存在差异。即,

-isystem=/path/to/lib/include
变为
-isystem =/path/to/lib/include
(带有空格)。看来 clangd 没有正确解析系统包含的
=
语法。

Clangd 将无法找到系统范围内安装的库的包含内容,除非我使用 clangd 配置文件手动添加

-I /path/to/lib/include

-isystem=/path/to/lib/include
形式是由CMake在编译命令中生成的,并且在使用NVCC/GCC编译时工作正常。然而,clangd 似乎将其误读为路径
=/path/to/lib/include
而不是
/path/to/lib/include

这是 C++/CUDA 库的问题,但我不认为这是根本原因。

是否有某种方法可以让 clangd 正确解析 CMake 为 NVCC 生成的

-isystem

 标志?这是一个错误,还是与 clang 的预期行为一致?

最小可重现示例

# CMakeLists.txt cmake_minimum_required(VERSION 3.20) project(demo LANGUAGES CUDA CXX) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # Download GoogleTest include(FetchContent) message(STATUS "> Downloading dependency: GoogleTest") FetchContent_Declare( googletest URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip ) FetchContent_MakeAvailable(googletest) message(STATUS "> Downloading dependency: GoogleTest - done") # Build demo executable add_executable(demo demo.cu) target_link_libraries(demo GTest::gtest_main)
// demo.cu
#include <iostream>

int main() { std::cout << "Hello world" << std::endl; }
使用

cmake -B build .

进行配置时,我们得到以下编译DB:

[ { "directory": "/home/sbone/repos/cmake_mvp/build", "command": "/path/to/bin/nvcc -forward-unknown-to-host-compiler -isystem=/home/sbone/repos/cmake_mvp/build/_deps/googletest-src/googletest/include -isystem=/home/sbone/repos/cmake_mvp/build/_deps/googletest-src/googletest --generate-code=arch=compute_52,code=[compute_52,sm_52] -std=c++17 -x cu -c /home/sbone/repos/cmake_mvp/demo.cu -o CMakeFiles/demo.dir/demo.cu.o", "file": "/home/sbone/repos/cmake_mvp/demo.cu" }, { "directory": "/home/sbone/repos/cmake_mvp/build/_deps/googletest-build/googlemock", "command": "/local/scratch/sbone/mambaforge/envs/cudaj_devel/bin/x86_64-conda-linux-gnu-c++ -I/home/sbone/repos/cmake_mvp/build/_deps/googletest-src/googlemock/include -I/home/sbone/repos/cmake_mvp/build/_deps/googletest-src/googlemock -isystem /home/sbone/repos/cmake_mvp/build/_deps/googletest-src/googletest/include -isystem /home/sbone/repos/cmake_mvp/build/_deps/googletest-src/googletest -fvisibility-inlines-hidden -fmessage-length=0 -march=nocona -mtune=haswell -ftree-vectorize -fPIC -fstack-protector-strong -fno-plt -O2 -ffunction-sections -pipe -isystem /local/scratch/sbone/mambaforge/envs/cudaj_devel/include -Wall -Wshadow -Wundef -Wno-error=dangling-else -DGTEST_HAS_PTHREAD=1 -fexceptions -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -o CMakeFiles/gmock.dir/src/gmock-all.cc.o -c /home/sbone/repos/cmake_mvp/build/_deps/googletest-src/googlemock/src/gmock-all.cc", "file": "/home/sbone/repos/cmake_mvp/build/_deps/googletest-src/googlemock/src/gmock-all.cc" }, { "directory": "/home/sbone/repos/cmake_mvp/build/_deps/googletest-build/googlemock", "command": "/local/scratch/sbone/mambaforge/envs/cudaj_devel/bin/x86_64-conda-linux-gnu-c++ -isystem /home/sbone/repos/cmake_mvp/build/_deps/googletest-src/googlemock/include -isystem /home/sbone/repos/cmake_mvp/build/_deps/googletest-src/googlemock -isystem /home/sbone/repos/cmake_mvp/build/_deps/googletest-src/googletest/include -isystem /home/sbone/repos/cmake_mvp/build/_deps/googletest-src/googletest -fvisibility-inlines-hidden -fmessage-length=0 -march=nocona -mtune=haswell -ftree-vectorize -fPIC -fstack-protector-strong -fno-plt -O2 -ffunction-sections -pipe -isystem /local/scratch/sbone/mambaforge/envs/cudaj_devel/include -Wall -Wshadow -Wundef -Wno-error=dangling-else -DGTEST_HAS_PTHREAD=1 -fexceptions -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -o CMakeFiles/gmock_main.dir/src/gmock_main.cc.o -c /home/sbone/repos/cmake_mvp/build/_deps/googletest-src/googlemock/src/gmock_main.cc", "file": "/home/sbone/repos/cmake_mvp/build/_deps/googletest-src/googlemock/src/gmock_main.cc" }, { "directory": "/home/sbone/repos/cmake_mvp/build/_deps/googletest-build/googletest", "command": "/local/scratch/sbone/mambaforge/envs/cudaj_devel/bin/x86_64-conda-linux-gnu-c++ -I/home/sbone/repos/cmake_mvp/build/_deps/googletest-src/googletest/include -I/home/sbone/repos/cmake_mvp/build/_deps/googletest-src/googletest -fvisibility-inlines-hidden -fmessage-length=0 -march=nocona -mtune=haswell -ftree-vectorize -fPIC -fstack-protector-strong -fno-plt -O2 -ffunction-sections -pipe -isystem /local/scratch/sbone/mambaforge/envs/cudaj_devel/include -Wall -Wshadow -Wundef -Wno-error=dangling-else -DGTEST_HAS_PTHREAD=1 -fexceptions -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -o CMakeFiles/gtest.dir/src/gtest-all.cc.o -c /home/sbone/repos/cmake_mvp/build/_deps/googletest-src/googletest/src/gtest-all.cc", "file": "/home/sbone/repos/cmake_mvp/build/_deps/googletest-src/googletest/src/gtest-all.cc" }, { "directory": "/home/sbone/repos/cmake_mvp/build/_deps/googletest-build/googletest", "command": "/local/scratch/sbone/mambaforge/envs/cudaj_devel/bin/x86_64-conda-linux-gnu-c++ -isystem /home/sbone/repos/cmake_mvp/build/_deps/googletest-src/googletest/include -isystem /home/sbone/repos/cmake_mvp/build/_deps/googletest-src/googletest -fvisibility-inlines-hidden -fmessage-length=0 -march=nocona -mtune=haswell -ftree-vectorize -fPIC -fstack-protector-strong -fno-plt -O2 -ffunction-sections -pipe -isystem /local/scratch/sbone/mambaforge/envs/cudaj_devel/include -Wall -Wshadow -Wundef -Wno-error=dangling-else -DGTEST_HAS_PTHREAD=1 -fexceptions -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -o CMakeFiles/gtest_main.dir/src/gtest_main.cc.o -c /home/sbone/repos/cmake_mvp/build/_deps/googletest-src/googletest/src/gtest_main.cc", "file": "/home/sbone/repos/cmake_mvp/build/_deps/googletest-src/googletest/src/gtest_main.cc" } ]
如您所见,CUDA 代码已使用 

-isystem=...

 指定了系统包含。

注意:这是使用 CMake 3.24.3 和 NVCC

cuda_12.2.r12.2/compiler.33191640_0

c++ gcc cmake nvcc clangd
1个回答
0
投票
Clang 确实不接受

-isystem=

 格式的标志。 (您可以从 
clang 源中定义选项的方式看到这一点。接受 =
 的标志,例如 
--sysroot
,具有 
_EQ 形式,而 -isystem
 则没有。)

因此,如果

nvcc

 接受 
-isystem=
,那么这看起来像是 
clang
nvcc
 的命令行参数语法之间存在细微的不一致。 (可能是无意的;假设 
nvcc
 是试图与此处的 
clang
 兼容的那个,这可能值得提交一个 
nvcc
 问题,以便其开发人员意识到。)

Clangd 使用 clang 驱动程序来处理

compile_commands.json

 中的命令,因此它接受 clang 接受的任何内容。

假设

nvcc

 确实接受 
-isystem=
,CMake 使用 
nvcc
 生成 
-isystem=
 命令本身并不是一个 CMake bug 
...但如果 nvcc 也接受
-isystem
且没有同等条件,也许它CMake 使用更便携的标志形式会更好吗? (可能值得 CMake 问题。)
目前,我认为你的选择是:

    以某种方式让 CMake 使用
  1. -isystem

    形式生成命令。我对 CMake 不太熟悉,无法提出具体建议,但也许您可以让它生成

    clang
    命令而不是
    nvcc
    命令? (您不必在构建过程中实际
    run
    clang 命令。)

  2. 使用
  3. clangd配置文件

    调整编译命令。您可以删除错误形式的标志并使用 CompileFlags: 添加正确的形式。

    
    

© www.soinside.com 2019 - 2024. All rights reserved.