You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派4上Neovim配置clangd LSP自动补全失败求助

树莓派4上Neovim配置外部clangd失败的问题

环境说明

  • 硬件:树莓派4(aarch64架构)
  • 编辑器:Neovim 0.9.1,支持桌面/无头远程模式
  • 插件配置:
    • 插件管理器:packer.nvim
    • LSP整合工具:lsp-zero.nvim,用于管理nvim-cmp、nvim-lspconfig、mason.nvim等补全相关插件

问题描述

使用:LspInstall clangd安装C++语言服务器时,提示“当前平台不受支持”——因为mason暂不支持aarch64架构的clangd预编译包。但已经通过snap包管理器在系统中安装了clangd(路径为/snap/bin/clangd),理论上可以让Neovim调用这个外部clangd,但目前配置后无法正常工作。

当前clangd的配置代码(在.lua配置文件中):

local cfg = require('lspconfig')
cfg.clangd.setup({})

编辑C++源码时,:LspLog的输出片段:

[START][2023-07-09 18:19:09] LSP logging initiated
[INFO][2023-07-09 18:19:09] .../vim/lsp/rpc.lua:662 "Starting RPC client"   {  args = {},  cmd = "/snap/bin/clangd",  extra = {    cwd = "/home/alexsavo/t/cproj"  }}
[DEBUG][2023-07-09 18:19:09] .../vim/lsp/rpc.lua:284    "rpc.send"  {  id = 1,  jsonrpc = "2.0",  method = "initialize",  params = {    capabilities = {      offsetEncoding = { "utf-8", "utf-16" },      textDocument = {        callHierarchy = {          dynamicRegistration = false        },        codeAction = {          codeActionLiteralSupport = {            codeActionKind = {              valueSet = { "", "quickfix", "refactor", "refactor.extract", "refactor.inline", "refactor.rewrite", "source", "source.organizeImports" }            }          },          dataSupport = true,          dynamicRegistration = false,          isPreferredSupport = true,          resolveSupport = {            properties = { "edit" }          }        },        completion = {          completionItem = {            commitCharactersSupport = true,            deprecatedSupport = true,            documentationFormat = { "markdown", "plaintext" },            insertReplaceSupport = true,            insertTextModeSupport = {              valueSet = { 1, 2 }            },            labelDetailsSupport = true,            preselectSupport = true,            resolveSupport = {              properties = { "documentation", "detail", "additionalTextEdits", "sortText", "filterText", "insertText", "textEdit", "insertTextFormat", "insertTextMode" }            },            snippetSupport = true,            tagSupport = {              valueSet = { 1 }            }          },          completionItemKind = {            valueSet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 }          },          completionList = {            itemDefaults = { "commitCharacters", "editRange", "insertTextFormat", "insertTextMode", "data" }          },          contextSupport = true,          dynamicRegistration = false,          editsNearCursor = true,          insertTextMode = 1        },        declaration = {          linkSupport = true        },        definition = {          linkSupport = true        },        documentHighlight = {          dynamicRegistration = false        },        documentSymbol = {          dynamicRegistration = false,          hierarchicalDocumentSymbolSupport = true,          symbolKind = {            valueSet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 }          }        },        hover = {          contentFormat = { "markdown", "plaintext" },          dynamicRegistration = false        },        implementation = {          linkSupport = true        },        publishDiagnostics = {          relatedInformation = true,          tagSupport = {            valueSet = { 1, 2 }          }        },        references = {          dynamicRegistration = false        },        rename = {          dynamicRegistration = false,          prepareSupport = true        },        semanticTokens = {          augmentsSyntaxTokens = true,          dynamicRegistration = false,          formats = { "relative" },          multilineTokenSupport = false,          overlappingTokenSupport = true,          requests = {            full = {              delta = true            },            range = false          },          serverCancelSupport = false,          tokenModifiers = { "declaration", "definition", "readonly", "static", "deprecated", "abstract", "async", "modification", "documentation", "defaultLibrary" },          tokenTypes = { "namespace", "type", "class", "enum", "interface", "struct", "typeParameter", "parameter", "variable", "property", "enumMember", "event", "function", "method", "macro", "keyword", "modifier", "comment", "string", "number", "regexp", "operator", "decorator" }        },        signatureHelp = {          dynamicRegistration = false,          signatureInformation = {            activeParameterSupport = true,            documentationFormat = { "markdown", "plaintext" },            parameterInformation = {              labelOffsetSupport = true            }          }        },        synchronization = {          didSave = true,          dynamicRegistration = false,          willSave = true,          willSaveWaitUntil = true        },        typeDefinition = {          linkSupport = true        }      },      window = {        showDocument = {          support = true        },        showMessage = {          messageActionItem = {            additionalPropertiesSupport = false          }        },        workDoneProgress = true      },      workspace = {        applyEdit = true,        configuration = true,        didChangeWatchedFiles = {          dynamicRegistration = false,          relativePatternSupport = true        },        semanticTokens = {          refreshSupport = true        },        symbol = {          dynamicRegistration = false,          hierarchicalWorkspaceSymbolSupport = true,          symbolKind = {            valueSet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 }          }        },        workspaceEdit = {          resourceOperations = { "rename", "create", "delete" }        },        workspaceFolders = true      }    },    clientInfo = {      name = "Neovim",      version = "0.9.1"    },    initializationOptions = vim.empty_dict(),    processId = 2218712,    rootPath = "/home/alexsavo/t/cproj",    rootUri = "file:///home/alexsavo/t/cproj",    trace = "off",    workspaceFolders = { {        name = "/home/alexsavo/t/cproj",        uri = "file:///home/alexsavo/t/cproj"      } }  }}

从日志看,Neovim尝试启动了/snap/bin/clangd并发送了initialize请求,但后续没有任何服务器响应记录,:LspInfo显示clangd未正常连接(截图如下):
LspInfo输出

解决方法

1. 明确指定clangd路径并添加启动参数

修改clangd的配置,显式指定可执行文件路径,并添加必要的启动参数,确保snap版本的clangd能正常运行:

local lspconfig = require('lspconfig')
lspconfig.clangd.setup({
  cmd = { "/snap/bin/clangd", "--background-index", "--compile-commands-dir=build" },
  -- 若项目用CMake,可指定compile_commands.json所在目录
  root_dir = lspconfig.util.root_pattern("compile_commands.json", "CMakeLists.txt", ".git"),
})

2. 检查snap clangd的权限与环境变量

snap包可能存在权限限制,确保Neovim能访问clangd的必要资源:

  • 执行snap connections clangd检查权限,确保有home接口连接
  • 若需要访问系统头文件,可手动添加路径到clangd的配置,比如添加--header-search-path=/usr/include到cmd参数中

3. 禁用mason对clangd的自动管理

因为mason无法安装aarch64的clangd,需要让lsp-zero不依赖mason安装clangd,在lsp-zero的配置中添加:

local lsp = require('lsp-zero').preset({})
lsp.skip_server_setup({'clangd'}) -- 跳过mason自动安装clangd
lsp.setup()

-- 手动配置clangd
require('lspconfig').clangd.setup({
  cmd = { "/snap/bin/clangd" },
  -- 其他配置项
})

4. 验证clangd本身是否正常工作

在终端直接执行/snap/bin/clangd --version,确认能正常输出版本信息;再尝试在项目目录下运行/snap/bin/clangd,看是否有报错信息,排查服务器本身的问题。


内容的提问来源于stack exchange,提问作者Alexandr Savochkin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 22:39:50