vscode-cmake-tools icon indicating copy to clipboard operation
vscode-cmake-tools copied to clipboard

Unexpected files being loaded as variants file

Open BobSmun opened this issue 2 years ago β€’ 11 comments
trafficstars

Brief Issue Summary

Given the repo organization for a project I'm working on, the .vscode directory is created as a symbolic link to elsewhere in the workspace

This seems to confuse the search for the variants file, as it ends up trying (and failing) to parse CMakeLists.txt and other files at workspace root

CMake Tools Diagnostics

No response

Debug Log

No response

Additional Information

No response

BobSmun avatar Dec 23 '22 07:12 BobSmun

Can you share more information about the folder layout and the symlinks so that we can try to reproduce this? The more detail you provide, the more likely it is that we can reproduce and debug this. Thanks!

bobbrow avatar Dec 29 '22 15:12 bobbrow

I have a similar, maybe related problem:

I have a library, which is used as submodule in a different project, which is not using CMake, therefore I want to create a pkg-config file, with the current built (but not installed) library.

Since I'm using a mixture of multi-config generators and single-config generators, I came up with the following code:

# create pkg-config file for easy inclusion into waf
get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
configure_file(wrapper.pc.in "${CMAKE_CURRENT_BINARY_DIR}/wrapper.pc_conf")
if (is_multi_config)
     file(GENERATE OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/wrapper-$<CONFIG>.pc"
                    INPUT "${CMAKE_CURRENT_BINARY_DIR}/wrapper.pc_conf")
     #set pkgconfig file without Config to Debug for backward compability and convenience 
     file(CREATE_LINK "${CMAKE_CURRENT_SOURCE_DIR}/wrapper-Debug.pc" "${CMAKE_CURRENT_SOURCE_DIR}/wrapper.pc"  SYMBOLIC)
else()
     #$<CONFIG> is not properly defined in single-config generators, therefore create only one.
     file(GENERATE OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/wrapper.pc"
                    INPUT "${CMAKE_CURRENT_BINARY_DIR}/wrapper.pc_conf")
endif()

The wrapper pkg-config template wrapper.pc.in looks like this:

Name: wrapper
Description: Wrapper
URL: abc
Version: 1.0
Requires: ext-lib1.0
Cflags: -I"@CMAKE_CURRENT_SOURCE_DIR@/wrapper" -I"@CMAKE_CURRENT_SOURCE_DIR@/inc" -I"@CMAKE_CURRENT_SOURCE_DIR@/example2/"
Libs: -L"$<TARGET_FILE_DIR:wrapper-lib>" -lwrapper-lib -L"$<TARGET_FILE_DIR:constants-lib>" -lconstants -Wl,-rpath,$<TARGET_FILE_DIR:wrapper-lib>

And in Vscode I got the following error

[variant] Invalid variants specified:
[variant]  >> /Name: should be object
[variant]  >> /Description: should be object
[variant]  >> /URL: should be object
[variant]  >> /Version: should be object
[variant]  >> /Requires: should be object
[variant]  >> /Cflags: should be object
[variant]  >> /Libs: should be object
[variant] Loaded default variants

So somehow the cmake-tools are parsing the wrong file. I also tried to create an empty cmake-variants.yaml in the root folder, but that did not work. I currently cannot share the real project, but maybe you can create a bug reproducer, with this.

BenjaminBeichler avatar Jan 05 '23 10:01 BenjaminBeichler

From a quick view on the code, I guess this code here is the problem

https://github.com/microsoft/vscode-cmake-tools/blob/896f499b99a85e60b36bd8b8bf5a5e779af14236/src/variant.ts#L214-L216

or respectively in the function

https://github.com/microsoft/vscode-cmake-tools/blob/896f499b99a85e60b36bd8b8bf5a5e779af14236/src/variant.ts#L232-L250

If any new file is generated, the function util.chokidarOnAnyChange triggers a call to _reloadVariantsFile with the new file name, but the file name is not checked against the candidates. Or maybe I'm getting it wrong πŸ˜„

BenjaminBeichler avatar Jan 05 '23 13:01 BenjaminBeichler

I have fixed my problem by moving my created pkg-config files into a different subfolder. This supports my hypothesis, that the util.chokidarOnAnyChange is triggered by my generated file.

