vscode-swift icon indicating copy to clipboard operation
vscode-swift copied to clipboard

Root-level compile_commands.json required for simple CMake projects

Open ADKaster opened this issue 11 months ago • 4 comments

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 https://github.com/swiftlang/sourcekit-lsp/issues/1816 rdar://139673190

ADKaster avatar Mar 20 '25 01:03 ADKaster

Should be configurable for sourcekit-lsp, we just need to expose a configuration

award999 avatar Mar 21 '25 15:03 award999

#1484 doesn't solve the general problem here.

My compile_commands.json doesn't live in out or build from the top level in my main work projects. It lives in Build/<configname> or similar.

I would have expected a general solution to actually force the LSP to read the .sourcekit-lsp/config.json in a subdirectory of the 'open folder' or some such.

From the issue description:

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.

cc @award999

ADKaster avatar May 13 '25 05:05 ADKaster

@ADKaster does creating and/or adding the following to $ROOT/.vscode/settings.json help in your case?

{
    "swift.sourcekit-lsp.serverArguments": [
        "--compilation-db-search-path",
        "out"
    ]
}

andre-richter avatar Jul 08 '25 08:07 andre-richter

Re-opening this as the original issue was not actually addressed by the PR. Needs a bit more investigation, but the workaround is to use "swift.sourcekit-lsp.serverArguments" as @andre-richter pointed out (thanks for looking into this!).

At the very least we need better documentation around how to get the extension working with CMake.

matthewbastien avatar Jul 08 '25 14:07 matthewbastien