跳过正文

Clangd Cmake Compile Commands Msvc Problem

·326 字·2 分钟
yjdyamv
作者
yjdyamv
偶尔写点东西,记录生活,分享知识。

cmake生成的compile_commands.json的详细程度远不如xmake生成的(目前仅对比了msvc时)。

cmake生成的compile_commands.json里含有宏并依赖INCLUDE、LIB等环境变量,因此clangd在没有加载vs的环境变量时,高亮是错误的。而xmake生成的直接把vs环境变量加入了编译命令,因此clangd直接找到了对应的头文件,高亮正常。

解决方案:从Develop Powershell for VS里启动VS(其中一种方案)

我的选择是将加载vs环境变量的脚本启动写入pwsh的$profile里,这样就无需专门打开那个终端了

# ====================================================
# 自动加载 Visual Studio 环境变量
# ====================================================

function Invoke-Environment {
    param(
        [Parameter(Mandatory=$true)]
        [string] $Command
    )
    # 让 cmd 执行命令,捕获所有环境变量并应用到当前会话
    cmd /c "$Command > nul 2>&1 && set" | .{process{
        if ($_ -match '^([^=]+)=(.*)') {
            [System.Environment]::SetEnvironmentVariable($matches[1], $matches[2])
        }
    }}
    if ($LASTEXITCODE) {
        throw "Command '$Command' failed with exit code: $LASTEXITCODE"
    }
}

# --- 自动查找并加载最新版 Visual Studio ---
# 1. 定义 vswhere.exe 的固定绝对路径(64位系统)
$vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"

# 2. 如果上述路径不存在,尝试 32 位系统的路径
if (-not (Test-Path $vswhere)) {
    $vswhere = "${env:ProgramFiles}\Microsoft Visual Studio\Installer\vswhere.exe"
}

# 3. 如果找到了 vswhere,用它查询最新 VS 的安装路径
if (Test-Path $vswhere) {
    $vsPath = & $vswhere -prerelease -latest -property installationPath
    if ($vsPath) {
        $vsDevCmd = Join-Path $vsPath "Common7\Tools\VsDevCmd.bat"
        if (Test-Path $vsDevCmd) {
            Write-Host "找到 Visual Studio: $vsPath" -ForegroundColor Green
            # 加载环境变量(默认加载 x64 架构,可自行修改)
            Invoke-Environment "call `"$vsDevCmd`" -arch=amd64 -host_arch=amd64"
            Write-Host "Visual Studio 环境变量已加载。" -ForegroundColor Green
        } else {
            Write-Warning "未找到 VsDevCmd.bat,路径: $vsDevCmd"
        }
    } else {
        Write-Warning "vswhere 未找到任何 Visual Studio 安装。"
    }
} else {
    Write-Warning "未找到 vswhere.exe,请确认 Visual Studio 已正确安装。"
}

另外的,我还对vscode新建内置终端添加了VS Dev Terminal的配置以自动加载vs环境变量,这样就类似Develop Powershell for VS了

"terminal.integrated.profiles.windows": {
    // 默认x64
    "VS Dev Terminal": {
      "source": "PowerShell",
      "icon": "terminal-powershell",
      "args": [
        "-NoExit",
        "-Command",
        "& { $vs = & 'C:\\Program Files (x86)\\Microsoft Visual Studio\\Installer\\vswhere.exe' -latest -products * -requires Microsoft.Component.MSBuild -property installationPath; Import-Module (Join-Path $vs 'Common7\\Tools\\Microsoft.VisualStudio.DevShell.dll'); Enter-VsDevShell -VsInstallPath $vs -DevCmdArguments '-arch=x64 -host_arch=x64' }"
      ],
    }
  },

附:

cmake生成的

[
{
  "directory": "C:/Users/yuan/Desktop/cpp-test/build",
  "command": "D:\\MICROS~3\\18\\ENTERP~1\\VC\\Tools\\MSVC\\1451~1.362\\bin\\Hostx64\\x64\\cl.exe  /nologo /TP -W4 -WX- -permissive- -EHsc -utf-8 -GS -guard:cf -Zi -Od -MDd -RTC1 -D_DEBUG -fp:precise -Oy- -std:c++latest -MDd /FoCMakeFiles\\cpp-test.dir\\main.cpp.obj /FdCMakeFiles\\cpp-test.dir\\ /FS -c C:\\Users\\yuan\\Desktop\\cpp-test\\main.cpp",
  "file": "C:/Users/yuan/Desktop/cpp-test/main.cpp",
  "output": "C:/Users/yuan/Desktop/cpp-test/build/CMakeFiles/cpp-test.dir/main.cpp.obj"
}
]

xmake生成的

[
{
  "directory": "c:\\Users\\yuan\\Desktop\\xmake-test",
  "arguments": ["D:\\Microsoft Visual Studio\\18\\Enterprise\\VC\\Tools\\MSVC\\14.51.36231\\bin\\HostX64\\x64\\cl.exe", "/c", "/nologo", "/MDd", "/Zi", "/FS", "/Fdbuild\\windows\\x64\\debug\\compile.xmake-test.pdb", "/Od", "/EHsc", "/Fobuild\\.objs\\xmake-test\\windows\\x64\\debug\\src\\main.cpp.obj", "src\\main.cpp", "-imsvc", "D:\\Microsoft Visual Studio\\18\\Enterprise\\VC\\Tools\\MSVC\\14.51.36231\\include", "-imsvc", "D:\\Microsoft Visual Studio\\18\\Enterprise\\VC\\Tools\\MSVC\\14.51.36231\\ATLMFC\\include", "-imsvc", "D:\\Microsoft Visual Studio\\18\\Enterprise\\VC\\Auxiliary\\VS\\include", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.26100.0\\ucrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.26100.0\\\\um", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.26100.0\\\\shared", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.26100.0\\\\winrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.26100.0\\\\cppwinrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8.1\\include\\um"],
  "file": "src\\main.cpp"
}]