I know, my approach of generating files into the source tree is also not best practice, but anyway, the current behavior of the cmake-tools is not ideal.

BenjaminBeichler avatar Jan 05 '23 14:01 BenjaminBeichler

Can you share more information about the folder layout and the symlinks so that we can try to reproduce this? The more detail you provide, the more likely it is that we can reproduce and debug this. Thanks!

Folder structure looks a little like the following:

Workspace root
β”œβ”€β”€ .vscode -> symbolic link to devenv/.vscode
β”œβ”€β”€ src
β”‚   β”œβ”€β”€ artifact1
β”‚   β”‚   └── .svn
β”‚   └── artifact2
β”‚       └── .svn
β”œβ”€β”€ devenv
β”‚   β”œβ”€β”€ .svn
β”‚   β”œβ”€β”€ .vscode
β”‚   β”‚   β”œβ”€β”€ settings.json
β”‚   β”‚   └── CMakeKits.json
β”‚   β”œβ”€β”€ _init.sh
β”‚   └── CMakeLists.txt
└── CMakeLists.txt -> symbolic link to devenv/CMakeLists.txt

Initial setup would be to checkout devenv and then run the _init.sh script, which would set up the rest of the checkout - including using ln -sf ... to set up the symbolic links. Although this is for linux, I strongly suspect the windows equivalent would have the same issue

I have a similar, maybe related problem:

Albeit slightly different way to reproduce, the end result appears the similar enough to what I'm seeing - that unrelated files at root are being parsed

Having a quick look at the code, I also see

https://github.com/microsoft/vscode-cmake-tools/blob/896f499b99a85e60b36bd8b8bf5a5e779af14236/src/variant.ts#L187-L190

Changing followSymlinks to true appears to address my particular instance, but I suspect that is too narrow to my case. It seems that the filewatcher is getting a little confused and ends up adding the workspace root (and thus any files that end up there). My guess is that, as a result, _reloadVariantsFile is getting an unexpected non-null filepath, which is then used blindly

I.e. it seems there are 2 related issues:

  • The file watcher appears to be able to get into a state where it is not correctly watching only the expected files
  • _reloadVariantsFile could do more to check (and filter) the file it is trying to load - ignoring the parameter and forcing it to null on L235 would probably help

BobSmun avatar Jan 06 '23 07:01 BobSmun

This issue is now marked as 'stale' due to there being no activity on it for the past 30 days and being labelled 'more info needed'. Unless the 'stale' label is removed or the issue is commented on, this will be closed in 7 days. If you would like to make this issue exempt from getting stale, please remove the 'more info needed' and 'stale' labels or add the 'stale-exempt' label

github-actions[bot] avatar Oct 18 '23 15:10 github-actions[bot]

This happens to me on a symlinked build_nero.sh file (symlinked as it is in a different git-repo for versioning)

I get the following error when ms-code.cmake-tools wrongly tries to parse the *.sh file as a variant:

[variant] Error parsing /home/nero/repos/external/myproject/build_nero.sh: 
	YAMLException: end of the stream or a document separator is expected (5:1)

 2 | set -ex
 3 | 
 4 | # install build dependencies ...
 5 | if [ "$1" = "--install-debs" ]; then
