【求助】Emacs lsp-bridge + clangd 无法在 C 项目的 .h 与 .c 之间跳转定义

  1. 背景与环境
  • 操作系统:macOS (Apple Silicon)
  • 编辑器:Emacs
  • LSP 客户端lsp-bridge
  • LSP 后端clangd
  • 项目结构

  1. 核心问题描述

在使用 lsp-bridge-find-def 时,尝试从 include/calc.h 中的函数声明跳转到 src/calc.c 中的实现,提示 “No definition found”

*lsp-bridge* Buffer 日志:

 [15:50:29.133571] Send textDocument/definition request (15671) to 'clangd' for project p1
I[15:50:29.133] <-- textDocument/definition(15671)
I[15:50:29.134] --> reply:textDocument/definition(15671) 0 ms  <-- 响应极快但内容为空
  1. 现有配置详情

CMakeLists.txt:


cmake_minimum_required(VERSION 3.0)
project(Phoenix VERSION 1.0 LANGUAGES C)
cmake_policy(SET CMP0076 NEW)

if(NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the build type" FORCE)
endif()

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

add_executable(phoneix_alpha_target)

target_sources(phoneix_alpha_target
  PRIVATE
      main.c
      src/calc.c
)


target_include_directories(phoneix_alpha_target
  PRIVATE
  ${CMAKE_CURRENT_SOURCE_DIR}/include
)

compile_commands.json (已在 build 文件夹生成,并拷贝到根目录): 该文件内容正常,包含了 -I/Users/.../include 路径以及对 src/calc.c 的编译指令。

  1. 已尝试的手段(均未解决)
  • 检查拼写:确认文件名 calc.hcalc.c 拼写一致,且 calc.c 中已 #include "calc.h"
  • 编译状态:项目可以正常编译通过,符号本身没有语法错误。
  • 配置文件位置:尝试在项目根目录运行,确认 compile_commands.json 存在。
  • LSP 重启:多次执行 lsp-bridge-restart-process
  • 创建 .clangd 文件
CompileFlags:
  CompilationDatabase: "build"
  Add: [-Iinclude]

Index:
  Background: Build

没有起作用

5. 困惑点

即便 compile_commands.json 中已经指定了包含路径和源文件,为什么 clangd 依然无法将 .h 里的符号关联到 .c 文件中?是否是 lsp-bridge 启动 clangd 时的工作目录识别问题,还是需要特殊的 .clangd 配置文件引导?

希望能得到有相关经验的大佬指点,非常感谢!

这是正常行为,你要看看其他的地方有没有问题。

工作目录识别问题可以尝试一下git init

(defun lsp-bridge--get-project-path-func (filename)
  "Get project root path, search order:

1. Follow the rule of `lsp-bridge-get-project-path-by-filepath'
2. Search up `.dir-locals.el'
3. Search up `.git'"
  (if lsp-bridge-get-project-path-by-filepath
      ;; Fetch project root path by `lsp-bridge-get-project-path-by-filepath' if it set by user.
      (funcall lsp-bridge-get-project-path-by-filepath filename)
    ;; Otherwise try to search up `.dir-locals.el' file
    (let* ((result (dir-locals-find-file filename))
           (dir (if (consp result) (car result) result)))
      (when dir (directory-file-name dir)))))

工作目录识别没有问题,git有的 是以项目模式启动的lsp-bridge

我试了,这应该是正常的行为。C++里面是可以跳转的,C不行

搜噶

我重新试了一下,如果没有分 src/,include/ 目录的话,都在根目录的话是可以跳转的

等会,我知道了,必须光标放在函数名上 :sweat_smile:

1 个赞