Skip to content

Root-level compile_commands.json required for simple CMake projects #1449

Open
@ADKaster

Description

@ADKaster

Describe the bug

I can only get the VsCode plugin to recognize my project if there is a compile_commands.json at the root level.
In any reasonable CMake project, the CMake -B flag is used to provide an out-of-source build directory. Alternatively, a build directory is created and projects specify that developers should invoke cmake .. to pass the source directory as the project root. In either case, the compile_commands.json file will always exist in a subdirectory of the repository, and never at the root. Requiring a symlink into one's build directory for the plugin to work is tedious.

To Reproduce
Create the following test project:

CMakeLists.txt

cmake_minimum_required(VERSION 3.25)

project(TestApp LANGUAGES Swift)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

add_executable(TestApp main.swift)

main.swift

print("Hello, world!")

.sourcekit-lsp/config.json

{
   "compilationDatabase": {
      "searchPaths": [ "out" ]
   }
}

build the project with

cmake -Bout -GNinja
ninja -Cout

Open the project in vscode

code .

Open main.swift, and observe errors

Inspect the Swift output tab, and see that there is no "focus" displayed:

18:56:06: Activating Swift for Visual Studio Code...
18:56:06: SourceKit-LSP setup
18:56:06: focus: undefined

Symlink out/compile_commands.json to the root of the directory:

ln -s out/compile_commands.json compile_commands.json

And reload the plugin, and you can see that the focus is correctly applied:

19:07:54: Activating Swift for Visual Studio Code...
19:07:54: SourceKit-LSP setup
19:07:54: lsp-weird-stuff: add: /home/andrew/ladybird-org/swift-test-apps/lsp-weird-stuff
19:07:54: lsp-weird-stuff: focus: /home/andrew/ladybird-org/swift-test-apps/lsp-weird-stuff

Expected behavior

As far as I can tell, there is some kind of circular logic going on here. The config.json in .sourcekit-lsp appears to never be loaded. Peeking at SourceKit-LSP's code, it seems that it will only detect a "compile commands workspace" when it finds a compile_commands.json? And all of the "here's how you find compile commands.json" directives (command line, config) require paths 'relative to workspace root'. But if it only finds the workspace root after finding a compile_commands.json, how am I supposed to instruct the project to find compile_commands.json in a subdirectory?

In any case, I expect that vscode-swift should be instructing the LSP that when I open a directory as a project, that directory is the "Workspace root", even if there's no "VsCode workspace" involved. I don't use that feature at all in any of my projects and clangd works fine :).

My config should be loaded as relative to the opened folder, and I shouldn't have to symlink my compile_commands.json to the project root in order for sourcekit-lsp to find it.

Environment

  • OS: Ubuntu 24.04
  • Swift version 6.2-dev (LLVM 162ee50b401fff2, Swift 57288d13c9f3c02), aka main-snapshot-2025-03-14 from swiftly
  • Visual Studio Code version: 1.98.2 ddc367ed5c8936efe395cffeec279b04ffd7db78 x64
  • vscode-swift version: 2.0.2

Additional context
swiftlang/sourcekit-lsp#1816
rdar://139673190

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    Status

    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions