跑步
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
。
-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 问题。)目前,我认为你的选择是:
-isystem
形式生成命令。我对 CMake 不太熟悉,无法提出具体建议,但也许您可以让它生成
clang
命令而不是 nvcc
命令? (您不必在构建过程中实际 run
clang
命令。)或
调整编译命令。您可以删除错误形式的标志并使用 CompileFlags:
添加正确的形式。