cmake 在neovim中使用clangd lsp编译命令json文件,无法解决“'iostream' file not found“错误,即使.exe可以成功生成

bbuxkriu  于 2023-10-20  发布在  iOS
关注(0)|答案(2)|浏览(452)

在Windows 10上的PowerShell
我使用g作为CMake和MinGW Makefiles的编译器
我还使用了从Mason安装的neovim(使用kickstarter配置)和clangdlsp
https://releases.llvm.org/下载LLVM。不确定这是否对clangd有必要,或者只是因为我使用clang
而不是g++。
无论我在哪里解释这个问题,我最终都会回到https://clangd.llvm.org/installation#project-setup,它谈论使用compile_commands.json,当我调用这个时,它应该由cmake生成:
cmake -S .\main\ -B .\main_build\ -G "MinGW Makefiles"
我的用户\repos目录中的目录看起来像这样:

User\repos\c--_sampler\
- main\
-- CMakeLists.txt
-- main.cpp
- main_build\ (empty dir until I call 'cmake ...' command above)
-- CMakeFiles\
-- CMakeCache.txt
-- cmake_install.cmake
-- compile_commands.json
-- Makefile

compile_commands.json确实出现在/main_build/中,并且我能够从\main_build\中运行cmake --build .,从而生成main1_executable.exe,然后我可以成功运行并输出“Hello,World!在powershell中,一切都如我所料。
问题是,尽管如此,当I nvim main\main.cpp,neovim(或者更好地说,clangd lsp)给出错误“'iostream' file not found“。我不知道clangd在哪里决定了stdlib的路径,但我假设clangd(或neovim)一定缺少了stdlibc++库的路径。
也就是说,我确实有C:\msys64\mingw64\bin,它包含libstdc++-6.dll,添加到env变量中的path中,我认为这足以让clangd使用库。
这是我的主. cpp

#include <iostream>

int main() 
{
    std::cout << "Hello, World!" << std::endl;
}

这是我的CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(Proj1)
cmake_path(SET var1 "C:\\msys64\\mingw64\\bin\\gcc.exe")
cmake_path(SET var2 "C:\\msys64\\mingw64\\bin\\g++.exe")
set( CMAKE_C_COMPILER "${var1}" )
set( CMAKE_CXX_COMPILER "${var2}" )
set( CMAKE_EXPORT_COMPILE_COMMANDS ON )
add_executable(main1_executable main.cpp)

这是cmake生成的compile_commands.json文件

[
{
  "directory": "C:/Users/User/repos/c--_sampler/main_build",
  "command": "C:\\msys64\\mingw64\\bin\\g++.exe    -o CMakeFiles\\main1_executable.dir\\main.cpp.obj -c C:\\Users\\User\\repos\\c--_sampler\\main\\main.cpp",
  "file": "C:/Users/User/repos/c--_sampler/main/main.cpp",
  "output": "CMakeFiles/main1_executable.dir/main.cpp.obj"
}
]

我看到很多类似的问题,但没有一个似乎与我的问题有关,或者如果是的话,我太密集了,无法理解。我想这里有一些很简单的东西我错过了,但我一直在努力与这个在过去的几天里,在这一点上,我只是运行在圈子里,我的大脑是转向粘。提前感谢您给予的任何指导!

sr4lhrrt

sr4lhrrt1#

这个问题通常通过使用--query-driver来解决,正如https://clangd.llvm.org/troubleshooting#cant-find-standard-library-headers-map-stdioh-etc的最后一段所讨论的那样(MinGW在这方面有点像“交叉编译器”,因为从clangd的Angular 来看,它是一个与默认MSVC不同的目标)。
因此,您需要将--query-driver=C:\msys64\mingw64\bin\g++.exe添加到clangd的命令行。这将指示clangd查询C:\msys64\mingw64\bin\g++.exe的内置包含路径,其中将包含标准库包含路径。
请注意,--query-driver需要指定为clangd本身的参数,而不是在compile_commands.json中。Clangd参数通常在特定于编辑器的地方指定;我不确定Neovim在哪里。
还有一点需要注意:clangd不会自动在main_build中找到compile_commands.json。您需要将其复制到main或祖先目录(如c--_sampler)。
或者,您可以将--compile-commands-dir=C:\Users\User\repos\c--_sampler\main_build添加到clangd的参数中(与--query-driver相同的位置),然后clangd将在该目录中查找compile_commands.json
如果你已经尝试了上面的方法,但仍然不起作用,请随时发布clangd日志,我们可以看看到底出了什么问题。

4xy9mtcn

4xy9mtcn2#

正如@HighCommander4所说,添加--query-driver作为clangd的参数解决了这个问题。(也需要将compile_commands.json设置为目录)
我可以通过添加一个if else语句来实现这一点,该语句使用cmd选项在init.lua中的mason_lspconfig.setup_handlers内部传递--query-driver

mason_lspconfig.setup_handlers {
  function(server_name)
    -- clangd cmd arguments here resolved missing header files error
    if server_name == 'clangd' then
      require('lspconfig')[server_name].setup {
        cmd = {'clangd', '--query-driver=C:/msys64/mingw64/bin/g++.exe'},
        capabilities = capabilities,
        on_attach = on_attach,
        settings = servers[server_name],
        filetypes = (servers[server_name] or {}).filetypes,
      }
    else
      require('lspconfig')[server_name].setup {
        capabilities = capabilities,
        on_attach = on_attach,
        settings = servers[server_name],
        filetypes = (servers[server_name] or {}).filetypes,
    }
    end
  end,
  -- adding my clangd cmd args here also solved missing header files, not sure which is more appropriate
  --[[["clangd"] = function()
    require('lspconfig')['clangd'].setup {
      cmd = {'clangd', '--query-driver=C:/msys64/mingw64/bin/g++.exe'}
      }
  end]]
}

可能有一个更干净的方法来做到这一点,但它的工作很好地解决我的问题

相关问题