尝试配置 Clangd 开发 SiFli 工程时报错找不到 'sys/stat.h'

系统环境:WSL: Ubuntu 24.04
Clangd版本:v18.1.3
SiFli SDK 版本:v2.4
开发板:立创黄山派

我正在尝试为 SiFli SDK 中的 hello_world/rtt 例程加入 VSCode 的 Clangd 插件支持。我选择了一个脚本为项目基本的 vscode & clion 支持中的 clion 方案,成功加入了 compile_commands.json,配置后 Clangd 插件可以正常跳转到 rt_kprintf 等函数,但是在 rtthread 引用中报错找不到 ‘sys/stat.h’。说明 scons 配合这个脚本并没有成功将 ‘sys/stat.h’ 加入到 compile_commands.json 中。

我尝试在 compile_commands.json 硬性加入 SDK 中找到的 stat.h,但是 SDK 中的 stat.h 有多个,同时我并不知道如何在 compile_commands.json 中正确加入 stat.h ,以及为什么 scons 没有将它载入 compile_commands.json 中。

希望有哪位能告诉我当前版本在 VSCode 配合 Clangd 开发 SiFli SDK 是否可行,如果可行如何正确解决找不到 ‘sys/stat.h’ 的问题?感谢!

论坛里有人配置过clangd,看看他是怎么弄的

clion会根据 compile_commands.json 智能解析宏定义,编译器位置等信息,我猜vscode的clangd并不会自动,需要手动配置

sys/stat.h 是编译器自带的头文件,不需要手动处理,只要配置好编译器路径,这个文件能自动找到

Clion 的智能解析也是基于 clangd 的。不过我好像有了点启发,这个 stat.h 是不是 SiFli SDK 加入到 .sifli 里的 arm-none-eabi-gcc 的呢?clangd 会从环境变量里找 arm-none-eabi-gcc,可能找到的不是 SDK 里的 arm-none-eabi-gcc

这一篇我也有看,也用的是差不多的配置

sys/stat.h是系统的头文件,按道理来说应该去gcc的目录下查找。
clangd使用交叉编译的时候就是有一些这样的奇奇怪怪的小问题,如果大佬解决了欢迎分享经验

在 Gemini 和社区的帮助下,目前问题基本得到解决:

原有的 ide_support.py 没有将编译器下的 include 目录加入到 compile_commands.json 中,需要在脚本中为 clangd 加入 -isystem 参数引用 include 目录。加入思路如下:

先定义函数 _get_system_include_paths 获取编译器所有的 include 目录:

def _get_system_include_paths(compiler_path: str) -> List[str]:
    """
    Runs the compiler to discover its built-in system include paths.
    """
    command = [compiler_path, "-E", "-Wp,-v", "-xc", os.devnull]
    try:
        # Run the command and capture stderr, which is where GCC prints this info
        result = subprocess.run(command, capture_output=True, text=True, check=True)
    except (subprocess.CalledProcessError, FileNotFoundError) as e:
        print(f"! Warning: Could not execute compiler to find system includes: {e}")
        return []

    output = result.stderr
    
    # Use regex to find the paths between the start and end markers
    search_block_match = re.search(r'#include <\.\.\.> search starts here:\s*(.*?)\s*End of search list\.', output, re.DOTALL)
    if not search_block_match:
        return []

    # Extract all lines from the matched block
    search_block = search_block_match.group(1)
    # Return a list of cleaned-up, absolute paths
    return [os.path.normpath(line.strip()) for line in search_block.splitlines() if line.strip()]

再在 _process_compile_commands 函数中加入以下内容,将 include 目录加入 clangd 索引:

    # --- MODIFICATION START ---
    # Automatically get system include paths from the compiler
    print("✓ Querying compiler for system include paths...")
    system_paths = _get_system_include_paths(compiler_path)
    if not system_paths:
        print("! Warning: Could not find system include paths. clangd might have issues.")
    
    # Create '-isystem' flags. This tells clangd they are system headers.
    system_include_flags = [f"-isystem{path}" for path in system_paths]
    print(f"✓ Found system paths: {system_paths}")
    # --- MODIFICATION END ---

再次编译后,在项目文件中不会再出现 找不到 sys/stat.h 报错。

但是跳转到 rtthread.h 之后还是会出现其他报错,但是疑似是 SDK 的设计问题,也权当小问题了,不影响开发。

1 个赞