-----^
 6 |     if [ ! -f /etc/apt/sources.l ...
 7 |         sudo apt install cmake ninja-build
	at generateError (/home/nero/.vscode/extensions/ms-vscode.cmake-tools-1.18.41/dist/main.js:27569:10)
	at throwError (/home/nero/.vscode/extensions/ms-vscode.cmake-tools-1.18.41/dist/main.js:27573:9)
	at readDocument (/home/nero/.vscode/extensions/ms-vscode.cmake-tools-1.18.41/dist/main.js:29031:5)
	at loadDocuments (/home/nero/.vscode/extensions/ms-vscode.cmake-tools-1.18.41/dist/main.js:29074:5)
	at Object.load (/home/nero/.vscode/extensions/ms-vscode.cmake-tools-1.18.41/dist/main.js:29100:19)
	at VariantManager._reloadVariantsFile (/home/nero/.vscode/extensions/ms-vscode.cmake-tools-1.18.41/dist/main.js:70901:41)
[variant] Loaded new set of variants

NeroBurner avatar Jun 06 '24 09:06 NeroBurner

I believe I'm also running into this issue. Generating a symlink to an exported compile_commands.json with cmake results in

[variant] Invalid variants specified:
[variant]  >> : should be object
[variant] Loaded default variants

rc-jpbarbosa avatar Jul 03 '24 21:07 rc-jpbarbosa

@rc-jpbarbosa I used a simple project to reproduce this issue but it doesn't reproduce, can you provide a simple project that can reproduce this issue so that we can reproduce it and how to go about fixing it subsequently?

v-frankwang avatar Jul 05 '24 09:07 v-frankwang

@v-frankwang I've stripped it down to a very simple project and I can still reproduce it.

# CMakeLists.txt
cmake_minimum_required(VERSION 3.15 FATAL_ERROR)

project(hello_cmake C CXX)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

if (CMAKE_EXPORT_COMPILE_COMMANDS)
    execute_process(
        COMMAND ${CMAKE_COMMAND} -E create_symlink
        ${CMAKE_BINARY_DIR}/compile_commands.json
        ${CMAKE_SOURCE_DIR}/compile_commands.json
    )
endif()

add_executable(hello_cmake main.cpp)
# .vscode/cmake-variants.yaml
buildType:
  default: debug
  choices:
    debug:
      short: Debug
      long: Emit debug information for the compilation target.
      buildType: Debug
    release:
      short: Release
      long: Optimize generated code for the compilation target.
      buildType: Release
model:
  default: Foo
  choices:
    Foo:
      short: "Foo"
      long: "Foo"
      settings:
        OPTION_MODEL: "Foo"
    Bar:
      short: "Bar"
      long: "Bar"
      settings:
        OPTION_MODEL: "Bar"
// main.cpp
#include <iostream>
int main(int argc, char *argv[]) {
    std::cout << "Hello, world!\n";
}

Output

[main] Configuring project: hello_cmake
[proc] Executing command: /usr/bin/cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -DOPTION_MODEL:STRING=Bar -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/clang -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/clang++ -S/home/ubuntu/dev/projects/hello_cmake -B/home/ubuntu/dev/projects/hello_cmake/build/debug-Bar -G Ninja
[cmake] Not searching for unused variables given on the command line.
[cmake] -- Configuring done
[cmake] -- Generating done
[cmake] -- Build files have been written to: /home/ubuntu/dev/projects/hello_cmake/build/debug-Bar
[variant] Invalid variants specified:
[variant]  >> : should be object
[variant] Loaded default variants

Environment

  • Windows 11, building with WSL (Ubunutu 22.04)*
  • CMake v3.22.1
  • CMake Tools extension v1.18.42
  • Relevant VSCode setting: "cmake.buildDirectory": "${workspaceFolder}/build/${variant:buildType}-${variant:model}"

*I tried to test in pure Windows as well, outside of WSL + VSCode Server, but I am running into some permissions issue when cmake tries to create the symlink and haven't looked into it further.

Notes

  • The issue only occurs (and the "Invalid variants specified" error is only emitted) when the symlink is actually created. Reconfiguring when the symlink already exists doesn't cause the issue. Also, symlinking to a non-existant files doesn't cause the issue.
  • Same results when using ln -s instead of cmake's create_symlink.
  • Issue does not occur when symlinking in a directory other than the project root, i.e. this does not cause the issue:
    execute_process(
       COMMAND ${CMAKE_COMMAND} -E create_symlink 
       ${CMAKE_BINARY_DIR}/compile_commands.json  
       ${CMAKE_SOURCE_DIR}/foo/compile_commands.json
    )
    
    Which is what we're currently doing as a workaround.

rc-jpbarbosa avatar Jul 05 '24 19:07 rc-jpbarbosa

@gcampbell-msft I reproduced the issue using a simple project provided by a user, here are the steps I took to reproduce it:

ENV: vscode version : 1.19.1 Ubuntu : 18.04 CMake Tools extension : v1.18.43 CMake:v3.30.0

Repro steps:

  1. Create a folder named hello_cmake on your linux machine
  2. Open vscode and run the command WSL: connect to WSL in New Windows
  3. Open the folder named hello_cmake.
  4. Create a CMakeLists.txt file and add the following code:
cmake_minimum_required(VERSION 3.15 FATAL_ERROR)

project(hello_cmake C CXX)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

if (CMAKE_EXPORT_COMPILE_COMMANDS)
    execute_process(
        COMMAND ${CMAKE_COMMAND} -E create_symlink
        ${CMAKE_BINARY_DIR}/compile_commands.json
        ${CMAKE_SOURCE_DIR}/compile_commands.json
    )
endif()

add_executable(hello_cmake main.cpp)
  1. Create a main.cpp file and add the following code:
#include <iostream>
int main(int argc, char *argv[]) {
    std::cout << "Hello, world!\n";
}
  1. Create a cmake-variants.yaml file in the .vscode folder and add the following code:
buildType:
  default: debug
  choices:
    debug:
      short: Debug
      long: Emit debug information for the compilation target.
      buildType: Debug
    release:
      short: Release
      long: Optimize generated code for the compilation target.
      buildType: Release
model:
  default: Foo
  choices:
    Foo:
      short: "Foo"
      long: "Foo"
      settings:
        OPTION_MODEL: "Foo"
    Bar:
      short: "Bar"
      long: "Bar"
      settings:
        OPTION_MODEL: "Bar"
  1. Run the command:CMake:Configure

Actual result: image

v-frankwang avatar Jul 12 '24 09:07 v-frankwang

Any news here? Seems like I'm facing the same issue as the thread owner.

Error:

[rollbar] Unhandled exception: Unhandled Promise rejection: Reloading variants file /home/patrick/workspace/cmake-tools-tryout/.vscode Error: EISDIR: illegal operation on a directory, read {}

Below is a minimal example to reproduce my issue:

Versions: Ubuntu 24.04.2 Visual Studio Code 1.97.2 CMake Tools 1.20.52 CMake 3.28.3

Folder layout:

cmake-tools-tryout/
β”œβ”€β”€ .vscode
β”œβ”€β”€ CMakeLists.txt
└── main.cpp

Details:

  • .vscode: A symlink to an empty folder somewhere in the file system. It does not necessarily be empty, but it may not contain a cmake variants file.
  • CMakeLists.txt:
    cmake_minimum_required(VERSION 3.25.0)
    project(HelloWorld)
    add_executable(${PROJECT_NAME} main.cpp)
    
  • main.cpp:
    #include <iostream>
    
    int main() {
        std::cout << "Hello World!" << std::endl;
    }
    

Further hints:

  • By providing a valid cmake variants file inside the symlinked .vscode folder the error disappears.

Screenshot:

Image

ptrckschcknbch avatar Feb 22 '25 10:02 ptrckschcknbch

Hi @ptrckschcknbch Based on your description, we found that your issue is not the same as this one, and if you still reproduce it, you can create a new issue for your issue to track. But we can't reproduce your problem. Image

Yingzi1234 avatar Feb 26 '25 09:02 Yingzi1234

Hi @Yingzi1234

Thank you for your answer. I created https://github.com/microsoft/vscode-cmake-tools/issues/4304 to track my issue further.

Regarding reproduction: It is important that the .vscode folder is a symlink. Symlinks are usually indicated by a little arrow in the file explorer (see picture) below. As this little arrow is missing in your screenshot, I assume that you did not create a proper symlink. I added a short hint on how to create symlinks into https://github.com/microsoft/vscode-cmake-tools/issues/4304 such that you should be able to reproduce the issue.

Image

ptrckschcknbch avatar Feb 26 '25 16:02 ptrckschcknbch

The user has submitted a new ticket for this issue

Hi @Yingzi1234

Thank you for your answer. I created #4304 to track my issue further.

Regarding reproduction: It is important that the .vscode folder is a symlink. Symlinks are usually indicated by a little arrow in the file explorer (see picture) below. As this little arrow is missing in your screenshot, I assume that you did not create a proper symlink. I added a short hint on how to create symlinks into #4304 such that you should be able to reproduce the issue.

Image

Yingzi1234 avatar Mar 12 '25 09:03 Yingzi1234